From 49fa0d82a40345342966e810b44429aec0480ef3 Mon Sep 17 00:00:00 2001
From: web <candymxq888@outlook.com>
Date: 星期二, 01 七月 2025 17:00:18 +0800
Subject: [PATCH] fix:修改.gitgnore文件,移除打包文件

---
 uni_modules/lime-shared/getCurrentPage/index.ts                                              |    9 
 uni_modules/uni-section/components/uni-section/uni-section.vue                               |  167 
 uni_modules/uni-transition/readme.md                                                         |   11 
 uni_modules/lime-shared/cloneDeep/uvue.ts                                                    |   17 
 uni_modules/uni-fab/changelog.md                                                             |   25 
 uni_modules/uni-load-more/components/uni-load-more/i18n/index.js                             |    8 
 uni_modules/uni-ui/components/uni-ui/uni-ui.vue                                              |    7 
 uni_modules/uni-popup/changelog.md                                                           |   92 
 uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js             |  287 
 uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue |  146 
 uni_modules/lime-shared/animation/uvue.uts                                                   |  117 
 uni_modules/uni-table/components/uni-tr/table-checkbox.vue                                   |  179 
 uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json                            |    4 
 uni_modules/lime-shared/isBrowser/index.ts                                                   |    8 
 uni_modules/uni-combox/changelog.md                                                          |   17 
 uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue                      |  431 
 uni_modules/uni-collapse/changelog.md                                                        |   38 
 uni_modules/lime-shared/components/lime-shared/lime-shared.vue                               |  156 
 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue           |  323 
 uni_modules/uni-list/components/uni-list/uni-refresh.wxs                                     |   87 
 uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json                           |   12 
 uni_modules/uni-tag/package.json                                                             |   84 
 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json                         |    6 
 uni_modules/uni-easyinput/readme.md                                                          |   11 
 uni_modules/uni-scss/styles/setting/_text.scss                                               |   24 
 uni_modules/lime-shared/animation/vue.ts                                                     |  123 
 uni_modules/lime-shared/toBoolean/index.ts                                                   |   40 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json             |   22 
 uni_modules/uni-countdown/readme.md                                                          |   10 
 uni_modules/uni-icons/readme.md                                                              |    8 
 uni_modules/uni-drawer/changelog.md                                                          |   13 
 uni_modules/uni-swipe-action/changelog.md                                                    |   47 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue             |  177 
 uni_modules/uni-notice-bar/changelog.md                                                      |   20 
 uni_modules/uni-fav/package.json                                                             |   89 
 uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json                       |    4 
 uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue                     |  143 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js                      |  270 
 uni_modules/uni-list/readme.md                                                               |  346 
 uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json                         |    6 
 uni_modules/lime-shared/getStyleStr/index.ts                                                 |   54 
 uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue                       |  325 
 uni_modules/uni-table/readme.md                                                              |   13 
 uni_modules/lime-shared/exif/index.ts                                                        |    9 
 uni_modules/lime-shared/animation/index.ts                                                   |   10 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js                 |    8 
 uni_modules/lime-shared/getCurrentPage/uvue.uts                                              |    5 
 uni_modules/uni-pagination/package.json                                                      |   83 
 uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue                |  367 
 uni_modules/uni-swipe-action/package.json                                                    |   84 
 uni_modules/lime-shared/exif/uvue.ts                                                         |    7 
 uni_modules/uni-scss/styles/setting/_variables.scss                                          |  146 
 uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.uvue                              |  140 
 uni_modules/uni-pagination/components/uni-pagination/i18n/index.js                           |   12 
 uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue             |  849 +
 uni_modules/lime-shared/selectElement/index.uts                                              |  275 
 uni_modules/uni-countdown/package.json                                                       |   84 
 uni_modules/lime-shared/getRect/index.ts                                                     |    9 
 uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue                   |  562 
 uni_modules/lime-shared/addUnit/index.ts                                                     |   42 
 uni_modules/uni-load-more/readme.md                                                          |   14 
 uni_modules/uni-scss/readme.md                                                               |    4 
 uni_modules/lime-shared/floatMul/index.ts                                                    |   44 
 uni_modules/lime-qrcode/components/l-qrcode/qrcode.js                                        |    6 
 uni_modules/uni-dateformat/changelog.md                                                      |   10 
 uni_modules/lime-shared/exif/vue.ts                                                          | 1057 +
 uni_modules/uni-file-picker/package.json                                                     |   84 
 uni_modules/uni-popup/package.json                                                           |   88 
 uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue                      |  309 
 uni_modules/uni-row/readme.md                                                                |   10 
 uni_modules/lime-shared/getLocalFilePath/index.ts                                            |   62 
 uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json                       |    4 
 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss                             |   58 
 uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json                                     |    4 
 uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue                            |  567 
 uni_modules/uni-transition/components/uni-transition/uni-transition.vue                      |  286 
 uni_modules/uni-list/components/uni-list/uni-refresh.vue                                     |   65 
 uni_modules/uni-easyinput/changelog.md                                                       |  115 
 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json                                 |    7 
 uni_modules/uni-scss/styles/setting/_border.scss                                             |    3 
 uni_modules/lime-shared/camelCase/index.ts                                                   |   21 
 uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue                      |   88 
 uni_modules/lime-shared/getRect/vue.ts                                                       |  117 
 uni_modules/lime-shared/platform/index.ts                                                    |   34 
 uni_modules/lime-shared/range/index.ts                                                       |   36 
 uni_modules/uni-pagination/changelog.md                                                      |   27 
 uni_modules/lime-shared/animation/bezier.ts                                                  |   82 
 uni_modules/lime-shared/unitConvert/index.ts                                                 |   79 
 uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue                      |  232 
 uni_modules/uni-link/readme.md                                                               |   11 
 uni_modules/uni-fav/changelog.md                                                             |   19 
 uni_modules/uni-badge/changelog.md                                                           |   33 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js                    |  195 
 uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue                         |  229 
 uni_modules/uni-link/package.json                                                            |   87 
 uni_modules/uni-ui/readme.md                                                                 |  247 
 uni_modules/uni-fav/readme.md                                                                |   10 
 uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json                         |    6 
 uni_modules/uni-data-picker/components/uni-data-picker/keypress.js                           |   45 
 uni_modules/lime-shared/vue/index.ts                                                         |   16 
 uni_modules/uni-easyinput/package.json                                                       |   88 
 uni_modules/uni-ui/package.json                                                              |  130 
 uni_modules/uni-card/readme.md                                                               |   12 
 uni_modules/uni-calendar/components/uni-calendar/i18n/index.js                               |    8 
 uni_modules/uni-icons/components/uni-icons/uniicons.ttf                                      |    0 
 uni_modules/uni-forms/components/uni-forms/utils.js                                          |  293 
 uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue                         |  676 
 uni_modules/uni-scss/styles/setting/_color.scss                                              |   66 
 uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json                         |    5 
 uni_modules/uni-icons/changelog.md                                                           |   42 
 uni_modules/uni-popup/components/uni-popup/keypress.js                                       |   45 
 uni_modules/lime-shared/debounce/uvue.ts                                                     |   36 
 uni_modules/uni-table/package.json                                                           |   84 
 uni_modules/lime-shared/getStyleStr/index_.uts                                               |   39 
 uni_modules/uni-section/package.json                                                         |   87 
 uni_modules/uni-grid/package.json                                                            |   86 
 uni_modules/uni-popup/components/uni-popup/i18n/en.json                                      |    7 
 uni_modules/uni-drawer/package.json                                                          |   87 
 uni_modules/uni-calendar/components/uni-calendar/calendar.js                                 |  544 
 uni_modules/lime-shared/isObject/index.ts                                                    |   19 
 uni_modules/uni-countdown/changelog.md                                                       |   28 
 uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json                       |    5 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue       | 1064 +
 uni_modules/uni-popup/components/uni-popup-dialog/keypress.js                                |   45 
 uni_modules/lime-shared/getClassStr/index.ts                                                 |   53 
 uni_modules/uni-data-checkbox/readme.md                                                      |   18 
 uni_modules/uni-swiper-dot/readme.md                                                         |   11 
 uni_modules/uni-list/components/uni-list/uni-list.vue                                        |  123 
 uni_modules/uni-scss/styles/tools/functions.scss                                             |   19 
 uni_modules/uni-data-picker/package.json                                                     |   91 
 uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json                            |    5 
 uni_modules/lime-shared/fillZero/index.ts                                                    |   11 
 uni_modules/lime-shared/raf/vue.ts                                                           |   32 
 uni_modules/lime-shared/clamp/index.ts                                                       |   16 
 uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue                       |  316 
 uni_modules/lime-shared/cloneDeep/vue.ts                                                     |  103 
 uni_modules/lime-shared/cloneDeep/index.ts                                                   |   10 
 uni_modules/lime-shared/isPromise/index.ts                                                   |   22 
 uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue                  |  402 
 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue                              |  593 
 uni_modules/uni-drawer/components/uni-drawer/keypress.js                                     |   45 
 uni_modules/uni-goods-nav/readme.md                                                          |   10 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json                  |   22 
 uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue                               |  357 
 uni_modules/uni-tag/changelog.md                                                             |   23 
 uni_modules/uni-icons/components/uni-icons/uniicons.css                                      |  664 
 uni_modules/uni-list/package.json                                                            |   88 
 uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue                  |  381 
 uni_modules/uni-scss/theme.scss                                                              |   31 
 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js                             |    8 
 uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue           |  144 
 uni_modules/lime-shared/animation/useTransition.ts                                           |   98 
 uni_modules/uni-popup/components/uni-popup/uni-popup.uvue                                    |   90 
 uni_modules/uni-number-box/package.json                                                      |   83 
 uni_modules/uni-row/components/uni-row/uni-row.vue                                           |  190 
 uni_modules/lime-shared/index.ts                                                             |   43 
 uni_modules/uni-icons/components/uni-icons/uni-icons.vue                                     |  110 
 uni_modules/uni-section/readme.md                                                            |    8 
 uni_modules/uni-data-checkbox/package.json                                                   |   84 
 uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue                                     |  223 
 uni_modules/uni-countdown/components/uni-countdown/i18n/index.js                             |    8 
 uni_modules/uni-table/components/uni-th/uni-th.vue                                           |  295 
 uni_modules/uni-calendar/readme.md                                                           |  103 
 uni_modules/uni-nav-bar/readme.md                                                            |   15 
 uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue                         |  276 
 uni_modules/uni-goods-nav/package.json                                                       |   88 
 uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue                      |  218 
 uni_modules/uni-transition/changelog.md                                                      |   24 
 uni_modules/uni-icons/components/uni-icons/uni-icons.uvue                                    |   91 
 uni_modules/uni-rate/package.json                                                            |   88 
 uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts                                     |   78 
 uni_modules/lime-shared/hasOwn/index.ts                                                      |    9 
 uni_modules/uni-table/components/uni-thead/uni-thead.vue                                     |  137 
 uni_modules/uni-countdown/components/uni-countdown/i18n/en.json                              |    6 
 uni_modules/uni-swiper-dot/package.json                                                      |   87 
 uni_modules/lime-shared/arrayBufferToFile/vue.ts                                             |   63 
 uni_modules/uni-title/package.json                                                           |   88 
 uni_modules/uni-fab/package.json                                                             |   85 
 uni_modules/uni-collapse/package.json                                                        |   86 
 uni_modules/lime-shared/kebabCase/index.ts                                                   |   24 
 uni_modules/uni-row/package.json                                                             |   87 
 uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue                      |  292 
 uni_modules/uni-datetime-picker/readme.md                                                    |   21 
 uni_modules/uni-popup/components/uni-popup/popup.js                                          |   26 
 uni_modules/uni-popup/readme.md                                                              |   17 
 uni_modules/uni-calendar/components/uni-calendar/i18n/en.json                                |   12 
 uni_modules/uni-group/components/uni-group/uni-group.vue                                     |  134 
 uni_modules/uni-calendar/changelog.md                                                        |   30 
 uni_modules/uni-scss/changelog.md                                                            |    8 
 uni_modules/uni-table/i18n/zh-Hans.json                                                      |    9 
 uni_modules/lime-shared/capitalizedAmount/index.ts                                           |  111 
 uni_modules/uni-data-select/changelog.md                                                     |   39 
 uni_modules/uni-calendar/components/uni-calendar/util.js                                     |  360 
 uni_modules/lime-shared/floatDiv/index.ts                                                    |   45 
 uni_modules/uni-card/package.json                                                            |   90 
 uni_modules/uni-tag/readme.md                                                                |   13 
 uni_modules/lime-shared/createAnimation/type.ts                                              |   25 
 uni_modules/uni-steps/readme.md                                                              |   13 
 uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue                         |  404 
 uni_modules/uni-scss/styles/index.scss                                                       |    7 
 uni_modules/lime-shared/debounce/vue.ts                                                      |   40 
 uni_modules/uni-steps/components/uni-steps/uni-steps.vue                                     |  280 
 uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue                                  |  107 
 uni_modules/uni-indexed-list/package.json                                                    |   89 
 uni_modules/uni-table/i18n/fr.json                                                           |    9 
 uni_modules/uni-table/i18n/index.js                                                          |   12 
 uni_modules/uni-swipe-action/readme.md                                                       |   11 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue               |  940 +
 uni_modules/uni-list/changelog.md                                                            |   46 
 uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json                         |    5 
 uni_modules/uni-icons/package.json                                                           |   89 
 uni_modules/uni-grid/changelog.md                                                            |   13 
 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json                              |    6 
 uni_modules/lime-shared/createAnimation/uvue.ts                                              |    5 
 uni_modules/lime-shared/selectAllComponent/index.ts                                          |    8 
 uni_modules/uni-scss/variables.scss                                                          |   62 
 uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue                            |  147 
 uni_modules/uni-datetime-picker/package.json                                                 |   88 
 uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue                   |  668 
 uni_modules/uni-indexed-list/readme.md                                                       |   11 
 uni_modules/uni-forms/package.json                                                           |   89 
 uni_modules/uni-nav-bar/changelog.md                                                         |   57 
 uni_modules/lime-qrcode/changelog.md                                                         |   37 
 uni_modules/lime-shared/hasOwn/uvue.ts                                                       |   39 
 uni_modules/uni-scss/styles/setting/_space.scss                                              |   56 
 uni_modules/uni-scss/styles/setting/_styles.scss                                             |  167 
 uni_modules/uni-load-more/changelog.md                                                       |   25 
 uni_modules/uni-steps/package.json                                                           |   87 
 uni_modules/uni-segmented-control/package.json                                               |   85 
 uni_modules/uni-group/readme.md                                                              |    9 
 uni_modules/lime-shared/pathToBase64/index.ts                                                |    9 
 uni_modules/lime-shared/package.json                                                         |   86 
 uni_modules/uni-combox/readme.md                                                             |   11 
 uni_modules/uni-link/changelog.md                                                            |   17 
 uni_modules/uni-table/components/uni-th/filter-dropdown.vue                                  |  511 
 uni_modules/uni-tooltip/changelog.md                                                         |   16 
 uni_modules/uni-badge/package.json                                                           |   85 
 uni_modules/lime-qrcode/hybrid/html/index.html                                               |   77 
 uni_modules/uni-table/i18n/zh-Hant.json                                                      |    9 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue      |  348 
 uni_modules/lime-shared/pathToBase64/uvue.uts                                                |   17 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js                     |  260 
 uni_modules/uni-link/components/uni-link/uni-link.vue                                        |  128 
 uni_modules/uni-data-picker/changelog.md                                                     |   79 
 uni_modules/lime-shared/canIUseCanvas2d/index.ts                                             |   67 
 uni_modules/uni-table/i18n/en.json                                                           |    9 
 uni_modules/uni-scss/styles/setting/_radius.scss                                             |   55 
 uni_modules/lime-shared/random/index.ts                                                      |   24 
 uni_modules/lime-shared/floatSub/index.ts                                                    |   32 
 uni_modules/uni-fab/readme.md                                                                |    9 
 uni_modules/uni-group/package.json                                                           |   87 
 uni_modules/uni-search-bar/changelog.md                                                      |   47 
 uni_modules/uni-file-picker/readme.md                                                        |   11 
 uni_modules/lime-shared/selectComponent/vue.ts                                               |  149 
 uni_modules/uni-easyinput/components/uni-easyinput/common.js                                 |   54 
 uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue                            |   30 
 uni_modules/lime-shared/selectAllComponent/uvue.uts                                          |   39 
 uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json                                     |    4 
 uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js                           |    8 
 uni_modules/lime-shared/throttle/index.ts                                                    |   77 
 uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue                      |  465 
 uni_modules/uni-forms/readme.md                                                              |   23 
 uni_modules/uni-list/components/uni-list-item/uni-list-item.vue                              |  534 
 uni_modules/lime-shared/isDef/index.ts                                                       |   23 
 uni_modules/uni-tag/components/uni-tag/uni-tag.vue                                           |  252 
 uni_modules/uni-pagination/components/uni-pagination/i18n/es.json                            |    5 
 uni_modules/uni-search-bar/readme.md                                                         |   14 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js                       |  421 
 uni_modules/lime-shared/base64ToPath/uvue.uts                                                |   22 
 uni_modules/uni-section/changelog.md                                                         |    2 
 uni_modules/uni-drawer/readme.md                                                             |   10 
 uni_modules/uni-group/changelog.md                                                           |   16 
 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json                                 |    7 
 uni_modules/uni-pagination/readme.md                                                         |   11 
 uni_modules/uni-load-more/components/uni-load-more/i18n/en.json                              |    5 
 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts               |  692 
 .gitignore                                                                                   |    1 
 uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json                       |    5 
 uni_modules/uni-table/changelog.md                                                           |   33 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs                         |  341 
 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue          |   69 
 uni_modules/uni-pagination/components/uni-pagination/i18n/en.json                            |    5 
 uni_modules/uni-collapse/readme.md                                                           |   12 
 uni_modules/lime-shared/selectComponent/uvue.uts                                             |   75 
 uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue                               |  108 
 uni_modules/lime-shared/floatAdd/index.ts                                                    |   36 
 uni_modules/lime-shared/toArray/index.ts                                                     |   21 
 uni_modules/uni-popup/components/uni-popup/i18n/index.js                                     |    8 
 uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue                         |  187 
 uni_modules/uni-dateformat/components/uni-dateformat/date-format.js                          |  200 
 uni_modules/lime-shared/raf/index.ts                                                         |   10 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js                       |   84 
 uni_modules/uni-data-picker/readme.md                                                        |   22 
 uni_modules/uni-dateformat/package.json                                                      |   88 
 uni_modules/lime-shared/isNumeric/index.ts                                                   |   33 
 uni_modules/uni-tooltip/readme.md                                                            |    8 
 uni_modules/uni-file-picker/changelog.md                                                     |   81 
 uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue                       |  187 
 uni_modules/uni-ui/changelog.md                                                              |  578 
 uni_modules/lime-shared/createImage/index.ts                                                 |   71 
 uni_modules/uni-badge/components/uni-badge/uni-badge.vue                                     |  268 
 uni_modules/uni-fab/components/uni-fab/uni-fab.vue                                           |  491 
 uni_modules/lime-qrcode/hybrid/html/qrcode.min.js                                            |    6 
 uni_modules/uni-calendar/package.json                                                        |   86 
 uni_modules/uni-title/components/uni-title/uni-title.vue                                     |  171 
 uni_modules/uni-notice-bar/package.json                                                      |   87 
 uni_modules/uni-notice-bar/readme.md                                                         |   13 
 uni_modules/uni-card/changelog.md                                                            |   26 
 uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.vue                               |   79 
 uni_modules/uni-table/components/uni-td/uni-td.vue                                           |   95 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js                    |  302 
 uni_modules/lime-qrcode/components/l-qrcode/props.ts                                         |   36 
 uni_modules/lime-shared/isBase64/index.ts                                                    |   23 
 uni_modules/uni-data-select/readme.md                                                        |    8 
 uni_modules/lime-shared/isNumber/index.ts                                                    |   26 
 uni_modules/uni-fav/components/uni-fav/i18n/index.js                                         |    8 
 uni_modules/uni-table/i18n/es.json                                                           |    9 
 uni_modules/uni-segmented-control/changelog.md                                               |   15 
 uni_modules/lime-shared/debounce/index.ts                                                    |   10 
 uni_modules/lime-shared/createAnimation/index.ts                                             |    9 
 uni_modules/lime-qrcode/components/l-qrcode/type.ts                                          |   48 
 uni_modules/uni-load-more/package.json                                                       |   84 
 uni_modules/uni-rate/components/uni-rate/uni-rate.vue                                        |  361 
 uni_modules/uni-grid/readme.md                                                               |   11 
 uni_modules/uni-fav/components/uni-fav/i18n/en.json                                          |    4 
 uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json                           |   12 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue                  |  947 +
 uni_modules/uni-nav-bar/package.json                                                         |   87 
 uni_modules/lime-shared/animation/ease.ts                                                    |    3 
 uni_modules/uni-datetime-picker/changelog.md                                                 |  168 
 uni_modules/uni-table/components/uni-table/uni-table.vue                                     |  460 
 uni_modules/uni-fav/components/uni-fav/uni-fav.vue                                           |  161 
 uni_modules/uni-combox/package.json                                                          |   88 
 uni_modules/uni-row/components/uni-col/uni-col.vue                                           |  317 
 uni_modules/lime-shared/arrayBufferToFile/index.ts                                           |    8 
 uni_modules/uni-search-bar/package.json                                                      |   87 
 uni_modules/uni-dateformat/readme.md                                                         |   11 
 uni_modules/uni-popup/components/uni-popup/uni-popup.vue                                     |  518 
 uni_modules/uni-steps/changelog.md                                                           |   18 
 uni_modules/uni-tooltip/package.json                                                         |   86 
 uni_modules/lime-shared/isEmpty/index.ts                                                     |   83 
 uni_modules/uni-forms/changelog.md                                                           |  100 
 uni_modules/lime-shared/getRect/uvue.uts                                                     |   16 
 uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue                   |  551 
 uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js                        |   12 
 uni_modules/uni-combox/components/uni-combox/uni-combox.vue                                  |  284 
 uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js                              |  649 
 uni_modules/lime-shared/selectAllComponent/vue.ts                                            |  151 
 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js                |  622 
 uni_modules/uni-grid/components/uni-grid/uni-grid.vue                                        |  142 
 uni_modules/uni-rate/readme.md                                                               |   12 
 uni_modules/lime-shared/hasOwn/vue.ts                                                        |   30 
 uni_modules/lime-shared/readme.md                                                            |  445 
 uni_modules/uni-card/components/uni-card/uni-card.vue                                        |  270 
 uni_modules/uni-transition/package.json                                                      |   85 
 uni_modules/lime-shared/pathToBase64/vue.ts                                                  |  121 
 uni_modules/lime-shared/isFunction/index.ts                                                  |   16 
 uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue                |   60 
 uni_modules/uni-table/components/uni-tbody/uni-tbody.vue                                     |   34 
 uni_modules/uni-icons/components/uni-icons/uniicons_file.ts                                  |  664 
 uni_modules/lime-shared/getCurrentPage/vue.ts                                                |    6 
 uni_modules/lime-qrcode/hybrid/html/uni.webview.1.5.3.js                                     |    1 
 uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue                              |  127 
 uni_modules/lime-shared/isString/index.ts                                                    |   19 
 uni_modules/lime-qrcode/readme.md                                                            |  152 
 uni_modules/lime-shared/changelog.md                                                         |   40 
 uni_modules/uni-transition/components/uni-transition/createAnimation.js                      |  131 
 uni_modules/uni-title/readme.md                                                              |   14 
 uni_modules/lime-shared/sleep/index.ts                                                       |   44 
 uni_modules/uni-forms/components/uni-forms/validate.js                                       |  486 
 uni_modules/lime-shared/toNumber/index.ts                                                    |   28 
 uni_modules/lime-shared/closest/index.ts                                                     |   22 
 uni_modules/uni-file-picker/components/uni-file-picker/utils.js                              |  110 
 uni_modules/lime-shared/base64ToPath/vue.ts                                                  |   75 
 uni_modules/lime-shared/base64ToArrayBuffer/index.ts                                         |   13 
 uni_modules/uni-goods-nav/changelog.md                                                       |   18 
 uni_modules/uni-segmented-control/readme.md                                                  |   13 
 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css           |   76 
 uni_modules/uni-number-box/readme.md                                                         |   13 
 uni_modules/uni-badge/readme.md                                                              |   10 
 uni_modules/uni-data-select/package.json                                                     |   86 
 uni_modules/lime-qrcode/components/l-qrcode/utils.uts                                        |   35 
 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json             |   22 
 uni_modules/lime-qrcode/package.json                                                         |   91 
 uni_modules/uni-forms/components/uni-forms/uni-forms.vue                                     |  404 
 uni_modules/lime-shared/createAnimation/vue.ts                                               |  148 
 uni_modules/lime-shared/raf/uvue.ts                                                          |   48 
 uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue                                  |  183 
 uni_modules/uni-table/components/uni-tr/uni-tr.vue                                           |  184 
 uni_modules/lime-shared/createCanvas/index.ts                                                |   73 
 uni_modules/uni-scss/index.scss                                                              |    1 
 uni_modules/uni-rate/changelog.md                                                            |   25 
 uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue                                    |  235 
 uni_modules/lime-shared/arrayBufferToFile/uvue.uts                                           |   10 
 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json                         |    6 
 uni_modules/uni-number-box/changelog.md                                                      |   39 
 uni_modules/uni-data-checkbox/changelog.md                                                   |   49 
 uni_modules/uni-scss/package.json                                                            |   82 
 uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue                           |  632 
 uni_modules/lime-shared/base64ToPath/index.ts                                                |    9 
 uni_modules/lime-shared/selectComponent/index.ts                                             |    7 
 uni_modules/uni-indexed-list/changelog.md                                                    |   17 
 uni_modules/uni-title/changelog.md                                                           |   10 
 uni_modules/uni-swiper-dot/changelog.md                                                      |   12 
 /dev/null                                                                                    |   28 
 uni_modules/uni-row/changelog.md                                                             |   10 
 406 files changed, 46,531 insertions(+), 28 deletions(-)

diff --git a/.gitignore b/.gitignore
index 3c3629e..8bdd202 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 node_modules
+unpackage/*
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/changelog.md b/uni_modules/lime-qrcode/changelog.md
new file mode 100644
index 0000000..779ab02
--- /dev/null
+++ b/uni_modules/lime-qrcode/changelog.md
@@ -0,0 +1,37 @@
+## 0.1.8(2024-08-05)
+- fix: 修复因shared升级导致微信小程序可能不生效的问题
+## 0.1.7(2024-05-15)
+- fix: 修复uvue因缺少依赖无法使用
+## 0.1.6(2024-05-09)
+- fix: 修复vue2因type问题导致无法使用
+## 0.1.5(2024-04-14)
+- fix: 修复缺少依赖
+## 0.1.4(2024-04-10)
+- chore: 更新文档
+## 0.1.3(2024-04-01)
+- chore: 兼容uniapp x ios(app-js)
+## 0.1.2(2023-12-14)
+- fix: uvue 引入 API 自定义包出错
+## 0.1.1(2023-12-11)
+- chore: uvue的二维码API独立,需要单独下载
+## 0.1.0(2023-12-07)
+- fix: 修复因utssdk目录导致无法运行
+## 0.0.9(2023-12-06)
+- feat: 支持uvue
+## 0.0.8(2023-12-06)
+- feat: 支持uvue
+## 0.0.7(2023-12-06)
+- feat: 支持uvue
+## 0.0.6(2023-12-06)
+- feat: 支持uvue
+## 0.0.5(2023-07-30)
+- fix: 修复再次生成前没有清空,导致图形叠加
+## 0.0.4(2023-07-27)
+- fix: 修复相同尺寸无法再次生成
+## 0.0.3(2023-06-09)
+- feat: 支持通过`@vue/composition-api`在`vue2`上使用
+- chore: 更新文档
+## 0.0.2(2023-06-08)
+- chore: 更新文档
+## 0.0.1(2023-06-08)
+- 首次
diff --git a/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue b/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue
new file mode 100644
index 0000000..fcab10a
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue
@@ -0,0 +1,235 @@
+<template>
+	<!-- #ifdef MP -->
+	<canvas :style="styles" type="2d" :canvas-id="canvasId" :id="canvasId"></canvas>
+	<!-- #endif  -->
+	<!-- #ifdef APP -->
+	<view class="l-qrcode" ref="drawableRef" :style="[styles]">
+		<image class="l-qrcode__icon" v-if="icon" :src="icon" :style="[iconStyle]"></image>
+	</view>
+	<!-- #endif  -->
+	<!-- #ifdef WEB -->
+	<view class="l-qrcode" ref="drawableRef" :style="[styles]">
+		
+	</view>
+	<!-- #endif  -->
+</template>
+<script lang="uts" setup>
+	import { type PropType, nextTick } from 'vue'
+	// #ifndef APP
+	import { QRCodeCanvas } from './qrcode.js';
+	import { QRCodePropsTypes , ImageSettings } from './type'
+	// #endif
+	// #ifdef APP
+	import { QRCodeCanvas, QRCodePropsTypes , ImageSettings } from '@/uni_modules/lime-qrcodegen'
+	// #endif
+	// import { addUnit } from '@/uni_modules/lime-shared/addUnit'
+	// import { unitConvert } from '@/uni_modules/lime-shared/unitConvert'
+	// import { toBoolean } from '@/uni_modules/lime-shared/toBoolean'
+	import { addUnit, unitConvert } from './utils'
+	import { LQrcodeFailCallback, LQrcodeCompleteCallback, LQrcodeSuccessCallback} from './type'
+	
+	const name = 'l-qrcode'
+	const props = defineProps({
+		value: {
+			type: String
+		},
+		icon: {
+			type: String
+		},
+		// #ifdef APP-ANDROID
+		size: {
+			type: Object,
+			default: 160
+		},
+		iconSize: {
+			type: Object,
+			default: 40
+		},
+		// #endif
+		// #ifndef APP-ANDROID
+		size: {
+			type: [Number, String],
+			default: 160
+		},
+		iconSize: {
+			type: [Number, String],
+			default: 40
+		},
+		// #endif
+		marginSize: {
+			type: Number,
+			default: 0
+		},
+		color: {
+			type: String,
+			default: '#000'
+		},
+		bgColor: {
+			type: String,
+			default: 'transparent'
+		},
+		bordered: {
+			type: Boolean,
+			default: true
+		},
+		errorLevel: {
+			type: String as PropType<'L' | 'M' | 'Q' | 'H'>,
+			default: 'M' // 'L' | 'M' | 'Q' | 'H'
+		},
+		useCanvasToTempFilePath: {
+			type: Boolean,
+			default: false
+		}
+		// status: {
+		// 	type: String as PropType<'active'|'expired'|'loading'>,
+		// 	default: 'active' // active | expired | loading
+		// }
+	})
+	const emits = defineEmits(['success'])
+	const context = getCurrentInstance();
+	const canvasId = `l-qrcode${context!.uid}` 
+	const styles = computed<Map<string, any>>(():Map<string, any>=>{
+		const style = new Map<string, any>()
+		const size = addUnit(props.size);
+		if(size!=null){
+			style.set('width', size)
+			style.set('height', size)
+		}
+		style.set('background', props.bgColor)
+		return style
+	})
+	// #ifdef APP
+	const iconStyle = computed<Map<string, any>>(():Map<string, any>=>{
+		const style = new Map<string, any>()
+		const size = addUnit(props.iconSize);
+		if(size!=null){
+			style.set('width', size)
+			style.set('height', size)
+		}
+		return style
+	})
+	// #endif
+	const drawableRef = ref<UniElement|null>(null);
+	// #ifdef WEB
+	let canvas:HTMLCanvasElement|null = null
+	// #endif
+	let qrcode:QRCodeCanvas|null = null
+	
+	const canvasToTempFilePath = (options: UTSJSONObject)=>{
+		
+		const format =   options.getString('format') ?? 'png';
+		const fail =     options.get('fail') as LQrcodeFailCallback | null;
+		const complete = options.get('complete') as LQrcodeCompleteCallback | null;
+		const success =  options.get('success') as LQrcodeSuccessCallback | null;
+		// #ifdef APP
+		const newOptions = {
+			format,
+			fail,
+			complete,
+			success,
+		} as TakeSnapshotOptions
+		drawableRef.value!.takeSnapshot(newOptions)
+		// #endif
+		// #ifdef WEB
+		success?.({
+			tempFilePath: canvas?.toDataURL('image/'+format)
+		})
+		// #endif
+		
+	}
+	const render = ()=>{
+		const param:QRCodePropsTypes = {
+			value: props.value,
+			size:  unitConvert(props.size),
+			fgColor: props.color,
+			level: ['L', 'M', 'Q', 'H'].includes(props.errorLevel) ? props.errorLevel : 'M',
+			marginSize: props.marginSize,
+			includeMargin: props.bordered,
+			imageSettings: null,
+		} as QRCodePropsTypes
+		
+		if(props.icon != null){
+		// if(toBoolean(props.iconSize) && toBoolean(props.icon)){
+			const size = unitConvert(props.iconSize)
+			param.imageSettings = {
+				src: props.icon,
+				width: size,
+				height: size,
+				excavate: true
+			} as ImageSettings
+		}
+		qrcode?.render(param)
+		
+		if(props.useCanvasToTempFilePath){
+			setTimeout(()=>{
+				canvasToTempFilePath({
+					success: (res: TakeSnapshotSuccess)=>{
+						emits('success', res.tempFilePath)
+					}
+				})
+			},100)
+		}
+	}
+	defineExpose({
+		canvasToTempFilePath
+	})
+	onMounted(()=>{
+		nextTick(()=>{
+			// #ifdef APP
+			const ctx = drawableRef.value!.getDrawableContext();
+			qrcode = new QRCodeCanvas(ctx!)
+			// #endif
+			// #ifdef WEB
+			canvas = document.createElement('canvas')
+			canvas.style.width = '100%'
+			canvas.style.height = '100%'
+			drawableRef.value!.appendChild(canvas)
+			qrcode = new QRCodeCanvas(canvas, {
+				pixelRatio: uni.getSystemInfoSync().pixelRatio,
+				createImage: () => {
+					const image = new Image();
+					image.crossOrigin = 'anonymous'; 
+					return image;
+				}
+			})
+			// #endif
+			
+			watchEffect(()=>{
+				render()
+			})
+		})
+		
+	})
+	onUnmounted(()=>{
+		// #ifdef WEB
+		canvas?.remove();
+		// #endif
+		qrcode = null;
+	})
+</script>
+<style lang="scss">
+	.l-qrcode {
+		position: relative;
+		background-color: aqua;
+		justify-content: center;
+		align-items: center;
+
+		&-mask {
+			position: absolute;
+			// inset: 0;
+			// inset-block-start: 0;
+			// inset-inline-start: 0;
+			z-index: 10;
+			display: flex;
+			flex-direction: column;
+			justify-content: center;
+			align-items: center;
+			// width: 100%;
+			// height: 100%;
+			color: rgba(0, 0, 0, 0.88);
+			line-height: 1.5714285714285714;
+			background: rgba(255, 255, 255, 0.96);
+			text-align: center;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue b/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue
new file mode 100644
index 0000000..f228583
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue
@@ -0,0 +1,223 @@
+<template>
+	<view class="l-qrcode" :style="[styles]">
+		<!-- #ifndef APP-NVUE -->
+		<canvas :style="styles" type="2d" :canvas-id="canvasId" :id="canvasId"></canvas>
+		<!-- #endif  -->
+		<!-- #ifdef APP-NVUE  -->
+		<web-view 
+		ref="qrcodeRef"
+		@pagefinish="onFinished" 
+		@error="onError" 
+		@onPostMessage="onMessage"
+		:style="styles" src="/uni_modules/lime-qrcode/hybrid/html/index.html?v=1"></web-view>
+		<!-- #endif  -->
+		<!-- <view class="l-qrcode-mask" v-if="['loading', 'expired'].includes(props.status)">
+			<l-loading v-if="props.status == 'loading'"></l-loading>
+			<view class="l-qrcode-expired" v-if="props.status == 'expired'">
+				<slot></slot>
+			</view>
+		</view> -->
+	</view>
+</template>
+<script lang="ts">
+	// @ts-nocheck
+	import { computed, defineComponent, getCurrentInstance, watch, onUnmounted, onMounted } from '@/uni_modules/lime-shared/vue';
+	import QRCodeProps from './props'
+	// #ifndef APP-NVUE
+	import { getCanvas, isCanvas2d } from './useCanvas'
+	import { QRCodeCanvas } from './qrcode.js';
+	// #endif
+	import { addUnit } from '@/uni_modules/lime-shared/addUnit'
+	import { createImage } from '@/uni_modules/lime-shared/createImage'
+	import { unitConvert } from '@/uni_modules/lime-shared/unitConvert'
+	import { isBase64 } from '@/uni_modules/lime-shared/isBase64'
+	import { pathToBase64 } from '@/uni_modules/lime-shared/pathToBase64'
+	import { debounce } from '@/uni_modules/lime-shared/debounce'
+	const name = 'l-qrcode'
+	export default defineComponent({
+		name,
+		props: QRCodeProps,
+		emits: ['success'],
+		setup(props, {emit}) {
+			const context = getCurrentInstance();
+			const canvasId = `l-qrcode${context.uid}` 
+			const styles = computed(() => `width: ${addUnit(props.size)}; height: ${addUnit(props.size)};`)
+			let qrcode = null
+			let canvas = null
+			const qrCodeProps = computed(() => {
+				const { value, icon, size, color, bgColor, bordered, iconSize, errorLevel, marginSize } = props
+				const imageSettings = {
+					src: icon,
+					x: undefined,
+					y: undefined,
+					height: unitConvert(iconSize),
+					width: unitConvert(iconSize),
+					excavate: true,
+				}
+				return {
+					value,
+					size: unitConvert(size),
+					level: errorLevel,
+					bgColor,
+					fgColor: color,
+					imageSettings: icon ? imageSettings : undefined,
+					includeMargin: bordered,
+					marginSize: marginSize ?? 0
+				}
+
+			})
+			
+			// #ifdef APP-NVUE
+			const stacks = new Map()
+			// #endif
+			const canvasToTempFilePath = debounce((args: UniNamespace.CanvasToTempFilePathRes) => {
+				if(!canvas) return
+				// #ifndef APP-NVUE
+				const copyArgs = Object.assign({
+					canvasId,
+					canvas: null
+				}, args)
+				
+				if (isCanvas2d) {
+					copyArgs.canvas = canvas
+				}
+				if ('toTempFilePath' in canvas) {
+					canvas.toTempFilePath(copyArgs)
+				} else {
+					uni.canvasToTempFilePath(copyArgs, context);
+				}
+				// #endif
+				// #ifdef APP-NVUE
+				if(!stacks.size) {
+					const flie = 'file-' + Math.random();
+					const stack = {args, time: +new Date()}
+					stacks.set(`${flie}`, stack)
+					canvas.toDataURL(flie)
+					setTimeout(() => {
+						const stack = stacks.get(flie)
+						if(stack && 'fail' in stack.args) {
+							stack.args.fail({
+								error: '超时'
+							})
+							stacks.delete(flie)
+						}
+					},5000)
+				} 
+				// #endif
+			})
+			const useCanvasToTempFilePath = () => {
+				if(props.useCanvasToTempFilePath) {
+					canvasToTempFilePath({
+						success(res: UniNamespace.CanvasToTempFilePathRes) {
+							emit('success', res.tempFilePath)
+						}
+					})
+				}
+			}
+			// #ifdef APP-NVUE
+			const onFinished = () => {
+				const { pixelRatio } = uni.getSystemInfoSync()
+				canvas = {
+					toDataURL(flie: string) {
+						const ref: any = context.refs['qrcodeRef'];
+						if(ref) {
+							ref?.evalJS(`toDataURL('${flie}')`)
+						}
+					}
+				};
+				qrcode = {
+					async render(props: any) {
+						const ref: any = context.refs['qrcodeRef'];
+						const { src } = props.imageSettings || { };
+						if(!ref) return
+						if(src && !isBase64(src) && !/^http/.test(src) && /^\/static/.test(src)) {
+							props.imageSettings.src = await pathToBase64(src)
+						}
+						const _props = JSON.stringify(Object.assign({}, props, {pixelRatio}));
+						ref?.evalJS(`render(${_props})`);
+					}
+				}
+				qrcode.render(qrCodeProps.value)
+				useCanvasToTempFilePath()
+			}
+			const onError = () => {
+				console.warn('lime-qrcode 加载失败')
+			}
+			const onMessage = (e: any) => {
+				const {detail:{data: [res]}} = e
+				if(res.event == 'toDataURL') {
+					const {file, image, msg} = res.data;
+					const stack = stacks.get(file)
+					if(stack && image && 'success' in stack.args) {
+						stack.args.success({tempFilePath: image})
+						stacks.delete(file)
+					} else if(stack && 'fails' in stack.args) {
+						stack.args.fail({error: msg})
+						stacks.delete(file)
+					}
+				} 
+			}
+			// #endif
+			const propsWatch = watch(props, () => {
+				if (qrcode) {
+					qrcode.render(qrCodeProps.value)
+					useCanvasToTempFilePath()
+				}
+			})
+			onMounted(() => {
+				// #ifndef APP-NVUE
+				getCanvas(canvasId, { context }).then(res => {
+					canvas = res
+					qrcode = new QRCodeCanvas(res, {
+						// #ifdef H5
+						path2D: false,
+						// #endif
+						pixelRatio: isCanvas2d ? uni.getSystemInfoSync().pixelRatio : 1,
+						createImage
+					})
+					qrcode.render(qrCodeProps.value)
+					useCanvasToTempFilePath()
+				})
+				// #endif
+			})
+			onUnmounted(() => {
+				propsWatch && propsWatch()
+			})
+			return {
+				canvasId,
+				styles,
+				props,
+				canvasToTempFilePath,
+				
+				// #ifdef APP-NVUE
+				onFinished,
+				onError,
+				onMessage
+				// #endif
+			}
+		}
+	})
+</script>
+<style lang="scss">
+	.l-qrcode {
+		position: relative;
+
+		&-mask {
+			position: absolute;
+			inset: 0;
+			// inset-block-start: 0;
+			// inset-inline-start: 0;
+			z-index: 10;
+			display: flex;
+			flex-direction: column;
+			justify-content: center;
+			align-items: center;
+			// width: 100%;
+			// height: 100%;
+			color: rgba(0, 0, 0, 0.88);
+			line-height: 1.5714285714285714;
+			background: rgba(255, 255, 255, 0.96);
+			text-align: center;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/components/l-qrcode/props.ts b/uni_modules/lime-qrcode/components/l-qrcode/props.ts
new file mode 100644
index 0000000..fb4d101
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/l-qrcode/props.ts
@@ -0,0 +1,36 @@
+// @ts-nocheck
+// import type { PropType } from './vue'
+export default {
+	value: String,
+	icon: String,
+	size: {
+		type: [Number, String],
+		default: 160
+	},
+	iconSize: {
+		type: [Number, String],
+		default: 40
+	},
+	marginSize: Number,
+	color: {
+		type: String,
+		default: '#000'
+	},
+	bgColor: {
+		type: String,
+		default: 'transparent'
+	},
+	bordered: {
+		type: Boolean,
+		default: true
+	},
+	errorLevel: {
+		type: String as PropType<'L'|'M'|'Q'|'H'>,
+		default: 'M' // 'L' | 'M' | 'Q' | 'H'
+	},
+	useCanvasToTempFilePath: Boolean
+	// status: {
+	// 	type: String as PropType<'active'|'expired'|'loading'>,
+	// 	default: 'active' // active | expired | loading
+	// }
+}
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/components/l-qrcode/qrcode.js b/uni_modules/lime-qrcode/components/l-qrcode/qrcode.js
new file mode 100644
index 0000000..b04047b
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/l-qrcode/qrcode.js
@@ -0,0 +1,6 @@
+function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var n=0;t.length>n;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function n(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function r(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);t>n;n++)r[n]=e[n];return r}function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,o=function(){};return{s:o,n:function(){return e.length>r?{done:!1,value:e[r++]}:{done:!0}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,u=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){u=!0,a=e},f:function(){try{s||null==n.return||n.return()}finally{if(u)throw a}}}}
+/**
+ * @license QR Code generator library (TypeScript)
+ * Copyright (c) Project Nayuki.
+ * SPDX-License-Identifier: MIT
+ */var a;!function(t){var r=function(){function r(t,n,i,o){if(e(this,r),this.version=void 0,this.errorCorrectionLevel=void 0,this.size=void 0,this.mask=void 0,this.modules=[],this.isFunction=[],this.version=t,this.errorCorrectionLevel=n,r.MIN_VERSION>t||t>r.MAX_VERSION)throw new RangeError("Version value out of range");if(-1>o||o>7)throw new RangeError("Mask value out of range");this.size=4*t+17;for(var a=[],u=0;this.size>u;u++)a.push(!1);for(var l=0;this.size>l;l++)this.modules.push(a.slice()),this.isFunction.push(a.slice());this.drawFunctionPatterns();var h=this.addEccAndInterleave(i);if(this.drawCodewords(h),-1==o)for(var c=1e9,f=0;8>f;f++){this.applyMask(f),this.drawFormatBits(f);var v=this.getPenaltyScore();c>v&&(o=f,c=v),this.applyMask(f)}s(o>=0&&7>=o),this.mask=o,this.applyMask(o),this.drawFormatBits(o),this.isFunction=[]}return n(r,[{key:"getModule",value:function(e,t){return e>=0&&this.size>e&&t>=0&&this.size>t&&this.modules[t][e]}},{key:"getModules",value:function(){return this.modules}},{key:"drawFunctionPatterns",value:function(){for(var e=0;this.size>e;e++)this.setFunctionModule(6,e,e%2==0),this.setFunctionModule(e,6,e%2==0);this.drawFinderPattern(3,3),this.drawFinderPattern(this.size-4,3),this.drawFinderPattern(3,this.size-4);for(var t=this.getAlignmentPatternPositions(),n=t.length,r=0;n>r;r++)for(var i=0;n>i;i++)0==r&&0==i||0==r&&i==n-1||r==n-1&&0==i||this.drawAlignmentPattern(t[r],t[i]);this.drawFormatBits(0),this.drawVersion()}},{key:"drawFormatBits",value:function(e){for(var t=this.errorCorrectionLevel.formatBits<<3|e,n=t,r=0;10>r;r++)n=n<<1^1335*(n>>>9);var i=21522^(t<<10|n);s(i>>>15==0);for(var o=0;5>=o;o++)this.setFunctionModule(8,o,a(i,o));this.setFunctionModule(8,7,a(i,6)),this.setFunctionModule(8,8,a(i,7)),this.setFunctionModule(7,8,a(i,8));for(var u=9;15>u;u++)this.setFunctionModule(14-u,8,a(i,u));for(var l=0;8>l;l++)this.setFunctionModule(this.size-1-l,8,a(i,l));for(var h=8;15>h;h++)this.setFunctionModule(8,this.size-15+h,a(i,h));this.setFunctionModule(8,this.size-8,!0)}},{key:"drawVersion",value:function(){if(this.version>=7){for(var e=this.version,t=0;12>t;t++)e=e<<1^7973*(e>>>11);var n=this.version<<12|e;s(n>>>18==0);for(var r=0;18>r;r++){var i=a(n,r),o=this.size-11+r%3,u=Math.floor(r/3);this.setFunctionModule(o,u,i),this.setFunctionModule(u,o,i)}}}},{key:"drawFinderPattern",value:function(e,t){for(var n=-4;4>=n;n++)for(var r=-4;4>=r;r++){var i=Math.max(Math.abs(r),Math.abs(n)),o=e+r,a=t+n;o>=0&&this.size>o&&a>=0&&this.size>a&&this.setFunctionModule(o,a,2!=i&&4!=i)}}},{key:"drawAlignmentPattern",value:function(e,t){for(var n=-2;2>=n;n++)for(var r=-2;2>=r;r++)this.setFunctionModule(e+r,t+n,1!=Math.max(Math.abs(r),Math.abs(n)))}},{key:"setFunctionModule",value:function(e,t,n){this.modules[t][e]=n,this.isFunction[t][e]=!0}},{key:"addEccAndInterleave",value:function(e){var t=this.version,n=this.errorCorrectionLevel;if(e.length!=r.getNumDataCodewords(t,n))throw new RangeError("Invalid argument");for(var i=r.NUM_ERROR_CORRECTION_BLOCKS[n.ordinal][t],o=r.ECC_CODEWORDS_PER_BLOCK[n.ordinal][t],a=Math.floor(r.getNumRawDataModules(t)/8),u=i-a%i,l=Math.floor(a/i),h=[],c=r.reedSolomonComputeDivisor(o),f=0,v=0;i>f;f++){var d=e.slice(v,v+l-o+(u>f?0:1));v+=d.length;var m=r.reedSolomonComputeRemainder(d,c);u>f&&d.push(0),h.push(d.concat(m))}for(var g=[],y=function(e){h.forEach((function(t,n){e==l-o&&u>n||g.push(t[e])}))},E=0;h[0].length>E;E++)y(E);return s(g.length==a),g}},{key:"drawCodewords",value:function(e){if(e.length!=Math.floor(r.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");for(var t=0,n=this.size-1;n>=1;n-=2){6==n&&(n=5);for(var i=0;this.size>i;i++)for(var o=0;2>o;o++){var u=n-o,l=0==(n+1&2)?this.size-1-i:i;!this.isFunction[l][u]&&8*e.length>t&&(this.modules[l][u]=a(e[t>>>3],7-(7&t)),t++)}}s(t==8*e.length)}},{key:"applyMask",value:function(e){if(0>e||e>7)throw new RangeError("Mask value out of range");for(var t=0;this.size>t;t++)for(var n=0;this.size>n;n++){var r=void 0;switch(e){case 0:r=(n+t)%2==0;break;case 1:r=t%2==0;break;case 2:r=n%3==0;break;case 3:r=(n+t)%3==0;break;case 4:r=(Math.floor(n/3)+Math.floor(t/2))%2==0;break;case 5:r=n*t%2+n*t%3==0;break;case 6:r=(n*t%2+n*t%3)%2==0;break;case 7:r=((n+t)%2+n*t%3)%2==0;break;default:throw Error("Unreachable")}!this.isFunction[t][n]&&r&&(this.modules[t][n]=!this.modules[t][n])}}},{key:"getPenaltyScore",value:function(){for(var e=0,t=0;this.size>t;t++){for(var n=!1,i=0,a=[0,0,0,0,0,0,0],u=0;this.size>u;u++)this.modules[t][u]==n?5==++i?e+=r.PENALTY_N1:i>5&&e++:(this.finderPenaltyAddHistory(i,a),n||(e+=this.finderPenaltyCountPatterns(a)*r.PENALTY_N3),n=this.modules[t][u],i=1);e+=this.finderPenaltyTerminateAndCount(n,i,a)*r.PENALTY_N3}for(var l=0;this.size>l;l++){for(var h=!1,c=0,f=[0,0,0,0,0,0,0],v=0;this.size>v;v++)this.modules[v][l]==h?5==++c?e+=r.PENALTY_N1:c>5&&e++:(this.finderPenaltyAddHistory(c,f),h||(e+=this.finderPenaltyCountPatterns(f)*r.PENALTY_N3),h=this.modules[v][l],c=1);e+=this.finderPenaltyTerminateAndCount(h,c,f)*r.PENALTY_N3}for(var d=0;this.size-1>d;d++)for(var m=0;this.size-1>m;m++){var g=this.modules[d][m];g==this.modules[d][m+1]&&g==this.modules[d+1][m]&&g==this.modules[d+1][m+1]&&(e+=r.PENALTY_N2)}var y,E=0,w=o(this.modules);try{for(w.s();!(y=w.n()).done;){E=y.value.reduce((function(e,t){return e+(t?1:0)}),E)}}catch(e){w.e(e)}finally{w.f()}var M=this.size*this.size,C=Math.ceil(Math.abs(20*E-10*M)/M)-1;return s(C>=0&&9>=C),s((e+=C*r.PENALTY_N4)>=0&&2568888>=e),e}},{key:"getAlignmentPatternPositions",value:function(){if(1==this.version)return[];for(var e=Math.floor(this.version/7)+2,t=32==this.version?26:2*Math.ceil((4*this.version+4)/(2*e-2)),n=[6],r=this.size-7;e>n.length;r-=t)n.splice(1,0,r);return n}},{key:"finderPenaltyCountPatterns",value:function(e){var t=e[1];s(3*this.size>=t);var n=t>0&&e[2]==t&&e[3]==3*t&&e[4]==t&&e[5]==t;return(!n||4*t>e[0]||t>e[6]?0:1)+(!n||4*t>e[6]||t>e[0]?0:1)}},{key:"finderPenaltyTerminateAndCount",value:function(e,t,n){return e&&(this.finderPenaltyAddHistory(t,n),t=0),this.finderPenaltyAddHistory(t+=this.size,n),this.finderPenaltyCountPatterns(n)}},{key:"finderPenaltyAddHistory",value:function(e,t){0==t[0]&&(e+=this.size),t.pop(),t.unshift(e)}}],[{key:"encodeText",value:function(e,n){var i=t.QrSegment.makeSegments(e);return r.encodeSegments(i,n)}},{key:"encodeBinary",value:function(e,n){var i=t.QrSegment.makeBytes(e);return r.encodeSegments([i],n)}},{key:"encodeSegments",value:function(e,t){var n,a,l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,h=arguments.length>3&&void 0!==arguments[3]?arguments[3]:40,c=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1,f=5>=arguments.length||void 0===arguments[5]||arguments[5];if(r.MIN_VERSION>l||l>h||h>r.MAX_VERSION||-1>c||c>7)throw new RangeError("Invalid value");for(n=l;;n++){var v=8*r.getNumDataCodewords(n,t),d=u.getTotalBits(e,n);if(v>=d){a=d;break}if(n>=h)throw new RangeError("Data too long")}for(var m=0,g=[r.Ecc.MEDIUM,r.Ecc.QUARTILE,r.Ecc.HIGH];g.length>m;m++){var y=g[m];f&&a<=8*r.getNumDataCodewords(n,y)&&(t=y)}var E,w=[],M=o(e);try{for(M.s();!(E=M.n()).done;){var C=E.value;i(C.mode.modeBits,4,w),i(C.numChars,C.mode.numCharCountBits(n),w);var R,A=o(C.getData());try{for(A.s();!(R=A.n()).done;){var p=R.value;w.push(p)}}catch(e){A.e(e)}finally{A.f()}}}catch(e){M.e(e)}finally{M.f()}s(w.length==a);var P=8*r.getNumDataCodewords(n,t);s(P>=w.length),i(0,Math.min(4,P-w.length),w),i(0,(8-w.length%8)%8,w),s(w.length%8==0);for(var N=236;P>w.length;N^=253)i(N,8,w);for(var k=[];w.length>8*k.length;)k.push(0);return w.forEach((function(e,t){return k[t>>>3]|=e<<7-(7&t)})),new r(n,t,k,c)}},{key:"getNumRawDataModules",value:function(e){if(r.MIN_VERSION>e||e>r.MAX_VERSION)throw new RangeError("Version number out of range");var t=(16*e+128)*e+64;if(e>=2){var n=Math.floor(e/7)+2;t-=(25*n-10)*n-55,7>e||(t-=36)}return s(t>=208&&29648>=t),t}},{key:"getNumDataCodewords",value:function(e,t){return Math.floor(r.getNumRawDataModules(e)/8)-r.ECC_CODEWORDS_PER_BLOCK[t.ordinal][e]*r.NUM_ERROR_CORRECTION_BLOCKS[t.ordinal][e]}},{key:"reedSolomonComputeDivisor",value:function(e){if(1>e||e>255)throw new RangeError("Degree out of range");for(var t=[],n=0;e-1>n;n++)t.push(0);t.push(1);for(var i=1,o=0;e>o;o++){for(var a=0;t.length>a;a++)t[a]=r.reedSolomonMultiply(t[a],i),t.length>a+1&&(t[a]^=t[a+1]);i=r.reedSolomonMultiply(i,2)}return t}},{key:"reedSolomonComputeRemainder",value:function(e,t){var n,i=t.map((function(e){return 0})),a=o(e);try{var s=function(){var e=n.value^i.shift();i.push(0),t.forEach((function(t,n){return i[n]^=r.reedSolomonMultiply(t,e)}))};for(a.s();!(n=a.n()).done;)s()}catch(e){a.e(e)}finally{a.f()}return i}},{key:"reedSolomonMultiply",value:function(e,t){if(e>>>8!=0||t>>>8!=0)throw new RangeError("Byte out of range");for(var n=0,r=7;r>=0;r--)n=n<<1^285*(n>>>7),n^=(t>>>r&1)*e;return s(n>>>8==0),n}}]),r}();function i(e,t,n){if(0>t||t>31||e>>>t!=0)throw new RangeError("Value out of range");for(var r=t-1;r>=0;r--)n.push(e>>>r&1)}function a(e,t){return 0!=(e>>>t&1)}function s(e){if(!e)throw Error("Assertion error")}r.MIN_VERSION=1,r.MAX_VERSION=40,r.PENALTY_N1=3,r.PENALTY_N2=3,r.PENALTY_N3=40,r.PENALTY_N4=10,r.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],r.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],t.QrCode=r;var u=function(){function t(n,r,i){if(e(this,t),this.mode=void 0,this.numChars=void 0,this.bitData=void 0,this.mode=n,this.numChars=r,this.bitData=i,0>r)throw new RangeError("Invalid argument");this.bitData=i.slice()}return n(t,[{key:"getData",value:function(){return this.bitData.slice()}}],[{key:"makeBytes",value:function(e){var n,r=[],a=o(e);try{for(a.s();!(n=a.n()).done;){i(n.value,8,r)}}catch(e){a.e(e)}finally{a.f()}return new t(t.Mode.BYTE,e.length,r)}},{key:"makeNumeric",value:function(e){if(!t.isNumeric(e))throw new RangeError("String contains non-numeric characters");for(var n=[],r=0;e.length>r;){var o=Math.min(e.length-r,3);i(parseInt(e.substring(r,r+o),10),3*o+1,n),r+=o}return new t(t.Mode.NUMERIC,e.length,n)}},{key:"makeAlphanumeric",value:function(e){if(!t.isAlphanumeric(e))throw new RangeError("String contains unencodable characters in alphanumeric mode");var n,r=[];for(n=0;e.length>=n+2;n+=2){var o=45*t.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n));i(o+=t.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n+1)),11,r)}return e.length>n&&i(t.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n)),6,r),new t(t.Mode.ALPHANUMERIC,e.length,r)}},{key:"makeSegments",value:function(e){return""==e?[]:t.isNumeric(e)?[t.makeNumeric(e)]:t.isAlphanumeric(e)?[t.makeAlphanumeric(e)]:[t.makeBytes(t.toUtf8ByteArray(e))]}},{key:"makeEci",value:function(e){var n=[];if(0>e)throw new RangeError("ECI assignment value out of range");if(128>e)i(e,8,n);else if(16384>e)i(2,2,n),i(e,14,n);else{if(e>=1e6)throw new RangeError("ECI assignment value out of range");i(6,3,n),i(e,21,n)}return new t(t.Mode.ECI,0,n)}},{key:"isNumeric",value:function(e){return t.NUMERIC_REGEX.test(e)}},{key:"isAlphanumeric",value:function(e){return t.ALPHANUMERIC_REGEX.test(e)}},{key:"getTotalBits",value:function(e,t){var n,r=0,i=o(e);try{for(i.s();!(n=i.n()).done;){var a=n.value,s=a.mode.numCharCountBits(t);if(a.numChars>=1<<s)return 1/0;r+=4+s+a.bitData.length}}catch(e){i.e(e)}finally{i.f()}return r}},{key:"toUtf8ByteArray",value:function(e){e=encodeURI(e);for(var t=[],n=0;e.length>n;n++)"%"!=e.charAt(n)?t.push(e.charCodeAt(n)):(t.push(parseInt(e.substring(n+1,n+3),16)),n+=2);return t}}]),t}();u.NUMERIC_REGEX=/^[0-9]*$/,u.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,u.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",t.QrSegment=u}(a||(a={})),function(t){!function(t){var r=n((function t(n,r){e(this,t),this.ordinal=void 0,this.formatBits=void 0,this.ordinal=n,this.formatBits=r}));r.LOW=new r(0,1),r.MEDIUM=new r(1,0),r.QUARTILE=new r(2,3),r.HIGH=new r(3,2),t.Ecc=r}(t.QrCode||(t.QrCode={}))}(a||(a={})),function(t){!function(t){var r=function(){function t(n,r){e(this,t),this.modeBits=void 0,this.numBitsCharCount=void 0,this.modeBits=n,this.numBitsCharCount=r}return n(t,[{key:"numCharCountBits",value:function(e){return this.numBitsCharCount[Math.floor((e+7)/17)]}}]),t}();r.NUMERIC=new r(1,[10,12,14]),r.ALPHANUMERIC=new r(2,[9,11,13]),r.BYTE=new r(4,[8,16,16]),r.KANJI=new r(8,[8,10,12]),r.ECI=new r(7,[0,0,0]),t.Mode=r}(t.QrSegment||(t.QrSegment={}))}(a||(a={}));var s=a,u=["value","size","level","bgColor","fgColor","includeMargin","marginSize","imageSettings"],l={L:s.QrCode.Ecc.LOW,M:s.QrCode.Ecc.MEDIUM,Q:s.QrCode.Ecc.QUARTILE,H:s.QrCode.Ecc.HIGH};function h(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=[];return e.forEach((function(e,r){var i=null;e.forEach((function(o,a){if(!o&&null!==i)return n.push("M".concat(i+t," ").concat(r+t,"h").concat(a-i,"v1H").concat(i+t,"z")),void(i=null);if(a!==e.length-1)o&&null===i&&(i=a);else{if(!o)return;n.push(null===i?"M".concat(a+t,",").concat(r+t," h1v1H").concat(a+t,"z"):"M".concat(i+t,",").concat(r+t," h").concat(a+1-i,"v1H").concat(i+t,"z"))}}))})),n.join("")}function c(e,t){return e.slice().map((function(e,n){return t.y>n||n>=t.y+t.h?e:e.map((function(e,n){return(t.x>n||n>=t.x+t.w)&&e}))}))}var f=function(){function t(n,r){var i=this;for(var o in e(this,t),this.canvas=void 0,this.pixelRatio="undefined"!=typeof window?window.devicePixelRatio:1,this.path2D=!0,this.SUPPORTS_PATH2D=void 0,this.createImage=function(){return new Image},this.createPath2D=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,t="createPath2D";return i.canvas&&t in i.canvas?i.canvas[t](e):new Path2D(e)},this.canvas=n,r)o in this&&(this[o]=r[o]);this.SUPPORTS_PATH2D=function(){try{i.createPath2D()}catch(e){return!1}return!0}()}return n(t,[{key:"render",value:function(e,t){var n=this,i=e.value,o=e.size,a=void 0===o?128:o,f=e.level,v=void 0===f?"L":f,d=e.bgColor,m=void 0===d?"#FFFFFF":d,g=e.fgColor,y=void 0===g?"#000000":g,E=e.includeMargin,w=void 0!==E&&E,M=e.marginSize,C=e.imageSettings,R=(r(e,u),null==C?void 0:C.src),A=this.canvas,p=A.getContext("2d");if(p&&i){var P=s.QrCode.encodeText(i,l[v]).getModules(),N=function(e,t){return null!=t?Math.floor(t):e?4:0}(w,M),k=P.length+2*N,S=function(e,t,n,r){if(null==r)return null;var i=e.length+2*n,o=Math.floor(.1*t),a=i/t,s=(r.width||o)*a,u=(r.height||o)*a,l=null==r.x?e.length/2-s/2:r.x*a,h=null==r.y?e.length/2-u/2:r.y*a,c=null;if(r.excavate){var f=Math.floor(l),v=Math.floor(h);c={x:f,y:v,w:Math.ceil(s+l-f),h:Math.ceil(u+h-v)}}return{x:l,y:h,h:u,w:s,excavation:c}}(P,a,N,C),I=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=null!=S&&null!==e&&e.complete&&0!==e.naturalHeight&&0!==e.naturalWidth;r&&null!=S.excavation&&(P=c(P,S.excavation)),t&&t(P);var i=n.pixelRatio;p.clearRect(0,0,A.width,A.height),p.setTransform(1,0,0,1,0,0),A.height=A.width=a*i;var o=a/k*i;if(p.scale(o,o),p.fillStyle=m,p.fillRect(0,0,k,k),p.fillStyle=y,n.SUPPORTS_PATH2D&&n.path2D){var s=n.createPath2D(h(P,N));p.fill(s)}else P.forEach((function(e,t){e.forEach((function(e,n){e&&p.fillRect(n+N,t+N,1,1)}))}));var u=(null==e?void 0:e.path)||e;r&&p.drawImage(u,S.x+N,S.y+N,S.w,S.h),"draw"in p&&p.draw()};if(R){var b=this.createImage(A);b.onload=function(){I(b)},b.onerror=function(e){I(),console.warn(e)},b.src=R}else I()}}}]),t}();export{f as QRCodeCanvas};
diff --git a/uni_modules/lime-qrcode/components/l-qrcode/type.ts b/uni_modules/lime-qrcode/components/l-qrcode/type.ts
new file mode 100644
index 0000000..8a1556b
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/l-qrcode/type.ts
@@ -0,0 +1,48 @@
+// @ts-nocheck
+export type ImageSettings = {
+	width: number
+	height: number
+	x?: number
+	y?: number
+	excavate: boolean
+}
+export type QRCodePropsTypes = {
+	value?: string
+	size?: number
+	fgColor?: string
+	level?: string
+	marginSize: number
+	includeMargin: boolean
+	imageSettings?: ImageSettings
+}
+
+export type QRCodeCallback = (cells : boolean[][]) => void
+
+export type Excavation = {
+	x: number
+	y: number
+	h: number
+	w: number
+}
+
+
+
+
+
+/**
+ * 成功回调函数定义
+ */
+export type TakeSnapshotSuccessCallback = (res: TakeSnapshotSuccess) => void
+/**
+ * 失败回调函数定义
+ */
+export type TakeSnapshotFailCallback = (res: TakeSnapshotFail) => void
+/**
+ * 完成回调函数定义
+ */
+export type TakeSnapshotCompleteCallback = (res: any) => void
+
+
+export type LQrcodeFailCallback = TakeSnapshotFailCallback
+export type LQrcodeCompleteCallback = TakeSnapshotCompleteCallback
+export type LQrcodeSuccessCallback  = TakeSnapshotSuccessCallback
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts b/uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts
new file mode 100644
index 0000000..78ce660
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts
@@ -0,0 +1,78 @@
+
+// @ts-nocheck
+import type { ComponentInternalInstance } from '@/uni_modules/lime-shared/vue'
+import { getRect } from '@/uni_modules/lime-shared/getRect'
+import { canIUseCanvas2d } from '@/uni_modules/lime-shared/canIUseCanvas2d'
+export const isCanvas2d = canIUseCanvas2d()
+
+export async function getCanvas(canvasId: string, options: {context: ComponentInternalInstance}) {
+	let { context } = options
+	// #ifdef MP || VUE2
+	if (context.proxy) context = context.proxy
+	// #endif
+	return getRect('#' + canvasId, context, isCanvas2d).then(res => {
+		if(res.node){
+			return res.node
+		} else {
+			const ctx = uni.createCanvasContext(canvasId, context)
+			return {
+				getContext(type: string) {
+					if(type == '2d') {
+						return ctx
+					}
+				},
+				width: res.width,
+				height: res.height,
+			}
+			// #ifdef H5
+			// canvas.value = context.proxy.$el.querySelector('#'+ canvasId)
+			// #endif
+		}
+	})
+}
+
+// #ifndef H5 || APP-NVUE
+class Image {
+	currentSrc: string | null = null
+	naturalHeight: number = 0
+	naturalWidth: number = 0
+	width: number = 0
+	height: number = 0
+	tagName: string = 'IMG'
+	path: any = ''
+	crossOrigin: any = ''
+	referrerPolicy: any = ''
+	onload: () => void
+	onerror: () => void
+	constructor() {}
+	set src(src) {
+		this.currentSrc = src
+		uni.getImageInfo({
+			src,
+			success: (res) => {
+				this.path = res.path
+				this.naturalWidth = this.width = res.width
+				this.naturalHeight = this.height = res.height
+				this.onload()
+			},
+			fail: () => {
+				this.onerror()
+			}
+		})
+	}
+	get src() {
+		return this.currentSrc
+	}
+}
+// #endif
+
+export function createImage(canvas: WechatMiniprogram.Canvas) {
+	if(canvas && canvas.createImage) {
+		return canvas.createImage()
+	} else if(typeof window != 'undefined' && window.Image) {
+		return new window.Image()
+	}
+	// #ifndef H5 || APP-NVUE
+	return new Image()
+	// #endif
+}
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/components/l-qrcode/utils.uts b/uni_modules/lime-qrcode/components/l-qrcode/utils.uts
new file mode 100644
index 0000000..a88a930
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/l-qrcode/utils.uts
@@ -0,0 +1,35 @@
+export function addUnit(value: any|null):string{
+	if(value == null){
+		return ''
+	}
+	value = `${value}` 
+	return /^(-)?\d+(\\.\d+)?$/.test(value) ?  `${value}px` : value
+}
+
+export function unitConvert(value: any|null): number{
+	if(typeof value == 'number'){
+		return value as number
+	}
+	if(typeof value == 'string'){
+		value = `${value}` 
+		if(/^(-)?\d+(\\.\d+)?$/.test(value)){
+			return parseFloat(value);
+		}
+		
+		const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g;
+		const results = reg.exec(value);
+		if (results == null) {
+			return 0;
+		}
+		const unit = results[3];
+		const v = parseFloat(value);
+		if (unit == 'rpx') {
+			const { windowWidth } = uni.getWindowInfo()
+			return windowWidth / 750 * v;
+		}
+		if (unit == 'px') {
+			return v;
+		}
+	}
+	return 0;
+}
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.uvue b/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.uvue
new file mode 100644
index 0000000..93e10d2
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.uvue
@@ -0,0 +1,140 @@
+<template>
+	<view class="demo-block">
+		<text class="demo-block__title-text ultra">QRCode</text>
+		<text class="demo-block__desc-text">能够将文本转换生成二维码的组件,支持自定义配色和 Logo 配置</text>	
+		<view class="demo-block__body">
+			<view class="demo-block card">
+				<text class="demo-block__title-text large">基础</text>
+				<view class="demo-block__body">
+					<l-qrcode value="https://limeui.qcoon.cn" size="300rpx"></l-qrcode>
+				</view>	
+			</view>	
+			
+			<view class="demo-block card">
+				<text class="demo-block__title-text large">icon</text>
+				<view class="demo-block__body">
+					<image v-if="image !=''" :src="image" style="width: 300rpx;" mode="widthFix"></image>
+					<view style="flex-direction: row; justify-content: space-between">
+						<l-qrcode ref="qrcodeRef" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
+						<l-qrcode :useCanvasToTempFilePath="true" @success="success" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
+					</view>
+					<button type="primary" style="margin-top: 20rpx;" @click="onClick">生成图片</button>
+				</view>	
+			</view>
+			
+			<view class="demo-block card">
+				<text class="demo-block__title-text large">颜色</text>
+				<view class="demo-block__body">
+					<view style="flex-direction: row; justify-content: space-between">
+						<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(82,196,26)"></l-qrcode>
+						<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(22,119,255)" bgColor="rgb(245,245,245)"></l-qrcode>
+					</view>	
+				</view>	
+			</view>
+			
+			<view class="demo-block card">
+				<text class="demo-block__title-text large">纠错比例</text>
+				<view class="demo-block__body">
+					<l-qrcode value="img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" size="300rpx" :errorLevel="levels[index]"></l-qrcode>
+					<button type="primary" style="margin-top: 20rpx;" @click="onToggle">切换纠错等级:{{levels[index]}}</button>
+				</view>	
+			</view>
+			
+			<view class="demo-block card">
+				<text class="demo-block__title-text large">动态</text>
+				<view class="demo-block__body">
+					<l-qrcode :value="text" size="300rpx" :marginSize="1" bgColor="white"></l-qrcode>
+					<button type="primary" style="margin-top: 20rpx;"  @click="update">更新</button>
+				</view>	
+			</view>
+			
+		</view>	
+	</view>
+	
+</template>
+<script>
+	// import {ComponentPublicInstance} from 'vue'
+	export default {
+		name: 'lime-qrcode',
+		data() {
+			return {
+				text: 'qcoon.com.cn',
+				image: '',
+				index: 0,
+				levels: ['L', 'M', 'Q', 'H']
+			}
+		},
+		methods:{ 
+			success(src: string) {
+				console.log(`src`, src)
+			},
+			update() {
+				this.text =  `qcoon.cn?v=${Math.random()}`
+			},
+			onToggle() {
+				this.index++
+				this.index = this.index % this.levels.length
+			},
+			onClick() {
+				const el:LQrcodeComponentPublicInstance = this.$refs['qrcodeRef'] as LQrcodeComponentPublicInstance 
+				el.canvasToTempFilePath({
+					success:(res: TakeSnapshotSuccess)=>{
+						this.image = res.tempFilePath
+					}
+				})
+			}
+		},
+		mounted() {
+			
+		}
+	}
+</script>
+<style lang="scss">
+	
+	.demo-block {
+		margin: 32px 10px 0;
+		overflow: visible;
+		&.card{
+			background-color: white;
+			padding: 30rpx;
+			margin-bottom: 20rpx;
+		}
+		&__title {
+			margin: 0;
+			margin-top: 8px;
+			&-text {
+				color: rgba(0, 0, 0, 0.6);
+				font-weight: 400;
+				font-size: 14px;
+				line-height: 16px;
+				
+				&.large {
+					color: rgba(0, 0, 0, 0.9);
+					font-size: 18px;
+					font-weight: 700;
+					line-height: 26px;
+				}
+				&.ultra {
+					color: rgba(0, 0, 0, 0.9);
+					font-size: 24px;
+					font-weight: 700;
+					line-height: 32px;
+				}
+			}
+		}
+		&__desc-text {
+			color: rgba(0, 0, 0, 0.6);
+			margin: 8px 16px 0 0;
+			font-size: 14px;
+			line-height: 22px;
+		}
+		&__body {
+			margin: 16px 0;
+			overflow: visible;
+			.demo-block {
+				// margin-top: 0px;
+				margin: 0;
+			}
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.vue b/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.vue
new file mode 100644
index 0000000..113ef87
--- /dev/null
+++ b/uni_modules/lime-qrcode/components/lime-qrcode/lime-qrcode.vue
@@ -0,0 +1,79 @@
+<template>
+	<demo-block title="QRCode" type="ultra">
+		<demo-block title="基础">
+			<l-qrcode value="https://limeui.qcoon.cn" size="300rpx"></l-qrcode>
+		</demo-block>
+		 <demo-block title="icon">
+			<view style="display: flex; gap: 10px">
+				<image v-if="image" :src="image" style="width: 300rpx;" mode="widthFix"></image>
+				<l-qrcode ref="qrcodeRef" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
+				<l-qrcode useCanvasToTempFilePath @success="success" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
+			</view>
+			<button @click="onClick">生成图片</button>
+		</demo-block>
+		<demo-block title="颜色">
+			<view style="display: flex; gap: 10px">
+				<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(82,196,26)"></l-qrcode>
+				<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(22,119,255)" bgColor="rgb(245,245,245)"></l-qrcode>
+			</view>	
+		</demo-block>
+		<demo-block title="纠错比例">
+			<l-qrcode value="img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" size="300rpx" :errorLevel="levels[index]"></l-qrcode>
+			<button @click="onToggle">切换纠错等级:{{levels[index]}}</button>
+		</demo-block>
+		<demo-block title="动态">
+			<l-qrcode :value="text" size="300rpx" :marginSize="1" bgColor="white"></l-qrcode>
+			<button @click="update">更新</button>
+		</demo-block>
+	</demo-block>
+</template>
+<script>
+	import {ref, defineComponent} from '@/uni_modules/lime-shared/vue'
+	export default defineComponent({
+		setup() {
+			const qrcodeRef = ref(null)
+			const image = ref(null)
+			const text = ref('qcoon.com.cn')
+			const levels = ['L', 'M', 'Q', 'H']
+			let index = ref(0)
+			const onToggle = () => {
+				index.value++
+				index.value = index.value % levels.length
+			}
+			const onClick = () => {
+				if(qrcodeRef.value) {
+					qrcodeRef.value.canvasToTempFilePath({
+						success(res) {
+							image.value = res.tempFilePath
+							console.log('success:::', res)
+						},
+						fail(err) {
+							console.log('err:::', err)
+						}
+					})
+				}
+			}
+			const success = (res) => {
+				console.log('res', res)
+			}
+			
+			const update = () =>{
+				text.value =  `qcoon.cn?v=${Math.random()}`
+			}
+			
+			return {
+				levels,
+				index,
+				image,
+				text,
+				qrcodeRef,
+				onClick,
+				update,
+				success,
+				onToggle,
+			}
+		}
+	})
+</script>
+<style>
+</style>
diff --git a/uni_modules/lime-qrcode/hybrid/html/index.html b/uni_modules/lime-qrcode/hybrid/html/index.html
new file mode 100644
index 0000000..bf4def9
--- /dev/null
+++ b/uni_modules/lime-qrcode/hybrid/html/index.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html lang="zh">
+<head>
+	<meta charset="UTF-8">
+	<meta http-equiv="X-UA-Compatible" content="IE=edge">
+	<meta name="viewport" content="width=device-width, initial-scale=1.0">
+	<title>lime-qrcode</title>
+	<style>
+		html,body,canvas {
+			margin: 0;
+			padding: 0;
+			width: 100%;
+			height: 100%;
+			pointer-events: none;
+			/* background-color: rgba(255,0,0,0.1) */
+		}
+	</style>
+</head>
+<body>
+	<canvas id="lime-qrcode"></canvas>
+	<script type="text/javascript" src="./uni.webview.1.5.3.js"></script>
+	<script type="text/javascript" src="./qrcode.min.js"></script>
+	<script>
+		var canvas = document.querySelector('#lime-qrcode')
+		var pixelRatio = window.devicePixelRatio || 1
+		function appendWatermark(image) {
+			emit('append', mark.toDataURL())
+		}
+		
+		var qrcode = new lime.QRCodeCanvas(canvas, {
+			pixelRatio,
+		})
+		function render(props) {
+			if(props.pixelRatio) {
+				pixelRatio = props.pixelRatio
+			}
+			if(qrcode) {
+				qrcode.render(props)
+			} 
+		}
+		function toDataURL(file) {
+			if(qrcode && canvas) {
+				try{
+					const image = canvas.toDataURL()
+					emit('toDataURL', {
+						file,
+						image
+					})
+				}catch(e){
+					emit('toDataURL', {
+						file,
+						msg: e
+					})
+				}
+				
+			} 
+		}
+		function emit(event, data) {
+			postMessage({
+				event,
+				data
+			});
+		};
+		function postMessage(data) {
+			uni.postMessage({
+				data
+			});
+		};
+		// render({
+		// 	content: ['Lime UI'],
+		// 	// rotate: -22,
+		// 	// baseSize: 2,
+		// 	// fontGap: 3
+		// })
+	</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/hybrid/html/qrcode.min.js b/uni_modules/lime-qrcode/hybrid/html/qrcode.min.js
new file mode 100644
index 0000000..a0c79ce
--- /dev/null
+++ b/uni_modules/lime-qrcode/hybrid/html/qrcode.min.js
@@ -0,0 +1,6 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).lime={})}(this,(function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;t.length>n;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function r(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function i(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;o.length>r;r++)0>t.indexOf(n=o[r])&&Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);t>n;n++)r[n]=e[n];return r}function a(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return o(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?o(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return e.length>r?{done:!1,value:e[r++]}:{done:!0}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,u=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){u=!0,a=e},f:function(){try{s||null==n.return||n.return()}finally{if(u)throw a}}}}
+/**
+   * @license QR Code generator library (TypeScript)
+   * Copyright (c) Project Nayuki.
+   * SPDX-License-Identifier: MIT
+   */var s;!function(e){var n=function(){function n(e,r,i,o){if(t(this,n),this.version=void 0,this.errorCorrectionLevel=void 0,this.size=void 0,this.mask=void 0,this.modules=[],this.isFunction=[],this.version=e,this.errorCorrectionLevel=r,n.MIN_VERSION>e||e>n.MAX_VERSION)throw new RangeError("Version value out of range");if(-1>o||o>7)throw new RangeError("Mask value out of range");this.size=4*e+17;for(var a=[],u=0;this.size>u;u++)a.push(!1);for(var l=0;this.size>l;l++)this.modules.push(a.slice()),this.isFunction.push(a.slice());this.drawFunctionPatterns();var h=this.addEccAndInterleave(i);if(this.drawCodewords(h),-1==o)for(var c=1e9,f=0;8>f;f++){this.applyMask(f),this.drawFormatBits(f);var d=this.getPenaltyScore();c>d&&(o=f,c=d),this.applyMask(f)}s(o>=0&&7>=o),this.mask=o,this.applyMask(o),this.drawFormatBits(o),this.isFunction=[]}return r(n,[{key:"getModule",value:function(e,t){return e>=0&&this.size>e&&t>=0&&this.size>t&&this.modules[t][e]}},{key:"getModules",value:function(){return this.modules}},{key:"drawFunctionPatterns",value:function(){for(var e=0;this.size>e;e++)this.setFunctionModule(6,e,e%2==0),this.setFunctionModule(e,6,e%2==0);this.drawFinderPattern(3,3),this.drawFinderPattern(this.size-4,3),this.drawFinderPattern(3,this.size-4);for(var t=this.getAlignmentPatternPositions(),n=t.length,r=0;n>r;r++)for(var i=0;n>i;i++)0==r&&0==i||0==r&&i==n-1||r==n-1&&0==i||this.drawAlignmentPattern(t[r],t[i]);this.drawFormatBits(0),this.drawVersion()}},{key:"drawFormatBits",value:function(e){for(var t=this.errorCorrectionLevel.formatBits<<3|e,n=t,r=0;10>r;r++)n=n<<1^1335*(n>>>9);var i=21522^(t<<10|n);s(i>>>15==0);for(var a=0;5>=a;a++)this.setFunctionModule(8,a,o(i,a));this.setFunctionModule(8,7,o(i,6)),this.setFunctionModule(8,8,o(i,7)),this.setFunctionModule(7,8,o(i,8));for(var u=9;15>u;u++)this.setFunctionModule(14-u,8,o(i,u));for(var l=0;8>l;l++)this.setFunctionModule(this.size-1-l,8,o(i,l));for(var h=8;15>h;h++)this.setFunctionModule(8,this.size-15+h,o(i,h));this.setFunctionModule(8,this.size-8,!0)}},{key:"drawVersion",value:function(){if(this.version>=7){for(var e=this.version,t=0;12>t;t++)e=e<<1^7973*(e>>>11);var n=this.version<<12|e;s(n>>>18==0);for(var r=0;18>r;r++){var i=o(n,r),a=this.size-11+r%3,u=Math.floor(r/3);this.setFunctionModule(a,u,i),this.setFunctionModule(u,a,i)}}}},{key:"drawFinderPattern",value:function(e,t){for(var n=-4;4>=n;n++)for(var r=-4;4>=r;r++){var i=Math.max(Math.abs(r),Math.abs(n)),o=e+r,a=t+n;o>=0&&this.size>o&&a>=0&&this.size>a&&this.setFunctionModule(o,a,2!=i&&4!=i)}}},{key:"drawAlignmentPattern",value:function(e,t){for(var n=-2;2>=n;n++)for(var r=-2;2>=r;r++)this.setFunctionModule(e+r,t+n,1!=Math.max(Math.abs(r),Math.abs(n)))}},{key:"setFunctionModule",value:function(e,t,n){this.modules[t][e]=n,this.isFunction[t][e]=!0}},{key:"addEccAndInterleave",value:function(e){var t=this.version,r=this.errorCorrectionLevel;if(e.length!=n.getNumDataCodewords(t,r))throw new RangeError("Invalid argument");for(var i=n.NUM_ERROR_CORRECTION_BLOCKS[r.ordinal][t],o=n.ECC_CODEWORDS_PER_BLOCK[r.ordinal][t],a=Math.floor(n.getNumRawDataModules(t)/8),u=i-a%i,l=Math.floor(a/i),h=[],c=n.reedSolomonComputeDivisor(o),f=0,d=0;i>f;f++){var v=e.slice(d,d+l-o+(u>f?0:1));d+=v.length;var m=n.reedSolomonComputeRemainder(v,c);u>f&&v.push(0),h.push(v.concat(m))}for(var g=[],y=function(e){h.forEach((function(t,n){e==l-o&&u>n||g.push(t[e])}))},E=0;h[0].length>E;E++)y(E);return s(g.length==a),g}},{key:"drawCodewords",value:function(e){if(e.length!=Math.floor(n.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");for(var t=0,r=this.size-1;r>=1;r-=2){6==r&&(r=5);for(var i=0;this.size>i;i++)for(var a=0;2>a;a++){var u=r-a,l=0==(r+1&2)?this.size-1-i:i;!this.isFunction[l][u]&&8*e.length>t&&(this.modules[l][u]=o(e[t>>>3],7-(7&t)),t++)}}s(t==8*e.length)}},{key:"applyMask",value:function(e){if(0>e||e>7)throw new RangeError("Mask value out of range");for(var t=0;this.size>t;t++)for(var n=0;this.size>n;n++){var r=void 0;switch(e){case 0:r=(n+t)%2==0;break;case 1:r=t%2==0;break;case 2:r=n%3==0;break;case 3:r=(n+t)%3==0;break;case 4:r=(Math.floor(n/3)+Math.floor(t/2))%2==0;break;case 5:r=n*t%2+n*t%3==0;break;case 6:r=(n*t%2+n*t%3)%2==0;break;case 7:r=((n+t)%2+n*t%3)%2==0;break;default:throw Error("Unreachable")}!this.isFunction[t][n]&&r&&(this.modules[t][n]=!this.modules[t][n])}}},{key:"getPenaltyScore",value:function(){for(var e=0,t=0;this.size>t;t++){for(var r=!1,i=0,o=[0,0,0,0,0,0,0],u=0;this.size>u;u++)this.modules[t][u]==r?5==++i?e+=n.PENALTY_N1:i>5&&e++:(this.finderPenaltyAddHistory(i,o),r||(e+=this.finderPenaltyCountPatterns(o)*n.PENALTY_N3),r=this.modules[t][u],i=1);e+=this.finderPenaltyTerminateAndCount(r,i,o)*n.PENALTY_N3}for(var l=0;this.size>l;l++){for(var h=!1,c=0,f=[0,0,0,0,0,0,0],d=0;this.size>d;d++)this.modules[d][l]==h?5==++c?e+=n.PENALTY_N1:c>5&&e++:(this.finderPenaltyAddHistory(c,f),h||(e+=this.finderPenaltyCountPatterns(f)*n.PENALTY_N3),h=this.modules[d][l],c=1);e+=this.finderPenaltyTerminateAndCount(h,c,f)*n.PENALTY_N3}for(var v=0;this.size-1>v;v++)for(var m=0;this.size-1>m;m++){var g=this.modules[v][m];g==this.modules[v][m+1]&&g==this.modules[v+1][m]&&g==this.modules[v+1][m+1]&&(e+=n.PENALTY_N2)}var y,E=0,w=a(this.modules);try{for(w.s();!(y=w.n()).done;){E=y.value.reduce((function(e,t){return e+(t?1:0)}),E)}}catch(e){w.e(e)}finally{w.f()}var M=this.size*this.size,C=Math.ceil(Math.abs(20*E-10*M)/M)-1;return s(C>=0&&9>=C),s((e+=C*n.PENALTY_N4)>=0&&2568888>=e),e}},{key:"getAlignmentPatternPositions",value:function(){if(1==this.version)return[];for(var e=Math.floor(this.version/7)+2,t=32==this.version?26:2*Math.ceil((4*this.version+4)/(2*e-2)),n=[6],r=this.size-7;e>n.length;r-=t)n.splice(1,0,r);return n}},{key:"finderPenaltyCountPatterns",value:function(e){var t=e[1];s(3*this.size>=t);var n=t>0&&e[2]==t&&e[3]==3*t&&e[4]==t&&e[5]==t;return(!n||4*t>e[0]||t>e[6]?0:1)+(!n||4*t>e[6]||t>e[0]?0:1)}},{key:"finderPenaltyTerminateAndCount",value:function(e,t,n){return e&&(this.finderPenaltyAddHistory(t,n),t=0),this.finderPenaltyAddHistory(t+=this.size,n),this.finderPenaltyCountPatterns(n)}},{key:"finderPenaltyAddHistory",value:function(e,t){0==t[0]&&(e+=this.size),t.pop(),t.unshift(e)}}],[{key:"encodeText",value:function(t,r){var i=e.QrSegment.makeSegments(t);return n.encodeSegments(i,r)}},{key:"encodeBinary",value:function(t,r){var i=e.QrSegment.makeBytes(t);return n.encodeSegments([i],r)}},{key:"encodeSegments",value:function(e,t){var r,o,l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,h=arguments.length>3&&void 0!==arguments[3]?arguments[3]:40,c=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1,f=5>=arguments.length||void 0===arguments[5]||arguments[5];if(n.MIN_VERSION>l||l>h||h>n.MAX_VERSION||-1>c||c>7)throw new RangeError("Invalid value");for(r=l;;r++){var d=8*n.getNumDataCodewords(r,t),v=u.getTotalBits(e,r);if(d>=v){o=v;break}if(r>=h)throw new RangeError("Data too long")}for(var m=0,g=[n.Ecc.MEDIUM,n.Ecc.QUARTILE,n.Ecc.HIGH];g.length>m;m++){var y=g[m];f&&o<=8*n.getNumDataCodewords(r,y)&&(t=y)}var E,w=[],M=a(e);try{for(M.s();!(E=M.n()).done;){var C=E.value;i(C.mode.modeBits,4,w),i(C.numChars,C.mode.numCharCountBits(r),w);var R,p=a(C.getData());try{for(p.s();!(R=p.n()).done;){var A=R.value;w.push(A)}}catch(e){p.e(e)}finally{p.f()}}}catch(e){M.e(e)}finally{M.f()}s(w.length==o);var P=8*n.getNumDataCodewords(r,t);s(P>=w.length),i(0,Math.min(4,P-w.length),w),i(0,(8-w.length%8)%8,w),s(w.length%8==0);for(var N=236;P>w.length;N^=253)i(N,8,w);for(var k=[];w.length>8*k.length;)k.push(0);return w.forEach((function(e,t){return k[t>>>3]|=e<<7-(7&t)})),new n(r,t,k,c)}},{key:"getNumRawDataModules",value:function(e){if(n.MIN_VERSION>e||e>n.MAX_VERSION)throw new RangeError("Version number out of range");var t=(16*e+128)*e+64;if(e>=2){var r=Math.floor(e/7)+2;t-=(25*r-10)*r-55,7>e||(t-=36)}return s(t>=208&&29648>=t),t}},{key:"getNumDataCodewords",value:function(e,t){return Math.floor(n.getNumRawDataModules(e)/8)-n.ECC_CODEWORDS_PER_BLOCK[t.ordinal][e]*n.NUM_ERROR_CORRECTION_BLOCKS[t.ordinal][e]}},{key:"reedSolomonComputeDivisor",value:function(e){if(1>e||e>255)throw new RangeError("Degree out of range");for(var t=[],r=0;e-1>r;r++)t.push(0);t.push(1);for(var i=1,o=0;e>o;o++){for(var a=0;t.length>a;a++)t[a]=n.reedSolomonMultiply(t[a],i),t.length>a+1&&(t[a]^=t[a+1]);i=n.reedSolomonMultiply(i,2)}return t}},{key:"reedSolomonComputeRemainder",value:function(e,t){var r,i=t.map((function(e){return 0})),o=a(e);try{var s=function(){var e=r.value^i.shift();i.push(0),t.forEach((function(t,r){return i[r]^=n.reedSolomonMultiply(t,e)}))};for(o.s();!(r=o.n()).done;)s()}catch(e){o.e(e)}finally{o.f()}return i}},{key:"reedSolomonMultiply",value:function(e,t){if(e>>>8!=0||t>>>8!=0)throw new RangeError("Byte out of range");for(var n=0,r=7;r>=0;r--)n=n<<1^285*(n>>>7),n^=(t>>>r&1)*e;return s(n>>>8==0),n}}]),n}();function i(e,t,n){if(0>t||t>31||e>>>t!=0)throw new RangeError("Value out of range");for(var r=t-1;r>=0;r--)n.push(e>>>r&1)}function o(e,t){return 0!=(e>>>t&1)}function s(e){if(!e)throw Error("Assertion error")}n.MIN_VERSION=1,n.MAX_VERSION=40,n.PENALTY_N1=3,n.PENALTY_N2=3,n.PENALTY_N3=40,n.PENALTY_N4=10,n.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],n.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],e.QrCode=n;var u=function(){function e(n,r,i){if(t(this,e),this.mode=void 0,this.numChars=void 0,this.bitData=void 0,this.mode=n,this.numChars=r,this.bitData=i,0>r)throw new RangeError("Invalid argument");this.bitData=i.slice()}return r(e,[{key:"getData",value:function(){return this.bitData.slice()}}],[{key:"makeBytes",value:function(t){var n,r=[],o=a(t);try{for(o.s();!(n=o.n()).done;){i(n.value,8,r)}}catch(e){o.e(e)}finally{o.f()}return new e(e.Mode.BYTE,t.length,r)}},{key:"makeNumeric",value:function(t){if(!e.isNumeric(t))throw new RangeError("String contains non-numeric characters");for(var n=[],r=0;t.length>r;){var o=Math.min(t.length-r,3);i(parseInt(t.substring(r,r+o),10),3*o+1,n),r+=o}return new e(e.Mode.NUMERIC,t.length,n)}},{key:"makeAlphanumeric",value:function(t){if(!e.isAlphanumeric(t))throw new RangeError("String contains unencodable characters in alphanumeric mode");var n,r=[];for(n=0;t.length>=n+2;n+=2){var o=45*e.ALPHANUMERIC_CHARSET.indexOf(t.charAt(n));i(o+=e.ALPHANUMERIC_CHARSET.indexOf(t.charAt(n+1)),11,r)}return t.length>n&&i(e.ALPHANUMERIC_CHARSET.indexOf(t.charAt(n)),6,r),new e(e.Mode.ALPHANUMERIC,t.length,r)}},{key:"makeSegments",value:function(t){return""==t?[]:e.isNumeric(t)?[e.makeNumeric(t)]:e.isAlphanumeric(t)?[e.makeAlphanumeric(t)]:[e.makeBytes(e.toUtf8ByteArray(t))]}},{key:"makeEci",value:function(t){var n=[];if(0>t)throw new RangeError("ECI assignment value out of range");if(128>t)i(t,8,n);else if(16384>t)i(2,2,n),i(t,14,n);else{if(t>=1e6)throw new RangeError("ECI assignment value out of range");i(6,3,n),i(t,21,n)}return new e(e.Mode.ECI,0,n)}},{key:"isNumeric",value:function(t){return e.NUMERIC_REGEX.test(t)}},{key:"isAlphanumeric",value:function(t){return e.ALPHANUMERIC_REGEX.test(t)}},{key:"getTotalBits",value:function(e,t){var n,r=0,i=a(e);try{for(i.s();!(n=i.n()).done;){var o=n.value,s=o.mode.numCharCountBits(t);if(o.numChars>=1<<s)return 1/0;r+=4+s+o.bitData.length}}catch(e){i.e(e)}finally{i.f()}return r}},{key:"toUtf8ByteArray",value:function(e){e=encodeURI(e);for(var t=[],n=0;e.length>n;n++)"%"!=e.charAt(n)?t.push(e.charCodeAt(n)):(t.push(parseInt(e.substring(n+1,n+3),16)),n+=2);return t}}]),e}();u.NUMERIC_REGEX=/^[0-9]*$/,u.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,u.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",e.QrSegment=u}(s||(s={})),function(e){!function(e){var n=r((function e(n,r){t(this,e),this.ordinal=void 0,this.formatBits=void 0,this.ordinal=n,this.formatBits=r}));n.LOW=new n(0,1),n.MEDIUM=new n(1,0),n.QUARTILE=new n(2,3),n.HIGH=new n(3,2),e.Ecc=n}(e.QrCode||(e.QrCode={}))}(s||(s={})),function(e){!function(e){var n=function(){function e(n,r){t(this,e),this.modeBits=void 0,this.numBitsCharCount=void 0,this.modeBits=n,this.numBitsCharCount=r}return r(e,[{key:"numCharCountBits",value:function(e){return this.numBitsCharCount[Math.floor((e+7)/17)]}}]),e}();n.NUMERIC=new n(1,[10,12,14]),n.ALPHANUMERIC=new n(2,[9,11,13]),n.BYTE=new n(4,[8,16,16]),n.KANJI=new n(8,[8,10,12]),n.ECI=new n(7,[0,0,0]),e.Mode=n}(e.QrSegment||(e.QrSegment={}))}(s||(s={}));var u=s,l=["value","size","level","bgColor","fgColor","includeMargin","marginSize","imageSettings"],h={L:u.QrCode.Ecc.LOW,M:u.QrCode.Ecc.MEDIUM,Q:u.QrCode.Ecc.QUARTILE,H:u.QrCode.Ecc.HIGH};function c(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=[];return e.forEach((function(e,r){var i=null;e.forEach((function(o,a){if(!o&&null!==i)return n.push("M".concat(i+t," ").concat(r+t,"h").concat(a-i,"v1H").concat(i+t,"z")),void(i=null);if(a!==e.length-1)o&&null===i&&(i=a);else{if(!o)return;n.push(null===i?"M".concat(a+t,",").concat(r+t," h1v1H").concat(a+t,"z"):"M".concat(i+t,",").concat(r+t," h").concat(a+1-i,"v1H").concat(i+t,"z"))}}))})),n.join("")}function f(e,t){return e.slice().map((function(e,n){return t.y>n||n>=t.y+t.h?e:e.map((function(e,n){return(t.x>n||n>=t.x+t.w)&&e}))}))}var d=function(){function e(n,r){var i=this;for(var o in t(this,e),this.canvas=void 0,this.pixelRatio="undefined"!=typeof window?window.devicePixelRatio:1,this.path2D=!0,this.SUPPORTS_PATH2D=void 0,this.createImage=function(){return new Image},this.createPath2D=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,t="createPath2D";return i.canvas&&t in i.canvas?i.canvas[t](e):new Path2D(e)},this.canvas=n,r)o in this&&(this[o]=r[o]);this.SUPPORTS_PATH2D=function(){try{i.createPath2D()}catch(e){return!1}return!0}()}return r(e,[{key:"render",value:function(e,t){var n=this,r=e.value,o=e.size,a=void 0===o?128:o,s=e.level,d=void 0===s?"L":s,v=e.bgColor,m=void 0===v?"#FFFFFF":v,g=e.fgColor,y=void 0===g?"#000000":g,E=e.includeMargin,w=void 0!==E&&E,M=e.marginSize,C=e.imageSettings,R=(i(e,l),null==C?void 0:C.src),p=this.canvas,A=p.getContext("2d");if(A&&r){var P=u.QrCode.encodeText(r,h[d]).getModules(),N=function(e,t){return null!=t?Math.floor(t):e?4:0}(w,M),k=P.length+2*N,S=function(e,t,n,r){if(null==r)return null;var i=e.length+2*n,o=Math.floor(.1*t),a=i/t,s=(r.width||o)*a,u=(r.height||o)*a,l=null==r.x?e.length/2-s/2:r.x*a,h=null==r.y?e.length/2-u/2:r.y*a,c=null;if(r.excavate){var f=Math.floor(l),d=Math.floor(h);c={x:f,y:d,w:Math.ceil(s+l-f),h:Math.ceil(u+h-d)}}return{x:l,y:h,h:u,w:s,excavation:c}}(P,a,N,C),I=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=null!=S&&null!==e&&e.complete&&0!==e.naturalHeight&&0!==e.naturalWidth;r&&null!=S.excavation&&(P=f(P,S.excavation)),t&&t(P);var i=n.pixelRatio;A.clearRect(0,0,p.width,p.height),A.setTransform(1,0,0,1,0,0),p.height=p.width=a*i;var o=a/k*i;if(A.scale(o,o),A.fillStyle=m,A.fillRect(0,0,k,k),A.fillStyle=y,n.SUPPORTS_PATH2D&&n.path2D){var s=n.createPath2D(c(P,N));A.fill(s)}else P.forEach((function(e,t){e.forEach((function(e,n){e&&A.fillRect(n+N,t+N,1,1)}))}));var u=(null==e?void 0:e.path)||e;r&&A.drawImage(u,S.x+N,S.y+N,S.w,S.h),"draw"in A&&A.draw()};if(R){var b=this.createImage(p);b.onload=function(){I(b)},b.onerror=function(e){I(),console.warn(e)},b.src=R}else I()}}}]),e}();e.QRCodeCanvas=d,Object.defineProperty(e,"__esModule",{value:!0})}));
diff --git a/uni_modules/lime-qrcode/hybrid/html/uni.webview.1.5.3.js b/uni_modules/lime-qrcode/hybrid/html/uni.webview.1.5.3.js
new file mode 100644
index 0000000..d6524fa
--- /dev/null
+++ b/uni_modules/lime-qrcode/hybrid/html/uni.webview.1.5.3.js
@@ -0,0 +1 @@
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).uni=n()}(this,(function(){"use strict";try{var e={};Object.defineProperty(e,"passive",{get:function(){!0}}),window.addEventListener("test-passive",null,e)}catch(e){}var n=Object.prototype.hasOwnProperty;function i(e,i){return n.call(e,i)}var t=[];function o(){return window.__dcloud_weex_postMessage||window.__dcloud_weex_}var r=function(e,n){var i={options:{timestamp:+new Date},name:e,arg:n};if(o()){if("postMessage"===e){var r={data:[n]};return window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessage(r):window.__dcloud_weex_.postMessage(JSON.stringify(r))}var a={type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}};window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessageToService(a):window.__dcloud_weex_.postMessageToService(JSON.stringify(a))}if(!window.plus)return window.parent.postMessage({type:"WEB_INVOKE_APPSERVICE",data:i,pageId:""},"*");if(0===t.length){var d=plus.webview.currentWebview();if(!d)throw new Error("plus.webview.currentWebview() is undefined");var s=d.parent(),w="";w=s?s.id:d.id,t.push(w)}if(plus.webview.getWebviewById("__uniapp__service"))plus.webview.postMessageToUniNView({type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}},"__uniapp__service");else{var u=JSON.stringify(i);plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat("WEB_INVOKE_APPSERVICE",'",').concat(u,",").concat(JSON.stringify(t),");"))}},a={navigateTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;r("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("redirectTo",{url:encodeURI(n)})},getEnv:function(e){o()?e({nvue:!0}):window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};r("postMessage",e.data||{})}},d=/uni-app/i.test(navigator.userAgent),s=/Html5Plus/i.test(navigator.userAgent),w=/complete|loaded|interactive/;var u=window.my&&navigator.userAgent.indexOf("AlipayClient")>-1;var g=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var c=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var v=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var m=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var p=window.qa&&/quickapp/i.test(navigator.userAgent);var f=window.ks&&window.ks.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var l=window.tt&&window.tt.miniProgram&&/Lark|Feishu/i.test(navigator.userAgent);var _=window.jd&&window.jd.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);for(var E,b=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},h=[function(e){if(d||s)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&w.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),a},function(e){if(m)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(c)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(u){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(g)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(v)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(p){window.QaJSBridge&&window.QaJSBridge.invoke?setTimeout(e,0):document.addEventListener("QaJSBridgeReady",e);var n=window.qa;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(f)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.ks.miniProgram},function(e){if(l)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(_)return window.JDJSBridgeReady&&window.JDJSBridgeReady.invoke?setTimeout(e,0):document.addEventListener("JDJSBridgeReady",e),window.jd.miniProgram},function(e){return document.addEventListener("DOMContentLoaded",e),a}],y=0;y<h.length&&!(E=h[y](b));y++);E||(E={});var B="undefined"!=typeof uni?uni:{};if(!B.navigateTo)for(var S in E)i(E,S)&&(B[S]=E[S]);return B.webView=E,B}));
diff --git a/uni_modules/lime-qrcode/package.json b/uni_modules/lime-qrcode/package.json
new file mode 100644
index 0000000..c8446a3
--- /dev/null
+++ b/uni_modules/lime-qrcode/package.json
@@ -0,0 +1,91 @@
+{
+	"id": "lime-qrcode",
+	"displayName": "qrcode 二维码生成",
+	"version": "0.1.8",
+	"description": "一款全平台通用的二维码生成插件,支持uniapp/uniappx(web,ios,安卓)",
+	"keywords": [
+        "qrcode",
+        "qr",
+        "uvue",
+        "生成图片",
+        "二维码"
+    ],
+	"repository": "",
+    "engines": {
+	},
+	"dcloudext": {
+		"type": "component-vue",
+		"sale": {
+			"regular": {
+				"price": "0.00"
+			},
+			"sourcecode": {
+				"price": "0.00"
+			}
+		},
+		"contact": {
+			"qq": "305716444"
+		},
+		"declaration": {
+			"ads": "无",
+			"data": "无",
+			"permissions": "无"
+		},
+		"npmurl": ""
+	},
+	"uni_modules": {
+		"dependencies": [
+			"lime-shared"
+		],
+		"encrypt": [],
+		"platforms": {
+			"cloud": {
+				"tcb": "y",
+                "aliyun": "y",
+                "alipay": "n"
+			},
+			"client": {
+				"Vue": {
+					"vue2": "y",
+					"vue3": "y"
+				},
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "y",
+					"app-uvue": "y",
+					"app-android": {
+						"minVersion": "19"
+                    }
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "u",
+					"Edge": "u",
+					"Firefox": "u",
+					"Safari": "u"
+				},
+				"小程序": {
+					"微信": "y",
+					"阿里": "u",
+					"百度": "u",
+					"字节跳动": "u",
+					"QQ": "u",
+					"钉钉": "u",
+					"快手": "u",
+					"飞书": "u",
+					"京东": "u"
+				},
+				"快应用": {
+					"华为": "u",
+					"联盟": "u"
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/lime-qrcode/readme.md b/uni_modules/lime-qrcode/readme.md
new file mode 100644
index 0000000..320874a
--- /dev/null
+++ b/uni_modules/lime-qrcode/readme.md
@@ -0,0 +1,152 @@
+# lime-qrcode 二维码
+- 一款全平台通用的二维码生成插件,支持uniapp/uniappx(web,ios,安卓)
+- uvue 需要导入[lime-qrcodegen](https://ext.dcloud.net.cn/plugin?id=15838)
+
+## 使用
+- 导入插件后直接使用
+- uvue 需要导入**[lime-qrcodegen](https://ext.dcloud.net.cn/plugin?id=15838)**
+
+#### 基础使用
+
+```html
+<l-qrcode value="http://lime.qcoon.cn" />
+```
+
+
+#### ICON
+- 带 Icon 的二维码
+
+```html
+<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" icon="/static/logo.png" iconSize="70rpx"></l-qrcode>
+```
+
+#### 颜色
+- 通过设置 `color` 自定义二维码颜色,通过设置 `bgColor` 自定义背景颜色。
+
+```html
+<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(82,196,26)"></l-qrcode>
+<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(22,119,255)" bgColor="rgb(245,245,245)"></l-qrcode>
+```
+
+#### 纠错比例
+- 通过设置 `errorLevel` 调整不同的容错等级。
+
+```html
+<l-qrcode value="img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" size="300rpx" errorLevel="H"></l-qrcode>
+```
+
+#### 生成图片
+- 1、通过调用插件的`canvasToTempFilePath`方法生成图片。
+
+```html
+<image v-if="image" :src="image" style="width: 300rpx;" mode="widthFix"></image>
+<l-qrcode ref="qrcodeRef" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
+<button @click="onClick">生成图片</button>
+```
+```js
+// vue3
+const qrcodeRef = ref(null)
+const onClick = () => {
+	if(!qrcodeRef.value) return
+	qrcodeRef.value.canvasToTempFilePath({
+		success(res) {
+			image.value = res.tempFilePath
+			console.log('success:::', res)
+		},
+		fail(err) {
+			console.log('err:::', err)
+		}
+	})
+}
+
+// vue2
+const el = this.$refs['qrcodeRef'] 
+el.canvasToTempFilePath({
+	success:(res)=>{
+		this.image = res.tempFilePath
+	},
+	fail(err) {
+		console.log('err:::', err)
+	}
+})
+
+// uvue
+const el:LQrcodeComponentPublicInstance = this.$refs['qrcodeRef'] as LQrcodeComponentPublicInstance 
+el.canvasToTempFilePath({
+	success:(res: TakeSnapshotSuccess)=>{
+		this.image = res.tempFilePath
+	},
+	fail(err: TakeSnapshotFail) {
+		console.log('err:::', err)
+	}
+})
+```
+
+- 2、通过设置`useCanvasToTempFilePath`在`success`事件里接收图片地址
+
+```html
+<image v-if="image" :src="image" style="width: 300rpx;" mode="widthFix"></image>
+<l-qrcode useCanvasToTempFilePath @success="success" value="https://limeui.qcoon.cn"></l-qrcode>
+```
+```js
+const image = ref(null)
+const success = (img) => {
+	image.value = img
+}
+```
+
+### 关于vue2的使用方式
+- 插件使用了`composition-api`, 如果你希望在vue2中使用请按官方的教程[vue-composition-api](https://uniapp.dcloud.net.cn/tutorial/vue-composition-api.html)配置
+- 关键代码是: 在main.js中 在vue2部分加上这一段即可
+
+```js
+// main.js vue2
+import Vue from 'vue'
+import VueCompositionAPI from '@vue/composition-api'
+Vue.use(VueCompositionAPI)
+```
+另外插件也用到了TS,vue2可能会遇过官方的TS版本过低的问题,找到HX目录下的`compile-typescript`目录
+```cmd
+// \HBuilderX\plugins\compile-typescript
+yarn add typescript -D
+- or - 
+npm install typescript -D
+```
+
+### 查看示例
+- 导入后直接使用这个标签查看演示效果
+
+```html
+// 代码位于 uni_modules/lime-qrcode/compoents/lime-qrcode
+<lime-qrcode />
+```
+
+### 插件标签
+- 默认 l-qrcode 为 component
+- 默认 lime-qrcode 为 demo
+
+
+
+## API
+
+### Props
+
+| 参数                       | 说明                                                         | 类型             | 默认值       |
+| --------------------------| ------------------------------------------------------------ | ---------------- | ------------ |
+| value                     | 扫描后的文本                                       			| <em>string</em>  | `-`        |
+| icon                      | 二维码中图片的地址                                              | <em>string</em>  | `-`        |
+| size                      | 二维码大小                                                      | <em>number,string</em>  | `160`     |
+| iconSize           		| 二维码中图片的大小                                                | <em>number,string</em>  | `40`      |
+| color           	        | 二维码颜色                                                        | <em>string</em>  | `-`      |
+| bgColor           	    | 二维码背景颜色          	                                      | <em>string</em>  | `-`  |
+| errorLevel             	| 二维码纠错等级       					                         | `'L' | 'M' | 'Q' | 'H' ` | `M`  |
+| marginSize             	| 边距码大小,默认为0码点      					                          | <em>number</em>  | `0`     |
+
+### 常见问题
+- icon 是网络地址时,H5和Nvue需要解决跨域问题,小程序需要配置download
+
+## 打赏
+
+如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。  
+![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/alipay.png)
+![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/wpay.png)
\ No newline at end of file
diff --git a/uni_modules/lime-shared/addUnit/index.ts b/uni_modules/lime-shared/addUnit/index.ts
new file mode 100644
index 0000000..78476c9
--- /dev/null
+++ b/uni_modules/lime-shared/addUnit/index.ts
@@ -0,0 +1,42 @@
+// @ts-nocheck
+import {isNumeric} from '../isNumeric'
+import {isDef} from '../isDef'
+/**
+ * 给一个值添加单位(像素 px)
+ * @param value 要添加单位的值,可以是字符串或数字
+ * @returns 添加了单位的值,如果值为 null 则返回 null
+ */
+
+// #ifndef UNI-APP-X && APP
+export function addUnit(value?: string | number): string | null {
+  if (!isDef(value)) {
+    return null;
+  }
+  value = String(value); // 将值转换为字符串
+  // 如果值是数字,则在后面添加单位 "px",否则保持原始值
+  return isNumeric(value) ? `${value}px` : value;
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+function addUnit(value: string): string
+function addUnit(value: number): string
+function addUnit(value: any|null): string|null  {
+  if (!isDef(value)) {
+    return null;
+  }
+  value = `${value}` //value.toString(); // 将值转换为字符串
+
+  // 如果值是数字,则在后面添加单位 "px",否则保持原始值
+  return isNumeric(value) ? `${value}px` : value;
+}
+export {addUnit}
+// #endif
+
+
+// console.log(addUnit(100)); // 输出: "100px"
+// console.log(addUnit("200")); // 输出: "200px"
+// console.log(addUnit("300px")); // 输出: "300px"(已经包含单位)
+// console.log(addUnit()); // 输出: undefined(值为 undefined)
+// console.log(addUnit(null)); // 输出: undefined(值为 null)
\ No newline at end of file
diff --git a/uni_modules/lime-shared/animation/bezier.ts b/uni_modules/lime-shared/animation/bezier.ts
new file mode 100644
index 0000000..b4239e1
--- /dev/null
+++ b/uni_modules/lime-shared/animation/bezier.ts
@@ -0,0 +1,82 @@
+export function cubicBezier(p1x : number, p1y : number, p2x : number, p2y : number):(x: number)=> number {
+	const ZERO_LIMIT = 1e-6;
+	// Calculate the polynomial coefficients,
+	// implicit first and last control points are (0,0) and (1,1).
+	const ax = 3 * p1x - 3 * p2x + 1;
+	const bx = 3 * p2x - 6 * p1x;
+	const cx = 3 * p1x;
+
+	const ay = 3 * p1y - 3 * p2y + 1;
+	const by = 3 * p2y - 6 * p1y;
+	const cy = 3 * p1y;
+
+	function sampleCurveDerivativeX(t : number) : number {
+		// `ax t^3 + bx t^2 + cx t` expanded using Horner's rule
+		return (3 * ax * t + 2 * bx) * t + cx;
+	}
+
+	function sampleCurveX(t : number) : number {
+		return ((ax * t + bx) * t + cx) * t;
+	}
+
+	function sampleCurveY(t : number) : number {
+		return ((ay * t + by) * t + cy) * t;
+	}
+
+	// Given an x value, find a parametric value it came from.
+	function solveCurveX(x : number) : number {
+		let t2 = x;
+		let derivative : number;
+		let x2 : number;
+
+		// https://trac.webkit.org/browser/trunk/Source/WebCore/platform/animation
+		// first try a few iterations of Newton's method -- normally very fast.
+		// http://en.wikipedia.org/wikiNewton's_method
+		for (let i = 0; i < 8; i++) {
+			// f(t) - x = 0
+			x2 = sampleCurveX(t2) - x;
+			if (Math.abs(x2) < ZERO_LIMIT) {
+				return t2;
+			}
+			derivative = sampleCurveDerivativeX(t2);
+			// == 0, failure
+			/* istanbul ignore if */
+			if (Math.abs(derivative) < ZERO_LIMIT) {
+				break;
+			}
+			t2 -= x2 / derivative;
+		}
+
+		// Fall back to the bisection method for reliability.
+		// bisection
+		// http://en.wikipedia.org/wiki/Bisection_method
+		let t1 = 1;
+		/* istanbul ignore next */
+		let t0 = 0;
+
+		/* istanbul ignore next */
+		t2 = x;
+		/* istanbul ignore next */
+		while (t1 > t0) {
+			x2 = sampleCurveX(t2) - x;
+			if (Math.abs(x2) < ZERO_LIMIT) {
+				return t2;
+			}
+			if (x2 > 0) {
+				t1 = t2;
+			} else {
+				t0 = t2;
+			}
+			t2 = (t1 + t0) / 2;
+		}
+
+		// Failure
+		return t2;
+	}
+
+	return function (x : number) : number {
+		return sampleCurveY(solveCurveX(x));
+	}
+
+	// return solve;
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/animation/ease.ts b/uni_modules/lime-shared/animation/ease.ts
new file mode 100644
index 0000000..0af156e
--- /dev/null
+++ b/uni_modules/lime-shared/animation/ease.ts
@@ -0,0 +1,3 @@
+import {cubicBezier} from './bezier';
+export let ease = cubicBezier(0.25, 0.1, 0.25, 1);
+export let linear = cubicBezier(0,0,1,1);
\ No newline at end of file
diff --git a/uni_modules/lime-shared/animation/index.ts b/uni_modules/lime-shared/animation/index.ts
new file mode 100644
index 0000000..5979064
--- /dev/null
+++ b/uni_modules/lime-shared/animation/index.ts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
+
+
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
diff --git a/uni_modules/lime-shared/animation/useTransition.ts b/uni_modules/lime-shared/animation/useTransition.ts
new file mode 100644
index 0000000..02b0f4a
--- /dev/null
+++ b/uni_modules/lime-shared/animation/useTransition.ts
@@ -0,0 +1,98 @@
+// @ts-nocheck
+import { ComponentPublicInstance } from 'vue'
+import { ease, linear } from './ease';
+import { Timeline, Animation } from './';
+export type UseTransitionOptions = {
+	duration ?: number
+	immediate ?: boolean
+	context ?: ComponentPublicInstance
+}
+// #ifndef UNI-APP-X && APP
+import { ref, watch, Ref } from '@/uni_modules/lime-shared/vue'
+
+export function useTransition(percent : Ref<number>|(() => number), options : UseTransitionOptions) : Ref<number> {
+	const current = ref(0)
+	const { immediate, duration = 300 } = options
+	let tl:Timeline|null = null;
+	let timer = -1
+	const isFunction = typeof percent === 'function'
+	watch(isFunction ? percent : () => percent.value, (v) => {
+		if(tl == null){
+			tl = new Timeline()
+		}
+		tl.start();
+		tl.add(
+			new Animation(
+				current.value,
+				v,
+				duration,
+				0,
+				ease,
+				nowValue => {
+					current.value = nowValue
+					clearTimeout(timer)
+					if(current.value == v){
+						timer = setTimeout(()=>{
+							tl?.pause();
+							tl = null
+						}, duration)
+					}
+				}
+			)
+		);
+	}, { immediate })
+
+	return current
+}
+
+// #endif
+
+// #ifdef UNI-APP-X && APP
+type UseTransitionReturnType = Ref<number>
+// export function useTransition<T>(source : any, options : UseTransitionOptions) : UseTransitionReturnType
+export function useTransition(source : any, options : UseTransitionOptions) : UseTransitionReturnType {
+	const outputRef : Ref<number> = ref(0)
+	const immediate = options.immediate ?? false
+	const duration = options.duration ?? 300
+	const context = options.context //as ComponentPublicInstance | null
+	let tl:Timeline|null = null;
+	let timer = -1
+	const watchFunc = (v : number) => {
+		if(tl == null){
+			tl = new Timeline()
+		}
+		tl!.start();
+		tl!.add(
+			new Animation(
+				outputRef.value,
+				v,
+				duration,
+				0,
+				ease,
+				nowValue => {
+					outputRef.value = nowValue //nowValue < 0.0001 ? 0 : Math.abs(v - nowValue) < 0.00001 ? v : nowValue;
+					clearTimeout(timer)
+					if(outputRef.value == v){
+						timer = setTimeout(()=>{
+							tl?.pause();
+							tl = null
+						}, duration)
+					}
+				}
+			), null
+		);
+	}
+
+	if (context != null && typeof source == 'string') {
+		context.$watch(source, watchFunc, { immediate } as WatchOptions)
+	} else {
+		watch(source, watchFunc, { immediate } as WatchOptions)
+	}
+	
+	const stop = ()=>{
+		
+	}
+	return outputRef //as UseTransitionReturnType
+}
+
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/animation/uvue.uts b/uni_modules/lime-shared/animation/uvue.uts
new file mode 100644
index 0000000..9b6936c
--- /dev/null
+++ b/uni_modules/lime-shared/animation/uvue.uts
@@ -0,0 +1,117 @@
+// @ts-nocheck
+import {raf, cancelRaf} from '../raf'
+export class Timeline {
+	state : string
+	animations : Set<Animation> = new Set<Animation>()
+	delAnimations : Animation[] = []
+	startTimes : Map<Animation, number> = new Map<Animation, number>()
+	pauseTime : number = 0
+	pauseStart : number = Date.now()
+	tickHandler : number = 0
+	tickHandlers : number[] = []
+	tick : (() => void) | null = null
+	constructor() {
+		this.state = 'Initiated';
+	}
+	start() {
+		if (!(this.state === 'Initiated')) return;
+		this.state = 'Started';
+
+		let startTime = Date.now();
+		this.pauseTime = 0;
+		this.tick = () => {
+			let now = Date.now();
+			this.animations.forEach((animation : Animation) => {
+				let t:number;
+				const ani = this.startTimes.get(animation)
+				if (ani == null) return
+				if (ani < startTime) {
+					t = now - startTime - animation.delay - this.pauseTime;
+				} else {
+					t = now - ani - animation.delay - this.pauseTime;
+				}
+				if (t > animation.duration) {
+					this.delAnimations.push(animation)
+					// 不能在 foreach 里面 对 集合进行删除操作
+					// this.animations.delete(animation);
+					t = animation.duration;
+				}
+				if (t > 0) animation.run(t);
+			})
+			// 不能在 foreach 里面 对 集合进行删除操作
+			while (this.delAnimations.length > 0) {
+				const animation = this.delAnimations.pop();
+				if (animation == null) return
+				this.animations.delete(animation);
+			}
+			clearTimeout(this.tickHandler);
+			if (this.state != 'Started') return
+			// this.tickHandler = setTimeout(() => {
+			// 	this.tick!()
+			// }, 1000 / 60)
+			this.tickHandler = raf(()=> {
+				this.tick!()
+			})
+			// this.tickHandlers.push(this.tickHandler)
+		}
+		this.tick!()
+	}
+	pause() {
+		if (!(this.state === 'Started')) return;
+		this.state = 'Paused';
+		this.pauseStart = Date.now();
+		// clearTimeout(this.tickHandler);
+		cancelRaf(this.tickHandler);
+	}
+	resume() {
+		if (!(this.state === 'Paused')) return;
+		this.state = 'Started';
+		this.pauseTime += Date.now() - this.pauseStart;
+		this.tick!();
+	}
+	reset() {
+		this.pause();
+		this.state = 'Initiated';
+		this.pauseTime = 0;
+		this.pauseStart = 0;
+		this.animations.clear()
+		this.delAnimations.clear()
+		this.startTimes.clear()
+		this.tickHandler = 0;
+	}
+	add(animation : Animation, startTime ?: number | null) {
+		if (startTime == null) startTime = Date.now();
+		this.animations.add(animation);
+		this.startTimes.set(animation, startTime);
+	}
+}
+
+export class Animation {
+	startValue : number
+	endValue : number
+	duration : number
+	timingFunction : (t : number) => number
+	delay : number
+	template : (t : number) => void
+	constructor(
+		startValue : number,
+		endValue : number,
+		duration : number,
+		delay : number,
+		timingFunction : (t : number) => number,
+		template : (v : number) => void) {
+		this.startValue = startValue;
+		this.endValue = endValue;
+		this.duration = duration;
+		this.timingFunction = timingFunction;
+		this.delay = delay;
+		this.template = template;
+	}
+
+	run(time : number) {
+		let range = this.endValue - this.startValue;
+		let progress = time / this.duration
+		if(progress != 1) progress = this.timingFunction(progress)
+		this.template(this.startValue + range * progress)
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/animation/vue.ts b/uni_modules/lime-shared/animation/vue.ts
new file mode 100644
index 0000000..30f89e5
--- /dev/null
+++ b/uni_modules/lime-shared/animation/vue.ts
@@ -0,0 +1,123 @@
+// @ts-nocheck
+const TICK = Symbol('tick');
+const TICK_HANDLER = Symbol('tick-handler');
+const ANIMATIONS = Symbol('animations');
+const START_TIMES = Symbol('start-times');
+const PAUSE_START = Symbol('pause-start');
+const PAUSE_TIME = Symbol('pause-time');
+const _raf = typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame : function(cb: Function) {return setTimeout(cb, 1000/60)}
+const _caf = typeof cancelAnimationFrame !== 'undefined' ? cancelAnimationFrame: function(id: any) {clearTimeout(id)}
+
+// const TICK = 'tick';
+// const TICK_HANDLER = 'tick-handler';
+// const ANIMATIONS = 'animations';
+// const START_TIMES = 'start-times';
+// const PAUSE_START = 'pause-start';
+// const PAUSE_TIME = 'pause-time';
+// const _raf = function(callback):number|null {return setTimeout(callback, 1000/60)}
+// const _caf = function(id: number):void {clearTimeout(id)}
+
+export class Timeline {
+	state: string
+	constructor() {
+		this.state = 'Initiated';
+		this[ANIMATIONS] = new Set();
+		this[START_TIMES] = new Map();
+	}
+	start() {
+		if (!(this.state === 'Initiated')) return;
+		this.state = 'Started';
+
+		let startTime = Date.now();
+		this[PAUSE_TIME] = 0;
+		this[TICK] = () => {
+			let now = Date.now();
+			this[ANIMATIONS].forEach((animation) => {
+				 let t: number;
+				 if (this[START_TIMES].get(animation) < startTime) {
+				 	t = now - startTime - animation.delay - this[PAUSE_TIME];
+				 } else {
+				 	t = now - this[START_TIMES].get(animation) - animation.delay - this[PAUSE_TIME];
+				 }
+				 
+				 if (t > animation.duration) {
+				 	this[ANIMATIONS].delete(animation);
+				 	t = animation.duration;
+				 }
+				 if (t > 0) animation.run(t);
+			})
+			// for (let animation of this[ANIMATIONS]) {
+			// 	let t: number;
+			// 	console.log('animation', animation)
+			// 	if (this[START_TIMES].get(animation) < startTime) {
+			// 		t = now - startTime - animation.delay - this[PAUSE_TIME];
+			// 	} else {
+			// 		t = now - this[START_TIMES].get(animation) - animation.delay - this[PAUSE_TIME];
+			// 	}
+
+			// 	if (t > animation.duration) {
+			// 		this[ANIMATIONS].delete(animation);
+			// 		t = animation.duration;
+			// 	}
+			// 	if (t > 0) animation.run(t);
+			// }
+			this[TICK_HANDLER] = _raf(this[TICK]);
+		};
+		this[TICK]();
+	}
+	pause() {
+		if (!(this.state === 'Started')) return;
+		this.state = 'Paused';
+
+		this[PAUSE_START] = Date.now();
+		_caf(this[TICK_HANDLER]);
+	}
+	resume() {
+		if (!(this.state === 'Paused')) return;
+		this.state = 'Started';
+
+		this[PAUSE_TIME] += Date.now() - this[PAUSE_START];
+		this[TICK]();
+	}
+	reset() {
+		this.pause();
+		this.state = 'Initiated';
+		this[PAUSE_TIME] = 0;
+		this[PAUSE_START] = 0;
+		this[ANIMATIONS] = new Set();
+		this[START_TIMES] = new Map();
+		this[TICK_HANDLER] = null;
+	}
+	add(animation: any, startTime?: number) {
+		if (arguments.length < 2) startTime = Date.now();
+		this[ANIMATIONS].add(animation);
+		this[START_TIMES].set(animation, startTime);
+	}
+}
+
+export class Animation {
+	startValue: number
+	endValue: number
+	duration: number
+	timingFunction: (t: number) => number
+	delay: number
+	template: (t: number) => void
+	constructor(startValue: number, endValue: number, duration: number, delay: number, timingFunction: (t: number) => number, template: (v: number) => void) {
+		timingFunction = timingFunction || (v => v);
+		template = template || (v => v);
+		
+		this.startValue = startValue;
+		this.endValue = endValue;
+		this.duration = duration;
+		this.timingFunction = timingFunction;
+		this.delay = delay;
+		this.template = template;
+	}
+
+	run(time: number) {
+		let range = this.endValue - this.startValue;
+		let progress = time / this.duration
+		if(progress != 1) progress = this.timingFunction(progress)
+		this.template(this.startValue + range * progress)
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/arrayBufferToFile/index.ts b/uni_modules/lime-shared/arrayBufferToFile/index.ts
new file mode 100644
index 0000000..49ee530
--- /dev/null
+++ b/uni_modules/lime-shared/arrayBufferToFile/index.ts
@@ -0,0 +1,8 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/arrayBufferToFile/uvue.uts b/uni_modules/lime-shared/arrayBufferToFile/uvue.uts
new file mode 100644
index 0000000..65c7b14
--- /dev/null
+++ b/uni_modules/lime-shared/arrayBufferToFile/uvue.uts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+// import {platform} from '../platform'
+/**
+ * buffer转路径
+ * @param {Object} buffer
+ */
+// @ts-nocheck
+export function arrayBufferToFile(buffer: ArrayBuffer, name?: string, format?:string):Promise<(File|string)> {
+	console.error('[arrayBufferToFile] 当前环境不支持')
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/arrayBufferToFile/vue.ts b/uni_modules/lime-shared/arrayBufferToFile/vue.ts
new file mode 100644
index 0000000..9760b20
--- /dev/null
+++ b/uni_modules/lime-shared/arrayBufferToFile/vue.ts
@@ -0,0 +1,63 @@
+// @ts-nocheck
+import {platform} from '../platform'
+/**
+ * buffer转路径
+ * @param {Object} buffer
+ */
+// @ts-nocheck
+export function arrayBufferToFile(buffer: ArrayBuffer | Blob, name?: string, format?:string):Promise<(File|string)> {
+	return new Promise((resolve, reject) => {
+		// #ifdef MP
+		const fs = uni.getFileSystemManager()
+		//自定义文件名
+		if (!name && !format) {
+			reject(new Error('ERROR_NAME_PARSE'))
+		}
+		const fileName = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
+		let pre = platform()
+		const filePath = `${pre.env.USER_DATA_PATH}/${fileName}`
+		fs.writeFile({
+			filePath,
+			data: buffer, 
+			success() {
+				resolve(filePath)
+			},
+			fail(err) {
+				console.error(err)
+				reject(err)
+			}
+		})
+		// #endif
+
+		// #ifdef H5
+		const file = new File([buffer], name, {
+		     type: format,
+		});
+		resolve(file)
+		// #endif
+
+		// #ifdef APP-PLUS
+		const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+		const base64 = uni.arrayBufferToBase64(buffer)
+		bitmap.loadBase64Data(base64, () => {
+			if (!name && !format) {
+				reject(new Error('ERROR_NAME_PARSE'))
+			}
+			const fileNmae = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
+			const filePath = `_doc/uniapp_temp/${fileNmae}`
+			bitmap.save(filePath, {},
+				() => {
+					bitmap.clear()
+					resolve(filePath)
+				},
+				(error) => {
+					bitmap.clear()
+					reject(error)
+				})
+		}, (error) => {
+			bitmap.clear()
+			reject(error)
+		})
+		// #endif
+	})
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/base64ToArrayBuffer/index.ts b/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
new file mode 100644
index 0000000..f83b640
--- /dev/null
+++ b/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+// 未完成
+export function base64ToArrayBuffer(base64 : string) {
+	const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
+	if (!format) {
+		new Error('ERROR_BASE64SRC_PARSE')
+	}
+	if(uni.base64ToArrayBuffer) {
+		return uni.base64ToArrayBuffer(bodyData)
+	} else {
+		
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/base64ToPath/index.ts b/uni_modules/lime-shared/base64ToPath/index.ts
new file mode 100644
index 0000000..af9a9d2
--- /dev/null
+++ b/uni_modules/lime-shared/base64ToPath/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
diff --git a/uni_modules/lime-shared/base64ToPath/uvue.uts b/uni_modules/lime-shared/base64ToPath/uvue.uts
new file mode 100644
index 0000000..7019ecb
--- /dev/null
+++ b/uni_modules/lime-shared/base64ToPath/uvue.uts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+import { processFile, ProcessFileOptions  } from '@/uni_modules/lime-file-utils'
+
+/**
+ * base64转路径
+ * @param {Object} base64
+ */
+export function base64ToPath(base64: string, filename: string | null = null):Promise<string> {
+	return new Promise((resolve,reject) => {
+		processFile({
+		    type: 'toDataURL',
+		    path: base64,
+		    filename,
+		    success(res: string){
+		       resolve(res)
+		    },
+			fail(err){
+				reject(err)
+			}
+		} as ProcessFileOptions)
+	})
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/base64ToPath/vue.ts b/uni_modules/lime-shared/base64ToPath/vue.ts
new file mode 100644
index 0000000..735000f
--- /dev/null
+++ b/uni_modules/lime-shared/base64ToPath/vue.ts
@@ -0,0 +1,75 @@
+// @ts-nocheck
+import {platform} from '../platform'
+/**
+ * base64转路径
+ * @param {Object} base64
+ */
+export function base64ToPath(base64: string, filename?: string):Promise<string> {
+	const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];
+	return new Promise((resolve, reject) => {
+		// #ifdef MP
+		const fs = uni.getFileSystemManager()
+		//自定义文件名
+		if (!filename && !format) {
+			reject(new Error('ERROR_BASE64SRC_PARSE'))
+		}
+		// const time = new Date().getTime();
+		const name = filename || `${new Date().getTime()}.${format}`;
+		let pre = platform()
+		const filePath = `${pre.env.USER_DATA_PATH}/${name}`
+		fs.writeFile({
+			filePath,
+			data: base64.split(',')[1], 
+			encoding: 'base64',
+			success() {
+				resolve(filePath)
+			},
+			fail(err) {
+				console.error(err)
+				reject(err)
+			}
+		})
+		// #endif
+
+		// #ifdef H5
+		// mime类型
+		let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
+		//base64 解码
+		let byteString = atob(base64.split(',')[1]);
+		//创建缓冲数组
+		let arrayBuffer = new ArrayBuffer(byteString.length);
+		//创建视图
+		let intArray = new Uint8Array(arrayBuffer);
+		for (let i = 0; i < byteString.length; i++) {
+			intArray[i] = byteString.charCodeAt(i);
+		}
+		resolve(URL.createObjectURL(new Blob([intArray], {
+			type: mimeString
+		})))
+		// #endif
+
+		// #ifdef APP-PLUS
+		const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+		bitmap.loadBase64Data(base64, () => {
+			if (!filename && !format) {
+				reject(new Error('ERROR_BASE64SRC_PARSE'))
+			}
+			// const time = new Date().getTime();
+			const name = filename || `${new Date().getTime()}.${format}`;
+			const filePath = `_doc/uniapp_temp/${name}`
+			bitmap.save(filePath, {},
+				() => {
+					bitmap.clear()
+					resolve(filePath)
+				},
+				(error) => {
+					bitmap.clear()
+					reject(error)
+				})
+		}, (error) => {
+			bitmap.clear()
+			reject(error)
+		})
+		// #endif
+	})
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/camelCase/index.ts b/uni_modules/lime-shared/camelCase/index.ts
new file mode 100644
index 0000000..dd470ab
--- /dev/null
+++ b/uni_modules/lime-shared/camelCase/index.ts
@@ -0,0 +1,21 @@
+/**
+ * 将字符串转换为 camelCase 或 PascalCase 风格的命名约定
+ * @param str 要转换的字符串
+ * @param isPascalCase 指示是否转换为 PascalCase 的布尔值,默认为 false
+ * @returns 转换后的字符串
+ */
+export function camelCase(str: string, isPascalCase: boolean = false): string {
+    // 将字符串分割成单词数组
+    let words: string[] = str.split(/[\s_-]+/);
+  
+    // 将数组中的每个单词首字母大写(除了第一个单词)
+    let camelCased: string[] = words.map((word, index):string => {
+      if (index == 0 && !isPascalCase) {
+        return word.toLowerCase(); // 第一个单词全小写
+      }
+      return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+    });
+  
+    // 将数组中的单词拼接成一个字符串
+    return camelCased.join('');
+};
\ No newline at end of file
diff --git a/uni_modules/lime-shared/canIUseCanvas2d/index.ts b/uni_modules/lime-shared/canIUseCanvas2d/index.ts
new file mode 100644
index 0000000..2d60e65
--- /dev/null
+++ b/uni_modules/lime-shared/canIUseCanvas2d/index.ts
@@ -0,0 +1,67 @@
+// @ts-nocheck
+
+// #ifndef UNI-APP-X && APP
+
+// #ifdef MP-ALIPAY
+interface My {
+	SDKVersion: string
+}
+declare var my: My
+// #endif
+
+function compareVersion(v1:string, v2:string) {
+  let a1 = v1.split('.');
+  let a2 = v2.split('.');
+  const len = Math.max(a1.length, a2.length);
+
+  while (a1.length < len) {
+    a1.push('0');
+  }
+  while (a2.length < len) {
+    a2.push('0');
+  }
+
+  for (let i = 0; i < len; i++) {
+    const num1 = parseInt(a1[i], 10);
+    const num2 = parseInt(a2[i], 10);
+
+    if (num1 > num2) {
+      return 1;
+    }
+    if (num1 < num2) {
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+function gte(version: string) {
+	let {SDKVersion} = uni.getSystemInfoSync();
+	// #ifdef MP-ALIPAY
+	SDKVersion = my.SDKVersion
+	// #endif
+	return compareVersion(SDKVersion, version) >= 0;
+}
+// #endif
+
+
+/** 环境是否支持canvas 2d */
+export function canIUseCanvas2d(): boolean {
+	// #ifdef MP-WEIXIN
+	return gte('2.9.0');
+	// #endif
+	// #ifdef MP-ALIPAY
+	return gte('2.7.0');
+	// #endif
+	// #ifdef MP-TOUTIAO
+	return gte('1.78.0');
+	// #endif
+	// #ifndef MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO
+	return false
+	// #endif
+	
+	// #ifdef UNI-APP-X && APP || APP-NVUE || APP-VUE
+	return false;
+	// #endif
+}
diff --git a/uni_modules/lime-shared/capitalizedAmount/index.ts b/uni_modules/lime-shared/capitalizedAmount/index.ts
new file mode 100644
index 0000000..9a0c1f4
--- /dev/null
+++ b/uni_modules/lime-shared/capitalizedAmount/index.ts
@@ -0,0 +1,111 @@
+// @ts-nocheck
+import { isString } from "../isString";
+import { isNumber } from "../isNumber";
+/**
+ * 将金额转换为中文大写形式
+ * @param {number | string} amount - 需要转换的金额,可以是数字或字符串
+ * @returns {string} 转换后的中文大写金额
+ */
+function capitalizedAmount(amount : number) : string
+function capitalizedAmount(amount : string) : string
+function capitalizedAmount(amount : any | null) : string {
+	try {
+		let _amountStr :string;
+		let _amountNum :number = 0;
+		// 如果输入是字符串,先将其转换为数字,并去除逗号
+		if (typeof amount == 'string') {
+			 _amountNum = parseFloat((amount as string).replace(/,/g, ''));
+		}
+		if(isNumber(amount)) {
+			_amountNum = amount as number
+		}
+		// 判断输入是否为有效的金额  || isNaN(amount)
+		if (amount == null) throw new Error('不是有效的金额!');
+
+		let result = '';
+
+		// 处理负数情况
+		if (_amountNum < 0) {
+			result = '欠';
+			_amountNum = Math.abs(_amountNum);
+		}
+
+		// 金额不能超过千亿以上
+		if (_amountNum >= 10e11) throw new Error('计算金额过大!');
+
+		// 保留两位小数并转换为字符串
+		_amountStr = _amountNum.toFixed(2);
+
+		// 定义数字、单位和小数单位的映射
+		const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
+		const units = ['', '拾', '佰', '仟'];
+		const bigUnits = ['', '万', '亿'];
+		const decimalUnits = ['角', '分'];
+
+		// 分离整数部分和小数部分
+		const amountArray = _amountStr.split('.');
+		let integerPart = amountArray[0]; // string| number[]
+		const decimalPart = amountArray[1];
+
+		// 处理整数部分
+		if (integerPart != '0') {
+			let _integerPart = integerPart.split('').map((item):number => parseInt(item));
+
+			// 将整数部分按四位一级进行分组
+			const levels = _integerPart.reverse().reduce((prev:string[][], item, index):string[][] => {
+				// const level = prev?.[0]?.length < 4 ? prev[0] : [];
+				const level = prev.length > 0 && prev[0].length < 4 ? prev[0]: []
+
+				const value = item == 0 ? digits[item] : digits[item] + units[index % 4];
+
+				level.unshift(value);
+
+				if (level.length == 1) {
+					prev.unshift(level);
+				} else {
+					prev[0] = level;
+				}
+
+				return prev;
+			}, [] as string[][]);
+			// 将分组后的整数部分转换为中文大写形式
+			result += levels.reduce((prev, item, index):string => {
+				let _level = bigUnits[levels.length - index - 1];
+				let _item = item.join('').replace(/(零)\1+/g, '$1');
+
+				if (_item == '零') {
+					_level = '';
+					_item = '';
+				} else if (_item.endsWith('零')) {
+					_item = _item.slice(0, _item.length - 1);
+				}
+
+				return prev + _item + _level;
+			}, '');
+		} else {
+			result += '零';
+		}
+
+		// 添加元
+		result += '元';
+
+		// 处理小数部分
+		if (decimalPart != '00') {
+			if (result == '零元') result = '';
+
+			for (let i = 0; i < decimalPart.length; i++) {
+				const digit = parseInt(decimalPart.charAt(i));
+
+				if (digit != 0) {
+					result += digits[digit] + decimalUnits[i];
+				}
+			}
+		} else {
+			result += '整';
+		}
+
+		return result;
+	} catch (error : Error) {
+		return error.message;
+	}
+};
\ No newline at end of file
diff --git a/uni_modules/lime-shared/changelog.md b/uni_modules/lime-shared/changelog.md
new file mode 100644
index 0000000..f791344
--- /dev/null
+++ b/uni_modules/lime-shared/changelog.md
@@ -0,0 +1,40 @@
+## 0.1.8(2024-10-08)
+- fix: vue2 条件编译 // #ifdef APP-IOS || APP-ANDROID 会生效
+## 0.1.7(2024-09-23)
+- fix: raf 类型跟随版本变更
+## 0.1.6(2024-07-24)
+- fix: vue2 app ts需要明确的后缀,所有补全
+- chore: 减少依赖
+## 0.1.5(2024-07-21)
+- feat: 删除 Hooks
+- feat: 兼容uniappx
+## 0.1.4(2023-09-05)
+- feat: 增加 Hooks `useIntersectionObserver`
+- feat: 增加 `floatAdd`
+- feat: 因为本人插件兼容 vue2 需要使用 `composition-api`,故增加vue文件代码插件的条件编译
+## 0.1.3(2023-08-13)
+- feat: 增加 `camelCase`
+## 0.1.2(2023-07-17)
+- feat: 增加 `getClassStr`
+## 0.1.1(2023-07-06)
+- feat: 增加 `isNumeric`, 区别于 `isNumber`
+## 0.1.0(2023-06-30)
+- fix: `clamp`忘记导出了
+## 0.0.9(2023-06-27)
+- feat: 增加`arrayBufferToFile`
+## 0.0.8(2023-06-19)
+- feat: 增加`createAnimation`、`clamp`
+## 0.0.7(2023-06-08)
+- chore: 更新注释
+## 0.0.6(2023-06-08)
+- chore: 增加`createImage`为`lime-watermark`和`lime-qrcode`提供依赖
+## 0.0.5(2023-06-03)
+- chore: 更新注释
+## 0.0.4(2023-05-22)
+- feat: 增加`range`,`exif`,`selectComponent`
+## 0.0.3(2023-05-08)
+- feat: 增加`fillZero`,`debounce`,`throttle`,`random`
+## 0.0.2(2023-05-05)
+- chore: 更新文档
+## 0.0.1(2023-05-05)
+- 无
diff --git a/uni_modules/lime-shared/clamp/index.ts b/uni_modules/lime-shared/clamp/index.ts
new file mode 100644
index 0000000..0e16358
--- /dev/null
+++ b/uni_modules/lime-shared/clamp/index.ts
@@ -0,0 +1,16 @@
+// @ts-nocheck
+/**
+ * 将一个值限制在指定的范围内
+ * @param val 要限制的值
+ * @param min 最小值
+ * @param max 最大值
+ * @returns 限制后的值
+ */
+export function clamp(val: number, min: number, max: number): number {
+  return Math.max(min, Math.min(max, val));
+}
+
+
+// console.log(clamp(5 ,0, 10)); // 输出: 5(在范围内,不做更改)
+// console.log(clamp(-5 ,0, 10)); // 输出: 0(小于最小值,被限制为最小值)
+// console.log(clamp(15 ,0, 10)); // 输出: 10(大于最大值,被限制为最大值)
\ No newline at end of file
diff --git a/uni_modules/lime-shared/cloneDeep/index.ts b/uni_modules/lime-shared/cloneDeep/index.ts
new file mode 100644
index 0000000..3428c49
--- /dev/null
+++ b/uni_modules/lime-shared/cloneDeep/index.ts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+// #endif
+
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/cloneDeep/uvue.ts b/uni_modules/lime-shared/cloneDeep/uvue.ts
new file mode 100644
index 0000000..7929bc2
--- /dev/null
+++ b/uni_modules/lime-shared/cloneDeep/uvue.ts
@@ -0,0 +1,17 @@
+// @ts-nocheck
+/**
+ * 深度克隆一个对象或数组
+ * @param obj 要克隆的对象或数组
+ * @returns 克隆后的对象或数组
+ */
+export function cloneDeep<T>(obj: any): T {
+  // 如果传入的对象是基本数据类型(如字符串、数字等),则直接返回
+  // if(['number', 'string'].includes(typeof obj) || Array.isArray(obj)){
+	 //   return obj as T
+  // }
+  if(typeof obj == 'object'){
+	return JSON.parse(JSON.stringify(obj as T)) as T;
+  }
+  return obj as T
+}
+
diff --git a/uni_modules/lime-shared/cloneDeep/vue.ts b/uni_modules/lime-shared/cloneDeep/vue.ts
new file mode 100644
index 0000000..ded334d
--- /dev/null
+++ b/uni_modules/lime-shared/cloneDeep/vue.ts
@@ -0,0 +1,103 @@
+// @ts-nocheck
+/**
+ * 深度克隆一个对象或数组
+ * @param obj 要克隆的对象或数组
+ * @returns 克隆后的对象或数组
+ */
+export function cloneDeep<T>(obj: any): T {
+  // 如果传入的对象为空,返回空
+  if (obj === null) {
+    return null as unknown as T;
+  }
+
+  // 如果传入的对象是 Set 类型,则将其转换为数组,并通过新的 Set 构造函数创建一个新的 Set 对象
+  if (obj instanceof Set) {
+    return new Set([...obj]) as unknown as T;
+  }
+
+  // 如果传入的对象是 Map 类型,则将其转换为数组,并通过新的 Map 构造函数创建一个新的 Map 对象
+  if (obj instanceof Map) {
+    return new Map([...obj]) as unknown as T;
+  }
+
+  // 如果传入的对象是 WeakMap 类型,则直接用传入的 WeakMap 对象进行赋值
+  if (obj instanceof WeakMap) {
+    let weakMap = new WeakMap();
+    weakMap = obj;
+    return weakMap as unknown as T;
+  }
+
+  // 如果传入的对象是 WeakSet 类型,则直接用传入的 WeakSet 对象进行赋值
+  if (obj instanceof WeakSet) {
+    let weakSet = new WeakSet();
+    weakSet = obj;
+    return weakSet as unknown as T;
+  }
+
+  // 如果传入的对象是 RegExp 类型,则通过新的 RegExp 构造函数创建一个新的 RegExp 对象
+  if (obj instanceof RegExp) {
+    return new RegExp(obj) as unknown as T;
+  }
+
+  // 如果传入的对象是 undefined 类型,则返回 undefined
+  if (typeof obj === 'undefined') {
+    return undefined as unknown as T;
+  }
+
+  // 如果传入的对象是数组,则递归调用 cloneDeep 函数对数组中的每个元素进行克隆
+  if (Array.isArray(obj)) {
+    return obj.map(cloneDeep) as unknown as T;
+  }
+
+  // 如果传入的对象是 Date 类型,则通过新的 Date 构造函数创建一个新的 Date 对象
+  if (obj instanceof Date) {
+    return new Date(obj.getTime()) as unknown as T;
+  }
+
+  // 如果传入的对象是普通对象,则使用递归调用 cloneDeep 函数对对象的每个属性进行克隆
+  if (typeof obj === 'object') {
+    const newObj: any = {};
+    for (const [key, value] of Object.entries(obj)) {
+      newObj[key] = cloneDeep(value);
+    }
+    const symbolKeys = Object.getOwnPropertySymbols(obj);
+    for (const key of symbolKeys) {
+      newObj[key] = cloneDeep(obj[key]);
+    }
+    return newObj;
+  }
+
+  // 如果传入的对象是基本数据类型(如字符串、数字等),则直接返回
+  return obj;
+}
+
+// 示例使用
+
+// // 克隆一个对象
+// const obj = { name: 'John', age: 30 };
+// const clonedObj = cloneDeep(obj);
+
+// console.log(clonedObj); // 输出: { name: 'John', age: 30 }
+// console.log(clonedObj === obj); // 输出: false (副本与原对象是独立的)
+
+// // 克隆一个数组
+// const arr = [1, 2, 3];
+// const clonedArr = cloneDeep(arr);
+
+// console.log(clonedArr); // 输出: [1, 2, 3]
+// console.log(clonedArr === arr); // 输出: false (副本与原数组是独立的)
+
+// // 克隆一个包含嵌套对象的对象
+// const person = {
+//   name: 'Alice',
+//   age: 25,
+//   address: {
+//     city: 'New York',
+//     country: 'USA',
+//   },
+// };
+// const clonedPerson = cloneDeep(person);
+
+// console.log(clonedPerson); // 输出: { name: 'Alice', age: 25, address: { city: 'New York', country: 'USA' } }
+// console.log(clonedPerson === person); // 输出: false (副本与原对象是独立的)
+// console.log(clonedPerson.address === person.address); // 输出: false (嵌套对象的副本也是独立的)
\ No newline at end of file
diff --git a/uni_modules/lime-shared/closest/index.ts b/uni_modules/lime-shared/closest/index.ts
new file mode 100644
index 0000000..e6e79c2
--- /dev/null
+++ b/uni_modules/lime-shared/closest/index.ts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+
+/**
+ * 在给定数组中找到最接近目标数字的元素。
+ * @param arr 要搜索的数字数组。
+ * @param target 目标数字。
+ * @returns 最接近目标数字的数组元素。
+ */
+export function closest(arr: number[], target: number):number {
+  return arr.reduce((pre: number, cur: number):number =>
+    Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
+  );
+}
+
+// 示例
+// // 定义一个数字数组
+// const numbers = [1, 3, 5, 7, 9];
+
+// // 在数组中找到最接近目标数字 6 的元素
+// const closestNumber = closest(numbers, 6);
+
+// console.log(closestNumber); // 输出结果: 5
\ No newline at end of file
diff --git a/uni_modules/lime-shared/components/lime-shared/lime-shared.vue b/uni_modules/lime-shared/components/lime-shared/lime-shared.vue
new file mode 100644
index 0000000..e2d7fe2
--- /dev/null
+++ b/uni_modules/lime-shared/components/lime-shared/lime-shared.vue
@@ -0,0 +1,156 @@
+<template>
+	<view id="shared" style="height: 500px; width: 300px; background-color: aqua;">
+		
+	</view>
+</template>
+
+<script lang="ts">
+	import { getRect, getAllRect } from '@/uni_modules/lime-shared/getRect'
+	
+	import { camelCase } from '@/uni_modules/lime-shared/camelCase'
+	import { canIUseCanvas2d } from '@/uni_modules/lime-shared/canIUseCanvas2d'
+	import { clamp } from '@/uni_modules/lime-shared/clamp'
+	import { cloneDeep } from '@/uni_modules/lime-shared/cloneDeep'
+	import { closest } from '@/uni_modules/lime-shared/closest'
+	import { debounce } from '@/uni_modules/lime-shared/debounce'
+	import { fillZero } from '@/uni_modules/lime-shared/fillZero'
+	import { floatAdd } from '@/uni_modules/lime-shared/floatAdd'
+	import { floatMul } from '@/uni_modules/lime-shared/floatMul'
+	import { floatDiv } from '@/uni_modules/lime-shared/floatDiv'
+	import { floatSub } from '@/uni_modules/lime-shared/floatSub'
+	import { getClassStr } from '@/uni_modules/lime-shared/getClassStr'
+	import { getCurrentPage } from '@/uni_modules/lime-shared/getCurrentPage'
+	import { getStyleStr } from '@/uni_modules/lime-shared/getStyleStr'
+	import { hasOwn } from '@/uni_modules/lime-shared/hasOwn'
+	import { isBase64 } from '@/uni_modules/lime-shared/isBase64'
+	import { isBrowser } from '@/uni_modules/lime-shared/isBrowser'
+	import { isDef } from '@/uni_modules/lime-shared/isDef'
+	import { isEmpty } from '@/uni_modules/lime-shared/isEmpty'
+	import { isFunction } from '@/uni_modules/lime-shared/isFunction'
+	import { isNumber } from '@/uni_modules/lime-shared/isNumber'
+	import { isNumeric } from '@/uni_modules/lime-shared/isNumeric'
+	import { isObject } from '@/uni_modules/lime-shared/isObject'
+	import { isPromise } from '@/uni_modules/lime-shared/isPromise'
+	import { isString } from '@/uni_modules/lime-shared/isString'
+	import { kebabCase } from '@/uni_modules/lime-shared/kebabCase'
+	import { raf, doubleRaf } from '@/uni_modules/lime-shared/raf'
+	import { random } from '@/uni_modules/lime-shared/random'
+	import { range } from '@/uni_modules/lime-shared/range'
+	import { sleep } from '@/uni_modules/lime-shared/sleep'
+	import { throttle } from '@/uni_modules/lime-shared/throttle'
+	import { toArray } from '@/uni_modules/lime-shared/toArray'
+	import { toBoolean } from '@/uni_modules/lime-shared/toBoolean'
+	import { toNumber } from '@/uni_modules/lime-shared/toNumber'
+	import { unitConvert } from '@/uni_modules/lime-shared/unitConvert'
+	import { getCurrentInstance } from '@/uni_modules/lime-shared/vue'
+	import { capitalizedAmount } from '@/uni_modules/lime-shared/capitalizedAmount'
+	
+	// #ifdef VUE2
+	type UTSJSONObject = any
+	// #endif
+	
+	const context = getCurrentInstance()
+	// getRect('#shared', context!).then(res =>{
+	// 	console.log('res', res.bottom)
+	// })
+	// getAllRect('#shared', context).then(res =>{
+	// 	console.log('res', res)
+	// })
+	
+	
+	// console.log('camelCase::', camelCase("hello world"));
+	// console.log('camelCase::', camelCase("my_name_is_john", true));
+	// console.log('canIUseCanvas2d::', canIUseCanvas2d());
+	// console.log('clamp::', clamp(5 ,0, 10));
+	// console.log('cloneDeep::', cloneDeep<UTSJSONObject>({a:5}));
+	// console.log('closest::', closest([1, 3, 5, 7, 9], 6));
+	
+	
+	
+	
+	// const saveData = (data: any) => {
+	// 	// 模拟保存数据的操作
+	// 	console.log(`Saving data: ${data}`);
+	// }
+	
+	// const debouncedSaveData = debounce(saveData, 500);
+	// debouncedSaveData('Data 1'); 
+	// debouncedSaveData('Data 2'); 
+	
+	// console.log('fillZero', fillZero(1))
+	// console.log('floatAdd', floatAdd(0.1, 0.2), floatAdd(1.05, 0.05), floatAdd(0.1, 0.7), floatAdd(0.0001, 0.0002), floatAdd(123.456 , 789.012))
+	// console.log('floatMul', floatMul(0.1, 0.02), floatMul(1.0255, 100))
+	// console.log('floatDiv', floatDiv(10.44, 100), floatDiv(1.0255, 100), floatDiv(5.419909340994699, 0.2))
+	// console.log('floatSub', floatSub(0.4, 0.1), floatSub(1.0255, 100))
+	const now = () : number => System.nanoTime() / 1_000_000.0
+	console.log('capitalizedAmount', capitalizedAmount(0.4))
+	console.log('capitalizedAmount', capitalizedAmount(100))
+	console.log('capitalizedAmount', capitalizedAmount(100000000))
+	console.log('capitalizedAmount', capitalizedAmount('2023.04'))
+	console.log('capitalizedAmount', capitalizedAmount(-1024))
+	console.log('now', now(), Date.now())
+	// console.log('getClassStr', getClassStr({hover: true}))
+	// console.log('getStyleStr', getStyleStr({ color: 'red', fontSize: '16px', backgroundColor: '', border: null }))
+	// console.log('hasOwn', hasOwn({a: true}, 'key'))
+	// console.log('isBase64::', isBase64("SGVsbG8sIFdvcmxkIQ=="));
+	// console.log('isBrowser::', isBrowser);
+	// console.log('isDef::', isDef('6'));
+	// console.log('isEmpty::', isEmpty({a: true}));
+	
+	// const b = () =>{}
+	// console.log('isFunction::', isFunction(b));
+	// console.log('isNumber::', isNumber('6'));
+	// console.log('isNumeric::', isNumeric('6'));
+	// console.log('isObject::', isObject({}));
+	
+	// const promise = ():Promise<boolean> => {
+	// 	return new Promise((resolve) => {
+	// 		resolve(true)
+	// 	})
+	// }
+	// const a = promise()
+	// console.log('isPromise::', isPromise(a));
+	// console.log('isString::', isString('null'));
+	// console.log('kebabCase::', kebabCase('my love'));
+	// console.log('raf::', raf(()=>{
+	// 	console.log('raf:::1')
+	// }));
+	// console.log('doubleRaf::', doubleRaf(()=>{
+	// 	console.log('doubleRaf:::1')
+	// }));
+	// console.log('random', random(0, 10))
+	// console.log('random', random(0, 1, 2))
+	// console.log('range', range(0, 10, 2))
+	// console.log('sleep', sleep(300).then(res => {
+	// 	console.log('log')
+	// }))
+	
+	// const handleScroll = (a: string) => {
+	//   console.log("Scroll event handled!", a);
+	// }
+	
+	// // // 使用节流函数对 handleScroll 进行节流,间隔时间为 500 毫秒
+	// const throttledScroll = throttle(handleScroll, 500);
+	// throttledScroll('5');
+	// const page = getCurrentPage()
+	// console.log('getCurrentPage::', page)
+	
+	// console.log('toArray', toArray<number>(5))
+	// console.log('toBoolean', toBoolean(5))
+	// console.log('toNumber', toNumber('5'))
+	// console.log('unitConvert', unitConvert('5'))
+	
+	// uni.getImageInfo({
+	// 	src: '/static/logo.png',
+	// 	success(res) {
+	// 		console.log('res', res)
+	// 	}
+	// })
+	export default {
+		
+	}
+</script>
+
+<style>
+
+</style>
\ No newline at end of file
diff --git a/uni_modules/lime-shared/createAnimation/index.ts b/uni_modules/lime-shared/createAnimation/index.ts
new file mode 100644
index 0000000..999ec1c
--- /dev/null
+++ b/uni_modules/lime-shared/createAnimation/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X
+export * from './type.ts'
+export * from './vue.ts'
+// #endif
+
+// #ifdef UNI-APP-X
+export * from './uvue.ts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/createAnimation/type.ts b/uni_modules/lime-shared/createAnimation/type.ts
new file mode 100644
index 0000000..0f8ad34
--- /dev/null
+++ b/uni_modules/lime-shared/createAnimation/type.ts
@@ -0,0 +1,25 @@
+export type CreateAnimationOptions = {
+	/**
+	 * 动画持续时间,单位ms
+	 */
+	duration ?: number;
+	/**
+	 * 定义动画的效果
+	 * - linear: 动画从头到尾的速度是相同的
+	 * - ease: 动画以低速开始,然后加快,在结束前变慢
+	 * - ease-in: 动画以低速开始
+	 * - ease-in-out: 动画以低速开始和结束
+	 * - ease-out: 动画以低速结束
+	 * - step-start: 动画第一帧就跳至结束状态直到结束
+	 * - step-end: 动画一直保持开始状态,最后一帧跳到结束状态
+	 */
+	timingFunction ?: string //'linear' | 'ease' | 'ease-in' | 'ease-in-out' | 'ease-out' | 'step-start' | 'step-end';
+	/**
+	 * 动画延迟时间,单位 ms
+	 */
+	delay ?: number;
+	/**
+	 * 设置transform-origin
+	 */
+	transformOrigin ?: string;
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/createAnimation/uvue.ts b/uni_modules/lime-shared/createAnimation/uvue.ts
new file mode 100644
index 0000000..96d8263
--- /dev/null
+++ b/uni_modules/lime-shared/createAnimation/uvue.ts
@@ -0,0 +1,5 @@
+// @ts-nocheck
+// export * from '@/uni_modules/lime-animateIt'
+export function createAnimation() {
+	console.error('当前环境不支持,请使用:lime-animateIt')
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/createAnimation/vue.ts b/uni_modules/lime-shared/createAnimation/vue.ts
new file mode 100644
index 0000000..d6223d8
--- /dev/null
+++ b/uni_modules/lime-shared/createAnimation/vue.ts
@@ -0,0 +1,148 @@
+// @ts-nocheck
+// nvue 需要在节点上设置ref或在export里传入
+// const animation = createAnimation({
+//   ref: this.$refs['xxx'],
+// 	 duration: 0,
+// 	 timingFunction: 'linear'
+// })
+// animation.opacity(1).translate(x, y).step({duration})
+// animation.export(ref)
+
+// 抹平nvue 与 uni.createAnimation的使用差距
+// 但是nvue动画太慢
+
+
+
+import { CreateAnimationOptions } from './type'
+// #ifdef APP-NVUE
+const nvueAnimation = uni.requireNativePlugin('animation')
+
+type AnimationTypes = 'matrix' | 'matrix3d' | 'rotate' | 'rotate3d' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scale' | 'scale3d' | 'scaleX' | 'scaleY' | 'scaleZ' | 'skew' | 'skewX' | 'skewY' | 'translate' | 'translate3d' | 'translateX' | 'translateY' | 'translateZ'
+	| 'opacity' | 'backgroundColor' | 'width' | 'height' | 'left' | 'right' | 'top' | 'bottom'
+
+interface Styles {
+	[key : string] : any
+}
+	
+interface StepConfig {
+	duration?: number
+	timingFunction?: string
+	delay?: number
+	needLayout?: boolean
+	transformOrigin?: string
+}
+interface StepAnimate {
+	styles?: Styles
+	config?: StepConfig
+}
+interface StepAnimates {
+	[key: number]: StepAnimate
+}
+// export interface CreateAnimationOptions extends UniApp.CreateAnimationOptions {
+// 	ref?: string
+// }
+
+type Callback = (time: number) => void
+const animateTypes1 : AnimationTypes[] = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
+	'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
+	'translateZ'
+]
+const animateTypes2 : AnimationTypes[] = ['opacity', 'backgroundColor']
+const animateTypes3 : AnimationTypes[] = ['width', 'height', 'left', 'right', 'top', 'bottom']
+
+class LimeAnimation {
+	ref : any
+	context : any
+	options : UniApp.CreateAnimationOptions
+	// stack : any[] = []
+	next : number = 0
+	currentStepAnimates : StepAnimates = {}
+	duration : number = 0
+	constructor(options : CreateAnimationOptions) {
+		const {ref} = options
+		this.ref = ref
+		this.options = options
+	}
+	addAnimate(type : AnimationTypes, args: (string | number)[]) {
+		let aniObj = this.currentStepAnimates[this.next]
+		let stepAnimate:StepAnimate = {}
+		if (!aniObj) {
+			stepAnimate = {styles: {}, config: {}}
+		} else {
+			stepAnimate = aniObj
+		}
+
+		if (animateTypes1.includes(type)) {
+			if (!stepAnimate.styles.transform) {
+				stepAnimate.styles.transform = ''
+			}
+			let unit = ''
+			if (type === 'rotate') {
+				unit = 'deg'
+			}
+			stepAnimate.styles.transform += `${type}(${args.map((v: number) => v + unit).join(',')}) `
+		} else {
+			stepAnimate.styles[type] = `${args.join(',')}`
+		}
+		this.currentStepAnimates[this.next] = stepAnimate
+	}
+	animateRun(styles: Styles = {}, config:StepConfig = {}, ref: any) {
+		const el = ref || this.ref
+		if (!el) return
+		return new Promise((resolve) => {
+			const time = +new Date()
+			nvueAnimation.transition(el, {
+				styles,
+				...config
+			}, () => {
+				resolve(+new Date() - time)
+			})
+		})
+	}
+	nextAnimate(animates: StepAnimates, step: number = 0, ref: any, cb: Callback) {
+		let obj = animates[step]
+		if (obj) {
+			let { styles, config } = obj
+			// this.duration += config.duration
+			this.animateRun(styles, config, ref).then((time: number) => {
+				step += 1
+				this.duration += time
+				this.nextAnimate(animates, step, ref, cb)
+			})
+		} else {
+			this.currentStepAnimates = {}
+			cb && cb(this.duration)
+		}
+	}
+	step(config:StepConfig = {}) {
+		this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
+		this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
+		this.next++
+		return this
+	}
+	export(ref: any, cb?: Callback) {
+		ref = ref || this.ref
+		if(!ref) return
+		this.duration = 0
+		this.next = 0
+		this.nextAnimate(this.currentStepAnimates, 0, ref, cb)
+		return null
+	}
+}
+
+
+animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
+	LimeAnimation.prototype[type] = function(...args: (string | number)[]) {
+		this.addAnimate(type, args)
+		return this
+	}
+})
+// #endif
+export function createAnimation(options : CreateAnimationOptions) {
+	// #ifndef APP-NVUE
+	return uni.createAnimation({ ...options })
+	// #endif
+	// #ifdef APP-NVUE
+	return new LimeAnimation(options)
+	// #endif
+}
diff --git a/uni_modules/lime-shared/createCanvas/index.ts b/uni_modules/lime-shared/createCanvas/index.ts
new file mode 100644
index 0000000..987be92
--- /dev/null
+++ b/uni_modules/lime-shared/createCanvas/index.ts
@@ -0,0 +1,73 @@
+
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+import type { ComponentInternalInstance } from '@/uni_modules/lime-shared/vue'
+import { getRect } from '@/uni_modules/lime-shared/getRect'
+import { canIUseCanvas2d } from '@/uni_modules/lime-shared/canIUseCanvas2d'
+export const isCanvas2d = canIUseCanvas2d()
+// #endif
+
+
+export function createCanvas(canvasId : string, component : ComponentInternalInstance) {
+	// #ifdef UNI-APP-X
+	uni.createCanvasContextAsync({
+		canvasId,
+		component,
+		success(context : CanvasContext) {
+
+		},
+		fail(error : UniError) {
+
+		}
+	})
+	// #endif
+	// #ifndef UNI-APP-X
+	const isCanvas2d = canIUseCanvas2d()
+	getRect('#' + canvasId, context, isCanvas2d).then(res => {
+		if (res.node) {
+			res.node.width = res.width
+			res.node.height = res.height
+			return res.node
+		} else {
+			const ctx = uni.createCanvasContext(canvasId, context)
+			if (!ctx._drawImage) {
+				ctx._drawImage = ctx.drawImage
+				ctx.drawImage = function (...args) {
+					const { path } = args.shift()
+					ctx._drawImage(path, ...args)
+				}
+			}
+			if (!ctx.getImageData) {
+				ctx.getImageData = function () {
+					return new Promise((resolve, reject) => {
+						uni.canvasGetImageData({
+							canvasId,
+							x: parseInt(arguments[0]),
+							y: parseInt(arguments[1]),
+							width: parseInt(arguments[2]),
+							height: parseInt(arguments[3]),
+							success(res) {
+								resolve(res)
+							},
+							fail(err) {
+								reject(err)
+							}
+						}, context)
+					})
+
+				}
+				return {
+					getContext(type: string) {
+						if(type == '2d') {
+							return ctx
+						}
+					},
+					width: res.width,
+					height: res.height,
+					createImage
+				}
+			}
+		}
+	})
+	// #endif
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/createImage/index.ts b/uni_modules/lime-shared/createImage/index.ts
new file mode 100644
index 0000000..c9e72fe
--- /dev/null
+++ b/uni_modules/lime-shared/createImage/index.ts
@@ -0,0 +1,71 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+import {isBrowser} from '../isBrowser'
+class Image {
+	currentSrc: string | null = null
+	naturalHeight: number = 0
+	naturalWidth: number = 0
+	width: number = 0
+	height: number = 0
+	tagName: string = 'IMG'
+	path: string = ''
+	crossOrigin: string = ''
+	referrerPolicy: string = ''
+	onload: () => void = () => {}
+	onerror: () => void = () => {}
+	complete: boolean = false
+	constructor() {}
+	set src(src: string) {
+		console.log('src', src)
+		if(!src) {
+			return this.onerror()
+		}
+		src = src.replace(/^@\//,'/')
+		this.currentSrc = src
+		uni.getImageInfo({
+			src,
+			success: (res) => {
+				const localReg = /^\.|^\/(?=[^\/])/;
+				// #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
+				res.path = localReg.test(src) ?  `/${res.path}` : res.path;
+				// #endif
+				this.complete = true
+				this.path = res.path
+				this.naturalWidth = this.width = res.width
+				this.naturalHeight = this.height = res.height
+				this.onload()
+			},
+			fail: () => {
+				this.onerror()
+			}
+		})
+	}
+	get src() {
+		return this.currentSrc
+	}
+}
+interface UniImage extends WechatMiniprogram.Image {
+	complete?: boolean
+	naturalHeight?: number
+	naturalWidth?: number
+}
+/** 创建用于 canvas 的 img */
+export function createImage(canvas?: any): HTMLImageElement | UniImage {
+	if(canvas && canvas.createImage) {
+		return (canvas as WechatMiniprogram.Canvas).createImage()
+	} else if(this && this['tagName'] == 'canvas' && !('toBlob' in this) || canvas && !('toBlob' in canvas)){
+		return new Image()
+	} else if(isBrowser) {
+		return new window.Image()
+	}
+	return new Image()
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export function createImage():Image{
+	// console.error('当前环境不支持')
+	return new Image()
+}
+// #endif
diff --git a/uni_modules/lime-shared/debounce/index.ts b/uni_modules/lime-shared/debounce/index.ts
new file mode 100644
index 0000000..a168ca3
--- /dev/null
+++ b/uni_modules/lime-shared/debounce/index.ts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+
+// #endif
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/debounce/uvue.ts b/uni_modules/lime-shared/debounce/uvue.ts
new file mode 100644
index 0000000..f1fc29d
--- /dev/null
+++ b/uni_modules/lime-shared/debounce/uvue.ts
@@ -0,0 +1,36 @@
+// @ts-nocheck
+/**
+ * 防抖函数,通过延迟一定时间来限制函数的执行频率。
+ * @param fn 要防抖的函数。
+ * @param wait 触发防抖的等待时间,单位为毫秒。
+ * @returns 防抖函数。
+ */
+export function debounce<A extends any>(fn : (args: A)=> void, wait = 300): (args: A)=> void {
+	let timer = -1
+	
+	return (args: A) => {
+		if (timer >-1) {clearTimeout(timer)};
+		
+		timer = setTimeout(()=>{
+			fn(args)
+		}, wait)
+	}
+};
+
+
+
+// 示例
+// 定义一个函数
+// function saveData(data: string) {
+//   // 模拟保存数据的操作
+//   console.log(`Saving data: ${data}`);
+// }
+
+// // 创建一个防抖函数,延迟 500 毫秒后调用 saveData 函数
+// const debouncedSaveData = debounce(saveData, 500);
+
+// // 连续调用防抖函数
+// debouncedSaveData('Data 1'); // 不会立即调用 saveData 函数
+// debouncedSaveData('Data 2'); // 不会立即调用 saveData 函数
+
+// 在 500 毫秒后,只会调用一次 saveData 函数,输出结果为 "Saving data: Data 2"
\ No newline at end of file
diff --git a/uni_modules/lime-shared/debounce/vue.ts b/uni_modules/lime-shared/debounce/vue.ts
new file mode 100644
index 0000000..694b44d
--- /dev/null
+++ b/uni_modules/lime-shared/debounce/vue.ts
@@ -0,0 +1,40 @@
+// @ts-nocheck
+type Timeout = ReturnType<typeof setTimeout> | null;
+/**
+ * 防抖函数,通过延迟一定时间来限制函数的执行频率。
+ * @param fn 要防抖的函数。
+ * @param wait 触发防抖的等待时间,单位为毫秒。
+ * @returns 防抖函数。
+ */
+export function debounce<A extends any, R>(
+	fn : (...args : A) => R,
+	wait : number = 300) : (...args : A) => void {
+	let timer : Timeout = null; 
+
+	return function (...args : A) {
+		if (timer) clearTimeout(timer); // 如果上一个 setTimeout 存在,则清除它
+
+		// 设置一个新的 setTimeout,在指定的等待时间后调用防抖函数
+		timer = setTimeout(() => {
+			fn.apply(this, args); // 使用提供的参数调用原始函数
+		}, wait);
+	};
+};
+
+
+
+// 示例
+// 定义一个函数
+// function saveData(data: string) {
+//   // 模拟保存数据的操作
+//   console.log(`Saving data: ${data}`);
+// }
+
+// // 创建一个防抖函数,延迟 500 毫秒后调用 saveData 函数
+// const debouncedSaveData = debounce(saveData, 500);
+
+// // 连续调用防抖函数
+// debouncedSaveData('Data 1'); // 不会立即调用 saveData 函数
+// debouncedSaveData('Data 2'); // 不会立即调用 saveData 函数
+
+// 在 500 毫秒后,只会调用一次 saveData 函数,输出结果为 "Saving data: Data 2"
\ No newline at end of file
diff --git a/uni_modules/lime-shared/exif/index.ts b/uni_modules/lime-shared/exif/index.ts
new file mode 100644
index 0000000..c1e7e3f
--- /dev/null
+++ b/uni_modules/lime-shared/exif/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+// #endif
diff --git a/uni_modules/lime-shared/exif/uvue.ts b/uni_modules/lime-shared/exif/uvue.ts
new file mode 100644
index 0000000..01d21a2
--- /dev/null
+++ b/uni_modules/lime-shared/exif/uvue.ts
@@ -0,0 +1,7 @@
+class EXIF {
+	constructor(){
+		console.error('当前环境不支持')
+	}
+}
+
+export const exif = new EXIF()
\ No newline at end of file
diff --git a/uni_modules/lime-shared/exif/vue.ts b/uni_modules/lime-shared/exif/vue.ts
new file mode 100644
index 0000000..86f2454
--- /dev/null
+++ b/uni_modules/lime-shared/exif/vue.ts
@@ -0,0 +1,1057 @@
+// @ts-nocheck
+import { base64ToArrayBuffer } from '../base64ToArrayBuffer';
+import { pathToBase64 } from '../pathToBase64';
+// import { isBase64 } from '../isBase64';
+import { isBase64DataUri } from '../isBase64';
+import { isString } from '../isString';
+
+interface File {
+	exifdata : any
+	iptcdata : any
+	xmpdata : any
+	src : string
+}
+class EXIF {
+	isXmpEnabled = false
+	debug = false
+	Tags = {
+		// version tags
+		0x9000: "ExifVersion", // EXIF version
+		0xA000: "FlashpixVersion", // Flashpix format version
+
+		// colorspace tags
+		0xA001: "ColorSpace", // Color space information tag
+
+		// image configuration
+		0xA002: "PixelXDimension", // Valid width of meaningful image
+		0xA003: "PixelYDimension", // Valid height of meaningful image
+		0x9101: "ComponentsConfiguration", // Information about channels
+		0x9102: "CompressedBitsPerPixel", // Compressed bits per pixel
+
+		// user information
+		0x927C: "MakerNote", // Any desired information written by the manufacturer
+		0x9286: "UserComment", // Comments by user
+
+		// related file
+		0xA004: "RelatedSoundFile", // Name of related sound file
+
+		// date and time
+		0x9003: "DateTimeOriginal", // Date and time when the original image was generated
+		0x9004: "DateTimeDigitized", // Date and time when the image was stored digitally
+		0x9290: "SubsecTime", // Fractions of seconds for DateTime
+		0x9291: "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal
+		0x9292: "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized
+
+		// picture-taking conditions
+		0x829A: "ExposureTime", // Exposure time (in seconds)
+		0x829D: "FNumber", // F number
+		0x8822: "ExposureProgram", // Exposure program
+		0x8824: "SpectralSensitivity", // Spectral sensitivity
+		0x8827: "ISOSpeedRatings", // ISO speed rating
+		0x8828: "OECF", // Optoelectric conversion factor
+		0x9201: "ShutterSpeedValue", // Shutter speed
+		0x9202: "ApertureValue", // Lens aperture
+		0x9203: "BrightnessValue", // Value of brightness
+		0x9204: "ExposureBias", // Exposure bias
+		0x9205: "MaxApertureValue", // Smallest F number of lens
+		0x9206: "SubjectDistance", // Distance to subject in meters
+		0x9207: "MeteringMode", // Metering mode
+		0x9208: "LightSource", // Kind of light source
+		0x9209: "Flash", // Flash status
+		0x9214: "SubjectArea", // Location and area of main subject
+		0x920A: "FocalLength", // Focal length of the lens in mm
+		0xA20B: "FlashEnergy", // Strobe energy in BCPS
+		0xA20C: "SpatialFrequencyResponse", //
+		0xA20E: "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
+		0xA20F: "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
+		0xA210: "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
+		0xA214: "SubjectLocation", // Location of subject in image
+		0xA215: "ExposureIndex", // Exposure index selected on camera
+		0xA217: "SensingMethod", // Image sensor type
+		0xA300: "FileSource", // Image source (3 == DSC)
+		0xA301: "SceneType", // Scene type (1 == directly photographed)
+		0xA302: "CFAPattern", // Color filter array geometric pattern
+		0xA401: "CustomRendered", // Special processing
+		0xA402: "ExposureMode", // Exposure mode
+		0xA403: "WhiteBalance", // 1 = auto white balance, 2 = manual
+		0xA404: "DigitalZoomRation", // Digital zoom ratio
+		0xA405: "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm)
+		0xA406: "SceneCaptureType", // Type of scene
+		0xA407: "GainControl", // Degree of overall image gain adjustment
+		0xA408: "Contrast", // Direction of contrast processing applied by camera
+		0xA409: "Saturation", // Direction of saturation processing applied by camera
+		0xA40A: "Sharpness", // Direction of sharpness processing applied by camera
+		0xA40B: "DeviceSettingDescription", //
+		0xA40C: "SubjectDistanceRange", // Distance to subject
+
+		// other tags
+		0xA005: "InteroperabilityIFDPointer",
+		0xA420: "ImageUniqueID" // Identifier assigned uniquely to each image
+	}
+	TiffTags = {
+		0x0100: "ImageWidth",
+		0x0101: "ImageHeight",
+		0x8769: "ExifIFDPointer",
+		0x8825: "GPSInfoIFDPointer",
+		0xA005: "InteroperabilityIFDPointer",
+		0x0102: "BitsPerSample",
+		0x0103: "Compression",
+		0x0106: "PhotometricInterpretation",
+		0x0112: "Orientation",
+		0x0115: "SamplesPerPixel",
+		0x011C: "PlanarConfiguration",
+		0x0212: "YCbCrSubSampling",
+		0x0213: "YCbCrPositioning",
+		0x011A: "XResolution",
+		0x011B: "YResolution",
+		0x0128: "ResolutionUnit",
+		0x0111: "StripOffsets",
+		0x0116: "RowsPerStrip",
+		0x0117: "StripByteCounts",
+		0x0201: "JPEGInterchangeFormat",
+		0x0202: "JPEGInterchangeFormatLength",
+		0x012D: "TransferFunction",
+		0x013E: "WhitePoint",
+		0x013F: "PrimaryChromaticities",
+		0x0211: "YCbCrCoefficients",
+		0x0214: "ReferenceBlackWhite",
+		0x0132: "DateTime",
+		0x010E: "ImageDescription",
+		0x010F: "Make",
+		0x0110: "Model",
+		0x0131: "Software",
+		0x013B: "Artist",
+		0x8298: "Copyright"
+	}
+	GPSTags = {
+		0x0000: "GPSVersionID",
+		0x0001: "GPSLatitudeRef",
+		0x0002: "GPSLatitude",
+		0x0003: "GPSLongitudeRef",
+		0x0004: "GPSLongitude",
+		0x0005: "GPSAltitudeRef",
+		0x0006: "GPSAltitude",
+		0x0007: "GPSTimeStamp",
+		0x0008: "GPSSatellites",
+		0x0009: "GPSStatus",
+		0x000A: "GPSMeasureMode",
+		0x000B: "GPSDOP",
+		0x000C: "GPSSpeedRef",
+		0x000D: "GPSSpeed",
+		0x000E: "GPSTrackRef",
+		0x000F: "GPSTrack",
+		0x0010: "GPSImgDirectionRef",
+		0x0011: "GPSImgDirection",
+		0x0012: "GPSMapDatum",
+		0x0013: "GPSDestLatitudeRef",
+		0x0014: "GPSDestLatitude",
+		0x0015: "GPSDestLongitudeRef",
+		0x0016: "GPSDestLongitude",
+		0x0017: "GPSDestBearingRef",
+		0x0018: "GPSDestBearing",
+		0x0019: "GPSDestDistanceRef",
+		0x001A: "GPSDestDistance",
+		0x001B: "GPSProcessingMethod",
+		0x001C: "GPSAreaInformation",
+		0x001D: "GPSDateStamp",
+		0x001E: "GPSDifferential"
+	}
+	// EXIF 2.3 Spec
+	IFD1Tags = {
+		0x0100: "ImageWidth",
+		0x0101: "ImageHeight",
+		0x0102: "BitsPerSample",
+		0x0103: "Compression",
+		0x0106: "PhotometricInterpretation",
+		0x0111: "StripOffsets",
+		0x0112: "Orientation",
+		0x0115: "SamplesPerPixel",
+		0x0116: "RowsPerStrip",
+		0x0117: "StripByteCounts",
+		0x011A: "XResolution",
+		0x011B: "YResolution",
+		0x011C: "PlanarConfiguration",
+		0x0128: "ResolutionUnit",
+		0x0201: "JpegIFOffset", // When image format is JPEG, this value show offset to JPEG data stored.(aka "ThumbnailOffset" or "JPEGInterchangeFormat")
+		0x0202: "JpegIFByteCount", // When image format is JPEG, this value shows data size of JPEG image (aka "ThumbnailLength" or "JPEGInterchangeFormatLength")
+		0x0211: "YCbCrCoefficients",
+		0x0212: "YCbCrSubSampling",
+		0x0213: "YCbCrPositioning",
+		0x0214: "ReferenceBlackWhite"
+	}
+	StringValues = {
+		ExposureProgram: {
+			0: "Not defined",
+			1: "Manual",
+			2: "Normal program",
+			3: "Aperture priority",
+			4: "Shutter priority",
+			5: "Creative program",
+			6: "Action program",
+			7: "Portrait mode",
+			8: "Landscape mode"
+		},
+		MeteringMode: {
+			0: "Unknown",
+			1: "Average",
+			2: "CenterWeightedAverage",
+			3: "Spot",
+			4: "MultiSpot",
+			5: "Pattern",
+			6: "Partial",
+			255: "Other"
+		},
+		LightSource: {
+			0: "Unknown",
+			1: "Daylight",
+			2: "Fluorescent",
+			3: "Tungsten (incandescent light)",
+			4: "Flash",
+			9: "Fine weather",
+			10: "Cloudy weather",
+			11: "Shade",
+			12: "Daylight fluorescent (D 5700 - 7100K)",
+			13: "Day white fluorescent (N 4600 - 5400K)",
+			14: "Cool white fluorescent (W 3900 - 4500K)",
+			15: "White fluorescent (WW 3200 - 3700K)",
+			17: "Standard light A",
+			18: "Standard light B",
+			19: "Standard light C",
+			20: "D55",
+			21: "D65",
+			22: "D75",
+			23: "D50",
+			24: "ISO studio tungsten",
+			255: "Other"
+		},
+		Flash: {
+			0x0000: "Flash did not fire",
+			0x0001: "Flash fired",
+			0x0005: "Strobe return light not detected",
+			0x0007: "Strobe return light detected",
+			0x0009: "Flash fired, compulsory flash mode",
+			0x000D: "Flash fired, compulsory flash mode, return light not detected",
+			0x000F: "Flash fired, compulsory flash mode, return light detected",
+			0x0010: "Flash did not fire, compulsory flash mode",
+			0x0018: "Flash did not fire, auto mode",
+			0x0019: "Flash fired, auto mode",
+			0x001D: "Flash fired, auto mode, return light not detected",
+			0x001F: "Flash fired, auto mode, return light detected",
+			0x0020: "No flash function",
+			0x0041: "Flash fired, red-eye reduction mode",
+			0x0045: "Flash fired, red-eye reduction mode, return light not detected",
+			0x0047: "Flash fired, red-eye reduction mode, return light detected",
+			0x0049: "Flash fired, compulsory flash mode, red-eye reduction mode",
+			0x004D: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
+			0x004F: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
+			0x0059: "Flash fired, auto mode, red-eye reduction mode",
+			0x005D: "Flash fired, auto mode, return light not detected, red-eye reduction mode",
+			0x005F: "Flash fired, auto mode, return light detected, red-eye reduction mode"
+		},
+		SensingMethod: {
+			1: "Not defined",
+			2: "One-chip color area sensor",
+			3: "Two-chip color area sensor",
+			4: "Three-chip color area sensor",
+			5: "Color sequential area sensor",
+			7: "Trilinear sensor",
+			8: "Color sequential linear sensor"
+		},
+		SceneCaptureType: {
+			0: "Standard",
+			1: "Landscape",
+			2: "Portrait",
+			3: "Night scene"
+		},
+		SceneType: {
+			1: "Directly photographed"
+		},
+		CustomRendered: {
+			0: "Normal process",
+			1: "Custom process"
+		},
+		WhiteBalance: {
+			0: "Auto white balance",
+			1: "Manual white balance"
+		},
+		GainControl: {
+			0: "None",
+			1: "Low gain up",
+			2: "High gain up",
+			3: "Low gain down",
+			4: "High gain down"
+		},
+		Contrast: {
+			0: "Normal",
+			1: "Soft",
+			2: "Hard"
+		},
+		Saturation: {
+			0: "Normal",
+			1: "Low saturation",
+			2: "High saturation"
+		},
+		Sharpness: {
+			0: "Normal",
+			1: "Soft",
+			2: "Hard"
+		},
+		SubjectDistanceRange: {
+			0: "Unknown",
+			1: "Macro",
+			2: "Close view",
+			3: "Distant view"
+		},
+		FileSource: {
+			3: "DSC"
+		},
+
+		Components: {
+			0: "",
+			1: "Y",
+			2: "Cb",
+			3: "Cr",
+			4: "R",
+			5: "G",
+			6: "B"
+		}
+	}
+	enableXmp() {
+		this.isXmpEnabled = true
+	}
+	disableXmp() {
+		this.isXmpEnabled = false;
+	}
+	/**
+	 * 获取图片数据
+	 * @param img 图片地址
+	 * @param callback 回调 返回图片数据
+	 * */
+	getData(img : any, callback : Function) {
+		// if (((self.Image && img instanceof self.Image) || (self.HTMLImageElement && img instanceof self.HTMLImageElement)) && !img.complete)
+		// 	return false;
+		let file : File = {
+			src: '',
+			exifdata: null,
+			iptcdata: null,
+			xmpdata: null,
+		}
+		if (isBase64(img)) {
+			file.src = img
+		} else if (img.path) {
+			file.src = img.path
+		} else if (isString(img)) {
+			file.src = img
+		} else {
+			return false;
+		}
+
+
+		if (!imageHasData(file)) {
+			getImageData(file, callback);
+		} else {
+			if (callback) {
+				callback.call(file);
+			}
+		}
+		return true;
+	}
+	/**
+	 * 获取图片tag
+	 * @param img 图片数据
+	 * @param tag tag 类型
+	 * */
+	getTag(img : File, tag : string) {
+		if (!imageHasData(img)) return;
+		return img.exifdata[tag];
+	}
+	getIptcTag(img : File, tag : string) {
+		if (!imageHasData(img)) return;
+		return img.iptcdata[tag];
+	}
+	getAllTags(img : File) {
+		if (!imageHasData(img)) return {};
+		let a,
+			data = img.exifdata,
+			tags = {};
+		for (a in data) {
+			if (data.hasOwnProperty(a)) {
+				tags[a] = data[a];
+			}
+		}
+		return tags;
+	}
+	getAllIptcTags(img : File) {
+		if (!imageHasData(img)) return {};
+		let a,
+			data = img.iptcdata,
+			tags = {};
+		for (a in data) {
+			if (data.hasOwnProperty(a)) {
+				tags[a] = data[a];
+			}
+		}
+		return tags;
+	}
+	pretty(img : File) {
+		if (!imageHasData(img)) return "";
+		let a,
+			data = img.exifdata,
+			strPretty = "";
+		for (a in data) {
+			if (data.hasOwnProperty(a)) {
+				if (typeof data[a] == "object") {
+					if (data[a] instanceof Number) {
+						strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a]
+							.denominator + "]\r\n";
+					} else {
+						strPretty += a + " : [" + data[a].length + " values]\r\n";
+					}
+				} else {
+					strPretty += a + " : " + data[a] + "\r\n";
+				}
+			}
+		}
+		return strPretty;
+	}
+	readFromBinaryFile(file: ArrayBuffer) {
+		return findEXIFinJPEG(file);
+	}
+}
+
+export const exif = new EXIF()
+// export function getData(img, callback) {
+// 	const exif = new EXIF()
+// 	exif.getData(img, callback)
+// }
+
+// export default {getData}
+const ExifTags = exif.Tags
+const TiffTags = exif.TiffTags
+const IFD1Tags = exif.IFD1Tags
+const GPSTags = exif.GPSTags
+const StringValues = exif.StringValues
+
+
+function imageHasData(img : File) : boolean {
+	return !!(img.exifdata);
+}
+
+function objectURLToBlob(url : string, callback : Function) {
+	try {
+		const http = new XMLHttpRequest();
+		http.open("GET", url, true);
+		http.responseType = "blob";
+		http.onload = function (e) {
+			if (this.status == 200 || this.status === 0) {
+				callback(this.response);
+			}
+		};
+		http.send();
+	} catch (e) {
+		console.warn(e)
+	}
+}
+
+
+function getImageData(img : File, callback : Function) {
+	function handleBinaryFile(binFile: ArrayBuffer) {
+		const data = findEXIFinJPEG(binFile);
+		img.exifdata = data ?? {};
+		const iptcdata = findIPTCinJPEG(binFile);
+		img.iptcdata = iptcdata ?? {};
+		if (exif.isXmpEnabled) {
+			const xmpdata = findXMPinJPEG(binFile);
+			img.xmpdata = xmpdata ?? {};
+		}
+		if (callback) {
+			callback.call(img);
+		}
+	}
+
+	if (img.src) {
+		if (/^data\:/i.test(img.src)) { // Data URI
+			// var arrayBuffer = base64ToArrayBuffer(img.src);
+			handleBinaryFile(base64ToArrayBuffer(img.src));
+
+		} else if (/^blob\:/i.test(img.src) && typeof FileReader !== 'undefined') { // Object URL
+			var fileReader = new FileReader();
+			fileReader.onload = function (e) {
+				handleBinaryFile(e.target.result);
+			};
+			objectURLToBlob(img.src, function (blob : Blob) {
+				fileReader.readAsArrayBuffer(blob);
+			});
+		} else if (typeof XMLHttpRequest !== 'undefined') {
+			var http = new XMLHttpRequest();
+			http.onload = function () {
+				if (this.status == 200 || this.status === 0) {
+					handleBinaryFile(http.response);
+				} else {
+					throw "Could not load image";
+				}
+				http = null;
+			};
+			http.open("GET", img.src, true);
+			http.responseType = "arraybuffer";
+			http.send(null);
+		} else {
+			pathToBase64(img.src).then(res => {
+				handleBinaryFile(base64ToArrayBuffer(res));
+			})
+		}
+	} else if (typeof FileReader !== 'undefined' && self.FileReader && (img instanceof self.Blob || img instanceof self.File)) {
+		var fileReader = new FileReader();
+		fileReader.onload = function (e : any) {
+			if (exif.debug) console.log("Got file of length " + e.target.result.byteLength);
+			handleBinaryFile(e.target.result);
+		};
+
+		fileReader.readAsArrayBuffer(img);
+	}
+}
+
+function findEXIFinJPEG(file: ArrayBuffer) {
+	const dataView = new DataView(file);
+
+	if (exif.debug) console.log("Got file of length " + file.byteLength);
+	if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+		if (exif.debug) console.log("Not a valid JPEG");
+		return false; // not a valid jpeg
+	}
+
+	let offset = 2,
+		length = file.byteLength,
+		marker;
+
+	while (offset < length) {
+		if (dataView.getUint8(offset) != 0xFF) {
+			if (exif.debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(
+				offset));
+			return false; // not a valid marker, something is wrong
+		}
+
+		marker = dataView.getUint8(offset + 1);
+		if (exif.debug) console.log(marker);
+
+		// we could implement handling for other markers here,
+		// but we're only looking for 0xFFE1 for EXIF data
+
+		if (marker == 225) {
+			if (exif.debug) console.log("Found 0xFFE1 marker");
+
+			return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
+
+			// offset += 2 + file.getShortAt(offset+2, true);
+
+		} else {
+			offset += 2 + dataView.getUint16(offset + 2);
+		}
+
+	}
+
+}
+
+function findIPTCinJPEG(file: ArrayBuffer) {
+	const dataView = new DataView(file);
+
+	if (exif.debug) console.log("Got file of length " + file.byteLength);
+	if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+		if (exif.debug) console.log("Not a valid JPEG");
+		return false; // not a valid jpeg
+	}
+
+	let offset = 2,
+		length = file.byteLength;
+
+
+	const isFieldSegmentStart = function (dataView, offset: number) {
+		return (
+			dataView.getUint8(offset) === 0x38 &&
+			dataView.getUint8(offset + 1) === 0x42 &&
+			dataView.getUint8(offset + 2) === 0x49 &&
+			dataView.getUint8(offset + 3) === 0x4D &&
+			dataView.getUint8(offset + 4) === 0x04 &&
+			dataView.getUint8(offset + 5) === 0x04
+		);
+	};
+
+	while (offset < length) {
+
+		if (isFieldSegmentStart(dataView, offset)) {
+
+			// Get the length of the name header (which is padded to an even number of bytes)
+			var nameHeaderLength = dataView.getUint8(offset + 7);
+			if (nameHeaderLength % 2 !== 0) nameHeaderLength += 1;
+			// Check for pre photoshop 6 format
+			if (nameHeaderLength === 0) {
+				// Always 4
+				nameHeaderLength = 4;
+			}
+
+			var startOffset = offset + 8 + nameHeaderLength;
+			var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength);
+
+			return readIPTCData(file, startOffset, sectionLength);
+
+			break;
+
+		}
+
+
+		// Not the marker, continue searching
+		offset++;
+
+	}
+
+}
+
+const IptcFieldMap = {
+	0x78: 'caption',
+	0x6E: 'credit',
+	0x19: 'keywords',
+	0x37: 'dateCreated',
+	0x50: 'byline',
+	0x55: 'bylineTitle',
+	0x7A: 'captionWriter',
+	0x69: 'headline',
+	0x74: 'copyright',
+	0x0F: 'category'
+};
+
+function readIPTCData(file: ArrayBuffer, startOffset: number, sectionLength: number) {
+	const dataView = new DataView(file);
+	let data = {};
+	let fieldValue, fieldName, dataSize, segmentType, segmentSize;
+	let segmentStartPos = startOffset;
+	while (segmentStartPos < startOffset + sectionLength) {
+		if (dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos + 1) === 0x02) {
+			segmentType = dataView.getUint8(segmentStartPos + 2);
+			if (segmentType in IptcFieldMap) {
+				dataSize = dataView.getInt16(segmentStartPos + 3);
+				segmentSize = dataSize + 5;
+				fieldName = IptcFieldMap[segmentType];
+				fieldValue = getStringFromDB(dataView, segmentStartPos + 5, dataSize);
+				// Check if we already stored a value with this name
+				if (data.hasOwnProperty(fieldName)) {
+					// Value already stored with this name, create multivalue field
+					if (data[fieldName] instanceof Array) {
+						data[fieldName].push(fieldValue);
+					} else {
+						data[fieldName] = [data[fieldName], fieldValue];
+					}
+				} else {
+					data[fieldName] = fieldValue;
+				}
+			}
+
+		}
+		segmentStartPos++;
+	}
+	return data;
+}
+
+function readTags(file: DataView, tiffStart: number, dirStart: number, strings: any[], bigEnd: number) {
+	let entries = file.getUint16(dirStart, !bigEnd),
+		tags = {},
+		entryOffset, tag;
+
+	for (let i = 0; i < entries; i++) {
+		entryOffset = dirStart + i * 12 + 2;
+		tag = strings[file.getUint16(entryOffset, !bigEnd)];
+		if (!tag && exif.debug) console.log("Unknown tag: " + file.getUint16(entryOffset, !bigEnd));
+		tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);
+	}
+	return tags;
+}
+
+function readTagValue(file: DataView, entryOffset: number, tiffStart: number, dirStart: number, bigEnd: number) {
+	let type = file.getUint16(entryOffset + 2, !bigEnd),
+		numValues = file.getUint32(entryOffset + 4, !bigEnd),
+		valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart,
+		offset,
+		vals, val, n,
+		numerator, denominator;
+
+	switch (type) {
+		case 1: // byte, 8-bit unsigned int
+		case 7: // undefined, 8-bit byte, value depending on field
+			if (numValues == 1) {
+				return file.getUint8(entryOffset + 8, !bigEnd);
+			} else {
+				offset = numValues > 4 ? valueOffset : (entryOffset + 8);
+				vals = [];
+				for (n = 0; n < numValues; n++) {
+					vals[n] = file.getUint8(offset + n);
+				}
+				return vals;
+			}
+
+		case 2: // ascii, 8-bit byte
+			offset = numValues > 4 ? valueOffset : (entryOffset + 8);
+			return getStringFromDB(file, offset, numValues - 1);
+
+		case 3: // short, 16 bit int
+			if (numValues == 1) {
+				return file.getUint16(entryOffset + 8, !bigEnd);
+			} else {
+				offset = numValues > 2 ? valueOffset : (entryOffset + 8);
+				vals = [];
+				for (n = 0; n < numValues; n++) {
+					vals[n] = file.getUint16(offset + 2 * n, !bigEnd);
+				}
+				return vals;
+			}
+
+		case 4: // long, 32 bit int
+			if (numValues == 1) {
+				return file.getUint32(entryOffset + 8, !bigEnd);
+			} else {
+				vals = [];
+				for (n = 0; n < numValues; n++) {
+					vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd);
+				}
+				return vals;
+			}
+
+		case 5: // rational = two long values, first is numerator, second is denominator
+			if (numValues == 1) {
+				numerator = file.getUint32(valueOffset, !bigEnd);
+				denominator = file.getUint32(valueOffset + 4, !bigEnd);
+				val = new Number(numerator / denominator);
+				val.numerator = numerator;
+				val.denominator = denominator;
+				return val;
+			} else {
+				vals = [];
+				for (n = 0; n < numValues; n++) {
+					numerator = file.getUint32(valueOffset + 8 * n, !bigEnd);
+					denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd);
+					vals[n] = new Number(numerator / denominator);
+					vals[n].numerator = numerator;
+					vals[n].denominator = denominator;
+				}
+				return vals;
+			}
+
+		case 9: // slong, 32 bit signed int
+			if (numValues == 1) {
+				return file.getInt32(entryOffset + 8, !bigEnd);
+			} else {
+				vals = [];
+				for (n = 0; n < numValues; n++) {
+					vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd);
+				}
+				return vals;
+			}
+
+		case 10: // signed rational, two slongs, first is numerator, second is denominator
+			if (numValues == 1) {
+				return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd);
+			} else {
+				vals = [];
+				for (n = 0; n < numValues; n++) {
+					vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 *
+						n, !bigEnd);
+				}
+				return vals;
+			}
+	}
+}
+/**
+	 * Given an IFD (Image File Directory) start offset
+	 * returns an offset to next IFD or 0 if it's the last IFD.
+	 */
+function getNextIFDOffset(dataView: DataView, dirStart: number, bigEnd: number) {
+	//the first 2bytes means the number of directory entries contains in this IFD
+	var entries = dataView.getUint16(dirStart, !bigEnd);
+
+	// After last directory entry, there is a 4bytes of data,
+	// it means an offset to next IFD.
+	// If its value is '0x00000000', it means this is the last IFD and there is no linked IFD.
+
+	return dataView.getUint32(dirStart + 2 + entries * 12, !bigEnd); // each entry is 12 bytes long
+}
+
+function readThumbnailImage(dataView: DataView, tiffStart: number, firstIFDOffset: number, bigEnd: number) {
+	// get the IFD1 offset
+	const IFD1OffsetPointer = getNextIFDOffset(dataView, tiffStart + firstIFDOffset, bigEnd);
+
+	if (!IFD1OffsetPointer) {
+		// console.log('******** IFD1Offset is empty, image thumb not found ********');
+		return {};
+	} else if (IFD1OffsetPointer > dataView.byteLength) { // this should not happen
+		// console.log('******** IFD1Offset is outside the bounds of the DataView ********');
+		return {};
+	}
+	// console.log('*******  thumbnail IFD offset (IFD1) is: %s', IFD1OffsetPointer);
+
+	let thumbTags : any = readTags(dataView, tiffStart, tiffStart + IFD1OffsetPointer, IFD1Tags, bigEnd)
+
+	// EXIF 2.3 specification for JPEG format thumbnail
+
+	// If the value of Compression(0x0103) Tag in IFD1 is '6', thumbnail image format is JPEG.
+	// Most of Exif image uses JPEG format for thumbnail. In that case, you can get offset of thumbnail
+	// by JpegIFOffset(0x0201) Tag in IFD1, size of thumbnail by JpegIFByteCount(0x0202) Tag.
+	// Data format is ordinary JPEG format, starts from 0xFFD8 and ends by 0xFFD9. It seems that
+	// JPEG format and 160x120pixels of size are recommended thumbnail format for Exif2.1 or later.
+
+	if (thumbTags['Compression'] && typeof Blob !== 'undefined') {
+		// console.log('Thumbnail image found!');
+
+		switch (thumbTags['Compression']) {
+			case 6:
+				// console.log('Thumbnail image format is JPEG');
+				if (thumbTags.JpegIFOffset && thumbTags.JpegIFByteCount) {
+					// extract the thumbnail
+					var tOffset = tiffStart + thumbTags.JpegIFOffset;
+					var tLength = thumbTags.JpegIFByteCount;
+					thumbTags['blob'] = new Blob([new Uint8Array(dataView.buffer, tOffset, tLength)], {
+						type: 'image/jpeg'
+					});
+				}
+				break;
+
+			case 1:
+				console.log("Thumbnail image format is TIFF, which is not implemented.");
+				break;
+			default:
+				console.log("Unknown thumbnail image format '%s'", thumbTags['Compression']);
+		}
+	} else if (thumbTags['PhotometricInterpretation'] == 2) {
+		console.log("Thumbnail image format is RGB, which is not implemented.");
+	}
+	return thumbTags;
+}
+
+function getStringFromDB(buffer: DataView, start: number, length: number) {
+	let outstr = "";
+	for (let n = start; n < start + length; n++) {
+		outstr += String.fromCharCode(buffer.getUint8(n));
+	}
+	return outstr;
+}
+
+function readEXIFData(file: DataView, start: number) {
+	if (getStringFromDB(file, start, 4) != "Exif") {
+		if (exif.debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4));
+		return false;
+	}
+
+	let bigEnd,
+		tags, tag,
+		exifData, gpsData,
+		tiffOffset = start + 6;
+
+	// test for TIFF validity and endianness
+	if (file.getUint16(tiffOffset) == 0x4949) {
+		bigEnd = false;
+	} else if (file.getUint16(tiffOffset) == 0x4D4D) {
+		bigEnd = true;
+	} else {
+		if (exif.debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
+		return false;
+	}
+
+	if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) {
+		if (exif.debug) console.log("Not valid TIFF data! (no 0x002A)");
+		return false;
+	}
+
+	const firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd);
+
+	if (firstIFDOffset < 0x00000008) {
+		if (exif.debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset + 4,
+			!bigEnd));
+		return false;
+	}
+
+	tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);
+
+	if (tags.ExifIFDPointer) {
+		exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);
+		for (tag in exifData) {
+			switch (tag) {
+				case "LightSource":
+				case "Flash":
+				case "MeteringMode":
+				case "ExposureProgram":
+				case "SensingMethod":
+				case "SceneCaptureType":
+				case "SceneType":
+				case "CustomRendered":
+				case "WhiteBalance":
+				case "GainControl":
+				case "Contrast":
+				case "Saturation":
+				case "Sharpness":
+				case "SubjectDistanceRange":
+				case "FileSource":
+					exifData[tag] = StringValues[tag][exifData[tag]];
+					break;
+
+				case "ExifVersion":
+				case "FlashpixVersion":
+					exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2],
+						exifData[tag][3]);
+					break;
+
+				case "ComponentsConfiguration":
+					exifData[tag] =
+						StringValues.Components[exifData[tag][0]] +
+						StringValues.Components[exifData[tag][1]] +
+						StringValues.Components[exifData[tag][2]] +
+						StringValues.Components[exifData[tag][3]];
+					break;
+			}
+			tags[tag] = exifData[tag];
+		}
+	}
+
+	if (tags.GPSInfoIFDPointer) {
+		gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);
+		for (tag in gpsData) {
+			switch (tag) {
+				case "GPSVersionID":
+					gpsData[tag] = gpsData[tag][0] +
+						"." + gpsData[tag][1] +
+						"." + gpsData[tag][2] +
+						"." + gpsData[tag][3];
+					break;
+			}
+			tags[tag] = gpsData[tag];
+		}
+	}
+
+	// extract thumbnail
+	tags['thumbnail'] = readThumbnailImage(file, tiffOffset, firstIFDOffset, bigEnd);
+
+	return tags;
+}
+
+function findXMPinJPEG(file: ArrayBuffer) {
+
+	if (!('DOMParser' in self)) {
+		// console.warn('XML parsing not supported without DOMParser');
+		return;
+	}
+	const dataView = new DataView(file);
+
+	if (exif.debug) console.log("Got file of length " + file.byteLength);
+	if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
+		if (exif.debug) console.log("Not a valid JPEG");
+		return false; // not a valid jpeg
+	}
+
+	let offset = 2,
+		length = file.byteLength,
+		dom = new DOMParser();
+
+	while (offset < (length - 4)) {
+		if (getStringFromDB(dataView, offset, 4) == "http") {
+			const startOffset = offset - 1;
+			const sectionLength = dataView.getUint16(offset - 2) - 1;
+			let xmpString = getStringFromDB(dataView, startOffset, sectionLength)
+			const xmpEndIndex = xmpString.indexOf('xmpmeta>') + 8;
+			xmpString = xmpString.substring(xmpString.indexOf('<x:xmpmeta'), xmpEndIndex);
+
+			const indexOfXmp = xmpString.indexOf('x:xmpmeta') + 10
+			//Many custom written programs embed xmp/xml without any namespace. Following are some of them.
+			//Without these namespaces, XML is thought to be invalid by parsers
+			xmpString = xmpString.slice(0, indexOfXmp) +
+				'xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" ' +
+				'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
+				'xmlns:tiff="http://ns.adobe.com/tiff/1.0/" ' +
+				'xmlns:plus="http://schemas.android.com/apk/lib/com.google.android.gms.plus" ' +
+				'xmlns:ext="http://www.gettyimages.com/xsltExtension/1.0" ' +
+				'xmlns:exif="http://ns.adobe.com/exif/1.0/" ' +
+				'xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" ' +
+				'xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" ' +
+				'xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/" ' +
+				'xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/" ' +
+				'xmlns:Iptc4xmpExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/" ' +
+				xmpString.slice(indexOfXmp)
+
+			var domDocument = dom.parseFromString(xmpString, 'text/xml');
+			return xml2Object(domDocument);
+		} else {
+			offset++;
+		}
+	}
+}
+
+
+function xml2json(xml: any) {
+	var json = {};
+
+	if (xml.nodeType == 1) { // element node
+		if (xml.attributes.length > 0) {
+			json['@attributes'] = {};
+			for (var j = 0; j < xml.attributes.length; j++) {
+				var attribute = xml.attributes.item(j);
+				json['@attributes'][attribute.nodeName] = attribute.nodeValue;
+			}
+		}
+	} else if (xml.nodeType == 3) { // text node
+		return xml.nodeValue;
+	}
+
+	// deal with children
+	if (xml.hasChildNodes()) {
+		for (var i = 0; i < xml.childNodes.length; i++) {
+			var child = xml.childNodes.item(i);
+			var nodeName = child.nodeName;
+			if (json[nodeName] == null) {
+				json[nodeName] = xml2json(child);
+			} else {
+				if (json[nodeName].push == null) {
+					var old = json[nodeName];
+					json[nodeName] = [];
+					json[nodeName].push(old);
+				}
+				json[nodeName].push(xml2json(child));
+			}
+		}
+	}
+
+	return json;
+}
+
+function xml2Object(xml: any) {
+	try {
+		var obj = {};
+		if (xml.children.length > 0) {
+			for (var i = 0; i < xml.children.length; i++) {
+				var item = xml.children.item(i);
+				var attributes = item.attributes;
+				for (var idx in attributes) {
+					var itemAtt = attributes[idx];
+					var dataKey = itemAtt.nodeName;
+					var dataValue = itemAtt.nodeValue;
+
+					if (dataKey !== undefined) {
+						obj[dataKey] = dataValue;
+					}
+				}
+				var nodeName = item.nodeName;
+
+				if (typeof (obj[nodeName]) == "undefined") {
+					obj[nodeName] = xml2json(item);
+				} else {
+					if (typeof (obj[nodeName].push) == "undefined") {
+						var old = obj[nodeName];
+
+						obj[nodeName] = [];
+						obj[nodeName].push(old);
+					}
+					obj[nodeName].push(xml2json(item));
+				}
+			}
+		} else {
+			obj = xml.textContent;
+		}
+		return obj;
+	} catch (e) {
+		console.log(e.message);
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/fillZero/index.ts b/uni_modules/lime-shared/fillZero/index.ts
new file mode 100644
index 0000000..9952c45
--- /dev/null
+++ b/uni_modules/lime-shared/fillZero/index.ts
@@ -0,0 +1,11 @@
+// @ts-nocheck
+/**
+ * 在数字前填充零,返回字符串形式的结果
+ * @param number 要填充零的数字
+ * @param length 填充零后的字符串长度,默认为2
+ * @returns 填充零后的字符串
+ */
+export function fillZero(number: number, length: number = 2): string {
+  // 将数字转换为字符串,然后使用 padStart 方法填充零到指定长度
+  return `${number}`.padStart(length, '0');
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/floatAdd/index.ts b/uni_modules/lime-shared/floatAdd/index.ts
new file mode 100644
index 0000000..aad3929
--- /dev/null
+++ b/uni_modules/lime-shared/floatAdd/index.ts
@@ -0,0 +1,36 @@
+import { isNumber } from '../isNumber'
+/**
+ * 返回两个浮点数相加的结果
+ * @param num1 第一个浮点数
+ * @param num2 第二个浮点数
+ * @returns 两个浮点数的相加结果
+ */
+export function floatAdd(num1 : number, num2 : number) : number {
+	// 检查 num1 和 num2 是否为数字类型
+	if (!(isNumber(num1) || isNumber(num2))) {
+		console.warn('Please pass in the number type');
+		return NaN;
+	}
+
+	let r1 : number, r2 : number, m : number;
+
+	try {
+		// 获取 num1 小数点后的位数
+		r1 = num1.toString().split('.')[1].length;
+	} catch (error) {
+		r1 = 0;
+	}
+
+	try {
+		// 获取 num2 小数点后的位数
+		r2 = num2.toString().split('.')[1].length;
+	} catch (error) {
+		r2 = 0;
+	}
+
+	// 计算需要扩大的倍数
+	m = Math.pow(10, Math.max(r1, r2));
+
+	// 返回相加结果
+	return (num1 * m + num2 * m) / m;
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/floatDiv/index.ts b/uni_modules/lime-shared/floatDiv/index.ts
new file mode 100644
index 0000000..195d4ab
--- /dev/null
+++ b/uni_modules/lime-shared/floatDiv/index.ts
@@ -0,0 +1,45 @@
+import { floatMul } from '../floatMul';
+import { isNumber } from '../isNumber';
+
+/**
+ * 除法函数,用于处理浮点数除法并保持精度。
+ * @param {number} num1 - 被除数。
+ * @param {number} num2 - 除数。
+ * @returns {number} 除法运算的结果,保留正确的精度。
+ */
+export function floatDiv(num1:number, num2:number):number {
+  // 如果传入的不是数字类型,则打印警告并返回NaN
+  if (!isNumber(num1) || !isNumber(num2)) {
+    console.warn('请传入数字类型');
+    return NaN;
+  }
+
+  let m1 = 0, // 被除数小数点后的位数
+    m2 = 0, // 除数小数点后的位数
+    s1 = num1.toString(), // 将被除数转换为字符串
+    s2 = num2.toString(); // 将除数转换为字符串
+
+  // 计算被除数小数点后的位数
+  try {
+    m1 += s1.split('.')[1].length;
+  } catch (error) {}
+
+  // 计算除数小数点后的位数
+  try {
+    m2 += s2.split('.')[1].length;
+  } catch (error) {}
+
+  // 进行除法运算并处理小数点后的位数,使用之前定义的乘法函数保持精度
+  // #ifdef APP-ANDROID
+  return floatMul(
+    parseFloat(s1.replace('.', '')) / parseFloat(s2.replace('.', '')),
+    Math.pow(10, m2 - m1),
+  );
+  // #endif
+  // #ifndef APP-ANDROID
+  return floatMul(
+    Number(s1.replace('.', '')) / Number(s2.replace('.', '')),
+    Math.pow(10, m2 - m1),
+  );
+  // #endif
+}
diff --git a/uni_modules/lime-shared/floatMul/index.ts b/uni_modules/lime-shared/floatMul/index.ts
new file mode 100644
index 0000000..51a867e
--- /dev/null
+++ b/uni_modules/lime-shared/floatMul/index.ts
@@ -0,0 +1,44 @@
+// @ts-nocheck
+import {isNumber} from '../isNumber';
+// #ifdef APP-ANDROID
+import BigDecimal from 'java.math.BigDecimal'
+// import BigDecimal from 'java.math.BigDecimal'
+// import StringBuilder from 'java.lang.StringBuilder'
+// import java.math.BigDecimal;
+// #endif
+
+/**
+ * 乘法函数,用于处理浮点数乘法并保持精度。
+ * @param {number} num1 - 第一个乘数。
+ * @param {number} num2 - 第二个乘数。
+ * @returns {number} 乘法运算的结果,保留正确的精度。
+ */
+export function floatMul(num1 : number, num2 : number) : number {
+	if (!(isNumber(num1) || isNumber(num2))) {
+		console.warn('Please pass in the number type');
+		return NaN;
+	}
+	let m = 0;
+	// #ifdef APP-ANDROID
+	let	s1 = BigDecimal.valueOf(num1.toDouble()).toPlainString(); //new UTSNumber(num1).toString() // //`${num1.toFloat()}`// num1.toString(),
+	let	s2 = BigDecimal.valueOf(num2.toDouble()).toPlainString(); //new UTSNumber(num2).toString() //`${num2.toFloat()}`//.toString();
+	// #endif
+	// #ifndef APP-ANDROID
+	let	s1:string = `${num1}`// num1.toString(),
+	let	s2:string = `${num2}`//.toString();
+	// #endif
+	
+	try {
+		m += s1.split('.')[1].length;
+	} catch (error) { }
+	try {
+		m += s2.split('.')[1].length;
+	} catch (error) { }
+	
+	// #ifdef APP-ANDROID
+	return parseFloat(s1.replace('.', '')) * parseFloat(s2.replace('.', '')) / Math.pow(10, m);
+	// #endif
+	// #ifndef APP-ANDROID
+	return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m);
+	// #endif
+}
diff --git a/uni_modules/lime-shared/floatSub/index.ts b/uni_modules/lime-shared/floatSub/index.ts
new file mode 100644
index 0000000..9bc25cb
--- /dev/null
+++ b/uni_modules/lime-shared/floatSub/index.ts
@@ -0,0 +1,32 @@
+import { isNumber } from '../isNumber';
+/**
+ * 减法函数,用于处理浮点数减法并保持精度。
+ * @param {number} num1 - 被减数。
+ * @param {number} num2 - 减数。
+ * @returns {number} 减法运算的结果,保留正确的精度。
+ */
+export function floatSub(num1 : number, num2 : number) : number {
+	if (!(isNumber(num1) || isNumber(num2))) {
+		console.warn('Please pass in the number type');
+		return NaN;
+	}
+	let r1:number, r2:number, m:number, n:number;
+	try {
+		r1 = num1.toString().split('.')[1].length;
+	} catch (error) {
+		r1 = 0;
+	}
+	try {
+		r2 = num2.toString().split('.')[1].length;
+	} catch (error) {
+		r2 = 0;
+	}
+	m = Math.pow(10, Math.max(r1, r2));
+	n = r1 >= r2 ? r1 : r2;
+	// #ifndef APP-ANDROID
+	return Number(((num1 * m - num2 * m) / m).toFixed(n));
+	// #endif
+	// #ifdef APP-ANDROID
+	return parseFloat(((num1 * m - num2 * m) / m).toFixed(n));
+	// #endif
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getClassStr/index.ts b/uni_modules/lime-shared/getClassStr/index.ts
new file mode 100644
index 0000000..ef8c7d6
--- /dev/null
+++ b/uni_modules/lime-shared/getClassStr/index.ts
@@ -0,0 +1,53 @@
+// @ts-nocheck
+
+// #ifdef UNI-APP-X && APP
+import { isNumber } from '../isNumber'
+import { isString } from '../isString'
+import { isDef } from '../isDef'
+// #endif
+
+/**
+ * 获取对象的类名字符串
+ * @param obj - 需要处理的对象
+ * @returns 由对象属性作为类名组成的字符串
+ */
+export function getClassStr<T>(obj : T) : string {
+	let classNames : string[] = [];
+	// #ifdef UNI-APP-X && APP
+	if (obj instanceof UTSJSONObject) {
+		(obj as UTSJSONObject).toMap().forEach((value, key) => {
+			if (isDef(value)) {
+				if (isNumber(value)) {
+					classNames.push(key);
+				}
+				if (isString(value) && value !== '') {
+					classNames.push(key);
+				}
+				if (typeof value == 'boolean' && (value as boolean)) {
+					classNames.push(key);
+				}
+			}
+		})
+	} 
+	// #endif
+	// #ifndef UNI-APP-X && APP
+	// 遍历对象的属性
+	for (let key in obj) {
+		// 检查属性确实属于对象自身且其值为true
+		if ((obj as any).hasOwnProperty(key) && obj[key]) {
+			// 将属性名添加到类名数组中
+			classNames.push(key);
+		}
+	}
+	// #endif
+
+
+	// 将类名数组用空格连接成字符串并返回
+	return classNames.join(' ');
+}
+
+
+// 示例
+// const obj = { foo: true, bar: false, baz: true };
+// const classNameStr = getClassStr(obj);
+// console.log(classNameStr); // 输出: "foo baz"
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getCurrentPage/index.ts b/uni_modules/lime-shared/getCurrentPage/index.ts
new file mode 100644
index 0000000..af9a9d2
--- /dev/null
+++ b/uni_modules/lime-shared/getCurrentPage/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
diff --git a/uni_modules/lime-shared/getCurrentPage/uvue.uts b/uni_modules/lime-shared/getCurrentPage/uvue.uts
new file mode 100644
index 0000000..9e96d2b
--- /dev/null
+++ b/uni_modules/lime-shared/getCurrentPage/uvue.uts
@@ -0,0 +1,5 @@
+// @ts-nocheck
+export const getCurrentPage = ():Page => {
+  const pages = getCurrentPages();
+  return pages[pages.length - 1]
+};
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getCurrentPage/vue.ts b/uni_modules/lime-shared/getCurrentPage/vue.ts
new file mode 100644
index 0000000..79ecac8
--- /dev/null
+++ b/uni_modules/lime-shared/getCurrentPage/vue.ts
@@ -0,0 +1,6 @@
+// @ts-nocheck
+/** 获取当前页 */
+export const getCurrentPage = () => {
+  const pages = getCurrentPages();
+  return pages[pages.length - 1] //as T & WechatMiniprogram.Page.TrivialInstance;
+};
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getLocalFilePath/index.ts b/uni_modules/lime-shared/getLocalFilePath/index.ts
new file mode 100644
index 0000000..c496a07
--- /dev/null
+++ b/uni_modules/lime-shared/getLocalFilePath/index.ts
@@ -0,0 +1,62 @@
+// @ts-nocheck
+// #ifdef APP-NVUE  || APP-VUE
+export const getLocalFilePath = (path : string) => {
+	if (typeof plus == 'undefined') return path
+	if (/^(_www|_doc|_documents|_downloads|file:\/\/|\/storage\/emulated\/0\/)/.test(path)) return path
+	if (/^\//.test(path)) {
+		const localFilePath = plus.io.convertAbsoluteFileSystem(path)
+		if (localFilePath !== path) {
+			return localFilePath
+		} else {
+			path = path.slice(1)
+		}
+	}
+	return '_www/' + path
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export { getResourcePath as getLocalFilePath } from '@/uni_modules/lime-file-utils'
+// export const getLocalFilePath = (path : string) : string => {
+// 	let uri = path
+// 	if (uri.startsWith("http") || uri.startsWith("<svg") || uri.startsWith("data:image/svg+xml")) {
+// 		return uri
+// 	}
+// 	if (uri.startsWith("file://")) {
+// 		uri = uri.substring("file://".length)
+// 	} else if (uri.startsWith("unifile://")) {
+// 		uri = UTSAndroid.convert2AbsFullPath(uri)
+// 	} else {
+// 		uri = UTSAndroid.convert2AbsFullPath(uri)
+// 		if (uri.startsWith("/android_asset/")) {
+// 			uri = uri.replace("/android_asset/", "")
+// 		}
+// 	}
+// 	if (new File(uri).exists()) {
+// 		return uri
+// 	} else {
+// 		return null
+// 	}
+// 	// return UTSAndroid.convert2AbsFullPath(path)
+// }
+// #endif
+// #ifdef APP-IOS
+// export const getLocalFilePath = (path : string) : string => {
+// 	try {
+// 		let uri = path
+// 		if (uri.startsWith("http") || uri.startsWith("<svg") || uri.startsWith("data:image/svg+xml")) {
+// 			return uri
+// 		}
+// 		if (uri.startsWith("file://")) {
+// 			return uri.substring("file://".length)
+// 		} else if (path.startsWith("/var/")) {
+// 			return path
+// 		}
+// 		return UTSiOS.getResourcePath(path)
+// 	} catch (e) {
+// 		return null
+// 	}
+// 	// return UTSiOS.getResourcePath(path)
+// }
+// #endif
diff --git a/uni_modules/lime-shared/getRect/index.ts b/uni_modules/lime-shared/getRect/index.ts
new file mode 100644
index 0000000..4a82c3c
--- /dev/null
+++ b/uni_modules/lime-shared/getRect/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
+
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getRect/uvue.uts b/uni_modules/lime-shared/getRect/uvue.uts
new file mode 100644
index 0000000..abceb2d
--- /dev/null
+++ b/uni_modules/lime-shared/getRect/uvue.uts
@@ -0,0 +1,16 @@
+// @ts-nocheck
+export function getRect(selector : string, context: ComponentInternalInstance):Promise<NodeInfo> {
+	return new Promise((resolve)=>{
+		uni.createSelectorQuery().in(context).select(selector).boundingClientRect(res =>{
+			resolve(res as NodeInfo)
+		}).exec();
+	})
+}
+
+export function getAllRect(selector : string, context: ComponentInternalInstance):Promise<NodeInfo[]> {
+	return new Promise((resolve)=>{
+		uni.createSelectorQuery().in(context).selectAll(selector).boundingClientRect(res =>{
+			resolve(res as NodeInfo[])
+		}).exec();
+	})
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getRect/vue.ts b/uni_modules/lime-shared/getRect/vue.ts
new file mode 100644
index 0000000..992ad09
--- /dev/null
+++ b/uni_modules/lime-shared/getRect/vue.ts
@@ -0,0 +1,117 @@
+// @ts-nocheck
+
+// #ifdef APP-NVUE
+// 当编译环境是 APP-NVUE 时,引入 uni.requireNativePlugin('dom'),具体插件用途未知
+const dom = uni.requireNativePlugin('dom')
+// #endif
+
+/** 
+ * 获取节点信息
+ * @param selector 选择器字符串
+ * @param context ComponentInternalInstance 对象
+ * @param node 是否获取node
+ * @returns 包含节点信息的 Promise 对象
+ */
+export function getRect(selector : string, context : ComponentInternalInstance, node: boolean = false) {
+	// 之前是个对象,现在改成实例,防止旧版会报错
+	if(context== null) {
+		return Promise.reject('context is null')
+	}
+	if(context.context){
+		context = context.context
+	}
+	// #ifdef MP || VUE2
+	if (context.proxy) context = context.proxy
+	// #endif
+	return new Promise<UniNamespace.NodeInfo>((resolve, reject) => {
+		// #ifndef APP-NVUE
+		const dom = uni.createSelectorQuery().in(context).select(selector);
+		const result = (rect: UniNamespace.NodeInfo) => {
+			if (rect) {
+				resolve(rect)
+			} else {
+				reject('no rect')
+			}
+		}
+		
+		if (!node) {
+			dom.boundingClientRect(result).exec()
+		} else {
+			dom.fields({
+				node: true,
+				size: true,
+				rect: true
+			}, result).exec()
+		}
+		// #endif
+		// #ifdef APP-NVUE
+		let { context } = options
+		if (/#|\./.test(selector) && context.refs) {
+			selector = selector.replace(/#|\./, '')
+			if (context.refs[selector]) {
+				selector = context.refs[selector]
+				if(Array.isArray(selector)) {
+					selector = selector[0]
+				}
+			}
+		}
+		dom.getComponentRect(selector, (res) => {
+			if (res.size) {
+				resolve(res.size)
+			} else {
+				reject('no rect')
+			}
+		})
+		// #endif
+	});
+};
+
+
+export function getAllRect(selector : string, context: ComponentInternalInstance, node:boolean = false) {
+	if(context== null) {
+		return Promise.reject('context is null')
+	}
+	// #ifdef MP || VUE2
+	if (context.proxy) context = context.proxy
+	// #endif
+	return new Promise<UniNamespace.NodeInfo>((resolve, reject) => {
+		// #ifndef APP-NVUE
+		const dom = uni.createSelectorQuery().in(context).selectAll(selector);
+		const result = (rect: UniNamespace.NodeInfo[]) => {
+			if (rect) {
+				resolve(rect)
+			} else {
+				reject('no rect')
+			}
+		}
+		if (!node) {
+			dom.boundingClientRect(result).exec()
+		} else {
+			dom.fields({
+				node: true,
+				size: true,
+				rect: true
+			}, result).exec()
+		}
+		// #endif
+		// #ifdef APP-NVUE
+		let { context } = options
+		if (/#|\./.test(selector) && context.refs) {
+			selector = selector.replace(/#|\./, '')
+			if (context.refs[selector]) {
+				selector = context.refs[selector]
+				if(Array.isArray(selector)) {
+					selector = selector[0]
+				}
+			}
+		}
+		dom.getComponentRect(selector, (res) => {
+			if (res.size) {
+				resolve([res.size])
+			} else {
+				reject('no rect')
+			}
+		})
+		// #endif
+	});
+};
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getStyleStr/index.ts b/uni_modules/lime-shared/getStyleStr/index.ts
new file mode 100644
index 0000000..665941c
--- /dev/null
+++ b/uni_modules/lime-shared/getStyleStr/index.ts
@@ -0,0 +1,54 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+interface CSSProperties {
+	[key : string] : string | number | null
+}
+// #endif
+
+// #ifdef VUE3
+// #ifdef UNI-APP-X && APP
+type CSSProperties = UTSJSONObject
+// #endif
+// #endif
+/**
+ * 将字符串转换为带有连字符分隔的小写形式
+ * @param key - 要转换的字符串
+ * @returns 转换后的字符串
+ */
+export function toLowercaseSeparator(key : string):string {
+	return key.replace(/([A-Z])/g, '-$1').toLowerCase();
+}
+
+/**
+ * 获取样式对象对应的样式字符串
+ * @param style - CSS样式对象
+ * @returns 由非空有效样式属性键值对组成的字符串
+ */
+export function getStyleStr(style : CSSProperties) : string {
+	
+	// #ifdef UNI-APP-X && APP
+	let styleStr = '';
+	style.toMap().forEach((value, key) => {
+		if(value !== null && value != '') {
+			styleStr += `${toLowercaseSeparator(key as string)}: ${value};`
+		}
+	})
+	return styleStr
+	// #endif
+	// #ifndef UNI-APP-X && APP
+	return Object.keys(style)
+		.filter(
+			(key) => 
+				style[key] !== undefined && 
+				style[key] !== null && 
+				style[key] !== '')
+		.map((key : string) => `${toLowercaseSeparator(key)}: ${style[key]};`)
+		.join(' ');
+	// #endif
+}
+
+// 示例
+// const style = { color: 'red', fontSize: '16px', backgroundColor: '', border: null };
+// const styleStr = getStyleStr(style);
+// console.log(styleStr);
+// 输出: "color: red; font-size: 16px;"
\ No newline at end of file
diff --git a/uni_modules/lime-shared/getStyleStr/index_.uts b/uni_modules/lime-shared/getStyleStr/index_.uts
new file mode 100644
index 0000000..a4c4494
--- /dev/null
+++ b/uni_modules/lime-shared/getStyleStr/index_.uts
@@ -0,0 +1,39 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X
+interface CSSProperties {
+	[key : string] : string | number
+}
+// #endif
+
+// #ifdef UNI-APP-X
+type CSSProperties = UTSJSONObject
+// #endif
+/**
+ * 将字符串转换为带有连字符分隔的小写形式
+ * @param key - 要转换的字符串
+ * @returns 转换后的字符串
+ */
+export function toLowercaseSeparator(key : string) : string {
+	return key.replace(/([A-Z])/g, '-$1').toLowerCase();
+}
+
+/**
+ * 获取样式对象对应的样式字符串
+ * @param style - CSS样式对象
+ * @returns 由非空有效样式属性键值对组成的字符串
+ */
+export function getStyleStr(style : CSSProperties) : string {
+	let styleStr = '';
+	style.toMap().forEach((value, key) => {
+		if(value !== null && value != '') {
+			styleStr += `${toLowercaseSeparator(key as string)}: ${value};`
+		}
+	})
+	return styleStr
+}
+
+// 示例
+// const style = { color: 'red', fontSize: '16px', backgroundColor: '', border: null };
+// const styleStr = getStyleStr(style);
+// console.log(styleStr);
+// 输出: "color: red; font-size: 16px;"
\ No newline at end of file
diff --git a/uni_modules/lime-shared/hasOwn/index.ts b/uni_modules/lime-shared/hasOwn/index.ts
new file mode 100644
index 0000000..5e2b6da
--- /dev/null
+++ b/uni_modules/lime-shared/hasOwn/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+// #endif
+
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/hasOwn/uvue.ts b/uni_modules/lime-shared/hasOwn/uvue.ts
new file mode 100644
index 0000000..50345bf
--- /dev/null
+++ b/uni_modules/lime-shared/hasOwn/uvue.ts
@@ -0,0 +1,39 @@
+// @ts-nocheck
+/**
+ * 检查对象或数组是否具有指定的属性或键
+ * @param obj 要检查的对象或数组
+ * @param key 指定的属性或键
+ * @returns 如果对象或数组具有指定的属性或键,则返回true;否则返回false
+ */
+function hasOwn(obj: UTSJSONObject, key: string): boolean
+function hasOwn(obj: Map<string, unknown>, key: string): boolean
+function hasOwn(obj: any, key: string): boolean {
+  if(obj instanceof UTSJSONObject){
+	 return obj[key] != null
+  }
+  if(obj instanceof Map<string, unknown>){
+  	 return (obj as Map<string, unknown>).has(key)
+  }
+  return false
+}
+export {
+	hasOwn
+}
+// 示例
+// const obj = { name: 'John', age: 30 };
+
+// if (hasOwn(obj, 'name')) {
+//   console.log("对象具有 'name' 属性");
+// } else {
+//   console.log("对象不具有 'name' 属性");
+// }
+// // 输出: 对象具有 'name' 属性
+
+// const arr = [1, 2, 3];
+
+// if (hasOwn(arr, 'length')) {
+//   console.log("数组具有 'length' 属性");
+// } else {
+//   console.log("数组不具有 'length' 属性");
+// }
+// 输出: 数组具有 'length' 属性
\ No newline at end of file
diff --git a/uni_modules/lime-shared/hasOwn/vue.ts b/uni_modules/lime-shared/hasOwn/vue.ts
new file mode 100644
index 0000000..7317879
--- /dev/null
+++ b/uni_modules/lime-shared/hasOwn/vue.ts
@@ -0,0 +1,30 @@
+// @ts-nocheck
+const hasOwnProperty = Object.prototype.hasOwnProperty
+/**
+ * 检查对象或数组是否具有指定的属性或键
+ * @param obj 要检查的对象或数组
+ * @param key 指定的属性或键
+ * @returns 如果对象或数组具有指定的属性或键,则返回true;否则返回false
+ */
+export function hasOwn(obj: Object | Array<any>, key: string): boolean {
+  return hasOwnProperty.call(obj, key);
+}
+
+// 示例
+// const obj = { name: 'John', age: 30 };
+
+// if (hasOwn(obj, 'name')) {
+//   console.log("对象具有 'name' 属性");
+// } else {
+//   console.log("对象不具有 'name' 属性");
+// }
+// // 输出: 对象具有 'name' 属性
+
+// const arr = [1, 2, 3];
+
+// if (hasOwn(arr, 'length')) {
+//   console.log("数组具有 'length' 属性");
+// } else {
+//   console.log("数组不具有 'length' 属性");
+// }
+// 输出: 数组具有 'length' 属性
\ No newline at end of file
diff --git a/uni_modules/lime-shared/index.ts b/uni_modules/lime-shared/index.ts
new file mode 100644
index 0000000..2eb1d94
--- /dev/null
+++ b/uni_modules/lime-shared/index.ts
@@ -0,0 +1,43 @@
+// @ts-nocheck
+// validator
+// export * from './isString'
+// export * from './isNumber'
+// export * from './isNumeric'
+// export * from './isDef'
+// export * from './isFunction'
+// export * from './isObject'
+// export * from './isPromise'
+// export * from './isBase64'
+
+// export * from './hasOwn'
+
+// // 单位转换
+// export * from './addUnit'
+// export * from './unitConvert'
+// export * from './toNumber'
+
+// export * from './random'
+// export * from './range'
+// export * from './fillZero'
+
+// // image 
+// export * from './base64ToPath'
+// export * from './pathToBase64'
+// export * from './exif'
+
+// // canvas
+// export * from './canIUseCanvas2d'
+
+// // page
+// export * from './getCurrentPage'
+
+// // dom
+// export * from './getRect'
+// export * from './selectComponent'
+// export * from './createAnimation'
+
+// // delay
+// export * from './sleep'
+// export * from './debounce'
+// export * from './throttle'
+
diff --git a/uni_modules/lime-shared/isBase64/index.ts b/uni_modules/lime-shared/isBase64/index.ts
new file mode 100644
index 0000000..dcb8f3e
--- /dev/null
+++ b/uni_modules/lime-shared/isBase64/index.ts
@@ -0,0 +1,23 @@
+// @ts-nocheck
+
+/**
+ * 判断一个字符串是否为Base64编码。
+ * Base64编码的字符串只包含A-Z、a-z、0-9、+、/ 和 = 这些字符。
+ * @param {string} str - 要检查的字符串。
+ * @returns {boolean} 如果字符串是Base64编码,返回true,否则返回false。
+ */
+export function isBase64(str: string): boolean {
+    const base64Regex = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
+    return base64Regex.test(str);
+}
+
+/**
+ * 判断一个字符串是否为Base64编码的data URI。
+ * Base64编码的data URI通常以"data:"开头,后面跟着MIME类型和编码信息,然后是Base64编码的数据。
+ * @param {string} str - 要检查的字符串。
+ * @returns {boolean} 如果字符串是Base64编码的data URI,返回true,否则返回false。
+ */
+export function isBase64DataUri(str: string): boolean {
+    const dataUriRegex = /^data:([a-zA-Z]+\/[a-zA-Z0-9-+.]+)(;base64)?,([a-zA-Z0-9+/]+={0,2})$/;
+    return dataUriRegex.test(str);
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/isBrowser/index.ts b/uni_modules/lime-shared/isBrowser/index.ts
new file mode 100644
index 0000000..6baee2b
--- /dev/null
+++ b/uni_modules/lime-shared/isBrowser/index.ts
@@ -0,0 +1,8 @@
+// @ts-nocheck
+// #ifdef WEB
+export const isBrowser = typeof window !== 'undefined';
+// #endif
+
+// #ifndef WEB
+export const isBrowser = false;
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/isDef/index.ts b/uni_modules/lime-shared/isDef/index.ts
new file mode 100644
index 0000000..f8ca9bc
--- /dev/null
+++ b/uni_modules/lime-shared/isDef/index.ts
@@ -0,0 +1,23 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否已定义(不为 undefined)且不为 null
+ * @param value 要检查的值
+ * @returns 如果值已定义且不为 null,则返回 true;否则返回 false
+ */
+// #ifndef UNI-APP-X
+export function isDef(value: unknown): boolean {
+  return value !== undefined && value !== null;
+}
+// #endif
+
+
+// #ifdef UNI-APP-X
+export function isDef(value : any|null) : boolean {
+	// #ifdef UNI-APP-X && APP
+	return value != null;
+	// #endif
+	// #ifndef UNI-APP-X && APP
+	return value != null && value != undefined;
+	// #endif
+}
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/isEmpty/index.ts b/uni_modules/lime-shared/isEmpty/index.ts
new file mode 100644
index 0000000..74dbc35
--- /dev/null
+++ b/uni_modules/lime-shared/isEmpty/index.ts
@@ -0,0 +1,83 @@
+// @ts-nocheck
+import {isDef} from '../isDef'
+import {isString} from '../isString'
+import {isNumber} from '../isNumber'
+/**
+ * 判断一个值是否为空。
+ *
+ * 对于字符串,去除首尾空格后判断长度是否为0。
+ * 对于数组,判断长度是否为0。
+ * 对于对象,判断键的数量是否为0。
+ * 对于null或undefined,直接返回true。
+ * 其他类型(如数字、布尔值等)默认不为空。
+ *
+ * @param {any} value - 要检查的值。
+ * @returns {boolean} 如果值为空,返回true,否则返回false。
+ */
+
+
+// #ifdef UNI-APP-X && APP
+export function isEmpty(value : any | null) : boolean {
+	// 为null
+	if(!isDef(value)){
+		return true
+	}
+	// 为空字符
+	if(isString(value)){
+		return value.toString().trim().length == 0
+	}
+	// 为数值
+	if(isNumber(value)){
+		return false
+	}
+
+	if(typeof value == 'object'){
+		// 数组
+		if(Array.isArray(value)){
+			return (value as Array<unknown>).length == 0
+		}
+		// Map
+		if(value instanceof Map<unknown, unknown>) {
+			return value.size == 0
+		}
+		// Set
+		if(value instanceof Set<unknown>) {
+			return value.size == 0
+		}
+		if(value instanceof UTSJSONObject) {
+			return value.toMap().size == 0
+		}
+		return JSON.stringify(value) == '{}'
+	}
+	
+	return true
+}
+// #endif
+
+
+// #ifndef UNI-APP-X && APP
+export function isEmpty(value: any): boolean {
+    // 检查是否为null或undefined
+    if (value == null) {
+        return true;
+    }
+
+    // 检查字符串是否为空
+    if (typeof value === 'string') {
+        return value.trim().length === 0;
+    }
+
+    // 检查数组是否为空
+    if (Array.isArray(value)) {
+        return value.length === 0;
+    }
+
+    // 检查对象是否为空
+    if (typeof value === 'object') {
+        return Object.keys(value).length === 0;
+    }
+
+    // 其他类型(如数字、布尔值等)不为空
+    return false;
+}
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/isFunction/index.ts b/uni_modules/lime-shared/isFunction/index.ts
new file mode 100644
index 0000000..12605c3
--- /dev/null
+++ b/uni_modules/lime-shared/isFunction/index.ts
@@ -0,0 +1,16 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为函数类型
+ * @param val 要检查的值
+ * @returns 如果值的类型是函数类型,则返回 true;否则返回 false
+ */
+
+// #ifdef UNI-APP-X && APP
+export const isFunction = (val: any):boolean => typeof val == 'function';
+ // #endif
+
+
+// #ifndef UNI-APP-X && APP
+export const isFunction = (val: unknown): val is Function =>
+  typeof val === 'function';
+// #endif
diff --git a/uni_modules/lime-shared/isNumber/index.ts b/uni_modules/lime-shared/isNumber/index.ts
new file mode 100644
index 0000000..cf8dd9b
--- /dev/null
+++ b/uni_modules/lime-shared/isNumber/index.ts
@@ -0,0 +1,26 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为数字类型
+ * @param value 要检查的值,可以是 number 类型或 string 类型的数字
+ * @returns 如果值是数字类型且不是 NaN,则返回 true;否则返回 false
+ */
+
+// #ifndef UNI-APP-X
+export function isNumber(value: number | string | null): boolean {
+  return typeof value === 'number' && !isNaN(value);
+}
+// #endif
+
+// #ifdef UNI-APP-X
+export function isNumber(value: any|null): boolean {
+	// #ifdef APP-ANDROID
+	return ['Byte', 'UByte','Short','UShort','Int','UInt','Long','ULong','Float','Double','number'].includes(typeof value)
+	// #endif
+	// #ifdef APP-IOS
+	return ['Int8', 'UInt8','Int16','UInt16','Int32','UInt32','Int64','UInt64','Int','UInt','Float','Float16','Float32','Float64','Double', 'number'].includes(typeof value)
+	// #endif
+	// #ifndef UNI-APP-X && APP
+	return typeof value === 'number' && !isNaN(value);
+	// #endif
+}
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/isNumeric/index.ts b/uni_modules/lime-shared/isNumeric/index.ts
new file mode 100644
index 0000000..af5020e
--- /dev/null
+++ b/uni_modules/lime-shared/isNumeric/index.ts
@@ -0,0 +1,33 @@
+// @ts-nocheck
+
+/**
+ * 检查一个值是否为数字类型或表示数字的字符串
+ * @param value 要检查的值,可以是 string 类型或 number 类型
+ * @returns 如果值是数字类型或表示数字的字符串,则返回 true;否则返回 false
+ */
+
+// #ifndef UNI-APP-X && APP
+export function isNumeric(value: string | number | undefined | null): boolean {
+  return /^(-)?\d+(\.\d+)?$/.test(value);
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+import {isNumber} from '../isNumber';
+import {isString} from '../isString';
+export function isNumeric(value : any|null) : boolean {
+	if(value == null) {
+		return false
+	}
+	if(isNumber(value)) {
+		return true
+	} else if(isString(value)) {
+		// const regex = "-?\\d+(\\.\\d+)?".toRegex()
+		const regex = new RegExp("^(-)?\\d+(\\.\\d+)?$")
+		return  regex.test(value as string) //regex.matches(value as string) 
+	}
+	return false
+	// return /^(-)?\d+(\.\d+)?$/.test(value);
+}
+// #endif
diff --git a/uni_modules/lime-shared/isObject/index.ts b/uni_modules/lime-shared/isObject/index.ts
new file mode 100644
index 0000000..d06c15b
--- /dev/null
+++ b/uni_modules/lime-shared/isObject/index.ts
@@ -0,0 +1,19 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为对象类型
+ * @param val 要检查的值
+ * @returns 如果值的类型是对象类型,则返回 true;否则返回 false
+ */
+
+// #ifndef UNI-APP-X && APP
+export const isObject = (val : unknown) : val is Record<any, any> =>
+	val !== null && typeof val === 'object';
+	
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export const isObject = (val : any | null) : boolean =>{
+	return val !== null && typeof val === 'object';
+}
+// #endif
diff --git a/uni_modules/lime-shared/isPromise/index.ts b/uni_modules/lime-shared/isPromise/index.ts
new file mode 100644
index 0000000..b13c10b
--- /dev/null
+++ b/uni_modules/lime-shared/isPromise/index.ts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+import {isFunction} from '../isFunction'
+import {isObject} from '../isObject'
+/**
+ * 检查一个值是否为 Promise 类型
+ * @param val 要检查的值
+ * @returns 如果值的类型是 Promise 类型,则返回 true;否则返回 false
+ */
+// #ifndef APP-ANDROID
+export const isPromise = <T = any>(val: unknown): val is Promise<T> => {
+  // 使用 isObject 函数判断值是否为对象类型
+  // 使用 isFunction 函数判断值是否具有 then 方法和 catch 方法
+  return isObject(val) && isFunction(val.then) && isFunction(val.catch);
+};
+// #endif
+
+
+// #ifdef APP-ANDROID
+export const isPromise = (val: any): boolean => {
+  return val instanceof Promise<unknown>
+};
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/isString/index.ts b/uni_modules/lime-shared/isString/index.ts
new file mode 100644
index 0000000..143f876
--- /dev/null
+++ b/uni_modules/lime-shared/isString/index.ts
@@ -0,0 +1,19 @@
+// @ts-nocheck
+/**
+ * 检查一个值是否为字符串类型
+ * @param str 要检查的值
+ * @returns 如果值的类型是字符串类型,则返回 true;否则返回 false
+ */
+// #ifndef UNI-APP-X && APP
+// export const isString = (str: unknown): str is string => typeof str === 'string';
+export function isString (str: unknown): str is string {
+	return typeof str == 'string'
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export function isString (str: any|null): boolean {
+	return typeof str == 'string'
+}
+// #endif
diff --git a/uni_modules/lime-shared/kebabCase/index.ts b/uni_modules/lime-shared/kebabCase/index.ts
new file mode 100644
index 0000000..114c52c
--- /dev/null
+++ b/uni_modules/lime-shared/kebabCase/index.ts
@@ -0,0 +1,24 @@
+// @ts-nocheck
+// export function toLowercaseSeparator(key: string) {
+//   return key.replace(/([A-Z])/g, '-$1').toLowerCase();
+// }
+
+/**
+ * 将字符串转换为指定连接符的命名约定
+ * @param str 要转换的字符串
+ * @param separator 指定的连接符,默认为 "-"
+ * @returns 转换后的字符串
+ */
+export function kebabCase(str : string, separator : string = "-") : string {
+	return str
+		
+		// #ifdef UNI-APP-X && APP
+		.replace(/[A-Z]/g, (match : string, _ : number, _ : string) : string => `${separator}${match.toLowerCase()}`) // 将大写字母替换为连接符加小写字母
+		// #endif
+		// #ifndef UNI-APP-X && APP
+		.replace(/[A-Z]/g, (match : string) : string => `${separator}${match.toLowerCase()}`) // 将大写字母替换为连接符加小写字母
+		// #endif
+		.replace(/[\s_-]+/g, separator) // 将空格、下划线和短横线替换为指定连接符
+		.replace(new RegExp(`^${separator}|${separator}$`, "g"), "") // 删除开头和结尾的连接符
+		.toLowerCase(); // 将结果转换为全小写
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/package.json b/uni_modules/lime-shared/package.json
new file mode 100644
index 0000000..a307b41
--- /dev/null
+++ b/uni_modules/lime-shared/package.json
@@ -0,0 +1,86 @@
+{
+  "id": "lime-shared",
+  "displayName": "lime-shared",
+  "version": "0.1.8",
+  "description": "本人插件的几个公共函数,获取当前页,图片的base64转临时路径,图片的exif信息等",
+  "keywords": [
+    "lime-shared",
+    "exif"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "type": "sdk-js",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [
+		
+	],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-uvue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "u"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y",
+          "钉钉": "y",
+          "快手": "y",
+          "飞书": "y",
+          "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/pathToBase64/index.ts b/uni_modules/lime-shared/pathToBase64/index.ts
new file mode 100644
index 0000000..af9a9d2
--- /dev/null
+++ b/uni_modules/lime-shared/pathToBase64/index.ts
@@ -0,0 +1,9 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.uts'
+// #endif
diff --git a/uni_modules/lime-shared/pathToBase64/uvue.uts b/uni_modules/lime-shared/pathToBase64/uvue.uts
new file mode 100644
index 0000000..d5bbdb1
--- /dev/null
+++ b/uni_modules/lime-shared/pathToBase64/uvue.uts
@@ -0,0 +1,17 @@
+// @ts-nocheck
+// import { processFile, ProcessFileOptions } from '@/uni_modules/lime-file-utils'
+export function pathToBase64(path : string) : Promise<string> {
+	console.error('pathToBase64: 当前环境不支持,请使用 【lime-file-utils】')
+	// return new Promise((resolve, reject) => {
+	// 	processFile({
+	// 		type: 'toDataURL',
+	// 		path,
+	// 		success(res : string) {
+	// 			resolve(res)
+	// 		},
+	// 		fail(err: any){
+	// 			reject(err)
+	// 		}
+	// 	} as ProcessFileOptions)
+	// })
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/pathToBase64/vue.ts b/uni_modules/lime-shared/pathToBase64/vue.ts
new file mode 100644
index 0000000..8167f88
--- /dev/null
+++ b/uni_modules/lime-shared/pathToBase64/vue.ts
@@ -0,0 +1,121 @@
+// @ts-nocheck
+
+// #ifdef APP-PLUS
+import { getLocalFilePath } from '../getLocalFilePath'
+// #endif
+function isImage(extension : string) {
+	const imageExtensions = ["jpg", "jpeg", "png", "gif", "bmp", "svg"];
+	return imageExtensions.includes(extension.toLowerCase());
+}
+// #ifdef H5
+function getSVGFromURL(url: string) {
+	return new Promise((resolve, reject) => {
+		const xhr = new XMLHttpRequest();
+		xhr.open('GET', url, true);
+		xhr.responseType = 'text';
+
+		xhr.onload = function () {
+			if (xhr.status === 200) {
+				const svg = xhr.responseText;
+				resolve(svg);
+			} else {
+				reject(new Error(xhr.statusText));
+			}
+		};
+
+		xhr.onerror = function () {
+			reject(new Error('Network error'));
+		};
+
+		xhr.send();
+	});
+}
+// #endif
+/**
+ * 路径转base64
+ * @param {Object} string
+ */
+export function pathToBase64(path : string) : Promise<string> {
+	if (/^data:/.test(path)) return path
+	let extension = path.substring(path.lastIndexOf('.') + 1);
+	const isImageFile = isImage(extension)
+	let prefix = ''
+	if (isImageFile) {
+		prefix = 'image/';
+		if(extension == 'svg') {
+			extension += '+xml'
+		}
+	} else if (extension === 'pdf') {
+		prefix = 'application/pdf';
+	} else if (extension === 'txt') {
+		prefix = 'text/plain';
+	} else {
+		// 添加更多文件类型的判断
+		// 如果不是图片、PDF、文本等类型,可以设定默认的前缀或采取其他处理
+		prefix = 'application/octet-stream';
+	}
+	return new Promise((resolve, reject) => {
+		// #ifdef H5
+		if (isImageFile) {
+			if(extension == 'svg') {
+				getSVGFromURL(path).then(svg => {
+					const base64 = btoa(svg);
+					resolve(`data:image/svg+xml;base64,${base64}`);
+				})
+			} else {
+				let image = new Image();
+				image.setAttribute("crossOrigin", 'Anonymous');
+				image.onload = function () {
+					let canvas = document.createElement('canvas');
+					canvas.width = this.naturalWidth;
+					canvas.height = this.naturalHeight;
+					canvas.getContext('2d').drawImage(image, 0, 0);
+					let result = canvas.toDataURL(`${prefix}${extension}`)
+					resolve(result);
+					canvas.height = canvas.width = 0
+				}
+				image.src = path + '?v=' + Math.random()
+				image.onerror = (error) => {
+					reject(error);
+				};
+			}
+			
+		} else {
+			reject('not image');
+		}
+
+		// #endif
+
+		// #ifdef MP
+		if (uni.canIUse('getFileSystemManager')) {
+			uni.getFileSystemManager().readFile({
+				filePath: path,
+				encoding: 'base64',
+				success: (res) => {
+					resolve(`data:${prefix}${extension};base64,${res.data}`)
+				},
+				fail: (error) => {
+					console.error({ error, path })
+					reject(error)
+				}
+			})
+		}
+		// #endif
+
+		// #ifdef APP-PLUS
+		plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), (entry) => {
+			entry.file((file : any) => {
+				const fileReader = new plus.io.FileReader()
+				fileReader.onload = (data) => {
+					resolve(data.target.result)
+				}
+				fileReader.onerror = (error) => {
+					console.error({ error, path })
+					reject(error)
+				}
+				fileReader.readAsDataURL(file)
+			}, reject)
+		}, reject)
+		// #endif
+	})
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/platform/index.ts b/uni_modules/lime-shared/platform/index.ts
new file mode 100644
index 0000000..55fd412
--- /dev/null
+++ b/uni_modules/lime-shared/platform/index.ts
@@ -0,0 +1,34 @@
+// @ts-nocheck
+export function getPlatform():Uni {
+	// #ifdef MP-WEIXIN
+	return wx
+	// #endif
+	// #ifdef MP-BAIDU
+	return swan
+	// #endif
+	// #ifdef MP-ALIPAY
+	return my
+	// #endif
+	// #ifdef MP-JD
+	return jd
+	// #endif
+	// #ifdef MP-QQ
+	return qq
+	// #endif
+	// #ifdef MP-360
+	return qh
+	// #endif
+	// #ifdef MP-KUAISHOU
+	return ks
+	// #endif
+	// #ifdef MP-LARK||MP-TOUTIAO
+	return tt
+	// #endif
+	// #ifdef MP-DINGTALK
+	return dd
+	// #endif
+	// #ifdef QUICKAPP-WEBVIEW || QUICKAPP-WEBVIEW-UNION || QUICKAPP-WEBVIEW-HUAWEI
+	return qa
+	// #endif
+	return uni
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/raf/index.ts b/uni_modules/lime-shared/raf/index.ts
new file mode 100644
index 0000000..2da0808
--- /dev/null
+++ b/uni_modules/lime-shared/raf/index.ts
@@ -0,0 +1,10 @@
+// @ts-nocheck
+
+// #ifdef UNI-APP-X && APP
+export * from './uvue.ts'
+// #endif
+
+
+// #ifndef UNI-APP-X && APP
+export * from './vue.ts'
+// #endif
diff --git a/uni_modules/lime-shared/raf/uvue.ts b/uni_modules/lime-shared/raf/uvue.ts
new file mode 100644
index 0000000..1b0d9f2
--- /dev/null
+++ b/uni_modules/lime-shared/raf/uvue.ts
@@ -0,0 +1,48 @@
+// @ts-nocheck
+// 是否支持被动事件监听
+export const supportsPassive = true;
+
+// #ifdef  uniVersion < 4.25
+// 请求动画帧
+export function raf(fn: TimerCallback): number {
+   return setTimeout(fn, 1000 / 60); 
+}
+
+// 取消动画帧
+export function cancelRaf(id: number) {
+  clearTimeout(id);
+}
+
+
+// 双倍动画帧
+export function doubleRaf(fn: TimerCallback): void {
+  raf(():number => raf(fn)); // 在下一帧回调中再次请求动画帧,实现双倍动画帧效果
+}
+// #endif
+
+
+// #ifdef  uniVersion >= 4.25
+// 请求动画帧
+export function raf(fn: UniAnimationFrameCallback): number
+export function raf(fn: UniAnimationFrameCallbackWithNoArgument): number
+export function raf(fn: any): number {
+	if(typeof fn == 'UniAnimationFrameCallback') {
+		return requestAnimationFrame(fn as UniAnimationFrameCallback); 
+	} else {
+		return requestAnimationFrame(fn as UniAnimationFrameCallbackWithNoArgument); 
+	}
+}
+
+// 取消动画帧
+export function cancelRaf(id: number) {
+  cancelAnimationFrame(id);
+}
+
+// 双倍动画帧
+export function doubleRaf(fn: UniAnimationFrameCallback): void 
+export function doubleRaf(fn: UniAnimationFrameCallbackWithNoArgument): void 
+export function doubleRaf(fn: any): void {
+  raf(():number => raf(fn)); // 在下一帧回调中再次请求动画帧,实现双倍动画帧效果
+}
+// #endif
+
diff --git a/uni_modules/lime-shared/raf/vue.ts b/uni_modules/lime-shared/raf/vue.ts
new file mode 100644
index 0000000..98a364e
--- /dev/null
+++ b/uni_modules/lime-shared/raf/vue.ts
@@ -0,0 +1,32 @@
+// @ts-nocheck
+type Callback = () => void//Function
+// 是否支持被动事件监听
+export const supportsPassive = true;
+
+// 请求动画帧
+export function raf(fn : Callback) : number {
+	// #ifndef WEB
+	return setTimeout(fn, 1000 / 60); // 请求动画帧
+	// #endif
+	// #ifdef WEB
+	return requestAnimationFrame(fn); // 请求动画帧
+	// #endif
+}
+
+// 取消动画帧
+export function cancelRaf(id : number) {
+	// 如果是在浏览器环境下,使用 cancelAnimationFrame 方法
+	// #ifdef WEB
+	cancelAnimationFrame(id); // 取消动画帧
+	// #endif
+	// #ifndef WEB
+	clearTimeout(id); // 取消动画帧
+	// #endif
+}
+
+// 双倍动画帧
+export function doubleRaf(fn : Callback) : void {
+	raf(() => {
+		raf(fn)
+	}); // 在下一帧回调中再次请求动画帧,实现双倍动画帧效果
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/random/index.ts b/uni_modules/lime-shared/random/index.ts
new file mode 100644
index 0000000..49a21ed
--- /dev/null
+++ b/uni_modules/lime-shared/random/index.ts
@@ -0,0 +1,24 @@
+// @ts-nocheck
+/**
+ * 生成一个指定范围内的随机数
+ * @param min 随机数的最小值
+ * @param max 随机数的最大值
+ * @param fixed 随机数的小数位数,默认为 0
+ * @returns 生成的随机数
+ */
+
+export function random(min: number, max: number, fixed: number = 0):number {
+  // 将 min 和 max 转换为数字类型
+  // min = +min || 0;
+  // max = +max || 0;
+  // 计算随机数范围内的一个随机数
+  const num = Math.random() * (max - min) + min;
+  // 如果 fixed 参数为 0,则返回四舍五入的整数随机数;否则保留固定小数位数
+  // Number
+  return fixed == 0 ? Math.round(num) : parseFloat(num.toFixed(fixed));
+}
+
+// 示例
+// console.log(random(0, 10)); // 输出:在 0 和 10 之间的一个整数随机数
+// console.log(random(0, 1, 2)); // 输出:在 0 和 1 之间的一个保留两位小数的随机数
+// console.log(random(1, 100, 3)); // 输出:在 1 和 100 之间的一个保留三位小数的随机数
\ No newline at end of file
diff --git a/uni_modules/lime-shared/range/index.ts b/uni_modules/lime-shared/range/index.ts
new file mode 100644
index 0000000..483b7d1
--- /dev/null
+++ b/uni_modules/lime-shared/range/index.ts
@@ -0,0 +1,36 @@
+// @ts-nocheck
+/**
+ * 生成一个数字范围的数组
+ * @param start 范围的起始值
+ * @param end 范围的结束值
+ * @param step 步长,默认为 1
+ * @param fromRight 是否从右侧开始生成,默认为 false
+ * @returns 生成的数字范围数组
+ */
+export function range(start : number, end : number, step : number = 1, fromRight : boolean = false) : number[] {
+	let index = -1;
+	// 计算范围的长度
+	let length = Math.max(Math.ceil((end - start) / step), 0);
+	// 创建一个长度为 length 的数组
+	// #ifdef APP-ANDROID
+	const result = Array.fromNative(new IntArray(length.toInt()));
+	// #endif
+	// #ifndef APP-ANDROID
+	const result = new Array(length);
+	// #endif
+
+	// 使用循环生成数字范围数组
+	let _start = start
+	while (length-- > 0) {
+		// 根据 fromRight 参数决定从左侧还是右侧开始填充数组
+		result[fromRight ? length : ++index] = _start;
+		_start += step;
+	}
+	return result;
+}
+
+
+// 示例
+// console.log(range(0, 5)); // 输出: [0, 1, 2, 3, 4]
+// console.log(range(1, 10, 2, true)); // 输出: [9, 7, 5, 3, 1]
+// console.log(range(5, 0, -1)); // 输出: [5, 4, 3, 2, 1]
\ No newline at end of file
diff --git a/uni_modules/lime-shared/readme.md b/uni_modules/lime-shared/readme.md
new file mode 100644
index 0000000..3dc8c22
--- /dev/null
+++ b/uni_modules/lime-shared/readme.md
@@ -0,0 +1,445 @@
+# lime-shared 工具库
+- 本人插件的几个公共函数
+- 按需引入
+
+
+## 引入
+按需引入只会引入相关的方法,不要看着 插件函数列表多 而占空间,只要不引用不会被打包
+```js
+import {getRect} from '@/uni_modules/lime-shared/getRect'
+```
+
+## 目录
++ [getRect](#api_getRect): 获取节点尺寸信息
++ [addUnit](#api_addUnit): 将未带单位的数值添加px,如果有单位则返回原值
++ [unitConvert](#api_unitConvert): 将带有rpx|px的字符转成number,若本身是number则直接返回
++ [canIUseCanvas2d](#api_canIUseCanvas2d): 环境是否支持使用 canvas 2d
++ [getCurrentPage](#api_getCurrentPage): 获取当前页
++ [base64ToPath](#api_base64ToPath): 把base64的图片转成临时路径
++ [pathToBase64](#api_pathToBase64): 把图片的临时路径转成base64
++ [sleep](#api_sleep): async 内部程序等待一定时间后再执行
++ [throttle](#api_throttle): 节流
++ [debounce](#api_debounce): 防抖
++ [random](#api_random): 返回指定范围的随机数
++ [range](#api_range): 生成区间数组 
++ [clamp](#api_clamp): 夹在min和max之间的数值 
++ [floatAdd](#api_floatAdd): 返回两个浮点数相加的结果
++ [fillZero](#api_fillZero): 补零,如果传入的是个位数则在前面补0
++ [exif](#api_exif): 获取图片exif
++ [selectComponent](#api_selectComponent): 获取页面或当前实例的指定组件
++ [createAnimation](#api_createAnimation): uni.createAnimation
++ [animation](#api_animation): 数值从一个值到另一个值的过渡
++ [camelCase](#api_camelCase): 字符串转换为 camelCase 或 PascalCase 风格的命名约定
++ [kebabCase](#api_kebabCase): 将字符串转换为指定连接符的命名约定
++ [closest](#api_closest): 在给定数组中找到最接近目标数字的元素
++ [isBase64](#api_isBase64): 判断字符串是否为base64
++ [isNumber](#api_isNumber): 检查一个值是否为数字类型
++ [isNumeric](#api_isNumeric): 检查一个值是否为数字类型或表示数字的字符串
++ [isString](#api_isString): 检查一个值是否为字符串类型
++ [composition-api](#api_composition-api): 为兼容vue2
+
+## Utils
+
+
+### getRect <a id="api_getRect"></a>
+- 返回节点尺寸信息
+
+```js
+// 组件内需要传入上下文
+// 如果是nvue 则需要在节点上加与id或class同名的ref
+getRect('#id',{context: this}).then(res => {})
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+
+### addUnit <a id="api_addUnit"></a> 
+- 将未带单位的数值添加px,如果有单位则返回原值
+
+```js
+addUnit(10)
+// 10px
+```
+
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+
+### unitConvert <a id="api_unitConvert"></a>
+- 将带有rpx|px的字符转成number,若本身是number则直接返回
+
+```js
+unitConvert('10rpx') 
+// 5 设备不同 返回的值也不同
+unitConvert('10px') 
+// 10
+unitConvert(10) 
+// 10
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### canIUseCanvas2d <a id="api_canIUseCanvas2d"></a>
+- 环境是否支持使用 canvas 2d
+
+```js
+canIUseCanvas2d()
+// 若支持返回 true 否则 false
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### getCurrentPage <a id="api_getCurrentPage"></a>
+- 获取当前页
+
+```js
+const page = getCurrentPage()
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### base64ToPath <a id="api_base64ToPath"></a>
+- 把base64的图片转成临时路径
+
+```js
+base64ToPath(`xxxxx`).then(res => {})
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### pathToBase64 <a id="api_pathToBase64"></a>
+- 把图片的临时路径转成base64
+
+```js
+pathToBase64(`xxxxx/xxx.png`).then(res => {})
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### sleep <a id="api_sleep"></a>
+- 睡眠,让 async 内部程序等待一定时间后再执行
+
+```js
+async next () => {
+	await sleep(300)
+	console.log('limeui');
+}
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### throttle <a id="api_throttle"></a> 
+- 节流
+
+```js
+throttle((nama) => {console.log(nama)}, 200)('limeui');
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### debounce <a id="api_debounce"></a>
+- 防抖
+
+```js
+debounce((nama) => {console.log(nama)}, 200)('limeui');
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### random <a id="api_random"></a>
+- 返回指定范围的随机数
+
+```js
+random(1, 5);
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### range <a id="api_range"></a>
+- 生成区间数组
+
+```js
+range(0, 5)
+// [0,1,2,3,4,5]
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### clamp <a id="api_clamp"></a>
+- 夹在min和max之间的数值,如小于min,返回min, 如大于max,返回max,否侧原值返回
+
+```js
+clamp(0, 10, -1)
+// 0
+clamp(0, 10, 11)
+// 10
+clamp(0, 10, 9)
+// 9
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### floatAdd <a id="api_floatAdd"></a>
+- 返回两个浮点数相加的结果
+
+```js
+floatAdd(0.1, 0.2) // 0.3
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### fillZero <a id="api_fillZero"></a>
+- 补零,如果传入的是`个位数`则在前面补0
+
+```js
+fillZero(9);
+// 09
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### exif <a id="api_exif"></a>
+- 获取图片exif
+- 支持临时路径、base64
+
+```js
+uni.chooseImage({
+	count: 1, //最多可以选择的图片张数
+	sizeType: "original",
+	success: (res) => {
+		exif.getData(res.tempFiles[0], function() {
+			let tagj = exif.getTag(this, "GPSLongitude");
+			let	Orientation = exif.getTag(this, 'Orientation');  
+			console.log(tagj, Orientation)
+		})
+	}
+})
+```
+
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | x                 | 
+
+
+### selectComponent <a id="api_selectComponent"></a>
+- 获取页面或当前实例的指定组件,会在页面或实例向所有的节点查找(包括子组件或子子组件)
+- 仅vue3,vue2没有测试过
+
+```js
+// 当前页面
+const page = getCurrentPage()
+selectComponent('.custom', {context: page}).then(res => {
+})
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | x                 | 
+
+
+
+### createAnimation <a id="api_createAnimation"></a>
+- 创建动画,与uni.createAnimation使用方法一致,只为了抹平nvue
+
+```html
+<view ref="ball" :animation="animationData"></view>
+```
+```js
+const ball = ref(null)
+const animation = createAnimation({
+  transformOrigin: "50% 50%",
+  duration: 1000,
+  timingFunction: "ease",
+  delay: 0
+})
+
+animation.scale(2,2).rotate(45).step()
+// nvue 无导出数据,这样写只为了平台一致,
+// nvue 需要把 ref 传入,其它平台不需要
+const animationData = animation.export(ball.value)
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### camelCase <a id="api_camelCase"></a>
+- 将字符串转换为 camelCase 或 PascalCase 风格的命名约定
+
+```js
+camelCase("hello world") // helloWorld
+camelCase("hello world", true) // HelloWorld
+```
+
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### kebabCase <a id="api_kebabCase"></a>
+- 将字符串转换为指定连接符的命名约定
+
+```js
+kebabCase("helloWorld") // hello-world
+kebabCase("hello world_example") // hello-world-example
+kebabCase("helloWorld", "_") // hello_world
+```
+
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+
+### closest <a id="api_closest"></a>
+- 在给定数组中找到最接近目标数字的元素
+
+```js
+closest([1, 3, 5, 7, 9], 6) // 5
+```
+
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+### isBase64 <a id="api_isBase64"></a>
+- 判断字符串是否为base64
+
+```js
+isBase64('xxxxx')
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### isNumber <a id="api_isNumber"></a>
+-  检查一个值是否为数字类型
+
+```js
+isNumber('0') // false
+isNumber(0) // true
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+### isNumeric <a id="api_isNumeric"></a>
+-  检查一个值是否为数字类型或表示数字的字符串
+
+```js
+isNumeric('0') // true
+isNumeric(0) // true
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+### isString <a id="api_isString"></a>
+-  检查一个值是否为数字类型或表示数字的字符串
+
+```js
+isString('0') // true
+isString(0) // false
+```
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | √                 | 
+
+
+
+
+## composition-api <a id="api_composition-api"></a>
+- 因本人插件需要兼容vue2/vue3,故增加一个vue文件,代替条件编译
+- vue2需要在main.js加上这一段
+```js
+// vue2
+import Vue from 'vue'
+import VueCompositionAPI from '@vue/composition-api'
+Vue.use(VueCompositionAPI)
+```
+
+```js
+//使用
+import {computed, onMounted, watch, reactive} from '@/uni_modules/lime-shared/vue'
+```
+
+##### 兼容性
+| uni-app      | uni-app x                      | 
+|------------|----------------------------------|
+| √     | x                 | 
diff --git a/uni_modules/lime-shared/selectAllComponent/index.ts b/uni_modules/lime-shared/selectAllComponent/index.ts
new file mode 100644
index 0000000..17c3a3c
--- /dev/null
+++ b/uni_modules/lime-shared/selectAllComponent/index.ts
@@ -0,0 +1,8 @@
+// @ts-nocheck
+// #ifdef UNI-APP-X
+export * from './uvue.uts'
+// #endif
+
+// #ifndef UNI-APP-X
+export * from './vue.ts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/selectAllComponent/uvue.uts b/uni_modules/lime-shared/selectAllComponent/uvue.uts
new file mode 100644
index 0000000..07c9fcd
--- /dev/null
+++ b/uni_modules/lime-shared/selectAllComponent/uvue.uts
@@ -0,0 +1,39 @@
+// @ts-nocheck
+import { type ComponentPublicInstance } from 'vue';
+
+type SelectOptions = {
+	context : ComponentPublicInstance,
+	needAll : boolean | null,
+	
+}
+
+export function selectAllComponent(selector : string, options : UTSJSONObject) : ComponentPublicInstance[]|null {
+	const context = options.get('context')! as ComponentPublicInstance;
+	let needAll = options.get('needAll') as  boolean;
+	let result:ComponentPublicInstance[] = []
+	
+	if(needAll == null) { needAll = true };
+	
+	if(context.$children.length > 0) {
+		const queue:ComponentPublicInstance[] = [...context.$children];
+		while(queue.length > 0) {
+			const child = queue.shift();
+			const name = child?.$options?.name;
+			if(name == selector) {
+				result.push(child as ComponentPublicInstance)
+			} else {
+				const children = child?.$children 
+				if(children !== null) {
+					queue.push(...children)
+				}
+			}
+			if(result.length > 0 && !needAll) {
+				break;
+			}
+		}
+	}
+	if(result.length > 0) {
+		return result
+	}
+	return null
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/selectAllComponent/vue.ts b/uni_modules/lime-shared/selectAllComponent/vue.ts
new file mode 100644
index 0000000..380bd7a
--- /dev/null
+++ b/uni_modules/lime-shared/selectAllComponent/vue.ts
@@ -0,0 +1,151 @@
+// @ts-nocheck
+interface SelectOptions {
+	context?: any
+	needAll?: boolean
+	node?: boolean
+}
+// #ifdef MP
+function selectMPComponent(key: string, name: string, context: any, needAll: boolean) {
+	const {proxy, $vm} = context
+	context = $vm || proxy
+	if(!['ref','component'].includes(key)) {
+		const queue = [context]
+		let result = null
+		const selector = (key == 'id' ? '#': '.') + name;
+		while(queue.length > 0) {
+			const child = queue.shift();
+			const flag = child?.selectComponent(selector)
+			if(flag) {
+				if(!needAll) {return result = flag.$vm}
+				return result = child.selectAllComponents(selector).map(item => item.$vm)
+			} else {
+				child.$children && (queue.push(...child.$children));
+			}
+		}
+		return result
+	} else {
+		const {$templateRefs} = context.$
+		const nameMap = {}
+		for (var i = 0; i < $templateRefs.length; i++) {
+			const item = $templateRefs[i]
+			nameMap[item.i] = item.r
+		}
+		let result = []
+		if(context.$children.length) {
+			const queue = [...context.$children]
+			while(queue.length > 0) {
+				const child = queue.shift();
+				if(key == 'component' && (child.type?.name === name || child.$?.type?.name === name)) {
+					result.push(child)
+				} else if(child.$refs && child.$refs[name]) {
+					result = child.$refs[name]
+				} else if(nameMap[child.id] === name){
+					result.push(child)
+				}  else {
+					child.$children && (queue.push(...child.$children));
+				}
+				if(result.length && !needAll) {
+					return;
+				}
+			}
+		}
+		return needAll ? result : result[0]
+	}
+}
+// #endif
+// #ifdef H5
+function selectH5Component(key: string, name: string, context: any, needAll: boolean) {
+	const {_, component } = context
+	const child = {component: _ || component || context, children: null , subTree: null, props: null}
+	let result = []
+	let queue = [child]
+	while(queue.length > 0 ) {
+		const child = queue.shift()
+		const {component, children , props, subTree} = child
+		if(key === 'component' && component?.type?.name == name) {
+			result.push(component)
+		} else if(key === 'ref' && component && (props?.ref == name || component[key][name])) {
+			if(props?.ref == name) {
+				//exposed
+				result.push(component)
+			} else if(component[key][name]) {
+				result.push(component[key][name])
+			}
+		} else if(key !== 'ref' && component?.exposed && new RegExp(`\\b${name}\\b`).test(component.attrs[key])) {
+			// exposed
+			result.push(component)
+		} else if(children && Array.isArray(children)) {
+			queue.push(...children)
+		} else if(!component && subTree) {
+			queue.push(subTree)
+		} else if(component?.subTree) {
+			queue.push(component.subTree)
+		}
+		if(result.length && !needAll) {
+			break
+		}
+	}
+	return needAll ? result : result[0]
+}
+// #endif
+// #ifdef APP
+function selectAPPComponent(key: string, name: string, context: any, needAll: boolean, node: boolean) {
+	let result = []
+	// const {_, component} = context
+	// const child = {component: _ || component || context, children: null, props: null, subTree: null}
+	const queue = [context]
+	while(queue.length > 0) {
+		const child = queue.shift()
+		const {component, children, props, subTree} = child
+		const isComp = component && props && component.exposed && !node
+		if(key == 'component' && child.type && child.type.name === name) {
+			result.push(component)
+		} else if(props?.[key] === name && node) {
+			result.push(child)
+		} else if(key === 'ref' && isComp && (props.ref === name || props.ref_key === name)) {
+			// exposed
+			result.push(component)
+		} else if(key !== 'ref' && isComp && new RegExp(`\\b${name}\\b`).test(props[key])) {
+			// exposed
+			result.push(component)
+		}
+		// else if(component && component.subTree && Array.isArray(component.subTree.children)){
+		// 	queue.push(...component.subTree.children)
+		// }
+		else if(subTree) {
+			queue.push(subTree)
+		} else if(component && component.subTree){
+			queue.push(component.subTree)
+		} 
+		 else if(children && Array.isArray(children)) {
+			queue.push(...children)
+		}
+		if(result.length && !needAll) {
+			break;
+		}
+	}
+	return needAll ? result : result[0]
+}
+// #endif
+export function selectAllComponent(selector: string, options: SelectOptions = {}) {
+	// . class
+	// # id
+	// $ ref
+	// @ component name
+	const reg = /^(\.|#|@|\$)([a-zA-Z_0-9\-]+)$/;
+	if(!reg.test(selector)) return null
+	let { context, needAll = true, node} = options
+	const [,prefix, name] = selector.match(reg)
+	const symbolMappings  = {'.': 'class', '#': 'id', '$':'ref', '@':'component'}
+	
+	const key = symbolMappings [prefix] //prefix === '.' ? 'class' : prefix === '#' ? 'id' : 'ref';
+	// #ifdef MP
+	return selectMPComponent(key, name, context, needAll)
+	// #endif
+	// #ifdef H5
+	return selectH5Component(key, name, context, needAll)
+	// #endif
+	// #ifdef APP
+	return selectAPPComponent(key, name, context, needAll, node)
+	// #endif
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/selectComponent/index.ts b/uni_modules/lime-shared/selectComponent/index.ts
new file mode 100644
index 0000000..52454fb
--- /dev/null
+++ b/uni_modules/lime-shared/selectComponent/index.ts
@@ -0,0 +1,7 @@
+// @ts-nocheck
+// #ifndef UNI-APP-X
+export * from './vue.ts'
+// #endif
+// #ifdef UNI-APP-X
+export * from './uvue.uts'
+// #endif
\ No newline at end of file
diff --git a/uni_modules/lime-shared/selectComponent/uvue.uts b/uni_modules/lime-shared/selectComponent/uvue.uts
new file mode 100644
index 0000000..c2aa2bc
--- /dev/null
+++ b/uni_modules/lime-shared/selectComponent/uvue.uts
@@ -0,0 +1,75 @@
+// @ts-nocheck
+import { type ComponentPublicInstance } from 'vue';
+// #ifdef APP
+function findChildren(selector: string, context: ComponentPublicInstance, needAll: boolean): ComponentPublicInstance [] | null{
+	let result:ComponentPublicInstance[] = []
+	
+	if(context !== null && context.$children.length > 0) {
+		const queue:ComponentPublicInstance[] = [...context.$children];
+		while(queue.length > 0) {
+			const child = queue.shift();
+			const name = child?.$options?.name;
+			if(name == selector) {
+				result.push(child as ComponentPublicInstance)
+			} else {
+				const children = child?.$children 
+				if(children !== null) {
+					queue.push(...children)
+				}
+			}
+			if(result.length > 0 && !needAll) {
+				break;
+			}
+		}
+	}
+	if(result.length > 0) {
+		return result
+	}
+	return null
+}
+
+class Query {
+	context : ComponentPublicInstance | null = null
+	selector : string = ''
+	// components : ComponentPublicInstance[] = []
+	constructor(selector : string, context : ComponentPublicInstance | null) {
+		this.selector = selector
+		this.context = context
+	}
+	in(context : ComponentPublicInstance) : Query {
+		return new Query(this.selector, context)
+	}
+	find(): ComponentPublicInstance | null {
+		const selector = this.selector
+		if(selector == '') return null
+		const component = findChildren(selector, this.context!, false)
+		return component != null ? component[0]: null
+	}
+	findAll():ComponentPublicInstance[] | null {
+		const selector = this.selector
+		if(selector == '') return null
+		return findChildren(selector, this.context!, true)
+	}
+	closest(): ComponentPublicInstance | null {
+		const selector = this.selector
+		if(selector == '') return null
+		let parent = this.context!.$parent
+		let name = parent?.$options?.name;
+		while (parent != null && (name == null || selector != name)) {
+			parent = parent.$parent
+			if (parent != null) {
+				name = parent.$options.name
+			}
+		}
+		return parent
+	}
+}
+
+export function selectComponent(selector: string): Query{
+	return new Query(selector, null)
+}
+// #endif
+
+// selectComponent('selector').in(this).find()
+// selectComponent('selector').in(this).findAll()
+// selectComponent('selector').in(this).closest()
diff --git a/uni_modules/lime-shared/selectComponent/vue.ts b/uni_modules/lime-shared/selectComponent/vue.ts
new file mode 100644
index 0000000..9fca0cd
--- /dev/null
+++ b/uni_modules/lime-shared/selectComponent/vue.ts
@@ -0,0 +1,149 @@
+// @ts-nocheck
+// #ifdef MP
+function findChildren(selector : string, context : ComponentPublicInstance, needAll : boolean) {
+	const { proxy, $vm } = context
+	context = $vm || proxy
+	if ((selector.startsWith('.') || selector.startsWith('#'))) {
+		const queue = [context]
+		let result = null
+		while (queue.length > 0) {
+			const child = queue.shift();
+			const flag = child?.selectComponent(selector)
+			if (flag) {
+				if (!needAll) { return result = flag.$vm }
+				return result = child.selectAllComponents(selector).map(item => item.$vm)
+			} else {
+				child.$children && (queue.push(...child.$children));
+			}
+		}
+		return result
+	} else {
+		const { $templateRefs } = context.$
+		const selectorValue = /#|\.|@|$/.test(selector) ? selector.substring(1) : selector
+		const nameMap = {}
+		for (var i = 0; i < $templateRefs.length; i++) {
+			const item = $templateRefs[i]
+			nameMap[item.i] = item.r
+		}
+		let result = []
+		if (context.$children.length) {
+			const queue = [...context.$children]
+			while (queue.length > 0) {
+				const child = queue.shift();
+				if (child.type?.name === selectorValue || child.$?.type?.name === selectorValue) {
+					result.push(child)
+				} else if (child.$refs && child.$refs[selectorValue]) {
+					result = child.$refs[selectorValue]
+				} else if (nameMap[child.id] === selectorValue) {
+					result.push(child)
+				} else {
+					child.$children && (queue.push(...child.$children));
+				}
+				if (result.length && !needAll) {
+					return;
+				}
+			}
+		}
+		return needAll ? result : result[0]
+	}
+}
+// #endif
+
+// #ifdef H5
+function findChildren(selector : string, context : ComponentPublicInstance, needAll : boolean){
+	const {_, component } = context
+	const child = {component: _ || component || context, children: null , subTree: null, props: null}
+	let result = []
+	let queue = [child]
+	const selectorValue = /#|\.|@|$/.test(selector) ? selector.substring(1) : selector
+	while(queue.length > 0 ) {
+		const child = queue.shift()
+		const {component, children , props, subTree} = child
+		if(component?.type?.name == selectorValue) {
+			result.push(component)
+		} else if(selector.startsWith('$') && component && (props?.ref == selectorValue || component[key][selectorValue])) {
+			if(props?.ref == selectorValue) {
+				//exposed
+				result.push(component)
+			} else if(component[key][selectorValue]) {
+				result.push(component[key][selectorValue])
+			}
+		} else if(!selector.startsWith('$') && component?.exposed && new RegExp(`\\b${selectorValue}\\b`).test(component.attrs[key])) {
+			// exposed
+			result.push(component)
+		} else if(children && Array.isArray(children)) {
+			queue.push(...children)
+		} else if(!component && subTree) {
+			queue.push(subTree)
+		} else if(component?.subTree) {
+			queue.push(component.subTree)
+		}
+		if(result.length && !needAll) {
+			break
+		}
+	}
+	return needAll ? result : result[0]
+}
+// #endif
+
+// #ifdef APP
+function findChildren(selector : string, context : ComponentPublicInstance, needAll : boolean){
+	let result = []
+	const selectorValue = /#|\.|@|$/.test(selector) ? selector.substring(1) : selector
+	const queue = [context]
+	while(queue.length > 0) {
+		const child = queue.shift()
+		const {component, children, props, subTree} = child
+		const isComp = component && props && component.exposed && !node
+		if(child.type && child.type.name === selectorValue) {
+			result.push(component)
+		} else if(props?.[key] === selectorValue && node) {
+			result.push(child)
+		} else if(selector.startsWith('$') && isComp && (props.ref === selectorValue || props.ref_key === selectorValue)) {
+			// exposed
+			result.push(component)
+		} else if(!selector.startsWith('$') && isComp && new RegExp(`\\b${selectorValue}\\b`).test(props[key])) {
+			// exposed
+			result.push(component)
+		}
+		else if(subTree) {
+			queue.push(subTree)
+		} else if(component && component.subTree){
+			queue.push(component.subTree)
+		} 
+		 else if(children && Array.isArray(children)) {
+			queue.push(...children)
+		}
+		if(result.length && !needAll) {
+			break;
+		}
+	}
+	return needAll ? result : result[0]
+}
+// #endif
+
+class Query {
+	context : ComponentPublicInstance | null = null
+	selector : string = ''
+	// components : ComponentPublicInstance[] = []
+	constructor(selector : string, context : ComponentPublicInstance | null) {
+		this.selector = selector
+		this.context = context
+	}
+	in(context : ComponentPublicInstance) : Query {
+		return new Query(this.selector, context)
+	}
+	find() : ComponentPublicInstance | null {
+		return findChildren(this.selector, this.context, false)
+	}
+	findAll() : ComponentPublicInstance[] | null {
+		return findChildren(this.selector, this.context, true)
+	}
+	closest() : ComponentPublicInstance | null {
+		return null
+	}
+}
+
+export function selectComponent(selector: string) {
+	return new Query(selector)
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/selectElement/index.uts b/uni_modules/lime-shared/selectElement/index.uts
new file mode 100644
index 0000000..d189583
--- /dev/null
+++ b/uni_modules/lime-shared/selectElement/index.uts
@@ -0,0 +1,275 @@
+// @ts-nocheck
+import {isDef} from '../isDef'
+import {ComponentPublicInstance} from 'vue'
+
+type HasSelectorFunc = (selector : string, element : UniElement) => boolean
+
+const hasSelectorClassName : HasSelectorFunc = (selector : string, element : UniElement) : boolean => {
+	return element.classList.includes(selector)
+}
+const hasSelectorId : HasSelectorFunc = (selector : string, element : UniElement) : boolean => {
+	return element.getAttribute("id") == selector
+}
+const hasSelectorTagName : HasSelectorFunc = (selector : string, element : UniElement) : boolean => {
+	return element.tagName!.toLowerCase() == selector.toLowerCase()
+}
+
+type ProcessSelectorResult = {
+	selectorValue : string
+	hasSelector : HasSelectorFunc
+}
+const processSelector = (selector : string) : ProcessSelectorResult => {
+
+	const selectorValue = /#|\./.test(selector) ? selector.substring(1) : selector
+	let hasSelector : HasSelectorFunc
+
+	if (selector.startsWith('.')) {
+		hasSelector = hasSelectorClassName
+	} else if (selector.startsWith('#')) {
+		hasSelector = hasSelectorId
+	} else {
+		hasSelector = hasSelectorTagName
+	}
+
+	return {
+		selectorValue,
+		hasSelector
+	} as ProcessSelectorResult
+}
+
+
+function isNotEmptyString(str:string): boolean {
+  return str.length > 0;
+}
+
+function isElement(element:UniElement|null):boolean {
+  return isDef(element) && element?.tagName != 'COMMENT';
+}
+
+type ElementArray = Array<UniElement|null>
+class Query {
+	context : ComponentPublicInstance | null = null
+	selector : string = ''
+	elements : ElementArray = []
+	constructor(selector : string | null, context : ComponentPublicInstance | null) {
+		this.context = context
+		if(selector != null){
+			this.selector = selector
+		}
+		this.find(this.selector)
+	}
+	in(context : ComponentPublicInstance) : Query {
+		return new Query(this.selector, context)
+	}
+	findAll(selector : string): Query {
+		if (isDef(this.context)) {
+			const root = this.context?.$el //as Element | null;
+			if (isDef(root)) {
+				this.elements = [root!] //as ElementArray
+			}
+			const { selectorValue, hasSelector } = processSelector(selector)
+			const foundElements : ElementArray = [];
+		
+			function findChildren(element : UniElement) {
+				element.children.forEach((child : UniElement) => {
+					if (hasSelector(selectorValue, child)) {
+						foundElements.push(child)
+					}
+				})
+			}
+			this.elements.forEach(el => {
+				findChildren(el!);
+			});
+			this.elements = foundElements
+		} else if (selector.startsWith('#')) {
+			const element = uni.getElementById(selector)
+			if (isElement(element!)) {
+				this.elements = [element]
+			}
+		}
+		return this;
+	}
+	/**
+	 * 在当前元素集合中查找匹配的元素
+	 */
+	find(selector : string) : Query {
+		if (isDef(this.context)) {
+			const root = this.context?.$el //as Element | null;
+			if (isElement(root)) {
+				this.elements = [root] //as ElementArray
+			}
+			if(isNotEmptyString(selector) && this.elements.length > 0){
+				const { selectorValue, hasSelector } = processSelector(selector)
+				const foundElements : ElementArray = [];
+				function findChildren(element : UniElement) {
+					element.children.forEach((child : UniElement) => {
+						if (hasSelector(selectorValue, child) && foundElements.length < 1) {
+							foundElements.push(child)
+						}
+						if (foundElements.length < 1) {
+							findChildren(child);
+						}
+					})
+				}
+				this.elements.forEach(el => {
+					findChildren(el!);
+				});
+				this.elements = foundElements
+			}
+			
+		} else if (selector.startsWith('#')) {
+			const element = uni.getElementById(selector)
+			if (isElement(element!)) {
+				this.elements = [element]
+			}
+		}
+		return this;
+	}
+	/**
+	 * 获取当前元素集合的直接子元素
+	 */
+	children() : Query {
+		// if (this.elements.length > 0) {
+			// const children = this.elements.reduce((acc, el) => [...acc, ...Array.from(el.children)], []);
+			// this.elements = children;
+		// }
+		return this;
+	}
+	/**
+	 * 获取当前元素集合的父元素
+	 */
+	parent() : Query {
+		// if (this.elements.length > 0) {
+		// 	const parents = this.elements.map(el => el.parentElement).filter(parent => parent !== null) as ElementArray;
+		// 	this.elements = parents
+		// 	// this.elements = Array.from(new Set(parents));
+		// }
+		return this;
+	}
+	/**
+	 * 获取当前元素集合的兄弟元素
+	 */
+	siblings() : Query {
+		// if (this.elements.length > 0) {
+			// const siblings = this.elements.reduce((acc, el) => [...acc, ...Array.from(el.parentElement?.children || [])], []);
+			// this.elements = siblings.filter(sibling => sibling !== null && !this.elements?.includes(sibling));
+		// }
+		return this;
+	}
+	/**
+	 * 获取当前元素集合的下一个兄弟元素
+	 */
+	next() : Query {
+		// if (this.elements.length > 0) {
+		// 	const nextElements = this.elements.map(el => el.nextElementSibling).filter(next => next !== null) as ElementArray;
+		// 	this.elements = nextElements;
+		// }
+		return this;
+	}
+	/**
+	 * 获取当前元素集合的上一个兄弟元素
+	 */
+	prev() : Query {
+		// if (this.elements.length > 0) {
+		// 	const prevElements = this.elements.map(el => el.previousElementSibling).filter(prev => prev !== null) as ElementArray;
+		// 	this.elements = prevElements;
+		// }
+		return this;
+	}
+	/**
+	 * 从当前元素开始向上查找匹配的元素
+	 */
+	closest(selector : string) : Query {
+		if (isDef(this.context)) {
+			// && this.context.$parent != null && this.context.$parent.$el !== null
+			if(this.elements.length == 0 && isDef(this.context?.$parent) && isElement(this.context!.$parent?.$el)){
+				this.elements = [this.context!.$parent?.$el!]
+			}
+			
+			const selectorsArray = selector.split(',')
+			// const { selectorValue, hasSelector } = processSelector(selector)
+			const processedSelectors = selectorsArray.map((selector: string):ProcessSelectorResult => processSelector(selector)) 
+			const closestElements = this.elements.map((el) : UniElement | null => {
+				let closestElement : UniElement | null = el
+				while (closestElement !== null) {
+					// if (hasSelector(selectorValue, closestElement)) {
+					// 	break;
+					// }
+					const isMatchingSelector = processedSelectors.some(({selectorValue, hasSelector}):boolean => {
+						return hasSelector(selectorValue, closestElement!)
+					})
+					if(isMatchingSelector){
+						break;
+					}
+					closestElement = closestElement.parentElement;
+				}
+				return closestElement
+			})
+			this.elements = closestElements.filter((closest : UniElement | null) : boolean => isDef(closest))// as ElementArray
+			
+		}
+		return this;
+	}
+
+	/**
+	 * 从当前元素集合中过滤出匹配的元素
+	 */
+	filter() : Query {
+
+		return this;
+	}
+	/**
+	 * 从当前元素集合中排除匹配的元素
+	 */
+	not() { }
+	/**
+	 * 从当前元素集合中查找包含匹配元素的元素
+	 */
+	has() { }
+	/**
+	 * 获取当前元素集合的第一个
+	 */
+	first() : Query {
+		if (this.elements.length > 0) {
+			// this.elements = [this.elements[0]];
+		}
+		return this;
+	}
+	/**
+	 * 最后一个元素
+	 */
+	last() : Query {
+		if (this.elements.length > 0) {
+			// this.elements = [this.elements[this.elements.length - 1]];
+		}
+		return this;
+	}
+	/**
+	 * 获取当前元素在其兄弟元素中的索引
+	 */
+	index() : number | null {
+		// if (this.elements.length > 0 && this.elements.length > 0 && this.elements[0].parentElement !== null) {
+		// 	return Array.from(this.elements[0].parentElement.children).indexOf(this.elements[0]);
+		// }
+		return null;
+	}
+	get(index : number) : UniElement | null {
+		if (this.elements.length > index) {
+			return this.elements[index] //as Element
+		}
+		return null
+	}
+}
+
+export function selectElement(selector : string | null = null) : Query {
+	// if(typeof selector == 'string' || selector == null){
+	// 	return new Query(selector as string | null, null)
+	// } 
+	// else if(selector instanceof  ComponentPublicInstance){
+	// 	return new Query(null, selector)
+	// }
+	return new Query(selector, null)
+}
+
+// $('xxx').in(this).find('xxx')
+// $('xxx').in(this).get()
\ No newline at end of file
diff --git a/uni_modules/lime-shared/sleep/index.ts b/uni_modules/lime-shared/sleep/index.ts
new file mode 100644
index 0000000..a01cdfd
--- /dev/null
+++ b/uni_modules/lime-shared/sleep/index.ts
@@ -0,0 +1,44 @@
+// @ts-nocheck
+/**
+ * 延迟指定时间后解析的 Promise
+ * @param delay 延迟的时间(以毫秒为单位),默认为 300 毫秒
+ * @returns 一个 Promise,在延迟结束后解析
+ */
+
+
+// #ifdef UNI-APP-X && APP
+function sleep(delay: number = 300):Promise<boolean> {
+	return new Promise((resolve):void => {setTimeout(() => {resolve(true)}, delay)});
+}
+export {
+	sleep
+}
+
+// #endif
+
+// #ifndef UNI-APP-X && APP
+export const sleep = (delay: number = 300) =>
+  new Promise(resolve => setTimeout(resolve, delay));
+  
+// #endif
+  
+// 示例  
+// async function example() {
+//   console.log("Start");
+
+//   // 延迟 1 秒后执行
+//   await sleep(1000);
+//   console.log("1 second later");
+
+//   // 延迟 500 毫秒后执行
+//   await sleep(500);
+//   console.log("500 milliseconds later");
+
+//   // 延迟 2 秒后执行
+//   await sleep(2000);
+//   console.log("2 seconds later");
+
+//   console.log("End");
+// }
+
+// example();
\ No newline at end of file
diff --git a/uni_modules/lime-shared/throttle/index.ts b/uni_modules/lime-shared/throttle/index.ts
new file mode 100644
index 0000000..fff1d82
--- /dev/null
+++ b/uni_modules/lime-shared/throttle/index.ts
@@ -0,0 +1,77 @@
+// @ts-nocheck
+/**
+ * 节流函数,用于限制函数的调用频率
+ * @param fn 要进行节流的函数
+ * @param delay 两次调用之间的最小间隔时间
+ * @returns 节流后的函数
+ */
+
+// #ifndef UNI-APP-X && APP
+export function throttle(fn: (...args: any[]) => void, delay: number) {
+  let flag = true; // 标记是否可以执行函数
+
+  return (...args: any[]) => {
+    if (flag) {
+      flag = false; // 设置为不可执行状态
+      fn(...args); // 执行传入的函数
+
+      setTimeout(() => {
+        flag = true; // 经过指定时间后,设置为可执行状态
+      }, delay);
+    }
+  };
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+// type Rfun = (...args: any[]) => void
+// type Rfun = (...args: any[]) => void
+
+export function throttle<T extends any|null>(
+	fn: (args : T) => void, 
+	delay: number):(args : T) => void {
+	let flag = true; // 标记是否可以执行函数
+	
+	return (args : T) =>{
+		if(flag){
+			flag = false;
+			fn(args);
+			
+			setTimeout(()=>{
+				flag = true;
+			}, delay)
+		}
+	}
+  // return (...args: any[]) => {
+  //   // if (flag) {
+  //   //   flag = false; // 设置为不可执行状态
+  //   //   fn(...args); // 执行传入的函数
+
+  //   //   setTimeout(() => {
+  //   //     flag = true; // 经过指定时间后,设置为可执行状态
+  //   //   }, delay);
+  //   // }
+  // };
+}
+
+// #endif
+
+// // 示例
+// // 定义一个被节流的函数
+// function handleScroll() {
+//   console.log("Scroll event handled!");
+// }
+
+// // 使用节流函数对 handleScroll 进行节流,间隔时间为 500 毫秒
+// const throttledScroll = throttle(handleScroll, 500);
+
+// // 模拟多次调用 handleScroll
+// throttledScroll(); // 输出 "Scroll event handled!"
+// throttledScroll(); // 不会输出
+// throttledScroll(); // 不会输出
+
+// // 经过 500 毫秒后,再次调用 handleScroll
+// setTimeout(() => {
+//   throttledScroll(); // 输出 "Scroll event handled!"
+// }, 500);
\ No newline at end of file
diff --git a/uni_modules/lime-shared/toArray/index.ts b/uni_modules/lime-shared/toArray/index.ts
new file mode 100644
index 0000000..e0840d2
--- /dev/null
+++ b/uni_modules/lime-shared/toArray/index.ts
@@ -0,0 +1,21 @@
+// @ts-nocheck
+/**
+ * 将一个或多个元素转换为数组
+ * @param item 要转换为数组的元素
+ * @returns 转换后的数组
+ */
+// #ifndef UNI-APP-X && APP
+export const toArray = <T>(item: T | T[]): T[] => Array.isArray(item) ? item : [item];
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+export function toArray<T extends any>(item: any): T[] {
+	return Array.isArray(item) ? item as T[] : [item as T]// as T[]
+};
+// #endif
+// 示例
+// console.log(toArray(5)); // 输出: [5]
+// console.log(toArray("hello")); // 输出: ["hello"]
+// console.log(toArray([1, 2, 3])); // 输出: [1, 2, 3]
+// console.log(toArray(["apple", "banana"])); // 输出: ["apple", "banana"]
\ No newline at end of file
diff --git a/uni_modules/lime-shared/toBoolean/index.ts b/uni_modules/lime-shared/toBoolean/index.ts
new file mode 100644
index 0000000..f61d49d
--- /dev/null
+++ b/uni_modules/lime-shared/toBoolean/index.ts
@@ -0,0 +1,40 @@
+// @ts-nocheck
+import { isNumber } from '../isNumber'
+import { isString } from '../isString'
+// 函数重载,定义多个函数签名
+// function toBoolean(value : any) : boolean;
+// function toBoolean(value : string) : boolean;
+// function toBoolean(value : number) : boolean;
+// function toBoolean(value : boolean) : boolean;
+
+// #ifdef UNI-APP-X && APP
+function toBoolean(value : any | null) : boolean {
+	// 根据输入值的类型,返回相应的布尔值
+	// if (isNumber(value)) {
+	// 	return (value as number) != 0;
+	// }
+	// if (isString(value)) {
+	// 	return `${value}`.length > 0;
+	// }
+	// if (typeof value == 'boolean') {
+	// 	return value as boolean;
+	// }
+	// #ifdef APP-IOS
+	return value != null && value != undefined
+	// #endif
+	// #ifdef APP-ANDROID
+	return value != null
+	// #endif
+}
+// #endif
+
+
+// #ifndef UNI-APP-X && APP
+function toBoolean(value : any | null) : value is NonNullable<typeof value> {
+	return !!value//value !== null && value !== undefined;
+}
+// #endif
+
+export {
+	toBoolean
+}
\ No newline at end of file
diff --git a/uni_modules/lime-shared/toNumber/index.ts b/uni_modules/lime-shared/toNumber/index.ts
new file mode 100644
index 0000000..a8e1b1d
--- /dev/null
+++ b/uni_modules/lime-shared/toNumber/index.ts
@@ -0,0 +1,28 @@
+// @ts-nocheck
+/**
+ * 将字符串转换为数字
+ * @param val 要转换的字符串
+ * @returns 转换后的数字或原始字符串
+ */
+
+// #ifdef UNI-APP-X && APP
+// function toNumber(val: string): number
+// function toNumber(val: string): string 
+function toNumber(val: string): number|null {
+  const n = parseFloat(val); // 使用 parseFloat 函数将字符串转换为浮点数
+  return isNaN(n) ? null : n; // 使用 isNaN 函数判断是否为非数字,返回转换后的数字或原始字符串
+}
+export {toNumber}
+// #endif
+
+// #ifndef UNI-APP-X && APP
+export function toNumber(val: string): number | string {
+  const n = parseFloat(val); // 使用 parseFloat 函数将字符串转换为浮点数
+  return isNaN(n) ? val : n; // 使用 isNaN 函数判断是否为非数字,返回转换后的数字或原始字符串
+}
+// #endif
+
+// 示例
+// console.log(toNumber("123")); // 输出: 123
+// console.log(toNumber("3.14")); // 输出: 3.14
+// console.log(toNumber("hello")); // 输出: "hello"
\ No newline at end of file
diff --git a/uni_modules/lime-shared/unitConvert/index.ts b/uni_modules/lime-shared/unitConvert/index.ts
new file mode 100644
index 0000000..cf6063a
--- /dev/null
+++ b/uni_modules/lime-shared/unitConvert/index.ts
@@ -0,0 +1,79 @@
+// @ts-nocheck
+import { isString } from '../isString'
+import { isNumeric } from '../isNumeric'
+
+/**
+ * 单位转换函数,将字符串数字或带有单位的字符串转换为数字
+ * @param value 要转换的值,可以是字符串数字或带有单位的字符串
+ * @returns 转换后的数字,如果无法转换则返回0
+ */
+// #ifndef UNI-APP-X && APP
+export function unitConvert(value : string | number, base: number = 0) : number {
+	// 如果是字符串数字
+	if (isNumeric(value)) {
+		return Number(value);
+	}
+	// 如果有单位
+	if (isString(value)) {
+		const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g;
+		const results = reg.exec(value);
+		if (!value || !results) {
+			return 0;
+		}
+		const unit = results[3];
+		const _value = parseFloat(value);
+		if (unit === 'rpx') {
+			return uni.upx2px(_value);
+		}
+		if (unit === 'px') {
+			return _value * 1;
+		}
+		if(unit == '%') {
+			return _value / 100 * base
+		}
+		// 如果是其他单位,可以继续添加对应的转换逻辑
+	}
+	return 0;
+}
+// #endif
+
+
+// #ifdef UNI-APP-X && APP
+import { isNumber } from '../isNumber'
+export function unitConvert(value : any | null, base: number = 0) : number {
+	if (isNumber(value)) {
+		return value as number
+	}
+	// 如果是字符串数字
+	if (isNumeric(value)) {
+		return parseFloat(value as string);
+	}
+	// 如果有单位
+	if (isString(value)) {
+		const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g;
+		const results = reg.exec(value as string);
+		if (results == null) {
+			return 0;
+		}
+		const unit = results[3];
+		const _value = parseFloat(value);
+		if (unit == 'rpx') {
+			const { windowWidth } = uni.getWindowInfo()
+			return windowWidth / 750 * _value;
+		}
+		if (unit == 'px') {
+			return _value;
+		}
+		if(unit == '%') {
+			return _value / 100 * base
+		}
+		// 如果是其他单位,可以继续添加对应的转换逻辑
+	}
+	return 0;
+}
+// #endif
+// 示例
+// console.log(unitConvert("123")); // 输出: 123 (字符串数字转换为数字)
+// console.log(unitConvert("3.14em")); // 输出: 0 (无法识别的单位)
+// console.log(unitConvert("20rpx")); // 输出: 根据具体情况而定 (根据单位进行转换)
+// console.log(unitConvert(10)); // 输出: 10 (数字不需要转换)
\ No newline at end of file
diff --git a/uni_modules/lime-shared/vue/index.ts b/uni_modules/lime-shared/vue/index.ts
new file mode 100644
index 0000000..07f7135
--- /dev/null
+++ b/uni_modules/lime-shared/vue/index.ts
@@ -0,0 +1,16 @@
+// @ts-nocheck
+
+// #ifdef VUE3
+export * from 'vue';
+// #endif
+
+// #ifndef VUE3
+export * from '@vue/composition-api';
+
+// #ifdef APP-NVUE
+import Vue from 'vue'
+import VueCompositionAPI from '@vue/composition-api'
+Vue.use(VueCompositionAPI)
+// #endif
+
+// #endif
diff --git a/uni_modules/uni-badge/changelog.md b/uni_modules/uni-badge/changelog.md
new file mode 100644
index 0000000..e352c60
--- /dev/null
+++ b/uni_modules/uni-badge/changelog.md
@@ -0,0 +1,33 @@
+## 1.2.2(2023-01-28)
+- 修复 运行/打包 控制台警告问题
+## 1.2.1(2022-09-05)
+- 修复 当 text 超过 max-num 时,badge 的宽度计算是根据 text 的长度计算,更改为 css 计算实际展示宽度,详见:[https://ask.dcloud.net.cn/question/150473](https://ask.dcloud.net.cn/question/150473)
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-badge](https://uniapp.dcloud.io/component/uniui/uni-badge)
+## 1.1.7(2021-11-08)
+- 优化 升级ui
+- 修改 size 属性默认值调整为 small
+- 修改 type 属性,默认值调整为 error,info 替换 default
+## 1.1.6(2021-09-22)
+- 修复 在字节小程序上样式不生效的 bug
+## 1.1.5(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.4(2021-07-29)
+- 修复 去掉 nvue 不支持css 的 align-self 属性,nvue 下不暂支持 absolute 属性
+## 1.1.3(2021-06-24)
+- 优化 示例项目
+## 1.1.1(2021-05-12)
+- 新增 组件示例地址
+## 1.1.0(2021-05-12)
+- 新增 uni-badge 的 absolute 属性,支持定位
+- 新增 uni-badge 的 offset 属性,支持定位偏移
+- 新增 uni-badge 的 is-dot 属性,支持仅显示有一个小点
+- 新增 uni-badge 的 max-num 属性,支持自定义封顶的数字值,超过 99 显示99+
+- 优化 uni-badge 属性 custom-style, 支持以对象形式自定义样式
+## 1.0.7(2021-05-07)
+- 修复 uni-badge 在 App 端,数字小于10时不是圆形的bug
+- 修复 uni-badge 在父元素不是 flex 布局时,宽度缩小的bug
+- 新增 uni-badge 属性 custom-style, 支持自定义样式
+## 1.0.6(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-badge/components/uni-badge/uni-badge.vue b/uni_modules/uni-badge/components/uni-badge/uni-badge.vue
new file mode 100644
index 0000000..956354b
--- /dev/null
+++ b/uni_modules/uni-badge/components/uni-badge/uni-badge.vue
@@ -0,0 +1,268 @@
+<template>
+	<view class="uni-badge--x">
+		<slot />
+		<text v-if="text" :class="classNames" :style="[positionStyle, customStyle, dotStyle]"
+			class="uni-badge" @click="onClick()">{{displayValue}}</text>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Badge 数字角标
+	 * @description 数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=21
+	 * @property {String} text 角标内容
+	 * @property {String} size = [normal|small] 角标内容
+	 * @property {String} type = [info|primary|success|warning|error] 颜色类型
+	 * 	@value info 灰色
+	 * 	@value primary 蓝色
+	 * 	@value success 绿色
+	 * 	@value warning 黄色
+	 * 	@value error 红色
+	 * @property {String} inverted = [true|false] 是否无需背景颜色
+	 * @property {Number} maxNum 展示封顶的数字值,超过 99 显示 99+
+	 * @property {String} absolute = [rightTop|rightBottom|leftBottom|leftTop] 开启绝对定位, 角标将定位到其包裹的标签的四角上
+	 * 	@value rightTop 右上
+	 * 	@value rightBottom 右下
+	 * 	@value leftTop 左上
+	 * 	@value leftBottom 左下
+	 * @property {Array[number]} offset	距定位角中心点的偏移量,只有存在 absolute 属性时有效,例如:[-10, -10] 表示向外偏移 10px,[10, 10] 表示向 absolute 指定的内偏移 10px
+	 * @property {String} isDot = [true|false] 是否显示为一个小点
+	 * @event {Function} click 点击 Badge 触发事件
+	 * @example <uni-badge text="1"></uni-badge>
+	 */
+
+	export default {
+		name: 'UniBadge',
+		emits: ['click'],
+		props: {
+			type: {
+				type: String,
+				default: 'error'
+			},
+			inverted: {
+				type: Boolean,
+				default: false
+			},
+			isDot: {
+				type: Boolean,
+				default: false
+			},
+			maxNum: {
+				type: Number,
+				default: 99
+			},
+			absolute: {
+				type: String,
+				default: ''
+			},
+			offset: {
+				type: Array,
+				default () {
+					return [0, 0]
+				}
+			},
+			text: {
+				type: [String, Number],
+				default: ''
+			},
+			size: {
+				type: String,
+				default: 'small'
+			},
+			customStyle: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		data() {
+			return {};
+		},
+		computed: {
+			width() {
+				return String(this.text).length * 8 + 12
+			},
+			classNames() {
+				const {
+					inverted,
+					type,
+					size,
+					absolute
+				} = this
+				return [
+					inverted ? 'uni-badge--' + type + '-inverted' : '',
+					'uni-badge--' + type,
+					'uni-badge--' + size,
+					absolute ? 'uni-badge--absolute' : ''
+				].join(' ')
+			},
+			positionStyle() {
+				if (!this.absolute) return {}
+				let w = this.width / 2,
+					h = 10
+				if (this.isDot) {
+					w = 5
+					h = 5
+				}
+				const x = `${- w  + this.offset[0]}px`
+				const y = `${- h + this.offset[1]}px`
+
+				const whiteList = {
+					rightTop: {
+						right: x,
+						top: y
+					},
+					rightBottom: {
+						right: x,
+						bottom: y
+					},
+					leftBottom: {
+						left: x,
+						bottom: y
+					},
+					leftTop: {
+						left: x,
+						top: y
+					}
+				}
+				const match = whiteList[this.absolute]
+				return match ? match : whiteList['rightTop']
+			},
+			dotStyle() {
+				if (!this.isDot) return {}
+				return {
+					width: '10px',
+					minWidth: '0',
+					height: '10px',
+					padding: '0',
+					borderRadius: '10px'
+				}
+			},
+			displayValue() {
+				const {
+					isDot,
+					text,
+					maxNum
+				} = this
+				return isDot ? '' : (Number(text) > maxNum ? `${maxNum}+` : text)
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit('click');
+			}
+		}
+	};
+</script>
+
+<style lang="scss" >
+	$uni-primary: #2979ff !default;
+	$uni-success: #4cd964 !default;
+	$uni-warning: #f0ad4e !default;
+	$uni-error: #dd524d !default;
+	$uni-info: #909399 !default;
+
+
+	$bage-size: 12px;
+	$bage-small: scale(0.8);
+
+	.uni-badge--x {
+		/* #ifdef APP-NVUE */
+		// align-self: flex-start;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: inline-block;
+		/* #endif */
+		position: relative;
+	}
+
+	.uni-badge--absolute {
+		position: absolute;
+	}
+
+	.uni-badge--small {
+		transform: $bage-small;
+		transform-origin: center center;
+	}
+
+	.uni-badge {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		overflow: hidden;
+		box-sizing: border-box;
+		font-feature-settings: "tnum";
+		min-width: 20px;
+		/* #endif */
+		justify-content: center;
+		flex-direction: row;
+		height: 20px;
+		padding: 0 4px;
+		line-height: 18px;
+		color: #fff;
+		border-radius: 100px;
+		background-color: $uni-info;
+		background-color: transparent;
+		border: 1px solid #fff;
+		text-align: center;
+		font-family: 'Helvetica Neue', Helvetica, sans-serif;
+		font-size: $bage-size;
+		/* #ifdef H5 */
+		z-index: 999;
+		cursor: pointer;
+		/* #endif */
+
+		&--info {
+			color: #fff;
+			background-color: $uni-info;
+		}
+
+		&--primary {
+			background-color: $uni-primary;
+		}
+
+		&--success {
+			background-color: $uni-success;
+		}
+
+		&--warning {
+			background-color: $uni-warning;
+		}
+
+		&--error {
+			background-color: $uni-error;
+		}
+
+		&--inverted {
+			padding: 0 5px 0 0;
+			color: $uni-info;
+		}
+
+		&--info-inverted {
+			color: $uni-info;
+			background-color: transparent;
+		}
+
+		&--primary-inverted {
+			color: $uni-primary;
+			background-color: transparent;
+		}
+
+		&--success-inverted {
+			color: $uni-success;
+			background-color: transparent;
+		}
+
+		&--warning-inverted {
+			color: $uni-warning;
+			background-color: transparent;
+		}
+
+		&--error-inverted {
+			color: $uni-error;
+			background-color: transparent;
+		}
+
+	}
+</style>
diff --git a/uni_modules/uni-badge/package.json b/uni_modules/uni-badge/package.json
new file mode 100644
index 0000000..b0bac93
--- /dev/null
+++ b/uni_modules/uni-badge/package.json
@@ -0,0 +1,85 @@
+{
+  "id": "uni-badge",
+  "displayName": "uni-badge 数字角标",
+  "version": "1.2.2",
+  "description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。",
+  "keywords": [
+    "",
+    "badge",
+    "uni-ui",
+    "uniui",
+    "数字角标",
+    "徽章"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-badge/readme.md b/uni_modules/uni-badge/readme.md
new file mode 100644
index 0000000..bdf175d
--- /dev/null
+++ b/uni_modules/uni-badge/readme.md
@@ -0,0 +1,10 @@
+## Badge 数字角标
+> **组件名:uni-badge**
+> 代码块: `uBadge`
+
+数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景,
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-badge)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-calendar/changelog.md b/uni_modules/uni-calendar/changelog.md
new file mode 100644
index 0000000..30ca0df
--- /dev/null
+++ b/uni_modules/uni-calendar/changelog.md
@@ -0,0 +1,30 @@
+## 1.4.12(2024-09-21)
+- 修复 calendar在选择日期范围后重新选择日期需要点两次的Bug
+## 1.4.11(2024-01-10)
+- 修复 回到今天时,月份显示不一致问题
+## 1.4.10(2023-04-10)
+- 修复 某些情况 monthSwitch 未触发的Bug
+## 1.4.9(2023-02-02)
+- 修复 某些情况切换月份错误的Bug
+## 1.4.8(2023-01-30)
+- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/161964)
+## 1.4.7(2022-09-16)
+- 优化 支持使用 uni-scss 控制主题色
+## 1.4.6(2022-09-08)
+- 修复 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件的Bug
+## 1.4.5(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式的Bug
+## 1.4.4(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式的Bug
+## 1.4.3(2021-09-22)
+- 修复 startDate、 endDate 属性失效的Bug
+## 1.4.2(2021-08-24)
+- 新增 支持国际化
+## 1.4.1(2021-08-05)
+- 修复 弹出层被 tabbar 遮盖的Bug
+## 1.4.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.3.16(2021-05-12)
+- 新增 组件示例地址
+## 1.3.15(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-calendar/components/uni-calendar/calendar.js b/uni_modules/uni-calendar/components/uni-calendar/calendar.js
new file mode 100644
index 0000000..55eed81
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/calendar.js
@@ -0,0 +1,544 @@
+/**
+* @1900-2100区间内的公历、农历互转
+* @charset UTF-8
+* @github  https://github.com/jjonline/calendar.js
+* @Author  Jea杨(JJonline@JJonline.Cn)
+* @Time    2014-7-21
+* @Time    2016-8-13 Fixed 2033hex、Attribution Annals
+* @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
+* @Time    2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
+* @Version 1.0.3
+* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
+* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
+*/
+/* eslint-disable */
+var calendar = {
+
+  /**
+      * 农历1900-2100的润大小信息表
+      * @Array Of Property
+      * @return Hex
+      */
+  lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
+    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
+    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
+    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
+    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
+    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
+    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
+    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
+    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
+    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
+    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
+    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
+    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
+    0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
+    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
+    /** Add By JJonline@JJonline.Cn**/
+    0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
+    0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
+    0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
+    0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
+    0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
+    0x0d520], // 2100
+
+  /**
+      * 公历每个月份的天数普通表
+      * @Array Of Property
+      * @return Number
+      */
+  solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
+
+  /**
+      * 天干地支之天干速查表
+      * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
+      * @return Cn string
+      */
+  Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
+
+  /**
+      * 天干地支之地支速查表
+      * @Array Of Property
+      * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
+      * @return Cn string
+      */
+  Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
+
+  /**
+      * 天干地支之地支速查表<=>生肖
+      * @Array Of Property
+      * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
+      * @return Cn string
+      */
+  Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
+
+  /**
+      * 24节气速查表
+      * @Array Of Property
+      * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
+      * @return Cn string
+      */
+  solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
+
+  /**
+      * 1900-2100各年的24节气日期速查表
+      * @Array Of Property
+      * @return 0x string For splice
+      */
+  sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
+    '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
+    'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
+    '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
+    '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
+    '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
+    '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
+    '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+    '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
+    '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+    '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
+    '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+    '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+    '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
+    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
+    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
+    '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
+    '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
+    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
+
+  /**
+      * 数字转中文速查表
+      * @Array Of Property
+      * @trans ['日','一','二','三','四','五','六','七','八','九','十']
+      * @return Cn string
+      */
+  nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
+
+  /**
+      * 日期转农历称呼速查表
+      * @Array Of Property
+      * @trans ['初','十','廿','卅']
+      * @return Cn string
+      */
+  nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
+
+  /**
+      * 月份转农历称呼速查表
+      * @Array Of Property
+      * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
+      * @return Cn string
+      */
+  nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
+
+  /**
+      * 返回农历y年一整年的总天数
+      * @param lunar Year
+      * @return Number
+      * @eg:var count = calendar.lYearDays(1987) ;//count=387
+      */
+  lYearDays: function (y) {
+    var i; var sum = 348
+    for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
+    return (sum + this.leapDays(y))
+  },
+
+  /**
+      * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
+      * @param lunar Year
+      * @return Number (0-12)
+      * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
+      */
+  leapMonth: function (y) { // 闰字编码 \u95f0
+    return (this.lunarInfo[y - 1900] & 0xf)
+  },
+
+  /**
+      * 返回农历y年闰月的天数 若该年没有闰月则返回0
+      * @param lunar Year
+      * @return Number (0、29、30)
+      * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
+      */
+  leapDays: function (y) {
+    if (this.leapMonth(y)) {
+      return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
+    }
+    return (0)
+  },
+
+  /**
+      * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
+      * @param lunar Year
+      * @return Number (-1、29、30)
+      * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
+      */
+  monthDays: function (y, m) {
+    if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
+    return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
+  },
+
+  /**
+      * 返回公历(!)y年m月的天数
+      * @param solar Year
+      * @return Number (-1、28、29、30、31)
+      * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
+      */
+  solarDays: function (y, m) {
+    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
+    var ms = m - 1
+    if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
+      return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
+    } else {
+      return (this.solarMonth[ms])
+    }
+  },
+
+  /**
+     * 农历年份转换为干支纪年
+     * @param  lYear 农历年的年份数
+     * @return Cn string
+     */
+  toGanZhiYear: function (lYear) {
+    var ganKey = (lYear - 3) % 10
+    var zhiKey = (lYear - 3) % 12
+    if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
+    if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
+    return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
+  },
+
+  /**
+     * 公历月、日判断所属星座
+     * @param  cMonth [description]
+     * @param  cDay [description]
+     * @return Cn string
+     */
+  toAstro: function (cMonth, cDay) {
+    var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
+    var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
+    return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
+  },
+
+  /**
+      * 传入offset偏移量返回干支
+      * @param offset 相对甲子的偏移量
+      * @return Cn string
+      */
+  toGanZhi: function (offset) {
+    return this.Gan[offset % 10] + this.Zhi[offset % 12]
+  },
+
+  /**
+      * 传入公历(!)y年获得该年第n个节气的公历日期
+      * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
+      * @return day Number
+      * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
+      */
+  getTerm: function (y, n) {
+    if (y < 1900 || y > 2100) { return -1 }
+    if (n < 1 || n > 24) { return -1 }
+    var _table = this.sTermInfo[y - 1900]
+    var _info = [
+      parseInt('0x' + _table.substr(0, 5)).toString(),
+      parseInt('0x' + _table.substr(5, 5)).toString(),
+      parseInt('0x' + _table.substr(10, 5)).toString(),
+      parseInt('0x' + _table.substr(15, 5)).toString(),
+      parseInt('0x' + _table.substr(20, 5)).toString(),
+      parseInt('0x' + _table.substr(25, 5)).toString()
+    ]
+    var _calday = [
+      _info[0].substr(0, 1),
+      _info[0].substr(1, 2),
+      _info[0].substr(3, 1),
+      _info[0].substr(4, 2),
+
+      _info[1].substr(0, 1),
+      _info[1].substr(1, 2),
+      _info[1].substr(3, 1),
+      _info[1].substr(4, 2),
+
+      _info[2].substr(0, 1),
+      _info[2].substr(1, 2),
+      _info[2].substr(3, 1),
+      _info[2].substr(4, 2),
+
+      _info[3].substr(0, 1),
+      _info[3].substr(1, 2),
+      _info[3].substr(3, 1),
+      _info[3].substr(4, 2),
+
+      _info[4].substr(0, 1),
+      _info[4].substr(1, 2),
+      _info[4].substr(3, 1),
+      _info[4].substr(4, 2),
+
+      _info[5].substr(0, 1),
+      _info[5].substr(1, 2),
+      _info[5].substr(3, 1),
+      _info[5].substr(4, 2)
+    ]
+    return parseInt(_calday[n - 1])
+  },
+
+  /**
+      * 传入农历数字月份返回汉语通俗表示法
+      * @param lunar month
+      * @return Cn string
+      * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
+      */
+  toChinaMonth: function (m) { // 月 => \u6708
+    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
+    var s = this.nStr3[m - 1]
+    s += '\u6708'// 加上月字
+    return s
+  },
+
+  /**
+      * 传入农历日期数字返回汉字表示法
+      * @param lunar day
+      * @return Cn string
+      * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
+      */
+  toChinaDay: function (d) { // 日 => \u65e5
+    var s
+    switch (d) {
+      case 10:
+        s = '\u521d\u5341'; break
+      case 20:
+        s = '\u4e8c\u5341'; break
+      case 30:
+        s = '\u4e09\u5341'; break
+      default :
+        s = this.nStr2[Math.floor(d / 10)]
+        s += this.nStr1[d % 10]
+    }
+    return (s)
+  },
+
+  /**
+      * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
+      * @param y year
+      * @return Cn string
+      * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
+      */
+  getAnimal: function (y) {
+    return this.Animals[(y - 4) % 12]
+  },
+
+  /**
+      * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
+      * @param y  solar year
+      * @param m  solar month
+      * @param d  solar day
+      * @return JSON object
+      * @eg:console.log(calendar.solar2lunar(1987,11,01));
+      */
+  solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
+    // 年份限定、上限
+    if (y < 1900 || y > 2100) {
+      return -1// undefined转换为数字变为NaN
+    }
+    // 公历传参最下限
+    if (y == 1900 && m == 1 && d < 31) {
+      return -1
+    }
+    // 未传参  获得当天
+    if (!y) {
+      var objDate = new Date()
+    } else {
+      var objDate = new Date(y, parseInt(m) - 1, d)
+    }
+    var i; var leap = 0; var temp = 0
+    // 修正ymd参数
+    var y = objDate.getFullYear()
+    var m = objDate.getMonth() + 1
+    var d = objDate.getDate()
+    var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
+    for (i = 1900; i < 2101 && offset > 0; i++) {
+      temp = this.lYearDays(i)
+      offset -= temp
+    }
+    if (offset < 0) {
+      offset += temp; i--
+    }
+
+    // 是否今天
+    var isTodayObj = new Date()
+    var isToday = false
+    if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
+      isToday = true
+    }
+    // 星期几
+    var nWeek = objDate.getDay()
+    var cWeek = this.nStr1[nWeek]
+    // 数字表示周几顺应天朝周一开始的惯例
+    if (nWeek == 0) {
+      nWeek = 7
+    }
+    // 农历年
+    var year = i
+    var leap = this.leapMonth(i) // 闰哪个月
+    var isLeap = false
+
+    // 效验闰月
+    for (i = 1; i < 13 && offset > 0; i++) {
+      // 闰月
+      if (leap > 0 && i == (leap + 1) && isLeap == false) {
+        --i
+        isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
+      } else {
+        temp = this.monthDays(year, i)// 计算农历普通月天数
+      }
+      // 解除闰月
+      if (isLeap == true && i == (leap + 1)) { isLeap = false }
+      offset -= temp
+    }
+    // 闰月导致数组下标重叠取反
+    if (offset == 0 && leap > 0 && i == leap + 1) {
+      if (isLeap) {
+        isLeap = false
+      } else {
+        isLeap = true; --i
+      }
+    }
+    if (offset < 0) {
+      offset += temp; --i
+    }
+    // 农历月
+    var month = i
+    // 农历日
+    var day = offset + 1
+    // 天干地支处理
+    var sm = m - 1
+    var gzY = this.toGanZhiYear(year)
+
+    // 当月的两个节气
+    // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
+    var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
+    var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
+
+    // 依据12节气修正干支月
+    var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
+    if (d >= firstNode) {
+      gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
+    }
+
+    // 传入的日期的节气与否
+    var isTerm = false
+    var Term = null
+    if (firstNode == d) {
+      isTerm = true
+      Term = this.solarTerm[m * 2 - 2]
+    }
+    if (secondNode == d) {
+      isTerm = true
+      Term = this.solarTerm[m * 2 - 1]
+    }
+    // 日柱 当月一日与 1900/1/1 相差天数
+    var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
+    var gzD = this.toGanZhi(dayCyclical + d - 1)
+    // 该日期所属的星座
+    var astro = this.toAstro(m, d)
+
+    return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
+  },
+
+  /**
+      * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
+      * @param y  lunar year
+      * @param m  lunar month
+      * @param d  lunar day
+      * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
+      * @return JSON object
+      * @eg:console.log(calendar.lunar2solar(1987,9,10));
+      */
+  lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
+    var isLeapMonth = !!isLeapMonth
+    var leapOffset = 0
+    var leapMonth = this.leapMonth(y)
+    var leapDay = this.leapDays(y)
+    if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
+    if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
+    var day = this.monthDays(y, m)
+    var _day = day
+    // bugFix 2016-9-25
+    // if month is leap, _day use leapDays method
+    if (isLeapMonth) {
+      _day = this.leapDays(y, m)
+    }
+    if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
+
+    // 计算农历的时间差
+    var offset = 0
+    for (var i = 1900; i < y; i++) {
+      offset += this.lYearDays(i)
+    }
+    var leap = 0; var isAdd = false
+    for (var i = 1; i < m; i++) {
+      leap = this.leapMonth(y)
+      if (!isAdd) { // 处理闰月
+        if (leap <= i && leap > 0) {
+          offset += this.leapDays(y); isAdd = true
+        }
+      }
+      offset += this.monthDays(y, i)
+    }
+    // 转换闰月农历 需补充该年闰月的前一个月的时差
+    if (isLeapMonth) { offset += day }
+    // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
+    var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
+    var calObj = new Date((offset + d - 31) * 86400000 + stmap)
+    var cY = calObj.getUTCFullYear()
+    var cM = calObj.getUTCMonth() + 1
+    var cD = calObj.getUTCDate()
+
+    return this.solar2lunar(cY, cM, cD)
+  }
+}
+
+export default calendar
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json
new file mode 100644
index 0000000..fcbd13c
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json
@@ -0,0 +1,12 @@
+{
+	"uni-calender.ok": "ok",
+	"uni-calender.cancel": "cancel",
+	"uni-calender.today": "today",
+	"uni-calender.MON": "MON",
+	"uni-calender.TUE": "TUE",
+	"uni-calender.WED": "WED",
+	"uni-calender.THU": "THU",
+	"uni-calender.FRI": "FRI",
+	"uni-calender.SAT": "SAT",
+	"uni-calender.SUN": "SUN"
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js b/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
new file mode 100644
index 0000000..1ca43de
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
@@ -0,0 +1,12 @@
+{
+	"uni-calender.ok": "确定",
+	"uni-calender.cancel": "取消",
+	"uni-calender.today": "今日",
+	"uni-calender.SUN": "日",
+	"uni-calender.MON": "一",
+	"uni-calender.TUE": "二",
+	"uni-calender.WED": "三",
+	"uni-calender.THU": "四",
+	"uni-calender.FRI": "五",
+	"uni-calender.SAT": "六"
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
new file mode 100644
index 0000000..e0fe33b
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
@@ -0,0 +1,12 @@
+{
+	"uni-calender.ok": "確定",
+	"uni-calender.cancel": "取消",
+	"uni-calender.today": "今日",
+	"uni-calender.SUN": "日",
+	"uni-calender.MON": "一",
+	"uni-calender.TUE": "二",
+	"uni-calender.WED": "三",
+	"uni-calender.THU": "四",
+	"uni-calender.FRI": "五",
+	"uni-calender.SAT": "六"
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue
new file mode 100644
index 0000000..a54135e
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue
@@ -0,0 +1,187 @@
+<template>
+	<view class="uni-calendar-item__weeks-box" :class="{
+		'uni-calendar-item--disable':weeks.disable,
+		'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+		'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
+		'uni-calendar-item--before-checked':weeks.beforeMultiple,
+		'uni-calendar-item--multiple': weeks.multiple,
+		'uni-calendar-item--after-checked':weeks.afterMultiple,
+		}"
+	 @click="choiceDate(weeks)">
+		<view class="uni-calendar-item__weeks-box-item">
+			<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
+			<text class="uni-calendar-item__weeks-box-text" :class="{
+				'uni-calendar-item--isDay-text': weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">{{weeks.date}}</text>
+			<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
+				'uni-calendar-item--isDay-text':weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				}">{{todayText}}</text>
+			<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
+				'uni-calendar-item--isDay-text':weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">{{weeks.isDay ? todayText : (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
+			<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
+				'uni-calendar-item--extra':weeks.extraInfo.info,
+				'uni-calendar-item--isDay-text':weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">{{weeks.extraInfo.info}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	const {	t	} = initVueI18n(i18nMessages)
+
+	export default {
+		emits:['change'],
+		props: {
+			weeks: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			calendar: {
+				type: Object,
+				default: () => {
+					return {}
+				}
+			},
+			selected: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			},
+			lunar: {
+				type: Boolean,
+				default: false
+			}
+		},
+		computed: {
+			todayText() {
+				return t("uni-calender.today")
+			},
+		},
+		methods: {
+			choiceDate(weeks) {
+				this.$emit('change', weeks)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$uni-font-size-base:14px;
+	$uni-text-color:#333;
+	$uni-font-size-sm:12px;
+	$uni-color-error: #e43d33;
+	$uni-opacity-disabled: 0.3;
+	$uni-text-color-disable:#c0c0c0;
+	$uni-primary: #2979ff !default;
+	.uni-calendar-item__weeks-box {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-calendar-item__weeks-box-text {
+		font-size: $uni-font-size-base;
+		color: $uni-text-color;
+	}
+
+	.uni-calendar-item__weeks-lunar-text {
+		font-size: $uni-font-size-sm;
+		color: $uni-text-color;
+	}
+
+	.uni-calendar-item__weeks-box-item {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 100rpx;
+		height: 100rpx;
+	}
+
+	.uni-calendar-item__weeks-box-circle {
+		position: absolute;
+		top: 5px;
+		right: 5px;
+		width: 8px;
+		height: 8px;
+		border-radius: 8px;
+		background-color: $uni-color-error;
+
+	}
+
+	.uni-calendar-item--disable {
+		background-color: rgba(249, 249, 249, $uni-opacity-disabled);
+		color: $uni-text-color-disable;
+	}
+
+	.uni-calendar-item--isDay-text {
+		color: $uni-primary;
+	}
+
+	.uni-calendar-item--isDay {
+		background-color: $uni-primary;
+		opacity: 0.8;
+		color: #fff;
+	}
+
+	.uni-calendar-item--extra {
+		color: $uni-color-error;
+		opacity: 0.8;
+	}
+
+	.uni-calendar-item--checked {
+		background-color: $uni-primary;
+		color: #fff;
+		opacity: 0.8;
+	}
+
+	.uni-calendar-item--multiple {
+		background-color: $uni-primary;
+		color: #fff;
+		opacity: 0.8;
+	}
+	.uni-calendar-item--before-checked {
+		background-color: #ff5a5f;
+		color: #fff;
+	}
+	.uni-calendar-item--after-checked {
+		background-color: #ff5a5f;
+		color: #fff;
+	}
+</style>
diff --git a/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
new file mode 100644
index 0000000..0beebfb
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
@@ -0,0 +1,567 @@
+<template>
+	<view class="uni-calendar">
+		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
+		<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
+			<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
+				<view class="uni-calendar__header-btn-box" @click="close">
+					<text class="uni-calendar__header-text uni-calendar--fixed-width">{{cancelText}}</text>
+				</view>
+				<view class="uni-calendar__header-btn-box" @click="confirm">
+					<text class="uni-calendar__header-text uni-calendar--fixed-width">{{okText}}</text>
+				</view>
+			</view>
+			<view class="uni-calendar__header">
+				<view class="uni-calendar__header-btn-box" @click.stop="pre">
+					<view class="uni-calendar__header-btn uni-calendar--left"></view>
+				</view>
+				<picker mode="date" :value="date" fields="month" @change="bindDateChange">
+					<text class="uni-calendar__header-text">{{ (nowDate.year||'') +' / '+( nowDate.month||'')}}</text>
+				</picker>
+				<view class="uni-calendar__header-btn-box" @click.stop="next">
+					<view class="uni-calendar__header-btn uni-calendar--right"></view>
+				</view>
+				<text class="uni-calendar__backtoday" @click="backToday">{{todayText}}</text>
+
+			</view>
+			<view class="uni-calendar__box">
+				<view v-if="showMonth" class="uni-calendar__box-bg">
+					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
+				</view>
+				<view class="uni-calendar__weeks">
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{monText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
+					</view>
+				</view>
+				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
+					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
+						<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import Calendar from './util.js';
+	import CalendarItem from './uni-calendar-item.vue'
+
+	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	const {	t	} = initVueI18n(i18nMessages)
+
+	/**
+	 * Calendar 日历
+	 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
+	 * @property {String} date 自定义当前时间,默认为今天
+	 * @property {Boolean} lunar 显示农历
+	 * @property {String} startDate 日期选择范围-开始日期
+	 * @property {String} endDate 日期选择范围-结束日期
+	 * @property {Boolean} range 范围选择
+	 * @property {Boolean} insert = [true|false] 插入模式,默认为false
+	 * 	@value true 弹窗模式
+	 * 	@value false 插入模式
+	 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
+	 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
+	 * @property {Boolean} showMonth 是否选择月份为背景
+	 * @event {Function} change 日期改变,`insert :ture` 时生效
+	 * @event {Function} confirm 确认选择`insert :false` 时生效
+	 * @event {Function} monthSwitch 切换月份时触发
+	 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
+	 */
+	export default {
+		components: {
+			CalendarItem
+		},
+		emits:['close','confirm','change','monthSwitch'],
+		props: {
+			date: {
+				type: String,
+				default: ''
+			},
+			selected: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			lunar: {
+				type: Boolean,
+				default: false
+			},
+			startDate: {
+				type: String,
+				default: ''
+			},
+			endDate: {
+				type: String,
+				default: ''
+			},
+			range: {
+				type: Boolean,
+				default: false
+			},
+			insert: {
+				type: Boolean,
+				default: true
+			},
+			showMonth: {
+				type: Boolean,
+				default: true
+			},
+			clearDate: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				show: false,
+				weeks: [],
+				calendar: {},
+				nowDate: '',
+				aniMaskShow: false
+			}
+		},
+		computed:{
+			/**
+			 * for i18n
+			 */
+
+			okText() {
+				return t("uni-calender.ok")
+			},
+			cancelText() {
+				return t("uni-calender.cancel")
+			},
+			todayText() {
+				return t("uni-calender.today")
+			},
+			monText() {
+				return t("uni-calender.MON")
+			},
+			TUEText() {
+				return t("uni-calender.TUE")
+			},
+			WEDText() {
+				return t("uni-calender.WED")
+			},
+			THUText() {
+				return t("uni-calender.THU")
+			},
+			FRIText() {
+				return t("uni-calender.FRI")
+			},
+			SATText() {
+				return t("uni-calender.SAT")
+			},
+			SUNText() {
+				return t("uni-calender.SUN")
+			},
+		},
+		watch: {
+			date(newVal) {
+				// this.cale.setDate(newVal)
+				this.init(newVal)
+			},
+			startDate(val){
+				this.cale.resetSatrtDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			endDate(val){
+				this.cale.resetEndDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			selected(newVal) {
+				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
+				this.weeks = this.cale.weeks
+			}
+		},
+		created() {
+			this.cale = new Calendar({
+				selected: this.selected,
+				startDate: this.startDate,
+				endDate: this.endDate,
+				range: this.range,
+			})
+			this.init(this.date)
+		},
+		methods: {
+			// 取消穿透
+			clean() {},
+			bindDateChange(e) {
+				const value = e.detail.value + '-1'
+				this.setDate(value)
+
+				const { year,month } = this.cale.getDate(value)
+        this.$emit('monthSwitch', {
+            year,
+            month
+        })
+			},
+			/**
+			 * 初始化日期显示
+			 * @param {Object} date
+			 */
+			init(date) {
+				this.cale.setDate(date)
+				this.weeks = this.cale.weeks
+				this.nowDate = this.calendar = this.cale.getInfo(date)
+			},
+			/**
+			 * 打开日历弹窗
+			 */
+			open() {
+				// 弹窗模式并且清理数据
+				if (this.clearDate && !this.insert) {
+					this.cale.cleanMultipleStatus()
+					// this.cale.setDate(this.date)
+					this.init(this.date)
+				}
+				this.show = true
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.aniMaskShow = true
+					}, 50)
+				})
+			},
+			/**
+			 * 关闭日历弹窗
+			 */
+			close() {
+				this.aniMaskShow = false
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.show = false
+						this.$emit('close')
+					}, 300)
+				})
+			},
+			/**
+			 * 确认按钮
+			 */
+			confirm() {
+				this.setEmit('confirm')
+				this.close()
+			},
+			/**
+			 * 变化触发
+			 */
+			change() {
+				if (!this.insert) return
+				this.setEmit('change')
+			},
+			/**
+			 * 选择月份触发
+			 */
+			monthSwitch() {
+				let {
+					year,
+					month
+				} = this.nowDate
+				this.$emit('monthSwitch', {
+					year,
+					month: Number(month)
+				})
+			},
+			/**
+			 * 派发事件
+			 * @param {Object} name
+			 */
+			setEmit(name) {
+				let {
+					year,
+					month,
+					date,
+					fullDate,
+					lunar,
+					extraInfo
+				} = this.calendar
+				this.$emit(name, {
+					range: this.cale.multipleStatus,
+					year,
+					month,
+					date,
+					fulldate: fullDate,
+					lunar,
+					extraInfo: extraInfo || {}
+				})
+			},
+			/**
+			 * 选择天触发
+			 * @param {Object} weeks
+			 */
+			choiceDate(weeks) {
+				if (weeks.disable) return
+				this.calendar = weeks
+				// 设置多选
+				this.cale.setMultiple(this.calendar.fullDate)
+				this.weeks = this.cale.weeks
+				this.change()
+			},
+			/**
+			 * 回到今天
+			 */
+			backToday() {
+				const nowYearMonth = `${this.nowDate.year}-${this.nowDate.month}`
+				const date = this.cale.getDate(new Date())
+        const todayYearMonth = `${date.year}-${date.month}`
+
+				this.init(date.fullDate)
+
+        if(nowYearMonth !== todayYearMonth) {
+          this.monthSwitch()
+        }
+
+				this.change()
+			},
+			/**
+			 * 上个月
+			 */
+			pre() {
+				const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
+				this.setDate(preDate)
+				this.monthSwitch()
+
+			},
+			/**
+			 * 下个月
+			 */
+			next() {
+				const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
+				this.setDate(nextDate)
+				this.monthSwitch()
+			},
+			/**
+			 * 设置日期
+			 * @param {Object} date
+			 */
+			setDate(date) {
+				this.cale.setDate(date)
+				this.weeks = this.cale.weeks
+				this.nowDate = this.cale.getInfo(date)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$uni-bg-color-mask: rgba($color: #000000, $alpha: 0.4);
+	$uni-border-color: #EDEDED;
+	$uni-text-color: #333;
+	$uni-bg-color-hover:#f1f1f1;
+	$uni-font-size-base:14px;
+	$uni-text-color-placeholder: #808080;
+	$uni-color-subtitle: #555555;
+	$uni-text-color-grey:#999;
+	.uni-calendar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-calendar__mask {
+		position: fixed;
+		bottom: 0;
+		top: 0;
+		left: 0;
+		right: 0;
+		background-color: $uni-bg-color-mask;
+		transition-property: opacity;
+		transition-duration: 0.3s;
+		opacity: 0;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--mask-show {
+		opacity: 1
+	}
+
+	.uni-calendar--fixed {
+		position: fixed;
+		/* #ifdef APP-NVUE */
+		bottom: 0;
+		/* #endif */
+		left: 0;
+		right: 0;
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transform: translateY(460px);
+		/* #ifndef APP-NVUE */
+		bottom: calc(var(--window-bottom));
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--ani-show {
+		transform: translateY(0);
+	}
+
+	.uni-calendar__content {
+		background-color: #fff;
+	}
+
+	.uni-calendar__header {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 50px;
+		border-bottom-color: $uni-border-color;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+	}
+
+	.uni-calendar--fixed-top {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+		border-top-color: $uni-border-color;
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-calendar--fixed-width {
+		width: 50px;
+	}
+
+	.uni-calendar__backtoday {
+		position: absolute;
+		right: 0;
+		top: 25rpx;
+		padding: 0 5px;
+		padding-left: 10px;
+		height: 25px;
+		line-height: 25px;
+		font-size: 12px;
+		border-top-left-radius: 25px;
+		border-bottom-left-radius: 25px;
+		color: $uni-text-color;
+		background-color: $uni-bg-color-hover;
+	}
+
+	.uni-calendar__header-text {
+		text-align: center;
+		width: 100px;
+		font-size: $uni-font-size-base;
+		color: $uni-text-color;
+	}
+
+	.uni-calendar__header-btn-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		width: 50px;
+		height: 50px;
+	}
+
+	.uni-calendar__header-btn {
+		width: 10px;
+		height: 10px;
+		border-left-color: $uni-text-color-placeholder;
+		border-left-style: solid;
+		border-left-width: 2px;
+		border-top-color: $uni-color-subtitle;
+		border-top-style: solid;
+		border-top-width: 2px;
+	}
+
+	.uni-calendar--left {
+		transform: rotate(-45deg);
+	}
+
+	.uni-calendar--right {
+		transform: rotate(135deg);
+	}
+
+
+	.uni-calendar__weeks {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-calendar__weeks-item {
+		flex: 1;
+	}
+
+	.uni-calendar__weeks-day {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		height: 45px;
+		border-bottom-color: #F5F5F5;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+	}
+
+	.uni-calendar__weeks-day-text {
+		font-size: 14px;
+	}
+
+	.uni-calendar__box {
+		position: relative;
+	}
+
+	.uni-calendar__box-bg {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+	}
+
+	.uni-calendar__box-bg-text {
+		font-size: 200px;
+		font-weight: bold;
+		color: $uni-text-color-grey;
+		opacity: 0.1;
+		text-align: center;
+		/* #ifndef APP-NVUE */
+		line-height: 1;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-calendar/components/uni-calendar/util.js b/uni_modules/uni-calendar/components/uni-calendar/util.js
new file mode 100644
index 0000000..e0c5103
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/util.js
@@ -0,0 +1,360 @@
+import CALENDAR from './calendar.js'
+
+class Calendar {
+	constructor({
+		date,
+		selected,
+		startDate,
+		endDate,
+		range
+	} = {}) {
+		// 当前日期
+		this.date = this.getDate(new Date()) // 当前初入日期
+		// 打点信息
+		this.selected = selected || [];
+		// 范围开始
+		this.startDate = startDate
+		// 范围结束
+		this.endDate = endDate
+		this.range = range
+		// 多选状态
+		this.cleanMultipleStatus()
+		// 每周日期
+		this.weeks = {}
+		// this._getWeek(this.date.fullDate)
+	}
+	/**
+	 * 设置日期
+	 * @param {Object} date
+	 */
+	setDate(date) {
+		this.selectDate = this.getDate(date)
+		this._getWeek(this.selectDate.fullDate)
+	}
+
+	/**
+	 * 清理多选状态
+	 */
+	cleanMultipleStatus() {
+		this.multipleStatus = {
+			before: '',
+			after: '',
+			data: []
+		}
+	}
+
+	/**
+	 * 重置开始日期
+	 */
+	resetSatrtDate(startDate) {
+		// 范围开始
+		this.startDate = startDate
+
+	}
+
+	/**
+	 * 重置结束日期
+	 */
+	resetEndDate(endDate) {
+		// 范围结束
+		this.endDate = endDate
+	}
+
+	/**
+	 * 获取任意时间
+	 */
+	getDate(date, AddDayCount = 0, str = 'day') {
+		if (!date) {
+			date = new Date()
+		}
+		if (typeof date !== 'object') {
+			date = date.replace(/-/g, '/')
+		}
+		const dd = new Date(date)
+		switch (str) {
+			case 'day':
+				dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
+				break
+			case 'month':
+				if (dd.getDate() === 31 && AddDayCount>0) {
+					dd.setDate(dd.getDate() + AddDayCount)
+				} else {
+					const preMonth = dd.getMonth()
+					dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期
+					const nextMonth = dd.getMonth()
+					// 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
+					if(AddDayCount<0 && preMonth!==0 && nextMonth-preMonth>AddDayCount){
+						dd.setMonth(nextMonth+(nextMonth-preMonth+AddDayCount))
+					}
+					// 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
+					if(AddDayCount>0 && nextMonth-preMonth>AddDayCount){
+						dd.setMonth(nextMonth-(nextMonth-preMonth-AddDayCount))
+					}
+				}
+				break
+			case 'year':
+				dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
+				break
+		}
+		const y = dd.getFullYear()
+		const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
+		const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
+		return {
+			fullDate: y + '-' + m + '-' + d,
+			year: y,
+			month: m,
+			date: d,
+			day: dd.getDay()
+		}
+	}
+
+
+	/**
+	 * 获取上月剩余天数
+	 */
+	_getLastMonthDays(firstDay, full) {
+		let dateArr = []
+		for (let i = firstDay; i > 0; i--) {
+			const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
+			dateArr.push({
+				date: beforeDate,
+				month: full.month - 1,
+				lunar: this.getlunar(full.year, full.month - 1, beforeDate),
+				disable: true
+			})
+		}
+		return dateArr
+	}
+	/**
+	 * 获取本月天数
+	 */
+	_currentMonthDys(dateData, full) {
+		let dateArr = []
+		let fullDate = this.date.fullDate
+		for (let i = 1; i <= dateData; i++) {
+			let nowDate = full.year + '-' + (full.month < 10 ?
+				full.month : full.month) + '-' + (i < 10 ?
+				'0' + i : i)
+			// 是否今天
+			let isDay = fullDate === nowDate
+			// 获取打点信息
+			let info = this.selected && this.selected.find((item) => {
+				if (this.dateEqual(nowDate, item.date)) {
+					return item
+				}
+			})
+
+			// 日期禁用
+			let disableBefore = true
+			let disableAfter = true
+			if (this.startDate) {
+				// let dateCompBefore = this.dateCompare(this.startDate, fullDate)
+				// disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
+				disableBefore = this.dateCompare(this.startDate, nowDate)
+			}
+
+			if (this.endDate) {
+				// let dateCompAfter = this.dateCompare(fullDate, this.endDate)
+				// disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
+				disableAfter = this.dateCompare(nowDate, this.endDate)
+			}
+			let multiples = this.multipleStatus.data
+			let checked = false
+			let multiplesStatus = -1
+			if (this.range) {
+				if (multiples) {
+					multiplesStatus = multiples.findIndex((item) => {
+						return this.dateEqual(item, nowDate)
+					})
+				}
+				if (multiplesStatus !== -1) {
+					checked = true
+				}
+			}
+			let data = {
+				fullDate: nowDate,
+				year: full.year,
+				date: i,
+				multiple: this.range ? checked : false,
+				beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate),
+				afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate),
+				month: full.month,
+				lunar: this.getlunar(full.year, full.month, i),
+				disable: !(disableBefore && disableAfter),
+				isDay
+			}
+			if (info) {
+				data.extraInfo = info
+			}
+
+			dateArr.push(data)
+		}
+		return dateArr
+	}
+	/**
+	 * 获取下月天数
+	 */
+	_getNextMonthDays(surplus, full) {
+		let dateArr = []
+		for (let i = 1; i < surplus + 1; i++) {
+			dateArr.push({
+				date: i,
+				month: Number(full.month) + 1,
+				lunar: this.getlunar(full.year, Number(full.month) + 1, i),
+				disable: true
+			})
+		}
+		return dateArr
+	}
+
+	/**
+	 * 获取当前日期详情
+	 * @param {Object} date
+	 */
+	getInfo(date) {
+		if (!date) {
+			date = new Date()
+		}
+		const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
+		return dateInfo
+	}
+
+	/**
+	 * 比较时间大小
+	 */
+	dateCompare(startDate, endDate) {
+		// 计算截止时间
+		startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+		// 计算详细项的截止时间
+		endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+		if (startDate <= endDate) {
+			return true
+		} else {
+			return false
+		}
+	}
+
+	/**
+	 * 比较时间是否相等
+	 */
+	dateEqual(before, after) {
+		// 计算截止时间
+		before = new Date(before.replace('-', '/').replace('-', '/'))
+		// 计算详细项的截止时间
+		after = new Date(after.replace('-', '/').replace('-', '/'))
+		if (before.getTime() - after.getTime() === 0) {
+			return true
+		} else {
+			return false
+		}
+	}
+
+
+	/**
+	 * 获取日期范围内所有日期
+	 * @param {Object} begin
+	 * @param {Object} end
+	 */
+	geDateAll(begin, end) {
+		var arr = []
+		var ab = begin.split('-')
+		var ae = end.split('-')
+		var db = new Date()
+		db.setFullYear(ab[0], ab[1] - 1, ab[2])
+		var de = new Date()
+		de.setFullYear(ae[0], ae[1] - 1, ae[2])
+		var unixDb = db.getTime() - 24 * 60 * 60 * 1000
+		var unixDe = de.getTime() - 24 * 60 * 60 * 1000
+		for (var k = unixDb; k <= unixDe;) {
+			k = k + 24 * 60 * 60 * 1000
+			arr.push(this.getDate(new Date(parseInt(k))).fullDate)
+		}
+		return arr
+	}
+	/**
+	 * 计算阴历日期显示
+	 */
+	getlunar(year, month, date) {
+		return CALENDAR.solar2lunar(year, month, date)
+	}
+	/**
+	 * 设置打点
+	 */
+	setSelectInfo(data, value) {
+		this.selected = value
+		this._getWeek(data)
+	}
+
+	/**
+	 *  获取多选状态
+	 */
+	setMultiple(fullDate) {
+		let {
+			before,
+			after
+		} = this.multipleStatus
+
+		if (!this.range) return
+		if (before && after) {
+			this.multipleStatus.before = fullDate
+			this.multipleStatus.after = ''
+			this.multipleStatus.data = []
+		} else {
+			if (!before) {
+				this.multipleStatus.before = fullDate
+			} else {
+				this.multipleStatus.after = fullDate
+				if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
+				} else {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
+				}
+			}
+		}
+		this._getWeek(fullDate)
+	}
+
+	/**
+	 * 获取每周数据
+	 * @param {Object} dateData
+	 */
+	_getWeek(dateData) {
+		const {
+			year,
+			month
+		} = this.getDate(dateData)
+		let firstDay = new Date(year, month - 1, 1).getDay()
+		let currentDay = new Date(year, month, 0).getDate()
+		let dates = {
+			lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
+			currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
+			nextMonthDays: [], // 下个月开始几天
+			weeks: []
+		}
+		let canlender = []
+		const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
+		dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
+		canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
+		let weeks = {}
+		// 拼接数组  上个月开始几天 + 本月天数+ 下个月开始几天
+		for (let i = 0; i < canlender.length; i++) {
+			if (i % 7 === 0) {
+				weeks[parseInt(i / 7)] = new Array(7)
+			}
+			weeks[parseInt(i / 7)][i % 7] = canlender[i]
+		}
+		this.canlender = canlender
+		this.weeks = weeks
+	}
+
+	//静态方法
+	// static init(date) {
+	// 	if (!this.instance) {
+	// 		this.instance = new Calendar(date);
+	// 	}
+	// 	return this.instance;
+	// }
+}
+
+
+export default Calendar
diff --git a/uni_modules/uni-calendar/package.json b/uni_modules/uni-calendar/package.json
new file mode 100644
index 0000000..ec924e9
--- /dev/null
+++ b/uni_modules/uni-calendar/package.json
@@ -0,0 +1,86 @@
+{
+  "id": "uni-calendar",
+  "displayName": "uni-calendar 日历",
+  "version": "1.4.12",
+  "description": "日历组件",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "日历",
+    "",
+    "打卡",
+    "日历选择"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-calendar/readme.md b/uni_modules/uni-calendar/readme.md
new file mode 100644
index 0000000..4e1748c
--- /dev/null
+++ b/uni_modules/uni-calendar/readme.md
@@ -0,0 +1,103 @@
+
+
+## Calendar 日历
+> **组件名:uni-calendar**
+> 代码块: `uCalendar`
+
+
+日历组件
+
+> **注意事项**
+> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
+> - 本组件农历转换使用的js是 [@1900-2100区间内的公历、农历互转](https://github.com/jjonline/calendar.js)  
+> - 仅支持自定义组件模式
+> - `date`属性传入的应该是一个 String ,如: 2019-06-27 ,而不是 new Date()
+> - 通过 `insert` 属性来确定当前的事件是 @change 还是 @confirm 。理应合并为一个事件,但是为了区分模式,现使用两个事件,这里需要注意
+> - 弹窗模式下无法阻止后面的元素滚动,如有需要阻止,请在弹窗弹出后,手动设置滚动元素为不可滚动
+
+
+### 安装方式
+
+本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
+
+如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
+
+### 基本用法
+
+在 ``template`` 中使用组件
+
+```html
+<view>
+	<uni-calendar 
+	:insert="true"
+	:lunar="true" 
+	:start-date="'2019-3-2'"
+	:end-date="'2019-5-20'"
+	@change="change"
+	 />
+</view>
+```
+
+### 通过方法打开日历
+
+需要设置 `insert` 为 `false`
+
+```html
+<view>
+	<uni-calendar 
+	ref="calendar"
+	:insert="false"
+	@confirm="confirm"
+	 />
+	 <button @click="open">打开日历</button>
+</view>
+```
+
+```javascript
+
+export default {
+	data() {
+		return {};
+	},
+	methods: {
+		open(){
+			this.$refs.calendar.open();
+		},
+		confirm(e) {
+			console.log(e);
+		}
+	}
+};
+
+```
+
+
+## API
+
+### Calendar Props
+
+|  属性名	|    类型	| 默认值| 说明																													|
+| -	| -	| - | - |
+| date		| String	|-		| 自定义当前时间,默认为今天																							|
+| lunar		| Boolean	| false	| 显示农历																												|
+| startDate	| String	|-		| 日期选择范围-开始日期																									|
+| endDate	| String	|-		| 日期选择范围-结束日期																									|
+| range		| Boolean	| false	| 范围选择																												|
+| insert	| Boolean	| false	| 插入模式,可选值,ture:插入模式;false:弹窗模式;默认为插入模式														|
+|clearDate	|Boolean	|true	|弹窗模式是否清空上次选择内容	|
+| selected	| Array		|-		| 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]	|
+|showMonth	| Boolean	| true	| 是否显示月份为背景																									|
+
+### Calendar Events
+
+|  事件名		| 说明								|返回值|
+| -	|	-	| -	|
+| open	| 弹出日历组件,`insert :false` 时生效|- 	|
+
+
+
+
+
+## 组件示例
+
+点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar](https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar)
diff --git a/uni_modules/uni-card/changelog.md b/uni_modules/uni-card/changelog.md
new file mode 100644
index 0000000..c3cd8c4
--- /dev/null
+++ b/uni_modules/uni-card/changelog.md
@@ -0,0 +1,26 @@
+## 1.3.1(2021-12-20)
+- 修复 在vue页面下略缩图显示不正常的bug
+## 1.3.0(2021-11-19)
+- 重构插槽的用法 ,header 替换为 title 
+- 新增 actions 插槽
+- 新增 cover 封面图属性和插槽
+- 新增 padding 内容默认内边距离
+- 新增 margin 卡片默认外边距离
+- 新增 spacing 卡片默认内边距
+- 新增 shadow 卡片阴影属性
+- 取消 mode 属性,可使用组合插槽代替
+- 取消 note 属性 ,使用actions插槽代替
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-card](https://uniapp.dcloud.io/component/uniui/uni-card)
+## 1.2.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.8(2021-07-01)
+- 优化 图文卡片无图片加载时,提供占位图标
+- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持)
+- 修复 thumbnail 不存在仍然占位的 bug
+## 1.1.7(2021-05-12)
+- 新增 组件示例地址
+## 1.1.6(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-card/components/uni-card/uni-card.vue b/uni_modules/uni-card/components/uni-card/uni-card.vue
new file mode 100644
index 0000000..38cf594
--- /dev/null
+++ b/uni_modules/uni-card/components/uni-card/uni-card.vue
@@ -0,0 +1,270 @@
+<template>
+	<view class="uni-card" :class="{ 'uni-card--full': isFull, 'uni-card--shadow': isShadow,'uni-card--border':border}"
+		:style="{'margin':isFull?0:margin,'padding':spacing,'box-shadow':isShadow?shadow:''}">
+		<!-- 封面 -->
+		<slot name="cover">
+			<view v-if="cover" class="uni-card__cover">
+				<image class="uni-card__cover-image" mode="widthFix" @click="onClick('cover')" :src="cover"></image>
+			</view>
+		</slot>
+		<slot name="title">
+			<view v-if="title || extra" class="uni-card__header">
+				<!-- 卡片标题 -->
+				<view class="uni-card__header-box" @click="onClick('title')">
+					<view v-if="thumbnail" class="uni-card__header-avatar">
+						<image class="uni-card__header-avatar-image" :src="thumbnail" mode="aspectFit" />
+					</view>
+					<view class="uni-card__header-content">
+						<text class="uni-card__header-content-title uni-ellipsis">{{ title }}</text>
+						<text v-if="title&&subTitle"
+							class="uni-card__header-content-subtitle uni-ellipsis">{{ subTitle }}</text>
+					</view>
+				</view>
+				<view class="uni-card__header-extra" @click="onClick('extra')">
+					<text class="uni-card__header-extra-text">{{ extra }}</text>
+				</view>
+			</view>
+		</slot>
+		<!-- 卡片内容 -->
+		<view class="uni-card__content" :style="{padding:padding}" @click="onClick('content')">
+			<slot></slot>
+		</view>
+		<view class="uni-card__actions" @click="onClick('actions')">
+			<slot name="actions"></slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Card 卡片
+	 * @description 卡片视图组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=22
+	 * @property {String} title 标题文字
+	 * @property {String} subTitle 副标题
+	 * @property {Number} padding 内容内边距
+	 * @property {Number} margin 卡片外边距
+	 * @property {Number} spacing 卡片内边距
+	 * @property {String} extra 标题额外信息
+	 * @property {String} cover 封面图(本地路径需要引入)
+	 * @property {String} thumbnail 标题左侧缩略图
+	 * @property {Boolean} is-full = [true | false] 卡片内容是否通栏,为 true 时将去除padding值
+	 * @property {Boolean} is-shadow = [true | false] 卡片内容是否开启阴影
+	 * @property {String} shadow 卡片阴影
+	 * @property {Boolean} border 卡片边框
+	 * @event {Function} click 点击 Card 触发事件
+	 */
+	export default {
+		name: 'UniCard',
+		emits: ['click'],
+		props: {
+			title: {
+				type: String,
+				default: ''
+			},
+			subTitle: {
+				type: String,
+				default: ''
+			},
+			padding: {
+				type: String,
+				default: '10px'
+			},
+			margin: {
+				type: String,
+				default: '15px'
+			},
+			spacing: {
+				type: String,
+				default: '0 10px'
+			},
+			extra: {
+				type: String,
+				default: ''
+			},
+			cover: {
+				type: String,
+				default: ''
+			},
+			thumbnail: {
+				type: String,
+				default: ''
+			},
+			isFull: {
+				// 内容区域是否通栏
+				type: Boolean,
+				default: false
+			},
+			isShadow: {
+				// 是否开启阴影
+				type: Boolean,
+				default: true
+			},
+			shadow: {
+				type: String,
+				default: '0px 0px 3px 1px rgba(0, 0, 0, 0.08)'
+			},
+			border: {
+				type: Boolean,
+				default: true
+			}
+		},
+		methods: {
+			onClick(type) {
+				this.$emit('click', type)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-border-3: #EBEEF5 !default;
+	$uni-shadow-base:0 0px 6px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
+	$uni-main-color: #3a3a3a !default;
+	$uni-base-color: #6a6a6a !default;
+	$uni-secondary-color: #909399 !default;
+	$uni-spacing-sm: 8px !default;
+	$uni-border-color:$uni-border-3;
+	$uni-shadow: $uni-shadow-base;
+	$uni-card-title: 15px;
+	$uni-cart-title-color:$uni-main-color;
+	$uni-card-subtitle: 12px;
+	$uni-cart-subtitle-color:$uni-secondary-color;
+	$uni-card-spacing: 10px;
+	$uni-card-content-color: $uni-base-color;
+
+	.uni-card {
+		margin: $uni-card-spacing;
+		padding: 0 $uni-spacing-sm;
+		border-radius: 4px;
+		overflow: hidden;
+		font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
+		background-color: #fff;
+		flex: 1;
+
+		.uni-card__cover {
+			position: relative;
+			margin-top: $uni-card-spacing;
+			flex-direction: row;
+			overflow: hidden;
+			border-radius: 4px;
+			.uni-card__cover-image {
+				flex: 1;
+				// width: 100%;
+				/* #ifndef APP-PLUS */
+				vertical-align: middle;
+				/* #endif */
+			}
+		}
+
+		.uni-card__header {
+			display: flex;
+			border-bottom: 1px $uni-border-color solid;
+			flex-direction: row;
+			align-items: center;
+			padding: $uni-card-spacing;
+			overflow: hidden;
+
+			.uni-card__header-box {
+				/* #ifndef APP-NVUE */
+				display: flex;
+				/* #endif */
+				flex: 1;
+				flex-direction: row;
+				align-items: center;
+				overflow: hidden;
+			}
+
+			.uni-card__header-avatar {
+				width: 40px;
+				height: 40px;
+				overflow: hidden;
+				border-radius: 5px;
+				margin-right: $uni-card-spacing;
+				.uni-card__header-avatar-image {
+					flex: 1;
+					width: 40px;
+					height: 40px;
+				}
+			}
+
+			.uni-card__header-content {
+				/* #ifndef APP-NVUE */
+				display: flex;
+				/* #endif */
+				flex-direction: column;
+				justify-content: center;
+				flex: 1;
+				// height: 40px;
+				overflow: hidden;
+
+				.uni-card__header-content-title {
+					font-size: $uni-card-title;
+					color: $uni-cart-title-color;
+					// line-height: 22px;
+				}
+
+				.uni-card__header-content-subtitle {
+					font-size: $uni-card-subtitle;
+					margin-top: 5px;
+					color: $uni-cart-subtitle-color;
+				}
+			}
+
+			.uni-card__header-extra {
+				line-height: 12px;
+
+				.uni-card__header-extra-text {
+					font-size: 12px;
+					color: $uni-cart-subtitle-color;
+				}
+			}
+		}
+
+		.uni-card__content {
+			padding: $uni-card-spacing;
+			font-size: 14px;
+			color: $uni-card-content-color;
+			line-height: 22px;
+		}
+
+		.uni-card__actions {
+			font-size: 12px;
+		}
+	}
+
+	.uni-card--border {
+		border: 1px solid $uni-border-color;
+	}
+
+	.uni-card--shadow {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		box-shadow: $uni-shadow;
+		/* #endif */
+	}
+
+	.uni-card--full {
+		margin: 0;
+		border-left-width: 0;
+		border-left-width: 0;
+		border-radius: 0;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-card--full:after {
+		border-radius: 0;
+	}
+
+	/* #endif */
+	.uni-ellipsis {
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-card/package.json b/uni_modules/uni-card/package.json
new file mode 100644
index 0000000..f16224d
--- /dev/null
+++ b/uni_modules/uni-card/package.json
@@ -0,0 +1,90 @@
+{
+  "id": "uni-card",
+  "displayName": "uni-card 卡片",
+  "version": "1.3.1",
+  "description": "Card 组件,提供常见的卡片样式。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "card",
+    "",
+    "卡片"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-icons",
+			"uni-scss"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-card/readme.md b/uni_modules/uni-card/readme.md
new file mode 100644
index 0000000..7434e71
--- /dev/null
+++ b/uni_modules/uni-card/readme.md
@@ -0,0 +1,12 @@
+
+
+## Card 卡片
+> **组件名:uni-card**
+> 代码块: `uCard`
+
+卡片视图组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-card)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-collapse/changelog.md b/uni_modules/uni-collapse/changelog.md
new file mode 100644
index 0000000..455308a
--- /dev/null
+++ b/uni_modules/uni-collapse/changelog.md
@@ -0,0 +1,38 @@
+## 1.4.4(2024-03-20)
+- 修复 titleBorder类型修正
+## 1.4.3(2022-01-25)
+- 修复 初始化的时候 ,open 属性失效的bug
+## 1.4.2(2022-01-21)
+- 修复 微信小程序resize后组件收起的bug
+## 1.4.1(2021-11-22)
+- 修复 vue3中个别scss变量无法找到的问题
+## 1.4.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-collapse](https://uniapp.dcloud.io/component/uniui/uni-collapse)
+## 1.3.3(2021-08-17)
+- 优化 show-arrow 属性默认为true
+## 1.3.2(2021-08-17)
+- 新增 show-arrow 属性,控制是否显示右侧箭头
+## 1.3.1(2021-07-30)
+- 优化 vue3下小程序事件警告的问题
+## 1.3.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.2.2(2021-07-21)
+- 修复 由1.2.0版本引起的 change 事件返回 undefined 的Bug
+## 1.2.1(2021-07-21)
+- 优化 组件示例
+## 1.2.0(2021-07-21)
+- 新增 组件折叠动画
+- 新增 value\v-model 属性 ,动态修改面板折叠状态
+- 新增 title 插槽 ,可定义面板标题
+- 新增 border 属性 ,显示隐藏面板内容分隔线
+- 新增 title-border 属性 ,显示隐藏面板标题分隔线
+- 修复 resize 方法失效的Bug
+- 修复 change 事件返回参数不正确的Bug
+- 优化 H5、App 平台自动更具内容更新高度,无需调用 reszie() 方法
+## 1.1.7(2021-05-12)
+- 新增 组件示例地址
+## 1.1.6(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.1.5(2021-02-05)
+- 调整为uni_modules目录规范
\ No newline at end of file
diff --git a/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue b/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue
new file mode 100644
index 0000000..2f0862e
--- /dev/null
+++ b/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue
@@ -0,0 +1,402 @@
+<template>
+	<view class="uni-collapse-item">
+		<!-- onClick(!isOpen) -->
+		<view @click="onClick(!isOpen)" class="uni-collapse-item__title"
+			:class="{'is-open':isOpen &&titleBorder === 'auto' ,'uni-collapse-item-border':titleBorder !== 'none'}">
+			<view class="uni-collapse-item__title-wrap">
+				<slot name="title">
+					<view class="uni-collapse-item__title-box" :class="{'is-disabled':disabled}">
+						<image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
+						<text class="uni-collapse-item__title-text">{{ title }}</text>
+					</view>
+				</slot>
+			</view>
+			<view v-if="showArrow"
+				:class="{ 'uni-collapse-item__title-arrow-active': isOpen, 'uni-collapse-item--animation': showAnimation === true }"
+				class="uni-collapse-item__title-arrow">
+				<uni-icons :color="disabled?'#ddd':'#bbb'" size="14" type="bottom" />
+			</view>
+		</view>
+		<view class="uni-collapse-item__wrap" :class="{'is--transition':showAnimation}"
+			:style="{height: (isOpen?height:0) +'px'}">
+			<view :id="elId" ref="collapse--hook" class="uni-collapse-item__wrap-content"
+				:class="{open:isheight,'uni-collapse-item--border':border&&isOpen}">
+				<slot></slot>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const dom = weex.requireModule('dom')
+	// #endif
+	/**
+	 * CollapseItem 折叠面板子组件
+	 * @description 折叠面板子组件
+	 * @property {String} title 标题文字
+	 * @property {String} thumb 标题左侧缩略图
+	 * @property {String} name 唯一标志符
+	 * @property {Boolean} open = [true|false] 是否展开组件
+	 * @property {Boolean} titleBorder = [true|false] 是否显示标题分隔线
+	 * @property {String} border = ['auto'|'show'|'none'] 是否显示分隔线
+	 * @property {Boolean} disabled = [true|false] 是否展开面板
+	 * @property {Boolean} showAnimation = [true|false] 开启动画
+	 * @property {Boolean} showArrow = [true|false] 是否显示右侧箭头
+	 */
+	export default {
+		name: 'uniCollapseItem',
+		props: {
+			// 列表标题
+			title: {
+				type: String,
+				default: ''
+			},
+			name: {
+				type: [Number, String],
+				default: ''
+			},
+			// 是否禁用
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			// #ifdef APP-PLUS
+			// 是否显示动画,app 端默认不开启动画,卡顿严重
+			showAnimation: {
+				type: Boolean,
+				default: false
+			},
+			// #endif
+			// #ifndef APP-PLUS
+			// 是否显示动画
+			showAnimation: {
+				type: Boolean,
+				default: true
+			},
+			// #endif
+			// 是否展开
+			open: {
+				type: Boolean,
+				default: false
+			},
+			// 缩略图
+			thumb: {
+				type: String,
+				default: ''
+			},
+			// 标题分隔线显示类型
+			titleBorder: {
+				type: String,
+				default: 'auto'
+			},
+			border: {
+				type: Boolean,
+				default: true
+			},
+			showArrow: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			// TODO 随机生生元素ID,解决百度小程序获取同一个元素位置信息的bug
+			const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			return {
+				isOpen: false,
+				isheight: null,
+				height: 0,
+				elId,
+				nameSync: 0
+			}
+		},
+		watch: {
+			open(val) {
+				this.isOpen = val
+				this.onClick(val, 'init')
+			}
+		},
+		updated(e) {
+			this.$nextTick(() => {
+				this.init(true)
+			})
+		},
+		created() {
+			this.collapse = this.getCollapse()
+			this.oldHeight = 0
+			this.onClick(this.open, 'init')
+		},
+		// #ifndef VUE3
+		// TODO vue2
+		destroyed() {
+			if (this.__isUnmounted) return
+			this.uninstall()
+		},
+		// #endif
+		// #ifdef VUE3
+		// TODO vue3
+		unmounted() {
+			this.__isUnmounted = true
+			this.uninstall()
+		},
+		// #endif
+		mounted() {
+			if (!this.collapse) return
+			if (this.name !== '') {
+				this.nameSync = this.name
+			} else {
+				this.nameSync = this.collapse.childrens.length + ''
+			}
+			if (this.collapse.names.indexOf(this.nameSync) === -1) {
+				this.collapse.names.push(this.nameSync)
+			} else {
+				console.warn(`name 值 ${this.nameSync} 重复`);
+			}
+			if (this.collapse.childrens.indexOf(this) === -1) {
+				this.collapse.childrens.push(this)
+			}
+			this.init()
+		},
+		methods: {
+			init(type) {
+				// #ifndef APP-NVUE
+				this.getCollapseHeight(type)
+				// #endif
+				// #ifdef APP-NVUE
+				this.getNvueHwight(type)
+				// #endif
+			},
+			uninstall() {
+				if (this.collapse) {
+					this.collapse.childrens.forEach((item, index) => {
+						if (item === this) {
+							this.collapse.childrens.splice(index, 1)
+						}
+					})
+					this.collapse.names.forEach((item, index) => {
+						if (item === this.nameSync) {
+							this.collapse.names.splice(index, 1)
+						}
+					})
+				}
+			},
+			onClick(isOpen, type) {
+				if (this.disabled) return
+				this.isOpen = isOpen
+				if (this.isOpen && this.collapse) {
+					this.collapse.setAccordion(this)
+				}
+				if (type !== 'init') {
+					this.collapse.onChange(isOpen, this)
+				}
+			},
+			getCollapseHeight(type, index = 0) {
+				const views = uni.createSelectorQuery().in(this)
+				views
+					.select(`#${this.elId}`)
+					.fields({
+						size: true
+					}, data => {
+						// TODO 百度中可能获取不到节点信息 ,需要循环获取
+						if (index >= 10) return
+						if (!data) {
+							index++
+							this.getCollapseHeight(false, index)
+							return
+						}
+						// #ifdef APP-NVUE
+						this.height = data.height + 1
+						// #endif
+						// #ifndef APP-NVUE
+						this.height = data.height
+						// #endif
+						this.isheight = true
+						if (type) return
+						this.onClick(this.isOpen, 'init')
+					})
+					.exec()
+			},
+			getNvueHwight(type) {
+				const result = dom.getComponentRect(this.$refs['collapse--hook'], option => {
+					if (option && option.result && option.size) {
+						// #ifdef APP-NVUE
+						this.height = option.size.height + 1
+						// #endif
+						// #ifndef APP-NVUE
+						this.height = option.size.height
+						// #endif
+						this.isheight = true
+						if (type) return
+						this.onClick(this.open, 'init')
+					}
+				})
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getCollapse(name = 'uniCollapse') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false;
+					parentName = parent.$options.name;
+				}
+				return parent;
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.uni-collapse-item {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+
+		/* #endif */
+		&__title {
+			/* #ifndef APP-NVUE */
+			display: flex;
+			width: 100%;
+			box-sizing: border-box;
+			/* #endif */
+			flex-direction: row;
+			align-items: center;
+			transition: border-bottom-color .3s;
+
+			// transition-property: border-bottom-color;
+			// transition-duration: 5s;
+			&-wrap {
+				width: 100%;
+				flex: 1;
+
+			}
+
+			&-box {
+				padding: 0 15px;
+				/* #ifndef APP-NVUE */
+				display: flex;
+				width: 100%;
+				box-sizing: border-box;
+				/* #endif */
+				flex-direction: row;
+				justify-content: space-between;
+				align-items: center;
+				height: 48px;
+				line-height: 48px;
+				background-color: #fff;
+				color: #303133;
+				font-size: 13px;
+				font-weight: 500;
+				/* #ifdef H5 */
+				cursor: pointer;
+				outline: none;
+
+				/* #endif */
+				&.is-disabled {
+					.uni-collapse-item__title-text {
+						color: #999;
+					}
+				}
+
+			}
+
+			&.uni-collapse-item-border {
+				border-bottom: 1px solid #ebeef5;
+			}
+
+			&.is-open {
+				border-bottom-color: transparent;
+			}
+
+			&-img {
+				height: 22px;
+				width: 22px;
+				margin-right: 10px;
+			}
+
+			&-text {
+				flex: 1;
+				font-size: 14px;
+				/* #ifndef APP-NVUE */
+				white-space: nowrap;
+				color: inherit;
+				/* #endif */
+				/* #ifdef APP-NVUE */
+				lines: 1;
+				/* #endif */
+				overflow: hidden;
+				text-overflow: ellipsis;
+			}
+
+			&-arrow {
+				/* #ifndef APP-NVUE */
+				display: flex;
+				box-sizing: border-box;
+				/* #endif */
+				align-items: center;
+				justify-content: center;
+				width: 20px;
+				height: 20px;
+				margin-right: 10px;
+				transform: rotate(0deg);
+
+				&-active {
+					transform: rotate(-180deg);
+				}
+			}
+
+
+		}
+
+		&__wrap {
+			/* #ifndef APP-NVUE */
+			will-change: height;
+			box-sizing: border-box;
+			/* #endif */
+			background-color: #fff;
+			overflow: hidden;
+			position: relative;
+			height: 0;
+
+			&.is--transition {
+				// transition: all 0.3s;
+				transition-property: height, border-bottom-width;
+				transition-duration: 0.3s;
+				/* #ifndef APP-NVUE */
+				will-change: height;
+				/* #endif */
+			}
+
+
+
+			&-content {
+				position: absolute;
+				font-size: 13px;
+				color: #303133;
+				// transition: height 0.3s;
+				border-bottom-color: transparent;
+				border-bottom-style: solid;
+				border-bottom-width: 0;
+
+				&.uni-collapse-item--border {
+					border-bottom-width: 1px;
+					border-bottom-color: red;
+					border-bottom-color: #ebeef5;
+				}
+
+				&.open {
+					position: relative;
+				}
+			}
+		}
+
+		&--animation {
+			transition-property: transform;
+			transition-duration: 0.3s;
+			transition-timing-function: ease;
+		}
+
+	}
+</style>
diff --git a/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue b/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue
new file mode 100644
index 0000000..384c39a
--- /dev/null
+++ b/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue
@@ -0,0 +1,147 @@
+<template>
+	<view class="uni-collapse">
+		<slot />
+	</view>
+</template>
+<script>
+	/**
+	 * Collapse 折叠面板
+	 * @description 展示可以折叠 / 展开的内容区域
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=23
+	 * @property {String|Array} value 当前激活面板改变时触发(如果是手风琴模式,参数类型为string,否则为array)
+	 * @property {Boolean} accordion = [true|false] 是否开启手风琴效果是否开启手风琴效果
+	 * @event {Function} change 切换面板时触发,如果是手风琴模式,返回类型为string,否则为array
+	 */
+	export default {
+		name: 'uniCollapse',
+		emits:['change','activeItem','input','update:modelValue'],
+		props: {
+			value: {
+				type: [String, Array],
+				default: ''
+			},
+			modelValue: {
+				type: [String, Array],
+				default: ''
+			},
+			accordion: {
+				// 是否开启手风琴效果
+				type: [Boolean, String],
+				default: false
+			},
+		},
+		data() {
+			return {}
+		},
+		computed: {
+			// TODO 兼容 vue2 和 vue3
+			dataValue() {
+				let value = (typeof this.value === 'string' && this.value === '') ||
+					(Array.isArray(this.value) && this.value.length === 0)
+				let modelValue = (typeof this.modelValue === 'string' && this.modelValue === '') ||
+					(Array.isArray(this.modelValue) && this.modelValue.length === 0)
+				if (value) {
+					return this.modelValue
+				}
+				if (modelValue) {
+					return this.value
+				}
+
+				return this.value
+			}
+		},
+		watch: {
+			dataValue(val) {
+				this.setOpen(val)
+			}
+		},
+		created() {
+			this.childrens = []
+			this.names = []
+		},
+		mounted() {
+			this.$nextTick(()=>{
+				this.setOpen(this.dataValue)
+			})
+		},
+		methods: {
+			setOpen(val) {
+				let str = typeof val === 'string'
+				let arr = Array.isArray(val)
+				this.childrens.forEach((vm, index) => {
+					if (str) {
+						if (val === vm.nameSync) {
+							if (!this.accordion) {
+								console.warn('accordion 属性为 false ,v-model 类型应该为 array')
+								return
+							}
+							vm.isOpen = true
+						}
+					}
+					if (arr) {
+						val.forEach(v => {
+							if (v === vm.nameSync) {
+								if (this.accordion) {
+									console.warn('accordion 属性为 true ,v-model 类型应该为 string')
+									return
+								}
+								vm.isOpen = true
+							}
+						})
+					}
+				})
+				this.emit(val)
+			},
+			setAccordion(self) {
+				if (!this.accordion) return
+				this.childrens.forEach((vm, index) => {
+					if (self !== vm) {
+						vm.isOpen = false
+					}
+				})
+			},
+			resize() {
+				this.childrens.forEach((vm, index) => {
+					// #ifndef APP-NVUE
+					vm.getCollapseHeight()
+					// #endif
+					// #ifdef APP-NVUE
+					vm.getNvueHwight()
+					// #endif
+				})
+			},
+			onChange(isOpen, self) {
+				let activeItem = []
+
+				if (this.accordion) {
+					activeItem = isOpen ? self.nameSync : ''
+				} else {
+					this.childrens.forEach((vm, index) => {
+						if (vm.isOpen) {
+							activeItem.push(vm.nameSync)
+						}
+					})
+				}
+				this.$emit('change', activeItem)
+				this.emit(activeItem)
+			},
+			emit(val){
+				this.$emit('input', val)
+				this.$emit('update:modelValue', val)
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	.uni-collapse {
+		/* #ifndef APP-NVUE */
+		width: 100%;
+		display: flex;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+		flex-direction: column;
+		background-color: #fff;
+	}
+</style>
diff --git a/uni_modules/uni-collapse/package.json b/uni_modules/uni-collapse/package.json
new file mode 100644
index 0000000..65c5c2e
--- /dev/null
+++ b/uni_modules/uni-collapse/package.json
@@ -0,0 +1,86 @@
+{
+  "id": "uni-collapse",
+  "displayName": "uni-collapse 折叠面板",
+  "version": "1.4.4",
+  "description": "Collapse 组件,可以折叠 / 展开的内容区域。",
+  "keywords": [
+    "uni-ui",
+    "折叠",
+    "折叠面板",
+    "手风琴"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+      "uni-icons"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-collapse/readme.md b/uni_modules/uni-collapse/readme.md
new file mode 100644
index 0000000..bc758eb
--- /dev/null
+++ b/uni_modules/uni-collapse/readme.md
@@ -0,0 +1,12 @@
+
+
+## Collapse 折叠面板
+> **组件名:uni-collapse**
+> 代码块: `uCollapse`
+> 关联组件:`uni-collapse-item`、`uni-icons`。
+
+
+折叠面板用来折叠/显示过长的内容或者是列表。通常是在多内容分类项使用,折叠不重要的内容,显示重要内容。点击可以展开折叠部分。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-collapse)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-combox/changelog.md b/uni_modules/uni-combox/changelog.md
new file mode 100644
index 0000000..a9c0f2c
--- /dev/null
+++ b/uni_modules/uni-combox/changelog.md
@@ -0,0 +1,17 @@
+## 1.0.2(2024-09-21)
+- 新增 clearAble属性
+## 1.0.1(2021-11-23)
+- 优化 label、label-width 属性
+## 1.0.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-combox](https://uniapp.dcloud.io/component/uniui/uni-combox)
+## 0.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.0.6(2021-05-12)
+- 新增 组件示例地址
+## 0.0.5(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 0.0.4(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 0.0.3(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-combox/components/uni-combox/uni-combox.vue b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
new file mode 100644
index 0000000..cc702c2
--- /dev/null
+++ b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
@@ -0,0 +1,284 @@
+<template>
+	<view class="uni-combox" :class="border ? '' : 'uni-combox__no-border'">
+		<view v-if="label" class="uni-combox__label" :style="labelStyle">
+			<text>{{label}}</text>
+		</view>
+		<view class="uni-combox__input-box">
+			<input class="uni-combox__input" type="text" :placeholder="placeholder" placeholder-class="uni-combox__input-plac"
+				v-model="inputVal" @input="onInput" @focus="onFocus" @blur="onBlur" />
+			<uni-icons v-if="!inputVal || !clearAble" :type="showSelector? 'top' : 'bottom'" size="14" color="#999" @click="toggleSelector">
+			</uni-icons>
+			<uni-icons v-if="inputVal && clearAble" type="clear" size="24" color="#999" @click="clean">
+			</uni-icons>
+		</view>
+		<view class="uni-combox__selector" v-if="showSelector">
+			<view class="uni-popper__arrow"></view>
+			<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
+				<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0">
+					<text>{{emptyTips}}</text>
+				</view>
+				<view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index"
+					@click="onSelectorClick(index)">
+					<text>{{item}}</text>
+				</view>
+			</scroll-view>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Combox 组合输入框
+	 * @description 组合输入框一般用于既可以输入也可以选择的场景
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=1261
+	 * @property {String} label 左侧文字
+	 * @property {String} labelWidth 左侧内容宽度
+	 * @property {String} placeholder 输入框占位符
+	 * @property {Array} candidates 候选项列表
+	 * @property {String} emptyTips 筛选结果为空时显示的文字
+	 * @property {String} value 组合框的值
+	 */
+	export default {
+		name: 'uniCombox',
+		emits: ['input', 'update:modelValue'],
+		props: {
+			clearAble: {
+				type: Boolean,
+				default: false
+			},
+			border: {
+				type: Boolean,
+				default: true
+			},
+			label: {
+				type: String,
+				default: ''
+			},
+			labelWidth: {
+				type: String,
+				default: 'auto'
+			},
+			placeholder: {
+				type: String,
+				default: ''
+			},
+			candidates: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			emptyTips: {
+				type: String,
+				default: '无匹配项'
+			},
+			// #ifndef VUE3
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				type: [String, Number],
+				default: ''
+			},
+			// #endif
+		},
+		data() {
+			return {
+				showSelector: false,
+				inputVal: ''
+			}
+		},
+		computed: {
+			labelStyle() {
+				if (this.labelWidth === 'auto') {
+					return ""
+				}
+				return `width: ${this.labelWidth}`
+			},
+			filterCandidates() {
+				return this.candidates.filter((item) => {
+					return item.toString().indexOf(this.inputVal) > -1
+				})
+			},
+			filterCandidatesLength() {
+				return this.filterCandidates.length
+			}
+		},
+		watch: {
+			// #ifndef VUE3
+			value: {
+				handler(newVal) {
+					this.inputVal = newVal
+				},
+				immediate: true
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				handler(newVal) {
+					this.inputVal = newVal
+				},
+				immediate: true
+			},
+			// #endif
+		},
+		methods: {
+			toggleSelector() {
+				this.showSelector = !this.showSelector
+			},
+			onFocus() {
+				this.showSelector = true
+			},
+			onBlur() {
+				setTimeout(() => {
+					this.showSelector = false
+				}, 153)
+			},
+			onSelectorClick(index) {
+				this.inputVal = this.filterCandidates[index]
+				this.showSelector = false
+				this.$emit('input', this.inputVal)
+				this.$emit('update:modelValue', this.inputVal)
+			},
+			onInput() {
+				setTimeout(() => {
+					this.$emit('input', this.inputVal)
+					this.$emit('update:modelValue', this.inputVal)
+				})
+			},
+			clean() {
+				this.inputVal = ''
+				this.onInput()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-combox {
+		font-size: 14px;
+		border: 1px solid #DCDFE6;
+		border-radius: 4px;
+		padding: 6px 10px;
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		// height: 40px;
+		flex-direction: row;
+		align-items: center;
+		// border-bottom: solid 1px #DDDDDD;
+	}
+
+	.uni-combox__label {
+		font-size: 16px;
+		line-height: 22px;
+		padding-right: 10px;
+		color: #999999;
+	}
+
+	.uni-combox__input-box {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		align-items: center;
+	}
+
+	.uni-combox__input {
+		flex: 1;
+		font-size: 14px;
+		height: 22px;
+		line-height: 22px;
+	}
+
+	.uni-combox__input-plac {
+		font-size: 14px;
+		color: #999;
+	}
+
+	.uni-combox__selector {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		/* #endif */
+		position: absolute;
+		top: calc(100% + 12px);
+		left: 0;
+		width: 100%;
+		background-color: #FFFFFF;
+		border: 1px solid #EBEEF5;
+		border-radius: 6px;
+		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+		z-index: 2;
+		padding: 4px 0;
+	}
+
+	.uni-combox__selector-scroll {
+		/* #ifndef APP-NVUE */
+		max-height: 200px;
+		box-sizing: border-box;
+		/* #endif */
+	}
+
+	.uni-combox__selector-empty,
+	.uni-combox__selector-item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		cursor: pointer;
+		/* #endif */
+		line-height: 36px;
+		font-size: 14px;
+		text-align: center;
+		// border-bottom: solid 1px #DDDDDD;
+		padding: 0px 10px;
+	}
+
+	.uni-combox__selector-item:hover {
+		background-color: #f9f9f9;
+	}
+
+	.uni-combox__selector-empty:last-child,
+	.uni-combox__selector-item:last-child {
+		/* #ifndef APP-NVUE */
+		border-bottom: none;
+		/* #endif */
+	}
+
+	// picker 弹出层通用的指示小三角
+	.uni-popper__arrow,
+	.uni-popper__arrow::after {
+		position: absolute;
+		display: block;
+		width: 0;
+		height: 0;
+		border-color: transparent;
+		border-style: solid;
+		border-width: 6px;
+	}
+
+	.uni-popper__arrow {
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+		top: -6px;
+		left: 10%;
+		margin-right: 3px;
+		border-top-width: 0;
+		border-bottom-color: #EBEEF5;
+	}
+
+	.uni-popper__arrow::after {
+		content: " ";
+		top: 1px;
+		margin-left: -6px;
+		border-top-width: 0;
+		border-bottom-color: #fff;
+	}
+
+	.uni-combox__no-border {
+		border: none;
+	}
+</style>
diff --git a/uni_modules/uni-combox/package.json b/uni_modules/uni-combox/package.json
new file mode 100644
index 0000000..7af24fc
--- /dev/null
+++ b/uni_modules/uni-combox/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-combox",
+  "displayName": "uni-combox 组合框",
+  "version": "1.0.2",
+  "description": "可以选择也可以输入的表单项 ",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "combox",
+    "组合框",
+    "select"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-combox/readme.md b/uni_modules/uni-combox/readme.md
new file mode 100644
index 0000000..ffa2cc8
--- /dev/null
+++ b/uni_modules/uni-combox/readme.md
@@ -0,0 +1,11 @@
+
+
+## Combox 组合框
+> **组件名:uni-combox**
+> 代码块: `uCombox`
+
+
+组合框组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-combox)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-countdown/changelog.md b/uni_modules/uni-countdown/changelog.md
new file mode 100644
index 0000000..1337418
--- /dev/null
+++ b/uni_modules/uni-countdown/changelog.md
@@ -0,0 +1,28 @@
+## 1.2.4(2024-09-21)
+- 新增 支持控制显示位数 默认显示2位
+## 1.2.3(2024-02-20)
+- 新增 支持控制小时,分钟的显隐:showHour showMinute
+## 1.2.2(2022-01-19)
+- 修复 在微信小程序中样式不生效的bug
+## 1.2.1(2022-01-18)
+- 新增 update 方法 ,在动态更新时间后,刷新组件
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-countdown](https://uniapp.dcloud.io/component/uniui/uni-countdown)
+## 1.1.3(2021-10-18)
+- 重构
+- 新增 font-size 支持自定义字体大小
+## 1.1.2(2021-08-24)
+- 新增 支持国际化
+## 1.1.1(2021-07-30)
+- 优化 vue3下小程序事件警告的问题
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.5(2021-06-18)
+- 修复 uni-countdown 重复赋值跳两秒的 bug
+## 1.0.4(2021-05-12)
+- 新增 组件示例地址
+## 1.0.3(2021-05-08)
+- 修复 uni-countdown 不能控制倒计时的 bug
+## 1.0.2(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json b/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json
new file mode 100644
index 0000000..06309cb
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json
@@ -0,0 +1,6 @@
+{
+	"uni-countdown.day": "day",
+	"uni-countdown.h": "h",
+	"uni-countdown.m": "m",
+	"uni-countdown.s": "s"
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js b/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json
new file mode 100644
index 0000000..358cdd1
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json
@@ -0,0 +1,6 @@
+{
+	"uni-countdown.day": "天",
+	"uni-countdown.h": "时",
+	"uni-countdown.m": "分",
+	"uni-countdown.s": "秒"
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json
new file mode 100644
index 0000000..e5a63de
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json
@@ -0,0 +1,6 @@
+{
+	"uni-countdown.day": "天",
+	"uni-countdown.h": "時",
+	"uni-countdown.m": "分",
+	"uni-countdown.s": "秒"
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue b/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
new file mode 100644
index 0000000..94a90ae
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
@@ -0,0 +1,276 @@
+<template>
+	<view class="uni-countdown">
+		<text v-if="showDay" :style="[timeStyle]" class="uni-countdown__number">{{ d }}</text>
+		<text v-if="showDay" :style="[splitorStyle]" class="uni-countdown__splitor">{{dayText}}</text>
+		<text v-if="showHour" :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text>
+		<text v-if="showHour" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text>
+		<text v-if="showMinute" :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text>
+		<text v-if="showMinute" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text>
+		<text :style="[timeStyle]" class="uni-countdown__number">{{ s }}</text>
+		<text v-if="!showColon" :style="[splitorStyle]" class="uni-countdown__splitor">{{secondText}}</text>
+	</view>
+</template>
+<script>
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(messages)
+	/**
+	 * Countdown 倒计时
+	 * @description 倒计时组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=25
+	 * @property {String} backgroundColor 背景色
+	 * @property {String} color 文字颜色
+	 * @property {Number} day 天数
+	 * @property {Number} hour 小时
+	 * @property {Number} minute 分钟
+	 * @property {Number} second 秒
+	 * @property {Number} timestamp 时间戳
+	 * @property {Boolean} showDay = [true|false] 是否显示天数
+	 * @property {Boolean} showHour = [true|false] 是否显示小时
+	 * @property {Boolean} showMinute = [true|false] 是否显示分钟
+	 * @property {Boolean} show-colon = [true|false] 是否以冒号为分隔符
+	 * @property {String} splitorColor 分割符号颜色
+	 * @event {Function} timeup 倒计时时间到触发事件
+	 * @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>
+	 */
+	export default {
+		name: 'UniCountdown',
+		emits: ['timeup'],
+		props: {
+			showDay: {
+				type: Boolean,
+				default: true
+			},
+			showHour: {
+				type: Boolean,
+				default: true
+			},
+			showMinute: {
+				type: Boolean,
+				default: true
+			},
+			showColon: {
+				type: Boolean,
+				default: true
+			},
+			start: {
+				type: Boolean,
+				default: true
+			},
+			backgroundColor: {
+				type: String,
+				default: ''
+			},
+			color: {
+				type: String,
+				default: '#333'
+			},
+			fontSize: {
+				type: Number,
+				default: 14
+			},
+			splitorColor: {
+				type: String,
+				default: '#333'
+			},
+			day: {
+				type: Number,
+				default: 0
+			},
+			hour: {
+				type: Number,
+				default: 0
+			},
+			minute: {
+				type: Number,
+				default: 0
+			},
+			second: {
+				type: Number,
+				default: 0
+			},
+			timestamp: {
+				type: Number,
+				default: 0
+			},
+			filterShow : {
+				type:Object,
+				default:{}
+			}
+		},
+		data() {
+			return {
+				timer: null,
+				syncFlag: false,
+				d: '00',
+				h: '00',
+				i: '00',
+				s: '00',
+				leftTime: 0,
+				seconds: 0
+			}
+		},
+		computed: {
+			dayText() {
+				return t("uni-countdown.day")
+			},
+			hourText(val) {
+				return t("uni-countdown.h")
+			},
+			minuteText(val) {
+				return t("uni-countdown.m")
+			},
+			secondText(val) {
+				return t("uni-countdown.s")
+			},
+			timeStyle() {
+				const {
+					color,
+					backgroundColor,
+					fontSize
+				} = this
+				return {
+					color,
+					backgroundColor,
+					fontSize: `${fontSize}px`,
+					width: `${fontSize * 22 / 14}px`, // 按字体大小为 14px 时的比例缩放
+ 					lineHeight: `${fontSize * 20 / 14}px`,
+					borderRadius: `${fontSize * 3 / 14}px`,
+				}
+			},
+			splitorStyle() {
+				const { splitorColor, fontSize, backgroundColor } = this
+				return {
+					color: splitorColor,
+					fontSize: `${fontSize * 12 / 14}px`,
+					margin: backgroundColor ? `${fontSize * 4 / 14}px` : ''
+				}
+			}
+		},
+		watch: {
+			day(val) {
+				this.changeFlag()
+			},
+			hour(val) {
+				this.changeFlag()
+			},
+			minute(val) {
+				this.changeFlag()
+			},
+			second(val) {
+				this.changeFlag()
+			},
+			start: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					if (newVal) {
+						this.startData();
+					} else {
+						if (!oldVal) return
+						clearInterval(this.timer)
+					}
+				}
+
+			}
+		},
+		created: function(e) {
+			this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
+			this.countDown()
+		},
+		// #ifndef VUE3
+		destroyed() {
+			clearInterval(this.timer)
+		},
+		// #endif
+		// #ifdef VUE3
+		unmounted() {
+			clearInterval(this.timer)
+		},
+		// #endif
+		methods: {
+			toSeconds(timestamp, day, hours, minutes, seconds) {
+				if (timestamp) {
+					return timestamp - parseInt(new Date().getTime() / 1000, 10)
+				}
+				return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
+			},
+			timeUp() {
+				clearInterval(this.timer)
+				this.$emit('timeup')
+			},
+			countDown() {
+				let seconds = this.seconds
+				let [day, hour, minute, second] = [0, 0, 0, 0]
+				if (seconds > 0) {
+					day = Math.floor(seconds / (60 * 60 * 24))
+					hour = Math.floor(seconds / (60 * 60)) - (day * 24)
+					minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
+					second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
+				} else {
+					this.timeUp()
+				}
+				this.d  = String(day).padStart(this.validFilterShow(this.filterShow.d), '0')
+				this.h = String(hour).padStart(this.validFilterShow(this.filterShow.h), '0')
+				this.i = String(minute).padStart(this.validFilterShow(this.filterShow.m), '0')
+				this.s = String(second).padStart(this.validFilterShow(this.filterShow.s), '0')
+			},
+			validFilterShow(filter){
+				return (filter && filter > 0) ? filter : 2;
+			},
+			startData() {
+				this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
+				if (this.seconds <= 0) {
+					this.seconds = this.toSeconds(0, 0, 0, 0, 0)
+					this.countDown()
+					return
+				}
+				clearInterval(this.timer)
+				this.countDown()
+				this.timer = setInterval(() => {
+					this.seconds--
+					if (this.seconds < 0) {
+						this.timeUp()
+						return
+					}
+					this.countDown()
+				}, 1000)
+			},
+			update(){
+				this.startData();
+			},
+			changeFlag() {
+				if (!this.syncFlag) {
+					this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
+					this.startData();
+					this.syncFlag = true;
+				}
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	$font-size: 14px;
+
+	.uni-countdown {
+		display: flex;
+		flex-direction: row;
+		justify-content: flex-start;
+		align-items: center;
+
+		&__splitor {
+			margin: 0 2px;
+			font-size: $font-size;
+			color: #333;
+		}
+
+		&__number {
+			border-radius: 3px;
+			text-align: center;
+			font-size: $font-size;
+		}
+	}
+</style>
diff --git a/uni_modules/uni-countdown/package.json b/uni_modules/uni-countdown/package.json
new file mode 100644
index 0000000..9ec970b
--- /dev/null
+++ b/uni_modules/uni-countdown/package.json
@@ -0,0 +1,84 @@
+{
+  "id": "uni-countdown",
+  "displayName": "uni-countdown 倒计时",
+  "version": "1.2.4",
+  "description": "CountDown 倒计时组件",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "countdown",
+    "倒计时"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-countdown/readme.md b/uni_modules/uni-countdown/readme.md
new file mode 100644
index 0000000..4bcb1aa
--- /dev/null
+++ b/uni_modules/uni-countdown/readme.md
@@ -0,0 +1,10 @@
+
+
+## CountDown 倒计时
+> **组件名:uni-countdown**
+> 代码块: `uCountDown`
+
+倒计时组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-countdown)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-data-checkbox/changelog.md b/uni_modules/uni-data-checkbox/changelog.md
new file mode 100644
index 0000000..b475fcb
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/changelog.md
@@ -0,0 +1,49 @@
+## 1.0.5(2024-03-20)
+- 修复 单选模式下选中样式不生效的bug
+## 1.0.4(2024-01-27)
+- 修复 修复错别字chagne为change
+## 1.0.3(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 1.0.2(2022-06-30)
+- 优化 在 uni-forms 中的依赖注入方式
+## 1.0.1(2022-02-07)
+- 修复 multiple 为 true 时,v-model 的值为 null 报错的 bug
+## 1.0.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-checkbox](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
+## 0.2.5(2021-08-23)
+- 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
+## 0.2.4(2021-08-17)
+- 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
+## 0.2.3(2021-08-11)
+- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+## 0.2.2(2021-07-30)
+- 优化 在uni-forms组件,与label不对齐的问题
+## 0.2.1(2021-07-27)
+- 修复 单选默认值为0不能选中的Bug
+## 0.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.1.11(2021-07-06)
+- 优化 删除无用日志
+## 0.1.10(2021-07-05)
+- 修复 由 0.1.9 引起的非 nvue 端图标不显示的问题
+## 0.1.9(2021-07-05)
+- 修复 nvue 黑框样式问题
+## 0.1.8(2021-06-28)
+- 修复 selectedTextColor 属性不生效的Bug
+## 0.1.7(2021-06-02)
+- 新增 map 属性,可以方便映射text/value属性
+## 0.1.6(2021-05-26)
+- 修复 不关联服务空间的情况下组件报错的Bug
+## 0.1.5(2021-05-12)
+- 新增 组件示例地址
+## 0.1.4(2021-04-09)
+- 修复 nvue 下无法选中的问题
+## 0.1.3(2021-03-22)
+- 新增 disabled属性
+## 0.1.2(2021-02-24)
+- 优化 默认颜色显示
+## 0.1.1(2021-02-24)
+- 新增 支持nvue
+## 0.1.0(2021-02-18)
+- “暂无数据”显示居中
diff --git a/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
new file mode 100644
index 0000000..81d3f07
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
@@ -0,0 +1,849 @@
+<template>
+	<view class="uni-data-checklist" :style="{'margin-top':isTop+'px'}">
+		<template v-if="!isLocal">
+			<view class="uni-data-loading">
+				<uni-load-more v-if="!mixinDatacomErrorMessage" status="loading" iconType="snow" :iconSize="18"
+					:content-text="contentText"></uni-load-more>
+				<text v-else>{{mixinDatacomErrorMessage}}</text>
+			</view>
+		</template>
+		<template v-else>
+			<checkbox-group v-if="multiple" class="checklist-group" :class="{'is-list':mode==='list' || wrap}"
+				@change="change">
+				<label class="checklist-box"
+					:class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
+					:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
+					<checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item[map.value]+''"
+						:checked="item.selected" />
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')"
+						class="checkbox__inner" :style="item.styleIcon">
+						<view class="checkbox__inner-icon"></view>
+					</view>
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+						<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
+					</view>
+				</label>
+			</checkbox-group>
+			<radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="change">
+				<label class="checklist-box"
+					:class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
+					:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
+					<radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item[map.value]+''"
+						:checked="item.selected" />
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="radio__inner"
+						:style="item.styleBackgroud">
+						<view class="radio__inner-icon" :style="item.styleIcon"></view>
+					</view>
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+						<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
+					</view>
+				</label>
+			</radio-group>
+		</template>
+	</view>
+</template>
+
+<script>
+	/**
+	 * DataChecklist 数据选择器
+	 * @description 通过数据渲染 checkbox 和 radio
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
+	 * @property {String} mode = [default| list | button | tag] 显示模式
+	 * @value default  	默认横排模式
+	 * @value list		列表模式
+	 * @value button	按钮模式
+	 * @value tag 		标签模式
+	 * @property {Boolean} multiple = [true|false] 是否多选
+	 * @property {Array|String|Number} value 默认值
+	 * @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
+	 * @property {Number|String} min 最小选择个数 ,multiple为true时生效
+	 * @property {Number|String} max 最大选择个数 ,multiple为true时生效
+	 * @property {Boolean} wrap 是否换行显示
+	 * @property {String} icon = [left|right]  list 列表模式下icon显示位置
+	 * @property {Boolean} selectedColor 选中颜色
+	 * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
+	 * @property {Boolean} selectedTextColor 选中文本颜色,如不填写则自动显示
+	 * @property {Object} map 字段映射, 默认 map={text:'text',value:'value'}
+	 * @value left 左侧显示
+	 * @value right 右侧显示
+	 * @event {Function} change  选中发生变化触发
+	 */
+
+	export default {
+		name: 'uniDataChecklist',
+		mixins: [uniCloud.mixinDatacom || {}],
+		emits: ['input', 'update:modelValue', 'change'],
+		props: {
+			mode: {
+				type: String,
+				default: 'default'
+			},
+
+			multiple: {
+				type: Boolean,
+				default: false
+			},
+			value: {
+				type: [Array, String, Number],
+				default () {
+					return ''
+				}
+			},
+			// TODO vue3
+			modelValue: {
+				type: [Array, String, Number],
+				default () {
+					return '';
+				}
+			},
+			localdata: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			min: {
+				type: [Number, String],
+				default: ''
+			},
+			max: {
+				type: [Number, String],
+				default: ''
+			},
+			wrap: {
+				type: Boolean,
+				default: false
+			},
+			icon: {
+				type: String,
+				default: 'left'
+			},
+			selectedColor: {
+				type: String,
+				default: ''
+			},
+			selectedTextColor: {
+				type: String,
+				default: ''
+			},
+			emptyText: {
+				type: String,
+				default: '暂无数据'
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			map: {
+				type: Object,
+				default () {
+					return {
+						text: 'text',
+						value: 'value'
+					}
+				}
+			}
+		},
+		watch: {
+			localdata: {
+				handler(newVal) {
+					this.range = newVal
+					this.dataList = this.getDataList(this.getSelectedValue(newVal))
+				},
+				deep: true
+			},
+			mixinDatacomResData(newVal) {
+				this.range = newVal
+				this.dataList = this.getDataList(this.getSelectedValue(newVal))
+			},
+			value(newVal) {
+				this.dataList = this.getDataList(newVal)
+				// fix by mehaotian is_reset 在 uni-forms 中定义
+				// if(!this.is_reset){
+				// 	this.is_reset = false
+				// 	this.formItem && this.formItem.setValue(newVal)
+				// }
+			},
+			modelValue(newVal) {
+				this.dataList = this.getDataList(newVal);
+				// if(!this.is_reset){
+				// 	this.is_reset = false
+				// 	this.formItem && this.formItem.setValue(newVal)
+				// }
+			}
+		},
+		data() {
+			return {
+				dataList: [],
+				range: [],
+				contentText: {
+					contentdown: '查看更多',
+					contentrefresh: '加载中',
+					contentnomore: '没有更多'
+				},
+				isLocal: true,
+				styles: {
+					selectedColor: '#2979ff',
+					selectedTextColor: '#666',
+				},
+				isTop: 0
+			};
+		},
+		computed: {
+			dataValue() {
+				if (this.value === '') return this.modelValue
+				if (this.modelValue === '') return this.value
+				return this.value
+			}
+		},
+		created() {
+			// this.form = this.getForm('uniForms')
+			// this.formItem = this.getForm('uniFormsItem')
+			// this.formItem && this.formItem.setValue(this.value)
+
+			// if (this.formItem) {
+			// 	this.isTop = 6
+			// 	if (this.formItem.name) {
+			// 		// 如果存在name添加默认值,否则formData 中不存在这个字段不校验
+			// 		if(!this.is_reset){
+			// 			this.is_reset = false
+			// 			this.formItem.setValue(this.dataValue)
+			// 		}
+			// 		this.rename = this.formItem.name
+			// 		this.form.inputChildrens.push(this)
+			// 	}
+			// }
+
+			if (this.localdata && this.localdata.length !== 0) {
+				this.isLocal = true
+				this.range = this.localdata
+				this.dataList = this.getDataList(this.getSelectedValue(this.range))
+			} else {
+				if (this.collection) {
+					this.isLocal = false
+					this.loadData()
+				}
+			}
+		},
+		methods: {
+			loadData() {
+				this.mixinDatacomGet().then(res => {
+					this.mixinDatacomResData = res.result.data
+					if (this.mixinDatacomResData.length === 0) {
+						this.isLocal = false
+						this.mixinDatacomErrorMessage = this.emptyText
+					} else {
+						this.isLocal = true
+					}
+				}).catch(err => {
+					this.mixinDatacomErrorMessage = err.message
+				})
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniForms') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			change(e) {
+				const values = e.detail.value
+
+				let detail = {
+					value: [],
+					data: []
+				}
+
+				if (this.multiple) {
+					this.range.forEach(item => {
+
+						if (values.includes(item[this.map.value] + '')) {
+							detail.value.push(item[this.map.value])
+							detail.data.push(item)
+						}
+					})
+				} else {
+					const range = this.range.find(item => (item[this.map.value] + '') === values)
+					if (range) {
+						detail = {
+							value: range[this.map.value],
+							data: range
+						}
+					}
+				}
+				// this.formItem && this.formItem.setValue(detail.value)
+				// TODO 兼容 vue2
+				this.$emit('input', detail.value);
+				// // TOTO 兼容 vue3
+				this.$emit('update:modelValue', detail.value);
+				this.$emit('change', {
+					detail
+				})
+				if (this.multiple) {
+					// 如果 v-model 没有绑定 ,则走内部逻辑
+					// if (this.value.length === 0) {
+					this.dataList = this.getDataList(detail.value, true)
+					// }
+				} else {
+					this.dataList = this.getDataList(detail.value)
+				}
+			},
+
+			/**
+			 * 获取渲染的新数组
+			 * @param {Object} value 选中内容
+			 */
+			getDataList(value) {
+				// 解除引用关系,破坏原引用关系,避免污染源数据
+				let dataList = JSON.parse(JSON.stringify(this.range))
+				let list = []
+				if (this.multiple) {
+					if (!Array.isArray(value)) {
+						value = []
+					}
+				}
+				dataList.forEach((item, index) => {
+					item.disabled = item.disable || item.disabled || false
+					if (this.multiple) {
+						if (value.length > 0) {
+							let have = value.find(val => val === item[this.map.value])
+							item.selected = have !== undefined
+						} else {
+							item.selected = false
+						}
+					} else {
+						item.selected = value === item[this.map.value]
+					}
+
+					list.push(item)
+				})
+				return this.setRange(list)
+			},
+			/**
+			 * 处理最大最小值
+			 * @param {Object} list
+			 */
+			setRange(list) {
+				let selectList = list.filter(item => item.selected)
+				let min = Number(this.min) || 0
+				let max = Number(this.max) || ''
+				list.forEach((item, index) => {
+					if (this.multiple) {
+						if (selectList.length <= min) {
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
+							if (have !== undefined) {
+								item.disabled = true
+							}
+						}
+
+						if (selectList.length >= max && max !== '') {
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
+							if (have === undefined) {
+								item.disabled = true
+							}
+						}
+					}
+					this.setStyles(item, index)
+					list[index] = item
+				})
+				return list
+			},
+			/**
+			 * 设置 class
+			 * @param {Object} item
+			 * @param {Object} index
+			 */
+			setStyles(item, index) {
+				//  设置自定义样式
+				item.styleBackgroud = this.setStyleBackgroud(item)
+				item.styleIcon = this.setStyleIcon(item)
+				item.styleIconText = this.setStyleIconText(item)
+				item.styleRightIcon = this.setStyleRightIcon(item)
+			},
+
+			/**
+			 * 获取选中值
+			 * @param {Object} range
+			 */
+			getSelectedValue(range) {
+				if (!this.multiple) return this.dataValue
+				let selectedArr = []
+				range.forEach((item) => {
+					if (item.selected) {
+						selectedArr.push(item[this.map.value])
+					}
+				})
+				return this.dataValue.length > 0 ? this.dataValue : selectedArr
+			},
+
+			/**
+			 * 设置背景样式
+			 */
+			setStyleBackgroud(item) {
+				let styles = {}
+				let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
+				if (this.selectedColor) {
+					if (this.mode !== 'list') {
+						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
+					}
+					if (this.mode === 'tag') {
+						styles['background-color'] = item.selected ? selectedColor : '#f5f5f5'
+					}
+				}
+				let classles = ''
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleIcon(item) {
+				let styles = {}
+				let classles = ''
+				if (this.selectedColor) {
+					let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
+					styles['background-color'] = item.selected ? selectedColor : '#fff'
+					styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
+
+					if (!item.selected && item.disabled) {
+						styles['background-color'] = '#F2F6FC'
+						styles['border-color'] = item.selected ? selectedColor : '#DCDFE6'
+					}
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleIconText(item) {
+				let styles = {}
+				let classles = ''
+				if (this.selectedColor) {
+					let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff'
+					if (this.mode === 'tag') {
+						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : '#fff') : '#666'
+					} else {
+						styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : selectedColor) : '#666'
+					}
+					if (!item.selected && item.disabled) {
+						styles.color = '#999'
+					}
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+				return classles
+			},
+			setStyleRightIcon(item) {
+				let styles = {}
+				let classles = ''
+				if (this.mode === 'list') {
+					styles['border-color'] = item.selected ? this.styles.selectedColor : '#DCDFE6'
+				}
+				for (let i in styles) {
+					classles += `${i}:${styles[i]};`
+				}
+
+				return classles
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #2979ff !default;
+	$border-color: #DCDFE6;
+	$disable: 0.4;
+
+	@mixin flex {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+	}
+
+	.uni-data-loading {
+		@include flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 36px;
+		padding-left: 10px;
+		color: #999;
+	}
+
+	.uni-data-checklist {
+		position: relative;
+		z-index: 0;
+		flex: 1;
+
+		// 多选样式
+		.checklist-group {
+			@include flex;
+			flex-direction: row;
+			flex-wrap: wrap;
+
+			&.is-list {
+				flex-direction: column;
+			}
+
+			.checklist-box {
+				@include flex;
+				flex-direction: row;
+				align-items: center;
+				position: relative;
+				margin: 5px 0;
+				margin-right: 25px;
+
+				.hidden {
+					position: absolute;
+					opacity: 0;
+				}
+
+				// 文字样式
+				.checklist-content {
+					@include flex;
+					flex: 1;
+					flex-direction: row;
+					align-items: center;
+					justify-content: space-between;
+
+					.checklist-text {
+						font-size: 14px;
+						color: #666;
+						margin-left: 5px;
+						line-height: 14px;
+					}
+
+					.checkobx__list {
+						border-right-width: 1px;
+						border-right-color: #007aff;
+						border-right-style: solid;
+						border-bottom-width: 1px;
+						border-bottom-color: #007aff;
+						border-bottom-style: solid;
+						height: 12px;
+						width: 6px;
+						left: -5px;
+						transform-origin: center;
+						transform: rotate(45deg);
+						opacity: 0;
+					}
+				}
+
+				// 多选样式
+				.checkbox__inner {
+					/* #ifndef APP-NVUE */
+					flex-shrink: 0;
+					box-sizing: border-box;
+					/* #endif */
+					position: relative;
+					width: 16px;
+					height: 16px;
+					border: 1px solid $border-color;
+					border-radius: 4px;
+					background-color: #fff;
+					z-index: 1;
+
+					.checkbox__inner-icon {
+						position: absolute;
+						/* #ifdef APP-NVUE */
+						top: 2px;
+						/* #endif */
+						/* #ifndef APP-NVUE */
+						top: 1px;
+						/* #endif */
+						left: 5px;
+						height: 8px;
+						width: 4px;
+						border-right-width: 1px;
+						border-right-color: #fff;
+						border-right-style: solid;
+						border-bottom-width: 1px;
+						border-bottom-color: #fff;
+						border-bottom-style: solid;
+						opacity: 0;
+						transform-origin: center;
+						transform: rotate(40deg);
+					}
+				}
+
+				// 单选样式
+				.radio__inner {
+					@include flex;
+					/* #ifndef APP-NVUE */
+					flex-shrink: 0;
+					box-sizing: border-box;
+					/* #endif */
+					justify-content: center;
+					align-items: center;
+					position: relative;
+					width: 16px;
+					height: 16px;
+					border: 1px solid $border-color;
+					border-radius: 16px;
+					background-color: #fff;
+					z-index: 1;
+
+					.radio__inner-icon {
+						width: 8px;
+						height: 8px;
+						border-radius: 10px;
+						opacity: 0;
+					}
+				}
+
+				// 默认样式
+				&.is--default {
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+
+						/* #endif */
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.radio__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+						}
+
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					// 选中
+					&.is-checked {
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+
+						.radio__inner {
+							border-color: $uni-primary;
+
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						// 选中禁用
+						&.is-disable {
+							.checkbox__inner {
+								opacity: $disable;
+							}
+
+							.checklist-text {
+								opacity: $disable;
+							}
+
+							.radio__inner {
+								opacity: $disable;
+							}
+						}
+					}
+				}
+
+				// 按钮样式
+				&.is--button {
+					margin-right: 10px;
+					padding: 5px 10px;
+					border: 1px $border-color solid;
+					border-radius: 3px;
+					transition: border-color 0.2s;
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						border: 1px #eee solid;
+						opacity: $disable;
+
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.radio__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					&.is-checked {
+						border-color: $uni-primary;
+
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+
+						.radio__inner {
+							border-color: $uni-primary;
+
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						// 选中禁用
+						&.is-disable {
+							opacity: $disable;
+						}
+					}
+				}
+
+				// 标签样式
+				&.is--tag {
+					margin-right: 10px;
+					padding: 5px 10px;
+					border: 1px $border-color solid;
+					border-radius: 3px;
+					background-color: #f5f5f5;
+
+					.checklist-text {
+						margin: 0;
+						color: #666;
+					}
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+						/* #endif */
+						opacity: $disable;
+					}
+
+					&.is-checked {
+						background-color: $uni-primary;
+						border-color: $uni-primary;
+
+						.checklist-text {
+							color: #fff;
+						}
+					}
+				}
+
+				// 列表样式
+				&.is--list {
+					/* #ifndef APP-NVUE */
+					display: flex;
+					/* #endif */
+					padding: 10px 15px;
+					padding-left: 0;
+					margin: 0;
+
+					&.is-list-border {
+						border-top: 1px #eee solid;
+					}
+
+					// 禁用
+					&.is-disable {
+						/* #ifdef H5 */
+						cursor: not-allowed;
+
+						/* #endif */
+						.checkbox__inner {
+							background-color: #F2F6FC;
+							border-color: $border-color;
+							/* #ifdef H5 */
+							cursor: not-allowed;
+							/* #endif */
+						}
+
+						.checklist-text {
+							color: #999;
+						}
+					}
+
+					&.is-checked {
+						.checkbox__inner {
+							border-color: $uni-primary;
+							background-color: $uni-primary;
+
+							.checkbox__inner-icon {
+								opacity: 1;
+								transform: rotate(45deg);
+							}
+						}
+
+						.radio__inner {
+							border-color: $uni-primary;
+							.radio__inner-icon {
+								opacity: 1;
+								background-color: $uni-primary;
+							}
+						}
+
+						.checklist-text {
+							color: $uni-primary;
+						}
+
+						.checklist-content {
+							.checkobx__list {
+								opacity: 1;
+								border-color: $uni-primary;
+							}
+						}
+
+						// 选中禁用
+						&.is-disable {
+							.checkbox__inner {
+								opacity: $disable;
+							}
+
+							.checklist-text {
+								opacity: $disable;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+</style>
diff --git a/uni_modules/uni-data-checkbox/package.json b/uni_modules/uni-data-checkbox/package.json
new file mode 100644
index 0000000..fc15e8b
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/package.json
@@ -0,0 +1,84 @@
+{
+  "id": "uni-data-checkbox",
+  "displayName": "uni-data-checkbox 数据选择器",
+  "version": "1.0.5",
+  "description": "通过数据驱动的单选框和复选框",
+  "keywords": [
+    "uni-ui",
+    "checkbox",
+    "单选",
+    "多选",
+    "单选多选"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.1.1"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-load-more","uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-data-checkbox/readme.md b/uni_modules/uni-data-checkbox/readme.md
new file mode 100644
index 0000000..6eb253d
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/readme.md
@@ -0,0 +1,18 @@
+
+
+## DataCheckbox 数据驱动的单选复选框
+> **组件名:uni-data-checkbox**
+> 代码块: `uDataCheckbox`
+
+
+本组件是基于uni-app基础组件checkbox的封装。本组件要解决问题包括:
+
+1. 数据绑定型组件:给本组件绑定一个data,会自动渲染一组候选内容。再以往,开发者需要编写不少代码实现类似功能
+2. 自动的表单校验:组件绑定了data,且符合[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)组件的表单校验规范,搭配使用会自动实现表单校验
+3. 本组件合并了单选多选
+4. 本组件有若干风格选择,如普通的单选多选框、并列button风格、tag风格。开发者可以快速选择需要的风格。但作为一个封装组件,样式代码虽然不用自己写了,却会牺牲一定的样式自定义性
+
+在uniCloud开发中,`DB Schema`中配置了enum枚举等类型后,在web控制台的[自动生成表单](https://uniapp.dcloud.io/uniCloud/schema?id=autocode)功能中,会自动生成``uni-data-checkbox``组件并绑定好data
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-data-picker/changelog.md b/uni_modules/uni-data-picker/changelog.md
new file mode 100644
index 0000000..e095788
--- /dev/null
+++ b/uni_modules/uni-data-picker/changelog.md
@@ -0,0 +1,79 @@
+## 2.0.1(2024-08-22)
+- 修复 uni-app-x v-model 没有更新传入值的 bug
+## 2.0.0(2023-12-11)
+- 新增 支持 uni-app-x
+## 1.1.2(2023-04-11)
+- 修复 更改 modelValue 报错的 bug
+- 修复 v-for 未使用 key 值控制台 warning
+## 1.1.1(2023-02-21)
+- 修复代码合并时引发 value 属性为空时不渲染数据的问题
+## 1.1.0(2023-02-15)
+- 修复 localdata 不支持动态更新的bug
+## 1.0.9(2023-02-15)
+- 修复 localdata 不支持动态更新的bug
+## 1.0.8(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 1.0.7(2022-07-06)
+- 优化 pc端图标位置不正确的问题
+## 1.0.6(2022-07-05)
+- 优化 显示样式
+## 1.0.5(2022-07-04)
+- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+## 1.0.4(2022-04-19)
+- 修复 字节小程序 本地数据无法选择下一级的Bug
+## 1.0.3(2022-02-25)
+- 修复 nvue 不支持的 v-show 的 bug
+## 1.0.2(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式
+## 1.0.1(2021-11-23)
+- 修复 由上个版本引发的map、v-model等属性不生效的bug
+## 1.0.0(2021-11-19)
+- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+## 0.4.9(2021-10-28)
+- 修复 VUE2 v-model 概率无效的 bug
+## 0.4.8(2021-10-27)
+- 修复 v-model 概率无效的 bug
+## 0.4.7(2021-10-25)
+- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
+- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
+## 0.4.6(2021-10-19)
+- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
+## 0.4.5(2021-09-26)
+- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效
+- 修复 readonly 为 true 时报错的 bug
+## 0.4.4(2021-09-26)
+- 修复 上一版本造成的 map 属性失效的 bug
+- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略
+## 0.4.3(2021-09-24)
+- 修复 某些情况下级联未触发的 bug
+## 0.4.2(2021-09-23)
+- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用
+- 新增 选项内容过长自动添加省略号
+## 0.4.1(2021-09-15)
+- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段
+## 0.4.0(2021-07-13)
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.3.5(2021-06-04)
+- 修复 无法加载云端数据的问题
+## 0.3.4(2021-05-28)
+- 修复 v-model 无效问题
+- 修复 loaddata 为空数据组时加载时间过长问题
+- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
+## 0.3.3(2021-05-12)
+- 新增 组件示例地址
+## 0.3.2(2021-04-22)
+- 修复 非树形数据有 where 属性查询报错的问题
+## 0.3.1(2021-04-15)
+- 修复 本地数据概率无法回显时问题
+## 0.3.0(2021-04-07)
+- 新增 支持云端非树形表结构数据
+- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
+## 0.2.0(2021-03-15)
+- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
+## 0.1.9(2021-03-09)
+- 修复 微信小程序某些情况下无法选择的问题
+## 0.1.8(2021-02-05)
+- 优化 部分样式在 nvue 上的兼容表现
+## 0.1.7(2021-02-05)
+- 调整为 uni_modules 目录规范
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
new file mode 100644
index 0000000..6ef26a2
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    this.$once('hook:beforeDestroy', () => {
+      document.removeEventListener('keyup', listener)
+    })
+  },
+	render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
new file mode 100644
index 0000000..dcbfd5f
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
@@ -0,0 +1,381 @@
+<template>
+  <view class="uni-data-tree">
+    <view class="uni-data-tree-input" @click="handleInput">
+      <slot :data="selectedPaths" :error="error">
+        <view class="input-value" :class="{'input-value-border': border}">
+          <text v-if="error!=null" class="error-text">{{error!.errMsg}}</text>
+          <scroll-view v-if="selectedPaths.length" class="selected-path" scroll-x="true">
+            <view class="selected-list">
+              <template v-for="(item, index) in selectedPaths">
+                <text class="text-color">{{item[mappingTextName]}}</text>
+                <text v-if="index<selectedPaths.length-1" class="input-split-line">{{split}}</text>
+              </template>
+            </view>
+          </scroll-view>
+          <text v-else-if="error==null&&!loading" class="placeholder">{{placeholder}}</text>
+          <view v-if="!readonly" class="arrow-area">
+            <view class="input-arrow"></view>
+          </view>
+        </view>
+      </slot>
+      <view v-if="loading && !isOpened" class="selected-loading">
+        <slot name="picker-loading" :loading="loading"></slot>
+      </view>
+    </view>
+    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
+    <view class="uni-data-tree-dialog" v-if="isOpened">
+      <view class="uni-popper__arrow"></view>
+      <view class="dialog-caption">
+        <view class="dialog-title-view">
+          <text class="dialog-title">{{popupTitle}}</text>
+        </view>
+        <view class="dialog-close" @click="handleClose">
+          <view class="dialog-close-plus" data-id="close"></view>
+          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
+        </view>
+      </view>
+      <view ref="pickerView" class="uni-data-pickerview">
+        <view v-if="error!=null" class="error">
+          <text class="error-text">{{error!.errMsg}}</text>
+        </view>
+        <scroll-view v-if="!isCloudDataList" :scroll-x="true">
+          <view class="selected-node-list">
+            <template v-for="(item, index) in selectedNodes">
+              <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
+                @click="onTabSelect(index)">
+                {{item[mappingTextName]}}
+              </text>
+            </template>
+          </view>
+        </scroll-view>
+        <list-view class="list-view" :scroll-y="true">
+          <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
+            <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
+            <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
+          </list-item>
+        </list-view>
+        <view class="loading-cover" v-if="loading">
+          <slot name="pickerview-loading" :loading="loading"></slot>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import { dataPicker } from "../uni-data-pickerview/uni-data-picker.uts"
+
+  /**
+   * DataPicker 级联选择
+   * @description 支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {String} popup-title 弹出窗口标题
+   * @property {Array} localdata 本地数据,参考
+   * @property {Boolean} border = [true|false] 是否有边框
+   * @property {Boolean} readonly = [true|false] 是否仅读
+   * @property {Boolean} preload = [true|false] 是否预加载数据
+   * @value true 开启预加载数据,点击弹出窗口后显示已加载数据
+   * @value false 关闭预加载数据,点击弹出窗口后开始加载数据
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询,仅查询当前选中节点
+   * @value false 关闭分布查询,一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
+   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
+   */
+  export default {
+    name: 'UniDataPicker',
+    emits: ['popupopened', 'popupclosed', 'nodeclick', 'change', 'input', 'update:modelValue', 'inputclick'],
+    mixins: [dataPicker],
+    props: {
+      popupTitle: {
+        type: String,
+        default: '请选择'
+      },
+      placeholder: {
+        type: String,
+        default: '请选择'
+      },
+      heightMobile: {
+        type: String,
+        default: ''
+      },
+      readonly: {
+        type: Boolean,
+        default: false
+      },
+      clearIcon: {
+        type: Boolean,
+        default: true
+      },
+      border: {
+        type: Boolean,
+        default: true
+      },
+      split: {
+        type: String,
+        default: '/'
+      },
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data() {
+      return {
+        isOpened: false
+      }
+    },
+    computed: {
+      isShowClearIcon() : boolean {
+        if (this.readonly) {
+          return false
+        }
+
+        if (this.clearIcon && this.selectedPaths.length > 0) {
+          return true
+        }
+
+        return false
+      }
+    },
+    created() {
+      this.load()
+    },
+    methods: {
+      clear() {
+      },
+      load() {
+        if (this.isLocalData) {
+          this.loadLocalData()
+        } else if (this.isCloudDataList || this.isCloudDataTree) {
+          this.loadCloudDataPath()
+        }
+      },
+      show() {
+        this.isOpened = true
+        this.$emit('popupopened')
+        if (!this.hasCloudTreeData) {
+          this.loadData()
+        }
+      },
+      hide() {
+        this.isOpened = false
+        this.$emit('popupclosed')
+      },
+      handleInput() {
+        if (this.readonly) {
+          this.$emit('inputclick')
+        } else {
+          this.show()
+        }
+      },
+      handleClose() {
+        this.hide()
+      },
+      onFinish() {
+        this.selectedPaths = this.getChangeNodes()
+        this.$emit('update:modelValue', this.selectedPaths)
+        this.$emit('change', this.selectedPaths)
+        this.hide()
+      }
+    }
+  }
+</script>
+
+<style>
+  @import url("../uni-data-pickerview/uni-data-pickerview.css");
+
+  .uni-data-tree {
+    position: relative;
+  }
+
+  .uni-data-tree-input {
+    position: relative;
+  }
+
+  .selected-loading {
+    display: flex;
+    justify-content: center;
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+  }
+
+  .error-text {
+    flex: 1;
+    font-size: 12px;
+    color: #DD524D;
+  }
+
+  .input-value {
+    flex-direction: row;
+    align-items: center;
+    flex-wrap: nowrap;
+    padding: 5px 5px;
+    padding-right: 5px;
+    overflow: hidden;
+    min-height: 28px;
+  }
+
+  .input-value-border {
+    border: 1px solid #e5e5e5;
+    border-radius: 5px;
+  }
+
+  .selected-path {
+    flex: 1;
+    flex-direction: row;
+    overflow: hidden;
+  }
+
+  .load-more {
+    width: 40px;
+  }
+
+  .selected-list {
+    flex-direction: row;
+    flex-wrap: nowrap;
+  }
+
+  .selected-item {
+    flex-direction: row;
+    flex-wrap: nowrap;
+  }
+
+  .text-color {
+    font-size: 14px;
+    color: #333;
+  }
+
+  .placeholder {
+    color: grey;
+    font-size: 14px;
+  }
+
+  .input-split-line {
+    opacity: .5;
+    margin-left: 1px;
+    margin-right: 1px;
+  }
+
+  .arrow-area {
+    position: relative;
+    padding: 0 12px;
+    margin-left: auto;
+    justify-content: center;
+    transform: rotate(-45deg);
+    transform-origin: center;
+  }
+
+  .input-arrow {
+    width: 8px;
+    height: 8px;
+    border-left: 2px solid #999;
+    border-bottom: 2px solid #999;
+  }
+
+  .uni-data-tree-cover {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, .4);
+    flex-direction: column;
+    z-index: 100;
+  }
+
+  .uni-data-tree-dialog {
+    position: fixed;
+    left: 0;
+    top: 20%;
+    right: 0;
+    bottom: 0;
+    background-color: #FFFFFF;
+    border-top-left-radius: 10px;
+    border-top-right-radius: 10px;
+    flex-direction: column;
+    z-index: 102;
+    overflow: hidden;
+  }
+
+  .dialog-caption {
+    position: relative;
+    flex-direction: row;
+  }
+
+  .dialog-title-view {
+    flex: 1;
+  }
+
+  .dialog-title {
+    align-self: center;
+    padding: 0 10px;
+    line-height: 44px;
+  }
+
+  .dialog-close {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    flex-direction: row;
+    align-items: center;
+    padding: 0 15px;
+  }
+
+  .dialog-close-plus {
+    width: 16px;
+    height: 2px;
+    background-color: #666;
+    border-radius: 2px;
+    transform: rotate(45deg);
+  }
+
+  .dialog-close-rotate {
+    position: absolute;
+    transform: rotate(-45deg);
+  }
+
+  .uni-data-pickerview {
+    flex: 1;
+  }
+
+  .icon-clear {
+    display: flex;
+    align-items: center;
+  }
+
+  /* #ifdef H5 */
+  @media all and (min-width: 768px) {
+    .uni-data-tree-cover {
+      background-color: transparent;
+    }
+
+    .uni-data-tree-dialog {
+      position: absolute;
+      top: 55px;
+      height: auto;
+      min-height: 400px;
+      max-height: 50vh;
+      background-color: #fff;
+      border: 1px solid #EBEEF5;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+      border-radius: 4px;
+      overflow: unset;
+    }
+
+    .dialog-caption {
+      display: none;
+    }
+  }
+  /* #endif */
+</style>
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
new file mode 100644
index 0000000..179a4e0
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
@@ -0,0 +1,551 @@
+<template>
+  <view class="uni-data-tree">
+    <view class="uni-data-tree-input" @click="handleInput">
+      <slot :options="options" :data="inputSelected" :error="errorMessage">
+        <view class="input-value" :class="{'input-value-border': border}">
+          <text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
+          <view v-else-if="loading && !isOpened" class="selected-area">
+            <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
+          </view>
+          <scroll-view v-else-if="inputSelected.length" class="selected-area" scroll-x="true">
+            <view class="selected-list">
+              <view class="selected-item" v-for="(item,index) in inputSelected" :key="index">
+                <text class="text-color">{{item.text}}</text><text v-if="index<inputSelected.length-1"
+                  class="input-split-line">{{split}}</text>
+              </view>
+            </view>
+          </scroll-view>
+          <text v-else class="selected-area placeholder">{{placeholder}}</text>
+          <view v-if="clearIcon && !readonly && inputSelected.length" class="icon-clear" @click.stop="clear">
+            <uni-icons type="clear" color="#c0c4cc" size="24"></uni-icons>
+          </view>
+          <view class="arrow-area" v-if="(!clearIcon || !inputSelected.length) && !readonly ">
+            <view class="input-arrow"></view>
+          </view>
+        </view>
+      </slot>
+    </view>
+    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
+    <view class="uni-data-tree-dialog" v-if="isOpened">
+      <view class="uni-popper__arrow"></view>
+      <view class="dialog-caption">
+        <view class="title-area">
+          <text class="dialog-title">{{popupTitle}}</text>
+        </view>
+        <view class="dialog-close" @click="handleClose">
+          <view class="dialog-close-plus" data-id="close"></view>
+          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
+        </view>
+      </view>
+      <data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata"
+        :preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where"
+        :step-searh="stepSearh" :self-field="selfField" :parent-field="parentField" :managed-mode="true" :map="map"
+        :ellipsis="ellipsis" @change="onchange" @datachange="ondatachange" @nodeclick="onnodeclick">
+      </data-picker-view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import dataPicker from "../uni-data-pickerview/uni-data-picker.js"
+  import DataPickerView from "../uni-data-pickerview/uni-data-pickerview.vue"
+
+  /**
+   * DataPicker 级联选择
+   * @description 支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {String} popup-title 弹出窗口标题
+   * @property {Array} localdata 本地数据,参考
+   * @property {Boolean} border = [true|false] 是否有边框
+   * @property {Boolean} readonly = [true|false] 是否仅读
+   * @property {Boolean} preload = [true|false] 是否预加载数据
+   * @value true 开启预加载数据,点击弹出窗口后显示已加载数据
+   * @value false 关闭预加载数据,点击弹出窗口后开始加载数据
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询,仅查询当前选中节点
+   * @value false 关闭分布查询,一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
+   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
+   */
+  export default {
+    name: 'UniDataPicker',
+    emits: ['popupopened', 'popupclosed', 'nodeclick', 'input', 'change', 'update:modelValue','inputclick'],
+    mixins: [dataPicker],
+    components: {
+      DataPickerView
+    },
+    props: {
+      options: {
+        type: [Object, Array],
+        default () {
+          return {}
+        }
+      },
+      popupTitle: {
+        type: String,
+        default: '请选择'
+      },
+      placeholder: {
+        type: String,
+        default: '请选择'
+      },
+      heightMobile: {
+        type: String,
+        default: ''
+      },
+      readonly: {
+        type: Boolean,
+        default: false
+      },
+      clearIcon: {
+        type: Boolean,
+        default: true
+      },
+      border: {
+        type: Boolean,
+        default: true
+      },
+      split: {
+        type: String,
+        default: '/'
+      },
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data() {
+      return {
+        isOpened: false,
+        inputSelected: []
+      }
+    },
+    created() {
+      this.$nextTick(() => {
+        this.load();
+      })
+    },
+    watch: {
+			localdata: {
+				handler() {
+					this.load()
+				},
+        deep: true
+			},
+    },
+    methods: {
+      clear() {
+        this._dispatchEvent([]);
+      },
+      onPropsChange() {
+        this._treeData = [];
+        this.selectedIndex = 0;
+
+        this.load();
+      },
+      load() {
+        if (this.readonly) {
+          this._processReadonly(this.localdata, this.dataValue);
+          return;
+        }
+
+        // 回显本地数据
+        if (this.isLocalData) {
+          this.loadData();
+          this.inputSelected = this.selected.slice(0);
+        } else if (this.isCloudDataList || this.isCloudDataTree) { // 回显 Cloud 数据
+          this.loading = true;
+          this.getCloudDataValue().then((res) => {
+            this.loading = false;
+            this.inputSelected = res;
+          }).catch((err) => {
+            this.loading = false;
+            this.errorMessage = err;
+          })
+        }
+      },
+      show() {
+        this.isOpened = true
+        setTimeout(() => {
+          this.$refs.pickerView.updateData({
+            treeData: this._treeData,
+            selected: this.selected,
+            selectedIndex: this.selectedIndex
+          })
+        }, 200)
+        this.$emit('popupopened')
+      },
+      hide() {
+        this.isOpened = false
+        this.$emit('popupclosed')
+      },
+      handleInput() {
+        if (this.readonly) {
+					this.$emit('inputclick')
+          return
+        }
+        this.show()
+      },
+      handleClose(e) {
+        this.hide()
+      },
+      onnodeclick(e) {
+        this.$emit('nodeclick', e)
+      },
+      ondatachange(e) {
+        this._treeData = this.$refs.pickerView._treeData
+      },
+      onchange(e) {
+        this.hide()
+        this.$nextTick(() => {
+          this.inputSelected = e;
+        })
+        this._dispatchEvent(e)
+      },
+      _processReadonly(dataList, value) {
+        var isTree = dataList.findIndex((item) => {
+          return item.children
+        })
+        if (isTree > -1) {
+          let inputValue
+          if (Array.isArray(value)) {
+            inputValue = value[value.length - 1]
+            if (typeof inputValue === 'object' && inputValue.value) {
+              inputValue = inputValue.value
+            }
+          } else {
+            inputValue = value
+          }
+          this.inputSelected = this._findNodePath(inputValue, this.localdata)
+          return
+        }
+
+        if (!this.hasValue) {
+          this.inputSelected = []
+          return
+        }
+
+        let result = []
+        for (let i = 0; i < value.length; i++) {
+          var val = value[i]
+          var item = dataList.find((v) => {
+            return v.value == val
+          })
+          if (item) {
+            result.push(item)
+          }
+        }
+        if (result.length) {
+          this.inputSelected = result
+        }
+      },
+      _filterForArray(data, valueArray) {
+        var result = []
+        for (let i = 0; i < valueArray.length; i++) {
+          var value = valueArray[i]
+          var found = data.find((item) => {
+            return item.value == value
+          })
+          if (found) {
+            result.push(found)
+          }
+        }
+        return result
+      },
+      _dispatchEvent(selected) {
+        let item = {}
+        if (selected.length) {
+          var value = new Array(selected.length)
+          for (var i = 0; i < selected.length; i++) {
+            value[i] = selected[i].value
+          }
+          item = selected[selected.length - 1]
+        } else {
+          item.value = ''
+        }
+        if (this.formItem) {
+          this.formItem.setValue(item.value)
+        }
+
+        this.$emit('input', item.value)
+        this.$emit('update:modelValue', item.value)
+        this.$emit('change', {
+          detail: {
+            value: selected
+          }
+        })
+      }
+    }
+  }
+</script>
+
+<style>
+  .uni-data-tree {
+    flex: 1;
+    position: relative;
+    font-size: 14px;
+  }
+
+  .error-text {
+    color: #DD524D;
+  }
+
+  .input-value {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    align-items: center;
+    flex-wrap: nowrap;
+    font-size: 14px;
+    /* line-height: 35px; */
+    padding: 0 10px;
+    padding-right: 5px;
+    overflow: hidden;
+    height: 35px;
+    /* #ifndef APP-NVUE */
+    box-sizing: border-box;
+    /* #endif */
+  }
+
+  .input-value-border {
+    border: 1px solid #e5e5e5;
+    border-radius: 5px;
+  }
+
+  .selected-area {
+    flex: 1;
+    overflow: hidden;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+  }
+
+  .load-more {
+    /* #ifndef APP-NVUE */
+    margin-right: auto;
+    /* #endif */
+    /* #ifdef APP-NVUE */
+    width: 40px;
+    /* #endif */
+  }
+
+  .selected-list {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    flex-wrap: nowrap;
+    /* padding: 0 5px; */
+  }
+
+  .selected-item {
+    flex-direction: row;
+    /* padding: 0 1px; */
+    /* #ifndef APP-NVUE */
+    white-space: nowrap;
+    /* #endif */
+  }
+
+  .text-color {
+    color: #333;
+  }
+
+  .placeholder {
+    color: grey;
+    font-size: 12px;
+  }
+
+  .input-split-line {
+    opacity: .5;
+  }
+
+  .arrow-area {
+    position: relative;
+    width: 20px;
+    /* #ifndef APP-NVUE */
+    margin-bottom: 5px;
+    margin-left: auto;
+    display: flex;
+    /* #endif */
+    justify-content: center;
+    transform: rotate(-45deg);
+    transform-origin: center;
+  }
+
+  .input-arrow {
+    width: 7px;
+    height: 7px;
+    border-left: 1px solid #999;
+    border-bottom: 1px solid #999;
+  }
+
+  .uni-data-tree-cover {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, .4);
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    z-index: 100;
+  }
+
+  .uni-data-tree-dialog {
+    position: fixed;
+    left: 0;
+    /* #ifndef APP-NVUE */
+    top: 20%;
+    /* #endif */
+    /* #ifdef APP-NVUE */
+    top: 200px;
+    /* #endif */
+    right: 0;
+    bottom: 0;
+    background-color: #FFFFFF;
+    border-top-left-radius: 10px;
+    border-top-right-radius: 10px;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    z-index: 102;
+    overflow: hidden;
+    /* #ifdef APP-NVUE */
+    width: 750rpx;
+    /* #endif */
+  }
+
+  .dialog-caption {
+    position: relative;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    /* border-bottom: 1px solid #f0f0f0; */
+  }
+
+  .title-area {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    align-items: center;
+    /* #ifndef APP-NVUE */
+    margin: auto;
+    /* #endif */
+    padding: 0 10px;
+  }
+
+  .dialog-title {
+    /* font-weight: bold; */
+    line-height: 44px;
+  }
+
+  .dialog-close {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    align-items: center;
+    padding: 0 15px;
+  }
+
+  .dialog-close-plus {
+    width: 16px;
+    height: 2px;
+    background-color: #666;
+    border-radius: 2px;
+    transform: rotate(45deg);
+  }
+
+  .dialog-close-rotate {
+    position: absolute;
+    transform: rotate(-45deg);
+  }
+
+  .picker-view {
+    flex: 1;
+    overflow: hidden;
+  }
+
+  .icon-clear {
+    display: flex;
+    align-items: center;
+  }
+
+  /* #ifdef H5 */
+  @media all and (min-width: 768px) {
+    .uni-data-tree-cover {
+      background-color: transparent;
+    }
+
+    .uni-data-tree-dialog {
+      position: absolute;
+      top: 55px;
+      height: auto;
+      min-height: 400px;
+      max-height: 50vh;
+      background-color: #fff;
+      border: 1px solid #EBEEF5;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+      border-radius: 4px;
+      overflow: unset;
+    }
+
+    .dialog-caption {
+      display: none;
+    }
+
+    .icon-clear {
+      /* margin-right: 5px; */
+    }
+  }
+
+  /* #endif */
+
+  /* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
+  /* #ifndef APP-NVUE */
+  .uni-popper__arrow,
+  .uni-popper__arrow::after {
+    position: absolute;
+    display: block;
+    width: 0;
+    height: 0;
+    border-color: transparent;
+    border-style: solid;
+    border-width: 6px;
+  }
+
+  .uni-popper__arrow {
+    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+    top: -6px;
+    left: 10%;
+    margin-right: 3px;
+    border-top-width: 0;
+    border-bottom-color: #EBEEF5;
+  }
+
+  .uni-popper__arrow::after {
+    content: " ";
+    top: 1px;
+    margin-left: -6px;
+    border-top-width: 0;
+    border-bottom-color: #fff;
+  }
+
+  /* #endif */
+</style>
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
new file mode 100644
index 0000000..cfae22a
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
@@ -0,0 +1,622 @@
+export default {
+  props: {
+    localdata: {
+      type: [Array, Object],
+      default () {
+        return []
+      }
+    },
+    spaceInfo: {
+      type: Object,
+      default () {
+        return {}
+      }
+    },
+    collection: {
+      type: String,
+      default: ''
+    },
+    action: {
+      type: String,
+      default: ''
+    },
+    field: {
+      type: String,
+      default: ''
+    },
+    orderby: {
+      type: String,
+      default: ''
+    },
+    where: {
+      type: [String, Object],
+      default: ''
+    },
+    pageData: {
+      type: String,
+      default: 'add'
+    },
+    pageCurrent: {
+      type: Number,
+      default: 1
+    },
+    pageSize: {
+      type: Number,
+      default: 500
+    },
+    getcount: {
+      type: [Boolean, String],
+      default: false
+    },
+    getone: {
+      type: [Boolean, String],
+      default: false
+    },
+    gettree: {
+      type: [Boolean, String],
+      default: false
+    },
+    manual: {
+      type: Boolean,
+      default: false
+    },
+    value: {
+      type: [Array, String, Number],
+      default () {
+        return []
+      }
+    },
+    modelValue: {
+      type: [Array, String, Number],
+      default () {
+        return []
+      }
+    },
+    preload: {
+      type: Boolean,
+      default: false
+    },
+    stepSearh: {
+      type: Boolean,
+      default: true
+    },
+    selfField: {
+      type: String,
+      default: ''
+    },
+    parentField: {
+      type: String,
+      default: ''
+    },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    map: {
+      type: Object,
+      default () {
+        return {
+          text: "text",
+          value: "value"
+        }
+      }
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      errorMessage: '',
+      loadMore: {
+        contentdown: '',
+        contentrefresh: '',
+        contentnomore: ''
+      },
+      dataList: [],
+      selected: [],
+      selectedIndex: 0,
+      page: {
+        current: this.pageCurrent,
+        size: this.pageSize,
+        count: 0
+      }
+    }
+  },
+  computed: {
+    isLocalData() {
+      return !this.collection.length;
+    },
+    isCloudData() {
+      return this.collection.length > 0;
+    },
+    isCloudDataList() {
+      return (this.isCloudData && (!this.parentField && !this.selfField));
+    },
+    isCloudDataTree() {
+      return (this.isCloudData && this.parentField && this.selfField);
+    },
+    dataValue() {
+      let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
+        this.modelValue !== undefined);
+      return isModelValue ? this.modelValue : this.value;
+    },
+    hasValue() {
+      if (typeof this.dataValue === 'number') {
+        return true
+      }
+      return (this.dataValue != null) && (this.dataValue.length > 0)
+    }
+  },
+  created() {
+    this.$watch(() => {
+      var al = [];
+      ['pageCurrent',
+        'pageSize',
+        'spaceInfo',
+        'value',
+        'modelValue',
+        'localdata',
+        'collection',
+        'action',
+        'field',
+        'orderby',
+        'where',
+        'getont',
+        'getcount',
+        'gettree'
+      ].forEach(key => {
+        al.push(this[key])
+      });
+      return al
+    }, (newValue, oldValue) => {
+      let needReset = false
+      for (let i = 2; i < newValue.length; i++) {
+        if (newValue[i] != oldValue[i]) {
+          needReset = true
+          break
+        }
+      }
+      if (newValue[0] != oldValue[0]) {
+        this.page.current = this.pageCurrent
+      }
+      this.page.size = this.pageSize
+
+      this.onPropsChange()
+    })
+    this._treeData = []
+  },
+  methods: {
+    onPropsChange() {
+      this._treeData = [];
+    },
+
+    // 填充 pickview 数据
+    async loadData() {
+      if (this.isLocalData) {
+        this.loadLocalData();
+      } else if (this.isCloudDataList) {
+        this.loadCloudDataList();
+      } else if (this.isCloudDataTree) {
+        this.loadCloudDataTree();
+      }
+    },
+
+    // 加载本地数据
+    async loadLocalData() {
+      this._treeData = [];
+      this._extractTree(this.localdata, this._treeData);
+
+      let inputValue = this.dataValue;
+      if (inputValue === undefined) {
+        return;
+      }
+
+      if (Array.isArray(inputValue)) {
+        inputValue = inputValue[inputValue.length - 1];
+        if (typeof inputValue === 'object' && inputValue[this.map.value]) {
+          inputValue = inputValue[this.map.value];
+        }
+      }
+
+      this.selected = this._findNodePath(inputValue, this.localdata);
+    },
+
+    // 加载 Cloud 数据 (单列)
+    async loadCloudDataList() {
+      if (this.loading) {
+        return;
+      }
+      this.loading = true;
+
+      try {
+        let response = await this.getCommand();
+        let responseData = response.result.data;
+
+        this._treeData = responseData;
+
+        this._updateBindData();
+        this._updateSelected();
+
+        this.onDataChange();
+      } catch (e) {
+        this.errorMessage = e;
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 加载 Cloud 数据 (树形)
+    async loadCloudDataTree() {
+      if (this.loading) {
+        return;
+      }
+      this.loading = true;
+
+      try {
+        let commandOptions = {
+          field: this._cloudDataPostField(),
+          where: this._cloudDataTreeWhere()
+        };
+        if (this.gettree) {
+          commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
+        }
+
+        let response = await this.getCommand(commandOptions);
+        let responseData = response.result.data;
+
+        this._treeData = responseData;
+        this._updateBindData();
+        this._updateSelected();
+
+        this.onDataChange();
+      } catch (e) {
+        this.errorMessage = e;
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 加载 Cloud 数据 (节点)
+    async loadCloudDataNode(callback) {
+      if (this.loading) {
+        return;
+      }
+      this.loading = true;
+
+      try {
+        let commandOptions = {
+          field: this._cloudDataPostField(),
+          where: this._cloudDataNodeWhere()
+        };
+
+        let response = await this.getCommand(commandOptions);
+        let responseData = response.result.data;
+
+        callback(responseData);
+      } catch (e) {
+        this.errorMessage = e;
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 回显 Cloud 数据
+    getCloudDataValue() {
+      if (this.isCloudDataList) {
+        return this.getCloudDataListValue();
+      }
+
+      if (this.isCloudDataTree) {
+        return this.getCloudDataTreeValue();
+      }
+    },
+
+    // 回显 Cloud 数据 (单列)
+    getCloudDataListValue() {
+      // 根据 field's as value标识匹配 where 条件
+      let where = [];
+      let whereField = this._getForeignKeyByField();
+      if (whereField) {
+        where.push(`${whereField} == '${this.dataValue}'`)
+      }
+
+      where = where.join(' || ');
+
+      if (this.where) {
+        where = `(${this.where}) && (${where})`
+      }
+
+      return this.getCommand({
+        field: this._cloudDataPostField(),
+        where
+      }).then((res) => {
+        this.selected = res.result.data;
+        return res.result.data;
+      });
+    },
+
+    // 回显 Cloud 数据 (树形)
+    getCloudDataTreeValue() {
+      return this.getCommand({
+        field: this._cloudDataPostField(),
+        getTreePath: {
+          startWith: `${this.selfField}=='${this.dataValue}'`
+        }
+      }).then((res) => {
+        let treePath = [];
+        this._extractTreePath(res.result.data, treePath);
+        this.selected = treePath;
+        return treePath;
+      });
+    },
+
+    getCommand(options = {}) {
+      /* eslint-disable no-undef */
+      let db = uniCloud.database(this.spaceInfo)
+
+      const action = options.action || this.action
+      if (action) {
+        db = db.action(action)
+      }
+
+      const collection = options.collection || this.collection
+      db = db.collection(collection)
+
+      const where = options.where || this.where
+      if (!(!where || !Object.keys(where).length)) {
+        db = db.where(where)
+      }
+
+      const field = options.field || this.field
+      if (field) {
+        db = db.field(field)
+      }
+
+      const orderby = options.orderby || this.orderby
+      if (orderby) {
+        db = db.orderBy(orderby)
+      }
+
+      const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
+      const size = options.pageSize !== undefined ? options.pageSize : this.page.size
+      const getCount = options.getcount !== undefined ? options.getcount : this.getcount
+      const getTree = options.gettree !== undefined ? options.gettree : this.gettree
+
+      const getOptions = {
+        getCount,
+        getTree
+      }
+      if (options.getTreePath) {
+        getOptions.getTreePath = options.getTreePath
+      }
+
+      db = db.skip(size * (current - 1)).limit(size).get(getOptions)
+
+      return db
+    },
+
+    _cloudDataPostField() {
+      let fields = [this.field];
+      if (this.parentField) {
+        fields.push(`${this.parentField} as parent_value`);
+      }
+      return fields.join(',');
+    },
+
+    _cloudDataTreeWhere() {
+      let result = []
+      let selected = this.selected
+      let parentField = this.parentField
+      if (parentField) {
+        result.push(`${parentField} == null || ${parentField} == ""`)
+      }
+      if (selected.length) {
+        for (var i = 0; i < selected.length - 1; i++) {
+          result.push(`${parentField} == '${selected[i].value}'`)
+        }
+      }
+
+      let where = []
+      if (this.where) {
+        where.push(`(${this.where})`)
+      }
+
+      if (result.length) {
+        where.push(`(${result.join(' || ')})`)
+      }
+
+      return where.join(' && ')
+    },
+
+    _cloudDataNodeWhere() {
+      let where = []
+      let selected = this.selected;
+      if (selected.length) {
+        where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
+      }
+
+      where = where.join(' || ');
+
+      if (this.where) {
+        return `(${this.where}) && (${where})`
+      }
+
+      return where
+    },
+
+    _getWhereByForeignKey() {
+      let result = []
+      let whereField = this._getForeignKeyByField();
+      if (whereField) {
+        result.push(`${whereField} == '${this.dataValue}'`)
+      }
+
+      if (this.where) {
+        return `(${this.where}) && (${result.join(' || ')})`
+      }
+
+      return result.join(' || ')
+    },
+
+    _getForeignKeyByField() {
+      let fields = this.field.split(',');
+      let whereField = null;
+      for (let i = 0; i < fields.length; i++) {
+        const items = fields[i].split('as');
+        if (items.length < 2) {
+          continue;
+        }
+        if (items[1].trim() === 'value') {
+          whereField = items[0].trim();
+          break;
+        }
+      }
+      return whereField;
+    },
+
+    _updateBindData(node) {
+      const {
+        dataList,
+        hasNodes
+      } = this._filterData(this._treeData, this.selected)
+
+      let isleaf = this._stepSearh === false && !hasNodes
+
+      if (node) {
+        node.isleaf = isleaf
+      }
+
+      this.dataList = dataList
+      this.selectedIndex = dataList.length - 1
+
+      if (!isleaf && this.selected.length < dataList.length) {
+        this.selected.push({
+          value: null,
+          text: "请选择"
+        })
+      }
+
+      return {
+        isleaf,
+        hasNodes
+      }
+    },
+
+    _updateSelected() {
+      let dl = this.dataList
+      let sl = this.selected
+      let textField = this.map.text
+      let valueField = this.map.value
+      for (let i = 0; i < sl.length; i++) {
+        let value = sl[i].value
+        let dl2 = dl[i]
+        for (let j = 0; j < dl2.length; j++) {
+          let item2 = dl2[j]
+          if (item2[valueField] === value) {
+            sl[i].text = item2[textField]
+            break
+          }
+        }
+      }
+    },
+
+    _filterData(data, paths) {
+      let dataList = []
+      let hasNodes = true
+
+      dataList.push(data.filter((item) => {
+        return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
+      }))
+      for (let i = 0; i < paths.length; i++) {
+        let value = paths[i].value
+        let nodes = data.filter((item) => {
+          return item.parent_value === value
+        })
+
+        if (nodes.length) {
+          dataList.push(nodes)
+        } else {
+          hasNodes = false
+        }
+      }
+
+      return {
+        dataList,
+        hasNodes
+      }
+    },
+
+    _extractTree(nodes, result, parent_value) {
+      let list = result || []
+      let valueField = this.map.value
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+
+        let child = {}
+        for (let key in node) {
+          if (key !== 'children') {
+            child[key] = node[key]
+          }
+        }
+        if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
+          child.parent_value = parent_value
+        }
+        result.push(child)
+
+        let children = node.children
+        if (children) {
+          this._extractTree(children, result, node[valueField])
+        }
+      }
+    },
+
+    _extractTreePath(nodes, result) {
+      let list = result || []
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+
+        let child = {}
+        for (let key in node) {
+          if (key !== 'children') {
+            child[key] = node[key]
+          }
+        }
+        result.push(child)
+
+        let children = node.children
+        if (children) {
+          this._extractTreePath(children, result)
+        }
+      }
+    },
+
+    _findNodePath(key, nodes, path = []) {
+      let textField = this.map.text
+      let valueField = this.map.value
+      for (let i = 0; i < nodes.length; i++) {
+        let node = nodes[i]
+        let children = node.children
+        let text = node[textField]
+        let value = node[valueField]
+
+        path.push({
+          value,
+          text
+        })
+
+        if (value === key) {
+          return path
+        }
+
+        if (children) {
+          const p = this._findNodePath(key, children, path)
+          if (p.length) {
+            return p
+          }
+        }
+
+        path.pop()
+      }
+      return []
+    }
+  }
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
new file mode 100644
index 0000000..857408d
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
@@ -0,0 +1,692 @@
+export type PaginationType = {
+  current : number,
+  size : number,
+  count : number
+}
+
+export type LoadMoreType = {
+  contentdown : string,
+  contentrefresh : string,
+  contentnomore : string
+}
+
+export type SelectedItemType = {
+  name : string,
+  value : string,
+}
+
+export type GetCommandOptions = {
+  collection ?: UTSJSONObject,
+  field ?: string,
+  orderby ?: string,
+  where ?: any,
+  pageData ?: string,
+  pageCurrent ?: number,
+  pageSize ?: number,
+  getCount ?: boolean,
+  getTree ?: any,
+  getTreePath ?: UTSJSONObject,
+  startwith ?: string,
+  limitlevel ?: number,
+  groupby ?: string,
+  groupField ?: string,
+  distinct ?: boolean,
+  pageIndistinct ?: boolean,
+  foreignKey ?: string,
+  loadtime ?: string,
+  manual ?: boolean
+}
+
+const DefaultSelectedNode = {
+  text: '请选择',
+  value: ''
+}
+
+export const dataPicker = defineMixin({
+  props: {
+    localdata: {
+      type: Array as PropType<Array<UTSJSONObject>>,
+      default: [] as Array<UTSJSONObject>
+    },
+    collection: {
+      type: Object,
+      default: ''
+    },
+    field: {
+      type: String,
+      default: ''
+    },
+    orderby: {
+      type: String,
+      default: ''
+    },
+    where: {
+      type: Object,
+      default: ''
+    },
+    pageData: {
+      type: String,
+      default: 'add'
+    },
+    pageCurrent: {
+      type: Number,
+      default: 1
+    },
+    pageSize: {
+      type: Number,
+      default: 20
+    },
+    getcount: {
+      type: Boolean,
+      default: false
+    },
+    gettree: {
+      type: Object,
+      default: ''
+    },
+    gettreepath: {
+      type: Object,
+      default: ''
+    },
+    startwith: {
+      type: String,
+      default: ''
+    },
+    limitlevel: {
+      type: Number,
+      default: 10
+    },
+    groupby: {
+      type: String,
+      default: ''
+    },
+    groupField: {
+      type: String,
+      default: ''
+    },
+    distinct: {
+      type: Boolean,
+      default: false
+    },
+    pageIndistinct: {
+      type: Boolean,
+      default: false
+    },
+    foreignKey: {
+      type: String,
+      default: ''
+    },
+    loadtime: {
+      type: String,
+      default: 'auto'
+    },
+    manual: {
+      type: Boolean,
+      default: false
+    },
+    preload: {
+      type: Boolean,
+      default: false
+    },
+    stepSearh: {
+      type: Boolean,
+      default: true
+    },
+    selfField: {
+      type: String,
+      default: ''
+    },
+    parentField: {
+      type: String,
+      default: ''
+    },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    value: {
+      type: Object,
+      default: ''
+    },
+    modelValue: {
+      type: Object,
+      default: ''
+    },
+    defaultProps: {
+      type: Object as PropType<UTSJSONObject>,
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      error: null as UniCloudError | null,
+      treeData: [] as Array<UTSJSONObject>,
+      selectedIndex: 0,
+      selectedNodes: [] as Array<UTSJSONObject>,
+      selectedPages: [] as Array<UTSJSONObject>[],
+      selectedValue: '',
+      selectedPaths: [] as Array<UTSJSONObject>,
+      pagination: {
+        current: 1,
+        size: 20,
+        count: 0
+      } as PaginationType
+    }
+  },
+  computed: {
+    mappingTextName() : string {
+      // TODO
+      return (this.defaultProps != null) ? this.defaultProps!.getString('text', 'text') : 'text'
+    },
+    mappingValueName() : string {
+      // TODO
+      return (this.defaultProps != null) ? this.defaultProps!.getString('value', 'value') : 'value'
+    },
+    currentDataList() : Array<UTSJSONObject> {
+      if (this.selectedIndex > this.selectedPages.length - 1) {
+        return [] as Array<UTSJSONObject>
+      }
+      return this.selectedPages[this.selectedIndex]
+    },
+    isLocalData() : boolean {
+      return this.localdata.length > 0
+    },
+    isCloudData() : boolean {
+      return this._checkIsNotNull(this.collection)
+    },
+    isCloudDataList() : boolean {
+      return (this.isCloudData && (this.parentField.length == 0 && this.selfField.length == 0))
+    },
+    isCloudDataTree() : boolean {
+      return (this.isCloudData && this.parentField.length > 0 && this.selfField.length > 0)
+    },
+    dataValue() : any {
+      return this.hasModelValue ? this.modelValue : this.value
+    },
+    hasCloudTreeData() : boolean {
+      return this.treeData.length > 0
+    },
+    hasModelValue() : boolean {
+      if (typeof this.modelValue == 'string') {
+        const valueString = this.modelValue as string
+        return (valueString.length > 0)
+      } else if (Array.isArray(this.modelValue)) {
+        const valueArray = this.modelValue as Array<string>
+        return (valueArray.length > 0)
+      }
+      return false
+    },
+    hasCloudDataValue() : boolean {
+      if (typeof this.dataValue == 'string') {
+        const valueString = this.dataValue as string
+        return (valueString.length > 0)
+      }
+      return false
+    }
+  },
+  created() {
+    this.pagination.current = this.pageCurrent
+    this.pagination.size = this.pageSize
+
+    this.$watch(
+      () : any => [
+        this.pageCurrent,
+        this.pageSize,
+        this.localdata,
+        this.value,
+        this.collection,
+        this.field,
+        this.getcount,
+        this.orderby,
+        this.where,
+        this.groupby,
+        this.groupField,
+        this.distinct
+      ],
+      (newValue : Array<any>, oldValue : Array<any>) => {
+        this.pagination.size = this.pageSize
+        if (newValue[0] !== oldValue[0]) {
+          this.pagination.current = this.pageCurrent
+        }
+
+        this.onPropsChange()
+      }
+    )
+  },
+  methods: {
+    onPropsChange() {
+      this.selectedIndex = 0
+      this.selectedNodes.length = 0
+      this.selectedPages.length = 0
+      this.selectedPaths.length = 0
+
+      // 加载数据
+      this.$nextTick(() => {
+        this.loadData()
+      })
+    },
+
+    onTabSelect(index : number) {
+      this.selectedIndex = index
+    },
+
+    onNodeClick(nodeData : UTSJSONObject) {
+      if (nodeData.getBoolean('disable', false)) {
+        return
+      }
+
+      const isLeaf = this._checkIsLeafNode(nodeData)
+
+      this._trimSelectedNodes(nodeData)
+
+      this.$emit('nodeclick', nodeData)
+
+      if (this.isLocalData) {
+        if (isLeaf || !this._checkHasChildren(nodeData)) {
+          this.onFinish()
+        }
+      } else if (this.isCloudDataList) {
+        this.onFinish()
+      } else if (this.isCloudDataTree) {
+        if (isLeaf) {
+          this.onFinish()
+        } else if (!this._checkHasChildren(nodeData)) {
+          // 尝试请求一次,如果没有返回数据标记为叶子节点
+          this.loadCloudDataNode(nodeData)
+        }
+      }
+    },
+
+    getChangeNodes(): Array<UTSJSONObject> {
+      const nodes: Array<UTSJSONObject> = []
+      this.selectedNodes.forEach((node : UTSJSONObject) => {
+        const newNode: UTSJSONObject = {}
+        newNode[this.mappingTextName] = node.getString(this.mappingTextName)
+        newNode[this.mappingValueName] = node.getString(this.mappingValueName)
+        nodes.push(newNode)
+      })
+      return nodes
+    },
+
+    onFinish() { },
+
+    // 加载数据(自动判定环境)
+    loadData() {
+      if (this.isLocalData) {
+        this.loadLocalData()
+      } else if (this.isCloudDataList) {
+        this.loadCloudDataList()
+      } else if (this.isCloudDataTree) {
+        this.loadCloudDataTree()
+      }
+    },
+
+    // 加载本地数据
+    loadLocalData() {
+      this.treeData = this.localdata
+      if (Array.isArray(this.dataValue)) {
+        const value = this.dataValue as Array<UTSJSONObject>
+        this.selectedPaths = value.slice(0)
+        this._pushSelectedTreeNodes(value, this.localdata)
+      } else {
+        this._pushSelectedNodes(this.localdata)
+      }
+    },
+
+    // 加载 Cloud 数据 (单列)
+    loadCloudDataList() {
+      this._loadCloudData(null, (data : Array<UTSJSONObject>) => {
+        this.treeData = data
+        this._pushSelectedNodes(data)
+      })
+    },
+
+    // 加载 Cloud 数据 (树形)
+    loadCloudDataTree() {
+      let commandOptions = {
+        field: this._cloudDataPostField(),
+        where: this._cloudDataTreeWhere(),
+        getTree: true
+      } as GetCommandOptions
+      if (this._checkIsNotNull(this.gettree)) {
+        commandOptions.startwith = `${this.selfField}=='${this.dataValue as string}'`
+      }
+      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
+        this.treeData = data
+        if (this.selectedPaths.length > 0) {
+          this._pushSelectedTreeNodes(this.selectedPaths, data)
+        } else {
+          this._pushSelectedNodes(data)
+        }
+      })
+    },
+
+    // 加载 Cloud 数据 (节点)
+    loadCloudDataNode(nodeData : UTSJSONObject) {
+      const commandOptions = {
+        field: this._cloudDataPostField(),
+        where: this._cloudDataNodeWhere()
+      } as GetCommandOptions
+      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
+        nodeData['children'] = data
+        if (data.length == 0) {
+          nodeData['isleaf'] = true
+          this.onFinish()
+        } else {
+          this._pushSelectedNodes(data)
+        }
+      })
+    },
+
+    // 回显 Cloud Tree Path
+    loadCloudDataPath() {
+      if (!this.hasCloudDataValue) {
+        return
+      }
+
+      const command : GetCommandOptions = {}
+
+      // 单列
+      if (this.isCloudDataList) {
+        // 根据 field's as value标识匹配 where 条件
+        let where : Array<string> = [];
+        let whereField = this._getForeignKeyByField();
+        if (whereField.length > 0) {
+          where.push(`${whereField} == '${this.dataValue as string}'`)
+        }
+
+        let whereString = where.join(' || ')
+        if (this._checkIsNotNull(this.where)) {
+          whereString = `(${this.where}) && (${whereString})`
+        }
+
+        command.field = this._cloudDataPostField()
+        command.where = whereString
+      }
+
+      // 树形
+      if (this.isCloudDataTree) {
+        command.field = this._cloudDataPostField()
+        command.getTreePath = {
+          startWith: `${this.selfField}=='${this.dataValue as string}'`
+        }
+      }
+
+      this._loadCloudData(command, (data : Array<UTSJSONObject>) => {
+        this._extractTreePath(data, this.selectedPaths)
+      })
+    },
+
+    _loadCloudData(options ?: GetCommandOptions, callback ?: ((data : Array<UTSJSONObject>) => void)) {
+      if (this.loading) {
+        return
+      }
+      this.loading = true
+
+      this.error = null
+
+      this._getCommand(options).then((response : UniCloudDBGetResult) => {
+        callback?.(response.data)
+      }).catch((err : any | null) => {
+        this.error = err as UniCloudError
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+
+    _cloudDataPostField() : string {
+      let fields = [this.field];
+      if (this.parentField.length > 0) {
+        fields.push(`${this.parentField} as parent_value`)
+      }
+      return fields.join(',')
+    },
+
+    _cloudDataTreeWhere() : string {
+      let result : Array<string> = []
+      let selectedNodes = this.selectedNodes.length > 0 ? this.selectedNodes : this.selectedPaths
+      let parentField = this.parentField
+      if (parentField.length > 0) {
+        result.push(`${parentField} == null || ${parentField} == ""`)
+      }
+      if (selectedNodes.length > 0) {
+        for (var i = 0; i < selectedNodes.length - 1; i++) {
+          const parentFieldValue = selectedNodes[i].getString('value', '')
+          result.push(`${parentField} == '${parentFieldValue}'`)
+        }
+      }
+
+      let where : Array<string> = []
+      if (this._checkIsNotNull(this.where)) {
+        where.push(`(${this.where as string})`)
+      }
+
+      if (result.length > 0) {
+        where.push(`(${result.join(' || ')})`)
+      }
+
+      return where.join(' && ')
+    },
+
+    _cloudDataNodeWhere() : string {
+      const where : Array<string> = []
+      if (this.selectedNodes.length > 0) {
+        const value = this.selectedNodes[this.selectedNodes.length - 1].getString('value', '')
+        where.push(`${this.parentField} == '${value}'`)
+      }
+
+      let whereString = where.join(' || ')
+      if (this._checkIsNotNull(this.where)) {
+        return `(${this.where as string}) && (${whereString})`
+      }
+
+      return whereString
+    },
+
+    _getWhereByForeignKey() : string {
+      let result : Array<string> = []
+      let whereField = this._getForeignKeyByField();
+      if (whereField.length > 0) {
+        result.push(`${whereField} == '${this.dataValue as string}'`)
+      }
+
+      if (this._checkIsNotNull(this.where)) {
+        return `(${this.where}) && (${result.join(' || ')})`
+      }
+
+      return result.join(' || ')
+    },
+
+    _getForeignKeyByField() : string {
+      const fields = this.field.split(',')
+      let whereField = ''
+      for (let i = 0; i < fields.length; i++) {
+        const items = fields[i].split('as')
+        if (items.length < 2) {
+          continue
+        }
+        if (items[1].trim() === 'value') {
+          whereField = items[0].trim()
+          break
+        }
+      }
+      return whereField
+    },
+
+    _getCommand(options ?: GetCommandOptions) : Promise<UniCloudDBGetResult> {
+      let db = uniCloud.databaseForJQL()
+
+      let collection = Array.isArray(this.collection) ? db.collection(...(this.collection as Array<any>)) : db.collection(this.collection)
+
+      let filter : UniCloudDBFilter | null = null
+      if (this.foreignKey.length > 0) {
+        filter = collection.foreignKey(this.foreignKey)
+      }
+
+      const where : any = options?.where ?? this.where
+      if (typeof where == 'string') {
+        const whereString = where as string
+        if (whereString.length > 0) {
+          filter = (filter != null) ? filter.where(where) : collection.where(where)
+        }
+      } else {
+        filter = (filter != null) ? filter.where(where) : collection.where(where)
+      }
+
+      let query : UniCloudDBQuery | null = null
+      if (this.field.length > 0) {
+        query = (filter != null) ? filter.field(this.field) : collection.field(this.field)
+      }
+      if (this.groupby.length > 0) {
+        if (query != null) {
+          query = query.groupBy(this.groupby)
+        } else if (filter != null) {
+          query = filter.groupBy(this.groupby)
+        }
+      }
+      if (this.groupField.length > 0) {
+        if (query != null) {
+          query = query.groupField(this.groupField)
+        } else if (filter != null) {
+          query = filter.groupField(this.groupField)
+        }
+      }
+      if (this.distinct == true) {
+        if (query != null) {
+          query = query.distinct(this.field)
+        } else if (filter != null) {
+          query = filter.distinct(this.field)
+        }
+      }
+      if (this.orderby.length > 0) {
+        if (query != null) {
+          query = query.orderBy(this.orderby)
+        } else if (filter != null) {
+          query = filter.orderBy(this.orderby)
+        }
+      }
+
+      const size = this.pagination.size
+      const current = this.pagination.current
+      if (query != null) {
+        query = query.skip(size * (current - 1)).limit(size)
+      } else if (filter != null) {
+        query = filter.skip(size * (current - 1)).limit(size)
+      } else {
+        query = collection.skip(size * (current - 1)).limit(size)
+      }
+
+      const getOptions = {}
+      const treeOptions = {
+        limitLevel: this.limitlevel,
+        startWith: this.startwith
+      }
+      if (this.getcount == true) {
+        getOptions['getCount'] = this.getcount
+      }
+
+      const getTree : any = options?.getTree ?? this.gettree
+      if (typeof getTree == 'string') {
+        const getTreeString = getTree as string
+        if (getTreeString.length > 0) {
+          getOptions['getTree'] = treeOptions
+        }
+      } else if (typeof getTree == 'object') {
+        getOptions['getTree'] = treeOptions
+      } else {
+        getOptions['getTree'] = getTree
+      }
+
+      const getTreePath = options?.getTreePath ?? this.gettreepath
+      if (typeof getTreePath == 'string') {
+        const getTreePathString = getTreePath as string
+        if (getTreePathString.length > 0) {
+          getOptions['getTreePath'] = getTreePath
+        }
+      } else {
+        getOptions['getTreePath'] = getTreePath
+      }
+
+      return query.get(getOptions)
+    },
+
+    _checkIsNotNull(value : any) : boolean {
+      if (typeof value == 'string') {
+        const valueString = value as string
+        return (valueString.length > 0)
+      } else if (value instanceof UTSJSONObject) {
+        return true
+      }
+      return false
+    },
+
+    _checkIsLeafNode(nodeData : UTSJSONObject) : boolean {
+      if (this.selectedIndex >= this.limitlevel) {
+        return true
+      }
+
+      if (nodeData.getBoolean('isleaf', false)) {
+        return true
+      }
+
+      return false
+    },
+
+    _checkHasChildren(nodeData : UTSJSONObject) : boolean {
+      const children = nodeData.getArray('children') ?? ([] as Array<any>)
+      return children.length > 0
+    },
+
+    _pushSelectedNodes(nodes : Array<UTSJSONObject>) {
+      this.selectedNodes.push(DefaultSelectedNode)
+      this.selectedPages.push(nodes)
+      this.selectedIndex = this.selectedPages.length - 1
+    },
+
+    _trimSelectedNodes(nodeData : UTSJSONObject) {
+      this.selectedNodes.splice(this.selectedIndex)
+      this.selectedNodes.push(nodeData)
+
+      if (this.selectedPages.length > 0) {
+        this.selectedPages.splice(this.selectedIndex + 1)
+      }
+
+      const children = nodeData.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
+      if (children.length > 0) {
+        this.selectedNodes.push(DefaultSelectedNode)
+        this.selectedPages.push(children)
+      }
+
+      this.selectedIndex = this.selectedPages.length - 1
+    },
+
+    _pushSelectedTreeNodes(paths : Array<UTSJSONObject>, nodes : Array<UTSJSONObject>) {
+      let children : Array<UTSJSONObject> = nodes
+      paths.forEach((node : UTSJSONObject) => {
+        const findNode = children.find((item : UTSJSONObject) : boolean => {
+          return (item.getString(this.mappingValueName) == node.getString(this.mappingValueName))
+        })
+        if (findNode != null) {
+          this.selectedPages.push(children)
+          this.selectedNodes.push(node)
+          children = findNode.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
+        }
+      })
+      this.selectedIndex = this.selectedPages.length - 1
+    },
+
+    _extractTreePath(nodes : Array<UTSJSONObject>, result : Array<UTSJSONObject>) {
+      if (nodes.length == 0) {
+        return
+      }
+
+      const node = nodes[0]
+      result.push(node)
+
+      const children = node.getArray<UTSJSONObject>('children')
+      if (Array.isArray(children) && children!.length > 0) {
+        this._extractTreePath(children, result)
+      }
+    }
+  }
+})
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
new file mode 100644
index 0000000..39fe1c3
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
@@ -0,0 +1,76 @@
+.uni-data-pickerview {
+  position: relative;
+  flex-direction: column;
+  overflow: hidden;
+}
+
+.loading-cover {
+  position: absolute;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(150, 150, 150, .1);
+}
+
+.error {
+  background-color: #fff;
+  padding: 15px;
+}
+
+.error-text {
+  color: #DD524D;
+}
+
+.selected-node-list {
+  flex-direction: row;
+  flex-wrap: nowrap;
+}
+
+.selected-node-item {
+  margin-left: 10px;
+  margin-right: 10px;
+  padding: 8px 10px 8px 10px;
+  border-bottom: 2px solid transparent;
+}
+
+.selected-node-item-active {
+  color: #007aff;
+  border-bottom-color: #007aff;
+}
+
+.list-view {
+  flex: 1;
+}
+
+.list-item {
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 12px 15px;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.item-text {
+  color: #333333;
+}
+
+.item-text-disabled {
+  opacity: .5;
+}
+
+.item-text-overflow {
+  overflow: hidden;
+}
+
+.check {
+  margin-right: 5px;
+  border: 2px solid #007aff;
+  border-left: 0;
+  border-top: 0;
+  height: 12px;
+  width: 6px;
+  transform-origin: center;
+  transform: rotate(45deg);
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
new file mode 100644
index 0000000..f4780f3
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
@@ -0,0 +1,69 @@
+<template>
+  <view class="uni-data-pickerview">
+    <view v-if="error!=null" class="error">
+      <text class="error-text">{{error!.errMsg}}</text>
+    </view>
+    <scroll-view v-if="!isCloudDataList" :scroll-x="true">
+      <view class="selected-node-list">
+        <template v-for="(item, index) in selectedNodes">
+          <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
+            @click="onTabSelect(index)">
+            {{item[mappingTextName]}}
+          </text>
+        </template>
+      </view>
+    </scroll-view>
+    <list-view class="list-view" :scroll-y="true">
+      <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
+        <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
+        <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
+      </list-item>
+    </list-view>
+    <view class="loading-cover" v-if="loading">
+      <slot name="pickerview-loading" :loading="loading"></slot>
+    </view>
+  </view>
+</template>
+
+<script>
+  import { dataPicker } from "./uni-data-picker.uts"
+
+  /**
+   * DataPickerview
+   * @description uni-data-pickerview
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {Array} localdata 本地数据,参考
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询,仅查询当前选中节点
+   * @value false 关闭分布查询,一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   */
+  export default {
+    name: 'UniDataPickerView',
+    emits: ['nodeclick', 'change', 'update:modelValue'],
+    mixins: [dataPicker],
+    props: {
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    created() {
+      this.loadData()
+    },
+    methods: {
+      onFinish() {
+        this.$emit('change', this.getChangeNodes())
+      }
+    }
+  }
+</script>
+
+<style>
+  @import url("uni-data-pickerview.css");
+</style>
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
new file mode 100644
index 0000000..6ebced9
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
@@ -0,0 +1,323 @@
+<template>
+  <view class="uni-data-pickerview">
+    <scroll-view v-if="!isCloudDataList" class="selected-area" scroll-x="true">
+      <view class="selected-list">
+          <view 
+            class="selected-item"
+            v-for="(item,index) in selected"
+            :key="index"
+            :class="{
+              'selected-item-active':index == selectedIndex
+            }"
+            @click="handleSelect(index)"
+          >
+            <text>{{item.text || ''}}</text>
+          </view>
+      </view>
+    </scroll-view>
+    <view class="tab-c">
+      <scroll-view class="list" :scroll-y="true">
+        <view class="item" :class="{'is-disabled': !!item.disable}" v-for="(item, j) in dataList[selectedIndex]" :key="j"
+          @click="handleNodeClick(item, selectedIndex, j)">
+          <text class="item-text">{{item[map.text]}}</text>
+          <view class="check" v-if="selected.length > selectedIndex && item[map.value] == selected[selectedIndex].value"></view>
+        </view>
+      </scroll-view>
+
+      <view class="loading-cover" v-if="loading">
+        <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
+      </view>
+      <view class="error-message" v-if="errorMessage">
+        <text class="error-text">{{errorMessage}}</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import dataPicker from "./uni-data-picker.js"
+
+  /**
+   * DataPickerview
+   * @description uni-data-pickerview
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
+   * @property {Array} localdata 本地数据,参考
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
+   * @value true 启用分布查询,仅查询当前选中节点
+   * @value false 关闭分布查询,一次查询出所有数据
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
+   * @property {String|DBCollectionString} collection 表名
+   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
+   * @property {String} orderby 排序字段及正序倒叙设置
+   * @property {String|JQLString} where 查询条件
+   */
+  export default {
+    name: 'UniDataPickerView',
+    emits: ['nodeclick', 'change', 'datachange', 'update:modelValue'],
+    mixins: [dataPicker],
+    props: {
+      managedMode: {
+        type: Boolean,
+        default: false
+      },
+      ellipsis: {
+        type: Boolean,
+        default: true
+      }
+    },
+    created() {
+      if (!this.managedMode) {
+        this.$nextTick(() => {
+          this.loadData();
+        })
+      }
+    },
+    methods: {
+      onPropsChange() {
+        this._treeData = [];
+        this.selectedIndex = 0;
+        this.$nextTick(() => {
+          this.loadData();
+        })
+      },
+      handleSelect(index) {
+        this.selectedIndex = index;
+      },
+      handleNodeClick(item, i, j) {
+        if (item.disable) {
+          return;
+        }
+
+        const node = this.dataList[i][j];
+        const text = node[this.map.text];
+        const value = node[this.map.value];
+
+        if (i < this.selected.length - 1) {
+          this.selected.splice(i, this.selected.length - i)
+          this.selected.push({
+            text,
+            value
+          })
+        } else if (i === this.selected.length - 1) {
+          this.selected.splice(i, 1, {
+            text,
+            value
+          })
+        }
+
+        if (node.isleaf) {
+          this.onSelectedChange(node, node.isleaf)
+          return
+        }
+
+        const {
+          isleaf,
+          hasNodes
+        } = this._updateBindData()
+
+        // 本地数据
+        if (this.isLocalData) {
+          this.onSelectedChange(node, (!hasNodes || isleaf))
+        } else if (this.isCloudDataList) { // Cloud 数据 (单列)
+          this.onSelectedChange(node, true)
+        } else if (this.isCloudDataTree) { // Cloud 数据 (树形)
+          if (isleaf) {
+            this.onSelectedChange(node, node.isleaf)
+          } else if (!hasNodes) { // 请求一次服务器以确定是否为叶子节点
+            this.loadCloudDataNode((data) => {
+              if (!data.length) {
+                node.isleaf = true
+              } else {
+                this._treeData.push(...data)
+                this._updateBindData(node)
+              }
+              this.onSelectedChange(node, node.isleaf)
+            })
+          }
+        }
+      },
+      updateData(data) {
+        this._treeData = data.treeData
+        this.selected = data.selected
+        if (!this._treeData.length) {
+          this.loadData()
+        } else {
+          //this.selected = data.selected
+          this._updateBindData()
+        }
+      },
+      onDataChange() {
+        this.$emit('datachange');
+      },
+      onSelectedChange(node, isleaf) {
+        if (isleaf) {
+          this._dispatchEvent()
+        }
+
+        if (node) {
+          this.$emit('nodeclick', node)
+        }
+      },
+      _dispatchEvent() {
+        this.$emit('change', this.selected.slice(0))
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+	$uni-primary: #007aff !default;
+
+	.uni-data-pickerview {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		overflow: hidden;
+		height: 100%;
+	}
+
+  .error-text {
+    color: #DD524D;
+  }
+
+  .loading-cover {
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(255, 255, 255, .5);
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    align-items: center;
+    z-index: 1001;
+  }
+
+  .load-more {
+    /* #ifndef APP-NVUE */
+    margin: auto;
+    /* #endif */
+  }
+
+  .error-message {
+    background-color: #fff;
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    padding: 15px;
+    opacity: .9;
+    z-index: 102;
+  }
+
+  /* #ifdef APP-NVUE */
+  .selected-area {
+    width: 750rpx;
+  }
+  /* #endif */
+
+  .selected-list {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    flex-wrap: nowrap;
+    /* #endif */
+    flex-direction: row;
+    padding: 0 5px;
+    border-bottom: 1px solid #f8f8f8;
+  }
+
+  .selected-item {
+    margin-left: 10px;
+    margin-right: 10px;
+    padding: 12px 0;
+    text-align: center;
+    /* #ifndef APP-NVUE */
+    white-space: nowrap;
+    /* #endif */
+  }
+
+  .selected-item-text-overflow {
+    width: 168px;
+    /* fix nvue */
+    overflow: hidden;
+    /* #ifndef APP-NVUE */
+    width: 6em;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    /* #endif */
+  }
+
+	.selected-item-active {
+		border-bottom: 2px solid $uni-primary;
+	}
+
+	.selected-item-text {
+		color: $uni-primary;
+	}
+
+  .tab-c {
+    position: relative;
+    flex: 1;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    overflow: hidden;
+  }
+
+  .list {
+    flex: 1;
+  }
+
+  .item {
+    padding: 12px 15px;
+    /* border-bottom: 1px solid #f0f0f0; */
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: row;
+    justify-content: space-between;
+  }
+
+  .is-disabled {
+    opacity: .5;
+  }
+
+  .item-text {
+    /* flex: 1; */
+    color: #333333;
+  }
+
+  .item-text-overflow {
+    width: 280px;
+    /* fix nvue */
+    overflow: hidden;
+    /* #ifndef APP-NVUE */
+    width: 20em;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    /* #endif */
+  }
+
+	.check {
+		margin-right: 5px;
+		border: 2px solid $uni-primary;
+		border-left: 0;
+		border-top: 0;
+		height: 12px;
+		width: 6px;
+		transform-origin: center;
+		/* #ifndef APP-NVUE */
+		transition: all 0.3s;
+		/* #endif */
+		transform: rotate(45deg);
+	}
+</style>
diff --git a/uni_modules/uni-data-picker/package.json b/uni_modules/uni-data-picker/package.json
new file mode 100644
index 0000000..efc60c2
--- /dev/null
+++ b/uni_modules/uni-data-picker/package.json
@@ -0,0 +1,91 @@
+{
+  "id": "uni-data-picker",
+  "displayName": "uni-data-picker 数据驱动的picker选择器",
+  "version": "2.0.1",
+  "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "picker",
+    "级联",
+    "省市区",
+    ""
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+      "uni-load-more",
+			"uni-icons",
+			"uni-scss"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+        "QQ": "y",
+        "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-data-picker/readme.md b/uni_modules/uni-data-picker/readme.md
new file mode 100644
index 0000000..19dd0e8
--- /dev/null
+++ b/uni_modules/uni-data-picker/readme.md
@@ -0,0 +1,22 @@
+## DataPicker 级联选择
+> **组件名:uni-data-picker**
+> 代码块: `uDataPicker`
+> 关联组件:`uni-data-pickerview`、`uni-load-more`。
+
+
+`<uni-data-picker>` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
+
+支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
+
+候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。
+
+`<uni-data-picker>` 组件尤其适用于地址选择、分类选择等选择类。
+
+`<uni-data-picker>` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。
+
+`<uni-data-picker>` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。
+
+在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-data-select/changelog.md b/uni_modules/uni-data-select/changelog.md
new file mode 100644
index 0000000..016e3d2
--- /dev/null
+++ b/uni_modules/uni-data-select/changelog.md
@@ -0,0 +1,39 @@
+## 1.0.8(2024-03-28)
+- 修复 在vue2下:style动态绑定导致编译失败的bug
+## 1.0.7(2024-01-20)
+- 修复 长文本回显超过容器的bug,超过容器部分显示省略号
+## 1.0.6(2023-04-12)
+- 修复 微信小程序点击时会改变背景颜色的 bug
+## 1.0.5(2023-02-03)
+- 修复 禁用时会显示清空按钮
+## 1.0.4(2023-02-02)
+- 优化 查询条件短期内多次变更只查询最后一次变更后的结果
+- 调整 内部缓存键名调整为 uni-data-select-lastSelectedValue
+## 1.0.3(2023-01-16)
+- 修复 不关联服务空间报错的问题
+## 1.0.2(2023-01-14)
+- 新增  属性 `format` 可用于格式化显示选项内容
+## 1.0.1(2022-12-06)
+- 修复  当where变化时,数据不会自动更新的问题
+## 0.1.9(2022-09-05)
+- 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框
+## 0.1.8(2022-08-29)
+- 修复 点击的位置不准确
+## 0.1.7(2022-08-12)
+- 新增 支持 disabled 属性
+## 0.1.6(2022-07-06)
+- 修复 pc端宽度异常的bug
+## 0.1.5
+- 修复 pc端宽度异常的bug
+## 0.1.4(2022-07-05)
+- 优化 显示样式
+## 0.1.3(2022-06-02)
+- 修复 localdata 赋值不生效的 bug
+- 新增 支持  uni.scss 修改颜色
+- 新增 支持选项禁用(数据选项设置 disabled: true 即禁用)
+## 0.1.2(2022-05-08)
+- 修复 当 value 为 0 时选择不生效的 bug
+## 0.1.1(2022-05-07)
+- 新增 记住上次的选项(仅 collection 存在时有效)
+## 0.1.0(2022-04-22)
+- 初始化
diff --git a/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue b/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue
new file mode 100644
index 0000000..edab65a
--- /dev/null
+++ b/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue
@@ -0,0 +1,562 @@
+<template>
+	<view class="uni-stat__select">
+		<span v-if="label" class="uni-label-text hide-on-phone">{{label + ':'}}</span>
+		<view class="uni-stat-box" :class="{'uni-stat__actived': current}">
+			<view class="uni-select" :class="{'uni-select--disabled':disabled}">
+				<view class="uni-select__input-box" @click="toggleSelector">
+					<view v-if="current" class="uni-select__input-text">{{textShow}}</view>
+					<view v-else class="uni-select__input-text uni-select__input-placeholder">{{typePlaceholder}}</view>
+					<view v-if="current && clear && !disabled" @click.stop="clearVal">
+						<uni-icons type="clear" color="#c0c4cc" size="24" />
+					</view>
+					<view v-else>
+						<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" />
+					</view>
+				</view>
+				<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
+				<view class="uni-select__selector" :style="getOffsetByPlacement" v-if="showSelector">
+					<view :class="placement=='bottom'?'uni-popper__arrow_bottom':'uni-popper__arrow_top'"></view>
+					<scroll-view scroll-y="true" class="uni-select__selector-scroll">
+						<view class="uni-select__selector-empty" v-if="mixinDatacomResData.length === 0">
+							<text>{{emptyTips}}</text>
+						</view>
+						<view v-else class="uni-select__selector-item" v-for="(item,index) in mixinDatacomResData" :key="index"
+							@click="change(item)">
+							<text :class="{'uni-select__selector__disabled': item.disable}">{{formatItemName(item)}}</text>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * DataChecklist 数据选择器
+	 * @description 通过数据渲染的下拉框组件
+	 * @tutorial https://uniapp.dcloud.io/component/uniui/uni-data-select
+	 * @property {String} value 默认值
+	 * @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
+	 * @property {Boolean} clear 是否可以清空已选项
+	 * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
+	 * @property {String} label 左侧标题
+	 * @property {String} placeholder 输入框的提示文字
+	 * @property {Boolean} disabled 是否禁用
+	 * @property {String} placement 弹出位置
+	 * 	@value top   		顶部弹出
+	 * 	@value bottom		底部弹出(default)
+	 * @event {Function} change  选中发生变化触发
+	 */
+
+	export default {
+		name: "uni-data-select",
+		mixins: [uniCloud.mixinDatacom || {}],
+		props: {
+			localdata: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			modelValue: {
+				type: [String, Number],
+				default: ''
+			},
+			label: {
+				type: String,
+				default: ''
+			},
+			placeholder: {
+				type: String,
+				default: '请选择'
+			},
+			emptyTips: {
+				type: String,
+				default: '无选项'
+			},
+			clear: {
+				type: Boolean,
+				default: true
+			},
+			defItem: {
+				type: Number,
+				default: 0
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			// 格式化输出 用法 field="_id as value, version as text, uni_platform as label" format="{label} - {text}"
+			format: {
+				type: String,
+				default: ''
+			},
+			placement: {
+				type: String,
+				default: 'bottom'
+			}
+		},
+		data() {
+			return {
+				showSelector: false,
+				current: '',
+				mixinDatacomResData: [],
+				apps: [],
+				channels: [],
+				cacheKey: "uni-data-select-lastSelectedValue",
+			};
+		},
+		created() {
+			this.debounceGet = this.debounce(() => {
+				this.query();
+			}, 300);
+			if (this.collection && !this.localdata.length) {
+				this.debounceGet();
+			}
+		},
+		computed: {
+			typePlaceholder() {
+				const text = {
+					'opendb-stat-app-versions': '版本',
+					'opendb-app-channels': '渠道',
+					'opendb-app-list': '应用'
+				}
+				const common = this.placeholder
+				const placeholder = text[this.collection]
+				return placeholder ?
+					common + placeholder :
+					common
+			},
+			valueCom() {
+				// #ifdef VUE3
+				return this.modelValue;
+				// #endif
+				// #ifndef VUE3
+				return this.value;
+				// #endif
+			},
+			textShow() {
+				// 长文本显示
+				let text = this.current;
+				if (text.length > 10) {
+					return text.slice(0, 25) + '...';
+				}
+				return text;
+			},
+			getOffsetByPlacement() {
+				switch (this.placement) {
+					case 'top':
+						return "bottom:calc(100% + 12px);";
+					case 'bottom':
+						return "top:calc(100% + 12px);";
+				}
+			}
+		},
+
+		watch: {
+			localdata: {
+				immediate: true,
+				handler(val, old) {
+					if (Array.isArray(val) && old !== val) {
+						this.mixinDatacomResData = val
+					}
+				}
+			},
+			valueCom(val, old) {
+				this.initDefVal()
+			},
+			mixinDatacomResData: {
+				immediate: true,
+				handler(val) {
+					if (val.length) {
+						this.initDefVal()
+					}
+				}
+			},
+
+		},
+		methods: {
+			debounce(fn, time = 100) {
+				let timer = null
+				return function(...args) {
+					if (timer) clearTimeout(timer)
+					timer = setTimeout(() => {
+						fn.apply(this, args)
+					}, time)
+				}
+			},
+			// 执行数据库查询
+			query() {
+				this.mixinDatacomEasyGet();
+			},
+			// 监听查询条件变更事件
+			onMixinDatacomPropsChange() {
+				if (this.collection) {
+					this.debounceGet();
+				}
+			},
+			initDefVal() {
+				let defValue = ''
+				if ((this.valueCom || this.valueCom === 0) && !this.isDisabled(this.valueCom)) {
+					defValue = this.valueCom
+				} else {
+					let strogeValue
+					if (this.collection) {
+						strogeValue = this.getCache()
+					}
+					if (strogeValue || strogeValue === 0) {
+						defValue = strogeValue
+					} else {
+						let defItem = ''
+						if (this.defItem > 0 && this.defItem <= this.mixinDatacomResData.length) {
+							defItem = this.mixinDatacomResData[this.defItem - 1].value
+						}
+						defValue = defItem
+					}
+					if (defValue || defValue === 0) {
+						this.emit(defValue)
+					}
+				}
+				const def = this.mixinDatacomResData.find(item => item.value === defValue)
+				this.current = def ? this.formatItemName(def) : ''
+			},
+
+			/**
+			 * @param {[String, Number]} value
+			 * 判断用户给的 value 是否同时为禁用状态
+			 */
+			isDisabled(value) {
+				let isDisabled = false;
+
+				this.mixinDatacomResData.forEach(item => {
+					if (item.value === value) {
+						isDisabled = item.disable
+					}
+				})
+
+				return isDisabled;
+			},
+
+			clearVal() {
+				this.emit('')
+				if (this.collection) {
+					this.removeCache()
+				}
+			},
+			change(item) {
+				if (!item.disable) {
+					this.showSelector = false
+					this.current = this.formatItemName(item)
+					this.emit(item.value)
+				}
+			},
+			emit(val) {
+				this.$emit('input', val)
+				this.$emit('update:modelValue', val)
+				this.$emit('change', val)
+				if (this.collection) {
+					this.setCache(val);
+				}
+			},
+			toggleSelector() {
+				if (this.disabled) {
+					return
+				}
+
+				this.showSelector = !this.showSelector
+			},
+			formatItemName(item) {
+				let {
+					text,
+					value,
+					channel_code
+				} = item
+				channel_code = channel_code ? `(${channel_code})` : ''
+
+				if (this.format) {
+					// 格式化输出
+					let str = "";
+					str = this.format;
+					for (let key in item) {
+						str = str.replace(new RegExp(`{${key}}`, "g"), item[key]);
+					}
+					return str;
+				} else {
+					return this.collection.indexOf('app-list') > 0 ?
+						`${text}(${value})` :
+						(
+							text ?
+							text :
+							`未命名${channel_code}`
+						)
+				}
+			},
+			// 获取当前加载的数据
+			getLoadData() {
+				return this.mixinDatacomResData;
+			},
+			// 获取当前缓存key
+			getCurrentCacheKey() {
+				return this.collection;
+			},
+			// 获取缓存
+			getCache(name = this.getCurrentCacheKey()) {
+				let cacheData = uni.getStorageSync(this.cacheKey) || {};
+				return cacheData[name];
+			},
+			// 设置缓存
+			setCache(value, name = this.getCurrentCacheKey()) {
+				let cacheData = uni.getStorageSync(this.cacheKey) || {};
+				cacheData[name] = value;
+				uni.setStorageSync(this.cacheKey, cacheData);
+			},
+			// 删除缓存
+			removeCache(name = this.getCurrentCacheKey()) {
+				let cacheData = uni.getStorageSync(this.cacheKey) || {};
+				delete cacheData[name];
+				uni.setStorageSync(this.cacheKey, cacheData);
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-base-color: #6a6a6a !default;
+	$uni-main-color: #333 !default;
+	$uni-secondary-color: #909399 !default;
+	$uni-border-3: #e5e5e5;
+
+	/* #ifndef APP-NVUE */
+	@media screen and (max-width: 500px) {
+		.hide-on-phone {
+			display: none;
+		}
+	}
+
+	/* #endif */
+	.uni-stat__select {
+		display: flex;
+		align-items: center;
+		// padding: 15px;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+		width: 100%;
+		flex: 1;
+		box-sizing: border-box;
+	}
+
+	.uni-stat-box {
+		width: 100%;
+		flex: 1;
+	}
+
+	.uni-stat__actived {
+		width: 100%;
+		flex: 1;
+		// outline: 1px solid #2979ff;
+	}
+
+	.uni-label-text {
+		font-size: 14px;
+		font-weight: bold;
+		color: $uni-base-color;
+		margin: auto 0;
+		margin-right: 5px;
+	}
+
+	.uni-select {
+		font-size: 14px;
+		border: 1px solid $uni-border-3;
+		box-sizing: border-box;
+		border-radius: 4px;
+		padding: 0 5px;
+		padding-left: 10px;
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		user-select: none;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		border-bottom: solid 1px $uni-border-3;
+		width: 100%;
+		flex: 1;
+		height: 35px;
+
+		&--disabled {
+			background-color: #f5f7fa;
+			cursor: not-allowed;
+		}
+	}
+
+	.uni-select__label {
+		font-size: 16px;
+		// line-height: 22px;
+		height: 35px;
+		padding-right: 10px;
+		color: $uni-secondary-color;
+	}
+
+	.uni-select__input-box {
+		height: 35px;
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		align-items: center;
+	}
+
+	.uni-select__input {
+		flex: 1;
+		font-size: 14px;
+		height: 22px;
+		line-height: 22px;
+	}
+
+	.uni-select__input-plac {
+		font-size: 14px;
+		color: $uni-secondary-color;
+	}
+
+	.uni-select__selector {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		/* #endif */
+		position: absolute;
+		left: 0;
+		width: 100%;
+		background-color: #FFFFFF;
+		border: 1px solid #EBEEF5;
+		border-radius: 6px;
+		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+		z-index: 3;
+		padding: 4px 0;
+	}
+
+	.uni-select__selector-scroll {
+		/* #ifndef APP-NVUE */
+		max-height: 200px;
+		box-sizing: border-box;
+		/* #endif */
+	}
+
+	/* #ifdef H5 */
+	@media (min-width: 768px) {
+		.uni-select__selector-scroll {
+			max-height: 600px;
+		}
+	}
+
+	/* #endif */
+
+	.uni-select__selector-empty,
+	.uni-select__selector-item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		cursor: pointer;
+		/* #endif */
+		line-height: 35px;
+		font-size: 14px;
+		text-align: center;
+		/* border-bottom: solid 1px $uni-border-3; */
+		padding: 0px 10px;
+	}
+
+	.uni-select__selector-item:hover {
+		background-color: #f9f9f9;
+	}
+
+	.uni-select__selector-empty:last-child,
+	.uni-select__selector-item:last-child {
+		/* #ifndef APP-NVUE */
+		border-bottom: none;
+		/* #endif */
+	}
+
+	.uni-select__selector__disabled {
+		opacity: 0.4;
+		cursor: default;
+	}
+
+	/* picker 弹出层通用的指示小三角 */
+	.uni-popper__arrow_bottom,
+	.uni-popper__arrow_bottom::after,
+	.uni-popper__arrow_top,
+	.uni-popper__arrow_top::after,
+	{
+	position: absolute;
+	display: block;
+	width: 0;
+	height: 0;
+	border-color: transparent;
+	border-style: solid;
+	border-width: 6px;
+	}
+
+	.uni-popper__arrow_bottom {
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+		top: -6px;
+		left: 10%;
+		margin-right: 3px;
+		border-top-width: 0;
+		border-bottom-color: #EBEEF5;
+	}
+
+	.uni-popper__arrow_bottom::after {
+		content: " ";
+		top: 1px;
+		margin-left: -6px;
+		border-top-width: 0;
+		border-bottom-color: #fff;
+	}
+
+	.uni-popper__arrow_top {
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+		bottom: -6px;
+		left: 10%;
+		margin-right: 3px;
+		border-bottom-width: 0;
+		border-top-color: #EBEEF5;
+	}
+
+	.uni-popper__arrow_top::after {
+		content: " ";
+		bottom: 1px;
+		margin-left: -6px;
+		border-bottom-width: 0;
+		border-top-color: #fff;
+	}
+
+
+	.uni-select__input-text {
+		// width: 280px;
+		width: 100%;
+		color: $uni-main-color;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		-o-text-overflow: ellipsis;
+		overflow: hidden;
+	}
+
+	.uni-select__input-placeholder {
+		color: $uni-base-color;
+		font-size: 12px;
+	}
+
+	.uni-select--mask {
+		position: fixed;
+		top: 0;
+		bottom: 0;
+		right: 0;
+		left: 0;
+		z-index: 2;
+	}
+</style>
diff --git a/uni_modules/uni-data-select/package.json b/uni_modules/uni-data-select/package.json
new file mode 100644
index 0000000..5864594
--- /dev/null
+++ b/uni_modules/uni-data-select/package.json
@@ -0,0 +1,86 @@
+{
+  "id": "uni-data-select",
+  "displayName": "uni-data-select 下拉框选择器",
+  "version": "1.0.8",
+  "description": "通过数据驱动的下拉框选择器",
+  "keywords": [
+    "uni-ui",
+    "select",
+    "uni-data-select",
+    "下拉框",
+    "下拉选"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.1.1"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-load-more"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "u",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+        "QQ": "u",
+        "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-data-select/readme.md b/uni_modules/uni-data-select/readme.md
new file mode 100644
index 0000000..eb58de3
--- /dev/null
+++ b/uni_modules/uni-data-select/readme.md
@@ -0,0 +1,8 @@
+## DataSelect 下拉框选择器
+> **组件名:uni-data-select**
+> 代码块: `uDataSelect`
+
+当选项过多时,使用下拉菜单展示并选择内容
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-select)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
diff --git a/uni_modules/uni-dateformat/changelog.md b/uni_modules/uni-dateformat/changelog.md
new file mode 100644
index 0000000..d551d7b
--- /dev/null
+++ b/uni_modules/uni-dateformat/changelog.md
@@ -0,0 +1,10 @@
+## 1.0.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-dateformat](https://uniapp.dcloud.io/component/uniui/uni-dateformat)
+## 0.0.5(2021-07-08)
+- 调整 默认时间不再是当前时间,而是显示'-'字符
+## 0.0.4(2021-05-12)
+- 新增 组件示例地址
+## 0.0.3(2021-02-04)
+- 调整为uni_modules目录规范
+- 修复 iOS 平台日期格式化出错的问题
diff --git a/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js b/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js
new file mode 100644
index 0000000..e00d559
--- /dev/null
+++ b/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js
@@ -0,0 +1,200 @@
+// yyyy-MM-dd hh:mm:ss.SSS 所有支持的类型
+function pad(str, length = 2) {
+	str += ''
+	while (str.length < length) {
+		str = '0' + str
+	}
+	return str.slice(-length)
+}
+
+const parser = {
+	yyyy: (dateObj) => {
+		return pad(dateObj.year, 4)
+	},
+	yy: (dateObj) => {
+		return pad(dateObj.year)
+	},
+	MM: (dateObj) => {
+		return pad(dateObj.month)
+	},
+	M: (dateObj) => {
+		return dateObj.month
+	},
+	dd: (dateObj) => {
+		return pad(dateObj.day)
+	},
+	d: (dateObj) => {
+		return dateObj.day
+	},
+	hh: (dateObj) => {
+		return pad(dateObj.hour)
+	},
+	h: (dateObj) => {
+		return dateObj.hour
+	},
+	mm: (dateObj) => {
+		return pad(dateObj.minute)
+	},
+	m: (dateObj) => {
+		return dateObj.minute
+	},
+	ss: (dateObj) => {
+		return pad(dateObj.second)
+	},
+	s: (dateObj) => {
+		return dateObj.second
+	},
+	SSS: (dateObj) => {
+		return pad(dateObj.millisecond, 3)
+	},
+	S: (dateObj) => {
+		return dateObj.millisecond
+	},
+}
+
+// 这都n年了iOS依然不认识2020-12-12,需要转换为2020/12/12
+function getDate(time) {
+	if (time instanceof Date) {
+		return time
+	}
+	switch (typeof time) {
+		case 'string':
+			{
+				// 2020-12-12T12:12:12.000Z、2020-12-12T12:12:12.000
+				if (time.indexOf('T') > -1) {
+					return new Date(time)
+				}
+				return new Date(time.replace(/-/g, '/'))
+			}
+		default:
+			return new Date(time)
+	}
+}
+
+export function formatDate(date, format = 'yyyy/MM/dd hh:mm:ss') {
+	if (!date && date !== 0) {
+		return ''
+	}
+	date = getDate(date)
+	const dateObj = {
+		year: date.getFullYear(),
+		month: date.getMonth() + 1,
+		day: date.getDate(),
+		hour: date.getHours(),
+		minute: date.getMinutes(),
+		second: date.getSeconds(),
+		millisecond: date.getMilliseconds()
+	}
+	const tokenRegExp = /yyyy|yy|MM|M|dd|d|hh|h|mm|m|ss|s|SSS|SS|S/
+	let flag = true
+	let result = format
+	while (flag) {
+		flag = false
+		result = result.replace(tokenRegExp, function(matched) {
+			flag = true
+			return parser[matched](dateObj)
+		})
+	}
+	return result
+}
+
+export function friendlyDate(time, {
+	locale = 'zh',
+	threshold = [60000, 3600000],
+	format = 'yyyy/MM/dd hh:mm:ss'
+}) {
+	if (time === '-') {
+		return time
+	}
+	if (!time && time !== 0) {
+		return ''
+	}
+	const localeText = {
+		zh: {
+			year: '年',
+			month: '月',
+			day: '天',
+			hour: '小时',
+			minute: '分钟',
+			second: '秒',
+			ago: '前',
+			later: '后',
+			justNow: '刚刚',
+			soon: '马上',
+			template: '{num}{unit}{suffix}'
+		},
+		en: {
+			year: 'year',
+			month: 'month',
+			day: 'day',
+			hour: 'hour',
+			minute: 'minute',
+			second: 'second',
+			ago: 'ago',
+			later: 'later',
+			justNow: 'just now',
+			soon: 'soon',
+			template: '{num} {unit} {suffix}'
+		}
+	}
+	const text = localeText[locale] || localeText.zh
+	let date = getDate(time)
+	let ms = date.getTime() - Date.now()
+	let absMs = Math.abs(ms)
+	if (absMs < threshold[0]) {
+		return ms < 0 ? text.justNow : text.soon
+	}
+	if (absMs >= threshold[1]) {
+		return formatDate(date, format)
+	}
+	let num
+	let unit
+	let suffix = text.later
+	if (ms < 0) {
+		suffix = text.ago
+		ms = -ms
+	}
+	const seconds = Math.floor((ms) / 1000)
+	const minutes = Math.floor(seconds / 60)
+	const hours = Math.floor(minutes / 60)
+	const days = Math.floor(hours / 24)
+	const months = Math.floor(days / 30)
+	const years = Math.floor(months / 12)
+	switch (true) {
+		case years > 0:
+			num = years
+			unit = text.year
+			break
+		case months > 0:
+			num = months
+			unit = text.month
+			break
+		case days > 0:
+			num = days
+			unit = text.day
+			break
+		case hours > 0:
+			num = hours
+			unit = text.hour
+			break
+		case minutes > 0:
+			num = minutes
+			unit = text.minute
+			break
+		default:
+			num = seconds
+			unit = text.second
+			break
+	}
+
+	if (locale === 'en') {
+		if (num === 1) {
+			num = 'a'
+		} else {
+			unit += 's'
+		}
+	}
+
+	return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g,
+		suffix)
+}
diff --git a/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue b/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue
new file mode 100644
index 0000000..c5ed030
--- /dev/null
+++ b/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue
@@ -0,0 +1,88 @@
+<template>
+	<text>{{dateShow}}</text>
+</template>
+
+<script>
+	import {friendlyDate} from './date-format.js'
+	/**
+	 * Dateformat 日期格式化
+	 * @description 日期格式化组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3279
+	 * @property {Object|String|Number} date 日期对象/日期字符串/时间戳
+	 * @property {String} locale 格式化使用的语言
+	 * 	@value zh 中文
+	 * 	@value en 英文
+	 * @property {Array} threshold 应用不同类型格式化的阈值
+	 * @property {String} format 输出日期字符串时的格式
+	 */
+	export default {
+		name: 'uniDateformat',
+		props: {
+			date: {
+				type: [Object, String, Number],
+				default () {
+					return '-'
+				}
+			},
+			locale: {
+				type: String,
+				default: 'zh',
+			},
+			threshold: {
+				type: Array,
+				default () {
+					return [0, 0]
+				}
+			},
+			format: {
+				type: String,
+				default: 'yyyy/MM/dd hh:mm:ss'
+			},
+			// refreshRate使用不当可能导致性能问题,谨慎使用
+			refreshRate: {
+				type: [Number, String],
+				default: 0
+			}
+		},
+		data() {
+			return {
+				refreshMark: 0
+			}
+		},
+		computed: {
+			dateShow() {
+				this.refreshMark
+				return friendlyDate(this.date, {
+					locale: this.locale,
+					threshold: this.threshold,
+					format: this.format
+				})
+			}
+		},
+		watch: {
+			refreshRate: {
+				handler() {
+					this.setAutoRefresh()
+				},
+				immediate: true
+			}
+		},
+		methods: {
+			refresh() {
+				this.refreshMark++
+			},
+			setAutoRefresh() {
+				clearInterval(this.refreshInterval)
+				if (this.refreshRate) {
+					this.refreshInterval = setInterval(() => {
+						this.refresh()
+					}, parseInt(this.refreshRate))
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>
diff --git a/uni_modules/uni-dateformat/package.json b/uni_modules/uni-dateformat/package.json
new file mode 100644
index 0000000..786a670
--- /dev/null
+++ b/uni_modules/uni-dateformat/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-dateformat",
+  "displayName": "uni-dateformat 日期格式化",
+  "version": "1.0.0",
+  "description": "日期格式化组件,可以将日期格式化为1分钟前、刚刚等形式",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "日期格式化",
+    "时间格式化",
+    "格式化时间",
+    ""
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-dateformat/readme.md b/uni_modules/uni-dateformat/readme.md
new file mode 100644
index 0000000..37ddb6e
--- /dev/null
+++ b/uni_modules/uni-dateformat/readme.md
@@ -0,0 +1,11 @@
+
+
+### DateFormat 日期格式化
+> **组件名:uni-dateformat**
+> 代码块: `uDateformat`
+
+
+日期格式化组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-dateformat)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-datetime-picker/changelog.md b/uni_modules/uni-datetime-picker/changelog.md
new file mode 100644
index 0000000..102ddb1
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/changelog.md
@@ -0,0 +1,168 @@
+## 2.2.38(2024-10-15)
+- 修复 微信小程序中的getSystemInfo警告
+## 2.2.37(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 2.2.36(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 2.2.35(2024-09-21)
+- 修复 没有选中日期时点击确定直接报错的Bug [详情](https://ask.dcloud.net.cn/question/198168)
+## 2.2.34(2024-04-24)
+- 新增 日期点击事件,在点击日期时会触发该事件。
+## 2.2.33(2024-04-15)
+- 修复 抖音小程序事件传递失效bug
+## 2.2.32(2024-02-20)
+- 修复 日历的close事件触发异常的bug [详情](https://github.com/dcloudio/uni-ui/issues/844)
+## 2.2.31(2024-02-20)
+- 修复 h5平台 右边日历的月份默认+1的bug [详情](https://github.com/dcloudio/uni-ui/issues/841)
+## 2.2.30(2024-01-31)
+- 修复 隐藏“秒”时,在IOS15及以下版本时出现 结束时间在开始时间之前 的bug [详情](https://github.com/dcloudio/uni-ui/issues/788)
+## 2.2.29(2024-01-20)
+- 新增 show事件,弹窗弹出时触发该事件 [详情](https://github.com/dcloudio/uni-app/issues/4694)
+## 2.2.28(2024-01-18)
+- 去除 noChange事件,当进行日期范围选择时,若只选了一天,则开始结束日期都为同一天 [详情](https://github.com/dcloudio/uni-ui/issues/815)
+## 2.2.27(2024-01-10)
+- 优化 增加noChange事件,当进行日期范围选择时,若有空值,则触发该事件 [详情](https://github.com/dcloudio/uni-ui/issues/815)
+## 2.2.26(2024-01-08)
+- 修复 字节小程序时间选择范围器失效问题 [详情](https://github.com/dcloudio/uni-ui/issues/834)
+## 2.2.25(2023-10-18)
+- 修复 PC端初次修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
+## 2.2.24(2023-06-02)
+- 修复 部分情况修改时间,开始、结束时间显示异常的Bug [详情](https://ask.dcloud.net.cn/question/171146)
+- 优化 当前月可以选择上月、下月的日期的Bug
+## 2.2.23(2023-05-02)
+- 修复 部分情况修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
+- 修复 部分平台及设备第一次点击无法显示弹框的Bug
+- 修复 ios 日期格式未补零显示及使用异常的Bug [详情](https://ask.dcloud.net.cn/question/162979)
+## 2.2.22(2023-03-30)
+- 修复 日历 picker 修改年月后,自动选中当月1日的Bug [详情](https://ask.dcloud.net.cn/question/165937)
+- 修复 小程序端 低版本 ios NaN的Bug [详情](https://ask.dcloud.net.cn/question/162979)
+## 2.2.21(2023-02-20)
+- 修复 firefox 浏览器显示区域点击无法拉起日历弹框的Bug [详情](https://ask.dcloud.net.cn/question/163362)
+## 2.2.20(2023-02-17)
+- 优化 值为空依然选中当天问题
+- 优化 提供 default-value 属性支持配置选择器打开时默认显示的时间
+- 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间
+- 优化 字节小程序日期时间范围选择,底部日期换行的Bug
+## 2.2.19(2023-02-09)
+- 修复 2.2.18 引起范围选择配置 end 选择无效的Bug [详情](https://github.com/dcloudio/uni-ui/issues/686)
+## 2.2.18(2023-02-08)
+- 修复 移动端范围选择change事件触发异常的Bug [详情](https://github.com/dcloudio/uni-ui/issues/684)
+- 优化 PC端输入日期格式错误时返回当前日期时间
+- 优化 PC端输入日期时间超出 start、end 限制的Bug
+- 优化 移动端日期时间范围用法时间展示不完整问题
+## 2.2.17(2023-02-04)
+- 修复 小程序端绑定 Date 类型报错的Bug [详情](https://github.com/dcloudio/uni-ui/issues/679)
+- 修复 vue3 time-picker 无法显示绑定时分秒的Bug
+## 2.2.16(2023-02-02)
+- 修复 字节小程序报错的Bug
+## 2.2.15(2023-02-02)
+- 修复 某些情况切换月份错误的Bug
+## 2.2.14(2023-01-30)
+- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/162033)
+## 2.2.13(2023-01-10)
+- 修复 多次加载组件造成内存占用的Bug
+## 2.2.12(2022-12-01)
+- 修复 vue3 下 i18n 国际化初始值不正确的Bug
+## 2.2.11(2022-09-19)
+- 修复 支付宝小程序样式错乱的Bug [详情](https://github.com/dcloudio/uni-app/issues/3861)
+## 2.2.10(2022-09-19)
+- 修复 反向选择日期范围,日期显示异常的Bug [详情](https://ask.dcloud.net.cn/question/153401?item_id=212892&rf=false)
+## 2.2.9(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 2.2.8(2022-09-08)
+- 修复 close事件无效的Bug
+## 2.2.7(2022-09-05)
+- 修复 移动端 maskClick 无效的Bug [详情](https://ask.dcloud.net.cn/question/140824)
+## 2.2.6(2022-06-30)
+- 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
+## 2.2.5(2022-06-24)
+- 修复 日历顶部年月及底部确认未国际化的Bug
+## 2.2.4(2022-03-31)
+- 修复 Vue3 下动态赋值,单选类型未响应的Bug
+## 2.2.3(2022-03-28)
+- 修复 Vue3 下动态赋值未响应的Bug
+## 2.2.2(2021-12-10)
+- 修复 clear-icon 属性在小程序平台不生效的Bug
+## 2.2.1(2021-12-10)
+- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的Bug
+## 2.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源 [详情](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移 [https://uniapp.dcloud.io/component/uniui/uni-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
+## 2.1.5(2021-11-09)
+- 新增 提供组件设计资源,组件样式调整
+## 2.1.4(2021-09-10)
+- 修复 hide-second 在移动端的Bug
+- 修复 单选赋默认值时,赋值日期未高亮的Bug
+- 修复 赋默认值时,移动端未正确显示时间的Bug
+## 2.1.3(2021-09-09)
+- 新增 hide-second 属性,支持只使用时分,隐藏秒
+## 2.1.2(2021-09-03)
+- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
+- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
+- 优化 调整字号大小,美化日历界面
+- 修复 因国际化导致的 placeholder 失效的Bug
+## 2.1.1(2021-08-24)
+- 新增 支持国际化
+- 优化 范围选择器在 pc 端过宽的问题
+## 2.1.0(2021-08-09)
+- 新增 适配 vue3
+## 2.0.19(2021-08-09)
+- 新增 支持作为 uni-forms 子组件相关功能
+- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的Bug
+## 2.0.18(2021-08-05)
+- 修复 type 属性动态赋值无效的Bug
+- 修复 ‘确认’按钮被 tabbar 遮盖 bug
+- 修复 组件未赋值时范围选左、右日历相同的Bug
+## 2.0.17(2021-08-04)
+- 修复 范围选未正确显示当前值的Bug
+- 修复 h5 平台(移动端)报错 'cale' of undefined 的Bug
+## 2.0.16(2021-07-21)
+- 新增 return-type 属性支持返回 date 日期对象
+## 2.0.15(2021-07-14)
+- 修复 单选日期类型,初始赋值后不在当前日历的Bug
+- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效)
+- 优化 移动端移除显示框的清空按钮,无实际用途
+## 2.0.14(2021-07-14)
+- 修复 组件赋值为空,界面未更新的Bug
+- 修复 start 和 end 不能动态赋值的Bug
+- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的Bug
+## 2.0.13(2021-07-08)
+- 修复 范围选择不能动态赋值的Bug
+## 2.0.12(2021-07-08)
+- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug
+## 2.0.11(2021-07-08)
+- 优化 弹出层在超出视窗边缘定位不准确的问题
+## 2.0.10(2021-07-08)
+- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的Bug
+- 优化 弹出层在超出视窗边缘被遮盖的问题
+## 2.0.9(2021-07-07)
+- 新增 maskClick 事件
+- 修复 特殊情况日历 rpx 布局错误的Bug,rpx -> px
+- 修复 范围选择时清空返回值不合理的bug,['', ''] -> []
+## 2.0.8(2021-07-07)
+- 新增 日期时间显示框支持插槽
+## 2.0.7(2021-07-01)
+- 优化 添加 uni-icons 依赖
+## 2.0.6(2021-05-22)
+- 修复 图标在小程序上不显示的Bug
+- 优化 重命名引用组件,避免潜在组件命名冲突
+## 2.0.5(2021-05-20)
+- 优化 代码目录扁平化
+## 2.0.4(2021-05-12)
+- 新增 组件示例地址
+## 2.0.3(2021-05-10)
+- 修复 ios 下不识别 '-' 日期格式的Bug
+- 优化 pc 下弹出层添加边框和阴影
+## 2.0.2(2021-05-08)
+- 修复 在 admin 中获取弹出层定位错误的bug
+## 2.0.1(2021-05-08)
+- 修复 type 属性向下兼容,默认值从 date 变更为 datetime
+## 2.0.0(2021-04-30)
+- 支持日历形式的日期+时间的范围选择
+ > 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)
+## 1.0.6(2021-03-18)
+- 新增 hide-second 属性,时间支持仅选择时、分
+- 修复 选择跟显示的日期不一样的Bug
+- 修复 chang事件触发2次的Bug
+- 修复 分、秒 end 范围错误的Bug
+- 优化 更好的 nvue 适配
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue
new file mode 100644
index 0000000..dba9887
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue
@@ -0,0 +1,177 @@
+<template>
+	<view class="uni-calendar-item__weeks-box" :class="{
+		'uni-calendar-item--disable':weeks.disable,
+		'uni-calendar-item--before-checked-x':weeks.beforeMultiple,
+		'uni-calendar-item--multiple': weeks.multiple,
+		'uni-calendar-item--after-checked-x':weeks.afterMultiple,
+		}" @click="choiceDate(weeks)" @mouseenter="handleMousemove(weeks)">
+		<view class="uni-calendar-item__weeks-box-item" :class="{
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && (calendar.userChecked || !checkHover),
+				'uni-calendar-item--checked-range-text': checkHover,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">
+			<text v-if="selected && weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
+			<text class="uni-calendar-item__weeks-box-text uni-calendar-item__weeks-box-text-disable uni-calendar-item--checked-text">{{weeks.date}}</text>
+		</view>
+		<view :class="{'uni-calendar-item--today': weeks.isToday}"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			weeks: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			calendar: {
+				type: Object,
+				default: () => {
+					return {}
+				}
+			},
+			selected: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			},
+			checkHover: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			choiceDate(weeks) {
+				this.$emit('change', weeks)
+			},
+			handleMousemove(weeks) {
+				this.$emit('handleMouse', weeks)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	$uni-primary: #007aff !default;
+
+	.uni-calendar-item__weeks-box {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		margin: 1px 0;
+		position: relative;
+	}
+
+	.uni-calendar-item__weeks-box-text {
+		font-size: 14px;
+		// font-family: Lato-Bold, Lato;
+		font-weight: bold;
+		color: darken($color: $uni-primary, $amount: 40%);
+	}
+
+	.uni-calendar-item__weeks-box-item {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 40px;
+		height: 40px;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+
+	.uni-calendar-item__weeks-box-circle {
+		position: absolute;
+		top: 5px;
+		right: 5px;
+		width: 8px;
+		height: 8px;
+		border-radius: 8px;
+		background-color: #dd524d;
+
+	}
+
+	.uni-calendar-item__weeks-box .uni-calendar-item--disable {
+		cursor: default;
+	}
+
+	.uni-calendar-item--disable .uni-calendar-item__weeks-box-text-disable {
+		color: #D1D1D1;
+	}
+
+	.uni-calendar-item--today {
+		position: absolute;
+		top: 10px;
+		right: 17%;
+		background-color: #dd524d;
+		width:6px;
+		height: 6px;
+		border-radius: 50%;
+	}
+
+	.uni-calendar-item--extra {
+		color: #dd524d;
+		opacity: 0.8;
+	}
+
+	.uni-calendar-item__weeks-box .uni-calendar-item--checked {
+		background-color: $uni-primary;
+		border-radius: 50%;
+		box-sizing: border-box;
+		border: 3px solid #fff;
+	}
+
+	.uni-calendar-item--checked .uni-calendar-item--checked-text {
+		color: #fff;
+	}
+
+	.uni-calendar-item--multiple .uni-calendar-item--checked-range-text {
+		color: #333;
+	}
+
+	.uni-calendar-item--multiple {
+		background-color:  #F6F7FC;
+		// color: #fff;
+	}
+
+	.uni-calendar-item--multiple .uni-calendar-item--before-checked,
+	.uni-calendar-item--multiple .uni-calendar-item--after-checked {
+		background-color: $uni-primary;
+		border-radius: 50%;
+		box-sizing: border-box;
+		border: 3px solid #F6F7FC;
+	}
+
+	.uni-calendar-item--before-checked .uni-calendar-item--checked-text,
+	.uni-calendar-item--after-checked .uni-calendar-item--checked-text {
+		color: #fff;
+	}
+
+	.uni-calendar-item--before-checked-x {
+		border-top-left-radius: 50px;
+		border-bottom-left-radius: 50px;
+		box-sizing: border-box;
+		background-color: #F6F7FC;
+	}
+
+	.uni-calendar-item--after-checked-x {
+		border-top-right-radius: 50px;
+		border-bottom-right-radius: 50px;
+		background-color: #F6F7FC;
+	}
+</style>
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
new file mode 100644
index 0000000..0f9e121
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
@@ -0,0 +1,947 @@
+<template>
+	<view class="uni-calendar" @mouseleave="leaveCale">
+
+		<view v-if="!insert && show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}"
+			@click="maskClick"></view>
+
+		<view v-if="insert || show" class="uni-calendar__content"
+			:class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow, 'uni-calendar__content-mobile': aniMaskShow}">
+			<view class="uni-calendar__header" :class="{'uni-calendar__header-mobile' :!insert}">
+
+				<view class="uni-calendar__header-btn-box" @click.stop="changeMonth('pre')">
+					<view class="uni-calendar__header-btn uni-calendar--left"></view>
+				</view>
+
+				<picker mode="date" :value="date" fields="month" @change="bindDateChange">
+					<text
+						class="uni-calendar__header-text">{{ (nowDate.year||'') + yearText + ( nowDate.month||'') + monthText}}</text>
+				</picker>
+
+				<view class="uni-calendar__header-btn-box" @click.stop="changeMonth('next')">
+					<view class="uni-calendar__header-btn uni-calendar--right"></view>
+				</view>
+
+				<view v-if="!insert" class="dialog-close" @click="maskClick">
+					<view class="dialog-close-plus" data-id="close"></view>
+					<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
+				</view>
+			</view>
+			<view class="uni-calendar__box">
+
+				<view v-if="showMonth" class="uni-calendar__box-bg">
+					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
+				</view>
+
+				<view class="uni-calendar__weeks" style="padding-bottom: 7px;">
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{MONText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
+					</view>
+				</view>
+
+				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
+					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
+						<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected"
+							:checkHover="range" @change="choiceDate" @handleMouse="handleMouse">
+						</calendar-item>
+					</view>
+				</view>
+			</view>
+
+			<view v-if="!insert && !range && hasTime" class="uni-date-changed uni-calendar--fixed-top"
+				style="padding: 0 80px;">
+				<view class="uni-date-changed--time-date">{{tempSingleDate ? tempSingleDate : selectDateText}}</view>
+				<time-picker type="time" :start="timepickerStartTime" :end="timepickerEndTime" v-model="time"
+					:disabled="!tempSingleDate" :border="false" :hide-second="hideSecond" class="time-picker-style">
+				</time-picker>
+			</view>
+
+			<view v-if="!insert && range && hasTime" class="uni-date-changed uni-calendar--fixed-top">
+				<view class="uni-date-changed--time-start">
+					<view class="uni-date-changed--time-date">{{tempRange.before ? tempRange.before : startDateText}}
+					</view>
+					<time-picker type="time" :start="timepickerStartTime" v-model="timeRange.startTime" :border="false"
+						:hide-second="hideSecond" :disabled="!tempRange.before" class="time-picker-style">
+					</time-picker>
+				</view>
+				<view style="line-height: 50px;">
+					<uni-icons type="arrowthinright" color="#999"></uni-icons>
+				</view>
+				<view class="uni-date-changed--time-end">
+					<view class="uni-date-changed--time-date">{{tempRange.after ? tempRange.after : endDateText}}</view>
+					<time-picker type="time" :end="timepickerEndTime" v-model="timeRange.endTime" :border="false"
+						:hide-second="hideSecond" :disabled="!tempRange.after" class="time-picker-style">
+					</time-picker>
+				</view>
+			</view>
+
+			<view v-if="!insert" class="uni-date-changed uni-date-btn--ok">
+				<view class="uni-datetime-picker--btn" @click="confirm">{{confirmText}}</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		Calendar,
+		getDate,
+		getTime
+	} from './util.js';
+	import calendarItem from './calendar-item.vue'
+	import timePicker from './time-picker.vue'
+
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(i18nMessages)
+
+	/**
+	 * Calendar 日历
+	 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
+	 * @property {String} date 自定义当前时间,默认为今天
+	 * @property {String} startDate 日期选择范围-开始日期
+	 * @property {String} endDate 日期选择范围-结束日期
+	 * @property {Boolean} range 范围选择
+	 * @property {Boolean} insert = [true|false] 插入模式,默认为false
+	 * 	@value true 弹窗模式
+	 * 	@value false 插入模式
+	 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
+	 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
+	 * @property {Boolean} showMonth 是否选择月份为背景
+	 * @property {[String} defaultValue 选择器打开时默认显示的时间
+	 * @event {Function} change 日期改变,`insert :ture` 时生效
+	 * @event {Function} confirm 确认选择`insert :false` 时生效
+	 * @event {Function} monthSwitch 切换月份时触发
+	 * @example <uni-calendar :insert="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
+	 */
+	export default {
+		components: {
+			calendarItem,
+			timePicker
+		},
+
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		props: {
+			date: {
+				type: String,
+				default: ''
+			},
+			defTime: {
+				type: [String, Object],
+				default: ''
+			},
+			selectableTimes: {
+				type: [Object],
+				default () {
+					return {}
+				}
+			},
+			selected: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			startDate: {
+				type: String,
+				default: ''
+			},
+			endDate: {
+				type: String,
+				default: ''
+			},
+			startPlaceholder: {
+				type: String,
+				default: ''
+			},
+			endPlaceholder: {
+				type: String,
+				default: ''
+			},
+			range: {
+				type: Boolean,
+				default: false
+			},
+			hasTime: {
+				type: Boolean,
+				default: false
+			},
+			insert: {
+				type: Boolean,
+				default: true
+			},
+			showMonth: {
+				type: Boolean,
+				default: true
+			},
+			clearDate: {
+				type: Boolean,
+				default: true
+			},
+			checkHover: {
+				type: Boolean,
+				default: true
+			},
+			hideSecond: {
+				type: [Boolean],
+				default: false
+			},
+			pleStatus: {
+				type: Object,
+				default () {
+					return {
+						before: '',
+						after: '',
+						data: [],
+						fulldate: ''
+					}
+				}
+			},
+			defaultValue: {
+				type: [String, Object, Array],
+				default: ''
+			}
+		},
+		data() {
+			return {
+				show: false,
+				weeks: [],
+				calendar: {},
+				nowDate: {},
+				aniMaskShow: false,
+				firstEnter: true,
+				time: '',
+				timeRange: {
+					startTime: '',
+					endTime: ''
+				},
+				tempSingleDate: '',
+				tempRange: {
+					before: '',
+					after: ''
+				}
+			}
+		},
+		watch: {
+			date: {
+				immediate: true,
+				handler(newVal) {
+					if (!this.range) {
+						this.tempSingleDate = newVal
+						setTimeout(() => {
+							this.init(newVal)
+						}, 100)
+					}
+				}
+			},
+			defTime: {
+				immediate: true,
+				handler(newVal) {
+					if (!this.range) {
+						this.time = newVal
+					} else {
+						this.timeRange.startTime = newVal.start
+						this.timeRange.endTime = newVal.end
+					}
+				}
+			},
+			startDate(val) {
+				// 字节小程序 watch 早于 created
+				if (!this.cale) {
+					return
+				}
+				this.cale.setStartDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			endDate(val) {
+				// 字节小程序 watch 早于 created
+				if (!this.cale) {
+					return
+				}
+				this.cale.setEndDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			selected(newVal) {
+				// 字节小程序 watch 早于 created
+				if (!this.cale) {
+					return
+				}
+				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
+				this.weeks = this.cale.weeks
+			},
+			pleStatus: {
+				immediate: true,
+				handler(newVal) {
+					const {
+						before,
+						after,
+						fulldate,
+						which
+					} = newVal
+					this.tempRange.before = before
+					this.tempRange.after = after
+					setTimeout(() => {
+						if (fulldate) {
+							this.cale.setHoverMultiple(fulldate)
+							if (before && after) {
+								this.cale.lastHover = true
+								if (this.rangeWithinMonth(after, before)) return
+								this.setDate(before)
+							} else {
+								this.cale.setMultiple(fulldate)
+								this.setDate(this.nowDate.fullDate)
+								this.calendar.fullDate = ''
+								this.cale.lastHover = false
+							}
+						} else {
+							// 字节小程序 watch 早于 created
+							if (!this.cale) {
+								return
+							}
+
+							this.cale.setDefaultMultiple(before, after)
+							if (which === 'left' && before) {
+								this.setDate(before)
+								this.weeks = this.cale.weeks
+							} else if (after) {
+								this.setDate(after)
+								this.weeks = this.cale.weeks
+							}
+							this.cale.lastHover = true
+						}
+					}, 16)
+				}
+			}
+		},
+		computed: {
+			timepickerStartTime() {
+				const activeDate = this.range ? this.tempRange.before : this.calendar.fullDate
+				return activeDate === this.startDate ? this.selectableTimes.start : ''
+			},
+			timepickerEndTime() {
+				const activeDate = this.range ? this.tempRange.after : this.calendar.fullDate
+				return activeDate === this.endDate ? this.selectableTimes.end : ''
+			},
+			/**
+			 * for i18n
+			 */
+			selectDateText() {
+				return t("uni-datetime-picker.selectDate")
+			},
+			startDateText() {
+				return this.startPlaceholder || t("uni-datetime-picker.startDate")
+			},
+			endDateText() {
+				return this.endPlaceholder || t("uni-datetime-picker.endDate")
+			},
+			okText() {
+				return t("uni-datetime-picker.ok")
+			},
+			yearText() {
+				return t("uni-datetime-picker.year")
+			},
+			monthText() {
+				return t("uni-datetime-picker.month")
+			},
+			MONText() {
+				return t("uni-calender.MON")
+			},
+			TUEText() {
+				return t("uni-calender.TUE")
+			},
+			WEDText() {
+				return t("uni-calender.WED")
+			},
+			THUText() {
+				return t("uni-calender.THU")
+			},
+			FRIText() {
+				return t("uni-calender.FRI")
+			},
+			SATText() {
+				return t("uni-calender.SAT")
+			},
+			SUNText() {
+				return t("uni-calender.SUN")
+			},
+			confirmText() {
+				return t("uni-calender.confirm")
+			},
+		},
+		created() {
+			// 获取日历方法实例
+			this.cale = new Calendar({
+				selected: this.selected,
+				startDate: this.startDate,
+				endDate: this.endDate,
+				range: this.range,
+			})
+			// 选中某一天
+			this.init(this.date)
+		},
+		methods: {
+			leaveCale() {
+				this.firstEnter = true
+			},
+			handleMouse(weeks) {
+				if (weeks.disable) return
+				if (this.cale.lastHover) return
+				let {
+					before,
+					after
+				} = this.cale.multipleStatus
+				if (!before) return
+				this.calendar = weeks
+				// 设置范围选
+				this.cale.setHoverMultiple(this.calendar.fullDate)
+				this.weeks = this.cale.weeks
+				// hover时,进入一个日历,更新另一个
+				if (this.firstEnter) {
+					this.$emit('firstEnterCale', this.cale.multipleStatus)
+					this.firstEnter = false
+				}
+			},
+			rangeWithinMonth(A, B) {
+				const [yearA, monthA] = A.split('-')
+				const [yearB, monthB] = B.split('-')
+				return yearA === yearB && monthA === monthB
+			},
+			// 蒙版点击事件
+			maskClick() {
+				this.close()
+				this.$emit('maskClose')
+			},
+
+			clearCalender() {
+				if (this.range) {
+					this.timeRange.startTime = ''
+					this.timeRange.endTime = ''
+					this.tempRange.before = ''
+					this.tempRange.after = ''
+					this.cale.multipleStatus.before = ''
+					this.cale.multipleStatus.after = ''
+					this.cale.multipleStatus.data = []
+					this.cale.lastHover = false
+				} else {
+					this.time = ''
+					this.tempSingleDate = ''
+				}
+				this.calendar.fullDate = ''
+				this.setDate(new Date())
+			},
+
+			bindDateChange(e) {
+				const value = e.detail.value + '-1'
+				this.setDate(value)
+			},
+			/**
+			 * 初始化日期显示
+			 * @param {Object} date
+			 */
+			init(date) {
+				// 字节小程序 watch 早于 created
+				if (!this.cale) {
+					return
+				}
+				this.cale.setDate(date || new Date())
+				this.weeks = this.cale.weeks
+				this.nowDate = this.cale.getInfo(date)
+				this.calendar = {
+					...this.nowDate
+				}
+				if (!date) {
+					// 优化date为空默认不选中今天
+					this.calendar.fullDate = ''
+					if (this.defaultValue && !this.range) {
+						// 暂时只支持移动端非范围选择
+						const defaultDate = new Date(this.defaultValue)
+						const fullDate = getDate(defaultDate)
+						const year = defaultDate.getFullYear()
+						const month = defaultDate.getMonth() + 1
+						const date = defaultDate.getDate()
+						const day = defaultDate.getDay()
+						this.calendar = {
+								fullDate,
+								year,
+								month,
+								date,
+								day
+							},
+							this.tempSingleDate = fullDate
+						this.time = getTime(defaultDate, this.hideSecond)
+					}
+				}
+			},
+			/**
+			 * 打开日历弹窗
+			 */
+			open() {
+				// 弹窗模式并且清理数据
+				if (this.clearDate && !this.insert) {
+					this.cale.cleanMultipleStatus()
+					this.init(this.date)
+				}
+				this.show = true
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.aniMaskShow = true
+					}, 50)
+				})
+			},
+			/**
+			 * 关闭日历弹窗
+			 */
+			close() {
+				this.aniMaskShow = false
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.show = false
+						this.$emit('close')
+					}, 300)
+				})
+			},
+			/**
+			 * 确认按钮
+			 */
+			confirm() {
+				this.setEmit('confirm')
+				this.close()
+			},
+			/**
+			 * 变化触发
+			 */
+			change(isSingleChange) {
+				if (!this.insert && !isSingleChange) return
+				this.setEmit('change')
+			},
+			/**
+			 * 选择月份触发
+			 */
+			monthSwitch() {
+				let {
+					year,
+					month
+				} = this.nowDate
+				this.$emit('monthSwitch', {
+					year,
+					month: Number(month)
+				})
+			},
+			/**
+			 * 派发事件
+			 * @param {Object} name
+			 */
+			setEmit(name) {
+				if (!this.range) {
+					if (!this.calendar.fullDate) {
+						this.calendar = this.cale.getInfo(new Date())
+						this.tempSingleDate = this.calendar.fullDate
+					}
+					if (this.hasTime && !this.time) {
+						this.time = getTime(new Date(), this.hideSecond)
+					}
+				}
+				let {
+					year,
+					month,
+					date,
+					fullDate,
+					extraInfo
+				} = this.calendar
+				this.$emit(name, {
+					range: this.cale.multipleStatus,
+					year,
+					month,
+					date,
+					time: this.time,
+					timeRange: this.timeRange,
+					fulldate: fullDate,
+					extraInfo: extraInfo || {}
+				})
+			},
+			/**
+			 * 选择天触发
+			 * @param {Object} weeks
+			 */
+			choiceDate(weeks) {
+				if (weeks.disable) return
+				this.calendar = weeks
+				this.calendar.userChecked = true
+				// 设置多选
+				this.cale.setMultiple(this.calendar.fullDate, true)
+				this.weeks = this.cale.weeks
+				this.tempSingleDate = this.calendar.fullDate
+				const beforeDate = new Date(this.cale.multipleStatus.before).getTime()
+				const afterDate = new Date(this.cale.multipleStatus.after).getTime()
+				if (beforeDate > afterDate && afterDate) {
+					this.tempRange.before = this.cale.multipleStatus.after
+					this.tempRange.after = this.cale.multipleStatus.before
+				} else {
+					this.tempRange.before = this.cale.multipleStatus.before
+					this.tempRange.after = this.cale.multipleStatus.after
+				}
+				this.change(true)
+			},
+			changeMonth(type) {
+				let newDate
+				if (type === 'pre') {
+					newDate = this.cale.getPreMonthObj(this.nowDate.fullDate).fullDate
+				} else if (type === 'next') {
+					newDate = this.cale.getNextMonthObj(this.nowDate.fullDate).fullDate
+				}
+
+				this.setDate(newDate)
+				this.monthSwitch()
+			},
+			/**
+			 * 设置日期
+			 * @param {Object} date
+			 */
+			setDate(date) {
+				this.cale.setDate(date)
+				this.weeks = this.cale.weeks
+				this.nowDate = this.cale.getInfo(date)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #007aff !default;
+
+	.uni-calendar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-calendar__mask {
+		position: fixed;
+		bottom: 0;
+		top: 0;
+		left: 0;
+		right: 0;
+		background-color: rgba(0, 0, 0, 0.4);
+		transition-property: opacity;
+		transition-duration: 0.3s;
+		opacity: 0;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--mask-show {
+		opacity: 1
+	}
+
+	.uni-calendar--fixed {
+		position: fixed;
+		bottom: calc(var(--window-bottom));
+		left: 0;
+		right: 0;
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transform: translateY(460px);
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--ani-show {
+		transform: translateY(0);
+	}
+
+	.uni-calendar__content {
+		background-color: #fff;
+	}
+
+	.uni-calendar__content-mobile {
+		border-top-left-radius: 10px;
+		border-top-right-radius: 10px;
+		box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.1);
+	}
+
+	.uni-calendar__header {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 50px;
+	}
+
+	.uni-calendar__header-mobile {
+		padding: 10px;
+		padding-bottom: 0;
+	}
+
+	.uni-calendar--fixed-top {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+		border-top-color: rgba(0, 0, 0, 0.4);
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-calendar--fixed-width {
+		width: 50px;
+	}
+
+	.uni-calendar__backtoday {
+		position: absolute;
+		right: 0;
+		top: 25rpx;
+		padding: 0 5px;
+		padding-left: 10px;
+		height: 25px;
+		line-height: 25px;
+		font-size: 12px;
+		border-top-left-radius: 25px;
+		border-bottom-left-radius: 25px;
+		color: #fff;
+		background-color: #f1f1f1;
+	}
+
+	.uni-calendar__header-text {
+		text-align: center;
+		width: 100px;
+		font-size: 15px;
+		color: #666;
+	}
+
+	.uni-calendar__button-text {
+		text-align: center;
+		width: 100px;
+		font-size: 14px;
+		color: $uni-primary;
+		/* #ifndef APP-NVUE */
+		letter-spacing: 3px;
+		/* #endif */
+	}
+
+	.uni-calendar__header-btn-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		width: 50px;
+		height: 50px;
+	}
+
+	.uni-calendar__header-btn {
+		width: 9px;
+		height: 9px;
+		border-left-color: #808080;
+		border-left-style: solid;
+		border-left-width: 1px;
+		border-top-color: #555555;
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-calendar--left {
+		transform: rotate(-45deg);
+	}
+
+	.uni-calendar--right {
+		transform: rotate(135deg);
+	}
+
+
+	.uni-calendar__weeks {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-calendar__weeks-item {
+		flex: 1;
+	}
+
+	.uni-calendar__weeks-day {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		height: 40px;
+		border-bottom-color: #F5F5F5;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+	}
+
+	.uni-calendar__weeks-day-text {
+		font-size: 12px;
+		color: #B2B2B2;
+	}
+
+	.uni-calendar__box {
+		position: relative;
+		// padding: 0 10px;
+		padding-bottom: 7px;
+	}
+
+	.uni-calendar__box-bg {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+	}
+
+	.uni-calendar__box-bg-text {
+		font-size: 200px;
+		font-weight: bold;
+		color: #999;
+		opacity: 0.1;
+		text-align: center;
+		/* #ifndef APP-NVUE */
+		line-height: 1;
+		/* #endif */
+	}
+
+	.uni-date-changed {
+		padding: 0 10px;
+		// line-height: 50px;
+		text-align: center;
+		color: #333;
+		border-top-color: #DCDCDC;
+		;
+		border-top-style: solid;
+		border-top-width: 1px;
+		flex: 1;
+	}
+
+	.uni-date-btn--ok {
+		padding: 20px 15px;
+	}
+
+	.uni-date-changed--time-start {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+	}
+
+	.uni-date-changed--time-end {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+	}
+
+	.uni-date-changed--time-date {
+		color: #999;
+		line-height: 50px;
+		/* #ifdef MP-TOUTIAO */
+		font-size: 16px;
+		/* #endif */
+		margin-right: 5px;
+		// opacity: 0.6;
+	}
+
+	.time-picker-style {
+		// width: 62px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center
+	}
+
+	.mr-10 {
+		margin-right: 10px;
+	}
+
+	.dialog-close {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		padding: 0 25px;
+		margin-top: 10px;
+	}
+
+	.dialog-close-plus {
+		width: 16px;
+		height: 2px;
+		background-color: #737987;
+		border-radius: 2px;
+		transform: rotate(45deg);
+	}
+
+	.dialog-close-rotate {
+		position: absolute;
+		transform: rotate(-45deg);
+	}
+
+	.uni-datetime-picker--btn {
+		border-radius: 100px;
+		height: 40px;
+		line-height: 40px;
+		background-color: $uni-primary;
+		color: #fff;
+		font-size: 16px;
+		letter-spacing: 2px;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-datetime-picker--btn:active {
+		opacity: 0.7;
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json
new file mode 100644
index 0000000..024f22f
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json
@@ -0,0 +1,22 @@
+{
+	"uni-datetime-picker.selectDate": "select date",
+	"uni-datetime-picker.selectTime": "select time",
+	"uni-datetime-picker.selectDateTime": "select date and time",
+	"uni-datetime-picker.startDate": "start date",
+	"uni-datetime-picker.endDate": "end date",
+	"uni-datetime-picker.startTime": "start time",
+	"uni-datetime-picker.endTime": "end time",
+	"uni-datetime-picker.ok": "ok",
+	"uni-datetime-picker.clear": "clear",
+	"uni-datetime-picker.cancel": "cancel",
+	"uni-datetime-picker.year": "-",
+	"uni-datetime-picker.month": "",
+	"uni-calender.MON": "MON",
+	"uni-calender.TUE": "TUE",
+	"uni-calender.WED": "WED",
+	"uni-calender.THU": "THU",
+	"uni-calender.FRI": "FRI",
+	"uni-calender.SAT": "SAT",
+	"uni-calender.SUN": "SUN",
+	"uni-calender.confirm": "confirm"
+}
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json
new file mode 100644
index 0000000..d2df5e7
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json
@@ -0,0 +1,22 @@
+{
+	"uni-datetime-picker.selectDate": "选择日期",
+	"uni-datetime-picker.selectTime": "选择时间",
+	"uni-datetime-picker.selectDateTime": "选择日期时间",
+	"uni-datetime-picker.startDate": "开始日期",
+	"uni-datetime-picker.endDate": "结束日期",
+	"uni-datetime-picker.startTime": "开始时间",
+	"uni-datetime-picker.endTime": "结束时间",
+	"uni-datetime-picker.ok": "确定",
+	"uni-datetime-picker.clear": "清除",
+	"uni-datetime-picker.cancel": "取消",
+	"uni-datetime-picker.year": "年",
+	"uni-datetime-picker.month": "月",
+	"uni-calender.SUN": "日",
+	"uni-calender.MON": "一",
+	"uni-calender.TUE": "二",
+	"uni-calender.WED": "三",
+	"uni-calender.THU": "四",
+	"uni-calender.FRI": "五",
+	"uni-calender.SAT": "六",
+	"uni-calender.confirm": "确认"
+}
\ No newline at end of file
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json
new file mode 100644
index 0000000..d23fa3c
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json
@@ -0,0 +1,22 @@
+{
+  "uni-datetime-picker.selectDate": "選擇日期",
+  "uni-datetime-picker.selectTime": "選擇時間",
+  "uni-datetime-picker.selectDateTime": "選擇日期時間",
+  "uni-datetime-picker.startDate": "開始日期",
+  "uni-datetime-picker.endDate": "結束日期",
+  "uni-datetime-picker.startTime": "開始时间",
+  "uni-datetime-picker.endTime": "結束时间",
+  "uni-datetime-picker.ok": "確定",
+  "uni-datetime-picker.clear": "清除",
+  "uni-datetime-picker.cancel": "取消",
+  "uni-datetime-picker.year": "年",
+  "uni-datetime-picker.month": "月",
+  "uni-calender.SUN": "日",
+  "uni-calender.MON": "一",
+  "uni-calender.TUE": "二",
+  "uni-calender.WED": "三",
+  "uni-calender.THU": "四",
+  "uni-calender.FRI": "五",
+  "uni-calender.SAT": "六",
+  "uni-calender.confirm": "確認"
+}
\ No newline at end of file
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
new file mode 100644
index 0000000..1817692
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
@@ -0,0 +1,940 @@
+<template>
+	<view class="uni-datetime-picker">
+		<view @click="initTimePicker">
+			<slot>
+				<view class="uni-datetime-picker-timebox-pointer"
+					:class="{'uni-datetime-picker-disabled': disabled, 'uni-datetime-picker-timebox': border}">
+					<text class="uni-datetime-picker-text">{{time}}</text>
+					<view v-if="!time" class="uni-datetime-picker-time">
+						<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
+					</view>
+				</view>
+			</slot>
+		</view>
+		<view v-if="visible" id="mask" class="uni-datetime-picker-mask" @click="tiggerTimePicker"></view>
+		<view v-if="visible" class="uni-datetime-picker-popup" :class="[dateShow && timeShow ? '' : 'fix-nvue-height']"
+			:style="fixNvueBug">
+			<view class="uni-title">
+				<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
+			</view>
+			<view v-if="dateShow" class="uni-datetime-picker__container-box">
+				<picker-view class="uni-datetime-picker-view" :indicator-style="indicatorStyle" :value="ymd"
+					@change="bindDateChange">
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in years" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in months" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in days" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+				</picker-view>
+				<!-- 兼容 nvue 不支持伪类 -->
+				<text class="uni-datetime-picker-sign sign-left">-</text>
+				<text class="uni-datetime-picker-sign sign-right">-</text>
+			</view>
+			<view v-if="timeShow" class="uni-datetime-picker__container-box">
+				<picker-view class="uni-datetime-picker-view" :class="[hideSecond ? 'time-hide-second' : '']"
+					:indicator-style="indicatorStyle" :value="hms" @change="bindTimeChange">
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in hours" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in minutes" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column v-if="!hideSecond">
+						<view class="uni-datetime-picker-item" v-for="(item,index) in seconds" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+				</picker-view>
+				<!-- 兼容 nvue 不支持伪类 -->
+				<text class="uni-datetime-picker-sign" :class="[hideSecond ? 'sign-center' : 'sign-left']">:</text>
+				<text v-if="!hideSecond" class="uni-datetime-picker-sign sign-right">:</text>
+			</view>
+			<view class="uni-datetime-picker-btn">
+				<view @click="clearTime">
+					<text class="uni-datetime-picker-btn-text">{{clearText}}</text>
+				</view>
+				<view class="uni-datetime-picker-btn-group">
+					<view class="uni-datetime-picker-cancel" @click="tiggerTimePicker">
+						<text class="uni-datetime-picker-btn-text">{{cancelText}}</text>
+					</view>
+					<view @click="setTime">
+						<text class="uni-datetime-picker-btn-text">{{okText}}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(i18nMessages)
+	import {
+		fixIosDateFormat
+	} from './util'
+
+	/**
+	 * DatetimePicker 时间选择器
+	 * @description 可以同时选择日期和时间的选择器
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
+	 * @property {String} type = [datetime | date | time] 显示模式
+	 * @property {Boolean} multiple = [true|false] 是否多选
+	 * @property {String|Number} value 默认值
+	 * @property {String|Number} start 起始日期或时间
+	 * @property {String|Number} end 起始日期或时间
+	 * @property {String} return-type = [timestamp | string]
+	 * @event {Function} change  选中发生变化触发
+	 */
+
+	export default {
+		name: 'UniDatetimePicker',
+		data() {
+			return {
+				indicatorStyle: `height: 50px;`,
+				visible: false,
+				fixNvueBug: {},
+				dateShow: true,
+				timeShow: true,
+				title: '日期和时间',
+				// 输入框当前时间
+				time: '',
+				// 当前的年月日时分秒
+				year: 1920,
+				month: 0,
+				day: 0,
+				hour: 0,
+				minute: 0,
+				second: 0,
+				// 起始时间
+				startYear: 1920,
+				startMonth: 1,
+				startDay: 1,
+				startHour: 0,
+				startMinute: 0,
+				startSecond: 0,
+				// 结束时间
+				endYear: 2120,
+				endMonth: 12,
+				endDay: 31,
+				endHour: 23,
+				endMinute: 59,
+				endSecond: 59,
+			}
+		},
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		props: {
+			type: {
+				type: String,
+				default: 'datetime'
+			},
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			modelValue: {
+				type: [String, Number],
+				default: ''
+			},
+			start: {
+				type: [Number, String],
+				default: ''
+			},
+			end: {
+				type: [Number, String],
+				default: ''
+			},
+			returnType: {
+				type: String,
+				default: 'string'
+			},
+			disabled: {
+				type: [Boolean, String],
+				default: false
+			},
+			border: {
+				type: [Boolean, String],
+				default: true
+			},
+			hideSecond: {
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		watch: {
+			// #ifndef VUE3
+			value: {
+				handler(newVal) {
+					if (newVal) {
+						this.parseValue(fixIosDateFormat(newVal))
+						this.initTime(false)
+					} else {
+						this.time = ''
+						this.parseValue(Date.now())
+					}
+				},
+				immediate: true
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				handler(newVal) {
+					if (newVal) {
+						this.parseValue(fixIosDateFormat(newVal))
+						this.initTime(false)
+					} else {
+						this.time = ''
+						this.parseValue(Date.now())
+					}
+				},
+				immediate: true
+			},
+			// #endif
+			type: {
+				handler(newValue) {
+					if (newValue === 'date') {
+						this.dateShow = true
+						this.timeShow = false
+						this.title = '日期'
+					} else if (newValue === 'time') {
+						this.dateShow = false
+						this.timeShow = true
+						this.title = '时间'
+					} else {
+						this.dateShow = true
+						this.timeShow = true
+						this.title = '日期和时间'
+					}
+				},
+				immediate: true
+			},
+			start: {
+				handler(newVal) {
+					this.parseDatetimeRange(fixIosDateFormat(newVal), 'start')
+				},
+				immediate: true
+			},
+			end: {
+				handler(newVal) {
+					this.parseDatetimeRange(fixIosDateFormat(newVal), 'end')
+				},
+				immediate: true
+			},
+
+			// 月、日、时、分、秒可选范围变化后,检查当前值是否在范围内,不在则当前值重置为可选范围第一项
+			months(newVal) {
+				this.checkValue('month', this.month, newVal)
+			},
+			days(newVal) {
+				this.checkValue('day', this.day, newVal)
+			},
+			hours(newVal) {
+				this.checkValue('hour', this.hour, newVal)
+			},
+			minutes(newVal) {
+				this.checkValue('minute', this.minute, newVal)
+			},
+			seconds(newVal) {
+				this.checkValue('second', this.second, newVal)
+			}
+		},
+		computed: {
+			// 当前年、月、日、时、分、秒选择范围
+			years() {
+				return this.getCurrentRange('year')
+			},
+
+			months() {
+				return this.getCurrentRange('month')
+			},
+
+			days() {
+				return this.getCurrentRange('day')
+			},
+
+			hours() {
+				return this.getCurrentRange('hour')
+			},
+
+			minutes() {
+				return this.getCurrentRange('minute')
+			},
+
+			seconds() {
+				return this.getCurrentRange('second')
+			},
+
+			// picker 当前值数组
+			ymd() {
+				return [this.year - this.minYear, this.month - this.minMonth, this.day - this.minDay]
+			},
+			hms() {
+				return [this.hour - this.minHour, this.minute - this.minMinute, this.second - this.minSecond]
+			},
+
+			// 当前 date 是 start
+			currentDateIsStart() {
+				return this.year === this.startYear && this.month === this.startMonth && this.day === this.startDay
+			},
+
+			// 当前 date 是 end
+			currentDateIsEnd() {
+				return this.year === this.endYear && this.month === this.endMonth && this.day === this.endDay
+			},
+
+			// 当前年、月、日、时、分、秒的最小值和最大值
+			minYear() {
+				return this.startYear
+			},
+			maxYear() {
+				return this.endYear
+			},
+			minMonth() {
+				if (this.year === this.startYear) {
+					return this.startMonth
+				} else {
+					return 1
+				}
+			},
+			maxMonth() {
+				if (this.year === this.endYear) {
+					return this.endMonth
+				} else {
+					return 12
+				}
+			},
+			minDay() {
+				if (this.year === this.startYear && this.month === this.startMonth) {
+					return this.startDay
+				} else {
+					return 1
+				}
+			},
+			maxDay() {
+				if (this.year === this.endYear && this.month === this.endMonth) {
+					return this.endDay
+				} else {
+					return this.daysInMonth(this.year, this.month)
+				}
+			},
+			minHour() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart) {
+						return this.startHour
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					return this.startHour
+				}
+			},
+			maxHour() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd) {
+						return this.endHour
+					} else {
+						return 23
+					}
+				}
+				if (this.type === 'time') {
+					return this.endHour
+				}
+			},
+			minMinute() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart && this.hour === this.startHour) {
+						return this.startMinute
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.startHour) {
+						return this.startMinute
+					} else {
+						return 0
+					}
+				}
+			},
+			maxMinute() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd && this.hour === this.endHour) {
+						return this.endMinute
+					} else {
+						return 59
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.endHour) {
+						return this.endMinute
+					} else {
+						return 59
+					}
+				}
+			},
+			minSecond() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart && this.hour === this.startHour && this.minute === this.startMinute) {
+						return this.startSecond
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.startHour && this.minute === this.startMinute) {
+						return this.startSecond
+					} else {
+						return 0
+					}
+				}
+			},
+			maxSecond() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd && this.hour === this.endHour && this.minute === this.endMinute) {
+						return this.endSecond
+					} else {
+						return 59
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.endHour && this.minute === this.endMinute) {
+						return this.endSecond
+					} else {
+						return 59
+					}
+				}
+			},
+
+			/**
+			 * for i18n
+			 */
+			selectTimeText() {
+				return t("uni-datetime-picker.selectTime")
+			},
+			okText() {
+				return t("uni-datetime-picker.ok")
+			},
+			clearText() {
+				return t("uni-datetime-picker.clear")
+			},
+			cancelText() {
+				return t("uni-datetime-picker.cancel")
+			}
+		},
+
+		mounted() {
+			// #ifdef APP-NVUE
+			const res = uni.getSystemInfoSync();
+			this.fixNvueBug = {
+				top: res.windowHeight / 2,
+				left: res.windowWidth / 2
+			}
+			// #endif
+		},
+
+		methods: {
+			/**
+			 * @param {Object} item
+			 * 小于 10 在前面加个 0
+			 */
+
+			lessThanTen(item) {
+				return item < 10 ? '0' + item : item
+			},
+
+			/**
+			 * 解析时分秒字符串,例如:00:00:00
+			 * @param {String} timeString
+			 */
+			parseTimeType(timeString) {
+				if (timeString) {
+					let timeArr = timeString.split(':')
+					this.hour = Number(timeArr[0])
+					this.minute = Number(timeArr[1])
+					this.second = Number(timeArr[2])
+				}
+			},
+
+			/**
+			 * 解析选择器初始值,类型可以是字符串、时间戳,例如:2000-10-02、'08:30:00'、 1610695109000
+			 * @param {String | Number} datetime
+			 */
+			initPickerValue(datetime) {
+				let defaultValue = null
+				if (datetime) {
+					defaultValue = this.compareValueWithStartAndEnd(datetime, this.start, this.end)
+				} else {
+					defaultValue = Date.now()
+					defaultValue = this.compareValueWithStartAndEnd(defaultValue, this.start, this.end)
+				}
+				this.parseValue(defaultValue)
+			},
+
+			/**
+			 * 初始值规则:
+			 * - 用户设置初始值 value
+			 * 	- 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start
+			 * 	- 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start
+			 * 	- 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end
+			 * 	- 无起始终止时间,则初始值为 value
+			 * - 无初始值 value,则初始值为当前本地时间 Date.now()
+			 * @param {Object} value
+			 * @param {Object} dateBase
+			 */
+			compareValueWithStartAndEnd(value, start, end) {
+				let winner = null
+				value = this.superTimeStamp(value)
+				start = this.superTimeStamp(start)
+				end = this.superTimeStamp(end)
+
+				if (start && end) {
+					if (value < start) {
+						winner = new Date(start)
+					} else if (value > end) {
+						winner = new Date(end)
+					} else {
+						winner = new Date(value)
+					}
+				} else if (start && !end) {
+					winner = start <= value ? new Date(value) : new Date(start)
+				} else if (!start && end) {
+					winner = value <= end ? new Date(value) : new Date(end)
+				} else {
+					winner = new Date(value)
+				}
+
+				return winner
+			},
+
+			/**
+			 * 转换为可比较的时间戳,接受日期、时分秒、时间戳
+			 * @param {Object} value
+			 */
+			superTimeStamp(value) {
+				let dateBase = ''
+				if (this.type === 'time' && value && typeof value === 'string') {
+					const now = new Date()
+					const year = now.getFullYear()
+					const month = now.getMonth() + 1
+					const day = now.getDate()
+					dateBase = year + '/' + month + '/' + day + ' '
+				}
+				if (Number(value)) {
+					value = parseInt(value)
+					dateBase = 0
+				}
+				return this.createTimeStamp(dateBase + value)
+			},
+
+			/**
+			 * 解析默认值 value,字符串、时间戳
+			 * @param {Object} defaultTime
+			 */
+			parseValue(value) {
+				if (!value) {
+					return
+				}
+				if (this.type === 'time' && typeof value === "string") {
+					this.parseTimeType(value)
+				} else {
+					let defaultDate = null
+					defaultDate = new Date(value)
+					if (this.type !== 'time') {
+						this.year = defaultDate.getFullYear()
+						this.month = defaultDate.getMonth() + 1
+						this.day = defaultDate.getDate()
+					}
+					if (this.type !== 'date') {
+						this.hour = defaultDate.getHours()
+						this.minute = defaultDate.getMinutes()
+						this.second = defaultDate.getSeconds()
+					}
+				}
+				if (this.hideSecond) {
+					this.second = 0
+				}
+			},
+
+			/**
+			 * 解析可选择时间范围 start、end,年月日字符串、时间戳
+			 * @param {Object} defaultTime
+			 */
+			parseDatetimeRange(point, pointType) {
+				// 时间为空,则重置为初始值
+				if (!point) {
+					if (pointType === 'start') {
+						this.startYear = 1920
+						this.startMonth = 1
+						this.startDay = 1
+						this.startHour = 0
+						this.startMinute = 0
+						this.startSecond = 0
+					}
+					if (pointType === 'end') {
+						this.endYear = 2120
+						this.endMonth = 12
+						this.endDay = 31
+						this.endHour = 23
+						this.endMinute = 59
+						this.endSecond = 59
+					}
+					return
+				}
+				if (this.type === 'time') {
+					const pointArr = point.split(':')
+					this[pointType + 'Hour'] = Number(pointArr[0])
+					this[pointType + 'Minute'] = Number(pointArr[1])
+					this[pointType + 'Second'] = Number(pointArr[2])
+				} else {
+					if (!point) {
+						pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60
+						return
+					}
+					if (Number(point)) {
+						point = parseInt(point)
+					}
+					// datetime 的 end 没有时分秒, 则不限制
+					const hasTime = /[0-9]:[0-9]/
+					if (this.type === 'datetime' && pointType === 'end' && typeof point === 'string' && !hasTime.test(
+							point)) {
+						point = point + ' 23:59:59'
+					}
+					const pointDate = new Date(point)
+					this[pointType + 'Year'] = pointDate.getFullYear()
+					this[pointType + 'Month'] = pointDate.getMonth() + 1
+					this[pointType + 'Day'] = pointDate.getDate()
+					if (this.type === 'datetime') {
+						this[pointType + 'Hour'] = pointDate.getHours()
+						this[pointType + 'Minute'] = pointDate.getMinutes()
+						this[pointType + 'Second'] = pointDate.getSeconds()
+					}
+				}
+			},
+
+			// 获取 年、月、日、时、分、秒 当前可选范围
+			getCurrentRange(value) {
+				const range = []
+				for (let i = this['min' + this.capitalize(value)]; i <= this['max' + this.capitalize(value)]; i++) {
+					range.push(i)
+				}
+				return range
+			},
+
+			// 字符串首字母大写
+			capitalize(str) {
+				return str.charAt(0).toUpperCase() + str.slice(1)
+			},
+
+			// 检查当前值是否在范围内,不在则当前值重置为可选范围第一项
+			checkValue(name, value, values) {
+				if (values.indexOf(value) === -1) {
+					this[name] = values[0]
+				}
+			},
+
+			// 每个月的实际天数
+			daysInMonth(year, month) { // Use 1 for January, 2 for February, etc.
+				return new Date(year, month, 0).getDate();
+			},
+
+			/**
+			 * 生成时间戳
+			 * @param {Object} time
+			 */
+			createTimeStamp(time) {
+				if (!time) return
+				if (typeof time === "number") {
+					return time
+				} else {
+					time = time.replace(/-/g, '/')
+					if (this.type === 'date') {
+						time = time + ' ' + '00:00:00'
+					}
+					return Date.parse(time)
+				}
+			},
+
+			/**
+			 * 生成日期或时间的字符串
+			 */
+			createDomSting() {
+				const yymmdd = this.year +
+					'-' +
+					this.lessThanTen(this.month) +
+					'-' +
+					this.lessThanTen(this.day)
+
+				let hhmmss = this.lessThanTen(this.hour) +
+					':' +
+					this.lessThanTen(this.minute)
+
+				if (!this.hideSecond) {
+					hhmmss = hhmmss + ':' + this.lessThanTen(this.second)
+				}
+
+				if (this.type === 'date') {
+					return yymmdd
+				} else if (this.type === 'time') {
+					return hhmmss
+				} else {
+					return yymmdd + ' ' + hhmmss
+				}
+			},
+
+			/**
+			 * 初始化返回值,并抛出 change 事件
+			 */
+			initTime(emit = true) {
+				this.time = this.createDomSting()
+				if (!emit) return
+				if (this.returnType === 'timestamp' && this.type !== 'time') {
+					this.$emit('change', this.createTimeStamp(this.time))
+					this.$emit('input', this.createTimeStamp(this.time))
+					this.$emit('update:modelValue', this.createTimeStamp(this.time))
+				} else {
+					this.$emit('change', this.time)
+					this.$emit('input', this.time)
+					this.$emit('update:modelValue', this.time)
+				}
+			},
+
+			/**
+			 * 用户选择日期或时间更新 data
+			 * @param {Object} e
+			 */
+			bindDateChange(e) {
+				const val = e.detail.value
+				this.year = this.years[val[0]]
+				this.month = this.months[val[1]]
+				this.day = this.days[val[2]]
+			},
+			bindTimeChange(e) {
+				const val = e.detail.value
+				this.hour = this.hours[val[0]]
+				this.minute = this.minutes[val[1]]
+				this.second = this.seconds[val[2]]
+			},
+
+			/**
+			 * 初始化弹出层
+			 */
+			initTimePicker() {
+				if (this.disabled) return
+				const value = fixIosDateFormat(this.time)
+				this.initPickerValue(value)
+				this.visible = !this.visible
+			},
+
+			/**
+			 * 触发或关闭弹框
+			 */
+			tiggerTimePicker(e) {
+				this.visible = !this.visible
+			},
+
+			/**
+			 * 用户点击“清空”按钮,清空当前值
+			 */
+			clearTime() {
+				this.time = ''
+				this.$emit('change', this.time)
+				this.$emit('input', this.time)
+				this.$emit('update:modelValue', this.time)
+				this.tiggerTimePicker()
+			},
+
+			/**
+			 * 用户点击“确定”按钮
+			 */
+			setTime() {
+				this.initTime()
+				this.tiggerTimePicker()
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #007aff !default;
+
+	.uni-datetime-picker {
+		/* #ifndef APP-NVUE */
+		/* width: 100%; */
+		/* #endif */
+	}
+
+	.uni-datetime-picker-view {
+		height: 130px;
+		width: 270px;
+		/* #ifndef APP-NVUE */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-item {
+		height: 50px;
+		line-height: 50px;
+		text-align: center;
+		font-size: 14px;
+	}
+
+	.uni-datetime-picker-btn {
+		margin-top: 60px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		cursor: pointer;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+	}
+
+	.uni-datetime-picker-btn-text {
+		font-size: 14px;
+		color: $uni-primary;
+	}
+
+	.uni-datetime-picker-btn-group {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-datetime-picker-cancel {
+		margin-right: 30px;
+	}
+
+	.uni-datetime-picker-mask {
+		position: fixed;
+		bottom: 0px;
+		top: 0px;
+		left: 0px;
+		right: 0px;
+		background-color: rgba(0, 0, 0, 0.4);
+		transition-duration: 0.3s;
+		z-index: 998;
+	}
+
+	.uni-datetime-picker-popup {
+		border-radius: 8px;
+		padding: 30px;
+		width: 270px;
+		/* #ifdef APP-NVUE */
+		height: 500px;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		width: 330px;
+		/* #endif */
+		background-color: #fff;
+		position: fixed;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%);
+		transition-duration: 0.3s;
+		z-index: 999;
+	}
+
+	.fix-nvue-height {
+		/* #ifdef APP-NVUE */
+		height: 330px;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-time {
+		color: grey;
+	}
+
+	.uni-datetime-picker-column {
+		height: 50px;
+	}
+
+	.uni-datetime-picker-timebox {
+
+		border: 1px solid #E5E5E5;
+		border-radius: 5px;
+		padding: 7px 10px;
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-timebox-pointer {
+		/* #ifndef APP-NVUE */
+		cursor: pointer;
+		/* #endif */
+	}
+
+
+	.uni-datetime-picker-disabled {
+		opacity: 0.4;
+		/* #ifdef H5 */
+		cursor: not-allowed !important;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-text {
+		font-size: 14px;
+		line-height: 50px
+	}
+
+	.uni-datetime-picker-sign {
+		position: absolute;
+		top: 53px;
+		/* 减掉 10px 的元素高度,兼容nvue */
+		color: #999;
+		/* #ifdef APP-NVUE */
+		font-size: 16px;
+		/* #endif */
+	}
+
+	.sign-left {
+		left: 86px;
+	}
+
+	.sign-right {
+		right: 86px;
+	}
+
+	.sign-center {
+		left: 135px;
+	}
+
+	.uni-datetime-picker__container-box {
+		position: relative;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		margin-top: 40px;
+	}
+
+	.time-hide-second {
+		width: 180px;
+	}
+</style>
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
new file mode 100644
index 0000000..6843e80
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
@@ -0,0 +1,1064 @@
+<template>
+	<view class="uni-date">
+		<view class="uni-date-editor" @click="show">
+			<slot>
+				<view class="uni-date-editor--x"
+					:class="{'uni-date-editor--x__disabled': disabled,'uni-date-x--border': border}">
+					<view v-if="!isRange" class="uni-date-x uni-date-single">
+						<uni-icons class="icon-calendar" type="calendar" color="#c0c4cc" size="22"></uni-icons>
+						<view class="uni-date__x-input">{{ displayValue || singlePlaceholderText }}</view>
+					</view>
+
+					<view v-else class="uni-date-x uni-date-range">
+						<uni-icons class="icon-calendar" type="calendar" color="#c0c4cc" size="22"></uni-icons>
+						<view class="uni-date__x-input text-center">{{ displayRangeValue.startDate || startPlaceholderText }}</view>
+
+						<view class="range-separator">{{rangeSeparator}}</view>
+
+						<view class="uni-date__x-input text-center">{{ displayRangeValue.endDate || endPlaceholderText }}</view>
+					</view>
+
+					<view v-if="showClearIcon" class="uni-date__icon-clear" @click.stop="clear">
+						<uni-icons type="clear" color="#c0c4cc" size="22"></uni-icons>
+					</view>
+				</view>
+			</slot>
+		</view>
+
+		<view v-show="pickerVisible" class="uni-date-mask--pc" @click="close"></view>
+
+		<view v-if="!isPhone" v-show="pickerVisible" ref="datePicker" class="uni-date-picker__container">
+			<view v-if="!isRange" class="uni-date-single--x" :style="pickerPositionStyle">
+				<view class="uni-popper__arrow"></view>
+
+				<view v-if="hasTime" class="uni-date-changed popup-x-header">
+					<input class="uni-date__input text-center" type="text" v-model="inputDate" :placeholder="selectDateText" />
+
+					<time-picker type="time" v-model="pickerTime" :border="false" :disabled="!inputDate"
+						:start="timepickerStartTime" :end="timepickerEndTime" :hideSecond="hideSecond" style="width: 100%;">
+						<input class="uni-date__input text-center" type="text" v-model="pickerTime" :placeholder="selectTimeText"
+							:disabled="!inputDate" />
+					</time-picker>
+				</view>
+
+				<Calendar ref="pcSingle" :showMonth="false" :start-date="calendarRange.startDate"
+					:end-date="calendarRange.endDate" :date="calendarDate" @change="singleChange" :default-value="defaultValue"
+					style="padding: 0 8px;" />
+
+				<view v-if="hasTime" class="popup-x-footer">
+					<text class="confirm-text" @click="confirmSingleChange">{{okText}}</text>
+				</view>
+			</view>
+
+			<view v-else class="uni-date-range--x" :style="pickerPositionStyle">
+				<view class="uni-popper__arrow"></view>
+				<view v-if="hasTime" class="popup-x-header uni-date-changed">
+					<view class="popup-x-header--datetime">
+						<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.startDate"
+							:placeholder="startDateText" />
+
+						<time-picker type="time" v-model="tempRange.startTime" :start="timepickerStartTime" :border="false"
+							:disabled="!tempRange.startDate" :hideSecond="hideSecond">
+							<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.startTime"
+								:placeholder="startTimeText" :disabled="!tempRange.startDate" />
+						</time-picker>
+					</view>
+
+					<uni-icons type="arrowthinright" color="#999" style="line-height: 40px;"></uni-icons>
+
+					<view class="popup-x-header--datetime">
+						<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.endDate"
+							:placeholder="endDateText" />
+
+						<time-picker type="time" v-model="tempRange.endTime" :end="timepickerEndTime" :border="false"
+							:disabled="!tempRange.endDate" :hideSecond="hideSecond">
+							<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.endTime"
+								:placeholder="endTimeText" :disabled="!tempRange.endDate" />
+						</time-picker>
+					</view>
+				</view>
+
+				<view class="popup-x-body">
+					<Calendar ref="left" :showMonth="false" :start-date="calendarRange.startDate"
+						:end-date="calendarRange.endDate" :range="true" :pleStatus="endMultipleStatus" @change="leftChange"
+						@firstEnterCale="updateRightCale" style="padding: 0 8px;"/>
+					<Calendar ref="right" :showMonth="false" :start-date="calendarRange.startDate"
+						:end-date="calendarRange.endDate" :range="true" @change="rightChange" :pleStatus="startMultipleStatus"
+						@firstEnterCale="updateLeftCale" style="padding: 0 8px;border-left: 1px solid #F1F1F1;" />
+				</view>
+
+				<view v-if="hasTime" class="popup-x-footer">
+					<text @click="clear">{{clearText}}</text>
+					<text class="confirm-text" @click="confirmRangeChange">{{okText}}</text>
+				</view>
+			</view>
+		</view>
+
+		<Calendar v-if="isPhone" ref="mobile" :clearDate="false" :date="calendarDate" :defTime="mobileCalendarTime"
+			:start-date="calendarRange.startDate" :end-date="calendarRange.endDate" :selectableTimes="mobSelectableTime"
+			:startPlaceholder="startPlaceholder" :endPlaceholder="endPlaceholder" :default-value="defaultValue"
+			:pleStatus="endMultipleStatus" :showMonth="false" :range="isRange" :hasTime="hasTime" :insert="false"
+			:hideSecond="hideSecond" @confirm="mobileChange" @maskClose="close" @change="calendarClick"/>
+	</view>
+</template>
+<script>
+	/**
+	 * DatetimePicker 时间选择器
+	 * @description 同时支持 PC 和移动端使用日历选择日期和日期范围
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3962
+	 * @property {String} type 选择器类型
+	 * @property {String|Number|Array|Date} value 绑定值
+	 * @property {String} placeholder 单选择时的占位内容
+	 * @property {String} start 起始时间
+	 * @property {String} end 终止时间
+	 * @property {String} start-placeholder 范围选择时开始日期的占位内容
+	 * @property {String} end-placeholder 范围选择时结束日期的占位内容
+	 * @property {String} range-separator 选择范围时的分隔符
+	 * @property {Boolean} border = [true|false] 是否有边框
+	 * @property {Boolean} disabled = [true|false] 是否禁用
+	 * @property {Boolean} clearIcon = [true|false] 是否显示清除按钮(仅PC端适用)
+	 * @property {[String} defaultValue 选择器打开时默认显示的时间
+	 * @event {Function} change 确定日期时触发的事件
+	 * @event {Function} maskClick 点击遮罩层触发的事件
+	 * @event {Function} show 打开弹出层
+	 * @event {Function} close 关闭弹出层
+	 * @event {Function} clear 清除上次选中的状态和值
+	 **/
+	import Calendar from './calendar.vue'
+	import TimePicker from './time-picker.vue'
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	import {
+		getDateTime,
+		getDate,
+		getTime,
+		getDefaultSecond,
+		dateCompare,
+		checkDate,
+		fixIosDateFormat
+	} from './util'
+
+	export default {
+		name: 'UniDatetimePicker',
+
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		components: {
+			Calendar,
+			TimePicker
+		},
+		data() {
+			return {
+				isRange: false,
+				hasTime: false,
+				displayValue: '',
+				inputDate: '',
+				calendarDate: '',
+				pickerTime: '',
+				calendarRange: {
+					startDate: '',
+					startTime: '',
+					endDate: '',
+					endTime: ''
+				},
+				displayRangeValue: {
+					startDate: '',
+					endDate: '',
+				},
+				tempRange: {
+					startDate: '',
+					startTime: '',
+					endDate: '',
+					endTime: ''
+				},
+				// 左右日历同步数据
+				startMultipleStatus: {
+					before: '',
+					after: '',
+					data: [],
+					fulldate: ''
+				},
+				endMultipleStatus: {
+					before: '',
+					after: '',
+					data: [],
+					fulldate: ''
+				},
+				pickerVisible: false,
+				pickerPositionStyle: null,
+				isEmitValue: false,
+				isPhone: false,
+				isFirstShow: true,
+				i18nT: () => {}
+			}
+		},
+		props: {
+			type: {
+				type: String,
+				default: 'datetime'
+			},
+			value: {
+				type: [String, Number, Array, Date],
+				default: ''
+			},
+			modelValue: {
+				type: [String, Number, Array, Date],
+				default: ''
+			},
+			start: {
+				type: [Number, String],
+				default: ''
+			},
+			end: {
+				type: [Number, String],
+				default: ''
+			},
+			returnType: {
+				type: String,
+				default: 'string'
+			},
+			placeholder: {
+				type: String,
+				default: ''
+			},
+			startPlaceholder: {
+				type: String,
+				default: ''
+			},
+			endPlaceholder: {
+				type: String,
+				default: ''
+			},
+			rangeSeparator: {
+				type: String,
+				default: '-'
+			},
+			border: {
+				type: [Boolean],
+				default: true
+			},
+			disabled: {
+				type: [Boolean],
+				default: false
+			},
+			clearIcon: {
+				type: [Boolean],
+				default: true
+			},
+			hideSecond: {
+				type: [Boolean],
+				default: false
+			},
+			defaultValue: {
+				type: [String, Object, Array],
+				default: ''
+			}
+		},
+		watch: {
+			type: {
+				immediate: true,
+				handler(newVal) {
+					this.hasTime = newVal.indexOf('time') !== -1
+					this.isRange = newVal.indexOf('range') !== -1
+				}
+			},
+			// #ifndef VUE3
+			value: {
+				immediate: true,
+				handler(newVal) {
+					if (this.isEmitValue) {
+						this.isEmitValue = false
+						return
+					}
+					this.initPicker(newVal)
+				}
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				immediate: true,
+				handler(newVal) {
+					if (this.isEmitValue) {
+						this.isEmitValue = false
+						return
+					}
+					this.initPicker(newVal)
+				}
+			},
+			// #endif
+			start: {
+				immediate: true,
+				handler(newVal) {
+					if (!newVal) return
+					this.calendarRange.startDate = getDate(newVal)
+					if (this.hasTime) {
+						this.calendarRange.startTime = getTime(newVal)
+					}
+				}
+			},
+			end: {
+				immediate: true,
+				handler(newVal) {
+					if (!newVal) return
+					this.calendarRange.endDate = getDate(newVal)
+					if (this.hasTime) {
+						this.calendarRange.endTime = getTime(newVal, this.hideSecond)
+					}
+				}
+			},
+		},
+		computed: {
+			timepickerStartTime() {
+				const activeDate = this.isRange ? this.tempRange.startDate : this.inputDate
+				return activeDate === this.calendarRange.startDate ? this.calendarRange.startTime : ''
+			},
+			timepickerEndTime() {
+				const activeDate = this.isRange ? this.tempRange.endDate : this.inputDate
+				return activeDate === this.calendarRange.endDate ? this.calendarRange.endTime : ''
+			},
+			mobileCalendarTime() {
+				const timeRange = {
+					start: this.tempRange.startTime,
+					end: this.tempRange.endTime
+				}
+				return this.isRange ? timeRange : this.pickerTime
+			},
+			mobSelectableTime() {
+				return {
+					start: this.calendarRange.startTime,
+					end: this.calendarRange.endTime
+				}
+			},
+			datePopupWidth() {
+				// todo
+				return this.isRange ? 653 : 301
+			},
+
+			/**
+			 * for i18n
+			 */
+			singlePlaceholderText() {
+				return this.placeholder || (this.type === 'date' ? this.selectDateText : this.selectDateTimeText)
+			},
+			startPlaceholderText() {
+				return this.startPlaceholder || this.startDateText
+			},
+			endPlaceholderText() {
+				return this.endPlaceholder || this.endDateText
+			},
+			selectDateText() {
+				return this.i18nT("uni-datetime-picker.selectDate")
+			},
+			selectDateTimeText() {
+				return this.i18nT("uni-datetime-picker.selectDateTime")
+			},
+			selectTimeText() {
+				return this.i18nT("uni-datetime-picker.selectTime")
+			},
+			startDateText() {
+				return this.startPlaceholder || this.i18nT("uni-datetime-picker.startDate")
+			},
+			startTimeText() {
+				return this.i18nT("uni-datetime-picker.startTime")
+			},
+			endDateText() {
+				return this.endPlaceholder || this.i18nT("uni-datetime-picker.endDate")
+			},
+			endTimeText() {
+				return this.i18nT("uni-datetime-picker.endTime")
+			},
+			okText() {
+				return this.i18nT("uni-datetime-picker.ok")
+			},
+			clearText() {
+				return this.i18nT("uni-datetime-picker.clear")
+			},
+			showClearIcon() {
+				return this.clearIcon && !this.disabled && (this.displayValue || (this.displayRangeValue.startDate && this
+					.displayRangeValue.endDate))
+			}
+		},
+		created() {
+			this.initI18nT()
+			this.platform()
+		},
+		methods: {
+			initI18nT() {
+				const vueI18n = initVueI18n(i18nMessages)
+				this.i18nT = vueI18n.t
+			},
+			initPicker(newVal) {
+				if ((!newVal && !this.defaultValue) || Array.isArray(newVal) && !newVal.length) {
+					this.$nextTick(() => {
+						this.clear(false)
+					})
+					return
+				}
+
+				if (!Array.isArray(newVal) && !this.isRange) {
+					if (newVal) {
+						this.displayValue = this.inputDate = this.calendarDate = getDate(newVal)
+						if (this.hasTime) {
+							this.pickerTime = getTime(newVal, this.hideSecond)
+							this.displayValue = `${this.displayValue} ${this.pickerTime}`
+						}
+					} else if (this.defaultValue) {
+						this.inputDate = this.calendarDate = getDate(this.defaultValue)
+						if (this.hasTime) {
+							this.pickerTime = getTime(this.defaultValue, this.hideSecond)
+						}
+					}
+				} else {
+					const [before, after] = newVal
+					if (!before && !after) return
+					const beforeDate = getDate(before)
+					const beforeTime = getTime(before, this.hideSecond)
+
+					const afterDate = getDate(after)
+					const afterTime = getTime(after, this.hideSecond)
+					const startDate = beforeDate
+					const endDate = afterDate
+					this.displayRangeValue.startDate = this.tempRange.startDate = startDate
+					this.displayRangeValue.endDate = this.tempRange.endDate = endDate
+
+					if (this.hasTime) {
+						this.displayRangeValue.startDate = `${beforeDate} ${beforeTime}`
+						this.displayRangeValue.endDate = `${afterDate} ${afterTime}`
+						this.tempRange.startTime = beforeTime
+						this.tempRange.endTime = afterTime
+					}
+					const defaultRange = {
+						before: beforeDate,
+						after: afterDate
+					}
+					this.startMultipleStatus = Object.assign({}, this.startMultipleStatus, defaultRange, {
+						which: 'right'
+					})
+					this.endMultipleStatus = Object.assign({}, this.endMultipleStatus, defaultRange, {
+						which: 'left'
+					})
+				}
+			},
+			updateLeftCale(e) {
+				const left = this.$refs.left
+				// 设置范围选
+				left.cale.setHoverMultiple(e.after)
+				left.setDate(this.$refs.left.nowDate.fullDate)
+			},
+			updateRightCale(e) {
+				const right = this.$refs.right
+				// 设置范围选
+				right.cale.setHoverMultiple(e.after)
+				right.setDate(this.$refs.right.nowDate.fullDate)
+			},
+			platform() {
+				if (typeof navigator !== "undefined") {
+					this.isPhone = navigator.userAgent.toLowerCase().indexOf('mobile') !== -1
+					return
+				}
+				// #ifdef MP-WEIXIN
+				const {
+					windowWidth
+				} = uni.getWindowInfo()
+				// #endif
+				// #ifndef MP-WEIXIN
+				const {
+					windowWidth
+				} = uni.getSystemInfoSync()
+				// #endif
+				this.isPhone = windowWidth <= 500
+				this.windowWidth = windowWidth
+			},
+			show() {
+				this.$emit("show")
+				if (this.disabled) {
+					return
+				}
+				this.platform()
+				if (this.isPhone) {
+					setTimeout(() => {
+						this.$refs.mobile.open()
+					}, 0);
+					return
+				}
+				this.pickerPositionStyle = {
+					top: '10px'
+				}
+				const dateEditor = uni.createSelectorQuery().in(this).select(".uni-date-editor")
+				dateEditor.boundingClientRect(rect => {
+					if (this.windowWidth - rect.left < this.datePopupWidth) {
+						this.pickerPositionStyle.right = 0
+					}
+				}).exec()
+				setTimeout(() => {
+					this.pickerVisible = !this.pickerVisible
+					if (!this.isPhone && this.isRange && this.isFirstShow) {
+						this.isFirstShow = false
+						const {
+							startDate,
+							endDate
+						} = this.calendarRange
+						if (startDate && endDate) {
+							if (this.diffDate(startDate, endDate) < 30) {
+								this.$refs.right.changeMonth('pre')
+							}
+						} else {
+							// this.$refs.right.changeMonth('next')
+							if (this.isPhone) {
+								this.$refs.right.cale.lastHover = false;
+							}
+						}
+					}
+
+				}, 50)
+			},
+			close() {
+				setTimeout(() => {
+					this.pickerVisible = false
+					this.$emit('maskClick', this.value)
+					this.$refs.mobile && this.$refs.mobile.close()
+				}, 20)
+			},
+			setEmit(value) {
+				if (this.returnType === "timestamp" || this.returnType === "date") {
+					if (!Array.isArray(value)) {
+						if (!this.hasTime) {
+							value = value + ' ' + '00:00:00'
+						}
+						value = this.createTimestamp(value)
+						if (this.returnType === "date") {
+							value = new Date(value)
+						}
+					} else {
+						if (!this.hasTime) {
+							value[0] = value[0] + ' ' + '00:00:00'
+							value[1] = value[1] + ' ' + '00:00:00'
+						}
+						value[0] = this.createTimestamp(value[0])
+						value[1] = this.createTimestamp(value[1])
+						if (this.returnType === "date") {
+							value[0] = new Date(value[0])
+							value[1] = new Date(value[1])
+						}
+					}
+				}
+
+				this.$emit('update:modelValue', value)
+				this.$emit('input', value)
+				this.$emit('change', value)
+				this.isEmitValue = true
+			},
+			createTimestamp(date) {
+				date = fixIosDateFormat(date)
+				return Date.parse(new Date(date))
+			},
+			singleChange(e) {
+				this.calendarDate = this.inputDate = e.fulldate
+				if (this.hasTime) return
+				this.confirmSingleChange()
+			},
+			confirmSingleChange() {
+				if (!checkDate(this.inputDate)) {
+					const now = new Date()
+					this.calendarDate = this.inputDate = getDate(now)
+					this.pickerTime = getTime(now, this.hideSecond)
+				}
+
+				let startLaterInputDate = false
+				let startDate, startTime
+				if (this.start) {
+					let startString = this.start
+					if (typeof this.start === 'number') {
+						startString = getDateTime(this.start, this.hideSecond)
+					}
+					[startDate, startTime] = startString.split(' ')
+					if (this.start && !dateCompare(startDate, this.inputDate)) {
+						startLaterInputDate = true
+						this.inputDate = startDate
+					}
+				}
+
+				let endEarlierInputDate = false
+				let endDate, endTime
+				if (this.end) {
+					let endString = this.end
+					if (typeof this.end === 'number') {
+						endString = getDateTime(this.end, this.hideSecond)
+					}
+					[endDate, endTime] = endString.split(' ')
+					if (this.end && !dateCompare(this.inputDate, endDate)) {
+						endEarlierInputDate = true
+						this.inputDate = endDate
+					}
+				}
+				if (this.hasTime) {
+					if (startLaterInputDate) {
+						this.pickerTime = startTime || getDefaultSecond(this.hideSecond)
+					}
+					if (endEarlierInputDate) {
+						this.pickerTime = endTime || getDefaultSecond(this.hideSecond)
+					}
+					if (!this.pickerTime) {
+						this.pickerTime = getTime(Date.now(), this.hideSecond)
+					}
+					this.displayValue = `${this.inputDate} ${this.pickerTime}`
+				} else {
+					this.displayValue = this.inputDate
+				}
+				this.setEmit(this.displayValue)
+				this.pickerVisible = false
+			},
+			leftChange(e) {
+				const {
+					before,
+					after
+				} = e.range
+				this.rangeChange(before, after)
+				const obj = {
+					before: e.range.before,
+					after: e.range.after,
+					data: e.range.data,
+					fulldate: e.fulldate
+				}
+				this.startMultipleStatus = Object.assign({}, this.startMultipleStatus, obj)
+				this.$emit('calendarClick', e)
+			},
+			rightChange(e) {
+				const {
+					before,
+					after
+				} = e.range
+				this.rangeChange(before, after)
+				const obj = {
+					before: e.range.before,
+					after: e.range.after,
+					data: e.range.data,
+					fulldate: e.fulldate
+				}
+				this.endMultipleStatus = Object.assign({}, this.endMultipleStatus, obj)
+				this.$emit('calendarClick', e)
+			},
+			mobileChange(e) {
+				if (this.isRange) {
+					const {
+						before,
+						after
+					} = e.range
+					if (!before) {
+						return;
+					}
+
+					this.handleStartAndEnd(before, after, true)
+					if (this.hasTime) {
+						const {
+							startTime,
+							endTime
+						} = e.timeRange
+						this.tempRange.startTime = startTime
+						this.tempRange.endTime = endTime
+					}
+					this.confirmRangeChange()
+				} else {
+					if (this.hasTime) {
+						this.displayValue = e.fulldate + ' ' + e.time
+					} else {
+						this.displayValue = e.fulldate
+					}
+					this.setEmit(this.displayValue)
+				}
+				this.$refs.mobile.close()
+			},
+			rangeChange(before, after) {
+				if (!(before && after)) return
+				this.handleStartAndEnd(before, after, true)
+				if (this.hasTime) return
+				this.confirmRangeChange()
+			},
+			confirmRangeChange() {
+				if (!this.tempRange.startDate || !this.tempRange.endDate) {
+					this.pickerVisible = false
+					return
+				}
+				if (!checkDate(this.tempRange.startDate)) {
+					this.tempRange.startDate = getDate(Date.now())
+				}
+				if (!checkDate(this.tempRange.endDate)) {
+					this.tempRange.endDate = getDate(Date.now())
+				}
+
+				let start, end
+
+				let startDateLaterRangeStartDate = false
+				let startDateLaterRangeEndDate = false
+				let startDate, startTime
+				if (this.start) {
+					let startString = this.start
+					if (typeof this.start === 'number') {
+						startString = getDateTime(this.start, this.hideSecond)
+					}
+					[startDate, startTime] = startString.split(' ')
+					if (this.start && !dateCompare(this.start, `${this.tempRange.startDate} ${this.tempRange.startTime}`)) {
+						startDateLaterRangeStartDate = true
+						this.tempRange.startDate = startDate
+					}
+					if (this.start && !dateCompare(this.start, `${this.tempRange.endDate} ${this.tempRange.endTime}`)) {
+						startDateLaterRangeEndDate = true
+						this.tempRange.endDate = startDate
+					}
+				}
+				let endDateEarlierRangeStartDate = false
+				let endDateEarlierRangeEndDate = false
+				let endDate, endTime
+				if (this.end) {
+					let endString = this.end
+					if (typeof this.end === 'number') {
+						endString = getDateTime(this.end, this.hideSecond)
+					}
+					[endDate, endTime] = endString.split(' ')
+
+					if (this.end && !dateCompare(`${this.tempRange.startDate} ${this.tempRange.startTime}`, this.end)) {
+						endDateEarlierRangeStartDate = true
+						this.tempRange.startDate = endDate
+					}
+					if (this.end && !dateCompare(`${this.tempRange.endDate} ${this.tempRange.endTime}`, this.end)) {
+						endDateEarlierRangeEndDate = true
+						this.tempRange.endDate = endDate
+					}
+				}
+				if (!this.hasTime) {
+					start = this.displayRangeValue.startDate = this.tempRange.startDate
+					end = this.displayRangeValue.endDate = this.tempRange.endDate
+				} else {
+					if (startDateLaterRangeStartDate) {
+						this.tempRange.startTime = startTime || getDefaultSecond(this.hideSecond)
+					} else if (endDateEarlierRangeStartDate) {
+						this.tempRange.startTime = endTime || getDefaultSecond(this.hideSecond)
+					}
+					if (!this.tempRange.startTime) {
+						this.tempRange.startTime = getTime(Date.now(), this.hideSecond)
+					}
+
+					if (startDateLaterRangeEndDate) {
+						this.tempRange.endTime = startTime || getDefaultSecond(this.hideSecond)
+					} else if (endDateEarlierRangeEndDate) {
+						this.tempRange.endTime = endTime || getDefaultSecond(this.hideSecond)
+					}
+					if (!this.tempRange.endTime) {
+						this.tempRange.endTime = getTime(Date.now(), this.hideSecond)
+					}
+					start = this.displayRangeValue.startDate = `${this.tempRange.startDate} ${this.tempRange.startTime}`
+					end = this.displayRangeValue.endDate = `${this.tempRange.endDate} ${this.tempRange.endTime}`
+				}
+				if (!dateCompare(start, end)) {
+					[start, end] = [end, start]
+				}
+				this.displayRangeValue.startDate = start
+				this.displayRangeValue.endDate = end
+				const displayRange = [start, end]
+				this.setEmit(displayRange)
+				this.pickerVisible = false
+			},
+			handleStartAndEnd(before, after, temp = false) {
+				if (!before) return
+				if (!after) after = before;
+				const type = temp ? 'tempRange' : 'range'
+				const isStartEarlierEnd = dateCompare(before, after)
+				this[type].startDate = isStartEarlierEnd ? before : after
+				this[type].endDate = isStartEarlierEnd ? after : before
+			},
+			/**
+			 * 比较时间大小
+			 */
+			dateCompare(startDate, endDate) {
+				// 计算截止时间
+				startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+				// 计算详细项的截止时间
+				endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+				return startDate <= endDate
+			},
+
+			/**
+			 * 比较时间差
+			 */
+			diffDate(startDate, endDate) {
+				// 计算截止时间
+				startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+				// 计算详细项的截止时间
+				endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+				const diff = (endDate - startDate) / (24 * 60 * 60 * 1000)
+				return Math.abs(diff)
+			},
+
+			clear(needEmit = true) {
+				if (!this.isRange) {
+					this.displayValue = ''
+					this.inputDate = ''
+					this.pickerTime = ''
+					if (this.isPhone) {
+						this.$refs.mobile && this.$refs.mobile.clearCalender()
+					} else {
+						this.$refs.pcSingle && this.$refs.pcSingle.clearCalender()
+					}
+					if (needEmit) {
+						this.$emit('change', '')
+						this.$emit('input', '')
+						this.$emit('update:modelValue', '')
+					}
+				} else {
+					this.displayRangeValue.startDate = ''
+					this.displayRangeValue.endDate = ''
+					this.tempRange.startDate = ''
+					this.tempRange.startTime = ''
+					this.tempRange.endDate = ''
+					this.tempRange.endTime = ''
+					if (this.isPhone) {
+						this.$refs.mobile && this.$refs.mobile.clearCalender()
+					} else {
+						this.$refs.left && this.$refs.left.clearCalender()
+						this.$refs.right && this.$refs.right.clearCalender()
+						this.$refs.right && this.$refs.right.changeMonth('next')
+					}
+					if (needEmit) {
+						this.$emit('change', [])
+						this.$emit('input', [])
+						this.$emit('update:modelValue', [])
+					}
+				}
+			},
+
+			calendarClick(e) {
+				this.$emit('calendarClick', e)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #007aff !default;
+
+	.uni-date {
+		width: 100%;
+		flex: 1;
+	}
+
+	.uni-date-x {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		border-radius: 4px;
+		background-color: #fff;
+		color: #666;
+		font-size: 14px;
+		flex: 1;
+
+		.icon-calendar {
+			padding-left: 3px;
+		}
+
+		.range-separator {
+			height: 35px;
+			/* #ifndef MP */
+			padding: 0 2px;
+			/* #endif */
+			line-height: 35px;
+		}
+	}
+
+	.uni-date-x--border {
+		box-sizing: border-box;
+		border-radius: 4px;
+		border: 1px solid #e5e5e5;
+	}
+
+	.uni-date-editor--x {
+		display: flex;
+		align-items: center;
+		position: relative;
+	}
+
+	.uni-date-editor--x .uni-date__icon-clear {
+		padding-right: 3px;
+		display: flex;
+		align-items: center;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-date__x-input {
+		width: auto;
+		height: 35px;
+		/* #ifndef MP */
+		padding-left: 5px;
+		/* #endif */
+		position: relative;
+		flex: 1;
+		line-height: 35px;
+		font-size: 14px;
+		overflow: hidden;
+	}
+
+	.text-center {
+		text-align: center;
+	}
+
+	.uni-date__input {
+		height: 40px;
+		width: 100%;
+		line-height: 40px;
+		font-size: 14px;
+	}
+
+	.uni-date-range__input {
+		text-align: center;
+		max-width: 142px;
+	}
+
+	.uni-date-picker__container {
+		position: relative;
+	}
+
+	.uni-date-mask--pc {
+		position: fixed;
+		bottom: 0px;
+		top: 0px;
+		left: 0px;
+		right: 0px;
+		background-color: rgba(0, 0, 0, 0);
+		transition-duration: 0.3s;
+		z-index: 996;
+	}
+
+	.uni-date-single--x {
+		background-color: #fff;
+		position: absolute;
+		top: 0;
+		z-index: 999;
+		border: 1px solid #EBEEF5;
+		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+		border-radius: 4px;
+	}
+
+	.uni-date-range--x {
+		background-color: #fff;
+		position: absolute;
+		top: 0;
+		z-index: 999;
+		border: 1px solid #EBEEF5;
+		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+		border-radius: 4px;
+	}
+
+	.uni-date-editor--x__disabled {
+		opacity: 0.4;
+		cursor: default;
+	}
+
+	.uni-date-editor--logo {
+		width: 16px;
+		height: 16px;
+		vertical-align: middle;
+	}
+
+	/* 添加时间 */
+	.popup-x-header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.popup-x-header--datetime {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex: 1;
+	}
+
+	.popup-x-body {
+		display: flex;
+	}
+
+	.popup-x-footer {
+		padding: 0 15px;
+		border-top-color: #F1F1F1;
+		border-top-style: solid;
+		border-top-width: 1px;
+		line-height: 40px;
+		text-align: right;
+		color: #666;
+	}
+
+	.popup-x-footer text:hover {
+		color: $uni-primary;
+		cursor: pointer;
+		opacity: 0.8;
+	}
+
+	.popup-x-footer .confirm-text {
+		margin-left: 20px;
+		color: $uni-primary;
+	}
+
+	.uni-date-changed {
+		text-align: center;
+		color: #333;
+		border-bottom-color: #F1F1F1;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+	}
+
+	.uni-date-changed--time text {
+		height: 50px;
+		line-height: 50px;
+	}
+
+	.uni-date-changed .uni-date-changed--time {
+		flex: 1;
+	}
+
+	.uni-date-changed--time-date {
+		color: #333;
+		opacity: 0.6;
+	}
+
+	.mr-50 {
+		margin-right: 50px;
+	}
+
+	/* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
+	.uni-popper__arrow,
+	.uni-popper__arrow::after {
+		position: absolute;
+		display: block;
+		width: 0;
+		height: 0;
+		border: 6px solid transparent;
+		border-top-width: 0;
+	}
+
+	.uni-popper__arrow {
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+		top: -6px;
+		left: 10%;
+		margin-right: 3px;
+		border-bottom-color: #EBEEF5;
+	}
+
+	.uni-popper__arrow::after {
+		content: " ";
+		top: 1px;
+		margin-left: -6px;
+		border-bottom-color: #fff;
+	}
+</style>
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
new file mode 100644
index 0000000..6e9f47d
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
@@ -0,0 +1,421 @@
+class Calendar {
+	constructor({
+		selected,
+		startDate,
+		endDate,
+		range,
+	} = {}) {
+		// 当前日期
+		this.date = this.getDateObj(new Date()) // 当前初入日期
+		// 打点信息
+		this.selected = selected || [];
+		// 起始时间
+		this.startDate = startDate
+		// 终止时间
+		this.endDate = endDate
+		// 是否范围选择
+		this.range = range
+		// 多选状态
+		this.cleanMultipleStatus()
+		// 每周日期
+		this.weeks = {}
+		this.lastHover = false
+	}
+	/**
+	 * 设置日期
+	 * @param {Object} date
+	 */
+	setDate(date) {
+		const selectDate = this.getDateObj(date)
+		this.getWeeks(selectDate.fullDate)
+	}
+
+	/**
+	 * 清理多选状态
+	 */
+	cleanMultipleStatus() {
+		this.multipleStatus = {
+			before: '',
+			after: '',
+			data: []
+		}
+	}
+
+	setStartDate(startDate) {
+		this.startDate = startDate
+	}
+
+	setEndDate(endDate) {
+		this.endDate = endDate
+	}
+
+	getPreMonthObj(date) {
+		date = fixIosDateFormat(date)
+		date = new Date(date)
+
+		const oldMonth = date.getMonth()
+		date.setMonth(oldMonth - 1)
+		const newMonth = date.getMonth()
+		if (oldMonth !== 0 && newMonth - oldMonth === 0) {
+			date.setMonth(newMonth - 1)
+		}
+		return this.getDateObj(date)
+	}
+	getNextMonthObj(date) {
+		date = fixIosDateFormat(date)
+		date = new Date(date)
+
+		const oldMonth = date.getMonth()
+		date.setMonth(oldMonth + 1)
+		const newMonth = date.getMonth()
+		if (newMonth - oldMonth > 1) {
+			date.setMonth(newMonth - 1)
+		}
+		return this.getDateObj(date)
+	}
+
+	/**
+	 * 获取指定格式Date对象
+	 */
+	getDateObj(date) {
+		date = fixIosDateFormat(date)
+		date = new Date(date)
+
+		return {
+			fullDate: getDate(date),
+			year: date.getFullYear(),
+			month: addZero(date.getMonth() + 1),
+			date: addZero(date.getDate()),
+			day: date.getDay()
+		}
+	}
+
+	/**
+	 * 获取上一个月日期集合
+	 */
+	getPreMonthDays(amount, dateObj) {
+		const result = []
+		for (let i = amount - 1; i >= 0; i--) {
+			const month = dateObj.month - 1
+			result.push({
+				date: new Date(dateObj.year, month, -i).getDate(),
+				month,
+				disable: true
+			})
+		}
+		return result
+	}
+	/**
+	 * 获取本月日期集合
+	 */
+	getCurrentMonthDays(amount, dateObj) {
+		const result = []
+		const fullDate = this.date.fullDate
+		for (let i = 1; i <= amount; i++) {
+			const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}`
+			const isToday = fullDate === currentDate
+			// 获取打点信息
+			const info = this.selected && this.selected.find((item) => {
+				if (this.dateEqual(currentDate, item.date)) {
+					return item
+				}
+			})
+
+			// 日期禁用
+			let disableBefore = true
+			let disableAfter = true
+			if (this.startDate) {
+				disableBefore = dateCompare(this.startDate, currentDate)
+			}
+
+			if (this.endDate) {
+				disableAfter = dateCompare(currentDate, this.endDate)
+			}
+
+			let multiples = this.multipleStatus.data
+			let multiplesStatus = -1
+			if (this.range && multiples) {
+				multiplesStatus = multiples.findIndex((item) => {
+					return this.dateEqual(item, currentDate)
+				})
+			}
+			const checked = multiplesStatus !== -1
+
+			result.push({
+				fullDate: currentDate,
+				year: dateObj.year,
+				date: i,
+				multiple: this.range ? checked : false,
+				beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this.multipleStatus.after),
+				afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this.multipleStatus.after),
+				month: dateObj.month,
+				disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(
+					currentDate, this.endDate)),
+				isToday,
+				userChecked: false,
+				extraInfo: info
+			})
+		}
+		return result
+	}
+	/**
+	 * 获取下一个月日期集合
+	 */
+	_getNextMonthDays(amount, dateObj) {
+		const result = []
+		const month = dateObj.month + 1
+		for (let i = 1; i <= amount; i++) {
+			result.push({
+				date: i,
+				month,
+				disable: true
+			})
+		}
+		return result
+	}
+
+	/**
+	 * 获取当前日期详情
+	 * @param {Object} date
+	 */
+	getInfo(date) {
+		if (!date) {
+			date = new Date()
+		}
+		const res = this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
+		return res ? res : this.getDateObj(date)
+	}
+
+	/**
+	 * 比较时间是否相等
+	 */
+	dateEqual(before, after) {
+		before = new Date(fixIosDateFormat(before))
+		after = new Date(fixIosDateFormat(after))
+		return before.valueOf() === after.valueOf()
+	}
+
+	/**
+	 *  比较真实起始日期
+	 */
+
+	isLogicBefore(currentDate, before, after) {
+		let logicBefore = before
+		if (before && after) {
+			logicBefore = dateCompare(before, after) ? before : after
+		}
+		return this.dateEqual(logicBefore, currentDate)
+	}
+
+	isLogicAfter(currentDate, before, after) {
+		let logicAfter = after
+		if (before && after) {
+			logicAfter = dateCompare(before, after) ? after : before
+		}
+		return this.dateEqual(logicAfter, currentDate)
+	}
+
+	/**
+	 * 获取日期范围内所有日期
+	 * @param {Object} begin
+	 * @param {Object} end
+	 */
+	geDateAll(begin, end) {
+		var arr = []
+		var ab = begin.split('-')
+		var ae = end.split('-')
+		var db = new Date()
+		db.setFullYear(ab[0], ab[1] - 1, ab[2])
+		var de = new Date()
+		de.setFullYear(ae[0], ae[1] - 1, ae[2])
+		var unixDb = db.getTime() - 24 * 60 * 60 * 1000
+		var unixDe = de.getTime() - 24 * 60 * 60 * 1000
+		for (var k = unixDb; k <= unixDe;) {
+			k = k + 24 * 60 * 60 * 1000
+			arr.push(this.getDateObj(new Date(parseInt(k))).fullDate)
+		}
+		return arr
+	}
+
+	/**
+	 *  获取多选状态
+	 */
+	setMultiple(fullDate) {
+		if (!this.range) return
+
+		let {
+			before,
+			after
+		} = this.multipleStatus
+		if (before && after) {
+			if (!this.lastHover) {
+				this.lastHover = true
+				return
+			}
+			this.multipleStatus.before = fullDate
+			this.multipleStatus.after = ''
+			this.multipleStatus.data = []
+			this.multipleStatus.fulldate = ''
+			this.lastHover = false
+		} else {
+			if (!before) {
+				this.multipleStatus.before = fullDate
+				this.multipleStatus.after = undefined;
+				this.lastHover = false
+			} else {
+				this.multipleStatus.after = fullDate
+				if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
+						.after);
+				} else {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
+						.before);
+				}
+				this.lastHover = true
+			}
+		}
+		this.getWeeks(fullDate)
+	}
+
+	/**
+	 *  鼠标 hover 更新多选状态
+	 */
+	setHoverMultiple(fullDate) {
+		//抖音小程序点击会触发hover事件,需要避免一下
+		// #ifndef MP-TOUTIAO
+		if (!this.range || this.lastHover) return
+		const {
+			before
+		} = this.multipleStatus
+
+		if (!before) {
+			this.multipleStatus.before = fullDate
+		} else {
+			this.multipleStatus.after = fullDate
+			if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+				this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
+			} else {
+				this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
+			}
+		}
+		this.getWeeks(fullDate)
+		// #endif
+
+	}
+
+	/**
+	 * 更新默认值多选状态
+	 */
+	setDefaultMultiple(before, after) {
+		this.multipleStatus.before = before
+		this.multipleStatus.after = after
+		if (before && after) {
+			if (dateCompare(before, after)) {
+				this.multipleStatus.data = this.geDateAll(before, after);
+				this.getWeeks(after)
+			} else {
+				this.multipleStatus.data = this.geDateAll(after, before);
+				this.getWeeks(before)
+			}
+		}
+	}
+
+	/**
+	 * 获取每周数据
+	 * @param {Object} dateData
+	 */
+	getWeeks(dateData) {
+		const {
+			year,
+			month,
+		} = this.getDateObj(dateData)
+
+		const preMonthDayAmount = new Date(year, month - 1, 1).getDay()
+		const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))
+
+		const currentMonthDayAmount = new Date(year, month, 0).getDate()
+		const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))
+
+		const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
+		const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))
+
+		const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays]
+
+		const weeks = new Array(6)
+		for (let i = 0; i < calendarDays.length; i++) {
+			const index = Math.floor(i / 7)
+			if (!weeks[index]) {
+				weeks[index] = new Array(7)
+			}
+			weeks[index][i % 7] = calendarDays[i]
+		}
+
+		this.calendar = calendarDays
+		this.weeks = weeks
+	}
+}
+
+function getDateTime(date, hideSecond) {
+	return `${getDate(date)} ${getTime(date, hideSecond)}`
+}
+
+function getDate(date) {
+	date = fixIosDateFormat(date)
+	date = new Date(date)
+	const year = date.getFullYear()
+	const month = date.getMonth() + 1
+	const day = date.getDate()
+	return `${year}-${addZero(month)}-${addZero(day)}`
+}
+
+function getTime(date, hideSecond) {
+	date = fixIosDateFormat(date)
+	date = new Date(date)
+	const hour = date.getHours()
+	const minute = date.getMinutes()
+	const second = date.getSeconds()
+	return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
+}
+
+function addZero(num) {
+	if (num < 10) {
+		num = `0${num}`
+	}
+	return num
+}
+
+function getDefaultSecond(hideSecond) {
+	return hideSecond ? '00:00' : '00:00:00'
+}
+
+function dateCompare(startDate, endDate) {
+	startDate = new Date(fixIosDateFormat(startDate))
+	endDate = new Date(fixIosDateFormat(endDate))
+	return startDate <= endDate
+}
+
+function checkDate(date) {
+	const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
+	return date.match(dateReg)
+}
+//ios低版本15及以下,无法匹配 没有 ’秒‘ 时的情况,所以需要在末尾 秒 加上 问号
+const dateTimeReg = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])( [0-5]?[0-9]:[0-5]?[0-9](:[0-5]?[0-9])?)?$/;
+
+function fixIosDateFormat(value) {
+	if (typeof value === 'string' && dateTimeReg.test(value)) {
+		value = value.replace(/-/g, '/')
+	}
+	return value
+}
+
+export {
+	Calendar,
+	getDateTime,
+	getDate,
+	getTime,
+	addZero,
+	getDefaultSecond,
+	dateCompare,
+	checkDate,
+	fixIosDateFormat
+}
diff --git a/uni_modules/uni-datetime-picker/package.json b/uni_modules/uni-datetime-picker/package.json
new file mode 100644
index 0000000..a886f1b
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-datetime-picker",
+  "displayName": "uni-datetime-picker 日期选择器",
+  "version": "2.2.38",
+  "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择",
+  "keywords": [
+    "uni-datetime-picker",
+    "uni-ui",
+    "uniui",
+    "日期时间选择器",
+    "日期时间"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-datetime-picker/readme.md b/uni_modules/uni-datetime-picker/readme.md
new file mode 100644
index 0000000..162fbef
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/readme.md
@@ -0,0 +1,21 @@
+
+
+> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护`
+
+## DatetimePicker 时间选择器
+
+> **组件名:uni-datetime-picker**
+> 代码块: `uDatetimePicker`
+
+
+该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。
+
+若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。
+
+**_点击 picker 默认值规则:_**
+
+- 若设置初始值 value, 会显示在 picker 显示框中
+- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-drawer/changelog.md b/uni_modules/uni-drawer/changelog.md
new file mode 100644
index 0000000..6d2488c
--- /dev/null
+++ b/uni_modules/uni-drawer/changelog.md
@@ -0,0 +1,13 @@
+## 1.2.1(2021-11-22)
+- 修复 vue3中个别scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-drawer](https://uniapp.dcloud.io/component/uniui/uni-drawer)
+## 1.1.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-drawer/components/uni-drawer/keypress.js b/uni_modules/uni-drawer/components/uni-drawer/keypress.js
new file mode 100644
index 0000000..62dda46
--- /dev/null
+++ b/uni_modules/uni-drawer/components/uni-drawer/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    // this.$once('hook:beforeDestroy', () => {
+    //   document.removeEventListener('keyup', listener)
+    // })
+  },
+	render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue b/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
new file mode 100644
index 0000000..2471521
--- /dev/null
+++ b/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
@@ -0,0 +1,183 @@
+<template>
+	<view v-if="visibleSync" :class="{ 'uni-drawer--visible': showDrawer }" class="uni-drawer" @touchmove.stop.prevent="clear">
+		<view class="uni-drawer__mask" :class="{ 'uni-drawer__mask--visible': showDrawer && mask }" @tap="close('mask')" />
+		<view class="uni-drawer__content" :class="{'uni-drawer--right': rightMode,'uni-drawer--left': !rightMode, 'uni-drawer__content--visible': showDrawer}" :style="{width:drawerWidth+'px'}">
+			<slot />
+		</view>
+		<!-- #ifdef H5 -->
+		<keypress @esc="close('mask')" />
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	import keypress from './keypress.js'
+	// #endif
+	/**
+	 * Drawer 抽屉
+	 * @description 抽屉侧滑菜单
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=26
+	 * @property {Boolean} mask = [true | false] 是否显示遮罩
+	 * @property {Boolean} maskClick = [true | false] 点击遮罩是否关闭
+	 * @property {Boolean} mode = [left | right] Drawer 滑出位置
+	 * 	@value left 从左侧滑出
+	 * 	@value right 从右侧侧滑出
+	 * @property {Number} width 抽屉的宽度 ,仅 vue 页面生效
+	 * @event {Function} close 组件关闭时触发事件
+	 */
+	export default {
+		name: 'UniDrawer',
+		components: {
+			// #ifdef H5
+			keypress
+			// #endif
+		},
+		emits:['change'],
+		props: {
+			/**
+			 * 显示模式(左、右),只在初始化生效
+			 */
+			mode: {
+				type: String,
+				default: ''
+			},
+			/**
+			 * 蒙层显示状态
+			 */
+			mask: {
+				type: Boolean,
+				default: true
+			},
+			/**
+			 * 遮罩是否可点击关闭
+			 */
+			maskClick:{
+				type: Boolean,
+				default: true
+			},
+			/**
+			 * 抽屉宽度
+			 */
+			width: {
+				type: Number,
+				default: 220
+			}
+		},
+		data() {
+			return {
+				visibleSync: false,
+				showDrawer: false,
+				rightMode: false,
+				watchTimer: null,
+				drawerWidth: 220
+			}
+		},
+		created() {
+			// #ifndef APP-NVUE
+			this.drawerWidth = this.width
+			// #endif
+			this.rightMode = this.mode === 'right'
+		},
+		methods: {
+			clear(){},
+			close(type) {
+				// fixed by mehaotian 抽屉尚未完全关闭或遮罩禁止点击时不触发以下逻辑
+				if((type === 'mask' && !this.maskClick) || !this.visibleSync) return
+				this._change('showDrawer', 'visibleSync', false)
+			},
+			open() {
+				// fixed by mehaotian 处理重复点击打开的事件
+				if(this.visibleSync) return
+				this._change('visibleSync', 'showDrawer', true)
+			},
+			_change(param1, param2, status) {
+				this[param1] = status
+				if (this.watchTimer) {
+					clearTimeout(this.watchTimer)
+				}
+				this.watchTimer = setTimeout(() => {
+					this[param2] = status
+					this.$emit('change',status)
+				}, status ? 50 : 300)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$uni-mask: rgba($color: #000000, $alpha: 0.4) ;
+	// 抽屉宽度
+	$drawer-width: 220px;
+
+	.uni-drawer {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		overflow: hidden;
+		z-index: 999;
+	}
+
+	.uni-drawer__content {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: absolute;
+		top: 0;
+		width: $drawer-width;
+		bottom: 0;
+		background-color: $uni-bg-color;
+		transition: transform 0.3s ease;
+	}
+
+	.uni-drawer--left {
+		left: 0;
+		/* #ifdef APP-NVUE */
+		transform: translateX(-$drawer-width);
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		transform: translateX(-100%);
+		/* #endif */
+	}
+
+	.uni-drawer--right {
+		right: 0;
+		/* #ifdef APP-NVUE */
+		transform: translateX($drawer-width);
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		transform: translateX(100%);
+		/* #endif */
+	}
+
+	.uni-drawer__content--visible {
+		transform: translateX(0px);
+	}
+
+
+	.uni-drawer__mask {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		opacity: 0;
+		position: absolute;
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		background-color: $uni-mask;
+		transition: opacity 0.3s;
+	}
+
+	.uni-drawer__mask--visible {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		opacity: 1;
+	}
+</style>
diff --git a/uni_modules/uni-drawer/package.json b/uni_modules/uni-drawer/package.json
new file mode 100644
index 0000000..dd056e4
--- /dev/null
+++ b/uni_modules/uni-drawer/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-drawer",
+  "displayName": "uni-drawer 抽屉",
+  "version": "1.2.1",
+  "description": "抽屉式导航,用于展示侧滑菜单,侧滑导航。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "drawer",
+    "抽屉",
+    "侧滑导航"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-drawer/readme.md b/uni_modules/uni-drawer/readme.md
new file mode 100644
index 0000000..dcf6e6b
--- /dev/null
+++ b/uni_modules/uni-drawer/readme.md
@@ -0,0 +1,10 @@
+
+
+## Drawer 抽屉
+> **组件名:uni-drawer**
+> 代码块: `uDrawer`
+
+抽屉侧滑菜单。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-drawer)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-easyinput/changelog.md b/uni_modules/uni-easyinput/changelog.md
new file mode 100644
index 0000000..84c72eb
--- /dev/null
+++ b/uni_modules/uni-easyinput/changelog.md
@@ -0,0 +1,115 @@
+## 1.1.19(2024-07-18)
+- 修复 初始值传入 null 导致input报错的bug
+## 1.1.18(2024-04-11)
+- 修复 easyinput组件双向绑定问题
+## 1.1.17(2024-03-28)
+- 修复 在头条小程序下丢失事件绑定的问题
+## 1.1.16(2024-03-20)
+- 修复 在密码输入情况下 清除和小眼睛覆盖bug 在edge浏览器下显示双眼睛bug
+## 1.1.15(2024-02-21)
+- 新增 左侧插槽:left
+## 1.1.14(2024-02-19)
+- 修复 onBlur的emit传值错误
+## 1.1.12(2024-01-29)
+- 补充 adjust-position文档属性补充
+## 1.1.11(2024-01-29)
+- 补充 adjust-position属性传递值:(Boolean)当键盘弹起时,是否自动上推页面
+## 1.1.10(2024-01-22)
+- 去除 移除无用的log输出
+## 1.1.9(2023-04-11)
+- 修复 vue3 下 keyboardheightchange 事件报错的bug
+## 1.1.8(2023-03-29)
+- 优化 trim 属性默认值
+## 1.1.7(2023-03-29)
+- 新增 cursor-spacing 属性
+## 1.1.6(2023-01-28)
+- 新增 keyboardheightchange 事件,可监听键盘高度变化
+## 1.1.5(2022-11-29)
+- 优化 主题样式
+## 1.1.4(2022-10-27)
+- 修复 props 中背景颜色无默认值的bug
+## 1.1.0(2022-06-30)
+
+- 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
+- 新增 clear 事件,点击右侧叉号图标触发
+- 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
+- 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
+
+## 1.0.5(2022-06-07)
+
+- 优化 clearable 显示策略
+
+## 1.0.4(2022-06-07)
+
+- 优化 clearable 显示策略
+
+## 1.0.3(2022-05-20)
+
+- 修复 关闭图标某些情况下无法取消的 bug
+
+## 1.0.2(2022-04-12)
+
+- 修复 默认值不生效的 bug
+
+## 1.0.1(2022-04-02)
+
+- 修复 value 不能为 0 的 bug
+
+## 1.0.0(2021-11-19)
+
+- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput)
+
+## 0.1.4(2021-08-20)
+
+- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
+
+## 0.1.3(2021-08-11)
+
+- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+
+## 0.1.2(2021-07-30)
+
+- 优化 vue3 下事件警告的问题
+
+## 0.1.1
+
+- 优化 errorMessage 属性支持 Boolean 类型
+
+## 0.1.0(2021-07-13)
+
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+
+## 0.0.16(2021-06-29)
+
+- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug
+
+## 0.0.15(2021-06-21)
+
+- 修复 passwordIcon 属性拼写错误的 bug
+
+## 0.0.14(2021-06-18)
+
+- 新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标
+- 修复 confirmType 属性不生效的问题
+
+## 0.0.13(2021-06-04)
+
+- 修复 disabled 状态可清出内容的 bug
+
+## 0.0.12(2021-05-12)
+
+- 新增 组件示例地址
+
+## 0.0.11(2021-05-07)
+
+- 修复 input-border 属性不生效的问题
+
+## 0.0.10(2021-04-30)
+
+- 修复 ios 遮挡文字、显示一半的问题
+
+## 0.0.9(2021-02-05)
+
+- 调整为 uni_modules 目录规范
+- 优化 兼容 nvue 页面
diff --git a/uni_modules/uni-easyinput/components/uni-easyinput/common.js b/uni_modules/uni-easyinput/components/uni-easyinput/common.js
new file mode 100644
index 0000000..fde8d3c
--- /dev/null
+++ b/uni_modules/uni-easyinput/components/uni-easyinput/common.js
@@ -0,0 +1,54 @@
+/**
+ * @desc 函数防抖
+ * @param func 目标函数
+ * @param wait 延迟执行毫秒数
+ * @param immediate true - 立即执行, false - 延迟执行
+ */
+export const debounce = function(func, wait = 1000, immediate = true) {
+	let timer;
+	return function() {
+		let context = this,
+			args = arguments;
+		if (timer) clearTimeout(timer);
+		if (immediate) {
+			let callNow = !timer;
+			timer = setTimeout(() => {
+				timer = null;
+			}, wait);
+			if (callNow) func.apply(context, args);
+		} else {
+			timer = setTimeout(() => {
+				func.apply(context, args);
+			}, wait)
+		}
+	}
+}
+/**
+ * @desc 函数节流
+ * @param func 函数
+ * @param wait 延迟执行毫秒数
+ * @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发
+ */
+export const throttle = (func, wait = 1000, type = 1) => {
+	let previous = 0;
+	let timeout;
+	return function() {
+		let context = this;
+		let args = arguments;
+		if (type === 1) {
+			let now = Date.now();
+
+			if (now - previous > wait) {
+				func.apply(context, args);
+				previous = now;
+			}
+		} else if (type === 2) {
+			if (!timeout) {
+				timeout = setTimeout(() => {
+					timeout = null;
+					func.apply(context, args)
+				}, wait)
+			}
+		}
+	}
+}
diff --git a/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
new file mode 100644
index 0000000..93506d6
--- /dev/null
+++ b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
@@ -0,0 +1,676 @@
+<template>
+	<view class="uni-easyinput" :class="{ 'uni-easyinput-error': msg }" :style="boxStyle">
+		<view class="uni-easyinput__content" :class="inputContentClass" :style="inputContentStyle">
+			<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc" @click="onClickIcon('prefix')" size="22"></uni-icons>
+			<slot name="left">
+			</slot>
+			<!-- #ifdef MP-ALIPAY -->
+			<textarea :enableNative="enableNative" v-if="type === 'textarea'" class="uni-easyinput__content-textarea" :class="{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder" :placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class" :maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange"></textarea>
+			<input :enableNative="enableNative" v-else :type="type === 'password' ? 'text' : type" class="uni-easyinput__content-input" :style="inputStyle" :name="name" :value="val" :password="!showPassword && type === 'password'" :placeholder="placeholder" :placeholderStyle="placeholderStyle" placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled" :maxlength="inputMaxlength" :focus="focused" :confirmType="confirmType" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @focus="_Focus" @blur="_Blur" @input="onInput" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange" />
+			<!-- #endif -->
+			<!-- #ifndef MP-ALIPAY -->
+			<textarea v-if="type === 'textarea'" class="uni-easyinput__content-textarea" :class="{ 'input-padding': inputBorder }" :name="name" :value="val" :placeholder="placeholder" :placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class" :maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @input="onInput" @blur="_Blur" @focus="_Focus" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange"></textarea>
+			<input v-else :type="type === 'password' ? 'text' : type" class="uni-easyinput__content-input" :style="inputStyle" :name="name" :value="val" :password="!showPassword && type === 'password'" :placeholder="placeholder" :placeholderStyle="placeholderStyle" placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled" :maxlength="inputMaxlength" :focus="focused" :confirmType="confirmType" :cursor-spacing="cursorSpacing" :adjust-position="adjustPosition" @focus="_Focus" @blur="_Blur" @input="onInput" @confirm="onConfirm" @keyboardheightchange="onkeyboardheightchange" />
+			<!-- #endif -->
+
+			<template v-if="type === 'password' && passwordIcon">
+				<!-- 开启密码时显示小眼睛 -->
+				<uni-icons v-if="isVal" class="content-clear-icon" :class="{ 'is-textarea-icon': type === 'textarea' }" :type="showPassword ? 'eye-slash-filled' : 'eye-filled'" :size="22" :color="focusShow ? primaryColor : '#c0c4cc'" @click="onEyes"></uni-icons>
+			</template>
+			<template v-if="suffixIcon">
+				<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc" @click="onClickIcon('suffix')" size="22"></uni-icons>
+			</template>
+			<template v-else>
+				<uni-icons v-if="clearable && isVal && !disabled && type !== 'textarea'" class="content-clear-icon" :class="{ 'is-textarea-icon': type === 'textarea' }" type="clear" :size="clearSize" :color="msg ? '#dd524d' : focusShow ? primaryColor : '#c0c4cc'" @click="onClear"></uni-icons>
+			</template>
+			<slot name="right"></slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Easyinput 输入框
+	 * @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3455
+	 * @property {String}	value	输入内容
+	 * @property {String }	type	输入框的类型(默认text) password/text/textarea/..
+	 * 	@value text			文本输入键盘
+	 * 	@value textarea	多行文本输入键盘
+	 * 	@value password	密码输入键盘
+	 * 	@value number		数字输入键盘,注意iOS上app-vue弹出的数字键盘并非9宫格方式
+	 * 	@value idcard		身份证输入键盘,信、支付宝、百度、QQ小程序
+	 * 	@value digit		带小数点的数字键盘	,App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持
+	 * @property {Boolean}	clearable	是否显示右侧清空内容的图标控件,点击可清空输入框内容(默认true)
+	 * @property {Boolean}	autoHeight	是否自动增高输入区域,type为textarea时有效(默认true)
+	 * @property {String }	placeholder	输入框的提示文字
+	 * @property {String }	placeholderStyle	placeholder的样式(内联样式,字符串),如"color: #ddd"
+	 * @property {Boolean}	focus	是否自动获得焦点(默认false)
+	 * @property {Boolean}	disabled	是否禁用(默认false)
+	 * @property {Number }	maxlength	最大输入长度,设置为 -1 的时候不限制最大长度(默认140)
+	 * @property {String }	confirmType	设置键盘右下角按钮的文字,仅在type="text"时生效(默认done)
+	 * @property {Number }	clearSize	清除图标的大小,单位px(默认15)
+	 * @property {String}	prefixIcon	输入框头部图标
+	 * @property {String}	suffixIcon	输入框尾部图标
+	 * @property {String}	primaryColor	设置主题色(默认#2979ff)
+	 * @property {Boolean}	trim	是否自动去除两端的空格
+	 * @property {Boolean}	cursorSpacing	指定光标与键盘的距离,单位 px
+	 * @property {Boolean}  ajust-position 当键盘弹起时,是否上推内容,默认值:true
+	 * @value both	去除两端空格
+	 * @value left	去除左侧空格
+	 * @value right	去除右侧空格
+	 * @value start	去除左侧空格
+	 * @value end		去除右侧空格
+	 * @value all		去除全部空格
+	 * @value none	不去除空格
+	 * @property {Boolean}	inputBorder	是否显示input输入框的边框(默认true)
+	 * @property {Boolean}	passwordIcon	type=password时是否显示小眼睛图标
+	 * @property {Object}	styles	自定义颜色
+	 * @event {Function}	input	输入框内容发生变化时触发
+	 * @event {Function}	focus	输入框获得焦点时触发
+	 * @event {Function}	blur	输入框失去焦点时触发
+	 * @event {Function}	confirm	点击完成按钮时触发
+	 * @event {Function}	iconClick	点击图标时触发
+	 * @example <uni-easyinput v-model="mobile"></uni-easyinput>
+	 */
+	function obj2strClass(obj) {
+		let classess = '';
+		for (let key in obj) {
+			const val = obj[key];
+			if (val) {
+				classess += `${key} `;
+			}
+		}
+		return classess;
+	}
+
+	function obj2strStyle(obj) {
+		let style = '';
+		for (let key in obj) {
+			const val = obj[key];
+			style += `${key}:${val};`;
+		}
+		return style;
+	}
+	export default {
+		name: 'uni-easyinput',
+		emits: [
+			'click',
+			'iconClick',
+			'update:modelValue',
+			'input',
+			'focus',
+			'blur',
+			'confirm',
+			'clear',
+			'eyes',
+			'change',
+			'keyboardheightchange'
+		],
+		model: {
+			prop: 'modelValue',
+			event: 'update:modelValue'
+		},
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		inject: {
+			form: {
+				from: 'uniForm',
+				default: null
+			},
+			formItem: {
+				from: 'uniFormItem',
+				default: null
+			}
+		},
+		props: {
+			name: String,
+			value: [Number, String],
+			modelValue: [Number, String],
+			type: {
+				type: String,
+				default: 'text'
+			},
+			clearable: {
+				type: Boolean,
+				default: true
+			},
+			autoHeight: {
+				type: Boolean,
+				default: false
+			},
+			placeholder: {
+				type: String,
+				default: ' '
+			},
+			placeholderStyle: String,
+			focus: {
+				type: Boolean,
+				default: false
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			maxlength: {
+				type: [Number, String],
+				default: 140
+			},
+			confirmType: {
+				type: String,
+				default: 'done'
+			},
+			clearSize: {
+				type: [Number, String],
+				default: 24
+			},
+			inputBorder: {
+				type: Boolean,
+				default: true
+			},
+			prefixIcon: {
+				type: String,
+				default: ''
+			},
+			suffixIcon: {
+				type: String,
+				default: ''
+			},
+			trim: {
+				type: [Boolean, String],
+				default: false
+			},
+			cursorSpacing: {
+				type: Number,
+				default: 0
+			},
+			passwordIcon: {
+				type: Boolean,
+				default: true
+			},
+			adjustPosition: {
+				type: Boolean,
+				default: true
+			},
+			primaryColor: {
+				type: String,
+				default: '#2979ff'
+			},
+			styles: {
+				type: Object,
+				default () {
+					return {
+						color: '#333',
+						backgroundColor: '#fff',
+						disableColor: '#F7F6F6',
+						borderColor: '#e5e5e5'
+					};
+				}
+			},
+			errorMessage: {
+				type: [String, Boolean],
+				default: ''
+			},
+			// #ifdef MP-ALIPAY
+			enableNative: {
+				type: Boolean,
+				default: false
+			}
+			// #endif
+		},
+		data() {
+			return {
+				focused: false,
+				val: '',
+				showMsg: '',
+				border: false,
+				isFirstBorder: false,
+				showClearIcon: false,
+				showPassword: false,
+				focusShow: false,
+				localMsg: '',
+				isEnter: false // 用于判断当前是否是使用回车操作
+			};
+		},
+		computed: {
+			// 输入框内是否有值
+			isVal() {
+				const val = this.val;
+				// fixed by mehaotian 处理值为0的情况,字符串0不在处理范围
+				if (val || val === 0) {
+					return true;
+				}
+				return false;
+			},
+
+			msg() {
+				// console.log('computed', this.form, this.formItem);
+				// if (this.form) {
+				// 	return this.errorMessage || this.formItem.errMsg;
+				// }
+				// TODO 处理头条 formItem 中 errMsg 不更新的问题
+				return this.localMsg || this.errorMessage;
+			},
+			// 因为uniapp的input组件的maxlength组件必须要数值,这里转为数值,用户可以传入字符串数值
+			inputMaxlength() {
+				return Number(this.maxlength);
+			},
+
+			// 处理外层样式的style
+			boxStyle() {
+				return `color:${
+					this.inputBorder && this.msg ? '#e43d33' : this.styles.color
+				};`;
+			},
+			// input 内容的类和样式处理
+			inputContentClass() {
+				return obj2strClass({
+					'is-input-border': this.inputBorder,
+					'is-input-error-border': this.inputBorder && this.msg,
+					'is-textarea': this.type === 'textarea',
+					'is-disabled': this.disabled,
+					'is-focused': this.focusShow
+				});
+			},
+			inputContentStyle() {
+				const focusColor = this.focusShow ?
+					this.primaryColor :
+					this.styles.borderColor;
+				const borderColor =
+					this.inputBorder && this.msg ? '#dd524d' : focusColor;
+				return obj2strStyle({
+					'border-color': borderColor || '#e5e5e5',
+					'background-color': this.disabled ?
+						this.styles.disableColor : this.styles.backgroundColor
+				});
+			},
+			// input右侧样式
+			inputStyle() {
+				const paddingRight =
+					this.type === 'password' || this.clearable || this.prefixIcon ?
+					'' :
+					'10px';
+				return obj2strStyle({
+					'padding-right': paddingRight,
+					'padding-left': this.prefixIcon ? '' : '10px'
+				});
+			}
+		},
+		watch: {
+			value(newVal) {
+				// fix by mehaotian 解决 值为null的情况下,input报错的bug
+				if (newVal === null) {
+					this.val = '';
+					return
+				}
+				this.val = newVal;
+			},
+			modelValue(newVal) {
+				if (newVal === null) {
+					this.val = '';
+					return
+				}
+				this.val = newVal;
+			},
+			focus(newVal) {
+				this.$nextTick(() => {
+					this.focused = this.focus;
+					this.focusShow = this.focus;
+				});
+			}
+		},
+		created() {
+			this.init();
+			// TODO 处理头条vue3 computed 不监听 inject 更改的问题(formItem.errMsg)
+			if (this.form && this.formItem) {
+				this.$watch('formItem.errMsg', newVal => {
+					this.localMsg = newVal;
+				});
+			}
+		},
+		mounted() {
+			this.$nextTick(() => {
+				this.focused = this.focus;
+				this.focusShow = this.focus;
+			});
+		},
+		methods: {
+			/**
+			 * 初始化变量值
+			 */
+			init() {
+				if (this.value || this.value === 0) {
+					this.val = this.value;
+				} else if (
+					this.modelValue ||
+					this.modelValue === 0 ||
+					this.modelValue === ''
+				) {
+					this.val = this.modelValue; 
+				} else {
+					// fix by ht 如果初始值为null,则input报错,待框架修复
+					this.val = '';
+				}
+			},
+
+			/**
+			 * 点击图标时触发
+			 * @param {Object} type
+			 */
+			onClickIcon(type) {
+				this.$emit('iconClick', type);
+			},
+
+			/**
+			 * 显示隐藏内容,密码框时生效
+			 */
+			onEyes() {
+				this.showPassword = !this.showPassword;
+				this.$emit('eyes', this.showPassword);
+			},
+
+			/**
+			 * 输入时触发
+			 * @param {Object} event
+			 */
+			onInput(event) {
+				let value = event.detail.value;
+				// 判断是否去除空格
+				if (this.trim) {
+					if (typeof this.trim === 'boolean' && this.trim) {
+						value = this.trimStr(value);
+					}
+					if (typeof this.trim === 'string') {
+						value = this.trimStr(value, this.trim);
+					}
+				}
+				if (this.errMsg) this.errMsg = '';
+				this.val = value;
+				// TODO 兼容 vue2
+				this.$emit('input', value);
+				// TODO 兼容 vue3
+				this.$emit('update:modelValue', value);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 获取焦点时触发
+			 * @param {Object} event
+			 */
+			onFocus() {
+				this.$nextTick(() => {
+					this.focused = true;
+				});
+				this.$emit('focus', null);
+			},
+
+			_Focus(event) {
+				this.focusShow = true;
+				this.$emit('focus', event);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 失去焦点时触发
+			 * @param {Object} event
+			 */
+			onBlur() {
+				this.focused = false;
+				this.$emit('blur', null);
+			},
+			_Blur(event) {
+				let value = event.detail.value;
+				this.focusShow = false;
+				this.$emit('blur', event);
+				// 根据类型返回值,在event中获取的值理论上讲都是string
+				if (this.isEnter === false) {
+					this.$emit('change', this.val);
+				}
+				// 失去焦点时参与表单校验
+				if (this.form && this.formItem) {
+					const { validateTrigger } = this.form;
+					if (validateTrigger === 'blur') {
+						this.formItem.onFieldChange();
+					}
+				}
+			},
+
+			/**
+			 * 按下键盘的发送键
+			 * @param {Object} e
+			 */
+			onConfirm(e) {
+				this.$emit('confirm', this.val);
+				this.isEnter = true;
+				this.$emit('change', this.val);
+				this.$nextTick(() => {
+					this.isEnter = false;
+				});
+			},
+
+			/**
+			 * 清理内容
+			 * @param {Object} event
+			 */
+			onClear(event) {
+				this.val = '';
+				// TODO 兼容 vue2
+				this.$emit('input', '');
+				// TODO 兼容 vue2
+				// TODO 兼容 vue3
+				this.$emit('update:modelValue', '');
+				// 点击叉号触发
+				this.$emit('clear');
+			},
+
+			/**
+			 * 键盘高度发生变化的时候触发此事件
+			 * 兼容性:微信小程序2.7.0+、App 3.1.0+
+			 * @param {Object} event
+			 */
+			onkeyboardheightchange(event) {
+				this.$emit('keyboardheightchange', event);
+			},
+
+			/**
+			 * 去除空格
+			 */
+			trimStr(str, pos = 'both') {
+				if (pos === 'both') {
+					return str.trim();
+				} else if (pos === 'left') {
+					return str.trimLeft();
+				} else if (pos === 'right') {
+					return str.trimRight();
+				} else if (pos === 'start') {
+					return str.trimStart();
+				} else if (pos === 'end') {
+					return str.trimEnd();
+				} else if (pos === 'all') {
+					return str.replace(/\s+/g, '');
+				} else if (pos === 'none') {
+					return str;
+				}
+				return str;
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	$uni-error: #e43d33;
+	$uni-border-1: #dcdfe6 !default;
+
+	.uni-easyinput {
+		/* #ifndef APP-NVUE */
+		width: 100%;
+		/* #endif */
+		flex: 1;
+		position: relative;
+		text-align: left;
+		color: #333;
+		font-size: 14px;
+	}
+
+	.uni-easyinput__content {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		width: 100%;
+		display: flex;
+		box-sizing: border-box;
+		// min-height: 36px;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		// 处理border动画刚开始显示黑色的问题
+		border-color: #fff;
+		transition-property: border-color;
+		transition-duration: 0.3s;
+	}
+
+	.uni-easyinput__content-input {
+		/* #ifndef APP-NVUE */
+		width: auto;
+		/* #endif */
+		position: relative;
+		overflow: hidden;
+		flex: 1;
+		line-height: 1;
+		font-size: 14px;
+		height: 35px;
+		// min-height: 36px;
+
+		/*ifdef H5*/
+		& ::-ms-reveal {
+			display: none;
+		}
+
+		& ::-ms-clear {
+			display: none;
+		}
+
+		& ::-o-clear {
+			display: none;
+		}
+
+		/*endif*/
+	}
+
+	.uni-easyinput__placeholder-class {
+		color: #999;
+		font-size: 12px;
+		// font-weight: 200;
+	}
+
+	.is-textarea {
+		align-items: flex-start;
+	}
+
+	.is-textarea-icon {
+		margin-top: 5px;
+	}
+
+	.uni-easyinput__content-textarea {
+		position: relative;
+		overflow: hidden;
+		flex: 1;
+		line-height: 1.5;
+		font-size: 14px;
+		margin: 6px;
+		margin-left: 0;
+		height: 80px;
+		min-height: 80px;
+		/* #ifndef APP-NVUE */
+		min-height: 80px;
+		width: auto;
+		/* #endif */
+	}
+
+	.input-padding {
+		padding-left: 10px;
+	}
+
+	.content-clear-icon {
+		padding: 0 5px;
+	}
+
+	.label-icon {
+		margin-right: 5px;
+		margin-top: -1px;
+	}
+
+	// 显示边框
+	.is-input-border {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		border: 1px solid $uni-border-1;
+		border-radius: 4px;
+		/* #ifdef MP-ALIPAY */
+		overflow: hidden;
+		/* #endif */
+	}
+
+	.uni-error-message {
+		position: absolute;
+		bottom: -17px;
+		left: 0;
+		line-height: 12px;
+		color: $uni-error;
+		font-size: 12px;
+		text-align: left;
+	}
+
+	.uni-error-msg--boeder {
+		position: relative;
+		bottom: 0;
+		line-height: 22px;
+	}
+
+	.is-input-error-border {
+		border-color: $uni-error;
+
+		.uni-easyinput__placeholder-class {
+			color: mix(#fff, $uni-error, 50%);
+		}
+	}
+
+	.uni-easyinput--border {
+		margin-bottom: 0;
+		padding: 10px 15px;
+		// padding-bottom: 0;
+		border-top: 1px #eee solid;
+	}
+
+	.uni-easyinput-error {
+		padding-bottom: 0;
+	}
+
+	.is-first-border {
+		/* #ifndef APP-NVUE */
+		border: none;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		border-width: 0;
+		/* #endif */
+	}
+
+	.is-disabled {
+		background-color: #f7f6f6;
+		color: #d5d5d5;
+
+		.uni-easyinput__placeholder-class {
+			color: #d5d5d5;
+			font-size: 12px;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/uni_modules/uni-easyinput/package.json b/uni_modules/uni-easyinput/package.json
new file mode 100644
index 0000000..2939256
--- /dev/null
+++ b/uni_modules/uni-easyinput/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-easyinput",
+  "displayName": "uni-easyinput 增强输入框",
+  "version": "1.1.19",
+  "description": "Easyinput 组件是对原生input组件的增强",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "input",
+    "uni-easyinput",
+    "输入框"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+      "uni-icons"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-easyinput/readme.md b/uni_modules/uni-easyinput/readme.md
new file mode 100644
index 0000000..f1faf8f
--- /dev/null
+++ b/uni_modules/uni-easyinput/readme.md
@@ -0,0 +1,11 @@
+
+
+### Easyinput 增强输入框
+> **组件名:uni-easyinput**
+> 代码块: `uEasyinput`
+
+
+easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-fab/changelog.md b/uni_modules/uni-fab/changelog.md
new file mode 100644
index 0000000..8a22807
--- /dev/null
+++ b/uni_modules/uni-fab/changelog.md
@@ -0,0 +1,25 @@
+## 1.2.6(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.2.5(2023-03-29)
+- 新增 pattern.icon 属性,可自定义图标
+## 1.2.4(2022-09-07)
+小程序端由于 style 使用了对象导致报错,[详情](https://ask.dcloud.net.cn/question/152790?item_id=211778&rf=false)
+## 1.2.3(2022-09-05)
+- 修复 nvue 环境下,具有 tabBar 时,fab 组件下部位置无法正常获取 --window-bottom 的bug,详见:[https://ask.dcloud.net.cn/question/110638?notification_id=826310](https://ask.dcloud.net.cn/question/110638?notification_id=826310)
+## 1.2.2(2021-12-29)
+- 更新 组件依赖
+## 1.2.1(2021-11-19)
+- 修复 阴影颜色不正确的bug
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-fab](https://uniapp.dcloud.io/component/uniui/uni-fab)
+## 1.1.1(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-02-05)
+- 调整为uni_modules目录规范
+- 优化 按钮背景色调整
+- 优化 兼容pc端
diff --git a/uni_modules/uni-fab/components/uni-fab/uni-fab.vue b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
new file mode 100644
index 0000000..492b5d1
--- /dev/null
+++ b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
@@ -0,0 +1,491 @@
+<template>
+	<view class="uni-cursor-point">
+		<view v-if="popMenu && (leftBottom||rightBottom||leftTop||rightTop) && content.length > 0" :class="{
+        'uni-fab--leftBottom': leftBottom,
+        'uni-fab--rightBottom': rightBottom,
+        'uni-fab--leftTop': leftTop,
+        'uni-fab--rightTop': rightTop
+      }" class="uni-fab"
+				:style="nvueBottom"
+			>
+			<view :class="{
+          'uni-fab__content--left': horizontal === 'left',
+          'uni-fab__content--right': horizontal === 'right',
+          'uni-fab__content--flexDirection': direction === 'vertical',
+          'uni-fab__content--flexDirectionStart': flexDirectionStart,
+          'uni-fab__content--flexDirectionEnd': flexDirectionEnd,
+		  'uni-fab__content--other-platform': !isAndroidNvue
+        }" :style="{ width: boxWidth, height: boxHeight, backgroundColor: styles.backgroundColor }"
+				class="uni-fab__content" elevation="5">
+				<view v-if="flexDirectionStart || horizontalLeft" class="uni-fab__item uni-fab__item--first" />
+				<view v-for="(item, index) in content" :key="index" :class="{ 'uni-fab__item--active': isShow }"
+					class="uni-fab__item" @click="_onItemClick(index, item)">
+					<image :src="item.active ? item.selectedIconPath : item.iconPath" class="uni-fab__item-image"
+						mode="aspectFit" />
+					<text class="uni-fab__item-text"
+						:style="{ color: item.active ? styles.selectedColor : styles.color }">{{ item.text }}</text>
+				</view>
+				<view v-if="flexDirectionEnd || horizontalRight" class="uni-fab__item uni-fab__item--first" />
+			</view>
+		</view>
+		<view :class="{
+		  'uni-fab__circle--leftBottom': leftBottom,
+		  'uni-fab__circle--rightBottom': rightBottom,
+		  'uni-fab__circle--leftTop': leftTop,
+		  'uni-fab__circle--rightTop': rightTop,
+		  'uni-fab__content--other-platform': !isAndroidNvue
+		}" class="uni-fab__circle uni-fab__plus" :style="{ 'background-color': styles.buttonColor, 'bottom': nvueBottom }" @click="_onClick">
+			<uni-icons class="fab-circle-icon" :type="styles.icon" :color="styles.iconColor" size="32"
+				:class="{'uni-fab__plus--active': isShow && content.length > 0}"></uni-icons>
+			<!-- <view class="fab-circle-v"  :class="{'uni-fab__plus--active': isShow && content.length > 0}"></view>
+			<view class="fab-circle-h" :class="{'uni-fab__plus--active': isShow  && content.length > 0}"></view> -->
+		</view>
+	</view>
+</template>
+
+<script>
+	let platform = 'other'
+	// #ifdef APP-NVUE
+	platform = uni.getSystemInfoSync().platform
+	// #endif
+
+	/**
+	 * Fab 悬浮按钮
+	 * @description 点击可展开一个图形按钮菜单
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=144
+	 * @property {Object} pattern 可选样式配置项
+	 * @property {Object} horizontal = [left | right] 水平对齐方式
+	 * 	@value left 左对齐
+	 * 	@value right 右对齐
+	 * @property {Object} vertical = [bottom | top] 垂直对齐方式
+	 * 	@value bottom 下对齐
+	 * 	@value top 上对齐
+	 * @property {Object} direction = [horizontal | vertical] 展开菜单显示方式
+	 * 	@value horizontal 水平显示
+	 * 	@value vertical 垂直显示
+	 * @property {Array} content 展开菜单内容配置项
+	 * @property {Boolean} popMenu 是否使用弹出菜单
+	 * @event {Function} trigger 展开菜单点击事件,返回点击信息
+	 * @event {Function} fabClick 悬浮按钮点击事件
+	 */
+	export default {
+		name: 'UniFab',
+		emits: ['fabClick', 'trigger'],
+		props: {
+			pattern: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			horizontal: {
+				type: String,
+				default: 'left'
+			},
+			vertical: {
+				type: String,
+				default: 'bottom'
+			},
+			direction: {
+				type: String,
+				default: 'horizontal'
+			},
+			content: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			show: {
+				type: Boolean,
+				default: false
+			},
+			popMenu: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				fabShow: false,
+				isShow: false,
+				isAndroidNvue: platform === 'android',
+				styles: {
+					color: '#3c3e49',
+					selectedColor: '#007AFF',
+					backgroundColor: '#fff',
+					buttonColor: '#007AFF',
+					iconColor: '#fff',
+					icon: 'plusempty'
+				}
+			}
+		},
+		computed: {
+			contentWidth(e) {
+				return (this.content.length + 1) * 55 + 15 + 'px'
+			},
+			contentWidthMin() {
+				return '55px'
+			},
+			// 动态计算宽度
+			boxWidth() {
+				return this.getPosition(3, 'horizontal')
+			},
+			// 动态计算高度
+			boxHeight() {
+				return this.getPosition(3, 'vertical')
+			},
+			// 计算左下位置
+			leftBottom() {
+				return this.getPosition(0, 'left', 'bottom')
+			},
+			// 计算右下位置
+			rightBottom() {
+				return this.getPosition(0, 'right', 'bottom')
+			},
+			// 计算左上位置
+			leftTop() {
+				return this.getPosition(0, 'left', 'top')
+			},
+			rightTop() {
+				return this.getPosition(0, 'right', 'top')
+			},
+			flexDirectionStart() {
+				return this.getPosition(1, 'vertical', 'top')
+			},
+			flexDirectionEnd() {
+				return this.getPosition(1, 'vertical', 'bottom')
+			},
+			horizontalLeft() {
+				return this.getPosition(2, 'horizontal', 'left')
+			},
+			horizontalRight() {
+				return this.getPosition(2, 'horizontal', 'right')
+			},
+			// 计算 nvue bottom
+			nvueBottom() {
+				// #ifdef APP-NVUE
+				const safeBottom = uni.getSystemInfoSync().windowBottom;
+				return 30 + safeBottom
+				// #endif
+				// #ifndef APP-NVUE
+				return 30
+				// #endif
+			}
+		},
+		watch: {
+			pattern: {
+				handler(val, oldVal) {
+					this.styles = Object.assign({}, this.styles, val)
+				},
+				deep: true
+			}
+		},
+		created() {
+			this.isShow = this.show
+			if (this.top === 0) {
+				this.fabShow = true
+			}
+			// 初始化样式
+			this.styles = Object.assign({}, this.styles, this.pattern)
+		},
+		methods: {
+			_onClick() {
+				this.$emit('fabClick')
+				if (!this.popMenu) {
+					return
+				}
+				this.isShow = !this.isShow
+			},
+			open() {
+				this.isShow = true
+			},
+			close() {
+				this.isShow = false
+			},
+			/**
+			 * 按钮点击事件
+			 */
+			_onItemClick(index, item) {
+				if (!this.isShow) {
+					return
+				}
+				this.$emit('trigger', {
+					index,
+					item
+				})
+			},
+			/**
+			 * 获取 位置信息
+			 */
+			getPosition(types, paramA, paramB) {
+				if (types === 0) {
+					return this.horizontal === paramA && this.vertical === paramB
+				} else if (types === 1) {
+					return this.direction === paramA && this.vertical === paramB
+				} else if (types === 2) {
+					return this.direction === paramA && this.horizontal === paramB
+				} else {
+					return this.isShow && this.direction === paramA ? this.contentWidth : this.contentWidthMin
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	$uni-shadow-base:0 1px 5px 2px rgba($color: #000000, $alpha: 0.3) !default;
+
+	.uni-fab {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		z-index: 10;
+		border-radius: 45px;
+		box-shadow: $uni-shadow-base;
+	}
+
+	.uni-cursor-point {
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-fab--active {
+		opacity: 1;
+	}
+
+	.uni-fab--leftBottom {
+		left: 15px;
+		bottom: 30px;
+		/* #ifdef H5 */
+		left: calc(15px + var(--window-left));
+		bottom: calc(30px + var(--window-bottom));
+		/* #endif */
+		// padding: 10px;
+	}
+
+	.uni-fab--leftTop {
+		left: 15px;
+		top: 30px;
+		/* #ifdef H5 */
+		left: calc(15px + var(--window-left));
+		top: calc(30px + var(--window-top));
+		/* #endif */
+		// padding: 10px;
+	}
+
+	.uni-fab--rightBottom {
+		right: 15px;
+		bottom: 30px;
+		/* #ifdef H5 */
+		right: calc(15px + var(--window-right));
+		bottom: calc(30px + var(--window-bottom));
+		/* #endif */
+		// padding: 10px;
+	}
+
+	.uni-fab--rightTop {
+		right: 15px;
+		top: 30px;
+		/* #ifdef H5 */
+		right: calc(15px + var(--window-right));
+		top: calc(30px + var(--window-top));
+		/* #endif */
+		// padding: 10px;
+	}
+
+	.uni-fab__circle {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		width: 55px;
+		height: 55px;
+		background-color: #3c3e49;
+		border-radius: 45px;
+		z-index: 11;
+		// box-shadow: $uni-shadow-base;
+	}
+
+	.uni-fab__circle--leftBottom {
+		left: 15px;
+		bottom: 30px;
+		/* #ifdef H5 */
+		left: calc(15px + var(--window-left));
+		bottom: calc(30px + var(--window-bottom));
+		/* #endif */
+	}
+
+	.uni-fab__circle--leftTop {
+		left: 15px;
+		top: 30px;
+		/* #ifdef H5 */
+		left: calc(15px + var(--window-left));
+		top: calc(30px + var(--window-top));
+		/* #endif */
+	}
+
+	.uni-fab__circle--rightBottom {
+		right: 15px;
+		bottom: 30px;
+		/* #ifdef H5 */
+		right: calc(15px + var(--window-right));
+		bottom: calc(30px + var(--window-bottom));
+		/* #endif */
+	}
+
+	.uni-fab__circle--rightTop {
+		right: 15px;
+		top: 30px;
+		/* #ifdef H5 */
+		right: calc(15px + var(--window-right));
+		top: calc(30px + var(--window-top));
+		/* #endif */
+	}
+
+	.uni-fab__circle--left {
+		left: 0;
+	}
+
+	.uni-fab__circle--right {
+		right: 0;
+	}
+
+	.uni-fab__circle--top {
+		top: 0;
+	}
+
+	.uni-fab__circle--bottom {
+		bottom: 0;
+	}
+
+	.uni-fab__plus {
+		font-weight: bold;
+	}
+
+	// .fab-circle-v {
+	// 	position: absolute;
+	// 	width: 2px;
+	// 	height: 24px;
+	// 	left: 0;
+	// 	top: 0;
+	// 	right: 0;
+	// 	bottom: 0;
+	// 	/* #ifndef APP-NVUE */
+	// 	margin: auto;
+	// 	/* #endif */
+	// 	background-color: white;
+	// 	transform: rotate(0deg);
+	// 	transition: transform 0.3s;
+	// }
+
+	// .fab-circle-h {
+	// 	position: absolute;
+	// 	width: 24px;
+	// 	height: 2px;
+	// 	left: 0;
+	// 	top: 0;
+	// 	right: 0;
+	// 	bottom: 0;
+	// 	/* #ifndef APP-NVUE */
+	// 	margin: auto;
+	// 	/* #endif */
+	// 	background-color: white;
+	// 	transform: rotate(0deg);
+	// 	transition: transform 0.3s;
+	// }
+
+	.fab-circle-icon {
+		transform: rotate(0deg);
+		transition: transform 0.3s;
+		font-weight: 200;
+	}
+
+	.uni-fab__plus--active {
+		transform: rotate(135deg);
+	}
+
+	.uni-fab__content {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		border-radius: 55px;
+		overflow: hidden;
+		transition-property: width, height;
+		transition-duration: 0.2s;
+		width: 55px;
+		border-color: #DDDDDD;
+		border-width: 1rpx;
+		border-style: solid;
+	}
+
+	.uni-fab__content--other-platform {
+		border-width: 0px;
+		box-shadow: $uni-shadow-base;
+	}
+
+	.uni-fab__content--left {
+		justify-content: flex-start;
+	}
+
+	.uni-fab__content--right {
+		justify-content: flex-end;
+	}
+
+	.uni-fab__content--flexDirection {
+		flex-direction: column;
+		justify-content: flex-end;
+	}
+
+	.uni-fab__content--flexDirectionStart {
+		flex-direction: column;
+		justify-content: flex-start;
+	}
+
+	.uni-fab__content--flexDirectionEnd {
+		flex-direction: column;
+		justify-content: flex-end;
+	}
+
+	.uni-fab__item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 55px;
+		height: 55px;
+		opacity: 0;
+		transition: opacity 0.2s;
+	}
+
+	.uni-fab__item--active {
+		opacity: 1;
+	}
+
+	.uni-fab__item-image {
+		width: 20px;
+		height: 20px;
+		margin-bottom: 4px;
+	}
+
+	.uni-fab__item-text {
+		color: #FFFFFF;
+		font-size: 12px;
+		line-height: 12px;
+		margin-top: 2px;
+	}
+
+	.uni-fab__item--first {
+		width: 55px;
+	}
+</style>
diff --git a/uni_modules/uni-fab/package.json b/uni_modules/uni-fab/package.json
new file mode 100644
index 0000000..1b8543c
--- /dev/null
+++ b/uni_modules/uni-fab/package.json
@@ -0,0 +1,85 @@
+{
+  "id": "uni-fab",
+  "displayName": "uni-fab 悬浮按钮",
+  "version": "1.2.6",
+  "description": "悬浮按钮 fab button ,点击可展开一个图标按钮菜单。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "按钮",
+    "悬浮按钮",
+    "fab"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss","uni-icons"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-fab/readme.md b/uni_modules/uni-fab/readme.md
new file mode 100644
index 0000000..9a444e8
--- /dev/null
+++ b/uni_modules/uni-fab/readme.md
@@ -0,0 +1,9 @@
+## Fab 悬浮按钮
+> **组件名:uni-fab**
+> 代码块: `uFab`
+
+
+点击可展开一个图形按钮菜单
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-fab)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-fav/changelog.md b/uni_modules/uni-fav/changelog.md
new file mode 100644
index 0000000..d8a08d4
--- /dev/null
+++ b/uni_modules/uni-fav/changelog.md
@@ -0,0 +1,19 @@
+## 1.2.1(2022-05-30)
+- 新增 stat 属性 ,是否开启uni统计功能
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-fav](https://uniapp.dcloud.io/component/uniui/uni-fav)
+## 1.1.1(2021-08-24)
+- 新增 支持国际化
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.6(2021-05-12)
+- 新增 组件示例地址
+## 1.0.5(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.4(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.0.3(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.0.2(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/en.json b/uni_modules/uni-fav/components/uni-fav/i18n/en.json
new file mode 100644
index 0000000..9a0759e
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/i18n/en.json
@@ -0,0 +1,4 @@
+{
+	"uni-fav.collect": "collect",
+	"uni-fav.collected": "collected"
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/index.js b/uni_modules/uni-fav/components/uni-fav/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json
new file mode 100644
index 0000000..67c89bf
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json
@@ -0,0 +1,4 @@
+{
+	"uni-fav.collect": "收藏",
+	"uni-fav.collected": "已收藏"
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json
new file mode 100644
index 0000000..67c89bf
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json
@@ -0,0 +1,4 @@
+{
+	"uni-fav.collect": "收藏",
+	"uni-fav.collected": "已收藏"
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/uni-fav.vue b/uni_modules/uni-fav/components/uni-fav/uni-fav.vue
new file mode 100644
index 0000000..d2c58df
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/uni-fav.vue
@@ -0,0 +1,161 @@
+<template>
+	<view :class="[circle === true || circle === 'true' ? 'uni-fav--circle' : '']" :style="[{ backgroundColor: checked ? bgColorChecked : bgColor }]"
+	 @click="onClick" class="uni-fav">
+		<!-- #ifdef MP-ALIPAY -->
+		<view class="uni-fav-star" v-if="!checked && (star === true || star === 'true')">
+			<uni-icons :color="fgColor" :style="{color: checked ? fgColorChecked : fgColor}" size="14" type="star-filled" />
+		</view>
+		<!-- #endif -->
+		<!-- #ifndef MP-ALIPAY -->
+		<uni-icons :color="fgColor" :style="{color: checked ? fgColorChecked : fgColor}" class="uni-fav-star" size="14" type="star-filled"
+		 v-if="!checked && (star === true || star === 'true')" />
+		<!-- #endif -->
+		<text :style="{color: checked ? fgColorChecked : fgColor}" class="uni-fav-text">{{ checked ? contentFav : contentDefault }}</text>
+	</view>
+</template>
+
+<script>
+
+	/**
+	 * Fav 收藏按钮
+	 * @description 用于收藏功能,可点击切换选中、不选中的状态
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=864
+	 * @property {Boolean} star = [true|false] 按钮是否带星星
+	 * @property {String} bgColor 未收藏时的背景色
+	 * @property {String} bgColorChecked 已收藏时的背景色
+	 * @property {String} fgColor 未收藏时的文字颜色
+	 * @property {String} fgColorChecked 已收藏时的文字颜色
+	 * @property {Boolean} circle = [true|false] 是否为圆角
+	 * @property {Boolean} checked = [true|false] 是否为已收藏
+	 * @property {Object} contentText = [true|false] 收藏按钮文字
+	 * @property {Boolean} stat 是否开启统计功能
+	 * @event {Function} click 点击 fav按钮触发事件
+	 * @example <uni-fav :checked="true"/>
+	 */
+
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {	t	} = initVueI18n(messages)
+
+	export default {
+		name: "UniFav",
+		// TODO 兼容 vue3,需要注册事件
+		emits: ['click'],
+		props: {
+			star: {
+				type: [Boolean, String],
+				default: true
+			},
+			bgColor: {
+				type: String,
+				default: "#eeeeee"
+			},
+			fgColor: {
+				type: String,
+				default: "#666666"
+			},
+			bgColorChecked: {
+				type: String,
+				default: "#007aff"
+			},
+			fgColorChecked: {
+				type: String,
+				default: "#FFFFFF"
+			},
+			circle: {
+				type: [Boolean, String],
+				default: false
+			},
+			checked: {
+				type: Boolean,
+				default: false
+			},
+			contentText: {
+				type: Object,
+				default () {
+					return {
+						contentDefault: "",
+						contentFav: ""
+					};
+				}
+			},
+			stat:{
+				type: Boolean,
+				default: false
+			}
+		},
+		computed: {
+			contentDefault() {
+				return this.contentText.contentDefault || t("uni-fav.collect")
+			},
+			contentFav() {
+				return this.contentText.contentFav || t("uni-fav.collected")
+			},
+		},
+		watch: {
+			checked() {
+				if (uni.report && this.stat) {
+					if (this.checked) {
+						uni.report("收藏", "收藏");
+					} else {
+						uni.report("取消收藏", "取消收藏");
+					}
+				}
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit("click");
+			}
+		}
+	};
+</script>
+
+<style lang="scss" >
+	$fav-height: 25px;
+
+	.uni-fav {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		width: 60px;
+		height: $fav-height;
+		line-height: $fav-height;
+		text-align: center;
+		border-radius: 3px;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-fav--circle {
+		border-radius: 30px;
+	}
+
+	.uni-fav-star {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		height: $fav-height;
+		line-height: 24px;
+		margin-right: 3px;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.uni-fav-text {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		height: $fav-height;
+		line-height: $fav-height;
+		align-items: center;
+		justify-content: center;
+		font-size: 12px;
+	}
+</style>
diff --git a/uni_modules/uni-fav/package.json b/uni_modules/uni-fav/package.json
new file mode 100644
index 0000000..cc14697
--- /dev/null
+++ b/uni_modules/uni-fav/package.json
@@ -0,0 +1,89 @@
+{
+  "id": "uni-fav",
+  "displayName": "uni-fav 收藏按钮",
+  "version": "1.2.1",
+  "description": " Fav 收藏组件,可自定义颜色、大小。",
+  "keywords": [
+    "fav",
+    "uni-ui",
+    "uniui",
+    "收藏"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-fav/readme.md b/uni_modules/uni-fav/readme.md
new file mode 100644
index 0000000..4de125d
--- /dev/null
+++ b/uni_modules/uni-fav/readme.md
@@ -0,0 +1,10 @@
+
+
+## Fav 收藏按钮
+> **组件名:uni-fav**
+> 代码块: `uFav`
+
+用于收藏功能,可点击切换选中、不选中的状态。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-fav)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-file-picker/changelog.md b/uni_modules/uni-file-picker/changelog.md
new file mode 100644
index 0000000..b81e7f9
--- /dev/null
+++ b/uni_modules/uni-file-picker/changelog.md
@@ -0,0 +1,81 @@
+## 1.0.11(2024-07-19)
+- 修复 vue3 使用value报错的bug
+## 1.0.10(2024-07-09)
+- 优化 vue3兼容性
+## 1.0.9(2024-07-09)
+- 修复 value 属性不兼容vue3的bug
+## 1.0.8(2024-03-20)
+- 补充 删除文件时返回文件下标
+## 1.0.7(2024-02-21)
+- 新增 微信小程序选择视频时改用chooseMedia,并返回视频缩略图
+## 1.0.6(2024-01-06)
+- 新增 微信小程序不再调用chooseImage,而是调用chooseMedia
+## 1.0.5(2024-01-03)
+- 新增 上传文件至云存储携带本地文件名称
+## 1.0.4(2023-03-29)
+- 修复 手动上传删除一个文件后不能再上传的bug
+## 1.0.3(2022-12-19)
+- 新增 sourceType 属性, 可以自定义图片和视频选择的来源
+## 1.0.2(2022-07-04)
+- 修复 在uni-forms下样式不生效的bug
+## 1.0.1(2021-11-23)
+- 修复 参数为对象的情况下,url在某些情况显示错误的bug
+## 1.0.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-file-picker](https://uniapp.dcloud.io/component/uniui/uni-file-picker)
+## 0.2.16(2021-11-08)
+- 修复 传入空对象 ,显示错误的Bug
+## 0.2.15(2021-08-30)
+- 修复 return-type="object" 时且存在v-model时,无法删除文件的Bug
+## 0.2.14(2021-08-23)
+- 新增 参数中返回 fileID 字段
+## 0.2.13(2021-08-23)
+- 修复 腾讯云传入fileID 不能回显的bug
+- 修复 选择图片后,不能放大的问题
+## 0.2.12(2021-08-17)
+- 修复 由于 0.2.11 版本引起的不能回显图片的Bug
+## 0.2.11(2021-08-16)
+- 新增 clearFiles(index) 方法,可以手动删除指定文件
+- 修复 v-model 值设为 null 报错的Bug
+## 0.2.10(2021-08-13)
+- 修复 return-type="object" 时,无法删除文件的Bug
+## 0.2.9(2021-08-03)
+- 修复 auto-upload 属性失效的Bug
+## 0.2.8(2021-07-31)
+- 修复 fileExtname属性不指定值报错的Bug
+## 0.2.7(2021-07-31)
+- 修复 在某种场景下图片不回显的Bug
+## 0.2.6(2021-07-30)
+- 修复 return-type为object下,返回值不正确的Bug
+## 0.2.5(2021-07-30)
+- 修复(重要) H5 平台下如果和uni-forms组件一同使用导致页面卡死的问题
+## 0.2.3(2021-07-28)
+- 优化 调整示例代码
+## 0.2.2(2021-07-27)
+- 修复 vue3 下赋值错误的Bug
+- 优化 h5平台下上传文件导致页面卡死的问题
+## 0.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.1.1(2021-07-02)
+- 修复 sourceType 缺少默认值导致 ios 无法选择文件
+## 0.1.0(2021-06-30)
+- 优化 解耦与uniCloud的强绑定关系 ,如不绑定服务空间,默认autoUpload为false且不可更改
+## 0.0.11(2021-06-30)
+- 修复 由 0.0.10 版本引发的 returnType 属性失效的问题
+## 0.0.10(2021-06-29)
+- 优化 文件上传后进度条消失时机
+## 0.0.9(2021-06-29)
+- 修复 在uni-forms 中,删除文件 ,获取的值不对的Bug
+## 0.0.8(2021-06-15)
+- 修复 删除文件时无法触发 v-model 的Bug
+## 0.0.7(2021-05-12)
+- 新增 组件示例地址
+## 0.0.6(2021-04-09)
+- 修复 选择的文件非 file-extname 字段指定的扩展名报错的Bug
+## 0.0.5(2021-04-09)
+- 优化 更新组件示例
+## 0.0.4(2021-04-09)
+- 优化 file-extname 字段支持字符串写法,多个扩展名需要用逗号分隔
+## 0.0.3(2021-02-05)
+- 调整为uni_modules目录规范
+- 修复 微信小程序不指定 fileExtname 属性选择失败的Bug
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js b/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
new file mode 100644
index 0000000..9c6bcdf
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
@@ -0,0 +1,287 @@
+'use strict';
+
+const ERR_MSG_OK = 'chooseAndUploadFile:ok';
+const ERR_MSG_FAIL = 'chooseAndUploadFile:fail';
+
+function chooseImage(opts) {
+	const {
+		count,
+		sizeType = ['original', 'compressed'],
+		sourceType,
+		extension
+	} = opts
+	return new Promise((resolve, reject) => {
+		// 微信由于旧接口不再维护,针对微信小程序平台改用chooseMedia接口
+		// #ifdef MP-WEIXIN
+		uni.chooseMedia({
+			count,
+			sizeType,
+			sourceType,
+			mediaType: ['image'],
+			extension,
+			success(res) {
+				res.tempFiles.forEach(item => {
+					item.path = item.tempFilePath;
+				})
+				resolve(normalizeChooseAndUploadFileRes(res, 'image'));
+			},
+			fail(res) {
+				reject({
+					errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL),
+				});
+			},
+		})
+		// #endif
+		// #ifndef MP-WEIXIN
+		uni.chooseImage({
+			count,
+			sizeType,
+			sourceType,
+			extension,
+			success(res) {
+				resolve(normalizeChooseAndUploadFileRes(res, 'image'));
+			},
+			fail(res) {
+				reject({
+					errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL),
+				});
+			},
+		});
+		// #endif
+
+	});
+}
+
+function chooseVideo(opts) {
+	const {
+		count,
+		camera,
+		compressed,
+		maxDuration,
+		sourceType,
+		extension
+	} = opts;
+	return new Promise((resolve, reject) => {
+		// 微信由于旧接口不再维护,针对微信小程序平台改用chooseMedia接口
+		// #ifdef MP-WEIXIN
+		uni.chooseMedia({
+			count,
+			compressed,
+			maxDuration,
+			sourceType,
+			extension,
+			mediaType: ['video'],
+			success(res) {
+				const {
+					tempFiles,
+				} = res;
+				resolve(normalizeChooseAndUploadFileRes({
+					errMsg: 'chooseVideo:ok',
+					tempFiles: tempFiles.map(item => {
+						return {
+							name: item.name || '',
+							path: item.tempFilePath,
+							thumbTempFilePath: item.thumbTempFilePath,
+							size:item.size,
+							type: (res.tempFile && res.tempFile.type) || '',
+							width:item.width,
+							height:item.height,
+							duration:item.duration,
+							fileType: 'video',
+							cloudPath: '',
+						}
+					}),
+				}, 'video'));
+			},
+			fail(res) {
+				reject({
+					errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL),
+				});
+			},
+		})
+		// #endif
+		// #ifndef MP-WEIXIN
+		uni.chooseVideo({
+			camera,
+			compressed,
+			maxDuration,
+			sourceType,
+			extension,
+			success(res) {
+				const {
+					tempFilePath,
+					duration,
+					size,
+					height,
+					width
+				} = res;
+				resolve(normalizeChooseAndUploadFileRes({
+					errMsg: 'chooseVideo:ok',
+					tempFilePaths: [tempFilePath],
+					tempFiles: [{
+						name: (res.tempFile && res.tempFile.name) || '',
+						path: tempFilePath,
+						size,
+						type: (res.tempFile && res.tempFile.type) || '',
+						width,
+						height,
+						duration,
+						fileType: 'video',
+						cloudPath: '',
+					}, ],
+				}, 'video'));
+			},
+			fail(res) {
+				reject({
+					errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL),
+				});
+			},
+		});
+		// #endif
+	});
+}
+
+function chooseAll(opts) {
+	const {
+		count,
+		extension
+	} = opts;
+	return new Promise((resolve, reject) => {
+		let chooseFile = uni.chooseFile;
+		if (typeof wx !== 'undefined' &&
+			typeof wx.chooseMessageFile === 'function') {
+			chooseFile = wx.chooseMessageFile;
+		}
+		if (typeof chooseFile !== 'function') {
+			return reject({
+				errMsg: ERR_MSG_FAIL + ' 请指定 type 类型,该平台仅支持选择 image 或 video。',
+			});
+		}
+		chooseFile({
+			type: 'all',
+			count,
+			extension,
+			success(res) {
+				resolve(normalizeChooseAndUploadFileRes(res));
+			},
+			fail(res) {
+				reject({
+					errMsg: res.errMsg.replace('chooseFile:fail', ERR_MSG_FAIL),
+				});
+			},
+		});
+	});
+}
+
+function normalizeChooseAndUploadFileRes(res, fileType) {
+	res.tempFiles.forEach((item, index) => {
+		if (!item.name) {
+			item.name = item.path.substring(item.path.lastIndexOf('/') + 1);
+		}
+		if (fileType) {
+			item.fileType = fileType;
+		}
+		item.cloudPath =
+			Date.now() + '_' + index + item.name.substring(item.name.lastIndexOf('.'));
+	});
+	if (!res.tempFilePaths) {
+		res.tempFilePaths = res.tempFiles.map((file) => file.path);
+	}
+	return res;
+}
+
+function uploadCloudFiles(files, max = 5, onUploadProgress) {
+	files = JSON.parse(JSON.stringify(files))
+	const len = files.length
+	let count = 0
+	let self = this
+	return new Promise(resolve => {
+		while (count < max) {
+			next()
+		}
+
+		function next() {
+			let cur = count++
+			if (cur >= len) {
+				!files.find(item => !item.url && !item.errMsg) && resolve(files)
+				return
+			}
+			const fileItem = files[cur]
+			const index = self.files.findIndex(v => v.uuid === fileItem.uuid)
+			fileItem.url = ''
+			delete fileItem.errMsg
+
+			uniCloud
+				.uploadFile({
+					filePath: fileItem.path,
+					cloudPath: fileItem.cloudPath,
+					fileType: fileItem.fileType,
+					onUploadProgress: res => {
+						res.index = index
+						onUploadProgress && onUploadProgress(res)
+					}
+				})
+				.then(res => {
+					fileItem.url = res.fileID
+					fileItem.index = index
+					if (cur < len) {
+						next()
+					}
+				})
+				.catch(res => {
+					fileItem.errMsg = res.errMsg || res.message
+					fileItem.index = index
+					if (cur < len) {
+						next()
+					}
+				})
+		}
+	})
+}
+
+
+
+
+
+function uploadFiles(choosePromise, {
+	onChooseFile,
+	onUploadProgress
+}) {
+	return choosePromise
+		.then((res) => {
+			if (onChooseFile) {
+				const customChooseRes = onChooseFile(res);
+				if (typeof customChooseRes !== 'undefined') {
+					return Promise.resolve(customChooseRes).then((chooseRes) => typeof chooseRes === 'undefined' ?
+						res : chooseRes);
+				}
+			}
+			return res;
+		})
+		.then((res) => {
+			if (res === false) {
+				return {
+					errMsg: ERR_MSG_OK,
+					tempFilePaths: [],
+					tempFiles: [],
+				};
+			}
+			return res
+		})
+}
+
+function chooseAndUploadFile(opts = {
+	type: 'all'
+}) {
+	if (opts.type === 'image') {
+		return uploadFiles(chooseImage(opts), opts);
+	} else if (opts.type === 'video') {
+		return uploadFiles(chooseVideo(opts), opts);
+	}
+	return uploadFiles(chooseAll(opts), opts);
+}
+
+export {
+	chooseAndUploadFile,
+	uploadCloudFiles
+};
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
new file mode 100644
index 0000000..785c7eb
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
@@ -0,0 +1,668 @@
+<template>
+	<view class="uni-file-picker">
+		<view v-if="title" class="uni-file-picker__header">
+			<text class="file-title">{{ title }}</text>
+			<text class="file-count">{{ filesList.length }}/{{ limitLength }}</text>
+		</view>
+		<upload-image v-if="fileMediatype === 'image' && showType === 'grid'" :readonly="readonly"
+			:image-styles="imageStyles" :files-list="filesList" :limit="limitLength" :disablePreview="disablePreview"
+			:delIcon="delIcon" @uploadFiles="uploadFiles" @choose="choose" @delFile="delFile">
+			<slot>
+				<view class="is-add">
+					<view class="icon-add"></view>
+					<view class="icon-add rotate"></view>
+				</view>
+			</slot>
+		</upload-image>
+		<upload-file v-if="fileMediatype !== 'image' || showType !== 'grid'" :readonly="readonly"
+			:list-styles="listStyles" :files-list="filesList" :showType="showType" :delIcon="delIcon"
+			@uploadFiles="uploadFiles" @choose="choose" @delFile="delFile">
+			<slot><button type="primary" size="mini">选择文件</button></slot>
+		</upload-file>
+	</view>
+</template>
+
+<script>
+	import {
+		chooseAndUploadFile,
+		uploadCloudFiles
+	} from './choose-and-upload-file.js'
+	import {
+		get_file_ext,
+		get_extname,
+		get_files_and_is_max,
+		get_file_info,
+		get_file_data
+	} from './utils.js'
+	import uploadImage from './upload-image.vue'
+	import uploadFile from './upload-file.vue'
+	let fileInput = null
+	/**
+	 * FilePicker 文件选择上传
+	 * @description 文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=4079
+	 * @property {Object|Array}	value	组件数据,通常用来回显 ,类型由return-type属性决定
+	 * @property {Boolean}	disabled = [true|false]	组件禁用
+	 * 	@value true 	禁用
+	 * 	@value false 	取消禁用
+	 * @property {Boolean}	readonly = [true|false]	组件只读,不可选择,不显示进度,不显示删除按钮
+	 * 	@value true 	只读
+	 * 	@value false 	取消只读
+	 * @property {String}	return-type = [array|object]	限制 value 格式,当为 object 时 ,组件只能单选,且会覆盖
+	 * 	@value array	规定 value 属性的类型为数组
+	 * 	@value object	规定 value 属性的类型为对象
+	 * @property {Boolean}	disable-preview = [true|false]	禁用图片预览,仅 mode:grid 时生效
+	 * 	@value true 	禁用图片预览
+	 * 	@value false 	取消禁用图片预览
+	 * @property {Boolean}	del-icon = [true|false]	是否显示删除按钮
+	 * 	@value true 	显示删除按钮
+	 * 	@value false 	不显示删除按钮
+	 * @property {Boolean}	auto-upload = [true|false]	是否自动上传,值为true则只触发@select,可自行上传
+	 * 	@value true 	自动上传
+	 * 	@value false 	取消自动上传
+	 * @property {Number|String}	limit	最大选择个数 ,h5 会自动忽略多选的部分
+	 * @property {String}	title	组件标题,右侧显示上传计数
+	 * @property {String}	mode = [list|grid]	选择文件后的文件列表样式
+	 * 	@value list 	列表显示
+	 * 	@value grid 	宫格显示
+	 * @property {String}	file-mediatype = [image|video|all]	选择文件类型
+	 * 	@value image	只选择图片
+	 * 	@value video	只选择视频
+	 * 	@value all		选择所有文件
+	 * @property {Array}	file-extname	选择文件后缀,根据 file-mediatype 属性而不同
+	 * @property {Object}	list-style	mode:list 时的样式
+	 * @property {Object}	image-styles	选择文件后缀,根据 file-mediatype 属性而不同
+	 * @event {Function} select 	选择文件后触发
+	 * @event {Function} progress 文件上传时触发
+	 * @event {Function} success 	上传成功触发
+	 * @event {Function} fail 		上传失败触发
+	 * @event {Function} delete 	文件从列表移除时触发
+	 */
+	export default {
+		name: 'uniFilePicker',
+		components: {
+			uploadImage,
+			uploadFile
+		},
+		options: {
+			virtualHost: true
+		},
+		emits: ['select', 'success', 'fail', 'progress', 'delete', 'update:modelValue', 'input'],
+		props: {
+			modelValue: {
+				type: [Array, Object],
+				default () {
+					return []
+				}
+			},
+			value: {
+				type: [Array, Object],
+				default () {
+					return []
+				}
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			disablePreview: {
+				type: Boolean,
+				default: false
+			},
+			delIcon: {
+				type: Boolean,
+				default: true
+			},
+			// 自动上传
+			autoUpload: {
+				type: Boolean,
+				default: true
+			},
+			// 最大选择个数 ,h5只能限制单选或是多选
+			limit: {
+				type: [Number, String],
+				default: 9
+			},
+			// 列表样式 grid | list | list-card
+			mode: {
+				type: String,
+				default: 'grid'
+			},
+			// 选择文件类型  image/video/all
+			fileMediatype: {
+				type: String,
+				default: 'image'
+			},
+			// 文件类型筛选
+			fileExtname: {
+				type: [Array, String],
+				default () {
+					return []
+				}
+			},
+			title: {
+				type: String,
+				default: ''
+			},
+			listStyles: {
+				type: Object,
+				default () {
+					return {
+						// 是否显示边框
+						border: true,
+						// 是否显示分隔线
+						dividline: true,
+						// 线条样式
+						borderStyle: {}
+					}
+				}
+			},
+			imageStyles: {
+				type: Object,
+				default () {
+					return {
+						width: 'auto',
+						height: 'auto'
+					}
+				}
+			},
+			readonly: {
+				type: Boolean,
+				default: false
+			},
+			returnType: {
+				type: String,
+				default: 'array'
+			},
+			sizeType: {
+				type: Array,
+				default () {
+					return ['original', 'compressed']
+				}
+			},
+			sourceType: {
+				type: Array,
+				default () {
+					return  ['album', 'camera']
+				}
+			},
+			provider: {
+				type: String,
+				default: '' // 默认上传到 unicloud 内置存储 extStorage 扩展存储
+			}
+		},
+		data() {
+			return {
+				files: [],
+				localValue: []
+			}
+		},
+		watch: {
+			value: {
+				handler(newVal, oldVal) {
+					this.setValue(newVal, oldVal)
+				},
+				immediate: true
+			},
+			modelValue: {
+				handler(newVal, oldVal) {
+					this.setValue(newVal, oldVal)
+				},
+				immediate: true
+			},
+		},
+		computed: {
+			filesList() {
+				let files = []
+				this.files.forEach(v => {
+					files.push(v)
+				})
+				return files
+			},
+			showType() {
+				if (this.fileMediatype === 'image') {
+					return this.mode
+				}
+				return 'list'
+			},
+			limitLength() {
+				if (this.returnType === 'object') {
+					return 1
+				}
+				if (!this.limit) {
+					return 1
+				}
+				if (this.limit >= 9) {
+					return 9
+				}
+				return this.limit
+			}
+		},
+		created() {
+			// TODO 兼容不开通服务空间的情况
+			if (!(uniCloud.config && uniCloud.config.provider)) {
+				this.noSpace = true
+				uniCloud.chooseAndUploadFile = chooseAndUploadFile
+			}
+			this.form = this.getForm('uniForms')
+			this.formItem = this.getForm('uniFormsItem')
+			if (this.form && this.formItem) {
+				if (this.formItem.name) {
+					this.rename = this.formItem.name
+					this.form.inputChildrens.push(this)
+				}
+			}
+		},
+		methods: {
+			/**
+			 * 公开用户使用,清空文件
+			 * @param {Object} index
+			 */
+			clearFiles(index) {
+				if (index !== 0 && !index) {
+					this.files = []
+					this.$nextTick(() => {
+						this.setEmit()
+					})
+				} else {
+					this.files.splice(index, 1)
+				}
+				this.$nextTick(() => {
+					this.setEmit()
+				})
+			},
+			/**
+			 * 公开用户使用,继续上传
+			 */
+			upload() {
+				let files = []
+				this.files.forEach((v, index) => {
+					if (v.status === 'ready' || v.status === 'error') {
+						files.push(Object.assign({}, v))
+					}
+				})
+				return this.uploadFiles(files)
+			},
+			async setValue(newVal, oldVal) {
+				const newData =  async (v) => {
+					const reg = /cloud:\/\/([\w.]+\/?)\S*/
+					let url = ''
+					if(v.fileID){
+						url = v.fileID
+					}else{
+						url = v.url
+					}
+					if (reg.test(url)) {
+						v.fileID = url
+						v.url = await this.getTempFileURL(url)
+					}
+					if(v.url) v.path = v.url
+					return v
+				}
+				if (this.returnType === 'object') {
+					if (newVal) {
+						await newData(newVal)
+					} else {
+						newVal = {}
+					}
+				} else {
+					if (!newVal) newVal = []
+					for(let i =0 ;i < newVal.length ;i++){
+						let v = newVal[i]
+						await newData(v)
+					}
+				}
+				this.localValue = newVal
+				if (this.form && this.formItem &&!this.is_reset) {
+					this.is_reset = false
+					this.formItem.setValue(this.localValue)
+				}
+				let filesData = Object.keys(newVal).length > 0 ? newVal : [];
+				this.files = [].concat(filesData)
+			},
+
+			/**
+			 * 选择文件
+			 */
+			choose() {
+				if (this.disabled) return
+				if (this.files.length >= Number(this.limitLength) && this.showType !== 'grid' && this.returnType ===
+					'array') {
+					uni.showToast({
+						title: `您最多选择 ${this.limitLength} 个文件`,
+						icon: 'none'
+					})
+					return
+				}
+				this.chooseFiles()
+			},
+
+			/**
+			 * 选择文件并上传
+			 */
+			chooseFiles() {
+				const _extname = get_extname(this.fileExtname)
+				// 获取后缀
+				uniCloud
+					.chooseAndUploadFile({
+						type: this.fileMediatype,
+						compressed: false,
+						sizeType: this.sizeType,
+						sourceType: this.sourceType,
+						// TODO 如果为空,video 有问题
+						extension: _extname.length > 0 ? _extname : undefined,
+						count: this.limitLength - this.files.length, //默认9
+						onChooseFile: this.chooseFileCallback,
+						onUploadProgress: progressEvent => {
+							this.setProgress(progressEvent, progressEvent.index)
+						}
+					})
+					.then(result => {
+						this.setSuccessAndError(result.tempFiles)
+					})
+					.catch(err => {
+						console.log('选择失败', err)
+					})
+			},
+
+			/**
+			 * 选择文件回调
+			 * @param {Object} res
+			 */
+			async chooseFileCallback(res) {
+				const _extname = get_extname(this.fileExtname)
+				const is_one = (Number(this.limitLength) === 1 &&
+						this.disablePreview &&
+						!this.disabled) ||
+					this.returnType === 'object'
+				// 如果这有一个文件 ,需要清空本地缓存数据
+				if (is_one) {
+					this.files = []
+				}
+
+				let {
+					filePaths,
+					files
+				} = get_files_and_is_max(res, _extname)
+				if (!(_extname && _extname.length > 0)) {
+					filePaths = res.tempFilePaths
+					files = res.tempFiles
+				}
+
+				let currentData = []
+				for (let i = 0; i < files.length; i++) {
+					if (this.limitLength - this.files.length <= 0) break
+					files[i].uuid = Date.now()
+					let filedata = await get_file_data(files[i], this.fileMediatype)
+					filedata.progress = 0
+					filedata.status = 'ready'
+					this.files.push(filedata)
+					currentData.push({
+						...filedata,
+						file: files[i]
+					})
+				}
+				this.$emit('select', {
+					tempFiles: currentData,
+					tempFilePaths: filePaths
+				})
+				res.tempFiles = files
+				// 停止自动上传
+				if (!this.autoUpload || this.noSpace) {
+					res.tempFiles = []
+				}
+				res.tempFiles.forEach((fileItem, index) => {
+					this.provider && (fileItem.provider = this.provider);
+					const fileNameSplit = fileItem.name.split('.')
+					const ext = fileNameSplit.pop()
+					const fileName = fileNameSplit.join('.').replace(/[\s\/\?<>\\:\*\|":]/g, '_')
+					fileItem.cloudPath = fileName + '_' + Date.now() + '_' + index + '.' + ext
+				})
+			},
+
+			/**
+			 * 批传
+			 * @param {Object} e
+			 */
+			uploadFiles(files) {
+				files = [].concat(files)
+				return uploadCloudFiles.call(this, files, 5, res => {
+						this.setProgress(res, res.index, true)
+					})
+					.then(result => {
+						this.setSuccessAndError(result)
+						return result;
+					})
+					.catch(err => {
+						console.log(err)
+					})
+			},
+
+			/**
+			 * 成功或失败
+			 */
+			async setSuccessAndError(res, fn) {
+				let successData = []
+				let errorData = []
+				let tempFilePath = []
+				let errorTempFilePath = []
+				for (let i = 0; i < res.length; i++) {
+					const item = res[i]
+					const index = item.uuid ? this.files.findIndex(p => p.uuid === item.uuid) : item.index
+
+					if (index === -1 || !this.files) break
+					if (item.errMsg === 'request:fail') {
+						this.files[index].url = item.path
+						this.files[index].status = 'error'
+						this.files[index].errMsg = item.errMsg
+						// this.files[index].progress = -1
+						errorData.push(this.files[index])
+						errorTempFilePath.push(this.files[index].url)
+					} else {
+						this.files[index].errMsg = ''
+						this.files[index].fileID = item.url
+						const reg = /cloud:\/\/([\w.]+\/?)\S*/
+						if (reg.test(item.url)) {
+							this.files[index].url = await this.getTempFileURL(item.url)
+						}else{
+							this.files[index].url = item.url
+						}
+
+						this.files[index].status = 'success'
+						this.files[index].progress += 1
+						successData.push(this.files[index])
+						tempFilePath.push(this.files[index].fileID)
+					}
+				}
+
+				if (successData.length > 0) {
+					this.setEmit()
+					// 状态改变返回
+					this.$emit('success', {
+						tempFiles: this.backObject(successData),
+						tempFilePaths: tempFilePath
+					})
+				}
+
+				if (errorData.length > 0) {
+					this.$emit('fail', {
+						tempFiles: this.backObject(errorData),
+						tempFilePaths: errorTempFilePath
+					})
+				}
+			},
+
+			/**
+			 * 获取进度
+			 * @param {Object} progressEvent
+			 * @param {Object} index
+			 * @param {Object} type
+			 */
+			setProgress(progressEvent, index, type) {
+				const fileLenth = this.files.length
+				const percentNum = (index / fileLenth) * 100
+				const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
+				let idx = index
+				if (!type) {
+					idx = this.files.findIndex(p => p.uuid === progressEvent.tempFile.uuid)
+				}
+				if (idx === -1 || !this.files[idx]) return
+				// fix by mehaotian 100 就会消失,-1 是为了让进度条消失
+				this.files[idx].progress = percentCompleted - 1
+				// 上传中
+				this.$emit('progress', {
+					index: idx,
+					progress: parseInt(percentCompleted),
+					tempFile: this.files[idx]
+				})
+			},
+
+			/**
+			 * 删除文件
+			 * @param {Object} index
+			 */
+			delFile(index) {
+				this.$emit('delete', {
+					index,
+					tempFile: this.files[index],
+					tempFilePath: this.files[index].url
+				})
+				this.files.splice(index, 1)
+				this.$nextTick(() => {
+					this.setEmit()
+				})
+			},
+
+			/**
+			 * 获取文件名和后缀
+			 * @param {Object} name
+			 */
+			getFileExt(name) {
+				const last_len = name.lastIndexOf('.')
+				const len = name.length
+				return {
+					name: name.substring(0, last_len),
+					ext: name.substring(last_len + 1, len)
+				}
+			},
+
+			/**
+			 * 处理返回事件
+			 */
+			setEmit() {
+				let data = []
+				if (this.returnType === 'object') {
+					data = this.backObject(this.files)[0]
+					this.localValue = data?data:null
+				} else {
+					data = this.backObject(this.files)
+					if (!this.localValue) {
+						this.localValue = []
+					}
+					this.localValue = [...data]
+				}
+				// #ifdef VUE3
+				this.$emit('update:modelValue', this.localValue)
+				// #endif
+				// #ifndef VUE3
+				this.$emit('input', this.localValue)
+				// #endif
+			},
+
+			/**
+			 * 处理返回参数
+			 * @param {Object} files
+			 */
+			backObject(files) {
+				let newFilesData = []
+				files.forEach(v => {
+					newFilesData.push({
+						extname: v.extname,
+						fileType: v.fileType,
+						image: v.image,
+						name: v.name,
+						path: v.path,
+						size: v.size,
+						fileID:v.fileID,
+						url: v.url,
+						// 修改删除一个文件后不能再上传的bug, #694
+            uuid: v.uuid,
+            status: v.status,
+            cloudPath: v.cloudPath
+					})
+				})
+				return newFilesData
+			},
+			async getTempFileURL(fileList) {
+				fileList = {
+					fileList: [].concat(fileList)
+				}
+				const urls = await uniCloud.getTempFileURL(fileList)
+				return urls.fileList[0].tempFileURL || ''
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniForms') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false;
+					parentName = parent.$options.name;
+				}
+				return parent;
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-file-picker {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		overflow: hidden;
+		width: 100%;
+		/* #endif */
+		flex: 1;
+	}
+
+	.uni-file-picker__header {
+		padding-top: 5px;
+		padding-bottom: 10px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: space-between;
+	}
+
+	.file-title {
+		font-size: 14px;
+		color: #333;
+	}
+
+	.file-count {
+		font-size: 14px;
+		color: #999;
+	}
+
+	.is-add {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		justify-content: center;
+	}
+
+	.icon-add {
+		width: 50px;
+		height: 5px;
+		background-color: #f1f1f1;
+		border-radius: 2px;
+	}
+
+	.rotate {
+		position: absolute;
+		transform: rotate(90deg);
+	}
+</style>
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue b/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue
new file mode 100644
index 0000000..625d92e
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue
@@ -0,0 +1,325 @@
+<template>
+	<view class="uni-file-picker__files">
+		<view v-if="!readonly" class="files-button" @click="choose">
+			<slot></slot>
+		</view>
+		<!-- :class="{'is-text-box':showType === 'list'}" -->
+		<view v-if="list.length > 0" class="uni-file-picker__lists is-text-box" :style="borderStyle">
+			<!-- ,'is-list-card':showType === 'list-card' -->
+
+			<view class="uni-file-picker__lists-box" v-for="(item ,index) in list" :key="index" :class="{
+				'files-border':index !== 0 && styles.dividline}"
+			 :style="index !== 0 && styles.dividline &&borderLineStyle">
+				<view class="uni-file-picker__item">
+					<!-- :class="{'is-text-image':showType === 'list'}" -->
+					<!-- 	<view class="files__image is-text-image">
+						<image class="header-image" :src="item.logo" mode="aspectFit"></image>
+					</view> -->
+					<view class="files__name">{{item.name}}</view>
+					<view v-if="delIcon&&!readonly" class="icon-del-box icon-files" @click="delFile(index)">
+						<view class="icon-del icon-files"></view>
+						<view class="icon-del rotate"></view>
+					</view>
+				</view>
+				<view v-if="(item.progress && item.progress !== 100) ||item.progress===0 " class="file-picker__progress">
+					<progress class="file-picker__progress-item" :percent="item.progress === -1?0:item.progress" stroke-width="4"
+					 :backgroundColor="item.errMsg?'#ff5a5f':'#EBEBEB'" />
+				</view>
+				<view v-if="item.status === 'error'" class="file-picker__mask" @click.stop="uploadFiles(item,index)">
+					点击重试
+				</view>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "uploadFile",
+		emits:['uploadFiles','choose','delFile'],
+		props: {
+			filesList: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			delIcon: {
+				type: Boolean,
+				default: true
+			},
+			limit: {
+				type: [Number, String],
+				default: 9
+			},
+			showType: {
+				type: String,
+				default: ''
+			},
+			listStyles: {
+				type: Object,
+				default () {
+					return {
+						// 是否显示边框
+						border: true,
+						// 是否显示分隔线
+						dividline: true,
+						// 线条样式
+						borderStyle: {}
+					}
+				}
+			},
+			readonly:{
+				type:Boolean,
+				default:false
+			}
+		},
+		computed: {
+			list() {
+				let files = []
+				this.filesList.forEach(v => {
+					files.push(v)
+				})
+				return files
+			},
+			styles() {
+				let styles = {
+					border: true,
+					dividline: true,
+					'border-style': {}
+				}
+				return Object.assign(styles, this.listStyles)
+			},
+			borderStyle() {
+				let {
+					borderStyle,
+					border
+				} = this.styles
+				let obj = {}
+				if (!border) {
+					obj.border = 'none'
+				} else {
+					let width = (borderStyle && borderStyle.width) || 1
+					width = this.value2px(width)
+					let radius = (borderStyle && borderStyle.radius) || 5
+					radius = this.value2px(radius)
+					obj = {
+						'border-width': width,
+						'border-style': (borderStyle && borderStyle.style) || 'solid',
+						'border-color': (borderStyle && borderStyle.color) || '#eee',
+						'border-radius': radius
+					}
+				}
+				let classles = ''
+				for (let i in obj) {
+					classles += `${i}:${obj[i]};`
+				}
+				return classles
+			},
+			borderLineStyle() {
+				let obj = {}
+				let {
+					borderStyle
+				} = this.styles
+				if (borderStyle && borderStyle.color) {
+					obj['border-color'] = borderStyle.color
+				}
+				if (borderStyle && borderStyle.width) {
+					let width = borderStyle && borderStyle.width || 1
+					let style = borderStyle && borderStyle.style || 0
+					if (typeof width === 'number') {
+						width += 'px'
+					} else {
+						width = width.indexOf('px') ? width : width + 'px'
+					}
+					obj['border-width'] = width
+
+					if (typeof style === 'number') {
+						style += 'px'
+					} else {
+						style = style.indexOf('px') ? style : style + 'px'
+					}
+					obj['border-top-style'] = style
+				}
+				let classles = ''
+				for (let i in obj) {
+					classles += `${i}:${obj[i]};`
+				}
+				return classles
+			}
+		},
+
+		methods: {
+			uploadFiles(item, index) {
+				this.$emit("uploadFiles", {
+					item,
+					index
+				})
+			},
+			choose() {
+				this.$emit("choose")
+			},
+			delFile(index) {
+				this.$emit('delFile', index)
+			},
+			value2px(value) {
+				if (typeof value === 'number') {
+					value += 'px'
+				} else {
+					value = value.indexOf('px') !== -1 ? value : value + 'px'
+				}
+				return value
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.uni-file-picker__files {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: flex-start;
+	}
+
+	.files-button {
+		// border: 1px red solid;
+	}
+
+	.uni-file-picker__lists {
+		position: relative;
+		margin-top: 5px;
+		overflow: hidden;
+	}
+
+	.file-picker__mask {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		color: #fff;
+		font-size: 14px;
+		background-color: rgba(0, 0, 0, 0.4);
+	}
+
+	.uni-file-picker__lists-box {
+		position: relative;
+	}
+
+	.uni-file-picker__item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		padding: 8px 10px;
+		padding-right: 5px;
+		padding-left: 10px;
+	}
+
+	.files-border {
+		border-top: 1px #eee solid;
+	}
+
+	.files__name {
+		flex: 1;
+		font-size: 14px;
+		color: #666;
+		margin-right: 25px;
+		/* #ifndef APP-NVUE */
+		word-break: break-all;
+		word-wrap: break-word;
+		/* #endif */
+	}
+
+	.icon-files {
+		/* #ifndef APP-NVUE */
+		position: static;
+		background-color: initial;
+		/* #endif */
+	}
+
+	// .icon-files .icon-del {
+	// 	background-color: #333;
+	// 	width: 12px;
+	// 	height: 1px;
+	// }
+
+
+	.is-list-card {
+		border: 1px #eee solid;
+		margin-bottom: 5px;
+		border-radius: 5px;
+		box-shadow: 0 0 2px 0px rgba(0, 0, 0, 0.1);
+		padding: 5px;
+	}
+
+	.files__image {
+		width: 40px;
+		height: 40px;
+		margin-right: 10px;
+	}
+
+	.header-image {
+		width: 100%;
+		height: 100%;
+	}
+
+	.is-text-box {
+		border: 1px #eee solid;
+		border-radius: 5px;
+	}
+
+	.is-text-image {
+		width: 25px;
+		height: 25px;
+		margin-left: 5px;
+	}
+
+	.rotate {
+		position: absolute;
+		transform: rotate(90deg);
+	}
+
+	.icon-del-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		margin: auto 0;
+		/* #endif */
+		align-items: center;
+		justify-content: center;
+		position: absolute;
+		top: 0px;
+		bottom: 0;
+		right: 5px;
+		height: 26px;
+		width: 26px;
+		// border-radius: 50%;
+		// background-color: rgba(0, 0, 0, 0.5);
+		z-index: 2;
+		transform: rotate(-45deg);
+	}
+
+	.icon-del {
+		width: 15px;
+		height: 1px;
+		background-color: #333;
+		// border-radius: 1px;
+	}
+
+	/* #ifdef H5 */
+	@media all and (min-width: 768px) {
+		.uni-file-picker__files {
+			max-width: 375px;
+		}
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue
new file mode 100644
index 0000000..2a29bc2
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue
@@ -0,0 +1,292 @@
+<template>
+	<view class="uni-file-picker__container">
+		<view class="file-picker__box" v-for="(item,index) in filesList" :key="index" :style="boxStyle">
+			<view class="file-picker__box-content" :style="borderStyle">
+				<image class="file-image" :src="item.url" mode="aspectFill" @click.stop="prviewImage(item,index)"></image>
+				<view v-if="delIcon && !readonly" class="icon-del-box" @click.stop="delFile(index)">
+					<view class="icon-del"></view>
+					<view class="icon-del rotate"></view>
+				</view>
+				<view v-if="(item.progress && item.progress !== 100) ||item.progress===0 " class="file-picker__progress">
+					<progress class="file-picker__progress-item" :percent="item.progress === -1?0:item.progress" stroke-width="4"
+					 :backgroundColor="item.errMsg?'#ff5a5f':'#EBEBEB'" />
+				</view>
+				<view v-if="item.errMsg" class="file-picker__mask" @click.stop="uploadFiles(item,index)">
+					点击重试
+				</view>
+			</view>
+		</view>
+		<view v-if="filesList.length < limit && !readonly" class="file-picker__box" :style="boxStyle">
+			<view class="file-picker__box-content is-add" :style="borderStyle" @click="choose">
+				<slot>
+					<view class="icon-add"></view>
+					<view class="icon-add rotate"></view>
+				</slot>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "uploadImage",
+		emits:['uploadFiles','choose','delFile'],
+		props: {
+			filesList: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			disabled:{
+				type: Boolean,
+				default: false
+			},
+			disablePreview: {
+				type: Boolean,
+				default: false
+			},
+			limit: {
+				type: [Number, String],
+				default: 9
+			},
+			imageStyles: {
+				type: Object,
+				default () {
+					return {
+						width: 'auto',
+						height: 'auto',
+						border: {}
+					}
+				}
+			},
+			delIcon: {
+				type: Boolean,
+				default: true
+			},
+			readonly:{
+				type:Boolean,
+				default:false
+			}
+		},
+		computed: {
+			styles() {
+				let styles = {
+					width: 'auto',
+					height: 'auto',
+					border: {}
+				}
+				return Object.assign(styles, this.imageStyles)
+			},
+			boxStyle() {
+				const {
+					width = 'auto',
+						height = 'auto'
+				} = this.styles
+				let obj = {}
+				if (height === 'auto') {
+					if (width !== 'auto') {
+						obj.height = this.value2px(width)
+						obj['padding-top'] = 0
+					} else {
+						obj.height = 0
+					}
+				} else {
+					obj.height = this.value2px(height)
+					obj['padding-top'] = 0
+				}
+
+				if (width === 'auto') {
+					if (height !== 'auto') {
+						obj.width = this.value2px(height)
+					} else {
+						obj.width = '33.3%'
+					}
+				} else {
+					obj.width = this.value2px(width)
+				}
+
+				let classles = ''
+				for(let i in obj){
+					classles+= `${i}:${obj[i]};`
+				}
+				return classles
+			},
+			borderStyle() {
+				let {
+					border
+				} = this.styles
+				let obj = {}
+				const widthDefaultValue = 1
+				const radiusDefaultValue = 3
+				if (typeof border === 'boolean') {
+					obj.border = border ? '1px #eee solid' : 'none'
+				} else {
+					let width = (border && border.width) || widthDefaultValue
+					width = this.value2px(width)
+					let radius = (border && border.radius) || radiusDefaultValue
+					radius = this.value2px(radius)
+					obj = {
+						'border-width': width,
+						'border-style': (border && border.style) || 'solid',
+						'border-color': (border && border.color) || '#eee',
+						'border-radius': radius
+					}
+				}
+				let classles = ''
+				for(let i in obj){
+					classles+= `${i}:${obj[i]};`
+				}
+				return classles
+			}
+		},
+		methods: {
+			uploadFiles(item, index) {
+				this.$emit("uploadFiles", item)
+			},
+			choose() {
+				this.$emit("choose")
+			},
+			delFile(index) {
+				this.$emit('delFile', index)
+			},
+			prviewImage(img, index) {
+				let urls = []
+				if(Number(this.limit) === 1&&this.disablePreview&&!this.disabled){
+					this.$emit("choose")
+				}
+				if(this.disablePreview) return
+				this.filesList.forEach(i => {
+					urls.push(i.url)
+				})
+
+				uni.previewImage({
+					urls: urls,
+					current: index
+				});
+			},
+			value2px(value) {
+				if (typeof value === 'number') {
+					value += 'px'
+				} else {
+					if (value.indexOf('%') === -1) {
+						value = value.indexOf('px') !== -1 ? value : value + 'px'
+					}
+				}
+				return value
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.uni-file-picker__container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-wrap: wrap;
+		margin: -5px;
+	}
+
+	.file-picker__box {
+		position: relative;
+		// flex: 0 0 33.3%;
+		width: 33.3%;
+		height: 0;
+		padding-top: 33.33%;
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		/* #endif */
+	}
+
+	.file-picker__box-content {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		margin: 5px;
+		border: 1px #eee solid;
+		border-radius: 5px;
+		overflow: hidden;
+	}
+
+	.file-picker__progress {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		/* border: 1px red solid; */
+		z-index: 2;
+	}
+
+	.file-picker__progress-item {
+		width: 100%;
+	}
+
+	.file-picker__mask {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		color: #fff;
+		font-size: 12px;
+		background-color: rgba(0, 0, 0, 0.4);
+	}
+
+	.file-image {
+		width: 100%;
+		height: 100%;
+	}
+
+	.is-add {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		justify-content: center;
+	}
+
+	.icon-add {
+		width: 50px;
+		height: 5px;
+		background-color: #f1f1f1;
+		border-radius: 2px;
+	}
+
+	.rotate {
+		position: absolute;
+		transform: rotate(90deg);
+	}
+
+	.icon-del-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		justify-content: center;
+		position: absolute;
+		top: 3px;
+		right: 3px;
+		height: 26px;
+		width: 26px;
+		border-radius: 50%;
+		background-color: rgba(0, 0, 0, 0.5);
+		z-index: 2;
+		transform: rotate(-45deg);
+	}
+
+	.icon-del {
+		width: 15px;
+		height: 2px;
+		background-color: #fff;
+		border-radius: 2px;
+	}
+</style>
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/utils.js b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js
new file mode 100644
index 0000000..1bc9259
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js
@@ -0,0 +1,110 @@
+/**
+ * 获取文件名和后缀
+ * @param {String} name
+ */
+export const get_file_ext = (name) => {
+	const last_len = name.lastIndexOf('.')
+	const len = name.length
+	return {
+		name: name.substring(0, last_len),
+		ext: name.substring(last_len + 1, len)
+	}
+}
+
+/**
+ * 获取扩展名
+ * @param {Array} fileExtname
+ */
+export const get_extname = (fileExtname) => {
+	if (!Array.isArray(fileExtname)) {
+		let extname = fileExtname.replace(/(\[|\])/g, '')
+		return extname.split(',')
+	} else {
+		return fileExtname
+	}
+	return []
+}
+
+/**
+ * 获取文件和检测是否可选
+ */
+export const get_files_and_is_max = (res, _extname) => {
+	let filePaths = []
+	let files = []
+	if(!_extname || _extname.length === 0){
+		return {
+			filePaths,
+			files
+		}
+	}
+	res.tempFiles.forEach(v => {
+		let fileFullName = get_file_ext(v.name)
+		const extname = fileFullName.ext.toLowerCase()
+		if (_extname.indexOf(extname) !== -1) {
+			files.push(v)
+			filePaths.push(v.path)
+		}
+	})
+	if (files.length !== res.tempFiles.length) {
+		uni.showToast({
+			title: `当前选择了${res.tempFiles.length}个文件 ,${res.tempFiles.length - files.length} 个文件格式不正确`,
+			icon: 'none',
+			duration: 5000
+		})
+	}
+
+	return {
+		filePaths,
+		files
+	}
+}
+
+
+/**
+ * 获取图片信息
+ * @param {Object} filepath
+ */
+export const get_file_info = (filepath) => {
+	return new Promise((resolve, reject) => {
+		uni.getImageInfo({
+			src: filepath,
+			success(res) {
+				resolve(res)
+			},
+			fail(err) {
+				reject(err)
+			}
+		})
+	})
+}
+/**
+ * 获取封装数据
+ */
+export const get_file_data = async (files, type = 'image') => {
+	// 最终需要上传数据库的数据
+	let fileFullName = get_file_ext(files.name)
+	const extname = fileFullName.ext.toLowerCase()
+	let filedata = {
+		name: files.name,
+		uuid: files.uuid,
+		extname: extname || '',
+		cloudPath: files.cloudPath,
+		fileType: files.fileType,
+		thumbTempFilePath: files.thumbTempFilePath,
+		url: files.path || files.path,
+		size: files.size, //单位是字节
+		image: {},
+		path: files.path,
+		video: {}
+	}
+	if (type === 'image') {
+		const imageinfo = await get_file_info(files.path)
+		delete filedata.video
+		filedata.image.width = imageinfo.width
+		filedata.image.height = imageinfo.height
+		filedata.image.location = imageinfo.path
+	} else {
+		delete filedata.image
+	}
+	return filedata
+}
diff --git a/uni_modules/uni-file-picker/package.json b/uni_modules/uni-file-picker/package.json
new file mode 100644
index 0000000..34bb18f
--- /dev/null
+++ b/uni_modules/uni-file-picker/package.json
@@ -0,0 +1,84 @@
+{
+  "id": "uni-file-picker",
+  "displayName": "uni-file-picker 文件选择上传",
+  "version": "1.0.11",
+  "description": "文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "图片上传",
+    "文件上传"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-file-picker/readme.md b/uni_modules/uni-file-picker/readme.md
new file mode 100644
index 0000000..c8399a5
--- /dev/null
+++ b/uni_modules/uni-file-picker/readme.md
@@ -0,0 +1,11 @@
+
+## FilePicker 文件选择上传
+
+> **组件名:uni-file-picker**
+>  代码块: `uFilePicker`
+
+
+文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-file-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-forms/changelog.md b/uni_modules/uni-forms/changelog.md
new file mode 100644
index 0000000..0b58ab8
--- /dev/null
+++ b/uni_modules/uni-forms/changelog.md
@@ -0,0 +1,100 @@
+## 1.4.13(2024-10-08)
+- 修复 校验规则在抖音开发者工具上不生效的bug,详见:[https://ask.dcloud.net.cn/question/191933](https://ask.dcloud.net.cn/question/191933)
+## 1.4.12 (2024-9-21)
+- 修复 form上次修改的问题
+## 1.4.11 (2024-9-14)
+- 修复 binddata的兼容性问题
+## 1.4.10(2023-11-03)
+- 优化 labelWidth 描述错误
+## 1.4.9(2023-02-10)
+- 修复 required 参数无法动态绑定
+## 1.4.8(2022-08-23)
+- 优化 根据 rules 自动添加 required 的问题
+## 1.4.7(2022-08-22)
+- 修复 item 未设置 require 属性,rules 设置 require 后,星号也显示的 bug,详见:[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540)
+## 1.4.6(2022-07-13)
+- 修复 model 需要校验的值没有声明对应字段时,导致第一次不触发校验的bug
+## 1.4.5(2022-07-05)
+- 新增 更多表单示例
+- 优化 子表单组件过期提示的问题
+- 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
+## 1.4.4(2022-07-04)
+- 更新 删除组件日志
+## 1.4.3(2022-07-04)
+- 修复 由 1.4.0 引发的 label 插槽不生效的bug
+## 1.4.2(2022-07-04)
+- 修复 子组件找不到 setValue 报错的bug
+## 1.4.1(2022-07-04)
+- 修复 uni-data-picker 在 uni-forms-item 中报错的bug
+- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+## 1.4.0(2022-06-30)
+- 【重要】组件逻辑重构,部分用法用旧版本不兼容,请注意兼容问题
+- 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
+- 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
+- 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
+- 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
+- 新增 子表单的 setRules 方法,配合自定义校验函数使用
+- 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
+- 优化 动态表单校验方式,废弃拼接name的方式
+## 1.3.3(2022-06-22)
+- 修复 表单校验顺序无序问题
+## 1.3.2(2021-12-09)
+-
+## 1.3.1(2021-11-19)
+- 修复 label 插槽不生效的bug
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-forms](https://uniapp.dcloud.io/component/uniui/uni-forms)
+## 1.2.7(2021-08-13)
+- 修复 没有添加校验规则的字段依然报错的Bug
+## 1.2.6(2021-08-11)
+- 修复 重置表单错误信息无法清除的问题
+## 1.2.5(2021-08-11)
+- 优化 组件文档
+## 1.2.4(2021-08-11)
+- 修复 表单验证只生效一次的问题
+## 1.2.3(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.2.2(2021-07-26)
+- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
+- 修复 1.2.1 引起的示例在小程序平台报错的Bug
+## 1.2.1(2021-07-22)
+- 修复 动态校验表单,默认值为空的情况下校验失效的Bug
+- 修复 不指定name属性时,运行报错的Bug
+- 优化 label默认宽度从65调整至70,使required为true且四字时不换行
+- 优化 组件示例,新增动态校验示例代码
+- 优化 组件文档,使用方式更清晰
+## 1.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.2(2021-06-25)
+- 修复 pattern 属性在微信小程序平台无效的问题
+## 1.1.1(2021-06-22)
+- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
+## 1.1.0(2021-06-22)
+- 修复 只写setRules方法而导致校验不生效的Bug
+- 修复 由上个办法引发的错误提示文字错位的Bug
+## 1.0.48(2021-06-21)
+- 修复 不设置 label 属性 ,无法设置label插槽的问题
+## 1.0.47(2021-06-21)
+- 修复 不设置label属性,label-width属性不生效的bug
+- 修复 setRules 方法与rules属性冲突的问题
+## 1.0.46(2021-06-04)
+- 修复 动态删减数据导致报错的问题
+## 1.0.45(2021-06-04)
+- 新增 modelValue 属性 ,value 即将废弃
+## 1.0.44(2021-06-02)
+- 新增 uni-forms-item 可以设置单独的 rules
+- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
+- 优化 submit 事件重命名为 validate
+## 1.0.43(2021-05-12)
+- 新增 组件示例地址
+## 1.0.42(2021-04-30)
+- 修复 自定义检验器失效的问题
+## 1.0.41(2021-03-05)
+- 更新 校验器
+- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug
+## 1.0.40(2021-03-04)
+- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug
+## 1.0.39(2021-02-05)
+- 调整为uni_modules目录规范
+- 修复 校验器传入 int 等类型 ,返回String类型的Bug
diff --git a/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue b/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
new file mode 100644
index 0000000..c924882
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
@@ -0,0 +1,632 @@
+<template>
+	<view class="uni-forms-item"
+		:class="['is-direction-' + localLabelPos ,border?'uni-forms-item--border':'' ,border && isFirstBorder?'is-first-border':'']">
+		<slot name="label">
+			<view class="uni-forms-item__label" :class="{'no-label':!label && !required}"
+				:style="{width:localLabelWidth,justifyContent: localLabelAlign}">
+				<text v-if="required" class="is-required">*</text>
+				<text>{{label}}</text>
+			</view>
+		</slot>
+		<!-- #ifndef APP-NVUE -->
+		<view class="uni-forms-item__content">
+			<slot></slot>
+			<view class="uni-forms-item__error" :class="{'msg--active':msg}">
+				<text>{{msg}}</text>
+			</view>
+		</view>
+		<!-- #endif -->
+		<!-- #ifdef APP-NVUE -->
+		<view class="uni-forms-item__nuve-content">
+			<view class="uni-forms-item__content">
+				<slot></slot>
+			</view>
+			<view class="uni-forms-item__error" :class="{'msg--active':msg}">
+				<text class="error-text">{{msg}}</text>
+			</view>
+		</view>
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	/**
+	 * uni-fomrs-item 表单子组件
+	 * @description uni-fomrs-item 表单子组件,提供了基础布局已经校验能力
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=2773
+	 * @property {Boolean} required 是否必填,左边显示红色"*"号
+	 * @property {String } 	label 				输入框左边的文字提示
+	 * @property {Number } 	labelWidth 			label的宽度,单位px(默认70)
+	 * @property {String } 	labelAlign = [left|center|right] label的文字对齐方式(默认left)
+	 * 	@value left		label 左侧显示
+	 * 	@value center	label 居中
+	 * 	@value right	label 右侧对齐
+	 * @property {String } 	errorMessage 		显示的错误提示内容,如果为空字符串或者false,则不显示错误信息
+	 * @property {String } 	name 				表单域的属性名,在使用校验规则时必填
+	 * @property {String } 	leftIcon 			【1.4.0废弃】label左边的图标,限 uni-ui 的图标名称
+	 * @property {String } 	iconColor 		【1.4.0废弃】左边通过icon配置的图标的颜色(默认#606266)
+	 * @property {String} validateTrigger = [bind|submit|blur]	【1.4.0废弃】校验触发器方式 默认 submit
+	 * 	@value bind 	发生变化时触发
+	 * 	@value submit 提交时触发
+	 * 	@value blur 	失去焦点触发
+	 * @property {String } 	labelPosition = [top|left] 【1.4.0废弃】label的文字的位置(默认left)
+	 * 	@value top	顶部显示 label
+	 * 	@value left	左侧显示 label
+	 */
+
+	export default {
+		name: 'uniFormsItem',
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		provide() {
+			return {
+				uniFormItem: this
+			}
+		},
+		inject: {
+			form: {
+				from: 'uniForm',
+				default: null
+			},
+		},
+		props: {
+			// 表单校验规则
+			rules: {
+				type: Array,
+				default () {
+					return null;
+				}
+			},
+			// 表单域的属性名,在使用校验规则时必填
+			name: {
+				type: [String, Array],
+				default: ''
+			},
+			required: {
+				type: Boolean,
+				default: false
+			},
+			label: {
+				type: String,
+				default: ''
+			},
+			// label的宽度
+			labelWidth: {
+				type: [String, Number],
+				default: ''
+			},
+			// label 居中方式,默认 left 取值 left/center/right
+			labelAlign: {
+				type: String,
+				default: ''
+			},
+			// 强制显示错误信息
+			errorMessage: {
+				type: [String, Boolean],
+				default: ''
+			},
+			// 1.4.0 弃用,统一使用 form 的校验时机
+			// validateTrigger: {
+			// 	type: String,
+			// 	default: ''
+			// },
+			// 1.4.0 弃用,统一使用 form 的label 位置
+			// labelPosition: {
+			// 	type: String,
+			// 	default: ''
+			// },
+			// 1.4.0 以下属性已经废弃,请使用  #label 插槽代替
+			leftIcon: String,
+			iconColor: {
+				type: String,
+				default: '#606266'
+			},
+		},
+		data() {
+			return {
+				errMsg: '',
+				userRules: null,
+				localLabelAlign: 'left',
+				localLabelWidth: '70px',
+				localLabelPos: 'left',
+				border: false,
+				isFirstBorder: false,
+			};
+		},
+		computed: {
+			// 处理错误信息
+			msg() {
+				return this.errorMessage || this.errMsg;
+			}
+		},
+		watch: {
+			// 规则发生变化通知子组件更新
+			'form.formRules'(val) {
+				// TODO 处理头条vue3 watch不生效的问题
+				// #ifndef MP-TOUTIAO
+				this.init()
+				// #endif
+			},
+			'form.labelWidth'(val) {
+				// 宽度
+				this.localLabelWidth = this._labelWidthUnit(val)
+
+			},
+			'form.labelPosition'(val) {
+				// 标签位置
+				this.localLabelPos = this._labelPosition()
+			},
+			'form.labelAlign'(val) {
+
+			}
+		},
+		created() {
+			this.init(true)
+			if (this.name && this.form) {
+				// TODO 处理头条vue3 watch不生效的问题
+				// #ifdef MP-TOUTIAO
+				this.$watch('form.formRules', () => {
+					this.init()
+				})
+				// #endif
+
+				// 监听变化
+				this.$watch(
+					() => {
+						const val = this.form._getDataValue(this.name, this.form.localData)
+						return val
+					},
+					(value, oldVal) => {
+						const isEqual = this.form._isEqual(value, oldVal)
+						// 简单判断前后值的变化,只有发生变化才会发生校验
+						// TODO  如果 oldVal = undefined ,那么大概率是源数据里没有值导致 ,这个情况不哦校验 ,可能不严谨 ,需要在做观察
+						// fix by mehaotian 暂时取消 && oldVal !== undefined ,如果formData 中不存在,可能会不校验
+						if (!isEqual) {
+							const val = this.itemSetValue(value)
+							this.onFieldChange(val, false)
+						}
+					}, {
+						immediate: false
+					}
+				);
+			}
+
+		},
+		// #ifndef VUE3
+		destroyed() {
+			if (this.__isUnmounted) return
+			this.unInit()
+		},
+		// #endif
+		// #ifdef VUE3
+		unmounted() {
+			this.__isUnmounted = true
+			this.unInit()
+		},
+		// #endif
+		methods: {
+			/**
+			 * 外部调用方法
+			 * 设置规则 ,主要用于小程序自定义检验规则
+			 * @param {Array} rules 规则源数据
+			 */
+			setRules(rules = null) {
+				this.userRules = rules
+				this.init(false)
+			},
+			// 兼容老版本表单组件
+			setValue() {
+				// console.log('setValue 方法已经弃用,请使用最新版本的 uni-forms 表单组件以及其他关联组件。');
+			},
+			/**
+			 * 外部调用方法
+			 * 校验数据
+			 * @param {any} value 需要校验的数据
+			 * @param {boolean} 是否立即校验
+			 * @return {Array|null} 校验内容
+			 */
+			async onFieldChange(value, formtrigger = true) {
+				const {
+					formData,
+					localData,
+					errShowType,
+					validateCheck,
+					validateTrigger,
+					_isRequiredField,
+					_realName
+				} = this.form
+				const name = _realName(this.name)
+				if (!value) {
+					value = this.form.formData[name]
+				}
+				// fixd by mehaotian 不在校验前清空信息,解决闪屏的问题
+				// this.errMsg = '';
+
+				// fix by mehaotian 解决没有检验规则的情况下,抛出错误的问题
+				const ruleLen = this.itemRules.rules && this.itemRules.rules.length
+				if (!this.validator || !ruleLen || ruleLen === 0) return;
+
+				// 检验时机
+				// let trigger = this.isTrigger(this.itemRules.validateTrigger, this.validateTrigger, validateTrigger);
+				const isRequiredField = _isRequiredField(this.itemRules.rules || []);
+				let result = null;
+				// 只有等于 bind 时 ,才能开启时实校验
+				if (validateTrigger === 'bind' || formtrigger) {
+					// 校验当前表单项
+					result = await this.validator.validateUpdate({
+							[name]: value
+						},
+						formData
+					);
+
+					// 判断是否必填,非必填,不填不校验,填写才校验 ,暂时只处理 undefined  和空的情况
+					if (!isRequiredField && (value === undefined || value === '')) {
+						result = null;
+					}
+
+					// 判断错误信息显示类型
+					if (result && result.errorMessage) {
+						if (errShowType === 'undertext') {
+							// 获取错误信息
+							this.errMsg = !result ? '' : result.errorMessage;
+						}
+						if (errShowType === 'toast') {
+							uni.showToast({
+								title: result.errorMessage || '校验错误',
+								icon: 'none'
+							});
+						}
+						if (errShowType === 'modal') {
+							uni.showModal({
+								title: '提示',
+								content: result.errorMessage || '校验错误'
+							});
+						}
+					} else {
+						this.errMsg = ''
+					}
+					// 通知 form 组件更新事件
+					validateCheck(result ? result : null)
+				} else {
+					this.errMsg = ''
+				}
+				return result ? result : null;
+			},
+			/**
+			 * 初始组件数据
+			 */
+			init(type = false) {
+				const {
+					validator,
+					formRules,
+					childrens,
+					formData,
+					localData,
+					_realName,
+					labelWidth,
+					_getDataValue,
+					_setDataValue
+				} = this.form || {}
+				// 对齐方式
+				this.localLabelAlign = this._justifyContent()
+				// 宽度
+				this.localLabelWidth = this._labelWidthUnit(labelWidth)
+				// 标签位置
+				this.localLabelPos = this._labelPosition()
+				// 将需要校验的子组件加入form 队列
+				this.form && type && childrens.push(this)
+
+				if (!validator || !formRules) return
+				// 判断第一个 item
+				if (!this.form.isFirstBorder) {
+					this.form.isFirstBorder = true;
+					this.isFirstBorder = true;
+				}
+
+				// 判断 group 里的第一个 item
+				if (this.group) {
+					if (!this.group.isFirstBorder) {
+						this.group.isFirstBorder = true;
+						this.isFirstBorder = true;
+					}
+				}
+				this.border = this.form.border;
+				// 获取子域的真实名称
+				const name = _realName(this.name)
+				const itemRule = this.userRules || this.rules
+				if (typeof formRules === 'object' && itemRule) {
+					// 子规则替换父规则
+					formRules[name] = {
+						rules: itemRule
+					}
+					validator.updateSchema(formRules);
+				}
+				// 注册校验规则
+				const itemRules = formRules[name] || {}
+				this.itemRules = itemRules
+				// 注册校验函数
+				this.validator = validator
+				// 默认值赋予
+				this.itemSetValue(_getDataValue(this.name, localData))
+			},
+			unInit() {
+				if (this.form) {
+					const {
+						childrens,
+						formData,
+						_realName
+					} = this.form
+					childrens.forEach((item, index) => {
+						if (item === this) {
+							this.form.childrens.splice(index, 1)
+							delete formData[_realName(item.name)]
+						}
+					})
+				}
+			},
+			// 设置item 的值
+			itemSetValue(value) {
+				const name = this.form._realName(this.name)
+				const rules = this.itemRules.rules || []
+				const val = this.form._getValue(name, value, rules)
+				this.form._setDataValue(name, this.form.formData, val)
+				return val
+			},
+
+			/**
+			 * 移除该表单项的校验结果
+			 */
+			clearValidate() {
+				this.errMsg = '';
+			},
+
+			// 是否显示星号
+			_isRequired() {
+				// TODO 不根据规则显示 星号,考虑后续兼容
+				// if (this.form) {
+				// 	if (this.form._isRequiredField(this.itemRules.rules || []) && this.required) {
+				// 		return true
+				// 	}
+				// 	return false
+				// }
+				return this.required
+			},
+
+			// 处理对齐方式
+			_justifyContent() {
+				if (this.form) {
+					const {
+						labelAlign
+					} = this.form
+					let labelAli = this.labelAlign ? this.labelAlign : labelAlign;
+					if (labelAli === 'left') return 'flex-start';
+					if (labelAli === 'center') return 'center';
+					if (labelAli === 'right') return 'flex-end';
+				}
+				return 'flex-start';
+			},
+			// 处理 label宽度单位 ,继承父元素的值
+			_labelWidthUnit(labelWidth) {
+
+				// if (this.form) {
+				// 	const {
+				// 		labelWidth
+				// 	} = this.form
+				return this.num2px(this.labelWidth ? this.labelWidth : (labelWidth || (this.label ? 70 : 'auto')))
+				// }
+				// return '70px'
+			},
+			// 处理 label 位置
+			_labelPosition() {
+				if (this.form) return this.form.labelPosition || 'left'
+				return 'left'
+
+			},
+
+			/**
+			 * 触发时机
+			 * @param {Object} rule 当前规则内时机
+			 * @param {Object} itemRlue 当前组件时机
+			 * @param {Object} parentRule 父组件时机
+			 */
+			isTrigger(rule, itemRlue, parentRule) {
+				//  bind  submit
+				if (rule === 'submit' || !rule) {
+					if (rule === undefined) {
+						if (itemRlue !== 'bind') {
+							if (!itemRlue) {
+								return parentRule === '' ? 'bind' : 'submit';
+							}
+							return 'submit';
+						}
+						return 'bind';
+					}
+					return 'submit';
+				}
+				return 'bind';
+			},
+			num2px(num) {
+				if (typeof num === 'number') {
+					return `${num}px`
+				}
+				return num
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	.uni-forms-item {
+		position: relative;
+		display: flex;
+		/* #ifdef APP-NVUE */
+		// 在 nvue 中,使用 margin-bottom error 信息会被隐藏
+		padding-bottom: 22px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		margin-bottom: 22px;
+		/* #endif */
+		flex-direction: row;
+
+		&__label {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			text-align: left;
+			font-size: 14px;
+			color: #606266;
+			height: 36px;
+			padding: 0 12px 0 0;
+			/* #ifndef APP-NVUE */
+			vertical-align: middle;
+			flex-shrink: 0;
+			/* #endif */
+
+			/* #ifndef APP-NVUE */
+			box-sizing: border-box;
+
+			/* #endif */
+			&.no-label {
+				padding: 0;
+			}
+		}
+
+		&__content {
+			/* #ifndef MP-TOUTIAO */
+			// display: flex;
+			// align-items: center;
+			/* #endif */
+			position: relative;
+			font-size: 14px;
+			flex: 1;
+			/* #ifndef APP-NVUE */
+			box-sizing: border-box;
+			/* #endif */
+			flex-direction: row;
+
+			/* #ifndef APP || H5 || MP-WEIXIN || APP-NVUE */
+			// TODO 因为小程序平台会多一层标签节点 ,所以需要在多余节点继承当前样式
+			&>uni-easyinput,
+			&>uni-data-picker {
+				width: 100%;
+			}
+
+			/* #endif */
+
+		}
+
+		& .uni-forms-item__nuve-content {
+			display: flex;
+			flex-direction: column;
+			flex: 1;
+		}
+
+		&__error {
+			color: #f56c6c;
+			font-size: 12px;
+			line-height: 1;
+			padding-top: 4px;
+			position: absolute;
+			/* #ifndef APP-NVUE */
+			top: 100%;
+			left: 0;
+			transition: transform 0.3s;
+			transform: translateY(-100%);
+			/* #endif */
+			/* #ifdef APP-NVUE */
+			bottom: 5px;
+			/* #endif */
+
+			opacity: 0;
+
+			.error-text {
+				// 只有 nvue 下这个样式才生效
+				color: #f56c6c;
+				font-size: 12px;
+			}
+
+			&.msg--active {
+				opacity: 1;
+				transform: translateY(0%);
+			}
+		}
+
+		// 位置修饰样式
+		&.is-direction-left {
+			flex-direction: row;
+		}
+
+		&.is-direction-top {
+			flex-direction: column;
+
+			.uni-forms-item__label {
+				padding: 0 0 8px;
+				line-height: 1.5715;
+				text-align: left;
+				/* #ifndef APP-NVUE */
+				white-space: initial;
+				/* #endif */
+			}
+		}
+
+		.is-required {
+			// color: $uni-color-error;
+			color: #dd524d;
+			font-weight: bold;
+		}
+	}
+
+
+	.uni-forms-item--border {
+		margin-bottom: 0;
+		padding: 10px 0;
+		// padding-bottom: 0;
+		border-top: 1px #eee solid;
+
+		/* #ifndef APP-NVUE */
+		.uni-forms-item__content {
+			flex-direction: column;
+			justify-content: flex-start;
+			align-items: flex-start;
+
+			.uni-forms-item__error {
+				position: relative;
+				top: 5px;
+				left: 0;
+				padding-top: 0;
+			}
+		}
+
+		/* #endif */
+
+		/* #ifdef APP-NVUE */
+		display: flex;
+		flex-direction: column;
+
+		.uni-forms-item__error {
+			position: relative;
+			top: 0px;
+			left: 0;
+			padding-top: 0;
+			margin-top: 5px;
+		}
+
+		/* #endif */
+
+	}
+
+	.is-first-border {
+		/* #ifndef APP-NVUE */
+		border: none;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		border-width: 0;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-forms/components/uni-forms/uni-forms.vue b/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
new file mode 100644
index 0000000..d061313
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
@@ -0,0 +1,404 @@
+<template>
+	<view class="uni-forms">
+		<form>
+			<slot></slot>
+		</form>
+	</view>
+</template>
+
+<script>
+	import Validator from './validate.js';
+	import {
+		deepCopy,
+		getValue,
+		isRequiredField,
+		setDataValue,
+		getDataValue,
+		realName,
+		isRealName,
+		rawData,
+		isEqual
+	} from './utils.js'
+
+	// #ifndef VUE3
+	// 后续会慢慢废弃这个方法
+	import Vue from 'vue';
+	Vue.prototype.binddata = function(name, value, formName) {
+		if (formName) {
+			this.$refs[formName].setValue(name, value);
+		} else {
+			let formVm;
+			for (let i in this.$refs) {
+				const vm = this.$refs[i];
+				if (vm && vm.$options && vm.$options.name === 'uniForms') {
+					formVm = vm;
+					break;
+				}
+			}
+			if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
+			formVm.setValue(name, value);
+		}
+	};
+	// #endif
+	/**
+	 * Forms 表单
+	 * @description 由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=2773
+	 * @property {Object} rules	表单校验规则
+	 * @property {String} validateTrigger = [bind|submit|blur]	校验触发器方式 默认 submit
+	 * @value bind		发生变化时触发
+	 * @value submit	提交时触发
+	 * @value blur	  失去焦点时触发
+	 * @property {String} labelPosition = [top|left]	label 位置 默认 left
+	 * @value top		顶部显示 label
+	 * @value left	左侧显示 label
+	 * @property {String} labelWidth	label 宽度,默认 70px
+	 * @property {String} labelAlign = [left|center|right]	label 居中方式  默认 left
+	 * @value left		label 左侧显示
+	 * @value center	label 居中
+	 * @value right		label 右侧对齐
+	 * @property {String} errShowType = [undertext|toast|modal]	校验错误信息提示方式
+	 * @value undertext	错误信息在底部显示
+	 * @value toast			错误信息toast显示
+	 * @value modal			错误信息modal显示
+	 * @event {Function} submit	提交时触发
+	 * @event {Function} validate	校验结果发生变化触发
+	 */
+	export default {
+		name: 'uniForms',
+		emits: ['validate', 'submit'],
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		props: {
+			// 即将弃用
+			value: {
+				type: Object,
+				default () {
+					return null;
+				}
+			},
+			// vue3 替换 value 属性
+			modelValue: {
+				type: Object,
+				default () {
+					return null;
+				}
+			},
+			// 1.4.0 开始将不支持 v-model ,且废弃 value 和 modelValue
+			model: {
+				type: Object,
+				default () {
+					return null;
+				}
+			},
+			// 表单校验规则
+			rules: {
+				type: Object,
+				default () {
+					return {};
+				}
+			},
+			//校验错误信息提示方式 默认 undertext 取值 [undertext|toast|modal]
+			errShowType: {
+				type: String,
+				default: 'undertext'
+			},
+			// 校验触发器方式 默认 bind 取值 [bind|submit]
+			validateTrigger: {
+				type: String,
+				default: 'submit'
+			},
+			// label 位置,默认 left 取值  top/left
+			labelPosition: {
+				type: String,
+				default: 'left'
+			},
+			// label 宽度
+			labelWidth: {
+				type: [String, Number],
+				default: ''
+			},
+			// label 居中方式,默认 left 取值 left/center/right
+			labelAlign: {
+				type: String,
+				default: 'left'
+			},
+			border: {
+				type: Boolean,
+				default: false
+			}
+		},
+		provide() {
+			return {
+				uniForm: this
+			}
+		},
+		data() {
+			return {
+				// 表单本地值的记录,不应该与传如的值进行关联
+				formData: {},
+				formRules: {}
+			};
+		},
+		computed: {
+			// 计算数据源变化的
+			localData() {
+				const localVal = this.model || this.modelValue || this.value
+				if (localVal) {
+					return deepCopy(localVal)
+				}
+				return {}
+			}
+		},
+		watch: {
+			// 监听数据变化 ,暂时不使用,需要单独赋值
+			// localData: {},
+			// 监听规则变化
+			rules: {
+				handler: function(val, oldVal) {
+					this.setRules(val)
+				},
+				deep: true,
+				immediate: true
+			}
+		},
+		created() {
+			// #ifdef VUE3
+			let getbinddata = getApp().$vm.$.appContext.config.globalProperties.binddata
+			if (!getbinddata) {
+				getApp().$vm.$.appContext.config.globalProperties.binddata = function(name, value, formName) {
+					if (formName) {
+						this.$refs[formName].setValue(name, value);
+					} else {
+						let formVm;
+						for (let i in this.$refs) {
+							const vm = this.$refs[i];
+							if (vm && vm.$options && vm.$options.name === 'uniForms') {
+								formVm = vm;
+								break;
+							}
+						}
+						if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
+						if(formVm.model)formVm.model[name] = value
+						if(formVm.modelValue)formVm.modelValue[name] = value
+						if(formVm.value)formVm.value[name] = value
+					}
+				}
+			}
+			// #endif
+
+			// 子组件实例数组
+			this.childrens = []
+			// TODO 兼容旧版 uni-data-picker ,新版本中无效,只是避免报错
+			this.inputChildrens = []
+			this.setRules(this.rules)
+		},
+		methods: {
+			/**
+			 * 外部调用方法
+			 * 设置规则 ,主要用于小程序自定义检验规则
+			 * @param {Array} rules 规则源数据
+			 */
+			setRules(rules) {
+				// TODO 有可能子组件合并规则的时机比这个要早,所以需要合并对象 ,而不是直接赋值,可能会被覆盖
+				this.formRules = Object.assign({}, this.formRules, rules)
+				// 初始化校验函数
+				this.validator = new Validator(rules);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 设置数据,用于设置表单数据,公开给用户使用 , 不支持在动态表单中使用
+			 * @param {Object} key
+			 * @param {Object} value
+			 */
+			setValue(key, value) {
+				let example = this.childrens.find(child => child.name === key);
+				if (!example) return null;
+				this.formData[key] = getValue(key, value, (this.formRules[key] && this.formRules[key].rules) || [])
+				return example.onFieldChange(this.formData[key]);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 手动提交校验表单
+			 * 对整个表单进行校验的方法,参数为一个回调函数。
+			 * @param {Array} keepitem 保留不参与校验的字段
+			 * @param {type} callback 方法回调
+			 */
+			validate(keepitem, callback) {
+				return this.checkAll(this.formData, keepitem, callback);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 部分表单校验
+			 * @param {Array|String} props 需要校验的字段
+			 * @param {Function} 回调函数
+			 */
+			validateField(props = [], callback) {
+				props = [].concat(props);
+				let invalidFields = {};
+				this.childrens.forEach(item => {
+					const name = realName(item.name)
+					if (props.indexOf(name) !== -1) {
+						invalidFields = Object.assign({}, invalidFields, {
+							[name]: this.formData[name]
+						});
+					}
+				});
+				return this.checkAll(invalidFields, [], callback);
+			},
+
+			/**
+			 * 外部调用方法
+			 * 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果
+			 * @param {Array|String} props 需要移除校验的字段 ,不填为所有
+			 */
+			clearValidate(props = []) {
+				props = [].concat(props);
+				this.childrens.forEach(item => {
+					if (props.length === 0) {
+						item.errMsg = '';
+					} else {
+						const name = realName(item.name)
+						if (props.indexOf(name) !== -1) {
+							item.errMsg = '';
+						}
+					}
+				});
+			},
+
+			/**
+			 * 外部调用方法 ,即将废弃
+			 * 手动提交校验表单
+			 * 对整个表单进行校验的方法,参数为一个回调函数。
+			 * @param {Array} keepitem 保留不参与校验的字段
+			 * @param {type} callback 方法回调
+			 */
+			submit(keepitem, callback, type) {
+				for (let i in this.dataValue) {
+					const itemData = this.childrens.find(v => v.name === i);
+					if (itemData) {
+						if (this.formData[i] === undefined) {
+							this.formData[i] = this._getValue(i, this.dataValue[i]);
+						}
+					}
+				}
+
+				if (!type) {
+					console.warn('submit 方法即将废弃,请使用validate方法代替!');
+				}
+
+				return this.checkAll(this.formData, keepitem, callback, 'submit');
+			},
+
+			// 校验所有
+			async checkAll(invalidFields, keepitem, callback, type) {
+				// 不存在校验规则 ,则停止校验流程
+				if (!this.validator) return
+				let childrens = []
+				// 处理参与校验的item实例
+				for (let i in invalidFields) {
+					const item = this.childrens.find(v => realName(v.name) === i)
+					if (item) {
+						childrens.push(item)
+					}
+				}
+
+				// 如果validate第一个参数是funciont ,那就走回调
+				if (!callback && typeof keepitem === 'function') {
+					callback = keepitem;
+				}
+
+				let promise;
+				// 如果不存在回调,那么使用 Promise 方式返回
+				if (!callback && typeof callback !== 'function' && Promise) {
+					promise = new Promise((resolve, reject) => {
+						callback = function(valid, invalidFields) {
+							!valid ? resolve(invalidFields) : reject(valid);
+						};
+					});
+				}
+
+				let results = [];
+				// 避免引用错乱 ,建议拷贝对象处理
+				let tempFormData = JSON.parse(JSON.stringify(invalidFields))
+				// 所有子组件参与校验,使用 for 可以使用  awiat
+				for (let i in childrens) {
+					const child = childrens[i]
+					let name = realName(child.name);
+					const result = await child.onFieldChange(tempFormData[name]);
+					if (result) {
+						results.push(result);
+						// toast ,modal 只需要执行第一次就可以
+						if (this.errShowType === 'toast' || this.errShowType === 'modal') break;
+					}
+				}
+
+
+				if (Array.isArray(results)) {
+					if (results.length === 0) results = null;
+				}
+				if (Array.isArray(keepitem)) {
+					keepitem.forEach(v => {
+						let vName = realName(v);
+						let value = getDataValue(v, this.localData)
+						if (value !== undefined) {
+							tempFormData[vName] = value
+						}
+					});
+				}
+
+				// TODO submit 即将废弃
+				if (type === 'submit') {
+					this.$emit('submit', {
+						detail: {
+							value: tempFormData,
+							errors: results
+						}
+					});
+				} else {
+					this.$emit('validate', results);
+				}
+
+				// const resetFormData = rawData(tempFormData, this.localData, this.name)
+				let resetFormData = {}
+				resetFormData = rawData(tempFormData, this.name)
+				callback && typeof callback === 'function' && callback(results, resetFormData);
+
+				if (promise && callback) {
+					return promise;
+				} else {
+					return null;
+				}
+
+			},
+
+			/**
+			 * 返回validate事件
+			 * @param {Object} result
+			 */
+			validateCheck(result) {
+				this.$emit('validate', result);
+			},
+			_getValue: getValue,
+			_isRequiredField: isRequiredField,
+			_setDataValue: setDataValue,
+			_getDataValue: getDataValue,
+			_realName: realName,
+			_isRealName: isRealName,
+			_isEqual: isEqual
+		}
+	};
+</script>
+
+<style lang="scss">
+	.uni-forms {}
+</style>
diff --git a/uni_modules/uni-forms/components/uni-forms/utils.js b/uni_modules/uni-forms/components/uni-forms/utils.js
new file mode 100644
index 0000000..6da2421
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms/utils.js
@@ -0,0 +1,293 @@
+/**
+ * 简单处理对象拷贝
+ * @param {Obejct} 被拷贝对象
+ * @@return {Object} 拷贝对象
+ */
+export const deepCopy = (val) => {
+	return JSON.parse(JSON.stringify(val))
+}
+/**
+ * 过滤数字类型
+ * @param {String} format 数字类型
+ * @@return {Boolean} 返回是否为数字类型
+ */
+export const typeFilter = (format) => {
+	return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp';
+}
+
+/**
+ * 把 value 转换成指定的类型,用于处理初始值,原因是初始值需要入库不能为 undefined
+ * @param {String} key 字段名
+ * @param {any} value 字段值
+ * @param {Object} rules 表单校验规则
+ */
+export const getValue = (key, value, rules) => {
+	const isRuleNumType = rules.find(val => val.format && typeFilter(val.format));
+	const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool');
+	// 输入类型为 number
+	if (!!isRuleNumType) {
+		if (!value && value !== 0) {
+			value = null
+		} else {
+			value = isNumber(Number(value)) ? Number(value) : value
+		}
+	}
+
+	// 输入类型为 boolean
+	if (!!isRuleBoolType) {
+		value = isBoolean(value) ? value : false
+	}
+
+	return value;
+}
+
+/**
+ * 获取表单数据
+ * @param {String|Array} name 真实名称,需要使用 realName 获取
+ * @param {Object} data 原始数据
+ * @param {any} value  需要设置的值
+ */
+export const setDataValue = (field, formdata, value) => {
+	formdata[field] = value
+	return value || ''
+}
+
+/**
+ * 获取表单数据
+ * @param {String|Array} field 真实名称,需要使用 realName 获取
+ * @param {Object} data 原始数据
+ */
+export const getDataValue = (field, data) => {
+	return objGet(data, field)
+}
+
+/**
+ * 获取表单类型
+ * @param {String|Array} field 真实名称,需要使用 realName 获取
+ */
+export const getDataValueType = (field, data) => {
+	const value = getDataValue(field, data)
+	return {
+		type: type(value),
+		value
+	}
+}
+
+/**
+ * 获取表单可用的真实name
+ * @param {String|Array} name 表单name
+ * @@return {String} 表单可用的真实name
+ */
+export const realName = (name, data = {}) => {
+	const base_name = _basePath(name)
+	if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) {
+		const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_')
+		return realname
+	}
+	return base_name[0] || name
+}
+
+/**
+ * 判断是否表单可用的真实name
+ * @param {String|Array} name 表单name
+ * @@return {String} 表单可用的真实name
+ */
+export const isRealName = (name) => {
+	const reg = /^_formdata_#*/
+	return reg.test(name)
+}
+
+/**
+ * 获取表单数据的原始格式
+ * @@return {Object|Array} object 需要解析的数据
+ */
+export const rawData = (object = {}, name) => {
+	let newData = JSON.parse(JSON.stringify(object))
+	let formData = {}
+	for(let i in newData){
+		let path = name2arr(i)
+		objSet(formData,path,newData[i])
+	}
+	return formData
+}
+
+/**
+ * 真实name还原为 array
+ * @param {*} name 
+ */
+export const name2arr = (name) => {
+	let field = name.replace('_formdata_#', '')
+	field = field.split('#').map(v => (isNumber(v) ? Number(v) : v))
+	return field
+}
+
+/**
+ * 对象中设置值
+ * @param {Object|Array} object 源数据
+ * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c']
+ * @param {String} value 需要设置的值
+ */
+export const objSet = (object, path, value) => {
+	if (typeof object !== 'object') return object;
+	_basePath(path).reduce((o, k, i, _) => {
+		if (i === _.length - 1) { 
+			// 若遍历结束直接赋值
+			o[k] = value
+			return null
+		} else if (k in o) { 
+			// 若存在对应路径,则返回找到的对象,进行下一次遍历
+			return o[k]
+		} else { 
+			// 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
+			o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {}
+			return o[k]
+		}
+	}, object)
+	// 返回object
+	return object;
+}
+
+// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用
+function _basePath(path) {
+	// 若是数组,则直接返回
+	if (Array.isArray(path)) return path
+	// 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']'
+	return path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
+}
+
+/**
+ * 从对象中获取值
+ * @param {Object|Array} object 源数据
+ * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c']
+ * @param {String} defaultVal 如果无法从调用链中获取值的默认值
+ */
+export const objGet = (object, path, defaultVal = 'undefined') => {
+	// 先将path处理成统一格式
+	let newPath = _basePath(path)
+	// 递归处理,返回最后结果
+	let val = newPath.reduce((o, k) => {
+		return (o || {})[k]
+	}, object);
+	return !val || val !== undefined ? val : defaultVal
+}
+
+
+/**
+ * 是否为 number 类型 
+ * @param {any} num 需要判断的值
+ * @return {Boolean} 是否为 number
+ */
+export const isNumber = (num) => {
+	return !isNaN(Number(num))
+}
+
+/**
+ * 是否为 boolean 类型 
+ * @param {any} bool 需要判断的值
+ * @return {Boolean} 是否为 boolean
+ */
+export const isBoolean = (bool) => {
+	return (typeof bool === 'boolean')
+}
+/**
+ * 是否有必填字段
+ * @param {Object} rules 规则
+ * @return {Boolean} 是否有必填字段
+ */
+export const isRequiredField = (rules) => {
+	let isNoField = false;
+	for (let i = 0; i < rules.length; i++) {
+		const ruleData = rules[i];
+		if (ruleData.required) {
+			isNoField = true;
+			break;
+		}
+	}
+	return isNoField;
+}
+
+
+/**
+ * 获取数据类型
+ * @param {Any} obj 需要获取数据类型的值
+ */
+export const type = (obj) => {
+	var class2type = {};
+
+	// 生成class2type映射
+	"Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) {
+		class2type["[object " + item + "]"] = item.toLowerCase();
+	})
+	if (obj == null) {
+		return obj + "";
+	}
+	return typeof obj === "object" || typeof obj === "function" ?
+		class2type[Object.prototype.toString.call(obj)] || "object" :
+		typeof obj;
+}
+
+/**
+ * 判断两个值是否相等
+ * @param {any} a 值  
+ * @param {any} b 值  
+ * @return {Boolean} 是否相等
+ */
+export const isEqual = (a, b) => {
+	//如果a和b本来就全等
+	if (a === b) {
+		//判断是否为0和-0
+		return a !== 0 || 1 / a === 1 / b;
+	}
+	//判断是否为null和undefined
+	if (a == null || b == null) {
+		return a === b;
+	}
+	//接下来判断a和b的数据类型
+	var classNameA = toString.call(a),
+		classNameB = toString.call(b);
+	//如果数据类型不相等,则返回false
+	if (classNameA !== classNameB) {
+		return false;
+	}
+	//如果数据类型相等,再根据不同数据类型分别判断
+	switch (classNameA) {
+		case '[object RegExp]':
+		case '[object String]':
+			//进行字符串转换比较
+			return '' + a === '' + b;
+		case '[object Number]':
+			//进行数字转换比较,判断是否为NaN
+			if (+a !== +a) {
+				return +b !== +b;
+			}
+			//判断是否为0或-0
+			return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+		case '[object Date]':
+		case '[object Boolean]':
+			return +a === +b;
+	}
+	//如果是对象类型
+	if (classNameA == '[object Object]') {
+		//获取a和b的属性长度
+		var propsA = Object.getOwnPropertyNames(a),
+			propsB = Object.getOwnPropertyNames(b);
+		if (propsA.length != propsB.length) {
+			return false;
+		}
+		for (var i = 0; i < propsA.length; i++) {
+			var propName = propsA[i];
+			//如果对应属性对应值不相等,则返回false
+			if (a[propName] !== b[propName]) {
+				return false;
+			}
+		}
+		return true;
+	}
+	//如果是数组类型
+	if (classNameA == '[object Array]') {
+		if (a.toString() == b.toString()) {
+			return true;
+		}
+		return false;
+	}
+}
diff --git a/uni_modules/uni-forms/components/uni-forms/validate.js b/uni_modules/uni-forms/components/uni-forms/validate.js
new file mode 100644
index 0000000..1834c6c
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms/validate.js
@@ -0,0 +1,486 @@
+var pattern = {
+	email: /^\S+?@\S+?\.\S+?$/,
+	idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
+	url: new RegExp(
+		"^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$",
+		'i')
+};
+
+const FORMAT_MAPPING = {
+	"int": 'integer',
+	"bool": 'boolean',
+	"double": 'number',
+	"long": 'number',
+	"password": 'string'
+	// "fileurls": 'array'
+}
+
+function formatMessage(args, resources = '') {
+	var defaultMessage = ['label']
+	defaultMessage.forEach((item) => {
+		if (args[item] === undefined) {
+			args[item] = ''
+		}
+	})
+
+	let str = resources
+	for (let key in args) {
+		let reg = new RegExp('{' + key + '}')
+		str = str.replace(reg, args[key])
+	}
+	return str
+}
+
+function isEmptyValue(value, type) {
+	if (value === undefined || value === null) {
+		return true;
+	}
+
+	if (typeof value === 'string' && !value) {
+		return true;
+	}
+
+	if (Array.isArray(value) && !value.length) {
+		return true;
+	}
+
+	if (type === 'object' && !Object.keys(value).length) {
+		return true;
+	}
+
+	return false;
+}
+
+const types = {
+	integer(value) {
+		return types.number(value) && parseInt(value, 10) === value;
+	},
+	string(value) {
+		return typeof value === 'string';
+	},
+	number(value) {
+		if (isNaN(value)) {
+			return false;
+		}
+		return typeof value === 'number';
+	},
+	"boolean": function(value) {
+		return typeof value === 'boolean';
+	},
+	"float": function(value) {
+		return types.number(value) && !types.integer(value);
+	},
+	array(value) {
+		return Array.isArray(value);
+	},
+	object(value) {
+		return typeof value === 'object' && !types.array(value);
+	},
+	date(value) {
+		return value instanceof Date;
+	},
+	timestamp(value) {
+		if (!this.integer(value) || Math.abs(value).toString().length > 16) {
+			return false
+		}
+		return true;
+	},
+	file(value) {
+		return typeof value.url === 'string';
+	},
+	email(value) {
+		return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255;
+	},
+	url(value) {
+		return typeof value === 'string' && !!value.match(pattern.url);
+	},
+	pattern(reg, value) {
+		try {
+			return new RegExp(reg).test(value);
+		} catch (e) {
+			return false;
+		}
+	},
+	method(value) {
+		return typeof value === 'function';
+	},
+	idcard(value) {
+		return typeof value === 'string' && !!value.match(pattern.idcard);
+	},
+	'url-https'(value) {
+		return this.url(value) && value.startsWith('https://');
+	},
+	'url-scheme'(value) {
+		return value.startsWith('://');
+	},
+	'url-web'(value) {
+		return false;
+	}
+}
+
+class RuleValidator {
+
+	constructor(message) {
+		this._message = message
+	}
+
+	async validateRule(fieldKey, fieldValue, value, data, allData) {
+		var result = null
+
+		let rules = fieldValue.rules
+
+		let hasRequired = rules.findIndex((item) => {
+			return item.required
+		})
+		if (hasRequired < 0) {
+			if (value === null || value === undefined) {
+				return result
+			}
+			if (typeof value === 'string' && !value.length) {
+				return result
+			}
+		}
+
+		var message = this._message
+
+		if (rules === undefined) {
+			return message['default']
+		}
+
+		for (var i = 0; i < rules.length; i++) {
+			let rule = rules[i]
+			let vt = this._getValidateType(rule)
+
+			Object.assign(rule, {
+				label: fieldValue.label || `["${fieldKey}"]`
+			})
+
+			if (RuleValidatorHelper[vt]) {
+				result = RuleValidatorHelper[vt](rule, value, message)
+				if (result != null) {
+					break
+				}
+			}
+
+			if (rule.validateExpr) {
+				let now = Date.now()
+				let resultExpr = rule.validateExpr(value, allData, now)
+				if (resultExpr === false) {
+					result = this._getMessage(rule, rule.errorMessage || this._message['default'])
+					break
+				}
+			}
+
+			if (rule.validateFunction) {
+				result = await this.validateFunction(rule, value, data, allData, vt)
+				if (result !== null) {
+					break
+				}
+			}
+		}
+
+		if (result !== null) {
+			result = message.TAG + result
+		}
+
+		return result
+	}
+
+	async validateFunction(rule, value, data, allData, vt) {
+		let result = null
+		try {
+			let callbackMessage = null
+			const res = await rule.validateFunction(rule, value, allData || data, (message) => {
+				callbackMessage = message
+			})
+			if (callbackMessage || (typeof res === 'string' && res) || res === false) {
+				result = this._getMessage(rule, callbackMessage || res, vt)
+			}
+		} catch (e) {
+			result = this._getMessage(rule, e.message, vt)
+		}
+		return result
+	}
+
+	_getMessage(rule, message, vt) {
+		return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default'])
+	}
+
+	_getValidateType(rule) {
+		var result = ''
+		if (rule.required) {
+			result = 'required'
+		} else if (rule.format) {
+			result = 'format'
+		} else if (rule.arrayType) {
+			result = 'arrayTypeFormat'
+		} else if (rule.range) {
+			result = 'range'
+		} else if (rule.maximum !== undefined || rule.minimum !== undefined) {
+			result = 'rangeNumber'
+		} else if (rule.maxLength !== undefined || rule.minLength !== undefined) {
+			result = 'rangeLength'
+		} else if (rule.pattern) {
+			result = 'pattern'
+		} else if (rule.validateFunction) {
+			result = 'validateFunction'
+		}
+		return result
+	}
+}
+
+const RuleValidatorHelper = {
+	required(rule, value, message) {
+		if (rule.required && isEmptyValue(value, rule.format || typeof value)) {
+			return formatMessage(rule, rule.errorMessage || message.required);
+		}
+
+		return null
+	},
+
+	range(rule, value, message) {
+		const {
+			range,
+			errorMessage
+		} = rule;
+
+		let list = new Array(range.length);
+		for (let i = 0; i < range.length; i++) {
+			const item = range[i];
+			if (types.object(item) && item.value !== undefined) {
+				list[i] = item.value;
+			} else {
+				list[i] = item;
+			}
+		}
+
+		let result = false
+		if (Array.isArray(value)) {
+			result = (new Set(value.concat(list)).size === list.length);
+		} else {
+			if (list.indexOf(value) > -1) {
+				result = true;
+			}
+		}
+
+		if (!result) {
+			return formatMessage(rule, errorMessage || message['enum']);
+		}
+
+		return null
+	},
+
+	rangeNumber(rule, value, message) {
+		if (!types.number(value)) {
+			return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
+		}
+
+		let {
+			minimum,
+			maximum,
+			exclusiveMinimum,
+			exclusiveMaximum
+		} = rule;
+		let min = exclusiveMinimum ? value <= minimum : value < minimum;
+		let max = exclusiveMaximum ? value >= maximum : value > maximum;
+
+		if (minimum !== undefined && min) {
+			return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ?
+				'exclusiveMinimum' : 'minimum'
+			])
+		} else if (maximum !== undefined && max) {
+			return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ?
+				'exclusiveMaximum' : 'maximum'
+			])
+		} else if (minimum !== undefined && maximum !== undefined && (min || max)) {
+			return formatMessage(rule, rule.errorMessage || message['number'].range)
+		}
+
+		return null
+	},
+
+	rangeLength(rule, value, message) {
+		if (!types.string(value) && !types.array(value)) {
+			return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
+		}
+
+		let min = rule.minLength;
+		let max = rule.maxLength;
+		let val = value.length;
+
+		if (min !== undefined && val < min) {
+			return formatMessage(rule, rule.errorMessage || message['length'].minLength)
+		} else if (max !== undefined && val > max) {
+			return formatMessage(rule, rule.errorMessage || message['length'].maxLength)
+		} else if (min !== undefined && max !== undefined && (val < min || val > max)) {
+			return formatMessage(rule, rule.errorMessage || message['length'].range)
+		}
+
+		return null
+	},
+
+	pattern(rule, value, message) {
+		if (!types['pattern'](rule.pattern, value)) {
+			return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
+		}
+
+		return null
+	},
+
+	format(rule, value, message) {
+		var customTypes = Object.keys(types);
+		var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType);
+
+		if (customTypes.indexOf(format) > -1) {
+			if (!types[format](value)) {
+				return formatMessage(rule, rule.errorMessage || message.typeError);
+			}
+		}
+
+		return null
+	},
+
+	arrayTypeFormat(rule, value, message) {
+		if (!Array.isArray(value)) {
+			return formatMessage(rule, rule.errorMessage || message.typeError);
+		}
+
+		for (let i = 0; i < value.length; i++) {
+			const element = value[i];
+			let formatResult = this.format(rule, element, message)
+			if (formatResult !== null) {
+				return formatResult
+			}
+		}
+
+		return null
+	}
+}
+
+class SchemaValidator extends RuleValidator {
+
+	constructor(schema, options) {
+		super(SchemaValidator.message);
+
+		this._schema = schema
+		this._options = options || null
+	}
+
+	updateSchema(schema) {
+		this._schema = schema
+	}
+
+	async validate(data, allData) {
+		let result = this._checkFieldInSchema(data)
+		if (!result) {
+			result = await this.invokeValidate(data, false, allData)
+		}
+		return result.length ? result[0] : null
+	}
+
+	async validateAll(data, allData) {
+		let result = this._checkFieldInSchema(data)
+		if (!result) {
+			result = await this.invokeValidate(data, true, allData)
+		}
+		return result
+	}
+
+	async validateUpdate(data, allData) {
+		let result = this._checkFieldInSchema(data)
+		if (!result) {
+			result = await this.invokeValidateUpdate(data, false, allData)
+		}
+		return result.length ? result[0] : null
+	}
+
+	async invokeValidate(data, all, allData) {
+		let result = []
+		let schema = this._schema
+		for (let key in schema) {
+			let value = schema[key]
+			let errorMessage = await this.validateRule(key, value, data[key], data, allData)
+			if (errorMessage != null) {
+				result.push({
+					key,
+					errorMessage
+				})
+				if (!all) break
+			}
+		}
+		return result
+	}
+
+	async invokeValidateUpdate(data, all, allData) {
+		let result = []
+		for (let key in data) {
+			let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData)
+			if (errorMessage != null) {
+				result.push({
+					key,
+					errorMessage
+				})
+				if (!all) break
+			}
+		}
+		return result
+	}
+
+	_checkFieldInSchema(data) {
+		var keys = Object.keys(data)
+		var keys2 = Object.keys(this._schema)
+		if (new Set(keys.concat(keys2)).size === keys2.length) {
+			return ''
+		}
+
+		var noExistFields = keys.filter((key) => {
+			return keys2.indexOf(key) < 0;
+		})
+		var errorMessage = formatMessage({
+			field: JSON.stringify(noExistFields)
+		}, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid'])
+		return [{
+			key: 'invalid',
+			errorMessage
+		}]
+	}
+}
+
+function Message() {
+	return {
+		TAG: "",
+		default: '验证错误',
+		defaultInvalid: '提交的字段{field}在数据库中并不存在',
+		validateFunction: '验证无效',
+		required: '{label}必填',
+		'enum': '{label}超出范围',
+		timestamp: '{label}格式无效',
+		whitespace: '{label}不能为空',
+		typeError: '{label}类型无效',
+		date: {
+			format: '{label}日期{value}格式无效',
+			parse: '{label}日期无法解析,{value}无效',
+			invalid: '{label}日期{value}无效'
+		},
+		length: {
+			minLength: '{label}长度不能少于{minLength}',
+			maxLength: '{label}长度不能超过{maxLength}',
+			range: '{label}必须介于{minLength}和{maxLength}之间'
+		},
+		number: {
+			minimum: '{label}不能小于{minimum}',
+			maximum: '{label}不能大于{maximum}',
+			exclusiveMinimum: '{label}不能小于等于{minimum}',
+			exclusiveMaximum: '{label}不能大于等于{maximum}',
+			range: '{label}必须介于{minimum}and{maximum}之间'
+		},
+		pattern: {
+			mismatch: '{label}格式不匹配'
+		}
+	};
+}
+
+
+SchemaValidator.message = new Message();
+
+export default SchemaValidator
diff --git a/uni_modules/uni-forms/package.json b/uni_modules/uni-forms/package.json
new file mode 100644
index 0000000..0d72c63
--- /dev/null
+++ b/uni_modules/uni-forms/package.json
@@ -0,0 +1,89 @@
+{
+  "id": "uni-forms",
+  "displayName": "uni-forms 表单",
+  "version": "1.4.13",
+  "description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据",
+  "keywords": [
+    "uni-ui",
+    "表单",
+    "校验",
+    "表单校验",
+    "表单验证"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+      "uni-icons"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+        "QQ": "y",
+        "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-forms/readme.md b/uni_modules/uni-forms/readme.md
new file mode 100644
index 0000000..63d5a04
--- /dev/null
+++ b/uni_modules/uni-forms/readme.md
@@ -0,0 +1,23 @@
+
+
+## Forms 表单
+
+> **组件名:uni-forms**
+> 代码块: `uForms`、`uni-forms-item`
+> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。
+
+
+uni-app的内置组件已经有了 `<form>`组件,用于提交表单内容。
+
+然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 `<form>`组件封装了 `<uni-forms>`组件,内置了表单验证功能。
+
+`<uni-forms>` 提供了 `rules`属性来描述校验规则、`<uni-forms-item>`子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。
+
+每个要校验的表单项,不管input还是checkbox,都必须放在`<uni-forms-item>`组件中,且一个`<uni-forms-item>`组件只能放置一个表单项。
+
+`<uni-forms-item>`组件内部预留了显示error message的区域,默认是在表单项的底部。
+
+另外,`<uni-forms>`组件下面的各个表单项,可以通过`<uni-group>`包裹为不同的分组。同一`<uni-group>`下的不同表单项目将聚拢在一起,同其他group保持垂直间距。`<uni-group>`仅影响视觉效果。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-forms)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-goods-nav/changelog.md b/uni_modules/uni-goods-nav/changelog.md
new file mode 100644
index 0000000..c6264c6
--- /dev/null
+++ b/uni_modules/uni-goods-nav/changelog.md
@@ -0,0 +1,18 @@
+## 1.2.1(2022-05-30)
+- 新增 stat属性,是否开启uni统计功能
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-goods-nav](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
+## 1.1.1(2021-08-24)
+- 新增 支持国际化
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.5(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json
new file mode 100644
index 0000000..dcdba41
--- /dev/null
+++ b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json
@@ -0,0 +1,6 @@
+{
+	"uni-goods-nav.options.shop": "shop",
+	"uni-goods-nav.options.cart": "cart",
+	"uni-goods-nav.buttonGroup.addToCart": "add to cart",
+	"uni-goods-nav.buttonGroup.buyNow": "buy now"
+}
diff --git a/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json
new file mode 100644
index 0000000..48ee344
--- /dev/null
+++ b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json
@@ -0,0 +1,6 @@
+{
+	"uni-goods-nav.options.shop": "店铺",
+	"uni-goods-nav.options.cart": "购物车",
+	"uni-goods-nav.buttonGroup.addToCart": "加入购物车",
+	"uni-goods-nav.buttonGroup.buyNow": "立即购买"
+}
diff --git a/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json
new file mode 100644
index 0000000..d0a0255
--- /dev/null
+++ b/uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json
@@ -0,0 +1,6 @@
+{
+	"uni-goods-nav.options.shop": "店鋪",
+	"uni-goods-nav.options.cart": "購物車",
+	"uni-goods-nav.buttonGroup.addToCart": "加入購物車",
+	"uni-goods-nav.buttonGroup.buyNow": "立即購買"
+}
diff --git a/uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue b/uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue
new file mode 100644
index 0000000..8a16b17
--- /dev/null
+++ b/uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue
@@ -0,0 +1,229 @@
+<template>
+	<view class="uni-goods-nav">
+		<!-- 底部占位 -->
+		<view class="uni-tab__seat" />
+		<view class="uni-tab__cart-box flex">
+			<view class="flex uni-tab__cart-sub-left">
+				<view v-for="(item,index) in options" :key="index" class="flex uni-tab__cart-button-left uni-tab__shop-cart" @click="onClick(index,item)">
+					<view class="uni-tab__icon">
+						<uni-icons :type="item.icon" size="20" color="#646566"></uni-icons>
+						<!-- <image class="image" :src="item.icon" mode="widthFix" /> -->
+					</view>
+					<text class="uni-tab__text">{{ item.text }}</text>
+					<view class="flex uni-tab__dot-box">
+						<text v-if="item.info" :class="{ 'uni-tab__dots': item.info > 9 }" class="uni-tab__dot " :style="{'backgroundColor':item.infoBackgroundColor?item.infoBackgroundColor:'#ff0000',
+						color:item.infoColor?item.infoColor:'#fff'
+						}">{{ item.info }}</text>
+					</view>
+				</view>
+			</view>
+			<view :class="{'uni-tab__right':fill}" class="flex uni-tab__cart-sub-right ">
+				<view v-for="(item,index) in buttonGroup" :key="index" :style="{background:item.backgroundColor,color:item.color}"
+				 class="flex uni-tab__cart-button-right" @click="buttonClick(index,item)"><text :style="{color:item.color}" class="uni-tab__cart-button-right-text">{{ item.text }}</text></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+	initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {	t	} = initVueI18n(messages)
+	/**
+	 * GoodsNav 商品导航
+	 * @description 商品加入购物车、立即购买等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=865
+	 * @property {Array} options 组件参数
+	 * @property {Array} buttonGroup 组件按钮组参数
+	 * @property {Boolean} fill = [true | false] 组件按钮组参数
+	 * @property {Boolean} stat 是否开启统计功能
+	 * @event {Function} click 左侧点击事件
+	 * @event {Function} buttonClick 右侧按钮组点击事件
+	 * @example <uni-goods-nav :fill="true"  options="" buttonGroup="buttonGroup"  @click="" @buttonClick="" />
+	 */
+	export default {
+		name: 'UniGoodsNav',
+		emits:['click','buttonClick'],
+		props: {
+			options: {
+				type: Array,
+				default () {
+					return [{
+						icon: 'shop',
+						text: t("uni-goods-nav.options.shop"),
+					}, {
+						icon: 'cart',
+						text: t("uni-goods-nav.options.cart")
+					}]
+				}
+			},
+			buttonGroup: {
+				type: Array,
+				default () {
+					return [{
+							text: t("uni-goods-nav.buttonGroup.addToCart"),
+							backgroundColor: 'linear-gradient(90deg, #FFCD1E, #FF8A18)',
+							color: '#fff'
+						},
+						{
+							text: t("uni-goods-nav.buttonGroup.buyNow"),
+							backgroundColor: 'linear-gradient(90deg, #FE6035, #EF1224)',
+							color: '#fff'
+						}
+					]
+				}
+			},
+			fill: {
+				type: Boolean,
+				default: false
+			},
+			stat:{
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			onClick(index, item) {
+				this.$emit('click', {
+					index,
+					content: item,
+				})
+			},
+			buttonClick(index, item) {
+				if (uni.report && this.stat) {
+					uni.report(item.text, item.text)
+				}
+				this.$emit('buttonClick', {
+					index,
+					content: item
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	.flex {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-goods-nav {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+	}
+
+	.uni-tab__cart-box {
+		flex: 1;
+		height: 50px;
+		background-color: #fff;
+		z-index: 900;
+	}
+
+	.uni-tab__cart-sub-left {
+		padding: 0 5px;
+	}
+
+	.uni-tab__cart-sub-right {
+		flex: 1;
+	}
+
+	.uni-tab__right {
+		margin: 5px 0;
+		margin-right: 10px;
+		border-radius: 100px;
+		overflow: hidden;
+	}
+
+	.uni-tab__cart-button-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		// flex: 1;
+		position: relative;
+		justify-content: center;
+		align-items: center;
+		flex-direction: column;
+		margin: 0 10px;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-tab__icon {
+		width: 18px;
+		height: 18px;
+	}
+
+	.image {
+		width: 18px;
+		height: 18px;
+	}
+
+	.uni-tab__text {
+		margin-top: 3px;
+		font-size: 12px;
+		color: #646566;
+	}
+
+	.uni-tab__cart-button-right {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-direction: column;
+		/* #endif */
+		flex: 1;
+		justify-content: center;
+		align-items: center;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-tab__cart-button-right-text {
+		font-size: 14px;
+		color: #fff;
+	}
+
+	.uni-tab__cart-button-right:active {
+		opacity: 0.7;
+	}
+
+	.uni-tab__dot-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-direction: column;
+		/* #endif */
+		position: absolute;
+		right: -2px;
+		top: 2px;
+		justify-content: center;
+		align-items: center;
+		// width: 0;
+		// height: 0;
+	}
+
+	.uni-tab__dot {
+		// width: 30rpx;
+		// height: 30rpx;
+		padding: 0 4px;
+		line-height: 15px;
+		color: #ffffff;
+		text-align: center;
+		font-size: 12px;
+		background-color: #ff0000;
+		border-radius: 15px;
+	}
+
+	.uni-tab__dots {
+		padding: 0 4px;
+		// width: auto;
+		border-radius: 15px;
+	}
+</style>
diff --git a/uni_modules/uni-goods-nav/package.json b/uni_modules/uni-goods-nav/package.json
new file mode 100644
index 0000000..636e45e
--- /dev/null
+++ b/uni_modules/uni-goods-nav/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-goods-nav",
+  "displayName": "uni-goods-nav 商品导航",
+  "version": "1.2.1",
+  "description": "商品导航组件主要用于电商类应用底部导航,可自定义加入购物车,购买等操作",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "商品导航"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-goods-nav/readme.md b/uni_modules/uni-goods-nav/readme.md
new file mode 100644
index 0000000..07df93f
--- /dev/null
+++ b/uni_modules/uni-goods-nav/readme.md
@@ -0,0 +1,10 @@
+
+
+## GoodsNav 商品导航
+> **组件名:uni-goods-nav**
+> 代码块: `uGoodsNav`
+
+商品加入购物车,立即购买等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-grid/changelog.md b/uni_modules/uni-grid/changelog.md
new file mode 100644
index 0000000..d301166
--- /dev/null
+++ b/uni_modules/uni-grid/changelog.md
@@ -0,0 +1,13 @@
+## 1.4.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-grid](https://uniapp.dcloud.io/component/uniui/uni-grid)
+## 1.3.2(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.3.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.3.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.2.4(2021-05-12)
+- 新增 组件示例地址
+## 1.2.3(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue b/uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue
new file mode 100644
index 0000000..19c08d7
--- /dev/null
+++ b/uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue
@@ -0,0 +1,127 @@
+<template>
+	<view v-if="width" :style="'width:'+width+';'+(square?'height:'+width:'')" class="uni-grid-item">
+		<view :class="{ 'uni-grid-item--border': showBorder,  'uni-grid-item--border-top': showBorder && index < column, 'uni-highlight': highlight }"
+		 :style="{'border-right-color': borderColor ,'border-bottom-color': borderColor ,'border-top-color': borderColor }"
+		 class="uni-grid-item__box" @click="_onClick">
+			<slot />
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * GridItem 宫格
+	 * @description 宫格组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=27
+	 * @property {Number} index 子组件的唯一标识 ,点击gird会返回当前的标识
+	 */
+	export default {
+		name: 'UniGridItem',
+		inject: ['grid'],
+		props: {
+			index: {
+				type: Number,
+				default: 0
+			}
+		},
+		data() {
+			return {
+				column: 0,
+				showBorder: true,
+				square: true,
+				highlight: true,
+				left: 0,
+				top: 0,
+				openNum: 2,
+				width: 0,
+				borderColor: '#e5e5e5'
+			}
+		},
+		created() {
+			this.column = this.grid.column
+			this.showBorder = this.grid.showBorder
+			this.square = this.grid.square
+			this.highlight = this.grid.highlight
+			this.top = this.hor === 0 ? this.grid.hor : this.hor
+			this.left = this.ver === 0 ? this.grid.ver : this.ver
+			this.borderColor = this.grid.borderColor
+			this.grid.children.push(this)
+			// this.grid.init()
+			this.width = this.grid.width
+		},
+		beforeDestroy() {
+			this.grid.children.forEach((item, index) => {
+				if (item === this) {
+					this.grid.children.splice(index, 1)
+				}
+			})
+		},
+		methods: {
+			_onClick() {
+				this.grid.change({
+					detail: {
+						index: this.index
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-grid-item {
+		/* #ifndef APP-NVUE */
+		height: 100%;
+		display: flex;
+		/* #endif */
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-grid-item__box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		width: 100%;
+		/* #endif */
+		position: relative;
+		flex: 1;
+		flex-direction: column;
+		// justify-content: center;
+		// align-items: center;
+	}
+
+	.uni-grid-item--border {
+		position: relative;
+		/* #ifdef APP-NVUE */
+		border-bottom-color: #D2D2D2;
+		border-bottom-style: solid;
+		border-bottom-width: 0.5px;
+		border-right-color: #D2D2D2;
+		border-right-style: solid;
+		border-right-width: 0.5px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		z-index: 0;
+		border-bottom: 1px #D2D2D2 solid;
+		border-right: 1px #D2D2D2 solid;
+		/* #endif */
+	}
+	.uni-grid-item--border-top {
+		position: relative;
+		/* #ifdef APP-NVUE */
+		border-top-color: #D2D2D2;
+		border-top-style: solid;
+		border-top-width: 0.5px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		border-top: 1px #D2D2D2 solid;
+		z-index: 0;
+		/* #endif */
+	}
+
+
+	.uni-highlight:active {
+		background-color: #f1f1f1;
+	}
+</style>
diff --git a/uni_modules/uni-grid/components/uni-grid/uni-grid.vue b/uni_modules/uni-grid/components/uni-grid/uni-grid.vue
new file mode 100644
index 0000000..0edc7ff
--- /dev/null
+++ b/uni_modules/uni-grid/components/uni-grid/uni-grid.vue
@@ -0,0 +1,142 @@
+<template>
+	<view class="uni-grid-wrap">
+		<view :id="elId" ref="uni-grid" class="uni-grid" :class="{ 'uni-grid--border': showBorder }" :style="{ 'border-left-color':borderColor}">
+			<slot />
+		</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const dom = uni.requireNativePlugin('dom');
+	// #endif
+
+	/**
+	 * Grid 宫格
+	 * @description 宫格组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=27
+	 * @property {Number} column 每列显示个数
+	 * @property {String} borderColor 边框颜色
+	 * @property {Boolean} showBorder 是否显示边框
+	 * @property {Boolean} square 是否方形显示
+	 * @property {Boolean} Boolean 点击背景是否高亮
+	 * @event {Function} change 点击 grid 触发,e={detail:{index:0}},index 为当前点击 gird 下标
+	 */
+	export default {
+		name: 'UniGrid',
+		emits:['change'],
+		props: {
+			// 每列显示个数
+			column: {
+				type: Number,
+				default: 3
+			},
+			// 是否显示边框
+			showBorder: {
+				type: Boolean,
+				default: true
+			},
+			// 边框颜色
+			borderColor: {
+				type: String,
+				default: '#D2D2D2'
+			},
+			// 是否正方形显示,默认为 true
+			square: {
+				type: Boolean,
+				default: true
+			},
+			highlight: {
+				type: Boolean,
+				default: true
+			}
+		},
+		provide() {
+			return {
+				grid: this
+			}
+		},
+		data() {
+			const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			return {
+				elId,
+				width: 0
+			}
+		},
+		created() {
+			this.children = []
+		},
+		mounted() {
+			this.$nextTick(()=>{
+				this.init()
+			})
+		},
+		methods: {
+			init() {
+				setTimeout(() => {
+					this._getSize((width) => {
+						this.children.forEach((item, index) => {
+							item.width = width
+						})
+					})
+				}, 50)
+			},
+			change(e) {
+				this.$emit('change', e)
+			},
+			_getSize(fn) {
+				// #ifndef APP-NVUE
+				uni.createSelectorQuery()
+					.in(this)
+					.select(`#${this.elId}`)
+					.boundingClientRect()
+					.exec(ret => {
+						this.width = parseInt((ret[0].width - 1) / this.column) + 'px'
+						fn(this.width)
+					})
+				// #endif
+				// #ifdef APP-NVUE
+				dom.getComponentRect(this.$refs['uni-grid'], (ret) => {
+					this.width = parseInt((ret.size.width - 1) / this.column) + 'px'
+					fn(this.width)
+				})
+				// #endif
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-grid-wrap {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: column;
+		/* #ifdef H5 */
+		width: 100%;
+		/* #endif */
+	}
+
+	.uni-grid {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		// flex: 1;
+		flex-direction: row;
+		flex-wrap: wrap;
+	}
+
+	.uni-grid--border {
+		position: relative;
+		/* #ifdef APP-NVUE */
+		border-left-color: #D2D2D2;
+		border-left-style: solid;
+		border-left-width: 0.5px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		z-index: 1;
+		border-left: 1px #D2D2D2 solid;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-grid/package.json b/uni_modules/uni-grid/package.json
new file mode 100644
index 0000000..ccb2c91
--- /dev/null
+++ b/uni_modules/uni-grid/package.json
@@ -0,0 +1,86 @@
+{
+  "id": "uni-grid",
+  "displayName": "uni-grid 宫格",
+  "version": "1.4.0",
+  "description": "Grid 宫格组件,提供移动端常见的宫格布局,如九宫格。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "九宫格",
+    "表格"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss","uni-icons"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-grid/readme.md b/uni_modules/uni-grid/readme.md
new file mode 100644
index 0000000..0aa44cc
--- /dev/null
+++ b/uni_modules/uni-grid/readme.md
@@ -0,0 +1,11 @@
+
+
+## Grid 宫格
+> **组件名:uni-grid**
+> 代码块: `uGrid`
+
+
+宫格组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-grid)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-group/changelog.md b/uni_modules/uni-group/changelog.md
new file mode 100644
index 0000000..a7024fd
--- /dev/null
+++ b/uni_modules/uni-group/changelog.md
@@ -0,0 +1,16 @@
+## 1.2.2(2022-05-30)
+- 新增 stat属性,是否开启uni统计功能
+## 1.2.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-group](https://uniapp.dcloud.io/component/uniui/uni-group)
+## 1.1.7(2021-11-08)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+- 优化 组件文档
+## 1.0.3(2021-05-12)
+- 新增 组件示例地址
+## 1.0.2(2021-02-05)
+- 调整为uni_modules目录规范
+- 优化 兼容 nvue 页面
diff --git a/uni_modules/uni-group/components/uni-group/uni-group.vue b/uni_modules/uni-group/components/uni-group/uni-group.vue
new file mode 100644
index 0000000..3425ecd
--- /dev/null
+++ b/uni_modules/uni-group/components/uni-group/uni-group.vue
@@ -0,0 +1,134 @@
+<template>
+	<view class="uni-group" :class="['uni-group--'+mode ,margin?'group-margin':'']" :style="{marginTop: `${top}px` }">
+		<slot name="title">
+			<view v-if="title" class="uni-group__title" :style="{'padding-left':border?'30px':'15px'}">
+				<text class="uni-group__title-text">{{ title }}</text>
+			</view>
+		</slot>
+		<view class="uni-group__content" :class="{'group-conent-padding':border}">
+			<slot />
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Group 分组
+	 * @description 表单字段分组
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3281
+	 * @property {String} title 主标题
+	 * @property {Number} top 分组间隔
+	 * @property {Number} mode 模式
+	 */
+	export default {
+		name: 'uniGroup',
+		emits:['click'],
+		props: {
+			title: {
+				type: String,
+				default: ''
+			},
+			top: {
+				type: [Number, String],
+				default: 10
+			},
+			mode: {
+				type: String,
+				default: 'default'
+			},
+			stat:{
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				margin: false,
+				border: false
+			}
+		},
+		watch: {
+			title(newVal) {
+				if (uni.report && this.stat && newVal !== '') {
+					uni.report('title', newVal)
+				}
+			}
+		},
+		created() {
+			this.form = this.getForm()
+			if (this.form) {
+				this.margin = true
+				this.border = this.form.border
+			}
+		},
+		methods: {
+			/**
+			 * 获取父元素实例
+			 */
+			getForm() {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== 'uniForms') {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	.uni-group {
+		background: #fff;
+		margin-top: 10px;
+		// border: 1px red solid;
+	}
+
+	.group-margin {
+		// margin: 0 -15px;
+	}
+
+	.uni-group__title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		padding-left: 15px;
+		height: 40px;
+		background-color: #eee;
+		font-weight: normal;
+		color: #666;
+	}
+
+	.uni-group__content {
+		padding: 15px;
+		// padding-bottom: 5px;
+		// background-color: #FFF;
+	}
+
+	.group-conent-padding {
+		padding: 0 15px;
+	}
+
+	.uni-group__title-text {
+		font-size: 14px;
+		color: #666;
+	}
+
+	.distraction {
+		flex-direction: row;
+		align-items: center;
+	}
+
+	.uni-group--card {
+		margin: 10px;
+		border-radius: 5px;
+		overflow: hidden;
+		box-shadow: 0 0 5px 1px rgba($color: #000000, $alpha: 0.08);
+	}
+</style>
diff --git a/uni_modules/uni-group/package.json b/uni_modules/uni-group/package.json
new file mode 100644
index 0000000..ea00a08
--- /dev/null
+++ b/uni_modules/uni-group/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-group",
+  "displayName": "uni-group 分组",
+  "version": "1.2.2",
+  "description": "分组组件可用于将组件用于分组,添加间隔,以产生明显的区块",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "group",
+    "分组",
+    ""
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-group/readme.md b/uni_modules/uni-group/readme.md
new file mode 100644
index 0000000..bae67f4
--- /dev/null
+++ b/uni_modules/uni-group/readme.md
@@ -0,0 +1,9 @@
+
+## Group 分组
+> **组件名:uni-group**
+> 代码块: `uGroup`
+
+分组组件可用于将组件分组,添加间隔,以产生明显的区块。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-group)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-icons/changelog.md b/uni_modules/uni-icons/changelog.md
new file mode 100644
index 0000000..0261131
--- /dev/null
+++ b/uni_modules/uni-icons/changelog.md
@@ -0,0 +1,42 @@
+## 2.0.10(2024-06-07)
+- 优化 uni-app x 中,size 属性的类型
+## 2.0.9(2024-01-12)
+fix: 修复图标大小默认值错误的问题
+## 2.0.8(2023-12-14)
+- 修复 项目未使用 ts 情况下,打包报错的bug
+## 2.0.7(2023-12-14)
+- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
+## 2.0.6(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.5(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.4(2023-12-06)
+- 优化 uni-app x 下示例项目图标排序
+## 2.0.3(2023-12-06)
+- 修复 nvue下引入组件报错的bug
+## 2.0.2(2023-12-05)
+-优化 size 属性支持单位
+## 2.0.1(2023-12-05)
+- 新增 uni-app x 支持定义图标
+## 1.3.5(2022-01-24)
+- 优化 size 属性可以传入不带单位的字符串数值
+## 1.3.4(2022-01-24)
+- 优化 size 支持其他单位
+## 1.3.3(2022-01-17)
+- 修复 nvue 有些图标不显示的bug,兼容老版本图标
+## 1.3.2(2021-12-01)
+- 优化 示例可复制图标名称
+## 1.3.1(2021-11-23)
+- 优化 兼容旧组件 type 值
+## 1.3.0(2021-11-19)
+- 新增 更多图标
+- 优化 自定义图标使用方式
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
+## 1.1.7(2021-11-08)
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.5(2021-05-12)
+- 新增 组件示例地址
+## 1.1.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
new file mode 100644
index 0000000..8740559
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
@@ -0,0 +1,91 @@
+<template>
+  <text class="uni-icons" :style="styleObj">
+    <slot>{{unicode}}</slot>
+  </text>
+</template>
+
+<script>
+  import { fontData, IconsDataItem } from './uniicons_file'
+
+  /**
+   * Icons 图标
+   * @description 用于展示 icon 图标
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=28
+   * @property {Number,String} size 图标大小
+   * @property {String} type 图标图案,参考示例
+   * @property {String} color 图标颜色
+   * @property {String} customPrefix 自定义图标
+   * @event {Function} click 点击 Icon 触发事件
+   */
+  export default {
+    name: "uni-icons",
+    props: {
+      type: {
+        type: String,
+        default: ''
+      },
+      color: {
+        type: String,
+        default: '#333333'
+      },
+      size: {
+        type: [Number, String],
+        default: 16
+      },
+      fontFamily: {
+        type: String,
+        default: ''
+      }
+    },
+    data() {
+      return {};
+    },
+    computed: {
+      unicode() : string {
+        let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
+        if (codes !== null) {
+          return codes.unicode
+        }
+        return ''
+      },
+      iconSize() : string {
+        const size = this.size
+        if (typeof size == 'string') {
+          const reg = /^[0-9]*$/g
+          return reg.test(size as string) ? '' + size + 'px' : '' + size;
+          // return '' + this.size
+        }
+        return this.getFontSize(size as number)
+      },
+      styleObj() : UTSJSONObject {
+        if (this.fontFamily !== '') {
+          return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
+        }
+        return { color: this.color, fontSize: this.iconSize }
+      }
+    },
+    created() { },
+    methods: {
+      /**
+       * 字体大小
+       */
+      getFontSize(size : number) : string {
+        return size + 'px';
+      },
+    },
+  }
+</script>
+
+<style scoped>
+  @font-face {
+    font-family: UniIconsFontFamily;
+    src: url('./uniicons.ttf');
+  }
+
+  .uni-icons {
+    font-family: UniIconsFontFamily;
+    font-size: 18px;
+    font-style: normal;
+    color: #333;
+  }
+</style>
diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.vue b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
new file mode 100644
index 0000000..7da5356
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
@@ -0,0 +1,110 @@
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
+	<!-- #endif -->
+	<!-- #ifndef APP-NVUE -->
+	<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
+		<slot></slot>
+	</text>
+	<!-- #endif -->
+</template>
+
+<script>
+	import { fontData } from './uniicons_file_vue.js';
+
+	const getVal = (val) => {
+		const reg = /^[0-9]*$/g
+		return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
+	}
+
+	// #ifdef APP-NVUE
+	var domModule = weex.requireModule('dom');
+	import iconUrl from './uniicons.ttf'
+	domModule.addRule('fontFace', {
+		'fontFamily': "uniicons",
+		'src': "url('" + iconUrl + "')"
+	});
+	// #endif
+
+	/**
+	 * Icons 图标
+	 * @description 用于展示 icons 图标
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=28
+	 * @property {Number} size 图标大小
+	 * @property {String} type 图标图案,参考示例
+	 * @property {String} color 图标颜色
+	 * @property {String} customPrefix 自定义图标
+	 * @event {Function} click 点击 Icon 触发事件
+	 */
+	export default {
+		name: 'UniIcons',
+		emits: ['click'],
+		props: {
+			type: {
+				type: String,
+				default: ''
+			},
+			color: {
+				type: String,
+				default: '#333333'
+			},
+			size: {
+				type: [Number, String],
+				default: 16
+			},
+			customPrefix: {
+				type: String,
+				default: ''
+			},
+			fontFamily: {
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				icons: fontData
+			}
+		},
+		computed: {
+			unicode() {
+				let code = this.icons.find(v => v.font_class === this.type)
+				if (code) {
+					return code.unicode
+				}
+				return ''
+			},
+			iconSize() {
+				return getVal(this.size)
+			},
+			styleObj() {
+				if (this.fontFamily !== '') {
+					return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
+				}
+				return `color: ${this.color}; font-size: ${this.iconSize};`
+			}
+		},
+		methods: {
+			_onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/* #ifndef APP-NVUE */
+	@import './uniicons.css';
+
+	@font-face {
+		font-family: uniicons;
+		src: url('./uniicons.ttf');
+	}
+
+	/* #endif */
+	.uni-icons {
+		font-family: uniicons;
+		text-decoration: none;
+		text-align: center;
+	}
+</style>
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.css b/uni_modules/uni-icons/components/uni-icons/uniicons.css
new file mode 100644
index 0000000..0a6b6fe
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons.css
@@ -0,0 +1,664 @@
+
+.uniui-cart-filled:before {
+  content: "\e6d0";
+}
+
+.uniui-gift-filled:before {
+  content: "\e6c4";
+}
+
+.uniui-color:before {
+  content: "\e6cf";
+}
+
+.uniui-wallet:before {
+  content: "\e6b1";
+}
+
+.uniui-settings-filled:before {
+  content: "\e6ce";
+}
+
+.uniui-auth-filled:before {
+  content: "\e6cc";
+}
+
+.uniui-shop-filled:before {
+  content: "\e6cd";
+}
+
+.uniui-staff-filled:before {
+  content: "\e6cb";
+}
+
+.uniui-vip-filled:before {
+  content: "\e6c6";
+}
+
+.uniui-plus-filled:before {
+  content: "\e6c7";
+}
+
+.uniui-folder-add-filled:before {
+  content: "\e6c8";
+}
+
+.uniui-color-filled:before {
+  content: "\e6c9";
+}
+
+.uniui-tune-filled:before {
+  content: "\e6ca";
+}
+
+.uniui-calendar-filled:before {
+  content: "\e6c0";
+}
+
+.uniui-notification-filled:before {
+  content: "\e6c1";
+}
+
+.uniui-wallet-filled:before {
+  content: "\e6c2";
+}
+
+.uniui-medal-filled:before {
+  content: "\e6c3";
+}
+
+.uniui-fire-filled:before {
+  content: "\e6c5";
+}
+
+.uniui-refreshempty:before {
+  content: "\e6bf";
+}
+
+.uniui-location-filled:before {
+  content: "\e6af";
+}
+
+.uniui-person-filled:before {
+  content: "\e69d";
+}
+
+.uniui-personadd-filled:before {
+  content: "\e698";
+}
+
+.uniui-arrowthinleft:before {
+  content: "\e6d2";
+}
+
+.uniui-arrowthinup:before {
+  content: "\e6d3";
+}
+
+.uniui-arrowthindown:before {
+  content: "\e6d4";
+}
+
+.uniui-back:before {
+  content: "\e6b9";
+}
+
+.uniui-forward:before {
+  content: "\e6ba";
+}
+
+.uniui-arrow-right:before {
+  content: "\e6bb";
+}
+
+.uniui-arrow-left:before {
+  content: "\e6bc";
+}
+
+.uniui-arrow-up:before {
+  content: "\e6bd";
+}
+
+.uniui-arrow-down:before {
+  content: "\e6be";
+}
+
+.uniui-arrowthinright:before {
+  content: "\e6d1";
+}
+
+.uniui-down:before {
+  content: "\e6b8";
+}
+
+.uniui-bottom:before {
+  content: "\e6b8";
+}
+
+.uniui-arrowright:before {
+  content: "\e6d5";
+}
+
+.uniui-right:before {
+  content: "\e6b5";
+}
+
+.uniui-up:before {
+  content: "\e6b6";
+}
+
+.uniui-top:before {
+  content: "\e6b6";
+}
+
+.uniui-left:before {
+  content: "\e6b7";
+}
+
+.uniui-arrowup:before {
+  content: "\e6d6";
+}
+
+.uniui-eye:before {
+  content: "\e651";
+}
+
+.uniui-eye-filled:before {
+  content: "\e66a";
+}
+
+.uniui-eye-slash:before {
+  content: "\e6b3";
+}
+
+.uniui-eye-slash-filled:before {
+  content: "\e6b4";
+}
+
+.uniui-info-filled:before {
+  content: "\e649";
+}
+
+.uniui-reload:before {
+  content: "\e6b2";
+}
+
+.uniui-micoff-filled:before {
+  content: "\e6b0";
+}
+
+.uniui-map-pin-ellipse:before {
+  content: "\e6ac";
+}
+
+.uniui-map-pin:before {
+  content: "\e6ad";
+}
+
+.uniui-location:before {
+  content: "\e6ae";
+}
+
+.uniui-starhalf:before {
+  content: "\e683";
+}
+
+.uniui-star:before {
+  content: "\e688";
+}
+
+.uniui-star-filled:before {
+  content: "\e68f";
+}
+
+.uniui-calendar:before {
+  content: "\e6a0";
+}
+
+.uniui-fire:before {
+  content: "\e6a1";
+}
+
+.uniui-medal:before {
+  content: "\e6a2";
+}
+
+.uniui-font:before {
+  content: "\e6a3";
+}
+
+.uniui-gift:before {
+  content: "\e6a4";
+}
+
+.uniui-link:before {
+  content: "\e6a5";
+}
+
+.uniui-notification:before {
+  content: "\e6a6";
+}
+
+.uniui-staff:before {
+  content: "\e6a7";
+}
+
+.uniui-vip:before {
+  content: "\e6a8";
+}
+
+.uniui-folder-add:before {
+  content: "\e6a9";
+}
+
+.uniui-tune:before {
+  content: "\e6aa";
+}
+
+.uniui-auth:before {
+  content: "\e6ab";
+}
+
+.uniui-person:before {
+  content: "\e699";
+}
+
+.uniui-email-filled:before {
+  content: "\e69a";
+}
+
+.uniui-phone-filled:before {
+  content: "\e69b";
+}
+
+.uniui-phone:before {
+  content: "\e69c";
+}
+
+.uniui-email:before {
+  content: "\e69e";
+}
+
+.uniui-personadd:before {
+  content: "\e69f";
+}
+
+.uniui-chatboxes-filled:before {
+  content: "\e692";
+}
+
+.uniui-contact:before {
+  content: "\e693";
+}
+
+.uniui-chatbubble-filled:before {
+  content: "\e694";
+}
+
+.uniui-contact-filled:before {
+  content: "\e695";
+}
+
+.uniui-chatboxes:before {
+  content: "\e696";
+}
+
+.uniui-chatbubble:before {
+  content: "\e697";
+}
+
+.uniui-upload-filled:before {
+  content: "\e68e";
+}
+
+.uniui-upload:before {
+  content: "\e690";
+}
+
+.uniui-weixin:before {
+  content: "\e691";
+}
+
+.uniui-compose:before {
+  content: "\e67f";
+}
+
+.uniui-qq:before {
+  content: "\e680";
+}
+
+.uniui-download-filled:before {
+  content: "\e681";
+}
+
+.uniui-pyq:before {
+  content: "\e682";
+}
+
+.uniui-sound:before {
+  content: "\e684";
+}
+
+.uniui-trash-filled:before {
+  content: "\e685";
+}
+
+.uniui-sound-filled:before {
+  content: "\e686";
+}
+
+.uniui-trash:before {
+  content: "\e687";
+}
+
+.uniui-videocam-filled:before {
+  content: "\e689";
+}
+
+.uniui-spinner-cycle:before {
+  content: "\e68a";
+}
+
+.uniui-weibo:before {
+  content: "\e68b";
+}
+
+.uniui-videocam:before {
+  content: "\e68c";
+}
+
+.uniui-download:before {
+  content: "\e68d";
+}
+
+.uniui-help:before {
+  content: "\e679";
+}
+
+.uniui-navigate-filled:before {
+  content: "\e67a";
+}
+
+.uniui-plusempty:before {
+  content: "\e67b";
+}
+
+.uniui-smallcircle:before {
+  content: "\e67c";
+}
+
+.uniui-minus-filled:before {
+  content: "\e67d";
+}
+
+.uniui-micoff:before {
+  content: "\e67e";
+}
+
+.uniui-closeempty:before {
+  content: "\e66c";
+}
+
+.uniui-clear:before {
+  content: "\e66d";
+}
+
+.uniui-navigate:before {
+  content: "\e66e";
+}
+
+.uniui-minus:before {
+  content: "\e66f";
+}
+
+.uniui-image:before {
+  content: "\e670";
+}
+
+.uniui-mic:before {
+  content: "\e671";
+}
+
+.uniui-paperplane:before {
+  content: "\e672";
+}
+
+.uniui-close:before {
+  content: "\e673";
+}
+
+.uniui-help-filled:before {
+  content: "\e674";
+}
+
+.uniui-paperplane-filled:before {
+  content: "\e675";
+}
+
+.uniui-plus:before {
+  content: "\e676";
+}
+
+.uniui-mic-filled:before {
+  content: "\e677";
+}
+
+.uniui-image-filled:before {
+  content: "\e678";
+}
+
+.uniui-locked-filled:before {
+  content: "\e668";
+}
+
+.uniui-info:before {
+  content: "\e669";
+}
+
+.uniui-locked:before {
+  content: "\e66b";
+}
+
+.uniui-camera-filled:before {
+  content: "\e658";
+}
+
+.uniui-chat-filled:before {
+  content: "\e659";
+}
+
+.uniui-camera:before {
+  content: "\e65a";
+}
+
+.uniui-circle:before {
+  content: "\e65b";
+}
+
+.uniui-checkmarkempty:before {
+  content: "\e65c";
+}
+
+.uniui-chat:before {
+  content: "\e65d";
+}
+
+.uniui-circle-filled:before {
+  content: "\e65e";
+}
+
+.uniui-flag:before {
+  content: "\e65f";
+}
+
+.uniui-flag-filled:before {
+  content: "\e660";
+}
+
+.uniui-gear-filled:before {
+  content: "\e661";
+}
+
+.uniui-home:before {
+  content: "\e662";
+}
+
+.uniui-home-filled:before {
+  content: "\e663";
+}
+
+.uniui-gear:before {
+  content: "\e664";
+}
+
+.uniui-smallcircle-filled:before {
+  content: "\e665";
+}
+
+.uniui-map-filled:before {
+  content: "\e666";
+}
+
+.uniui-map:before {
+  content: "\e667";
+}
+
+.uniui-refresh-filled:before {
+  content: "\e656";
+}
+
+.uniui-refresh:before {
+  content: "\e657";
+}
+
+.uniui-cloud-upload:before {
+  content: "\e645";
+}
+
+.uniui-cloud-download-filled:before {
+  content: "\e646";
+}
+
+.uniui-cloud-download:before {
+  content: "\e647";
+}
+
+.uniui-cloud-upload-filled:before {
+  content: "\e648";
+}
+
+.uniui-redo:before {
+  content: "\e64a";
+}
+
+.uniui-images-filled:before {
+  content: "\e64b";
+}
+
+.uniui-undo-filled:before {
+  content: "\e64c";
+}
+
+.uniui-more:before {
+  content: "\e64d";
+}
+
+.uniui-more-filled:before {
+  content: "\e64e";
+}
+
+.uniui-undo:before {
+  content: "\e64f";
+}
+
+.uniui-images:before {
+  content: "\e650";
+}
+
+.uniui-paperclip:before {
+  content: "\e652";
+}
+
+.uniui-settings:before {
+  content: "\e653";
+}
+
+.uniui-search:before {
+  content: "\e654";
+}
+
+.uniui-redo-filled:before {
+  content: "\e655";
+}
+
+.uniui-list:before {
+  content: "\e644";
+}
+
+.uniui-mail-open-filled:before {
+  content: "\e63a";
+}
+
+.uniui-hand-down-filled:before {
+  content: "\e63c";
+}
+
+.uniui-hand-down:before {
+  content: "\e63d";
+}
+
+.uniui-hand-up-filled:before {
+  content: "\e63e";
+}
+
+.uniui-hand-up:before {
+  content: "\e63f";
+}
+
+.uniui-heart-filled:before {
+  content: "\e641";
+}
+
+.uniui-mail-open:before {
+  content: "\e643";
+}
+
+.uniui-heart:before {
+  content: "\e639";
+}
+
+.uniui-loop:before {
+  content: "\e633";
+}
+
+.uniui-pulldown:before {
+  content: "\e632";
+}
+
+.uniui-scan:before {
+  content: "\e62a";
+}
+
+.uniui-bars:before {
+  content: "\e627";
+}
+
+.uniui-checkbox:before {
+  content: "\e62b";
+}
+
+.uniui-checkbox-filled:before {
+  content: "\e62c";
+}
+
+.uniui-shop:before {
+  content: "\e62f";
+}
+
+.uniui-headphones:before {
+  content: "\e630";
+}
+
+.uniui-cart:before {
+  content: "\e631";
+}
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.ttf b/uni_modules/uni-icons/components/uni-icons/uniicons.ttf
new file mode 100644
index 0000000..14696d0
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons.ttf
Binary files differ
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts b/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
new file mode 100644
index 0000000..98e93aa
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
@@ -0,0 +1,664 @@
+
+export type IconsData = {
+	id : string
+	name : string
+	font_family : string
+	css_prefix_text : string
+	description : string
+	glyphs : Array<IconsDataItem>
+}
+
+export type IconsDataItem = {
+	font_class : string
+	unicode : string
+}
+
+
+export const fontData = [
+  {
+    "font_class": "arrow-down",
+    "unicode": "\ue6be"
+  },
+  {
+    "font_class": "arrow-left",
+    "unicode": "\ue6bc"
+  },
+  {
+    "font_class": "arrow-right",
+    "unicode": "\ue6bb"
+  },
+  {
+    "font_class": "arrow-up",
+    "unicode": "\ue6bd"
+  },
+  {
+    "font_class": "auth",
+    "unicode": "\ue6ab"
+  },
+  {
+    "font_class": "auth-filled",
+    "unicode": "\ue6cc"
+  },
+  {
+    "font_class": "back",
+    "unicode": "\ue6b9"
+  },
+  {
+    "font_class": "bars",
+    "unicode": "\ue627"
+  },
+  {
+    "font_class": "calendar",
+    "unicode": "\ue6a0"
+  },
+  {
+    "font_class": "calendar-filled",
+    "unicode": "\ue6c0"
+  },
+  {
+    "font_class": "camera",
+    "unicode": "\ue65a"
+  },
+  {
+    "font_class": "camera-filled",
+    "unicode": "\ue658"
+  },
+  {
+    "font_class": "cart",
+    "unicode": "\ue631"
+  },
+  {
+    "font_class": "cart-filled",
+    "unicode": "\ue6d0"
+  },
+  {
+    "font_class": "chat",
+    "unicode": "\ue65d"
+  },
+  {
+    "font_class": "chat-filled",
+    "unicode": "\ue659"
+  },
+  {
+    "font_class": "chatboxes",
+    "unicode": "\ue696"
+  },
+  {
+    "font_class": "chatboxes-filled",
+    "unicode": "\ue692"
+  },
+  {
+    "font_class": "chatbubble",
+    "unicode": "\ue697"
+  },
+  {
+    "font_class": "chatbubble-filled",
+    "unicode": "\ue694"
+  },
+  {
+    "font_class": "checkbox",
+    "unicode": "\ue62b"
+  },
+  {
+    "font_class": "checkbox-filled",
+    "unicode": "\ue62c"
+  },
+  {
+    "font_class": "checkmarkempty",
+    "unicode": "\ue65c"
+  },
+  {
+    "font_class": "circle",
+    "unicode": "\ue65b"
+  },
+  {
+    "font_class": "circle-filled",
+    "unicode": "\ue65e"
+  },
+  {
+    "font_class": "clear",
+    "unicode": "\ue66d"
+  },
+  {
+    "font_class": "close",
+    "unicode": "\ue673"
+  },
+  {
+    "font_class": "closeempty",
+    "unicode": "\ue66c"
+  },
+  {
+    "font_class": "cloud-download",
+    "unicode": "\ue647"
+  },
+  {
+    "font_class": "cloud-download-filled",
+    "unicode": "\ue646"
+  },
+  {
+    "font_class": "cloud-upload",
+    "unicode": "\ue645"
+  },
+  {
+    "font_class": "cloud-upload-filled",
+    "unicode": "\ue648"
+  },
+  {
+    "font_class": "color",
+    "unicode": "\ue6cf"
+  },
+  {
+    "font_class": "color-filled",
+    "unicode": "\ue6c9"
+  },
+  {
+    "font_class": "compose",
+    "unicode": "\ue67f"
+  },
+  {
+    "font_class": "contact",
+    "unicode": "\ue693"
+  },
+  {
+    "font_class": "contact-filled",
+    "unicode": "\ue695"
+  },
+  {
+    "font_class": "down",
+    "unicode": "\ue6b8"
+  },
+	{
+	  "font_class": "bottom",
+	  "unicode": "\ue6b8"
+	},
+  {
+    "font_class": "download",
+    "unicode": "\ue68d"
+  },
+  {
+    "font_class": "download-filled",
+    "unicode": "\ue681"
+  },
+  {
+    "font_class": "email",
+    "unicode": "\ue69e"
+  },
+  {
+    "font_class": "email-filled",
+    "unicode": "\ue69a"
+  },
+  {
+    "font_class": "eye",
+    "unicode": "\ue651"
+  },
+  {
+    "font_class": "eye-filled",
+    "unicode": "\ue66a"
+  },
+  {
+    "font_class": "eye-slash",
+    "unicode": "\ue6b3"
+  },
+  {
+    "font_class": "eye-slash-filled",
+    "unicode": "\ue6b4"
+  },
+  {
+    "font_class": "fire",
+    "unicode": "\ue6a1"
+  },
+  {
+    "font_class": "fire-filled",
+    "unicode": "\ue6c5"
+  },
+  {
+    "font_class": "flag",
+    "unicode": "\ue65f"
+  },
+  {
+    "font_class": "flag-filled",
+    "unicode": "\ue660"
+  },
+  {
+    "font_class": "folder-add",
+    "unicode": "\ue6a9"
+  },
+  {
+    "font_class": "folder-add-filled",
+    "unicode": "\ue6c8"
+  },
+  {
+    "font_class": "font",
+    "unicode": "\ue6a3"
+  },
+  {
+    "font_class": "forward",
+    "unicode": "\ue6ba"
+  },
+  {
+    "font_class": "gear",
+    "unicode": "\ue664"
+  },
+  {
+    "font_class": "gear-filled",
+    "unicode": "\ue661"
+  },
+  {
+    "font_class": "gift",
+    "unicode": "\ue6a4"
+  },
+  {
+    "font_class": "gift-filled",
+    "unicode": "\ue6c4"
+  },
+  {
+    "font_class": "hand-down",
+    "unicode": "\ue63d"
+  },
+  {
+    "font_class": "hand-down-filled",
+    "unicode": "\ue63c"
+  },
+  {
+    "font_class": "hand-up",
+    "unicode": "\ue63f"
+  },
+  {
+    "font_class": "hand-up-filled",
+    "unicode": "\ue63e"
+  },
+  {
+    "font_class": "headphones",
+    "unicode": "\ue630"
+  },
+  {
+    "font_class": "heart",
+    "unicode": "\ue639"
+  },
+  {
+    "font_class": "heart-filled",
+    "unicode": "\ue641"
+  },
+  {
+    "font_class": "help",
+    "unicode": "\ue679"
+  },
+  {
+    "font_class": "help-filled",
+    "unicode": "\ue674"
+  },
+  {
+    "font_class": "home",
+    "unicode": "\ue662"
+  },
+  {
+    "font_class": "home-filled",
+    "unicode": "\ue663"
+  },
+  {
+    "font_class": "image",
+    "unicode": "\ue670"
+  },
+  {
+    "font_class": "image-filled",
+    "unicode": "\ue678"
+  },
+  {
+    "font_class": "images",
+    "unicode": "\ue650"
+  },
+  {
+    "font_class": "images-filled",
+    "unicode": "\ue64b"
+  },
+  {
+    "font_class": "info",
+    "unicode": "\ue669"
+  },
+  {
+    "font_class": "info-filled",
+    "unicode": "\ue649"
+  },
+  {
+    "font_class": "left",
+    "unicode": "\ue6b7"
+  },
+  {
+    "font_class": "link",
+    "unicode": "\ue6a5"
+  },
+  {
+    "font_class": "list",
+    "unicode": "\ue644"
+  },
+  {
+    "font_class": "location",
+    "unicode": "\ue6ae"
+  },
+  {
+    "font_class": "location-filled",
+    "unicode": "\ue6af"
+  },
+  {
+    "font_class": "locked",
+    "unicode": "\ue66b"
+  },
+  {
+    "font_class": "locked-filled",
+    "unicode": "\ue668"
+  },
+  {
+    "font_class": "loop",
+    "unicode": "\ue633"
+  },
+  {
+    "font_class": "mail-open",
+    "unicode": "\ue643"
+  },
+  {
+    "font_class": "mail-open-filled",
+    "unicode": "\ue63a"
+  },
+  {
+    "font_class": "map",
+    "unicode": "\ue667"
+  },
+  {
+    "font_class": "map-filled",
+    "unicode": "\ue666"
+  },
+  {
+    "font_class": "map-pin",
+    "unicode": "\ue6ad"
+  },
+  {
+    "font_class": "map-pin-ellipse",
+    "unicode": "\ue6ac"
+  },
+  {
+    "font_class": "medal",
+    "unicode": "\ue6a2"
+  },
+  {
+    "font_class": "medal-filled",
+    "unicode": "\ue6c3"
+  },
+  {
+    "font_class": "mic",
+    "unicode": "\ue671"
+  },
+  {
+    "font_class": "mic-filled",
+    "unicode": "\ue677"
+  },
+  {
+    "font_class": "micoff",
+    "unicode": "\ue67e"
+  },
+  {
+    "font_class": "micoff-filled",
+    "unicode": "\ue6b0"
+  },
+  {
+    "font_class": "minus",
+    "unicode": "\ue66f"
+  },
+  {
+    "font_class": "minus-filled",
+    "unicode": "\ue67d"
+  },
+  {
+    "font_class": "more",
+    "unicode": "\ue64d"
+  },
+  {
+    "font_class": "more-filled",
+    "unicode": "\ue64e"
+  },
+  {
+    "font_class": "navigate",
+    "unicode": "\ue66e"
+  },
+  {
+    "font_class": "navigate-filled",
+    "unicode": "\ue67a"
+  },
+  {
+    "font_class": "notification",
+    "unicode": "\ue6a6"
+  },
+  {
+    "font_class": "notification-filled",
+    "unicode": "\ue6c1"
+  },
+  {
+    "font_class": "paperclip",
+    "unicode": "\ue652"
+  },
+  {
+    "font_class": "paperplane",
+    "unicode": "\ue672"
+  },
+  {
+    "font_class": "paperplane-filled",
+    "unicode": "\ue675"
+  },
+  {
+    "font_class": "person",
+    "unicode": "\ue699"
+  },
+  {
+    "font_class": "person-filled",
+    "unicode": "\ue69d"
+  },
+  {
+    "font_class": "personadd",
+    "unicode": "\ue69f"
+  },
+  {
+    "font_class": "personadd-filled",
+    "unicode": "\ue698"
+  },
+  {
+    "font_class": "personadd-filled-copy",
+    "unicode": "\ue6d1"
+  },
+  {
+    "font_class": "phone",
+    "unicode": "\ue69c"
+  },
+  {
+    "font_class": "phone-filled",
+    "unicode": "\ue69b"
+  },
+  {
+    "font_class": "plus",
+    "unicode": "\ue676"
+  },
+  {
+    "font_class": "plus-filled",
+    "unicode": "\ue6c7"
+  },
+  {
+    "font_class": "plusempty",
+    "unicode": "\ue67b"
+  },
+  {
+    "font_class": "pulldown",
+    "unicode": "\ue632"
+  },
+  {
+    "font_class": "pyq",
+    "unicode": "\ue682"
+  },
+  {
+    "font_class": "qq",
+    "unicode": "\ue680"
+  },
+  {
+    "font_class": "redo",
+    "unicode": "\ue64a"
+  },
+  {
+    "font_class": "redo-filled",
+    "unicode": "\ue655"
+  },
+  {
+    "font_class": "refresh",
+    "unicode": "\ue657"
+  },
+  {
+    "font_class": "refresh-filled",
+    "unicode": "\ue656"
+  },
+  {
+    "font_class": "refreshempty",
+    "unicode": "\ue6bf"
+  },
+  {
+    "font_class": "reload",
+    "unicode": "\ue6b2"
+  },
+  {
+    "font_class": "right",
+    "unicode": "\ue6b5"
+  },
+  {
+    "font_class": "scan",
+    "unicode": "\ue62a"
+  },
+  {
+    "font_class": "search",
+    "unicode": "\ue654"
+  },
+  {
+    "font_class": "settings",
+    "unicode": "\ue653"
+  },
+  {
+    "font_class": "settings-filled",
+    "unicode": "\ue6ce"
+  },
+  {
+    "font_class": "shop",
+    "unicode": "\ue62f"
+  },
+  {
+    "font_class": "shop-filled",
+    "unicode": "\ue6cd"
+  },
+  {
+    "font_class": "smallcircle",
+    "unicode": "\ue67c"
+  },
+  {
+    "font_class": "smallcircle-filled",
+    "unicode": "\ue665"
+  },
+  {
+    "font_class": "sound",
+    "unicode": "\ue684"
+  },
+  {
+    "font_class": "sound-filled",
+    "unicode": "\ue686"
+  },
+  {
+    "font_class": "spinner-cycle",
+    "unicode": "\ue68a"
+  },
+  {
+    "font_class": "staff",
+    "unicode": "\ue6a7"
+  },
+  {
+    "font_class": "staff-filled",
+    "unicode": "\ue6cb"
+  },
+  {
+    "font_class": "star",
+    "unicode": "\ue688"
+  },
+  {
+    "font_class": "star-filled",
+    "unicode": "\ue68f"
+  },
+  {
+    "font_class": "starhalf",
+    "unicode": "\ue683"
+  },
+  {
+    "font_class": "trash",
+    "unicode": "\ue687"
+  },
+  {
+    "font_class": "trash-filled",
+    "unicode": "\ue685"
+  },
+  {
+    "font_class": "tune",
+    "unicode": "\ue6aa"
+  },
+  {
+    "font_class": "tune-filled",
+    "unicode": "\ue6ca"
+  },
+  {
+    "font_class": "undo",
+    "unicode": "\ue64f"
+  },
+  {
+    "font_class": "undo-filled",
+    "unicode": "\ue64c"
+  },
+  {
+    "font_class": "up",
+    "unicode": "\ue6b6"
+  },
+	{
+	  "font_class": "top",
+	  "unicode": "\ue6b6"
+	},
+  {
+    "font_class": "upload",
+    "unicode": "\ue690"
+  },
+  {
+    "font_class": "upload-filled",
+    "unicode": "\ue68e"
+  },
+  {
+    "font_class": "videocam",
+    "unicode": "\ue68c"
+  },
+  {
+    "font_class": "videocam-filled",
+    "unicode": "\ue689"
+  },
+  {
+    "font_class": "vip",
+    "unicode": "\ue6a8"
+  },
+  {
+    "font_class": "vip-filled",
+    "unicode": "\ue6c6"
+  },
+  {
+    "font_class": "wallet",
+    "unicode": "\ue6b1"
+  },
+  {
+    "font_class": "wallet-filled",
+    "unicode": "\ue6c2"
+  },
+  {
+    "font_class": "weibo",
+    "unicode": "\ue68b"
+  },
+  {
+    "font_class": "weixin",
+    "unicode": "\ue691"
+  }
+] as IconsDataItem[]
+
+// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js b/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
new file mode 100644
index 0000000..1cd11e1
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
@@ -0,0 +1,649 @@
+
+export const fontData = [
+  {
+    "font_class": "arrow-down",
+    "unicode": "\ue6be"
+  },
+  {
+    "font_class": "arrow-left",
+    "unicode": "\ue6bc"
+  },
+  {
+    "font_class": "arrow-right",
+    "unicode": "\ue6bb"
+  },
+  {
+    "font_class": "arrow-up",
+    "unicode": "\ue6bd"
+  },
+  {
+    "font_class": "auth",
+    "unicode": "\ue6ab"
+  },
+  {
+    "font_class": "auth-filled",
+    "unicode": "\ue6cc"
+  },
+  {
+    "font_class": "back",
+    "unicode": "\ue6b9"
+  },
+  {
+    "font_class": "bars",
+    "unicode": "\ue627"
+  },
+  {
+    "font_class": "calendar",
+    "unicode": "\ue6a0"
+  },
+  {
+    "font_class": "calendar-filled",
+    "unicode": "\ue6c0"
+  },
+  {
+    "font_class": "camera",
+    "unicode": "\ue65a"
+  },
+  {
+    "font_class": "camera-filled",
+    "unicode": "\ue658"
+  },
+  {
+    "font_class": "cart",
+    "unicode": "\ue631"
+  },
+  {
+    "font_class": "cart-filled",
+    "unicode": "\ue6d0"
+  },
+  {
+    "font_class": "chat",
+    "unicode": "\ue65d"
+  },
+  {
+    "font_class": "chat-filled",
+    "unicode": "\ue659"
+  },
+  {
+    "font_class": "chatboxes",
+    "unicode": "\ue696"
+  },
+  {
+    "font_class": "chatboxes-filled",
+    "unicode": "\ue692"
+  },
+  {
+    "font_class": "chatbubble",
+    "unicode": "\ue697"
+  },
+  {
+    "font_class": "chatbubble-filled",
+    "unicode": "\ue694"
+  },
+  {
+    "font_class": "checkbox",
+    "unicode": "\ue62b"
+  },
+  {
+    "font_class": "checkbox-filled",
+    "unicode": "\ue62c"
+  },
+  {
+    "font_class": "checkmarkempty",
+    "unicode": "\ue65c"
+  },
+  {
+    "font_class": "circle",
+    "unicode": "\ue65b"
+  },
+  {
+    "font_class": "circle-filled",
+    "unicode": "\ue65e"
+  },
+  {
+    "font_class": "clear",
+    "unicode": "\ue66d"
+  },
+  {
+    "font_class": "close",
+    "unicode": "\ue673"
+  },
+  {
+    "font_class": "closeempty",
+    "unicode": "\ue66c"
+  },
+  {
+    "font_class": "cloud-download",
+    "unicode": "\ue647"
+  },
+  {
+    "font_class": "cloud-download-filled",
+    "unicode": "\ue646"
+  },
+  {
+    "font_class": "cloud-upload",
+    "unicode": "\ue645"
+  },
+  {
+    "font_class": "cloud-upload-filled",
+    "unicode": "\ue648"
+  },
+  {
+    "font_class": "color",
+    "unicode": "\ue6cf"
+  },
+  {
+    "font_class": "color-filled",
+    "unicode": "\ue6c9"
+  },
+  {
+    "font_class": "compose",
+    "unicode": "\ue67f"
+  },
+  {
+    "font_class": "contact",
+    "unicode": "\ue693"
+  },
+  {
+    "font_class": "contact-filled",
+    "unicode": "\ue695"
+  },
+  {
+    "font_class": "down",
+    "unicode": "\ue6b8"
+  },
+	{
+	  "font_class": "bottom",
+	  "unicode": "\ue6b8"
+	},
+  {
+    "font_class": "download",
+    "unicode": "\ue68d"
+  },
+  {
+    "font_class": "download-filled",
+    "unicode": "\ue681"
+  },
+  {
+    "font_class": "email",
+    "unicode": "\ue69e"
+  },
+  {
+    "font_class": "email-filled",
+    "unicode": "\ue69a"
+  },
+  {
+    "font_class": "eye",
+    "unicode": "\ue651"
+  },
+  {
+    "font_class": "eye-filled",
+    "unicode": "\ue66a"
+  },
+  {
+    "font_class": "eye-slash",
+    "unicode": "\ue6b3"
+  },
+  {
+    "font_class": "eye-slash-filled",
+    "unicode": "\ue6b4"
+  },
+  {
+    "font_class": "fire",
+    "unicode": "\ue6a1"
+  },
+  {
+    "font_class": "fire-filled",
+    "unicode": "\ue6c5"
+  },
+  {
+    "font_class": "flag",
+    "unicode": "\ue65f"
+  },
+  {
+    "font_class": "flag-filled",
+    "unicode": "\ue660"
+  },
+  {
+    "font_class": "folder-add",
+    "unicode": "\ue6a9"
+  },
+  {
+    "font_class": "folder-add-filled",
+    "unicode": "\ue6c8"
+  },
+  {
+    "font_class": "font",
+    "unicode": "\ue6a3"
+  },
+  {
+    "font_class": "forward",
+    "unicode": "\ue6ba"
+  },
+  {
+    "font_class": "gear",
+    "unicode": "\ue664"
+  },
+  {
+    "font_class": "gear-filled",
+    "unicode": "\ue661"
+  },
+  {
+    "font_class": "gift",
+    "unicode": "\ue6a4"
+  },
+  {
+    "font_class": "gift-filled",
+    "unicode": "\ue6c4"
+  },
+  {
+    "font_class": "hand-down",
+    "unicode": "\ue63d"
+  },
+  {
+    "font_class": "hand-down-filled",
+    "unicode": "\ue63c"
+  },
+  {
+    "font_class": "hand-up",
+    "unicode": "\ue63f"
+  },
+  {
+    "font_class": "hand-up-filled",
+    "unicode": "\ue63e"
+  },
+  {
+    "font_class": "headphones",
+    "unicode": "\ue630"
+  },
+  {
+    "font_class": "heart",
+    "unicode": "\ue639"
+  },
+  {
+    "font_class": "heart-filled",
+    "unicode": "\ue641"
+  },
+  {
+    "font_class": "help",
+    "unicode": "\ue679"
+  },
+  {
+    "font_class": "help-filled",
+    "unicode": "\ue674"
+  },
+  {
+    "font_class": "home",
+    "unicode": "\ue662"
+  },
+  {
+    "font_class": "home-filled",
+    "unicode": "\ue663"
+  },
+  {
+    "font_class": "image",
+    "unicode": "\ue670"
+  },
+  {
+    "font_class": "image-filled",
+    "unicode": "\ue678"
+  },
+  {
+    "font_class": "images",
+    "unicode": "\ue650"
+  },
+  {
+    "font_class": "images-filled",
+    "unicode": "\ue64b"
+  },
+  {
+    "font_class": "info",
+    "unicode": "\ue669"
+  },
+  {
+    "font_class": "info-filled",
+    "unicode": "\ue649"
+  },
+  {
+    "font_class": "left",
+    "unicode": "\ue6b7"
+  },
+  {
+    "font_class": "link",
+    "unicode": "\ue6a5"
+  },
+  {
+    "font_class": "list",
+    "unicode": "\ue644"
+  },
+  {
+    "font_class": "location",
+    "unicode": "\ue6ae"
+  },
+  {
+    "font_class": "location-filled",
+    "unicode": "\ue6af"
+  },
+  {
+    "font_class": "locked",
+    "unicode": "\ue66b"
+  },
+  {
+    "font_class": "locked-filled",
+    "unicode": "\ue668"
+  },
+  {
+    "font_class": "loop",
+    "unicode": "\ue633"
+  },
+  {
+    "font_class": "mail-open",
+    "unicode": "\ue643"
+  },
+  {
+    "font_class": "mail-open-filled",
+    "unicode": "\ue63a"
+  },
+  {
+    "font_class": "map",
+    "unicode": "\ue667"
+  },
+  {
+    "font_class": "map-filled",
+    "unicode": "\ue666"
+  },
+  {
+    "font_class": "map-pin",
+    "unicode": "\ue6ad"
+  },
+  {
+    "font_class": "map-pin-ellipse",
+    "unicode": "\ue6ac"
+  },
+  {
+    "font_class": "medal",
+    "unicode": "\ue6a2"
+  },
+  {
+    "font_class": "medal-filled",
+    "unicode": "\ue6c3"
+  },
+  {
+    "font_class": "mic",
+    "unicode": "\ue671"
+  },
+  {
+    "font_class": "mic-filled",
+    "unicode": "\ue677"
+  },
+  {
+    "font_class": "micoff",
+    "unicode": "\ue67e"
+  },
+  {
+    "font_class": "micoff-filled",
+    "unicode": "\ue6b0"
+  },
+  {
+    "font_class": "minus",
+    "unicode": "\ue66f"
+  },
+  {
+    "font_class": "minus-filled",
+    "unicode": "\ue67d"
+  },
+  {
+    "font_class": "more",
+    "unicode": "\ue64d"
+  },
+  {
+    "font_class": "more-filled",
+    "unicode": "\ue64e"
+  },
+  {
+    "font_class": "navigate",
+    "unicode": "\ue66e"
+  },
+  {
+    "font_class": "navigate-filled",
+    "unicode": "\ue67a"
+  },
+  {
+    "font_class": "notification",
+    "unicode": "\ue6a6"
+  },
+  {
+    "font_class": "notification-filled",
+    "unicode": "\ue6c1"
+  },
+  {
+    "font_class": "paperclip",
+    "unicode": "\ue652"
+  },
+  {
+    "font_class": "paperplane",
+    "unicode": "\ue672"
+  },
+  {
+    "font_class": "paperplane-filled",
+    "unicode": "\ue675"
+  },
+  {
+    "font_class": "person",
+    "unicode": "\ue699"
+  },
+  {
+    "font_class": "person-filled",
+    "unicode": "\ue69d"
+  },
+  {
+    "font_class": "personadd",
+    "unicode": "\ue69f"
+  },
+  {
+    "font_class": "personadd-filled",
+    "unicode": "\ue698"
+  },
+  {
+    "font_class": "personadd-filled-copy",
+    "unicode": "\ue6d1"
+  },
+  {
+    "font_class": "phone",
+    "unicode": "\ue69c"
+  },
+  {
+    "font_class": "phone-filled",
+    "unicode": "\ue69b"
+  },
+  {
+    "font_class": "plus",
+    "unicode": "\ue676"
+  },
+  {
+    "font_class": "plus-filled",
+    "unicode": "\ue6c7"
+  },
+  {
+    "font_class": "plusempty",
+    "unicode": "\ue67b"
+  },
+  {
+    "font_class": "pulldown",
+    "unicode": "\ue632"
+  },
+  {
+    "font_class": "pyq",
+    "unicode": "\ue682"
+  },
+  {
+    "font_class": "qq",
+    "unicode": "\ue680"
+  },
+  {
+    "font_class": "redo",
+    "unicode": "\ue64a"
+  },
+  {
+    "font_class": "redo-filled",
+    "unicode": "\ue655"
+  },
+  {
+    "font_class": "refresh",
+    "unicode": "\ue657"
+  },
+  {
+    "font_class": "refresh-filled",
+    "unicode": "\ue656"
+  },
+  {
+    "font_class": "refreshempty",
+    "unicode": "\ue6bf"
+  },
+  {
+    "font_class": "reload",
+    "unicode": "\ue6b2"
+  },
+  {
+    "font_class": "right",
+    "unicode": "\ue6b5"
+  },
+  {
+    "font_class": "scan",
+    "unicode": "\ue62a"
+  },
+  {
+    "font_class": "search",
+    "unicode": "\ue654"
+  },
+  {
+    "font_class": "settings",
+    "unicode": "\ue653"
+  },
+  {
+    "font_class": "settings-filled",
+    "unicode": "\ue6ce"
+  },
+  {
+    "font_class": "shop",
+    "unicode": "\ue62f"
+  },
+  {
+    "font_class": "shop-filled",
+    "unicode": "\ue6cd"
+  },
+  {
+    "font_class": "smallcircle",
+    "unicode": "\ue67c"
+  },
+  {
+    "font_class": "smallcircle-filled",
+    "unicode": "\ue665"
+  },
+  {
+    "font_class": "sound",
+    "unicode": "\ue684"
+  },
+  {
+    "font_class": "sound-filled",
+    "unicode": "\ue686"
+  },
+  {
+    "font_class": "spinner-cycle",
+    "unicode": "\ue68a"
+  },
+  {
+    "font_class": "staff",
+    "unicode": "\ue6a7"
+  },
+  {
+    "font_class": "staff-filled",
+    "unicode": "\ue6cb"
+  },
+  {
+    "font_class": "star",
+    "unicode": "\ue688"
+  },
+  {
+    "font_class": "star-filled",
+    "unicode": "\ue68f"
+  },
+  {
+    "font_class": "starhalf",
+    "unicode": "\ue683"
+  },
+  {
+    "font_class": "trash",
+    "unicode": "\ue687"
+  },
+  {
+    "font_class": "trash-filled",
+    "unicode": "\ue685"
+  },
+  {
+    "font_class": "tune",
+    "unicode": "\ue6aa"
+  },
+  {
+    "font_class": "tune-filled",
+    "unicode": "\ue6ca"
+  },
+  {
+    "font_class": "undo",
+    "unicode": "\ue64f"
+  },
+  {
+    "font_class": "undo-filled",
+    "unicode": "\ue64c"
+  },
+  {
+    "font_class": "up",
+    "unicode": "\ue6b6"
+  },
+	{
+	  "font_class": "top",
+	  "unicode": "\ue6b6"
+	},
+  {
+    "font_class": "upload",
+    "unicode": "\ue690"
+  },
+  {
+    "font_class": "upload-filled",
+    "unicode": "\ue68e"
+  },
+  {
+    "font_class": "videocam",
+    "unicode": "\ue68c"
+  },
+  {
+    "font_class": "videocam-filled",
+    "unicode": "\ue689"
+  },
+  {
+    "font_class": "vip",
+    "unicode": "\ue6a8"
+  },
+  {
+    "font_class": "vip-filled",
+    "unicode": "\ue6c6"
+  },
+  {
+    "font_class": "wallet",
+    "unicode": "\ue6b1"
+  },
+  {
+    "font_class": "wallet-filled",
+    "unicode": "\ue6c2"
+  },
+  {
+    "font_class": "weibo",
+    "unicode": "\ue68b"
+  },
+  {
+    "font_class": "weixin",
+    "unicode": "\ue691"
+  }
+]
+
+// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
diff --git a/uni_modules/uni-icons/package.json b/uni_modules/uni-icons/package.json
new file mode 100644
index 0000000..6b681b4
--- /dev/null
+++ b/uni_modules/uni-icons/package.json
@@ -0,0 +1,89 @@
+{
+  "id": "uni-icons",
+  "displayName": "uni-icons 图标",
+  "version": "2.0.10",
+  "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "icon",
+    "图标"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.2.14"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y",
+          "app-uvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y",
+					"钉钉": "y",
+					"快手": "y",
+					"飞书": "y",
+					"京东": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-icons/readme.md b/uni_modules/uni-icons/readme.md
new file mode 100644
index 0000000..86234ba
--- /dev/null
+++ b/uni_modules/uni-icons/readme.md
@@ -0,0 +1,8 @@
+## Icons 图标
+> **组件名:uni-icons**
+> 代码块: `uIcons`
+
+用于展示 icons 图标 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
diff --git a/uni_modules/uni-indexed-list/changelog.md b/uni_modules/uni-indexed-list/changelog.md
new file mode 100644
index 0000000..08fa71c
--- /dev/null
+++ b/uni_modules/uni-indexed-list/changelog.md
@@ -0,0 +1,17 @@
+## 1.2.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-indexed-list](https://uniapp.dcloud.io/component/uniui/uni-indexed-list)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.11(2021-05-12)
+- 新增 组件示例地址
+## 1.0.10(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.9(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.8(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 PC 端
diff --git a/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue b/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue
new file mode 100644
index 0000000..19284bd
--- /dev/null
+++ b/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue
@@ -0,0 +1,144 @@
+<template>
+	<view>
+		<view v-if="loaded || list.itemIndex < 15" class="uni-indexed-list__title-wrapper">
+			<text v-if="list.items && list.items.length > 0" class="uni-indexed-list__title">{{ list.key }}</text>
+		</view>
+		<view v-if="(loaded || list.itemIndex < 15) && list.items && list.items.length > 0" class="uni-indexed-list__list">
+			<view v-for="(item, index) in list.items" :key="index" class="uni-indexed-list__item" hover-class="uni-indexed-list__item--hover">
+				<view class="uni-indexed-list__item-container" @click="onClick(idx, index)">
+					<view class="uni-indexed-list__item-border" :class="{'uni-indexed-list__item-border--last':index===list.items.length-1}">
+						<view v-if="showSelect" style="margin-right: 20rpx;">
+							<uni-icons :type="item.checked ? 'checkbox-filled' : 'circle'" :color="item.checked ? '#007aff' : '#C0C0C0'" size="24" />
+						</view>
+						<text class="uni-indexed-list__item-content">{{ item.name }}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'UniIndexedList',
+		emits:['itemClick'],
+		props: {
+			loaded: {
+				type: Boolean,
+				default: false
+			},
+			idx: {
+				type: Number,
+				default: 0
+			},
+			list: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			showSelect: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			onClick(idx, index) {
+				this.$emit("itemClick", {
+					idx,
+					index
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-indexed-list__list {
+		background-color: $uni-bg-color;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		border-top-style: solid;
+		border-top-width: 1px;
+		border-top-color: #DEDEDE;
+	}
+
+	.uni-indexed-list__item {
+		font-size: 14px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+	}
+
+	.uni-indexed-list__item-container {
+		padding-left: 15px;
+		flex: 1;
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-indexed-list__item-border {
+		flex: 1;
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+		height: 50px;
+		padding: 25px;
+		padding-left: 0;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+		border-bottom-color:  #DEDEDE;
+	}
+
+	.uni-indexed-list__item-border--last {
+		border-bottom-width: 0px;
+	}
+
+	.uni-indexed-list__item-content {
+		flex: 1;
+		font-size: 14px;
+		color: #191919;
+	}
+
+	.uni-indexed-list {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-indexed-list__title-wrapper {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		width: 100%;
+		/* #endif */
+		background-color: #f7f7f7;
+	}
+
+	.uni-indexed-list__title {
+		padding: 6px 12px;
+		line-height: 24px;
+		font-size: 16px;
+		font-weight: 500;
+	}
+</style>
diff --git a/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue b/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue
new file mode 100644
index 0000000..ee3a7ec
--- /dev/null
+++ b/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue
@@ -0,0 +1,367 @@
+<template>
+	<view class="uni-indexed-list" ref="list" id="list">
+		<!-- #ifdef APP-NVUE -->
+		<list class="uni-indexed-list__scroll" scrollable="true" show-scrollbar="false">
+			<cell v-for="(list, idx) in lists" :key="idx" :ref="'uni-indexed-list-' + idx">
+				<!-- #endif -->
+				<!-- #ifndef APP-NVUE -->
+				<scroll-view :scroll-into-view="scrollViewId" class="uni-indexed-list__scroll" scroll-y>
+					<view v-for="(list, idx) in lists" :key="idx" :id="'uni-indexed-list-' + idx">
+						<!-- #endif -->
+						<indexed-list-item :list="list" :loaded="loaded" :idx="idx" :showSelect="showSelect"
+							@itemClick="onClick"></indexed-list-item>
+						<!-- #ifndef APP-NVUE -->
+					</view>
+				</scroll-view>
+				<!-- #endif -->
+				<!-- #ifdef APP-NVUE -->
+			</cell>
+		</list>
+		<!-- #endif -->
+		<view class="uni-indexed-list__menu" @touchstart="touchStart" @touchmove.stop.prevent="touchMove"
+			@touchend="touchEnd" @mousedown.stop="mousedown" @mousemove.stop.prevent="mousemove"
+			@mouseleave.stop="mouseleave">
+			<view v-for="(list, key) in lists" :key="key" class="uni-indexed-list__menu-item"
+				:class="touchmoveIndex == key ? 'uni-indexed-list__menu--active' : ''">
+				<text class="uni-indexed-list__menu-text"
+					:class="touchmoveIndex == key ? 'uni-indexed-list__menu-text--active' : ''">{{ list.key }}</text>
+			</view>
+		</view>
+		<view v-if="touchmove" class="uni-indexed-list__alert-wrapper">
+			<text class="uni-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text>
+		</view>
+	</view>
+</template>
+<script>
+	import indexedListItem from './uni-indexed-list-item.vue'
+	// #ifdef APP-NVUE
+	const dom = weex.requireModule('dom');
+	// #endif
+	// #ifdef APP-PLUS
+	function throttle(func, delay) {
+		var prev = Date.now();
+		return function() {
+			var context = this;
+			var args = arguments;
+			var now = Date.now();
+			if (now - prev >= delay) {
+				func.apply(context, args);
+				prev = Date.now();
+			}
+		}
+	}
+
+	function touchMove(e) {
+		let pageY = e.touches[0].pageY
+		let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
+		if (this.touchmoveIndex === index) {
+			return false
+		}
+		let item = this.lists[index]
+		if (item) {
+			// #ifndef APP-NVUE
+			this.scrollViewId = 'uni-indexed-list-' + index
+			this.touchmoveIndex = index
+			// #endif
+			// #ifdef APP-NVUE
+			dom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {
+				animated: false
+			})
+			this.touchmoveIndex = index
+			// #endif
+		}
+	}
+	const throttleTouchMove = throttle(touchMove, 40)
+	// #endif
+
+	/**
+	 * IndexedList 索引列表
+	 * @description 用于展示索引列表
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=375
+	 * @property {Boolean} showSelect = [true|false] 展示模式
+	 * 	@value true 展示模式
+	 * 	@value false 选择模式
+	 * @property {Object} options 索引列表需要的数据对象
+	 * @event {Function} click 点击列表事件 ,返回当前选择项的事件对象
+	 * @example <uni-indexed-list options="" showSelect="false" @click=""></uni-indexed-list>
+	 */
+	export default {
+		name: 'UniIndexedList',
+		components: {
+			indexedListItem
+		},
+		emits: ['click'],
+		props: {
+			options: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			showSelect: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				lists: [],
+				winHeight: 0,
+				itemHeight: 0,
+				winOffsetY: 0,
+				touchmove: false,
+				touchmoveIndex: -1,
+				scrollViewId: '',
+				touchmovable: true,
+				loaded: false,
+				isPC: false
+			}
+		},
+		watch: {
+			options: {
+				handler: function() {
+					this.setList()
+				},
+				deep: true
+			}
+		},
+		mounted() {
+			// #ifdef H5
+			this.isPC = this.IsPC()
+			// #endif
+			setTimeout(() => {
+				this.setList()
+			}, 50)
+			setTimeout(() => {
+				this.loaded = true
+			}, 300);
+		},
+		methods: {
+			setList() {
+				let index = 0;
+				this.lists = []
+				this.options.forEach((value, index) => {
+					if (value.data.length === 0) {
+						return
+					}
+					let indexBefore = index
+					let items = value.data.map(item => {
+						let obj = {}
+						obj['key'] = value.letter
+						obj['name'] = item
+						obj['itemIndex'] = index
+						index++
+						obj.checked = item.checked ? item.checked : false
+						return obj
+					})
+					this.lists.push({
+						title: value.letter,
+						key: value.letter,
+						items: items,
+						itemIndex: indexBefore
+					})
+				})
+				// #ifndef APP-NVUE
+				uni.createSelectorQuery()
+					.in(this)
+					.select('#list')
+					.boundingClientRect()
+					.exec(ret => {
+						this.winOffsetY = ret[0].top
+						this.winHeight = ret[0].height
+						this.itemHeight = this.winHeight / this.lists.length
+					})
+				// #endif
+				// #ifdef APP-NVUE
+				dom.getComponentRect(this.$refs['list'], (res) => {
+					this.winOffsetY = res.size.top
+					this.winHeight = res.size.height
+					this.itemHeight = this.winHeight / this.lists.length
+				})
+				// #endif
+			},
+			touchStart(e) {
+				this.touchmove = true
+				let pageY = this.isPC ? e.pageY : e.touches[0].pageY
+				let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
+				let item = this.lists[index]
+				if (item) {
+					this.scrollViewId = 'uni-indexed-list-' + index
+					this.touchmoveIndex = index
+					// #ifdef APP-NVUE
+					dom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {
+						animated: false
+					})
+					// #endif
+				}
+			},
+			touchMove(e) {
+				// #ifndef APP-PLUS
+				let pageY = this.isPC ? e.pageY : e.touches[0].pageY
+				let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
+				if (this.touchmoveIndex === index) {
+					return false
+				}
+				let item = this.lists[index]
+				if (item) {
+					this.scrollViewId = 'uni-indexed-list-' + index
+					this.touchmoveIndex = index
+				}
+				// #endif
+				// #ifdef APP-PLUS
+				throttleTouchMove.call(this, e)
+				// #endif
+			},
+			touchEnd() {
+				this.touchmove = false
+				// this.touchmoveIndex = -1
+			},
+
+			/**
+			 * 兼容 PC @tian
+			 */
+
+			mousedown(e) {
+				if (!this.isPC) return
+				this.touchStart(e)
+			},
+			mousemove(e) {
+				if (!this.isPC) return
+				this.touchMove(e)
+			},
+			mouseleave(e) {
+				if (!this.isPC) return
+				this.touchEnd(e)
+			},
+
+			// #ifdef H5
+			IsPC() {
+				var userAgentInfo = navigator.userAgent;
+				var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+				var flag = true;
+				for (let v = 0; v < Agents.length - 1; v++) {
+					if (userAgentInfo.indexOf(Agents[v]) > 0) {
+						flag = false;
+						break;
+					}
+				}
+				return flag;
+			},
+			// #endif
+
+
+			onClick(e) {
+				let {
+					idx,
+					index
+				} = e
+				let obj = {}
+				for (let key in this.lists[idx].items[index]) {
+					obj[key] = this.lists[idx].items[index][key]
+				}
+				let select = []
+				if (this.showSelect) {
+					this.lists[idx].items[index].checked = !this.lists[idx].items[index].checked
+					this.lists.forEach((value, idx) => {
+						value.items.forEach((item, index) => {
+							if (item.checked) {
+								let obj = {}
+								for (let key in this.lists[idx].items[index]) {
+									obj[key] = this.lists[idx].items[index][key]
+								}
+								select.push(obj)
+							}
+						})
+					})
+				}
+				this.$emit('click', {
+					item: obj,
+					select: select
+				})
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.uni-indexed-list {
+		position: absolute;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-indexed-list__scroll {
+		flex: 1;
+	}
+
+	.uni-indexed-list__menu {
+		width: 24px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-indexed-list__menu-item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		align-items: center;
+		justify-content: center;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-indexed-list__menu-text {
+		font-size: 12px;
+		text-align: center;
+		color: #aaa;
+	}
+
+	.uni-indexed-list__menu--active {
+		// background-color: rgb(200, 200, 200);
+	}
+
+	.uni-indexed-list__menu--active {}
+
+	.uni-indexed-list__menu-text--active {
+		border-radius: 16px;
+		width: 16px;
+		height: 16px;
+		line-height: 16px;
+		background-color: #007aff;
+		color: #fff;
+	}
+
+	.uni-indexed-list__alert-wrapper {
+		position: absolute;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.uni-indexed-list__alert {
+		width: 80px;
+		height: 80px;
+		border-radius: 80px;
+		text-align: center;
+		line-height: 80px;
+		font-size: 35px;
+		color: #fff;
+		background-color: rgba(0, 0, 0, 0.5);
+	}
+</style>
diff --git a/uni_modules/uni-indexed-list/package.json b/uni_modules/uni-indexed-list/package.json
new file mode 100644
index 0000000..125c0e7
--- /dev/null
+++ b/uni_modules/uni-indexed-list/package.json
@@ -0,0 +1,89 @@
+{
+  "id": "uni-indexed-list",
+  "displayName": "uni-indexed-list 索引列表",
+  "version": "1.2.1",
+  "description": "索引列表组件,右侧带索引的列表,方便快速定位到具体内容,通常用于城市/机场选择等场景",
+  "keywords": [
+    "uni-ui",
+    "索引列表",
+    "索引",
+    "列表"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-indexed-list/readme.md b/uni_modules/uni-indexed-list/readme.md
new file mode 100644
index 0000000..44ad84b
--- /dev/null
+++ b/uni_modules/uni-indexed-list/readme.md
@@ -0,0 +1,11 @@
+
+
+## IndexedList 索引列表
+> **组件名:uni-indexed-list**
+> 代码块: `uIndexedList`
+
+
+用于展示索引列表。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-indexed-list)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
diff --git a/uni_modules/uni-link/changelog.md b/uni_modules/uni-link/changelog.md
new file mode 100644
index 0000000..2cfbf59
--- /dev/null
+++ b/uni_modules/uni-link/changelog.md
@@ -0,0 +1,17 @@
+## 1.0.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-link](https://uniapp.dcloud.io/component/uniui/uni-link)
+## 1.1.7(2021-11-08)
+## 0.0.7(2021-09-03)
+- 修复 在 nvue 下不显示的 bug
+## 0.0.6(2021-07-30)
+- 新增 支持自定义插槽
+## 0.0.5(2021-06-21)
+- 新增 download 属性,H5平台下载文件名
+## 0.0.4(2021-05-12)
+- 新增 组件示例地址
+## 0.0.3(2021-03-09)
+- 新增 href 属性支持 tel:|mailto:
+
+## 0.0.2(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-link/components/uni-link/uni-link.vue b/uni_modules/uni-link/components/uni-link/uni-link.vue
new file mode 100644
index 0000000..27c5468
--- /dev/null
+++ b/uni_modules/uni-link/components/uni-link/uni-link.vue
@@ -0,0 +1,128 @@
+<template>
+	<a v-if="isShowA" class="uni-link" :href="href"
+		:class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
+		:style="{color,fontSize:fontSize+'px'}" :download="download">
+		<slot>{{text}}</slot>
+	</a>
+	<!-- #ifndef APP-NVUE -->
+	<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
+		:style="{color,fontSize:fontSize+'px'}" @click="openURL">
+		<slot>{{text}}</slot>
+	</text>
+	<!-- #endif -->
+	<!-- #ifdef APP-NVUE -->
+	<text v-else class="uni-link" :class="{'uni-link--withline':showUnderLine===true||showUnderLine==='true'}"
+		:style="{color,fontSize:fontSize+'px'}" @click="openURL">
+		{{text}}
+	</text>
+	<!-- #endif -->
+</template>
+
+<script>
+	/**
+	 * Link 外部网页超链接组件
+	 * @description uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=1182
+	 * @property {String} href 点击后打开的外部网页url
+	 * @property {String} text 显示的文字
+	 * @property {String} downlaod H5平台下载文件名
+	 * @property {Boolean} showUnderLine 是否显示下划线
+	 * @property {String} copyTips 在小程序端复制链接时显示的提示语
+	 * @property {String} color 链接文字颜色
+	 * @property {String} fontSize 链接文字大小
+	 * @example * <uni-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn"></uni-link>
+	 */
+	export default {
+		name: 'uniLink',
+		props: {
+			href: {
+				type: String,
+				default: ''
+			},
+			text: {
+				type: String,
+				default: ''
+			},
+			download: {
+				type: String,
+				default: ''
+			},
+			showUnderLine: {
+				type: [Boolean, String],
+				default: true
+			},
+			copyTips: {
+				type: String,
+				default: '已自动复制网址,请在手机浏览器里粘贴该网址'
+			},
+			color: {
+				type: String,
+				default: '#999999'
+			},
+			fontSize: {
+				type: [Number, String],
+				default: 14
+			}
+		},
+		computed: {
+			isShowA() {
+				// #ifdef H5
+				this._isH5 = true;
+				// #endif
+				if ((this.isMail() || this.isTel()) && this._isH5 === true) {
+					return true;
+				}
+				return false;
+			}
+		},
+		created() {
+			this._isH5 = null;
+		},
+		methods: {
+			isMail() {
+				return this.href.startsWith('mailto:');
+			},
+			isTel() {
+				return this.href.startsWith('tel:');
+			},
+			openURL() {
+				// #ifdef APP-PLUS
+				if (this.isTel()) {
+					this.makePhoneCall(this.href.replace('tel:', ''));
+				} else {
+					plus.runtime.openURL(this.href);
+				}
+				// #endif
+				// #ifdef H5
+				window.open(this.href)
+				// #endif
+				// #ifdef MP
+				uni.setClipboardData({
+					data: this.href
+				});
+				uni.showModal({
+					content: this.copyTips,
+					showCancel: false
+				});
+				// #endif
+			},
+			makePhoneCall(phoneNumber) {
+				uni.makePhoneCall({
+					phoneNumber
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	/* #ifndef APP-NVUE */
+	.uni-link {
+		cursor: pointer;
+	}
+
+	/* #endif */
+	.uni-link--withline {
+		text-decoration: underline;
+	}
+</style>
diff --git a/uni_modules/uni-link/package.json b/uni_modules/uni-link/package.json
new file mode 100644
index 0000000..77b1986
--- /dev/null
+++ b/uni_modules/uni-link/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-link",
+  "displayName": "uni-link 超链接",
+  "version": "1.0.0",
+  "description": "uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "link",
+    "超链接",
+    ""
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-link/readme.md b/uni_modules/uni-link/readme.md
new file mode 100644
index 0000000..7f09e94
--- /dev/null
+++ b/uni_modules/uni-link/readme.md
@@ -0,0 +1,11 @@
+
+
+## Link 链接
+> **组件名:uni-link**
+> 代码块: `uLink`
+
+
+uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-link)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-list/changelog.md b/uni_modules/uni-list/changelog.md
new file mode 100644
index 0000000..8254a18
--- /dev/null
+++ b/uni_modules/uni-list/changelog.md
@@ -0,0 +1,46 @@
+## 1.2.14(2023-04-14)
+- 优化 uni-list-chat 具名插槽`header` 非app端套一层元素,方便使用时通过外层元素定位实现样式修改
+## 1.2.13(2023-03-03)
+- uni-list-chat 新增 支持具名插槽`header`
+## 1.2.12(2023-02-01)
+- 新增 列表图标新增 customPrefix 属性 ,用法 [详见](https://uniapp.dcloud.net.cn/component/uniui/uni-icons.html#icons-props)
+## 1.2.11(2023-01-31)
+- 修复 无反馈效果呈现的bug
+## 1.2.9(2022-11-22)
+- 修复 uni-list-chat 在vue3下跳转报错的bug
+## 1.2.8(2022-11-21)
+- 修复 uni-list-chat avatar属性 值为本地路径时错误的问题
+## 1.2.7(2022-11-21)
+- 修复 uni-list-chat avatar属性 在腾讯云版uniCloud下错误的问题
+## 1.2.6(2022-11-18)
+- 修复 uni-list-chat note属性 支持:“草稿”字样功能 文本少1位的问题
+## 1.2.5(2022-11-15)
+- 修复 uni-list-item 的 customStyle 属性 padding值在 H5端 无效的bug
+## 1.2.4(2022-11-15)
+- 修复 uni-list-item 的 customStyle 属性 padding值在nvue(vue2)下无效的bug
+## 1.2.3(2022-11-14)
+- uni-list-chat 新增 avatar 支持 fileId
+## 1.2.2(2022-11-11)
+- uni-list 新增属性 render-reverse 详情参考:[https://uniapp.dcloud.net.cn/component/list.html](https://uniapp.dcloud.net.cn/component/list.html)
+- uni-list-chat note属性 支持:“草稿”字样 加红显示 详情参考uni-im:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im)
+- uni-list-item 新增属性 customStyle 支持设置padding、backgroundColor
+## 1.2.1(2022-03-30)
+- 删除无用文件
+## 1.2.0(2021-11-23)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-list](https://uniapp.dcloud.io/component/uniui/uni-list)
+## 1.1.3(2021-08-30)
+- 修复 在vue3中to属性在发行应用的时候报错的bug
+## 1.1.2(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.1.1(2021-07-21)
+- 修复 与其他组件嵌套使用时,点击失效的Bug
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.17(2021-05-12)
+- 新增 组件示例地址
+## 1.0.16(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.0.15(2021-02-05)
+- 调整为uni_modules目录规范
+- 修复 uni-list-chat 角标显示不正常的问题
diff --git a/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue b/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue
new file mode 100644
index 0000000..b9349c2
--- /dev/null
+++ b/uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue
@@ -0,0 +1,107 @@
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<cell>
+		<!-- #endif -->
+		<view class="uni-list-ad">
+			<view v-if="borderShow" :class="{'uni-list--border':border,'uni-list-item--first':isFirstChild}"></view>
+			<ad style="width: 200px;height: 300px;border-width: 1px;border-color: red;border-style: solid;" adpid="1111111111"
+			 unit-id="" appid="" apid="" type="feed" @error="aderror" @close="closeAd"></ad>
+		</view>
+		<!-- #ifdef APP-NVUE -->
+	</cell>
+	<!-- #endif -->
+
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const dom = uni.requireNativePlugin('dom');
+	// #endif
+	export default {
+		name: 'UniListAd',
+		props: {
+			title: {
+				type: String,
+				default: '',
+
+			}
+		},
+		// inject: ['list'],
+		data() {
+			return {
+				isFirstChild: false,
+				border: false,
+				borderShow: true,
+			}
+		},
+
+		mounted() {
+			this.list = this.getForm()
+			if (this.list) {
+				if (!this.list.firstChildAppend) {
+					this.list.firstChildAppend = true
+					this.isFirstChild = true
+				}
+				this.border = this.list.border
+			}
+		},
+		methods: {
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniList') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			aderror(e) {
+				console.log("aderror: " + JSON.stringify(e.detail));
+			},
+			closeAd(e) {
+				this.borderShow = false
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	.uni-list-ad {
+		position: relative;
+		border: 1px red solid;
+	}
+
+	.uni-list--border {
+		position: relative;
+		padding-bottom: 1px;
+		/* #ifdef APP-PLUS */
+		border-top-color: $uni-border-color;
+		border-top-style: solid;
+		border-top-width: 0.5px;
+		/* #endif */
+		margin-left: $uni-spacing-row-lg;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-list--border:after {
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: $uni-border-color;
+	}
+
+	.uni-list-item--first:after {
+		height: 0px;
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss b/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss
new file mode 100644
index 0000000..311f8d9
--- /dev/null
+++ b/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss
@@ -0,0 +1,58 @@
+/**
+ * 这里是 uni-list 组件内置的常用样式变量
+ * 如果需要覆盖样式,这里提供了基本的组件样式变量,您可以尝试修改这里的变量,去完成样式替换,而不用去修改源码
+ *
+ */
+
+// 背景色
+$background-color : #fff;
+// 分割线颜色
+$divide-line-color : #e5e5e5;
+
+// 默认头像大小,如需要修改此值,注意同步修改 js 中的值 const avatarWidth = xx ,目前只支持方形头像
+// nvue 页面不支持修改头像大小
+$avatar-width : 45px ;
+
+// 头像边框
+$avatar-border-radius: 5px;
+$avatar-border-color: #eee;
+$avatar-border-width: 1px;
+
+// 标题文字样式
+$title-size : 16px;
+$title-color : #3b4144;
+$title-weight : normal;
+
+// 描述文字样式
+$note-size : 12px;
+$note-color : #999;
+$note-weight : normal;
+
+// 右侧额外内容默认样式
+$right-text-size : 12px;
+$right-text-color : #999;
+$right-text-weight : normal;
+
+// 角标样式
+// nvue 页面不支持修改圆点位置以及大小
+// 角标在左侧时,角标的位置,默认为 0 ,负数左/下移动,正数右/上移动
+$badge-left: 0px;
+$badge-top: 0px;
+
+// 显示圆点时,圆点大小
+$dot-width: 10px;
+$dot-height: 10px;
+
+// 显示角标时,角标大小和字体大小
+$badge-size : 18px;
+$badge-font : 12px;
+// 显示角标时,角标前景色
+$badge-color : #fff;
+// 显示角标时,角标背景色
+$badge-background-color : #ff5a5f;
+// 显示角标时,角标左右间距
+$badge-space : 6px;
+
+// 状态样式
+// 选中颜色
+$hover : #f5f5f5;
diff --git a/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue b/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue
new file mode 100644
index 0000000..d49fd7c
--- /dev/null
+++ b/uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue
@@ -0,0 +1,593 @@
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<cell>
+		<!-- #endif -->
+		<view :hover-class="!clickable && !link ? '' : 'uni-list-chat--hover'" class="uni-list-chat" @click.stop="onClick">
+			<view :class="{ 'uni-list--border': border, 'uni-list-chat--first': isFirstChild }"></view>
+			<view class="uni-list-chat__container">
+				<view class="uni-list-chat__header-warp">
+					<view v-if="avatarCircle || avatarList.length === 0" class="uni-list-chat__header" :class="{ 'header--circle': avatarCircle }">
+						<image class="uni-list-chat__header-image" :class="{ 'header--circle': avatarCircle }" :src="avatarUrl" mode="aspectFill"></image>
+					</view>
+					<!-- 头像组 -->
+					<view v-else class="uni-list-chat__header">
+						<view v-for="(item, index) in avatarList" :key="index" class="uni-list-chat__header-box" :class="computedAvatar"
+						 :style="{ width: imageWidth + 'px', height: imageWidth + 'px' }">
+							<image class="uni-list-chat__header-image" :style="{ width: imageWidth + 'px', height: imageWidth + 'px' }" :src="item.url"
+							 mode="aspectFill"></image>
+						</view>
+					</view>
+				</view>
+				<!-- #ifndef APP -->
+				<view class="slot-header">
+				<!-- #endif -->
+					<slot name="header"></slot>
+				<!-- #ifndef APP -->
+				</view>
+				<!-- #endif -->
+				<view v-if="badgeText && badgePositon === 'left'" class="uni-list-chat__badge uni-list-chat__badge-pos" :class="[isSingle]">
+					<text class="uni-list-chat__badge-text">{{ badgeText === 'dot' ? '' : badgeText }}</text>
+				</view>
+				<view class="uni-list-chat__content">
+					<view class="uni-list-chat__content-main">
+						<text class="uni-list-chat__content-title uni-ellipsis">{{ title }}</text>
+						<view style="flex-direction: row;">
+							<text class="draft" v-if="isDraft">[草稿]</text>
+							<text class="uni-list-chat__content-note uni-ellipsis">{{isDraft?note.slice(14):note}}</text>
+						</view>
+					</view>
+					<view class="uni-list-chat__content-extra">
+						<slot>
+							<text class="uni-list-chat__content-extra-text">{{ time }}</text>
+							<view v-if="badgeText && badgePositon === 'right'" class="uni-list-chat__badge" :class="[isSingle, badgePositon === 'right' ? 'uni-list-chat--right' : '']">
+								<text class="uni-list-chat__badge-text">{{ badgeText === 'dot' ? '' : badgeText }}</text>
+							</view>
+						</slot>
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- #ifdef APP-NVUE -->
+	</cell>
+	<!-- #endif -->
+</template>
+
+<script>
+	// 头像大小
+	const avatarWidth = 45;
+
+	/**
+	 * ListChat 聊天列表
+	 * @description 聊天列表,用于创建聊天类列表
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=24
+	 * @property {String} 	title 							标题
+	 * @property {String} 	note 							描述
+	 * @property {Boolean} 	clickable = [true|false] 		是否开启点击反馈,默认为false
+	 * @property {String} 	badgeText						数字角标内容
+	 * @property {String}  	badgePositon = [left|right]		角标位置,默认为 right
+	 * @property {String} 	link = [false|navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈,默认为false
+	 *  @value false	 	不开启
+	 *  @value navigateTo 	同 uni.navigateTo()
+	 * 	@value redirectTo 	同 uni.redirectTo()
+	 * 	@value reLaunch   	同 uni.reLaunch()
+	 * 	@value switchTab  	同 uni.switchTab()
+	 * @property {String | PageURIString} 	to  			跳转目标页面
+	 * @property {String} 	time							右侧时间显示
+	 * @property {Boolean} 	avatarCircle = [true|false]		是否显示圆形头像,默认为false
+	 * @property {String} 	avatar							头像地址,avatarCircle 不填时生效
+	 * @property {Array} 	avatarList 						头像组,格式为 [{url:''}]
+	 * @event {Function} 	click 							点击 uniListChat 触发事件
+	 */
+	export default {
+		name: 'UniListChat',
+		emits:['click'],
+		props: {
+			title: {
+				type: String,
+				default: ''
+			},
+			note: {
+				type: String,
+				default: ''
+			},
+			clickable: {
+				type: Boolean,
+				default: false
+			},
+			link: {
+				type: [Boolean, String],
+				default: false
+			},
+			to: {
+				type: String,
+				default: ''
+			},
+			badgeText: {
+				type: [String, Number],
+				default: ''
+			},
+			badgePositon: {
+				type: String,
+				default: 'right'
+			},
+			time: {
+				type: String,
+				default: ''
+			},
+			avatarCircle: {
+				type: Boolean,
+				default: false
+			},
+			avatar: {
+				type: String,
+				default: ''
+			},
+			avatarList: {
+				type: Array,
+				default () {
+					return [];
+				}
+			}
+		},
+		// inject: ['list'],
+		computed: {
+			isDraft(){
+				return this.note.slice(0,14) == '[uni-im-draft]'
+			},
+			isSingle() {
+				if (this.badgeText === 'dot') {
+					return 'uni-badge--dot';
+				} else {
+					const badgeText = this.badgeText.toString();
+					if (badgeText.length > 1) {
+						return 'uni-badge--complex';
+					} else {
+						return 'uni-badge--single';
+					}
+				}
+			},
+			computedAvatar() {
+				if (this.avatarList.length > 4) {
+					this.imageWidth = avatarWidth * 0.31;
+					return 'avatarItem--3';
+				} else if (this.avatarList.length > 1) {
+					this.imageWidth = avatarWidth * 0.47;
+					return 'avatarItem--2';
+				} else {
+					this.imageWidth = avatarWidth;
+					return 'avatarItem--1';
+				}
+			}
+		},
+		watch: {
+			avatar:{
+				handler(avatar) {
+					if(avatar.substr(0,8) == 'cloud://'){
+						uniCloud.getTempFileURL({
+							fileList: [avatar]
+						}).then(res=>{
+							// console.log(res);
+							// 兼容uniCloud私有化部署
+							let fileList = res.fileList || res.result.fileList
+							this.avatarUrl = fileList[0].tempFileURL
+						})
+					}else{
+						this.avatarUrl = avatar
+					}
+				},
+				immediate: true
+			}
+		},
+		data() {
+			return {
+				isFirstChild: false,
+				border: true,
+				// avatarList: 3,
+				imageWidth: 50,
+				avatarUrl:''
+			};
+		},
+		mounted() {
+			this.list = this.getForm()
+			if (this.list) {
+				if (!this.list.firstChildAppend) {
+					this.list.firstChildAppend = true;
+					this.isFirstChild = true;
+				}
+				this.border = this.list.border;
+			}
+		},
+		methods: {
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniList') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			onClick() {
+				if (this.to !== '') {
+					this.openPage();
+					return;
+				}
+
+				if (this.clickable || this.link) {
+					this.$emit('click', {
+						data: {}
+					});
+				}
+			},
+			openPage() {
+				if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) {
+					this.pageApi(this.link);
+				} else {
+					this.pageApi('navigateTo');
+				}
+			},
+			pageApi(api) {
+				let callback = {
+					url: this.to,
+					success: res => {
+						this.$emit('click', {
+							data: res
+						});
+					},
+					fail: err => {
+						this.$emit('click', {
+							data: err
+						});
+					}
+				}
+				switch (api) {
+					case 'navigateTo':
+						uni.navigateTo(callback)
+						break
+					case 'redirectTo':
+						uni.redirectTo(callback)
+						break
+					case 'reLaunch':
+						uni.reLaunch(callback)
+						break
+					case 'switchTab':
+						uni.switchTab(callback)
+						break
+					default:
+					uni.navigateTo(callback)
+				}
+			}
+		}
+	};
+</script>
+
+<style lang="scss" >
+	$uni-font-size-lg:16px;
+	$uni-spacing-row-sm: 5px;
+	$uni-spacing-row-base: 10px;
+	$uni-spacing-row-lg: 15px;
+	$background-color: #fff;
+	$divide-line-color: #e5e5e5;
+	$avatar-width: 45px;
+	$avatar-border-radius: 5px;
+	$avatar-border-color: #eee;
+	$avatar-border-width: 1px;
+	$title-size: 16px;
+	$title-color: #3b4144;
+	$title-weight: normal;
+	$note-size: 12px;
+	$note-color: #999;
+	$note-weight: normal;
+	$right-text-size: 12px;
+	$right-text-color: #999;
+	$right-text-weight: normal;
+	$badge-left: 0px;
+	$badge-top: 0px;
+	$dot-width: 10px;
+	$dot-height: 10px;
+	$badge-size: 18px;
+	$badge-font: 12px;
+	$badge-color: #fff;
+	$badge-background-color: #ff5a5f;
+	$badge-space: 6px;
+	$hover: #f5f5f5;
+
+	.uni-list-chat {
+		font-size: $uni-font-size-lg;
+		position: relative;
+		flex-direction: column;
+		justify-content: space-between;
+		background-color: $background-color;
+	}
+
+	// .uni-list-chat--disabled {
+	// 	opacity: 0.3;
+	// }
+
+	.uni-list-chat--hover {
+		background-color: $hover;
+	}
+
+	.uni-list--border {
+		position: relative;
+		margin-left: $uni-spacing-row-lg;
+		/* #ifdef APP-PLUS */
+		border-top-color: $divide-line-color;
+		border-top-style: solid;
+		border-top-width: 0.5px;
+		/* #endif */
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-list--border:after {
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+		background-color: $divide-line-color;
+	}
+
+	.uni-list-item--first:after {
+		height: 0px;
+	}
+
+	/* #endif */
+
+	.uni-list-chat--first {
+		border-top-width: 0px;
+	}
+
+	.uni-ellipsis {
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		/* #endif */
+	}
+
+	.uni-ellipsis-2 {
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+		/* #endif */
+
+		/* #ifdef APP-NVUE */
+		lines: 2;
+		/* #endif */
+	}
+
+	.uni-list-chat__container {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex: 1;
+		padding: $uni-spacing-row-base $uni-spacing-row-lg;
+		position: relative;
+		overflow: hidden;
+	}
+
+	.uni-list-chat__header-warp {
+		position: relative;
+	}
+
+	.uni-list-chat__header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		align-content: center;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		flex-wrap: wrap-reverse;
+		/* #ifdef APP-NVUE */
+		width: 50px;
+		height: 50px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		width: $avatar-width;
+		height: $avatar-width;
+		/* #endif */
+
+		border-radius: $avatar-border-radius;
+		border-color: $avatar-border-color;
+		border-width: $avatar-border-width;
+		border-style: solid;
+		overflow: hidden;
+	}
+
+	.uni-list-chat__header-box {
+		/* #ifndef APP-PLUS */
+		box-sizing: border-box;
+		display: flex;
+		width: $avatar-width;
+		height: $avatar-width;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		width: 50px;
+		height: 50px;
+		/* #endif */
+		overflow: hidden;
+		border-radius: 2px;
+	}
+
+	.uni-list-chat__header-image {
+		margin: 1px;
+		/* #ifdef APP-NVUE */
+		width: 50px;
+		height: 50px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		width: $avatar-width;
+		height: $avatar-width;
+		/* #endif */
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-list-chat__header-image {
+		display: block;
+		width: 100%;
+		height: 100%;
+	}
+
+	.avatarItem--1 {
+		width: 100%;
+		height: 100%;
+	}
+
+	.avatarItem--2 {
+		width: 47%;
+		height: 47%;
+	}
+
+	.avatarItem--3 {
+		width: 32%;
+		height: 32%;
+	}
+
+	/* #endif */
+	.header--circle {
+		border-radius: 50%;
+	}
+
+	.uni-list-chat__content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex: 1;
+		overflow: hidden;
+		padding: 2px 0;
+	}
+
+	.uni-list-chat__content-main {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: space-between;
+		padding-left: $uni-spacing-row-base;
+		flex: 1;
+		overflow: hidden;
+	}
+
+	.uni-list-chat__content-title {
+		font-size: $title-size;
+		color: $title-color;
+		font-weight: $title-weight;
+		overflow: hidden;
+	}
+
+	.draft ,.uni-list-chat__content-note {
+		margin-top: 3px;
+		color: $note-color;
+		font-size: $note-size;
+		font-weight: $title-weight;
+		overflow: hidden;
+	}
+	.draft{
+		color: #eb3a41;
+		/* #ifndef APP-NVUE */
+		flex-shrink: 0;
+		/* #endif */
+		padding-right: 3px;
+	}
+
+	.uni-list-chat__content-extra {
+		/* #ifndef APP-NVUE */
+		flex-shrink: 0;
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: space-between;
+		align-items: flex-end;
+		margin-left: 5px;
+	}
+
+	.uni-list-chat__content-extra-text {
+		color: $right-text-color;
+		font-size: $right-text-size;
+		font-weight: $right-text-weight;
+		overflow: hidden;
+	}
+
+	.uni-list-chat__badge-pos {
+		position: absolute;
+		/* #ifdef APP-NVUE */
+		left: 55px;
+		top: 3px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		left: calc(#{$avatar-width} + 10px - #{$badge-space} + #{$badge-left});
+		top: calc(#{$uni-spacing-row-base}/ 2 + 1px + #{$badge-top});
+		/* #endif */
+	}
+
+	.uni-list-chat__badge {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		border-radius: 100px;
+		background-color: $badge-background-color;
+	}
+
+	.uni-list-chat__badge-text {
+		color: $badge-color;
+		font-size: $badge-font;
+	}
+
+	.uni-badge--single {
+		/* #ifndef APP-NVUE */
+		// left: calc(#{$avatar-width} + 7px + #{$badge-left});
+		/* #endif */
+		width: $badge-size;
+		height: $badge-size;
+	}
+
+	.uni-badge--complex {
+		/* #ifdef APP-NVUE */
+		left: 50px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		width: auto;
+		/* #endif */
+		height: $badge-size;
+		padding: 0 $badge-space;
+	}
+
+	.uni-badge--dot {
+		/* #ifdef APP-NVUE */
+		left: 60px;
+		top: 6px;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		left: calc(#{$avatar-width} + 15px - #{$dot-width}/ 2 + 1px + #{$badge-left});
+		/* #endif */
+		width: $dot-width;
+		height: $dot-height;
+		padding: 0;
+	}
+
+	.uni-list-chat--right {
+		/* #ifdef APP-NVUE */
+		left: 0;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue b/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
new file mode 100644
index 0000000..a274ac8
--- /dev/null
+++ b/uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
@@ -0,0 +1,534 @@
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<cell :keep-scroll-position="keepScrollPosition">
+		<!-- #endif -->
+		<view :class="{ 'uni-list-item--disabled': disabled }" :style="{'background-color':customStyle.backgroundColor}"
+			:hover-class="(!clickable && !link) || disabled || showSwitch ? '' : 'uni-list-item--hover'"
+			class="uni-list-item" @click="onClick">
+			<view v-if="!isFirstChild" class="border--left" :class="{ 'uni-list--border': border }"></view>
+			<view class="uni-list-item__container"
+				:class="{ 'container--right': showArrow || link, 'flex--direction': direction === 'column'}"
+				:style="{paddingTop:padding.top,paddingLeft:padding.left,paddingRight:padding.right,paddingBottom:padding.bottom}">
+				<slot name="header">
+					<view class="uni-list-item__header">
+						<view v-if="thumb" class="uni-list-item__icon">
+							<image :src="thumb" class="uni-list-item__icon-img" :class="['uni-list--' + thumbSize]" />
+						</view>
+						<view v-else-if="showExtraIcon" class="uni-list-item__icon">
+							<uni-icons :customPrefix="extraIcon.customPrefix" :color="extraIcon.color" :size="extraIcon.size" :type="extraIcon.type" />
+						</view>
+					</view>
+				</slot>
+				<slot name="body">
+					<view class="uni-list-item__content"
+						:class="{ 'uni-list-item__content--center': thumb || showExtraIcon || showBadge || showSwitch }">
+						<text v-if="title" class="uni-list-item__content-title"
+							:class="[ellipsis !== 0 && ellipsis <= 2 ? 'uni-ellipsis-' + ellipsis : '']">{{ title }}</text>
+						<text v-if="note" class="uni-list-item__content-note">{{ note }}</text>
+					</view>
+				</slot>
+				<slot name="footer">
+					<view v-if="rightText || showBadge || showSwitch" class="uni-list-item__extra"
+						:class="{ 'flex--justify': direction === 'column' }">
+						<text v-if="rightText" class="uni-list-item__extra-text">{{ rightText }}</text>
+						<uni-badge v-if="showBadge" :type="badgeType" :text="badgeText" :custom-style="badgeStyle" />
+						<switch v-if="showSwitch" :disabled="disabled" :checked="switchChecked"
+							@change="onSwitchChange" />
+					</view>
+				</slot>
+			</view>
+			<uni-icons v-if="showArrow || link" :size="16" class="uni-icon-wrapper" color="#bbb" type="arrowright" />
+		</view>
+		<!-- #ifdef APP-NVUE -->
+	</cell>
+	<!-- #endif -->
+</template>
+
+<script>
+	/**
+	 * ListItem 列表子组件
+	 * @description 列表子组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=24
+	 * @property {String} 	title 							标题
+	 * @property {String} 	note 							描述
+	 * @property {String} 	thumb 							左侧缩略图,若thumb有值,则不会显示扩展图标
+	 * @property {String}  	thumbSize = [lg|base|sm]		略缩图大小
+	 * 	@value 	 lg			大图
+	 * 	@value 	 base		一般
+	 * 	@value 	 sm			小图
+	 * @property {String} 	badgeText						数字角标内容
+	 * @property {String} 	badgeType 						数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)
+	 * @property {Object}   badgeStyle           数字角标样式
+	 * @property {String} 	rightText 						右侧文字内容
+	 * @property {Boolean} 	disabled = [true|false]			是否禁用
+	 * @property {Boolean} 	clickable = [true|false] 		是否开启点击反馈
+	 * @property {String} 	link = [navigateTo|redirectTo|reLaunch|switchTab] 是否展示右侧箭头并开启点击反馈
+	 *  @value 	navigateTo 	同 uni.navigateTo()
+	 * 	@value redirectTo 	同 uni.redirectTo()
+	 * 	@value reLaunch   	同 uni.reLaunch()
+	 * 	@value switchTab  	同 uni.switchTab()
+	 * @property {String | PageURIString} 	to  			跳转目标页面
+	 * @property {Boolean} 	showBadge = [true|false] 		是否显示数字角标
+	 * @property {Boolean} 	showSwitch = [true|false] 		是否显示Switch
+	 * @property {Boolean} 	switchChecked = [true|false] 	Switch是否被选中
+	 * @property {Boolean} 	showExtraIcon = [true|false] 	左侧是否显示扩展图标
+	 * @property {Object} 	extraIcon 						扩展图标参数,格式为 {color: '#4cd964',size: '22',type: 'spinner'}
+	 * @property {String} 	direction = [row|column]		排版方向
+	 * @value row 			水平排列
+	 * @value column 		垂直排列
+	 * @event {Function} 	click 							点击 uniListItem 触发事件
+	 * @event {Function} 	switchChange 					点击切换 Switch 时触发
+	 */
+	export default {
+		name: 'UniListItem',
+		emits: ['click', 'switchChange'],
+		props: {
+			direction: {
+				type: String,
+				default: 'row'
+			},
+			title: {
+				type: String,
+				default: ''
+			},
+			note: {
+				type: String,
+				default: ''
+			},
+			ellipsis: {
+				type: [Number, String],
+				default: 0
+			},
+			disabled: {
+				type: [Boolean, String],
+				default: false
+			},
+			clickable: {
+				type: Boolean,
+				default: false
+			},
+			showArrow: {
+				type: [Boolean, String],
+				default: false
+			},
+			link: {
+				type: [Boolean, String],
+				default: false
+			},
+			to: {
+				type: String,
+				default: ''
+			},
+			showBadge: {
+				type: [Boolean, String],
+				default: false
+			},
+			showSwitch: {
+				type: [Boolean, String],
+				default: false
+			},
+			switchChecked: {
+				type: [Boolean, String],
+				default: false
+			},
+			badgeText: {
+				type: String,
+				default: ''
+			},
+			badgeType: {
+				type: String,
+				default: 'success'
+			},
+			badgeStyle: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			rightText: {
+				type: String,
+				default: ''
+			},
+			thumb: {
+				type: String,
+				default: ''
+			},
+			thumbSize: {
+				type: String,
+				default: 'base'
+			},
+			showExtraIcon: {
+				type: [Boolean, String],
+				default: false
+			},
+			extraIcon: {
+				type: Object,
+				default () {
+					return {
+						type: '',
+						color: '#000000',
+						size: 20,
+						customPrefix: ''
+					};
+				}
+			},
+			border: {
+				type: Boolean,
+				default: true
+			},
+			customStyle: {
+				type: Object,
+				default () {
+					return {
+						padding: '',
+						backgroundColor: '#FFFFFF'
+					}
+				}
+			},
+			keepScrollPosition: {
+				type: Boolean,
+				default: false
+			}
+		},
+		watch: {
+			'customStyle.padding': {
+				handler(padding) {
+					if(typeof padding == 'number'){
+						padding += ''
+					}
+					let paddingArr = padding.split(' ')
+					if (paddingArr.length === 1) {
+						const allPadding = paddingArr[0]
+						this.padding = {
+							"top": allPadding,
+							"right": allPadding,
+							"bottom": allPadding,
+							"left": allPadding
+						}
+					} else if (paddingArr.length === 2) {
+						const [verticalPadding, horizontalPadding] = paddingArr;
+						this.padding = {
+							"top": verticalPadding,
+							"right": horizontalPadding,
+							"bottom": verticalPadding,
+							"left": horizontalPadding
+						}
+					} else if (paddingArr.length === 4) {
+							const [topPadding, rightPadding, bottomPadding, leftPadding] = paddingArr;
+							this.padding = {
+								"top": topPadding,
+								"right": rightPadding,
+								"bottom": bottomPadding,
+								"left": leftPadding
+							}
+					}
+				},
+				immediate: true
+			}
+		},
+		// inject: ['list'],
+		data() {
+			return {
+				isFirstChild: false,
+				padding: {
+					top: "",
+					right: "",
+					bottom: "",
+					left: ""
+				}
+			};
+		},
+		mounted() {
+			this.list = this.getForm()
+			// 判断是否存在 uni-list 组件
+			if (this.list) {
+				if (!this.list.firstChildAppend) {
+					this.list.firstChildAppend = true;
+					this.isFirstChild = true;
+				}
+			}
+		},
+		methods: {
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniList') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			onClick() {
+				if (this.to !== '') {
+					this.openPage();
+					return;
+				}
+				if (this.clickable || this.link) {
+					this.$emit('click', {
+						data: {}
+					});
+				}
+			},
+			onSwitchChange(e) {
+				this.$emit('switchChange', e.detail);
+			},
+			openPage() {
+				if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].indexOf(this.link) !== -1) {
+					this.pageApi(this.link);
+				} else {
+					this.pageApi('navigateTo');
+				}
+			},
+			pageApi(api) {
+				let callback = {
+					url: this.to,
+					success: res => {
+						this.$emit('click', {
+							data: res
+						});
+					},
+					fail: err => {
+						this.$emit('click', {
+							data: err
+						});
+					}
+				}
+				switch (api) {
+					case 'navigateTo':
+						uni.navigateTo(callback)
+						break
+					case 'redirectTo':
+						uni.redirectTo(callback)
+						break
+					case 'reLaunch':
+						uni.reLaunch(callback)
+						break
+					case 'switchTab':
+						uni.switchTab(callback)
+						break
+					default:
+						uni.navigateTo(callback)
+				}
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	$uni-font-size-sm:12px;
+	$uni-font-size-base:14px;
+	$uni-font-size-lg:16px;
+	$uni-spacing-col-lg: 12px;
+	$uni-spacing-row-lg: 15px;
+	$uni-img-size-sm:20px;
+	$uni-img-size-base:26px;
+	$uni-img-size-lg:40px;
+	$uni-border-color:#e5e5e5;
+	$uni-bg-color-hover:#f1f1f1;
+	$uni-text-color-grey:#999;
+	$list-item-pd: $uni-spacing-col-lg $uni-spacing-row-lg;
+
+	.uni-list-item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		font-size: $uni-font-size-lg;
+		position: relative;
+		justify-content: space-between;
+		align-items: center;
+		background-color: #fff;
+		flex-direction: row;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-list-item--disabled {
+		opacity: 0.3;
+	}
+
+	.uni-list-item--hover {
+		background-color: $uni-bg-color-hover !important;
+	}
+
+	.uni-list-item__container {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		padding: $list-item-pd;
+		padding-left: $uni-spacing-row-lg;
+		flex: 1;
+		overflow: hidden;
+		// align-items: center;
+	}
+
+	.container--right {
+		padding-right: 0;
+	}
+
+	// .border--left {
+	// 	margin-left: $uni-spacing-row-lg;
+	// }
+	.uni-list--border {
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+		/* #ifdef APP-NVUE */
+		border-top-color: $uni-border-color;
+		border-top-style: solid;
+		border-top-width: 0.5px;
+		/* #endif */
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-list--border:after {
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+		background-color: $uni-border-color;
+	}
+
+	/* #endif */
+	.uni-list-item__content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		padding-right: 8px;
+		flex: 1;
+		color: #3b4144;
+		// overflow: hidden;
+		flex-direction: column;
+		justify-content: space-between;
+		overflow: hidden;
+	}
+
+	.uni-list-item__content--center {
+		justify-content: center;
+	}
+
+	.uni-list-item__content-title {
+		font-size: $uni-font-size-base;
+		color: #3b4144;
+		overflow: hidden;
+	}
+
+	.uni-list-item__content-note {
+		margin-top: 6rpx;
+		color: $uni-text-color-grey;
+		font-size: $uni-font-size-sm;
+		overflow: hidden;
+	}
+
+	.uni-list-item__extra {
+		// width: 25%;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: flex-end;
+		align-items: center;
+	}
+
+	.uni-list-item__header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+	}
+
+	.uni-list-item__icon {
+		margin-right: 18rpx;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-list-item__icon-img {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		height: $uni-img-size-base;
+		width: $uni-img-size-base;
+		margin-right: 10px;
+	}
+
+	.uni-icon-wrapper {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		padding: 0 10px;
+	}
+
+	.flex--direction {
+		flex-direction: column;
+		/* #ifndef APP-NVUE */
+		align-items: initial;
+		/* #endif */
+	}
+
+	.flex--justify {
+		/* #ifndef APP-NVUE */
+		justify-content: initial;
+		/* #endif */
+	}
+
+	.uni-list--lg {
+		height: $uni-img-size-lg;
+		width: $uni-img-size-lg;
+	}
+
+	.uni-list--base {
+		height: $uni-img-size-base;
+		width: $uni-img-size-base;
+	}
+
+	.uni-list--sm {
+		height: $uni-img-size-sm;
+		width: $uni-img-size-sm;
+	}
+
+	.uni-list-item__extra-text {
+		color: $uni-text-color-grey;
+		font-size: $uni-font-size-sm;
+	}
+
+	.uni-ellipsis-1 {
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		text-overflow: ellipsis;
+		/* #endif */
+	}
+
+	.uni-ellipsis-2 {
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		lines: 2;
+		text-overflow: ellipsis;
+		/* #endif */
+	}
+</style>
\ No newline at end of file
diff --git a/uni_modules/uni-list/components/uni-list/uni-list.vue b/uni_modules/uni-list/components/uni-list/uni-list.vue
new file mode 100644
index 0000000..6ef5972
--- /dev/null
+++ b/uni_modules/uni-list/components/uni-list/uni-list.vue
@@ -0,0 +1,123 @@
+<template>
+	<!-- #ifndef APP-NVUE -->
+	<view class="uni-list uni-border-top-bottom">
+		<view v-if="border" class="uni-list--border-top"></view>
+		<slot />
+		<view v-if="border" class="uni-list--border-bottom"></view>
+	</view>
+	<!-- #endif -->
+	<!-- #ifdef APP-NVUE -->
+	<list :bounce="false" :scrollable="true" show-scrollbar :render-reverse="renderReverse" @scroll="scroll" class="uni-list" :class="{ 'uni-list--border': border }" :enableBackToTop="enableBackToTop"
+		loadmoreoffset="15">
+		<slot />
+	</list>
+	<!-- #endif -->
+</template>
+
+<script>
+	/**
+	 * List 列表
+	 * @description 列表组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=24
+	 * @property {String} 	border = [true|false] 		标题
+	 */
+	export default {
+		name: 'uniList',
+		'mp-weixin': {
+			options: {
+				multipleSlots: false
+			}
+		},
+		props: {
+			stackFromEnd:{
+				type: Boolean,
+				default:false
+			},
+			enableBackToTop: {
+				type: [Boolean, String],
+				default: false
+			},
+			scrollY: {
+				type: [Boolean, String],
+				default: false
+			},
+			border: {
+				type: Boolean,
+				default: true
+			},
+			renderReverse:{
+				type: Boolean,
+				default: false
+			}
+		},
+		// provide() {
+		// 	return {
+		// 		list: this
+		// 	};
+		// },
+		created() {
+			this.firstChildAppend = false;
+		},
+		methods: {
+			loadMore(e) {
+				this.$emit('scrolltolower');
+			},
+			scroll(e) {
+				this.$emit('scroll', e);
+			}
+		}
+	};
+</script>
+<style lang="scss">
+	$uni-bg-color:#ffffff;
+	$uni-border-color:#e5e5e5;
+
+	.uni-list {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		background-color: $uni-bg-color;
+		position: relative;
+		flex-direction: column;
+	}
+
+	.uni-list--border {
+		position: relative;
+		/* #ifdef APP-NVUE */
+		border-top-color: $uni-border-color;
+		border-top-style: solid;
+		border-top-width: 0.5px;
+		border-bottom-color: $uni-border-color;
+		border-bottom-style: solid;
+		border-bottom-width: 0.5px;
+		/* #endif */
+		z-index: -1;
+	}
+
+	/* #ifndef APP-NVUE */
+
+	.uni-list--border-top {
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+		height: 1px;
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+		background-color: $uni-border-color;
+		z-index: 1;
+	}
+
+	.uni-list--border-bottom {
+		position: absolute;
+		bottom: 0;
+		right: 0;
+		left: 0;
+		height: 1px;
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+		background-color: $uni-border-color;
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-list/components/uni-list/uni-refresh.vue b/uni_modules/uni-list/components/uni-list/uni-refresh.vue
new file mode 100644
index 0000000..3b4c5a2
--- /dev/null
+++ b/uni_modules/uni-list/components/uni-list/uni-refresh.vue
@@ -0,0 +1,65 @@
+<template>
+    <!-- #ifdef APP-NVUE -->
+    <refresh :display="display" @refresh="onrefresh" @pullingdown="onpullingdown">
+        <slot />
+    </refresh>
+    <!-- #endif -->
+    <!-- #ifndef APP-NVUE -->
+    <view ref="uni-refresh" class="uni-refresh" v-show="isShow">
+        <slot />
+    </view>
+    <!-- #endif -->
+</template>
+
+<script>
+    export default {
+        name: 'UniRefresh',
+        props: {
+            display: {
+                type: [String],
+                default: "hide"
+            }
+        },
+        data() {
+            return {
+                pulling: false
+            }
+        },
+        computed: {
+            isShow() {
+                if (this.display === "show" || this.pulling === true) {
+                    return true;
+                }
+                return false;
+            }
+        },
+        created() {},
+        methods: {
+            onchange(value) {
+                this.pulling = value;
+            },
+            onrefresh(e) {
+                this.$emit("refresh", e);
+            },
+            onpullingdown(e) {
+                // #ifdef APP-NVUE
+                this.$emit("pullingdown", e);
+                // #endif
+                // #ifndef APP-NVUE
+                var detail = {
+                    viewHeight: 90,
+                    pullingDistance: e.height
+                }
+                this.$emit("pullingdown", detail);
+                // #endif
+            }
+        }
+    }
+</script>
+
+<style>
+    .uni-refresh {
+        height: 0;
+        overflow: hidden;
+    }
+</style>
diff --git a/uni_modules/uni-list/components/uni-list/uni-refresh.wxs b/uni_modules/uni-list/components/uni-list/uni-refresh.wxs
new file mode 100644
index 0000000..818a6b7
--- /dev/null
+++ b/uni_modules/uni-list/components/uni-list/uni-refresh.wxs
@@ -0,0 +1,87 @@
+var pullDown = {
+    threshold: 95,
+    maxHeight: 200,
+    callRefresh: 'onrefresh',
+    callPullingDown: 'onpullingdown',
+    refreshSelector: '.uni-refresh'
+};
+
+function ready(newValue, oldValue, ownerInstance, instance) {
+    var state = instance.getState()
+    state.canPullDown = newValue;
+    // console.log(newValue);
+}
+
+function touchStart(e, instance) {
+    var state = instance.getState();
+    state.refreshInstance = instance.selectComponent(pullDown.refreshSelector);
+    state.canPullDown = (state.refreshInstance != null && state.refreshInstance != undefined);
+    if (!state.canPullDown) {
+        return
+    }
+
+    // console.log("touchStart");
+
+    state.height = 0;
+    state.touchStartY = e.touches[0].pageY || e.changedTouches[0].pageY;
+    state.refreshInstance.setStyle({
+        'height': 0
+    });
+    state.refreshInstance.callMethod("onchange", true);
+}
+
+function touchMove(e, ownerInstance) {
+    var instance = e.instance;
+    var state = instance.getState();
+    if (!state.canPullDown) {
+        return
+    }
+
+    var oldHeight = state.height;
+    var endY = e.touches[0].pageY || e.changedTouches[0].pageY;
+    var height = endY - state.touchStartY;
+    if (height > pullDown.maxHeight) {
+        return;
+    }
+
+    var refreshInstance = state.refreshInstance;
+    refreshInstance.setStyle({
+        'height': height + 'px'
+    });
+
+    height = height < pullDown.maxHeight ? height : pullDown.maxHeight;
+    state.height = height;
+    refreshInstance.callMethod(pullDown.callPullingDown, {
+        height: height
+    });
+}
+
+function touchEnd(e, ownerInstance) {
+    var state = e.instance.getState();
+    if (!state.canPullDown) {
+        return
+    }
+
+    state.refreshInstance.callMethod("onchange", false);
+
+    var refreshInstance = state.refreshInstance;
+    if (state.height > pullDown.threshold) {
+        refreshInstance.callMethod(pullDown.callRefresh);
+        return;
+    }
+
+    refreshInstance.setStyle({
+        'height': 0
+    });
+}
+
+function propObserver(newValue, oldValue, instance) {
+    pullDown = newValue;
+}
+
+module.exports = {
+    touchmove: touchMove,
+    touchstart: touchStart,
+    touchend: touchEnd,
+    propObserver: propObserver
+}
diff --git a/uni_modules/uni-list/package.json b/uni_modules/uni-list/package.json
new file mode 100644
index 0000000..8350efc
--- /dev/null
+++ b/uni_modules/uni-list/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-list",
+  "displayName": "uni-list 列表",
+  "version": "1.2.14",
+  "description": "List 组件 ,帮助使用者快速构建列表。",
+  "keywords": [
+    "",
+    "uni-ui",
+    "uniui",
+    "列表",
+    "",
+    "list"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+      "uni-badge",
+      "uni-icons"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-list/readme.md b/uni_modules/uni-list/readme.md
new file mode 100644
index 0000000..32c2865
--- /dev/null
+++ b/uni_modules/uni-list/readme.md
@@ -0,0 +1,346 @@
+## List 列表
+> **组件名:uni-list**
+> 代码块: `uList`、`uListItem`
+> 关联组件:`uni-list-item`、`uni-badge`、`uni-icons`、`uni-list-chat`、`uni-list-ad`
+
+
+List 列表组件,包含基本列表样式、可扩展插槽机制、长列表性能优化、多端兼容。
+
+在vue页面里,它默认使用页面级滚动。在app-nvue页面里,它默认使用原生list组件滚动。这样的长列表,在滚动出屏幕外后,系统会回收不可见区域的渲染内存资源,不会造成滚动越长手机越卡的问题。
+
+uni-list组件是父容器,里面的核心是uni-list-item子组件,它代表列表中的一个可重复行,子组件可以无限循环。
+
+uni-list-item有很多风格,uni-list-item组件通过内置的属性,满足一些常用的场景。当内置属性不满足需求时,可以通过扩展插槽来自定义列表内容。
+
+内置属性可以覆盖的场景包括:导航列表、设置列表、小图标列表、通信录列表、聊天记录列表。
+
+涉及很多大图或丰富内容的列表,比如类今日头条的新闻列表、类淘宝的电商列表,需要通过扩展插槽实现。
+
+下文均有样例给出。
+
+uni-list不包含下拉刷新和上拉翻页。上拉翻页另见组件:[uni-load-more](https://ext.dcloud.net.cn/plugin?id=29)
+
+
+### 安装方式
+
+本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
+
+如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
+
+> **注意事项**
+> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
+> - 组件需要依赖 `sass` 插件 ,请自行手动安装
+> - 组件内部依赖 `'uni-icons'` 、`uni-badge` 组件
+> - `uni-list` 和 `uni-list-item` 需要配套使用,暂不支持单独使用 `uni-list-item`
+> - 只有开启点击反馈后,会有点击选中效果
+> - 使用插槽时,可以完全自定义内容
+> - note 、rightText 属性暂时没做限制,不支持文字溢出隐藏,使用时应该控制长度显示或通过默认插槽自行扩展
+> - 支付宝小程序平台需要在支付宝小程序开发者工具里开启 component2 编译模式,开启方式: 详情 --> 项目配置 --> 启用 component2 编译
+> - 如果需要修改 `switch`、`badge` 样式,请使用插槽自定义
+> - 在 `HBuilderX` 低版本中,可能会出现组件显示 `undefined` 的问题,请升级最新的 `HBuilderX` 或者 `cli`
+> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+ 
+
+### 基本用法 
+
+- 设置 `title` 属性,可以显示列表标题
+- 设置 `disabled` 属性,可以禁用当前项
+
+```html
+<uni-list>
+	<uni-list-item  title="列表文字" ></uni-list-item>
+	<uni-list-item :disabled="true" title="列表禁用状态" ></uni-list-item>
+</uni-list>
+			 
+```
+
+### 多行内容显示
+
+- 设置 `note` 属性 ,可以在第二行显示描述文本信息
+
+```html
+<uni-list>
+	<uni-list-item title="列表文字" note="列表描述信息"></uni-list-item>
+	<uni-list-item :disabled="true" title="列表文字" note="列表禁用状态"></uni-list-item>
+</uni-list>
+
+```
+
+### 右侧显示角标、switch
+
+- 设置 `show-badge` 属性 ,可以显示角标内容
+- 设置 `show-switch` 属性,可以显示 switch 开关
+
+```html
+<uni-list>
+	<uni-list-item  title="列表右侧显示角标" :show-badge="true" badge-text="12" ></uni-list-item>
+	<uni-list-item title="列表右侧显示 switch"  :show-switch="true"  @switchChange="switchChange" ></uni-list-item>
+</uni-list>
+
+```
+
+### 左侧显示略缩图、图标  
+
+- 设置 `thumb` 属性 ,可以在列表左侧显示略缩图
+- 设置 `show-extra-icon` 属性,并指定 `extra-icon` 可以在左侧显示图标
+
+```html
+ <uni-list>
+ 	<uni-list-item title="列表左侧带略缩图" note="列表描述信息" thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"
+ 	 thumb-size="lg" rightText="右侧文字"></uni-list-item>
+ 	<uni-list-item :show-extra-icon="true" :extra-icon="extraIcon1" title="列表左侧带扩展图标" ></uni-list-item>
+</uni-list>
+```
+
+### 开启点击反馈和右侧箭头
+- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件
+- 设置 `link` 属性,会自动开启点击反馈,并给列表右侧添加一个箭头
+- 设置 `to` 属性,可以跳转页面,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo`
+
+```html
+
+<uni-list>
+	<uni-list-item title="开启点击反馈" clickable  @click="onClick" ></uni-list-item>
+	<uni-list-item title="默认 navigateTo 方式跳转页面" link to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
+	<uni-list-item title="reLaunch 方式跳转页面" link="reLaunch" to="/pages/vue/index/index" @click="onClick($event,1)" ></uni-list-item>
+</uni-list>
+
+```
+
+
+### 聊天列表示例
+- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件
+- 设置 `link` 属性,会自动开启点击反馈,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo`
+- 设置 `to` 属性,可以跳转页面
+- `time` 属性,通常会设置成时间显示,但是这个属性不仅仅可以设置时间,你可以传入任何文本,注意文本长度可能会影响显示
+- `avatar` 和 `avatarList` 属性同时只会有一个生效,同时设置的话,`avatarList` 属性的长度大于1 ,`avatar` 属性将失效
+- 可以通过默认插槽自定义列表右侧内容
+
+```html
+
+<uni-list>
+	<uni-list :border="true">
+		<!-- 显示圆形头像 -->
+		<uni-list-chat :avatar-circle="true" title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" ></uni-list-chat>
+		<!-- 右侧带角标 -->
+		<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-text="12" :badge-style="{backgroundColor:'#FF80AB'}"></uni-list-chat>
+		<!-- 头像显示圆点 -->
+		<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
+		<!-- 头像显示角标 -->
+		<uni-list-chat title="uni-app" avatar="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="99"></uni-list-chat>
+		<!-- 显示多头像 -->
+		<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot"></uni-list-chat>
+		<!-- 自定义右侧内容 -->
+		<uni-list-chat title="uni-app" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20" badge-positon="left" badge-text="dot">
+			<view class="chat-custom-right">
+				<text class="chat-custom-text">刚刚</text>
+				<!-- 需要使用 uni-icons 请自行引入 -->
+				<uni-icons type="star-filled" color="#999" size="18"></uni-icons>
+			</view>
+		</uni-list-chat>
+	</uni-list>
+</uni-list>
+
+```
+
+```javascript
+
+export default {
+	components: {},
+	data() {
+		return {
+			avatarList: [{
+				url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
+			}, {
+				url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
+			}, {
+				url: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png'
+			}]
+		}
+	}
+}
+
+```
+
+
+```css
+
+.chat-custom-right {
+	flex: 1;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: column;
+	justify-content: space-between;
+	align-items: flex-end;
+}
+
+.chat-custom-text {
+	font-size: 12px;
+	color: #999;
+}
+
+```
+
+## API
+
+### List Props
+
+属性名			|类型		|默认值		|	说明																									
+:-:				|:-:		|:-:		|	:-:	
+border			|Boolean	|true		|	是否显示边框
+
+
+### ListItem Props
+
+属性名			|类型		|默认值		|	说明																					
+:-:				|:-:		|:-:		|	:-:	
+title			|String		|-			|	标题
+note			|String		|-			|	描述
+ellipsis		|Number		|0			|	title 是否溢出隐藏,可选值,0:默认;  1:显示一行;	2:显示两行;【nvue 暂不支持】
+thumb			|String		|-			|	左侧缩略图,若thumb有值,则不会显示扩展图标
+thumbSize		|String 	|medium 	|	略缩图尺寸,可选值,lg:大图;  medium:一般;	sm:小图;
+showBadge		|Boolean	|false		|	是否显示数字角标	
+badgeText		|String		|-			|	数字角标内容
+badgeType		|String		|-			|	数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)	
+badgeStyle  |Object   |-      | 数字角标样式,使用uni-badge的custom-style参数
+rightText		|String		|-			|	右侧文字内容
+disabled		|Boolean	|false		|	是否禁用	
+showArrow 		|Boolean	|true		|	是否显示箭头图标			
+link			|String 	|navigateTo	|	新页面跳转方式,可选值见下表
+to				|String		|-			|	新页面跳转地址,如填写此属性,click 会返回页面是否跳转成功			
+clickable		|Boolean	|false		|	是否开启点击反馈
+showSwitch	    |Boolean	|false		|	是否显示Switch																			
+switchChecked	|Boolean	|false		|	Switch是否被选中																			
+showExtraIcon   |Boolean	|false		|	左侧是否显示扩展图标																		
+extraIcon		|Object		|-			|	扩展图标参数,格式为 ``{color: '#4cd964',size: '22',type: 'spinner'}``,参考 [uni-icons](https://ext.dcloud.net.cn/plugin?id=28)	
+direction		| String	|row		|	排版方向,可选值,row:水平排列;  column:垂直排列; 3个插槽是水平排还是垂直排,也受此属性控制
+
+
+#### Link Options
+
+属性名				|	说明
+:-:					|	:-:
+navigateTo 	| 	同 uni.navigateTo()
+redirectTo 	|	同 uni.reLaunch()
+reLaunch		|	同 uni.reLaunch()
+switchTab  	|	同 uni.switchTab()
+
+### ListItem Events
+
+事件称名			|说明									|返回参数			
+:-:				|:-:									|:-:				
+click			|点击 uniListItem 触发事件,需开启点击反馈	|-					
+switchChange	|点击切换 Switch 时触发,需显示 switch		|e={value:checked}	
+
+
+
+### ListItem Slots
+
+名称	 	|	说明					
+:-:		|	:-:						
+header	|	左/上内容插槽,可完全自定义默认显示
+body	|	中间内容插槽,可完全自定义中间内容				
+footer	|	右/下内容插槽,可完全自定义右侧内容		
+
+
+> **通过插槽扩展**
+> 需要注意的是当使用插槽时,内置样式将会失效,只保留排版样式,此时的样式需要开发者自己实现
+> 如果	`uni-list-item` 组件内置属性样式无法满足需求,可以使用插槽来自定义uni-list-item里的内容。
+> uni-list-item提供了3个可扩展的插槽:`header`、`body`、`footer`
+> - 当 `direction` 属性为 `row` 时表示水平排列,此时 `header` 表示列表的左边部分,`body` 表示列表的中间部分,`footer` 表示列表的右边部分
+> - 当 `direction` 属性为 `column` 时表示垂直排列,此时 `header` 表示列表的上边部分,`body` 表示列表的中间部分,`footer` 表示列表的下边部分
+> 开发者可以只用1个插槽,也可以3个一起使用。在插槽中可自主编写view标签,实现自己所需的效果。
+
+	
+**示例**
+
+```html
+<uni-list>
+	<uni-list-item title="自定义右侧插槽" note="列表描述信息" link>
+		<template slot="header">
+			<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
+		</template>
+	</uni-list-item>
+	<uni-list-item>
+		<!-- 自定义 header -->
+		<view slot="header" class="slot-box"><image class="slot-image" src="/static/logo.png" mode="widthFix"></image></view>
+		<!-- 自定义 body -->
+		<text slot="body" class="slot-box slot-text">自定义插槽</text>
+		<!-- 自定义 footer-->
+		<template slot="footer">
+			<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
+		</template>
+	</uni-list-item>
+</uni-list>
+```
+
+
+
+
+
+### ListItemChat Props
+
+属性名			|类型		|默认值		|	说明																		
+:-:				|:-:		|:-:		|	:-:	
+title 			|String		|-			|	标题
+note 			|String		|-			|	描述
+clickable		|Boolean	|false		|	是否开启点击反馈
+badgeText		|String		|-			|	数字角标内容,设置为 `dot` 将显示圆点
+badgePositon 	|String		|right		|	角标位置
+link			|String 	|navigateTo	|	是否展示右侧箭头并开启点击反馈,可选值见下表
+clickable		|Boolean	|false		|	是否开启点击反馈
+to				|String		|-			|	跳转页面地址,如填写此属性,click 会返回页面是否跳转成功	
+time			|String 	|-			|	右侧时间显示
+avatarCircle 	|Boolean 	|false		|	是否显示圆形头像
+avatar			|String 	|-			|	头像地址,avatarCircle 不填时生效
+avatarList 		|Array	 	|-			|	头像组,格式为 [{url:''}]
+
+#### Link Options
+
+属性名		|	说明
+:-:			|	:-:
+navigateTo 	| 	同 uni.navigateTo()
+redirectTo 	|	同 uni.reLaunch()
+reLaunch	|	同 uni.reLaunch()
+switchTab  	|	同 uni.switchTab()
+
+### ListItemChat Slots
+
+名称	 	|	说明					
+:-		|	:-						
+default	|	自定义列表右侧内容(包括时间和角标显示)
+
+### ListItemChat Events
+事件称名			|	说明						|	返回参数			
+:-:				|	:-:						|	:-:	
+@click			|	点击 uniListChat 触发事件	|	{data:{}}	,如有 to 属性,会返回页面跳转信息	
+
+
+
+
+
+
+## 基于uni-list扩展的页面模板
+
+通过扩展插槽,可实现多种常见样式的列表
+
+**新闻列表类**
+
+1. 云端一体混合布局:[https://ext.dcloud.net.cn/plugin?id=2546](https://ext.dcloud.net.cn/plugin?id=2546)
+2. 云端一体垂直布局,大图模式:[https://ext.dcloud.net.cn/plugin?id=2583](https://ext.dcloud.net.cn/plugin?id=2583)
+3. 云端一体垂直布局,多行图文混排:[https://ext.dcloud.net.cn/plugin?id=2584](https://ext.dcloud.net.cn/plugin?id=2584)
+4. 云端一体垂直布局,多图模式:[https://ext.dcloud.net.cn/plugin?id=2585](https://ext.dcloud.net.cn/plugin?id=2585)
+5. 云端一体水平布局,左图右文:[https://ext.dcloud.net.cn/plugin?id=2586](https://ext.dcloud.net.cn/plugin?id=2586)
+6. 云端一体水平布局,左文右图:[https://ext.dcloud.net.cn/plugin?id=2587](https://ext.dcloud.net.cn/plugin?id=2587)
+7. 云端一体垂直布局,无图模式,主标题+副标题:[https://ext.dcloud.net.cn/plugin?id=2588](https://ext.dcloud.net.cn/plugin?id=2588)
+
+**商品列表类**
+
+1. 云端一体列表/宫格视图互切:[https://ext.dcloud.net.cn/plugin?id=2651](https://ext.dcloud.net.cn/plugin?id=2651)
+2. 云端一体列表(宫格模式):[https://ext.dcloud.net.cn/plugin?id=2671](https://ext.dcloud.net.cn/plugin?id=2671)
+3. 云端一体列表(列表模式):[https://ext.dcloud.net.cn/plugin?id=2672](https://ext.dcloud.net.cn/plugin?id=2672)
+
+## 组件示例
+
+点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/list/list](https://hellouniapp.dcloud.net.cn/pages/extUI/list/list)
\ No newline at end of file
diff --git a/uni_modules/uni-load-more/changelog.md b/uni_modules/uni-load-more/changelog.md
new file mode 100644
index 0000000..667abdb
--- /dev/null
+++ b/uni_modules/uni-load-more/changelog.md
@@ -0,0 +1,25 @@
+## 1.3.6(2024-10-15)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.5(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.4(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.3(2022-01-20)
+- 新增 showText属性 ,是否显示文本
+## 1.3.2(2022-01-19)
+- 修复 nvue 平台下不显示文本的bug
+## 1.3.1(2022-01-19)
+- 修复 微信小程序平台样式选择器报警告的问题
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
+## 1.2.1(2021-08-24)
+- 新增 支持国际化
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.8(2021-05-12)
+- 新增 组件示例地址
+## 1.1.7(2021-03-30)
+- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
+## 1.1.6(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json b/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json
new file mode 100644
index 0000000..a4f14a5
--- /dev/null
+++ b/uni_modules/uni-load-more/components/uni-load-more/i18n/en.json
@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "Pull up to show more",
+	"uni-load-more.contentrefresh": "loading...",
+	"uni-load-more.contentnomore": "No more data"
+}
diff --git a/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js b/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-load-more/components/uni-load-more/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json b/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json
new file mode 100644
index 0000000..f15d510
--- /dev/null
+++ b/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json
@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "上拉显示更多",
+	"uni-load-more.contentrefresh": "正在加载...",
+	"uni-load-more.contentnomore": "没有更多数据了"
+}
diff --git a/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json b/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json
new file mode 100644
index 0000000..a255c6d
--- /dev/null
+++ b/uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json
@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "上拉顯示更多",
+	"uni-load-more.contentrefresh": "正在加載...",
+	"uni-load-more.contentnomore": "沒有更多數據了"
+}
diff --git a/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue b/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
new file mode 100644
index 0000000..a203417
--- /dev/null
+++ b/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
@@ -0,0 +1,404 @@
+<template>
+	<view class="uni-load-more" @click="onClick">
+		<!-- #ifdef APP-NVUE -->
+		<loading-indicator v-if="!webviewHide && status === 'loading' && showIcon"
+			:style="{color: color,width:iconSize+'px',height:iconSize+'px'}" :animating="true"
+			class="uni-load-more__img uni-load-more__img--nvue"></loading-indicator>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+		<svg width="24" height="24" viewBox="25 25 50 50"
+			v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
+			:style="{width:iconSize+'px',height:iconSize+'px'}"
+			class="uni-load-more__img uni-load-more__img--android-H5">
+			<circle cx="50" cy="50" r="20" fill="none" :style="{color:color}" :stroke-width="3"></circle>
+		</svg>
+		<!-- #endif -->
+		<!-- #ifndef APP-NVUE || H5 -->
+		<view
+			v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
+			:style="{width:iconSize+'px',height:iconSize+'px'}"
+			class="uni-load-more__img uni-load-more__img--android-MP">
+			<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
+			<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
+			<view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
+		</view>
+		<!-- #endif -->
+		<!-- #ifndef APP-NVUE -->
+		<view v-else-if="!webviewHide && status === 'loading' && showIcon"
+			:style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--ios-H5">
+			<image :src="imgBase64" mode="widthFix"></image>
+		</view>
+		<!-- #endif -->
+		<text v-if="showText" class="uni-load-more__text"
+			:style="{color: color}">{{ status === 'more' ? contentdownText : status === 'loading' ? contentrefreshText : contentnomoreText }}</text>
+	</view>
+</template>
+
+<script>
+	let platform
+	setTimeout(() => {
+		// #ifdef MP-WEIXIN
+		platform = uni.getDeviceInfo().platform
+		// #endif
+		// #ifndef MP-WEIXIN
+		platform = uni.getSystemInfoSync().platform
+		// #endif
+	}, 16)
+
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(messages)
+
+	/**
+	 * LoadMore 加载更多
+	 * @description 用于列表中,做滚动加载使用,展示 loading 的各种状态
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=29
+	 * @property {String} status = [more|loading|noMore] loading 的状态
+	 * 	@value more loading前
+	 * 	@value loading loading中
+	 * 	@value noMore 没有更多了
+	 * @property {Number} iconSize 指定图标大小
+	 * @property {Boolean} iconSize = [true|false] 是否显示 loading 图标
+	 * @property {String} iconType = [snow|circle|auto] 指定图标样式
+	 * 	@value snow ios雪花加载样式
+	 * 	@value circle 安卓唤醒加载样式
+	 * 	@value auto 根据平台自动选择加载样式
+	 * @property {String} color 图标和文字颜色
+	 * @property {Object} contentText 各状态文字说明,值为:{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}
+	 * @event {Function} clickLoadMore 点击加载更多时触发
+	 */
+	export default {
+		name: 'UniLoadMore',
+		emits: ['clickLoadMore'],
+		props: {
+			status: {
+				// 上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
+				type: String,
+				default: 'more'
+			},
+			showIcon: {
+				type: Boolean,
+				default: true
+			},
+			iconType: {
+				type: String,
+				default: 'auto'
+			},
+			iconSize: {
+				type: Number,
+				default: 24
+			},
+			color: {
+				type: String,
+				default: '#777777'
+			},
+			contentText: {
+				type: Object,
+				default () {
+					return {
+						contentdown: '',
+						contentrefresh: '',
+						contentnomore: ''
+					}
+				}
+			},
+			showText: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				webviewHide: false,
+				platform: platform,
+				imgBase64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZVHb98LM+F5bHL8khA1iSeiyQBCRM+YGqKUnnJTDLGI0BGZlKDIU2MMglUiDApEZvSsZnQtBRJtKwQNKQMFYeRDR10WOLd8ljYXdh+v8v5fR3Od+797t1dnOnO/Ofce77z+J//+b/P+ZqtXbs2sJ9MJhNUV1cHJ06cCJo3bx7EPc2aNcvpy7pWrVoF+/fvDyoqKoI2bdoE9fX1F7TjN8a+EXBn/fkfvw942Tf+wYMHg9mzZwfjxo0LDhw4EPa1x2MbFw/fOGfPng1qa2tzcCkILsLDydq2bRsunpOTMM7TD/W/tZDZhPdeKD+yGxHhdu3aBV27dg3OnDlzMVANMheLAO3btw8KCwuDmpoaX5OxbgUIMEq7K8IcPnw4KCsrC/r37x8cP378/4cAXAB3vqSkJMuiDhTkw+XcuXNhOWbMmKBly5YhUT8xArhyFvP0BfwRsAuwxJZJsm/nzp2DTp06he/OU+cZ64K6o0ePBkOHDg2GDx8e6gEbJ5Q/NHNuAJQ1hgBeHUDlR7nVTkY8rQAvAi4z34vR/mPs1FoRsaCgIJThI0eOBC1atEiFGGV+5MiRoS45efJkqFjJFXV1dQuA012m2WcwTw98fy6CqBdsaiIO4CScrGPHjvk4odhavPquRtFWXEC25VgkREKOCh/qDSq+vn37htzD/mZTOmOc5U7zKzBPEedygWshcDyWvs30igAbU+6oyMgJBCFhwQE0fccxN60Ay9iebbjoDh06hMowjQxT4fXq1SskArmHZpkArvixp/kWzHdMeArExSJEaiXIjjRjRJ4DaAGWpibLzXN3Fm1vA5teBgh3j1Rv3bp1YgKwPdmf2p9zcyNYYgPKMfY0T5f5nNYdw158nJ8QawW4CLKwiOBSEgO/hok2eBydR+3dYH+PLxA5J8Vv0KBBwenTp0P2JWAx6+yFEBfs8lMY+y0SWMBNI9E4ThKi58VKTg3FQZS1RQF1cz27eC0QHMu+3E0SkUowjhVt5VdaWhp07949ZHv2Qd1EjDXM2cla1M0nl3GxAs3J9yREzyTdFVKVFOaE9qRA8GM0WebRuo9JGZKA7Mv2SeS/Z8+eoQ9BArMfFrLGo6jvxbhHbJZnKX2Rzz1O7QhJJ9Cs2ZMaWIyq/zhdeqPNfIoHd58clIQD+JSXl4dKlyIAuBdVXZwFVWKspSSoxE++h8x4k3uCnEhE4I5KwRiFWGOU0QWKiCYLbdoRMRKAu2kQ9vkfLU6dOhX06NEjlH+yMRZSinnuyWnYosVcji8CEA/6Cg2JF+IIUBqnGKUTCNwtwBN4f89RiK1R96DEgO2o0NDmtEdvVFdVVYV+P3UAPUEs6GFwV3PHmXkD4vh74iDFJysVI/MlaQhwKeBNTLYX5VuA8T4/gZxA4MRGFxDB6R7OmYPfyykGRJbyie+XnGYnQIC/coH9+vULiYrxrkL9ZA9+0ykaHIfEpM7ge8TiJ2CsHYwyMfafAF1yCGBHYIbCVDjDjKt7BeB51D+LgQa6OkG7IDYEEtvQ7lnXLKLtLdLuJBpE4gPUXcW2+PkZwOex+4cGDhwYDBkyRL7/HFcEwUGPo/8uWRUpYnfxGHco8HkewLHLyYmAawAPuIFZxhOpDfJQ8gbUv41yORAptMWBNr6oqMhWird5+u+iHmBb2nhjDV7HWBNQTgK8y11l5NetWzc5ULscAtSj7nbNI0skhWeUZCc0W4nyH/jO4Vz0u1IeYhbk4AiwM6tjxIWByHsoZ9qcIBPJd/y+DwPfBESOmCa/QF3WiZHucLlEDpNxcNhmheEOPgdQNx6/VZFQzFZ5TN08AHXQt2Ii3EdyFuUsPtTcGPhW5iMiCNELvz+Gdn9huG4HUJaW/w3g0wxV0XaG7arG2WeKiUWYM4Y7GO5ezshTARbbWGw/DvXkpp/ivVvE0JVoMxN4rpGzJMhE5Pl+xlATsDIqikP9F9D2z3h9nOksEUFhK+qO4rcPkoalMQ/HqJLIyb3F3JdjrCcw1yZ8joyJLR5gCo54etlag7qIoeNh1N1BRYj3DTFJ0elotxPlVzkGuYAmL0VSJVGAJA41c4Z6A3BzTLfn0HYwYKEI6CUAMzZEWvLsIcQOo1AmmyyM72nHJCfYsogflGV6jEk9vyQZXSuq6w4c16NsGcGZbwOPr+H1RkOk2LEzjNepxQkihHSCQ4ynAYNRx2zMKV92CQMWqj8J0BRE8EShxRFN6YrfCRhC0x3r/Zm4IbQCcmJoV0kMamllccR6FjHqUC5F2R/wS2dcymOlfAKOS4KmzQb5cpNC2MC7JhVn5wjXoJ44rYhLh8n0eXOCorJxa7POjbSlCGVczr34/RsAmrcvo9s+wGp3tzVhntxiXiJ4nvEYb4FJkf0O8HocAePmLvCxnL0AORraVekJk6TYjDabRVXfRE2lCN1h6ZQRN1+InUbsCpKwoBZHh0dODN9JBCUffItXxEavTQkUtnfTVAplCWL3JISz29h4NjotnuSsQKJCk8dF+kJR6RARjrqFVmfPnj3ZbK8cIJ0msd6jgHPGtfVTQ8VLmlvh4mct9sobRmPic0DyDQQnx/NlfYUgyz59+oScsH379pAwXABD32nTpoUHIToESeI5mnbE/UqDdyLcafEBf2MCqgC7NwxIbMREJQ0g4D4sfJwnD+AmRrII05cfMWJE+L1169bQr+fip06dGp4oJ83lmYd5wj/EmMa4TaHivo4EeCguYZBnkB5g2aWA69OIEnUHOaGysjIYMGBAMGnSpODYsWPZwCpFmm4lNq+4gSLQA7jcX8DwtjEyRC8wjabnXEx9kfWnTJkSJkAo90xpJVV+FmcVNeYAF5zWngS4C4O91MBxmAv8blLEpbjI5sz9MTdAhcgkCT1RO8mZkAjfiYpTEvStAS53Uw1vAiUGgZ3GpuQEYvoiBqlIan7kSDHnTwJQFNiPu0+5VxCVYhcZIjNrdXUDdp+Eq5AZ3Gkg8QAyVZRZIk4Tl4QAbF9cXJxNYZMAtAokgs4BrNxEpCtteXg7DDTMDKYNSuQdKsnJBek7HxewvxaosWxLYXtw+cJp18217wql4aKCfBNoEu0O5VU+PhctJ0YeXD4C6JQpyrlpSLTojpGGGN5YwNziChdIZLk4lvLcFJ9jMX3QdiImY9bmGQU+TRUL5CHITTRlgF8D9ouD1MfmLoEPl5xokIumZ2cfgMpHt47IW9N64Hsh7wQYYjyIugWuF5fCqYncXRd5vPMWyizzvhi/32+nvG0dZc9vR6fZOu0md5e+uC408FvKSIOZwXlGvxPv95izA2Vtvg1xKFWARI+vMX66HUhpQQb643uW1bSjuTWyw2SBvDrBvjFic1eGGlz5esq3ko9uSIlBRqPuFcCv8F4WIcN12nVaBd0SaYwI6PDDImR11JkqgHcPmQssjxIn6bUshygDFJUTxPMpHk+jfjPgupgdnYV2R/g7xSjtpah8RJBewhwf0gGK6XI92u4wXFEU40afJ4DN4h5LcAd+40HI3JgJecuT0c062W0i2hQJUTcxan3/CMW1PF2K6bbA+Daz4xRs1D3Br1Cm0OihKCqizW78/nXAF/G5TXrEcVzaNMH6CyMswqsAHqDyDLEyou8lwOXnKF8DjI6KjV3KzMBiXkDH8ij/H214J5A596ekrZ3F0zXlWeL7+P5eUrNo3/QwC15uxthuzidy7DzKRwEDaAViiDgKbTbz7CJnzo0bN7pIfIiid8SuPwn25o3QCmpnyjlZkyxPP8EomCJzrGb7GJMx7tNsq4MT2xMUYaiErZOluTzKsnz3gwCeCZyVRZJfYplNEokEjwrPtxlxjeYAk+F1F74VAzPxQRNYYdtpOUvWs8J1sGhBJMNsb7igN8plJs1eSmLIhLKE4rvaCX27gOhLpLOsIzJ7qn/i+wZzcvSOZ23/du8TZjwV8zHIXoP4R3ifBxiFz1dcVpa3aPntPE+c6TmIWE9EtcMmAcPdWAhYhAXxcLOQi9L1WhD1Sc8p1d2oL7XGiRKp8F4A2i8K/nfI+y/gsTDJ/YC/8+AD5Uh04KHiGl+cIFPnBDDrPMjwRGkLXyxO4VGbfQWnDH2v0bVWE3C9QOXlepbgjEfIJQI6XDG3z5ahD9cw2pS78ipB85wyScNTvsVzlzzhL8/jRrnmVjfFJK/m3m4nj9vbgQTguT8XZTjsm672R5uJKEaQmBI/c58gyus8ZDagLpEVSJBIyHp4jn++xqPV71OgQgJYEWOtZ/haxRtKmWOBu8xdBLftWltsY84zE6WIEy/eIOWL+BaayMx+KHtL7EAkqdNDLiEXmEMUHniedtJqg9HmZtfvt26vNi0BdG3Ft3g8ZOf7PAu59TxtzivLNIekyi+wD1i8CuUiD9FXAa8C+/xS3JPmZnomyc7H+fb4/Se0bk41Fel621r4cgVxbq91V4jVqwB7HTe2M7jgB+QWHavZkDRPmZcASoZEmBx6i75bGjPcMdL4/VKGFAGWZkGzPG0XAbdL9A81G5LOmUnC9hHKJeO7dcUMjblSl12867ElFTtaGl20xvvLGPdVz/8TVuU7y0x1PG7vtNg24oz9Uo/Z412++VFWI7Fcog9tu9Lm6gvRmIPv9x1xmQAu6RDkXtbOtlGEmpgD5Nvnyc0dcv0EE6cfdi1HmhMf9wDF3k3gtRvEedhxjpgfqPb9PU9iEJHnyOUA7bQUXh6kq/D7l2iTjWv7XOD530BDr8jIrus+srXjt4MzumJMHuTsBa63YKE1+RR5lBjEikCCnWKWiHdzOgKO+nRIBAF88za/IFmJ3eMZov4CYxGBabcpGL8EYx+SeMXJeRwHNsV/h+vdxeuhEpN3ZyNY78Gm2fknJxVGhyjixPiQvVkNzT1elD9Py/aTAL64Hb9vcYmC9zfdXdT/C1LeGbg4rnBaAihDFJH12W5ulfNCNe/xTsP3bp8ikzJs5BF+5PNfAQYAPaseTdsEcaYAAAAASUVORK5CYII='
+			}
+		},
+		computed: {
+			iconSnowWidth() {
+				return (Math.floor(this.iconSize / 24) || 1) * 2
+			},
+			contentdownText() {
+				return this.contentText.contentdown || t("uni-load-more.contentdown")
+			},
+			contentrefreshText() {
+				return this.contentText.contentrefresh || t("uni-load-more.contentrefresh")
+			},
+			contentnomoreText() {
+				return this.contentText.contentnomore || t("uni-load-more.contentnomore")
+			}
+		},
+		mounted() {
+			// #ifdef APP-PLUS
+			var pages = getCurrentPages();
+			var page = pages[pages.length - 1];
+			var currentWebview = page.$getAppWebview();
+			currentWebview.addEventListener('hide', () => {
+				this.webviewHide = true
+			})
+			currentWebview.addEventListener('show', () => {
+				this.webviewHide = false
+			})
+			// #endif
+		},
+		methods: {
+			onClick() {
+				this.$emit('clickLoadMore', {
+					detail: {
+						status: this.status,
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	.uni-load-more {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		height: 40px;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.uni-load-more__text {
+		font-size: 14px;
+		margin-left: 8px;
+	}
+
+	.uni-load-more__img {
+		width: 24px;
+		height: 24px;
+		// margin-right: 8px;
+	}
+
+	.uni-load-more__img--nvue {
+		color: #666666;
+	}
+
+	.uni-load-more__img--android,
+	.uni-load-more__img--ios {
+		width: 24px;
+		height: 24px;
+		transform: rotate(0deg);
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-load-more__img--android {
+		animation: loading-ios 1s 0s linear infinite;
+	}
+
+	@keyframes loading-android {
+		0% {
+			transform: rotate(0deg);
+		}
+
+		100% {
+			transform: rotate(360deg);
+		}
+	}
+
+	.uni-load-more__img--ios-H5 {
+		position: relative;
+		animation: loading-ios-H5 1s 0s step-end infinite;
+	}
+
+	.uni-load-more__img--ios-H5 image {
+		position: absolute;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		top: 0;
+	}
+
+	@keyframes loading-ios-H5 {
+		0% {
+			transform: rotate(0deg);
+		}
+
+		8% {
+			transform: rotate(30deg);
+		}
+
+		16% {
+			transform: rotate(60deg);
+		}
+
+		24% {
+			transform: rotate(90deg);
+		}
+
+		32% {
+			transform: rotate(120deg);
+		}
+
+		40% {
+			transform: rotate(150deg);
+		}
+
+		48% {
+			transform: rotate(180deg);
+		}
+
+		56% {
+			transform: rotate(210deg);
+		}
+
+		64% {
+			transform: rotate(240deg);
+		}
+
+		73% {
+			transform: rotate(270deg);
+		}
+
+		82% {
+			transform: rotate(300deg);
+		}
+
+		91% {
+			transform: rotate(330deg);
+		}
+
+		100% {
+			transform: rotate(360deg);
+		}
+	}
+
+	/* #endif */
+
+	/* #ifdef H5 */
+	.uni-load-more__img--android-H5 {
+		animation: loading-android-H5-rotate 2s linear infinite;
+		transform-origin: center center;
+	}
+
+	.uni-load-more__img--android-H5 circle {
+		display: inline-block;
+		animation: loading-android-H5-dash 1.5s ease-in-out infinite;
+		stroke: currentColor;
+		stroke-linecap: round;
+	}
+
+	@keyframes loading-android-H5-rotate {
+		0% {
+			transform: rotate(0deg);
+		}
+
+		100% {
+			transform: rotate(360deg);
+		}
+	}
+
+	@keyframes loading-android-H5-dash {
+		0% {
+			stroke-dasharray: 1, 200;
+			stroke-dashoffset: 0;
+		}
+
+		50% {
+			stroke-dasharray: 90, 150;
+			stroke-dashoffset: -40;
+		}
+
+		100% {
+			stroke-dasharray: 90, 150;
+			stroke-dashoffset: -120;
+		}
+	}
+
+	/* #endif */
+
+	/* #ifndef APP-NVUE || H5 */
+	.uni-load-more__img--android-MP {
+		position: relative;
+		width: 24px;
+		height: 24px;
+		transform: rotate(0deg);
+		animation: loading-ios 1s 0s ease infinite;
+	}
+
+	.uni-load-more__img--android-MP .uni-load-more__img-icon {
+		position: absolute;
+		box-sizing: border-box;
+		width: 100%;
+		height: 100%;
+		border-radius: 50%;
+		border: solid 2px transparent;
+		border-top: solid 2px #777777;
+		transform-origin: center;
+	}
+
+	.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(1) {
+		animation: loading-android-MP-1 1s 0s linear infinite;
+	}
+
+	.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(2) {
+		animation: loading-android-MP-2 1s 0s linear infinite;
+	}
+
+	.uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(3) {
+		animation: loading-android-MP-3 1s 0s linear infinite;
+	}
+
+	@keyframes loading-android {
+		0% {
+			transform: rotate(0deg);
+		}
+
+		100% {
+			transform: rotate(360deg);
+		}
+	}
+
+	@keyframes loading-android-MP-1 {
+		0% {
+			transform: rotate(0deg);
+		}
+
+		50% {
+			transform: rotate(90deg);
+		}
+
+		100% {
+			transform: rotate(360deg);
+		}
+	}
+
+	@keyframes loading-android-MP-2 {
+		0% {
+			transform: rotate(0deg);
+		}
+
+		50% {
+			transform: rotate(180deg);
+		}
+
+		100% {
+			transform: rotate(360deg);
+		}
+	}
+
+	@keyframes loading-android-MP-3 {
+		0% {
+			transform: rotate(0deg);
+		}
+
+		50% {
+			transform: rotate(270deg);
+		}
+
+		100% {
+			transform: rotate(360deg);
+		}
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-load-more/package.json b/uni_modules/uni-load-more/package.json
new file mode 100644
index 0000000..cf44bff
--- /dev/null
+++ b/uni_modules/uni-load-more/package.json
@@ -0,0 +1,84 @@
+{
+  "id": "uni-load-more",
+  "displayName": "uni-load-more 加载更多",
+  "version": "1.3.6",
+  "description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "加载更多",
+    "load-more"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-load-more/readme.md b/uni_modules/uni-load-more/readme.md
new file mode 100644
index 0000000..54dc1fa
--- /dev/null
+++ b/uni_modules/uni-load-more/readme.md
@@ -0,0 +1,14 @@
+
+
+### LoadMore 加载更多
+> **组件名:uni-load-more**
+> 代码块: `uLoadMore`
+
+
+用于列表中,做滚动加载使用,展示 loading 的各种状态。
+
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-nav-bar/changelog.md b/uni_modules/uni-nav-bar/changelog.md
new file mode 100644
index 0000000..e3efe12
--- /dev/null
+++ b/uni_modules/uni-nav-bar/changelog.md
@@ -0,0 +1,57 @@
+## 1.3.14(2024-10-15)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.13(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.12(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.3.11(2023-03-29)
+- 修复 自定义状态栏高度闪动BUG
+## 1.3.10(2023-03-29)
+- 修复 暗黑模式下边线颜色错误的bug
+## 1.3.9(2022-10-13)
+- 修复 条件编译错误的bug
+## 1.3.8(2022-10-12)
+- 修复 nvue 环境 fixed 为 true 的情况下,无法置顶的 bug
+## 1.3.7(2022-08-11)
+- 修复 nvue 环境下 fixed 为 true 的情况下,无法置顶的 bug
+## 1.3.6(2022-06-30)
+- 修复 组件示例中插槽用法无法显示内容的bug
+## 1.3.5(2022-05-24)
+- 新增 stat 属性 ,可开启统计title 上报 ,仅使用了title 属性且项目开启了uni统计生效
+## 1.3.4(2022-01-24)
+- 更新 组件示例
+## 1.3.3(2022-01-24)
+- 新增 left-width/right-width属性 ,可修改左右两侧的宽度
+## 1.3.2(2022-01-18)
+- 修复 在vue下,标题不垂直居中的bug
+## 1.3.1(2022-01-18)
+- 修复 height 属性类型错误
+## 1.3.0(2022-01-18)
+- 新增 height 属性,可修改组件高度
+- 新增 dark 属性可可开启暗黑模式
+- 优化 标题字数过多显示省略号
+- 优化 插槽,插入内容可完全覆盖
+## 1.2.1(2022-01-10)
+- 修复 color 属性不生效的bug
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-nav-bar](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.11(2021-05-12)
+- 新增 组件示例地址
+## 1.0.10(2021-04-30)
+- 修复 在nvue下fixed为true,宽度不能撑满的Bug
+## 1.0.9(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.8(2021-04-14)
+- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
+
+## 1.0.7(2021-02-25)
+- 修复 easycom 下,找不到 uni-status-bar 的bug
+
+## 1.0.6(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
new file mode 100644
index 0000000..46806c1
--- /dev/null
+++ b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
@@ -0,0 +1,357 @@
+<template>
+	<view class="uni-navbar" :class="{'uni-dark':dark, 'uni-nvue-fixed': fixed}">
+		<view class="uni-navbar__content" :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }"
+			:style="{ 'background-color': themeBgColor, 'border-bottom-color':themeColor }" >
+			<status-bar v-if="statusBar" />
+			<view :style="{ color: themeColor,backgroundColor: themeBgColor ,height:navbarHeight}"
+				class="uni-navbar__header">
+				<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left"
+					:style="{width:leftIconWidth}">
+					<slot name="left">
+						<view class="uni-navbar__content_view" v-if="leftIcon.length > 0">
+							<uni-icons :color="themeColor" :type="leftIcon" size="20" />
+						</view>
+						<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text"
+							v-if="leftText.length">
+							<text :style="{ color: themeColor, fontSize: '12px' }">{{ leftText }}</text>
+						</view>
+					</slot>
+				</view>
+				<view class="uni-navbar__header-container " @tap="onClickTitle">
+					<slot>
+						<view class="uni-navbar__header-container-inner" v-if="title.length>0">
+							<text class="uni-nav-bar-text uni-ellipsis-1"
+								:style="{color: themeColor }">{{ title }}</text>
+						</view>
+					</slot>
+				</view>
+				<view @click="onClickRight" class="uni-navbar__header-btns uni-navbar__header-btns-right"
+					:style="{width:rightIconWidth}">
+					<slot name="right">
+						<view v-if="rightIcon.length">
+							<uni-icons :color="themeColor" :type="rightIcon" size="22" />
+						</view>
+						<view class="uni-navbar-btn-text" v-if="rightText.length && !rightIcon.length">
+							<text class="uni-nav-bar-right-text" :style="{ color: themeColor}">{{ rightText }}</text>
+						</view>
+					</slot>
+				</view>
+			</view>
+		</view>
+		<!-- #ifndef APP-NVUE -->
+		<view class="uni-navbar__placeholder" v-if="fixed">
+			<status-bar v-if="statusBar" />
+			<view class="uni-navbar__placeholder-view" :style="{ height:navbarHeight}" />
+		</view>
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	import statusBar from "./uni-status-bar.vue";
+	const getVal = (val) => typeof val === 'number' ? val + 'px' : val;
+
+	/**
+	 * 
+	 * 
+	 * NavBar 自定义导航栏
+	 * @description 导航栏组件,主要用于头部导航
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=52
+	 * @property {Boolean} dark 开启黑暗模式
+	 * @property {String} title 标题文字
+	 * @property {String} leftText 左侧按钮文本
+	 * @property {String} rightText 右侧按钮文本
+	 * @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+	 * @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+	 * @property {String} color 图标和文字颜色
+	 * @property {String} backgroundColor 导航栏背景颜色
+	 * @property {Boolean} fixed = [true|false] 是否固定顶部
+	 * @property {Boolean} statusBar = [true|false] 是否包含状态栏
+	 * @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
+	 * @property {Boolean} stat 是否开启统计标题上报
+	 * @event {Function} clickLeft 左侧按钮点击时触发
+	 * @event {Function} clickRight 右侧按钮点击时触发
+	 * @event {Function} clickTitle 中间标题点击时触发
+	 */
+	export default {
+		name: "UniNavBar",
+		components: {
+			statusBar
+		},
+		emits: ['clickLeft', 'clickRight', 'clickTitle'],
+		props: {
+			dark: {
+				type: Boolean,
+				default: false
+			},
+			title: {
+				type: String,
+				default: ""
+			},
+			leftText: {
+				type: String,
+				default: ""
+			},
+			rightText: {
+				type: String,
+				default: ""
+			},
+			leftIcon: {
+				type: String,
+				default: ""
+			},
+			rightIcon: {
+				type: String,
+				default: ""
+			},
+			fixed: {
+				type: [Boolean, String],
+				default: false
+			},
+			color: {
+				type: String,
+				default: ""
+			},
+			backgroundColor: {
+				type: String,
+				default: ""
+			},
+			statusBar: {
+				type: [Boolean, String],
+				default: false
+			},
+			shadow: {
+				type: [Boolean, String],
+				default: false
+			},
+			border: {
+				type: [Boolean, String],
+				default: true
+			},
+			height: {
+				type: [Number, String],
+				default: 44
+			},
+			leftWidth: {
+				type: [Number, String],
+				default: 60
+			},
+			rightWidth: {
+				type: [Number, String],
+				default: 60
+			},
+			stat: {
+				type: [Boolean, String],
+				default: ''
+			}
+		},
+		computed: {
+			themeBgColor() {
+				if (this.dark) {
+					// 默认值
+					if (this.backgroundColor) {
+						return this.backgroundColor
+					} else {
+						return this.dark ? '#333' : '#FFF'
+					}
+				}
+				return this.backgroundColor || '#FFF'
+			},
+			themeColor() {
+				if (this.dark) {
+					// 默认值
+					if (this.color) {
+						return this.color
+					} else {
+						return this.dark ? '#fff' : '#333'
+					}
+				}
+				return this.color || '#333'
+			},
+			navbarHeight() {
+				return getVal(this.height)
+			},
+			leftIconWidth() {
+				return getVal(this.leftWidth)
+			},
+			rightIconWidth() {
+				return getVal(this.rightWidth)
+			}
+		},
+		mounted() {
+			if (uni.report && this.stat && this.title !== '') {
+				uni.report('title', this.title)
+			}
+		},
+		methods: {
+			onClickLeft() {
+				this.$emit("clickLeft");
+			},
+			onClickRight() {
+				this.$emit("clickRight");
+			},
+			onClickTitle() {
+				this.$emit("clickTitle");
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$nav-height: 44px;
+
+	.uni-nvue-fixed {
+		/* #ifdef APP-NVUE */
+		position: sticky;
+		/* #endif */
+	}
+	.uni-navbar {
+		// box-sizing: border-box;
+	}
+
+	.uni-nav-bar-text {
+		/* #ifdef APP-PLUS */
+		font-size: 34rpx;
+		/* #endif */
+		/* #ifndef APP-PLUS */
+		font-size: 14px;
+		/* #endif */
+	}
+
+	.uni-nav-bar-right-text {
+		font-size: 12px;
+	}
+
+	.uni-navbar__content {
+		position: relative;
+		// background-color: #fff;
+		// box-sizing: border-box;
+		background-color: transparent;
+	}
+
+	.uni-navbar__content_view {
+		// box-sizing: border-box;
+	}
+
+	.uni-navbar-btn-text {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: flex-start;
+		align-items: center;
+		line-height: 12px;
+	}
+
+	.uni-navbar__header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		padding: 0 10px;
+		flex-direction: row;
+		height: $nav-height;
+		font-size: 12px;
+	}
+
+	.uni-navbar__header-btns {
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		display: flex;
+		/* #endif */
+		flex-wrap: nowrap;
+		flex-direction: row;
+		width: 120rpx;
+		// padding: 0 6px;
+		justify-content: center;
+		align-items: center;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-navbar__header-btns-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 120rpx;
+		justify-content: flex-start;
+		align-items: center;
+	}
+
+	.uni-navbar__header-btns-right {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		// width: 150rpx;
+		// padding-right: 30rpx;
+		justify-content: flex-end;
+		align-items: center;
+	}
+
+	.uni-navbar__header-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		padding: 0 10px;
+		overflow: hidden;
+	}
+
+	.uni-navbar__header-container-inner {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		font-size: 12px;
+		overflow: hidden;
+		// box-sizing: border-box;
+	}
+
+
+	.uni-navbar__placeholder-view {
+		height: $nav-height;
+	}
+
+	.uni-navbar--fixed {
+		position: fixed;
+		z-index: 99;
+		/* #ifdef H5 */
+		left: var(--window-left);
+		right: var(--window-right);
+		/* #endif */
+		/* #ifndef H5 */
+		left: 0;
+		right: 0;
+		/* #endif */
+
+	}
+
+	.uni-navbar--shadow {
+		box-shadow: 0 1px 6px #ccc;
+	}
+
+	.uni-navbar--border {
+		border-bottom-width: 1rpx;
+		border-bottom-style: solid;
+		border-bottom-color: #eee;
+	}
+
+	.uni-ellipsis-1 {
+		overflow: hidden;
+		/* #ifndef APP-NVUE */
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		text-overflow: ellipsis;
+		/* #endif */
+	}
+
+	// 暗主题配置
+	.uni-dark {}
+</style>
diff --git a/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
new file mode 100644
index 0000000..6185446
--- /dev/null
+++ b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
@@ -0,0 +1,30 @@
+<template>
+	<view :style="{ height: statusBarHeight }" class="uni-status-bar">
+		<slot />
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'UniStatusBar',
+		data() {
+			return {
+				// #ifdef MP-WEIXIN
+				statusBarHeight: uni.getWindowInfo().statusBarHeight + 'px',
+				// #endif
+				// #ifndef MP-WEIXIN
+				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+				// #endif
+
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	.uni-status-bar {
+		// width: 750rpx;
+		height: 20px;
+		// height: var(--status-bar-height);
+	}
+</style>
diff --git a/uni_modules/uni-nav-bar/package.json b/uni_modules/uni-nav-bar/package.json
new file mode 100644
index 0000000..d9f53b2
--- /dev/null
+++ b/uni_modules/uni-nav-bar/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-nav-bar",
+  "displayName": "uni-nav-bar 自定义导航栏",
+  "version": "1.3.14",
+  "description": "自定义导航栏组件,主要用于头部导航。",
+  "keywords": [
+    "uni-ui",
+    "导航",
+    "导航栏",
+    "自定义导航栏"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-nav-bar/readme.md b/uni_modules/uni-nav-bar/readme.md
new file mode 100644
index 0000000..3934b32
--- /dev/null
+++ b/uni_modules/uni-nav-bar/readme.md
@@ -0,0 +1,15 @@
+
+
+## NavBar 导航栏
+> **组件名:uni-nav-bar**
+> 代码块: `uNavBar`
+
+导航栏组件,主要用于头部导航。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
+
+
+
diff --git a/uni_modules/uni-notice-bar/changelog.md b/uni_modules/uni-notice-bar/changelog.md
new file mode 100644
index 0000000..ce50674
--- /dev/null
+++ b/uni_modules/uni-notice-bar/changelog.md
@@ -0,0 +1,20 @@
+## 1.2.2(2023-12-20)
+- 修复动态绑定title时,滚动速度不一致的问题
+## 1.2.1(2022-09-05)
+- 新增 属性 fontSize,可修改文字大小。
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-notice-bar](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
+## 1.1.1(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.9(2021-05-12)
+- 新增 组件示例地址
+## 1.0.8(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.7(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.6(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue b/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue
new file mode 100644
index 0000000..47fb9b3
--- /dev/null
+++ b/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue
@@ -0,0 +1,431 @@
+<template>
+	<view v-if="show" class="uni-noticebar" :style="{ backgroundColor }" @click="onClick">
+		<uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound"
+			:color="color" :size="fontSize * 1.5" />
+		<view ref="textBox" class="uni-noticebar__content-wrapper"
+			:class="{
+				'uni-noticebar__content-wrapper--scrollable': scrollable,
+				'uni-noticebar__content-wrapper--single': !scrollable && (single || moreText)
+			}"
+			:style="{ height: scrollable ? fontSize * 1.5 + 'px' : 'auto' }"
+		>
+			<view :id="elIdBox" class="uni-noticebar__content"
+				:class="{
+					'uni-noticebar__content--scrollable': scrollable,
+					'uni-noticebar__content--single': !scrollable && (single || moreText)
+				}"
+			>
+				<text :id="elId" ref="animationEle" class="uni-noticebar__content-text" 
+					:class="{
+						'uni-noticebar__content-text--scrollable': scrollable,
+						'uni-noticebar__content-text--single': !scrollable && (single || showGetMore)
+					}" 
+					:style="{
+						color: color,
+						fontSize: fontSize + 'px',
+						lineHeight: fontSize * 1.5 + 'px',
+						width: wrapWidth + 'px',
+						'animationDuration': animationDuration,
+						'-webkit-animationDuration': animationDuration,
+						animationPlayState: webviewHide ? 'paused' : animationPlayState,
+						'-webkit-animationPlayState': webviewHide ? 'paused' : animationPlayState,
+						animationDelay: animationDelay,
+						'-webkit-animationDelay': animationDelay
+					}"
+				>{{text}}</text>
+			</view>
+		</view>
+		<view v-if="isShowGetMore" class="uni-noticebar__more uni-cursor-point"
+			@click="clickMore">
+			<text v-if="moreText.length > 0" :style="{ color: moreColor, fontSize: fontSize + 'px' }">{{ moreText }}</text>
+			<uni-icons v-else type="right" :color="moreColor" :size="fontSize * 1.1" />
+		</view>
+		<view class="uni-noticebar-close uni-cursor-point" v-if="isShowClose">
+			<uni-icons type="closeempty" :color="color" :size="fontSize * 1.1" @click="close" />
+		</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const dom = weex.requireModule('dom');
+	const animation = weex.requireModule('animation');
+	// #endif
+
+	/**
+	 * NoticeBar 自定义导航栏
+	 * @description 通告栏组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=30
+	 * @property {Number} speed 文字滚动的速度,默认100px/秒
+	 * @property {String} text 显示文字
+	 * @property {String} backgroundColor 背景颜色
+	 * @property {String} color 文字颜色
+	 * @property {String} moreColor 查看更多文字的颜色
+	 * @property {String} moreText 设置“查看更多”的文本
+	 * @property {Boolean} single = [true|false] 是否单行
+	 * @property {Boolean} scrollable = [true|false] 是否滚动,为true时,NoticeBar为单行
+	 * @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
+	 * @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
+	 * @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标,为true时,NoticeBar为单行
+	 * @event {Function} click 点击 NoticeBar 触发事件
+	 * @event {Function} close 关闭 NoticeBar 触发事件
+	 * @event {Function} getmore 点击”查看更多“时触发事件
+	 */
+
+	export default {
+		name: 'UniNoticeBar',
+		emits: ['click', 'getmore', 'close'],
+		props: {
+			text: {
+				type: String,
+				default: ''
+			},
+			moreText: {
+				type: String,
+				default: ''
+			},
+			backgroundColor: {
+				type: String,
+				default: '#FFF9EA'
+			},
+			speed: {
+				// 默认1s滚动100px
+				type: Number,
+				default: 100
+			},
+			color: {
+				type: String,
+				default: '#FF9A43'
+			},
+			fontSize: {
+				type: Number,
+				default: 14
+			},
+			moreColor: {
+				type: String,
+				default: '#FF9A43'
+			},
+			single: {
+				// 是否单行
+				type: [Boolean, String],
+				default: false
+			},
+			scrollable: {
+				// 是否滚动,添加后控制单行效果取消
+				type: [Boolean, String],
+				default: false
+			},
+			showIcon: {
+				// 是否显示左侧icon
+				type: [Boolean, String],
+				default: false
+			},
+			showGetMore: {
+				// 是否显示右侧查看更多
+				type: [Boolean, String],
+				default: false
+			},
+			showClose: {
+				// 是否显示左侧关闭按钮
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		data() {
+			const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			return {
+				textWidth: 0,
+				boxWidth: 0,
+				wrapWidth: '',
+				webviewHide: false,
+				// #ifdef APP-NVUE
+				stopAnimation: false,
+				// #endif
+				elId: elId,
+				elIdBox: elIdBox,
+				show: true,
+				animationDuration: 'none',
+				animationPlayState: 'paused',
+				animationDelay: '0s'
+			}
+		},
+		watch:{
+			text:function(newValue,oldValue){
+				this.initSize();
+			}
+		},
+		computed: {
+			isShowGetMore() {
+				return this.showGetMore === true || this.showGetMore === 'true'
+			},
+			isShowClose() {
+				return (this.showClose === true || this.showClose === 'true') 
+					&& (this.showGetMore === false || this.showGetMore === 'false')
+			}
+		},
+		mounted() {
+			// #ifdef APP-PLUS
+			var pages = getCurrentPages();
+			var page = pages[pages.length - 1];
+			var currentWebview = page.$getAppWebview();
+			currentWebview.addEventListener('hide', () => {
+				this.webviewHide = true
+			})
+			currentWebview.addEventListener('show', () => {
+				this.webviewHide = false
+			})
+			// #endif
+			this.$nextTick(() => {
+				this.initSize()
+			})
+		},
+		// #ifdef APP-NVUE
+		beforeDestroy() {
+			this.stopAnimation = true
+		},
+		// #endif
+		methods: {
+			initSize() {
+				if (this.scrollable) {
+					// #ifndef APP-NVUE
+					let query = [],
+						boxWidth = 0,
+						textWidth = 0;
+					let textQuery = new Promise((resolve, reject) => {
+						uni.createSelectorQuery()
+							// #ifndef MP-ALIPAY
+							.in(this)
+							// #endif
+							.select(`#${this.elId}`)
+							.boundingClientRect()
+							.exec(ret => {
+								this.textWidth = ret[0].width
+								resolve()
+							})
+					})
+					let boxQuery = new Promise((resolve, reject) => {
+						uni.createSelectorQuery()
+							// #ifndef MP-ALIPAY
+							.in(this)
+							// #endif
+							.select(`#${this.elIdBox}`)
+							.boundingClientRect()
+							.exec(ret => {
+								this.boxWidth = ret[0].width
+								resolve()
+							})
+					})
+					query.push(textQuery)
+					query.push(boxQuery)
+					Promise.all(query).then(() => {
+						this.animationDuration = `${this.textWidth / this.speed}s`
+						this.animationDelay = `-${this.boxWidth / this.speed}s`
+						setTimeout(() => {
+							this.animationPlayState = 'running'
+						}, 1000)
+					})
+					// #endif
+					// #ifdef APP-NVUE
+					dom.getComponentRect(this.$refs['animationEle'], (res) => {
+						let winWidth = uni.getSystemInfoSync().windowWidth
+						this.textWidth = res.size.width
+						animation.transition(this.$refs['animationEle'], {
+							styles: {
+								transform: `translateX(-${winWidth}px)`
+							},
+							duration: 0,
+							timingFunction: 'linear',
+							delay: 0
+						}, () => {
+							if (!this.stopAnimation) {
+								animation.transition(this.$refs['animationEle'], {
+									styles: {
+										transform: `translateX(-${this.textWidth}px)`
+									},
+									timingFunction: 'linear',
+									duration: (this.textWidth - winWidth) / this.speed * 1000,
+									delay: 1000
+								}, () => {
+									if (!this.stopAnimation) {
+										this.loopAnimation()
+									}
+								});
+							}
+						});
+					})
+					// #endif
+				}
+				// #ifdef APP-NVUE
+				if (!this.scrollable && (this.single || this.moreText)) {
+					dom.getComponentRect(this.$refs['textBox'], (res) => {
+						this.wrapWidth = res.size.width
+					})
+				}
+				// #endif
+			},
+			loopAnimation() {
+				// #ifdef APP-NVUE
+				animation.transition(this.$refs['animationEle'], {
+					styles: {
+						transform: `translateX(0px)`
+					},
+					duration: 0
+				}, () => {
+					if (!this.stopAnimation) {
+						animation.transition(this.$refs['animationEle'], {
+							styles: {
+								transform: `translateX(-${this.textWidth}px)`
+							},
+							duration: this.textWidth / this.speed * 1000,
+							timingFunction: 'linear',
+							delay: 0
+						}, () => {
+							if (!this.stopAnimation) {
+								this.loopAnimation()
+							}
+						});
+					}
+				});
+				// #endif
+			},
+			clickMore() {
+				this.$emit('getmore')
+			},
+			close() {
+				this.show = false;
+				this.$emit('close')
+			},
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-noticebar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		width: 100%;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		padding: 10px 12px;
+		margin-bottom: 10px;
+	}
+
+	.uni-cursor-point {
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-noticebar-close {
+		margin-left: 8px;
+		margin-right: 5px;
+	}
+
+	.uni-noticebar-icon {
+		margin-right: 5px;
+	}
+
+	.uni-noticebar__content-wrapper {
+		flex: 1;
+		flex-direction: column;
+		overflow: hidden;
+	}
+
+	.uni-noticebar__content-wrapper--single {
+		/* #ifndef APP-NVUE */
+		line-height: 18px;
+		/* #endif */
+	}
+
+	.uni-noticebar__content-wrapper--single,
+	.uni-noticebar__content-wrapper--scrollable {
+		flex-direction: row;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-noticebar__content-wrapper--scrollable {
+		position: relative;
+	}
+
+	/* #endif */
+
+	.uni-noticebar__content--scrollable {
+		/* #ifdef APP-NVUE */
+		flex: 0;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		flex: 1;
+		display: block;
+		overflow: hidden;
+		/* #endif */
+	}
+
+	.uni-noticebar__content--single {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex: none;
+		width: 100%;
+		justify-content: center;
+		/* #endif */
+	}
+
+	.uni-noticebar__content-text {
+		font-size: 14px;
+		line-height: 18px;
+		/* #ifndef APP-NVUE */
+		word-break: break-all;
+		/* #endif */
+	}
+
+	.uni-noticebar__content-text--single {
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: block;
+		width: 100%;
+		white-space: nowrap;
+		/* #endif */
+		overflow: hidden;
+		text-overflow: ellipsis;
+	}
+
+	.uni-noticebar__content-text--scrollable {
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		padding-left: 750rpx;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		position: absolute;
+		display: block;
+		height: 18px;
+		line-height: 18px;
+		white-space: nowrap;
+		padding-left: 100%;
+		animation: notice 10s 0s linear infinite both;
+		animation-play-state: paused;
+		/* #endif */
+	}
+
+	.uni-noticebar__more {
+		/* #ifndef APP-NVUE */
+		display: inline-flex;
+		/* #endif */
+		flex-direction: row;
+		flex-wrap: nowrap;
+		align-items: center;
+		padding-left: 5px;
+	}
+
+	@keyframes notice {
+		100% {
+			transform: translate3d(-100%, 0, 0);
+		}
+	}
+</style>
diff --git a/uni_modules/uni-notice-bar/package.json b/uni_modules/uni-notice-bar/package.json
new file mode 100644
index 0000000..1e9762c
--- /dev/null
+++ b/uni_modules/uni-notice-bar/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-notice-bar",
+  "displayName": "uni-notice-bar 通告栏",
+  "version": "1.2.2",
+  "description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "通告栏",
+    "公告",
+    "跑马灯"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-notice-bar/readme.md b/uni_modules/uni-notice-bar/readme.md
new file mode 100644
index 0000000..fb2ede2
--- /dev/null
+++ b/uni_modules/uni-notice-bar/readme.md
@@ -0,0 +1,13 @@
+
+
+## NoticeBar 通告栏
+> **组件名:uni-notice-bar**
+> 代码块: `uNoticeBar`
+
+
+通告栏组件 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-number-box/changelog.md b/uni_modules/uni-number-box/changelog.md
new file mode 100644
index 0000000..adf9221
--- /dev/null
+++ b/uni_modules/uni-number-box/changelog.md
@@ -0,0 +1,39 @@
+## 1.2.8(2024-04-26)
+- 修复 在vue2下H5黑边的bug
+## 1.2.7(2024-04-26)
+- 修复 在vue2手动输入后失焦导致清空数值的严重bug
+## 1.2.6(2024-02-22)
+- 新增 设置宽度属性width(单位:px)
+## 1.2.5(2024-02-21)
+- 修复 step步长小于1时,键盘类型为number的bug
+## 1.2.4(2024-02-02)
+- 修复 加减号垂直位置偏移样式问题
+## 1.2.3(2023-05-23)
+- 更新示例工程
+## 1.2.2(2023-05-08)
+- 修复 change 事件执行顺序错误的问题
+## 1.2.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+## 1.1.2(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.1.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-04-20)
+- 修复 uni-number-box 浮点数运算不精确的 bug
+- 修复 uni-number-box change 事件触发不正确的 bug
+- 新增 uni-number-box v-model 双向绑定
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
+
+## 1.0.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 v-model
+- 新增 支持 focus、blur 事件
+- 新增 支持 PC 端
diff --git a/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue b/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue
new file mode 100644
index 0000000..4e203cc
--- /dev/null
+++ b/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue
@@ -0,0 +1,232 @@
+<template>
+	<view class="uni-numbox">
+		<view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }"
+				:style="{color}">-</text>
+		</view>
+		<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value"
+			:type="step<1?'digit':'number'" v-model="inputValue" :style="{background, color, width:widthWithPx}" />
+		<view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }"
+				:style="{color}">+</text>
+		</view>
+	</view>
+</template>
+<script>
+	/**
+	 * NumberBox 数字输入框
+	 * @description 带加减按钮的数字输入框
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=31
+	 * @property {Number} value 输入框当前值
+	 * @property {Number} min 最小值
+	 * @property {Number} max 最大值
+	 * @property {Number} step 每次点击改变的间隔大小
+	 * @property {String} background 背景色
+	 * @property {String} color 字体颜色(前景色)
+	 * @property {Number} width 输入框宽度(单位:px)
+	 * @property {Boolean} disabled = [true|false] 是否为禁用状态
+	 * @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value
+	 * @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象
+	 * @event {Function} blur 输入框失焦时触发的事件,参数为 event 对象
+	 */
+
+	export default {
+		name: "UniNumberBox",
+		emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'],
+		props: {
+			value: {
+				type: [Number, String],
+				default: 1
+			},
+			modelValue: {
+				type: [Number, String],
+				default: 1
+			},
+			min: {
+				type: Number,
+				default: 0
+			},
+			max: {
+				type: Number,
+				default: 100
+			},
+			step: {
+				type: Number,
+				default: 1
+			},
+			background: {
+				type: String,
+				default: '#f5f5f5'
+			},
+			color: {
+				type: String,
+				default: '#333'
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			width: {
+				type: Number,
+				default: 40,
+			}
+		},
+		data() {
+			return {
+				inputValue: 0
+			};
+		},
+		watch: {
+			value(val) {
+				this.inputValue = +val;
+			},
+			modelValue(val) {
+				this.inputValue = +val;
+			}
+		},
+		computed: {
+			widthWithPx() {
+				return this.width + 'px';
+			}
+		},
+		created() {
+			if (this.value === 1) {
+				this.inputValue = +this.modelValue;
+			}
+			if (this.modelValue === 1) {
+				this.inputValue = +this.value;
+			}
+		},
+		methods: {
+			_calcValue(type) {
+				if (this.disabled) {
+					return;
+				}
+				const scale = this._getDecimalScale();
+				let value = this.inputValue * scale;
+				let step = this.step * scale;
+				if (type === "minus") {
+					value -= step;
+					if (value < (this.min * scale)) {
+						return;
+					}
+					if (value > (this.max * scale)) {
+						value = this.max * scale
+					}
+				}
+
+				if (type === "plus") {
+					value += step;
+					if (value > (this.max * scale)) {
+						return;
+					}
+					if (value < (this.min * scale)) {
+						value = this.min * scale
+					}
+				}
+
+				this.inputValue = (value / scale).toFixed(String(scale).length - 1);
+				// TODO vue2 兼容
+				this.$emit("input", +this.inputValue);
+				// TODO vue3 兼容
+				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
+			},
+			_getDecimalScale() {
+
+				let scale = 1;
+				// 浮点型
+				if (~~this.step !== this.step) {
+					scale = Math.pow(10, String(this.step).split(".")[1].length);
+				}
+				return scale;
+			},
+			_onBlur(event) {
+				this.$emit('blur', event)
+				let value = event.detail.value;
+				if (isNaN(value)) {
+					this.inputValue = this.value;
+					return;
+				}
+				value = +value;
+				if (value > this.max) {
+					value = this.max;
+				} else if (value < this.min) {
+					value = this.min;
+				}
+				const scale = this._getDecimalScale();
+				this.inputValue = value.toFixed(String(scale).length - 1);
+				this.$emit("input", +this.inputValue);
+				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
+			},
+			_onFocus(event) {
+				this.$emit('focus', event)
+			}
+		}
+	};
+</script>
+<style lang="scss">
+	$box-height: 26px;
+	$bg: #f5f5f5;
+	$br: 2px;
+	$color: #333;
+
+	.uni-numbox {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-numbox-btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		padding: 0 8px;
+		background-color: $bg;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-numbox__value {
+		margin: 0 2px;
+		background-color: $bg;
+		width: 40px;
+		height: $box-height;
+		text-align: center;
+		font-size: 14px;
+		border-width: 0;
+		color: $color;
+	}
+
+	.uni-numbox__minus {
+		border-top-left-radius: $br;
+		border-bottom-left-radius: $br;
+	}
+
+	.uni-numbox__plus {
+		border-top-right-radius: $br;
+		border-bottom-right-radius: $br;
+	}
+
+	.uni-numbox--text {
+		// fix nvue
+		line-height: 20px;
+		margin-bottom: 2px;
+		font-size: 20px;
+		font-weight: 300;
+		color: $color;
+	}
+
+	.uni-numbox .uni-numbox--disabled {
+		color: #c0c0c0 !important;
+		/* #ifdef H5 */
+		cursor: not-allowed;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-number-box/package.json b/uni_modules/uni-number-box/package.json
new file mode 100644
index 0000000..4ac9047
--- /dev/null
+++ b/uni_modules/uni-number-box/package.json
@@ -0,0 +1,83 @@
+{
+  "id": "uni-number-box",
+  "displayName": "uni-number-box 数字输入框",
+  "version": "1.2.8",
+  "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "数字输入框"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-number-box/readme.md b/uni_modules/uni-number-box/readme.md
new file mode 100644
index 0000000..affc56f
--- /dev/null
+++ b/uni_modules/uni-number-box/readme.md
@@ -0,0 +1,13 @@
+
+
+## NumberBox 数字输入框
+> **组件名:uni-number-box**
+> 代码块: `uNumberBox`
+
+
+带加减按钮的数字输入框。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-pagination/changelog.md b/uni_modules/uni-pagination/changelog.md
new file mode 100644
index 0000000..2e94adc
--- /dev/null
+++ b/uni_modules/uni-pagination/changelog.md
@@ -0,0 +1,27 @@
+## 1.2.4(2022-09-19)
+- 修复,未对主题色设置默认色,导致未引入 uni-scss 变量文件报错。
+- 修复,未对移动端当前页文字做主题色适配。
+## 1.2.3(2022-09-15)
+- 修复未使用 uni-scss 主题色的 bug。
+## 1.2.2(2022-07-06)
+- 修复 es 语言 i18n 错误
+## 1.2.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-pagination](https://uniapp.dcloud.io/component/uniui/uni-pagination)
+## 1.1.2(2021-10-08)
+- 修复 current 、value 属性未监听,导致高亮样式失效的 bug
+## 1.1.1(2021-08-20)
+- 新增 支持国际化
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-04-12)
+- 新增 PC 和 移动端适配不同的 ui 
+## 1.0.5(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json b/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json
new file mode 100644
index 0000000..d6e2897
--- /dev/null
+++ b/uni_modules/uni-pagination/components/uni-pagination/i18n/en.json
@@ -0,0 +1,5 @@
+{
+	"uni-pagination.prevText": "prev",
+	"uni-pagination.nextText": "next",
+	"uni-pagination.piecePerPage": "piece/page"
+}
diff --git a/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json b/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json
new file mode 100644
index 0000000..604a113
--- /dev/null
+++ b/uni_modules/uni-pagination/components/uni-pagination/i18n/es.json
@@ -0,0 +1,5 @@
+{
+	"uni-pagination.prevText": "anterior",
+	"uni-pagination.nextText": "prxima",
+	"uni-pagination.piecePerPage": "Art��culo/P��gina"
+}
diff --git a/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json b/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json
new file mode 100644
index 0000000..a7a0c77
--- /dev/null
+++ b/uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json
@@ -0,0 +1,5 @@
+{
+	"uni-pagination.prevText": "précédente",
+	"uni-pagination.nextText": "suivante",
+	"uni-pagination.piecePerPage": "Articles/Pages"
+}
diff --git a/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js b/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js
new file mode 100644
index 0000000..2469dd0
--- /dev/null
+++ b/uni_modules/uni-pagination/components/uni-pagination/i18n/index.js
@@ -0,0 +1,12 @@
+import en from './en.json'
+import es from './es.json'
+import fr from './fr.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	es,
+	fr,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json b/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json
new file mode 100644
index 0000000..782bbe4
--- /dev/null
+++ b/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json
@@ -0,0 +1,5 @@
+{
+	"uni-pagination.prevText": "上一页",
+	"uni-pagination.nextText": "下一页",
+	"uni-pagination.piecePerPage": "条/页"
+}
diff --git a/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json b/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json
new file mode 100644
index 0000000..180fddb
--- /dev/null
+++ b/uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json
@@ -0,0 +1,5 @@
+{
+	"uni-pagination.prevText": "上一頁",
+	"uni-pagination.nextText": "下一頁",
+	"uni-pagination.piecePerPage": "條/頁"
+}
diff --git a/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue b/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue
new file mode 100644
index 0000000..5305b5f
--- /dev/null
+++ b/uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue
@@ -0,0 +1,465 @@
+<template>
+	<view class="uni-pagination">
+		<!-- #ifndef MP -->
+		<picker v-if="showPageSize === true || showPageSize === 'true'" class="select-picker" mode="selector"
+			:value="pageSizeIndex" :range="pageSizeRange" @change="pickerChange" @cancel="pickerClick"
+			@click.native="pickerClick">
+			<button type="default" size="mini" :plain="true">
+				<text>{{pageSizeRange[pageSizeIndex]}} {{piecePerPage}}</text>
+				<uni-icons class="select-picker-icon" type="arrowdown" size="12" color="#999"></uni-icons>
+			</button>
+		</picker>
+		<!-- #endif -->
+		<!-- #ifndef APP-NVUE -->
+		<view class="uni-pagination__total is-phone-hide">共 {{ total }} 条</view>
+		<!-- #endif -->
+		<view class="uni-pagination__btn"
+			:class="currentIndex === 1 ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
+			:hover-class="currentIndex === 1 ? '' : 'uni-pagination--hover'" :hover-start-time="20"
+			:hover-stay-time="70" @click="clickLeft">
+			<template v-if="showIcon === true || showIcon === 'true'">
+				<uni-icons color="#666" size="16" type="left" />
+			</template>
+			<template v-else>
+				<text class="uni-pagination__child-btn">{{ prevPageText }}</text>
+			</template>
+		</view>
+		<view class="uni-pagination__num uni-pagination__num-flex-none">
+			<view class="uni-pagination__num-current">
+				<text class="uni-pagination__num-current-text is-pc-hide current-index-text">{{ currentIndex }}</text>
+				<text class="uni-pagination__num-current-text is-pc-hide">/{{ maxPage || 0 }}</text>
+				<!-- #ifndef APP-NVUE -->
+				<view v-for="(item, index) in paper" :key="index" :class="{ 'page--active': item === currentIndex }"
+					class="uni-pagination__num-tag tag--active is-phone-hide" @click.top="selectPage(item, index)">
+					<text>{{ item }}</text>
+				</view>
+				<!-- #endif -->
+
+			</view>
+		</view>
+		<view class="uni-pagination__btn"
+			:class="currentIndex >= maxPage ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
+			:hover-class="currentIndex === maxPage ? '' : 'uni-pagination--hover'" :hover-start-time="20"
+			:hover-stay-time="70" @click="clickRight">
+			<template v-if="showIcon === true || showIcon === 'true'">
+				<uni-icons color="#666" size="16" type="right" />
+			</template>
+			<template v-else>
+				<text class="uni-pagination__child-btn">{{ nextPageText }}</text>
+			</template>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Pagination 分页器
+	 * @description 分页器组件,用于展示页码、请求数据等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=32
+	 * @property {String} prevText 左侧按钮文字
+	 * @property {String} nextText 右侧按钮文字
+	 * @property {String} piecePerPageText 条/页文字
+	 * @property {Number} current 当前页
+	 * @property {Number} total 数据总量
+	 * @property {Number} pageSize 每页数据量
+	 * @property {Boolean} showIcon = [true|false] 是否以 icon 形式展示按钮
+	 * @property {Boolean} showPageSize = [true|false] 是否展示每页条数
+	 * @property {Array} pageSizeRange = [20, 50, 100, 500] 每页条数选框
+	 * @event {Function} change 点击页码按钮时触发 ,e={type,current} current为当前页,type值为:next/prev,表示点击的是上一页还是下一个
+	 * * @event {Function} pageSizeChange 当前每页条数改变时触发 ,e={pageSize} pageSize 为当前所选的每页条数
+	 */
+
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(messages)
+	export default {
+		name: 'UniPagination',
+		emits: ['update:modelValue', 'input', 'change', 'pageSizeChange'],
+		props: {
+			value: {
+				type: [Number, String],
+				default: 1
+			},
+			modelValue: {
+				type: [Number, String],
+				default: 1
+			},
+			prevText: {
+				type: String,
+			},
+			nextText: {
+				type: String,
+			},
+			piecePerPageText: {
+				type: String
+			},
+			current: {
+				type: [Number, String],
+				default: 1
+			},
+			total: {
+				// 数据总量
+				type: [Number, String],
+				default: 0
+			},
+			pageSize: {
+				// 每页数据量
+				type: [Number, String],
+				default: 10
+			},
+			showIcon: {
+				// 是否以 icon 形式展示按钮
+				type: [Boolean, String],
+				default: false
+			},
+			showPageSize: {
+				// 是否以 icon 形式展示按钮
+				type: [Boolean, String],
+				default: false
+			},
+			pagerCount: {
+				type: Number,
+				default: 7
+			},
+			pageSizeRange: {
+				type: Array,
+				default: () => [20, 50, 100, 500]
+			}
+		},
+		data() {
+			return {
+				pageSizeIndex: 0,
+				currentIndex: 1,
+				paperData: [],
+				pickerShow: false
+			}
+		},
+		computed: {
+			piecePerPage() {
+				return this.piecePerPageText || t('uni-pagination.piecePerPage')
+			},
+			prevPageText() {
+				return this.prevText || t('uni-pagination.prevText')
+			},
+			nextPageText() {
+				return this.nextText || t('uni-pagination.nextText')
+			},
+			maxPage() {
+				let maxPage = 1
+				let total = Number(this.total)
+				let pageSize = Number(this.pageSize)
+				if (total && pageSize) {
+					maxPage = Math.ceil(total / pageSize)
+				}
+				return maxPage
+			},
+			paper() {
+				const num = this.currentIndex
+				// TODO 最大页数
+				const pagerCount = this.pagerCount
+				// const total = 181
+				const total = this.total
+				const pageSize = this.pageSize
+				let totalArr = []
+				let showPagerArr = []
+				let pagerNum = Math.ceil(total / pageSize)
+				for (let i = 0; i < pagerNum; i++) {
+					totalArr.push(i + 1)
+				}
+				showPagerArr.push(1)
+				const totalNum = totalArr[totalArr.length - (pagerCount + 1) / 2]
+				totalArr.forEach((item, index) => {
+					if ((pagerCount + 1) / 2 >= num) {
+						if (item < pagerCount + 1 && item > 1) {
+							showPagerArr.push(item)
+						}
+					} else if (num + 2 <= totalNum) {
+						if (item > num - (pagerCount + 1) / 2 && item < num + (pagerCount + 1) / 2) {
+							showPagerArr.push(item)
+						}
+					} else {
+						if ((item > num - (pagerCount + 1) / 2 || pagerNum - pagerCount < item) && item < totalArr[
+								totalArr.length - 1]) {
+							showPagerArr.push(item)
+						}
+					}
+				})
+				if (pagerNum > pagerCount) {
+					if ((pagerCount + 1) / 2 >= num) {
+						showPagerArr[showPagerArr.length - 1] = '...'
+					} else if (num + 2 <= totalNum) {
+						showPagerArr[1] = '...'
+						showPagerArr[showPagerArr.length - 1] = '...'
+					} else {
+						showPagerArr[1] = '...'
+					}
+					showPagerArr.push(totalArr[totalArr.length - 1])
+				} else {
+					if ((pagerCount + 1) / 2 >= num) {} else if (num + 2 <= totalNum) {} else {
+						showPagerArr.shift()
+						showPagerArr.push(totalArr[totalArr.length - 1])
+					}
+				}
+
+				return showPagerArr
+			}
+		},
+		watch: {
+			current: {
+				immediate: true,
+				handler(val, old) {
+					if (val < 1) {
+						this.currentIndex = 1
+					} else {
+						this.currentIndex = val
+					}
+				}
+			},
+			value: {
+				immediate: true,
+				handler(val) {
+					if (Number(this.current) !== 1) return
+					if (val < 1) {
+						this.currentIndex = 1
+					} else {
+						this.currentIndex = val
+					}
+				}
+			},
+			pageSizeIndex(val) {
+				this.$emit('pageSizeChange', this.pageSizeRange[val])
+			}
+		},
+		methods: {
+			pickerChange(e) {
+				this.pageSizeIndex = e.detail.value
+				this.pickerClick()
+			},
+			pickerClick() {
+				// #ifdef H5
+				const body = document.querySelector('body')
+				if (!body) return
+
+				const className = 'uni-pagination-picker-show'
+				this.pickerShow = !this.pickerShow
+
+				if (this.pickerShow) {
+					body.classList.add(className)
+				} else {
+					setTimeout(() => body.classList.remove(className), 300)
+				}
+				// #endif
+			},
+			// 选择标签
+			selectPage(e, index) {
+				if (parseInt(e)) {
+					this.currentIndex = e
+					this.change('current')
+				} else {
+					let pagerNum = Math.ceil(this.total / this.pageSize)
+					// let pagerNum = Math.ceil(181 / this.pageSize)
+					// 上一页
+					if (index <= 1) {
+						if (this.currentIndex - 5 > 1) {
+							this.currentIndex -= 5
+						} else {
+							this.currentIndex = 1
+						}
+						return
+					}
+					// 下一页
+					if (index >= 6) {
+						if (this.currentIndex + 5 > pagerNum) {
+							this.currentIndex = pagerNum
+						} else {
+							this.currentIndex += 5
+						}
+						return
+					}
+				}
+			},
+			clickLeft() {
+				if (Number(this.currentIndex) === 1) {
+					return
+				}
+				this.currentIndex -= 1
+				this.change('prev')
+			},
+			clickRight() {
+				if (Number(this.currentIndex) >= this.maxPage) {
+					return
+				}
+				this.currentIndex += 1
+				this.change('next')
+			},
+			change(e) {
+				this.$emit('input', this.currentIndex)
+				this.$emit('update:modelValue', this.currentIndex)
+				this.$emit('change', {
+					type: e,
+					current: this.currentIndex
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$uni-primary: #2979ff !default;
+	.uni-pagination {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		position: relative;
+		overflow: hidden;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-pagination__total {
+		font-size: 14px;
+		color: #999;
+		margin-right: 15px;
+	}
+
+	.uni-pagination__btn {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		cursor: pointer;
+		/* #endif */
+		padding: 0 8px;
+		line-height: 30px;
+		font-size: 12px;
+		position: relative;
+		background-color: #F0F0F0;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		text-align: center;
+		border-radius: 5px;
+		// border-width: 1px;
+		// border-style: solid;
+		// border-color: $uni-border-color;
+	}
+
+	.uni-pagination__child-btn {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		font-size: 12px;
+		position: relative;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		text-align: center;
+		color: #666;
+		font-size: 12px;
+	}
+
+	.uni-pagination__num {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 30px;
+		line-height: 30px;
+		font-size: 12px;
+		color: #666;
+		margin: 0 5px;
+	}
+
+	.uni-pagination__num-tag {
+		/* #ifdef H5 */
+		cursor: pointer;
+		min-width: 30px;
+		/* #endif */
+		margin: 0 5px;
+		height: 30px;
+		text-align: center;
+		line-height: 30px;
+		// border: 1px red solid;
+		color: #999;
+		border-radius: 4px;
+		// border-width: 1px;
+		// border-style: solid;
+		// border-color: $uni-border-color;
+	}
+
+	.uni-pagination__num-current {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-pagination__num-current-text {
+		font-size: 15px;
+	}
+
+	.current-index-text{
+		color: $uni-primary;
+	}
+
+	.uni-pagination--enabled {
+		color: #333333;
+		opacity: 1;
+	}
+
+	.uni-pagination--disabled {
+		opacity: 0.5;
+		/* #ifdef H5 */
+		cursor: default;
+		/* #endif */
+	}
+
+	.uni-pagination--hover {
+		color: rgba(0, 0, 0, 0.6);
+		background-color: #eee;
+	}
+
+	.tag--active:hover {
+		color: $uni-primary;
+	}
+
+	.page--active {
+		color: #fff;
+		background-color: $uni-primary;
+	}
+
+	.page--active:hover {
+		color: #fff;
+	}
+
+	/* #ifndef APP-NVUE */
+	.is-pc-hide {
+		display: block;
+	}
+
+	.is-phone-hide {
+		display: none;
+	}
+
+	@media screen and (min-width: 450px) {
+		.is-pc-hide {
+			display: none;
+		}
+
+		.is-phone-hide {
+			display: block;
+		}
+
+		.uni-pagination__num-flex-none {
+			flex: none;
+		}
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-pagination/package.json b/uni_modules/uni-pagination/package.json
new file mode 100644
index 0000000..862d5ab
--- /dev/null
+++ b/uni_modules/uni-pagination/package.json
@@ -0,0 +1,83 @@
+{
+  "id": "uni-pagination",
+  "displayName": "uni-pagination 分页器",
+  "version": "1.2.4",
+  "description": "Pagination 分页器组件,用于展示页码、请求数据等。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "分页器",
+    "页码"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss","uni-icons"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-pagination/readme.md b/uni_modules/uni-pagination/readme.md
new file mode 100644
index 0000000..97ea1d6
--- /dev/null
+++ b/uni_modules/uni-pagination/readme.md
@@ -0,0 +1,11 @@
+
+
+## Pagination 分页器
+> **组件名:uni-pagination**
+> 代码块: `uPagination`
+
+
+分页器组件,用于展示页码、请求数据等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-pagination)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
diff --git a/uni_modules/uni-popup/changelog.md b/uni_modules/uni-popup/changelog.md
new file mode 100644
index 0000000..f559715
--- /dev/null
+++ b/uni_modules/uni-popup/changelog.md
@@ -0,0 +1,92 @@
+## 1.9.5(2024-10-15)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.9.4(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.9.3(2024-10-12)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.9.2(2024-09-21)
+- 修复 uni-popup在android上的重复点击弹出位置不正确的bug
+## 1.9.1(2024-04-02)
+- 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法)
+## 1.9.0(2024-03-28)
+- 修复 uni-popup-dialog 双向绑定时初始化逻辑修正
+## 1.8.9(2024-03-20)
+- 修复 uni-popup-dialog 数据输入时修正为双向绑定
+## 1.8.8(2024-02-20)
+- 修复 uni-popup 在微信小程序下出现文字向上闪动的bug
+## 1.8.7(2024-02-02)
+- 新增 uni-popup-dialog 新增属性focus:input模式下,是否自动自动聚焦
+## 1.8.6(2024-01-30)
+- 新增 uni-popup-dialog 新增属性maxLength:限制输入框字数
+## 1.8.5(2024-01-26)
+- 新增 uni-popup-dialog 新增属性showClose:控制关闭按钮的显示
+## 1.8.4(2023-11-15)
+- 新增 uni-popup 支持uni-app-x 注意暂时仅支持 `maskClick` `@open` `@close`
+## 1.8.3(2023-04-17)
+- 修复 uni-popup 重复打开时的 bug
+## 1.8.2(2023-02-02)
+- uni-popup-dialog 组件新增 inputType 属性
+## 1.8.1(2022-12-01)
+- 修复 nvue 下 v-show 报错
+## 1.8.0(2022-11-29)
+- 优化 主题样式
+## 1.7.9(2022-04-02)
+- 修复 弹出层内部无法滚动的bug
+## 1.7.8(2022-03-28)
+- 修复 小程序中高度错误的bug
+## 1.7.7(2022-03-17)
+- 修复 快速调用open出现问题的Bug
+## 1.7.6(2022-02-14)
+- 修复 safeArea 属性不能设置为false的bug
+## 1.7.5(2022-01-19)
+- 修复 isMaskClick 失效的bug
+## 1.7.4(2022-01-19)
+- 新增 cancelText \ confirmText 属性 ,可自定义文本
+- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
+- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
+## 1.7.3(2022-01-13)
+- 修复 设置 safeArea 属性不生效的bug
+## 1.7.2(2021-11-26)
+- 优化 组件示例
+## 1.7.1(2021-11-26)
+- 修复 vuedoc 文字错误
+## 1.7.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
+## 1.6.2(2021-08-24)
+- 新增 支持国际化
+## 1.6.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.6.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.5.0(2021-06-23)
+- 新增 mask-click 遮罩层点击事件
+## 1.4.5(2021-06-22)
+- 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+## 1.4.4(2021-06-18)
+- 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+## 1.4.3(2021-06-08)
+- 修复 错误的 watch 字段
+- 修复 safeArea 属性不生效的问题
+- 修复 点击内容,再点击遮罩无法关闭的Bug
+## 1.4.2(2021-05-12)
+- 新增 组件示例地址
+## 1.4.1(2021-04-29)
+- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
+## 1.4.0 (2021-04-29)
+- 新增 type 属性的 left\right 值,支持左右弹出
+- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
+- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
+- 新增 safeArea 属性,是否适配底部安全区
+- 修复 App\h5\微信小程序底部安全区占位不对的Bug
+- 修复 App 端弹出等待的Bug
+- 优化 提升低配设备性能,优化动画卡顿问题
+- 优化 更简单的组件自定义方式
+## 1.2.9(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.2.8(2021-02-05)
+- 调整为uni_modules目录规范
+## 1.2.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 PC 端
+- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
diff --git a/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js b/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
new file mode 100644
index 0000000..6ef26a2
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    this.$once('hook:beforeDestroy', () => {
+      document.removeEventListener('keyup', listener)
+    })
+  },
+	render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue b/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
new file mode 100644
index 0000000..08707d4
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
@@ -0,0 +1,316 @@
+<template>
+	<view class="uni-popup-dialog">
+		<view class="uni-dialog-title">
+			<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
+		</view>
+		<view v-if="mode === 'base'" class="uni-dialog-content">
+			<slot>
+				<text class="uni-dialog-content-text">{{content}}</text>
+			</slot>
+		</view>
+		<view v-else class="uni-dialog-content">
+			<slot>
+				<input class="uni-dialog-input" :maxlength="maxlength" v-model="val" :type="inputType"
+					:placeholder="placeholderText" :focus="focus">
+			</slot>
+		</view>
+		<view class="uni-dialog-button-group">
+			<view class="uni-dialog-button" v-if="showClose" @click="closeDialog">
+				<text class="uni-dialog-button-text">{{closeText}}</text>
+			</view>
+			<view class="uni-dialog-button" :class="showClose?'uni-border-left':''" @click="onOk">
+				<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	import popup from '../uni-popup/popup.js'
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from '../uni-popup/i18n/index.js'
+	const {
+		t
+	} = initVueI18n(messages)
+	/**
+	 * PopUp 弹出层-对话框样式
+	 * @description 弹出层-对话框样式
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} value input 模式下的默认值
+	 * @property {String} placeholder input 模式下输入提示
+	 * @property {Boolean} focus input模式下是否自动聚焦,默认为true
+	 * @property {String} type = [success|warning|info|error] 主题样式
+	 *  @value success 成功
+	 * 	@value warning 提示
+	 * 	@value info 消息
+	 * 	@value error 错误
+	 * @property {String} mode = [base|input] 模式、
+	 * 	@value base 基础对话框
+	 * 	@value input 可输入对话框
+	 * @showClose {Boolean} 是否显示关闭按钮
+	 * @property {String} content 对话框内容
+	 * @property {Boolean} beforeClose 是否拦截取消事件
+	 * @property {Number} maxlength 输入
+	 * @event {Function} confirm 点击确认按钮触发
+	 * @event {Function} close 点击取消按钮触发
+	 */
+
+	export default {
+		name: "uniPopupDialog",
+		mixins: [popup],
+		emits: ['confirm', 'close', 'update:modelValue', 'input'],
+		props: {
+			inputType: {
+				type: String,
+				default: 'text'
+			},
+			showClose: {
+				type: Boolean,
+				default: true
+			},
+			// #ifdef VUE2
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				type: [Number, String],
+				default: ''
+			},
+			// #endif
+
+
+			placeholder: {
+				type: [String, Number],
+				default: ''
+			},
+			type: {
+				type: String,
+				default: 'error'
+			},
+			mode: {
+				type: String,
+				default: 'base'
+			},
+			title: {
+				type: String,
+				default: ''
+			},
+			content: {
+				type: String,
+				default: ''
+			},
+			beforeClose: {
+				type: Boolean,
+				default: false
+			},
+			cancelText: {
+				type: String,
+				default: ''
+			},
+			confirmText: {
+				type: String,
+				default: ''
+			},
+			maxlength: {
+				type: Number,
+				default: -1,
+			},
+			focus: {
+				type: Boolean,
+				default: true,
+			}
+		},
+		data() {
+			return {
+				dialogType: 'error',
+				val: ""
+			}
+		},
+		computed: {
+			okText() {
+				return this.confirmText || t("uni-popup.ok")
+			},
+			closeText() {
+				return this.cancelText || t("uni-popup.cancel")
+			},
+			placeholderText() {
+				return this.placeholder || t("uni-popup.placeholder")
+			},
+			titleText() {
+				return this.title || t("uni-popup.title")
+			}
+		},
+		watch: {
+			type(val) {
+				this.dialogType = val
+			},
+			mode(val) {
+				if (val === 'input') {
+					this.dialogType = 'info'
+				}
+			},
+			value(val) {
+				if (this.maxlength != -1 && this.mode === 'input') {
+					this.val = val.slice(0, this.maxlength);
+				} else {
+					this.val = val
+				}
+			},
+			val(val) {
+				// #ifdef VUE2
+				// TODO 兼容 vue2
+				this.$emit('input', val);
+				// #endif
+				// #ifdef VUE3
+				// TODO 兼容 vue3
+				this.$emit('update:modelValue', val);
+				// #endif
+			}
+		},
+		created() {
+			// 对话框遮罩不可点击
+			this.popup.disableMask()
+			// this.popup.closeMask()
+			if (this.mode === 'input') {
+				this.dialogType = 'info'
+				this.val = this.value;
+				// #ifdef VUE3
+				this.val = this.modelValue;
+				// #endif
+			} else {
+				this.dialogType = this.type
+			}
+		},
+		methods: {
+			/**
+			 * 点击确认按钮
+			 */
+			onOk() {
+				if (this.mode === 'input') {
+					this.$emit('confirm', this.val)
+				} else {
+					this.$emit('confirm')
+				}
+				if (this.beforeClose) return
+				this.popup.close()
+			},
+			/**
+			 * 点击取消按钮
+			 */
+			closeDialog() {
+				this.$emit('close')
+				if (this.beforeClose) return
+				this.popup.close()
+			},
+			close() {
+				this.popup.close()
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.uni-popup-dialog {
+		width: 300px;
+		border-radius: 11px;
+		background-color: #fff;
+	}
+
+	.uni-dialog-title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		padding-top: 25px;
+	}
+
+	.uni-dialog-title-text {
+		font-size: 16px;
+		font-weight: 500;
+	}
+
+	.uni-dialog-content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		padding: 20px;
+	}
+
+	.uni-dialog-content-text {
+		font-size: 14px;
+		color: #6C6C6C;
+	}
+
+	.uni-dialog-button-group {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		border-top-color: #f5f5f5;
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-dialog-button {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+
+		flex: 1;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 45px;
+	}
+
+	.uni-border-left {
+		border-left-color: #f0f0f0;
+		border-left-style: solid;
+		border-left-width: 1px;
+	}
+
+	.uni-dialog-button-text {
+		font-size: 16px;
+		color: #333;
+	}
+
+	.uni-button-color {
+		color: #007aff;
+	}
+
+	.uni-dialog-input {
+		flex: 1;
+		font-size: 14px;
+		border: 1px #eee solid;
+		height: 40px;
+		padding: 0 10px;
+		border-radius: 5px;
+		color: #555;
+	}
+
+	.uni-popup__success {
+		color: #4cd964;
+	}
+
+	.uni-popup__warn {
+		color: #f0ad4e;
+	}
+
+	.uni-popup__error {
+		color: #dd524d;
+	}
+
+	.uni-popup__info {
+		color: #909399;
+	}
+</style>
diff --git a/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue b/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
new file mode 100644
index 0000000..91370a8
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
@@ -0,0 +1,143 @@
+<template>
+	<view class="uni-popup-message">
+		<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
+			<slot>
+				<text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
+			</slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	import popup from '../uni-popup/popup.js'
+	/**
+	 * PopUp 弹出层-消息提示
+	 * @description 弹出层-消息提示
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [success|warning|info|error] 主题样式
+	 *  @value success 成功
+	 * 	@value warning 提示
+	 * 	@value info 消息
+	 * 	@value error 错误
+	 * @property {String} message 消息提示文字
+	 * @property {String} duration 显示时间,设置为 0 则不会自动关闭
+	 */
+
+	export default {
+		name: 'uniPopupMessage',
+		mixins:[popup],
+		props: {
+			/**
+			 * 主题 success/warning/info/error	  默认 success
+			 */
+			type: {
+				type: String,
+				default: 'success'
+			},
+			/**
+			 * 消息文字
+			 */
+			message: {
+				type: String,
+				default: ''
+			},
+			/**
+			 * 显示时间,设置为 0 则不会自动关闭
+			 */
+			duration: {
+				type: Number,
+				default: 3000
+			},
+			maskShow:{
+				type:Boolean,
+				default:false
+			}
+		},
+		data() {
+			return {}
+		},
+		created() {
+			this.popup.maskShow = this.maskShow
+			this.popup.messageChild = this
+		},
+		methods: {
+			timerClose(){
+				if(this.duration === 0) return
+				clearTimeout(this.timer) 
+				this.timer = setTimeout(()=>{
+					this.popup.close()
+				},this.duration)
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	.uni-popup-message {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+	}
+
+	.uni-popup-message__box {
+		background-color: #e1f3d8;
+		padding: 10px 15px;
+		border-color: #eee;
+		border-style: solid;
+		border-width: 1px;
+		flex: 1;
+	}
+
+	@media screen and (min-width: 500px) {
+		.fixforpc-width {
+			margin-top: 20px;
+			border-radius: 4px;
+			flex: none;
+			min-width: 380px;
+			/* #ifndef APP-NVUE */
+			max-width: 50%;
+			/* #endif */
+			/* #ifdef APP-NVUE */
+			max-width: 500px;
+			/* #endif */
+		}
+	}
+
+	.uni-popup-message-text {
+		font-size: 14px;
+		padding: 0;
+	}
+
+	.uni-popup__success {
+		background-color: #e1f3d8;
+	}
+
+	.uni-popup__success-text {
+		color: #67C23A;
+	}
+
+	.uni-popup__warn {
+		background-color: #faecd8;
+	}
+
+	.uni-popup__warn-text {
+		color: #E6A23C;
+	}
+
+	.uni-popup__error {
+		background-color: #fde2e2;
+	}
+
+	.uni-popup__error-text {
+		color: #F56C6C;
+	}
+
+	.uni-popup__info {
+		background-color: #F2F6FC;
+	}
+
+	.uni-popup__info-text {
+		color: #909399;
+	}
+</style>
diff --git a/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue b/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
new file mode 100644
index 0000000..f7e667c
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
@@ -0,0 +1,187 @@
+<template>
+	<view class="uni-popup-share">
+		<view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
+		<view class="uni-share-content">
+			<view class="uni-share-content-box">
+				<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
+					<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
+					<text class="uni-share-text">{{item.text}}</text>
+				</view>
+
+			</view>
+		</view>
+		<view class="uni-share-button-box">
+			<button class="uni-share-button" @click="close">{{cancelText}}</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	import popup from '../uni-popup/popup.js'
+	import {
+	initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from '../uni-popup/i18n/index.js'
+	const {	t	} = initVueI18n(messages)
+	export default {
+		name: 'UniPopupShare',
+		mixins:[popup],
+		emits:['select'],
+		props: {
+			title: {
+				type: String,
+				default: ''
+			},
+			beforeClose: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				bottomData: [{
+						text: '微信',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
+						name: 'wx'
+					},
+					{
+						text: '支付宝',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
+						name: 'ali'
+					},
+					{
+						text: 'QQ',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
+						name: 'qq'
+					},
+					{
+						text: '新浪',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
+						name: 'sina'
+					},
+					// {
+					// 	text: '百度',
+					// 	icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
+					// 	name: 'copy'
+					// },
+					// {
+					// 	text: '其他',
+					// 	icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
+					// 	name: 'more'
+					// }
+				]
+			}
+		},
+		created() {},
+		computed: {
+			cancelText() {
+				return t("uni-popup.cancel")
+			},
+		shareTitleText() {
+				return this.title || t("uni-popup.shareTitle")
+			}
+		},
+		methods: {
+			/**
+			 * 选择内容
+			 */
+			select(item, index) {
+				this.$emit('select', {
+					item,
+					index
+				})
+				this.close()
+
+			},
+			/**
+			 * 关闭窗口
+			 */
+			close() {
+				if(this.beforeClose) return
+				this.popup.close()
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	.uni-popup-share {
+		background-color: #fff;
+		border-top-left-radius: 11px;
+		border-top-right-radius: 11px;
+	}
+	.uni-share-title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		height: 40px;
+	}
+	.uni-share-title-text {
+		font-size: 14px;
+		color: #666;
+	}
+	.uni-share-content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		padding-top: 10px;
+	}
+
+	.uni-share-content-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex-wrap: wrap;
+		width: 360px;
+	}
+
+	.uni-share-content-item {
+		width: 90px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		padding: 10px 0;
+		align-items: center;
+	}
+
+	.uni-share-content-item:active {
+		background-color: #f5f5f5;
+	}
+
+	.uni-share-image {
+		width: 30px;
+		height: 30px;
+	}
+
+	.uni-share-text {
+		margin-top: 10px;
+		font-size: 14px;
+		color: #3B4144;
+	}
+
+	.uni-share-button-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		padding: 10px 15px;
+	}
+
+	.uni-share-button {
+		flex: 1;
+		border-radius: 50px;
+		color: #666;
+		font-size: 16px;
+	}
+
+	.uni-share-button::after {
+		border-radius: 50px;
+	}
+</style>
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/en.json b/uni_modules/uni-popup/components/uni-popup/i18n/en.json
new file mode 100644
index 0000000..7f1bd06
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/en.json
@@ -0,0 +1,7 @@
+{
+	"uni-popup.cancel": "cancel",
+	"uni-popup.ok": "ok",
+	"uni-popup.placeholder": "pleace enter",
+	"uni-popup.title": "Hint",
+	"uni-popup.shareTitle": "Share to"
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/index.js b/uni_modules/uni-popup/components/uni-popup/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
new file mode 100644
index 0000000..5e3003c
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
@@ -0,0 +1,7 @@
+{
+	"uni-popup.cancel": "取消",
+	"uni-popup.ok": "确定",
+	"uni-popup.placeholder": "请输入",
+		"uni-popup.title": "提示",
+		"uni-popup.shareTitle": "分享到"
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
new file mode 100644
index 0000000..13e39eb
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
@@ -0,0 +1,7 @@
+{
+	"uni-popup.cancel": "取消",
+	"uni-popup.ok": "確定",
+	"uni-popup.placeholder": "請輸入",
+	"uni-popup.title": "提示",
+	"uni-popup.shareTitle": "分享到"
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/keypress.js b/uni_modules/uni-popup/components/uni-popup/keypress.js
new file mode 100644
index 0000000..62dda46
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    // this.$once('hook:beforeDestroy', () => {
+    //   document.removeEventListener('keyup', listener)
+    // })
+  },
+	render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-popup/components/uni-popup/popup.js b/uni_modules/uni-popup/components/uni-popup/popup.js
new file mode 100644
index 0000000..c4e5781
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/popup.js
@@ -0,0 +1,26 @@
+
+export default {
+	data() {
+		return {
+			
+		}
+	},
+	created(){
+		this.popup = this.getParent()
+	},
+	methods:{
+		/**
+		 * 获取父元素实例
+		 */
+		getParent(name = 'uniPopup') {
+			let parent = this.$parent;
+			let parentName = parent.$options.name;
+			while (parentName !== name) {
+				parent = parent.$parent;
+				if (!parent) return false
+				parentName = parent.$options.name;
+			}
+			return parent;
+		},
+	}
+}
diff --git a/uni_modules/uni-popup/components/uni-popup/uni-popup.uvue b/uni_modules/uni-popup/components/uni-popup/uni-popup.uvue
new file mode 100644
index 0000000..5eb8d5b
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/uni-popup.uvue
@@ -0,0 +1,90 @@
+<template>
+  <view class="popup-root" v-if="isOpen" v-show="isShow" @click="clickMask">
+    <view @click.stop>
+      <slot></slot>
+    </view>
+  </view>
+</template>
+
+<script>
+  type CloseCallBack = ()=> void;
+  let closeCallBack:CloseCallBack = () :void => {};
+  export default {
+    emits:["close","clickMask"],
+    data() {
+      return {
+        isShow:false,
+        isOpen:false
+      }
+    },
+    props: {
+      maskClick: {
+        type: Boolean,
+        default: true
+      },
+    },
+    watch: {
+      // 设置show = true 时,如果没有 open 需要设置为 open
+      isShow:{
+        handler(isShow) {
+          // console.log("isShow",isShow)
+          if(isShow && this.isOpen == false){
+            this.isOpen = true
+          }
+        },
+        immediate:true
+      },
+      // 设置isOpen = true 时,如果没有 isShow 需要设置为 isShow
+      isOpen:{
+        handler(isOpen) {
+          // console.log("isOpen",isOpen)
+          if(isOpen && this.isShow == false){
+            this.isShow = true
+          }
+        },
+        immediate:true
+      }
+    },
+    methods:{
+      open(){
+        // ...funs : CloseCallBack[]
+        // if(funs.length > 0){
+        //   closeCallBack = funs[0]
+        // }
+        this.isOpen = true;
+      },
+      clickMask(){
+        if(this.maskClick == true){
+          this.$emit('clickMask')
+          this.close()
+        }
+      },
+      close(): void{
+        this.isOpen = false;
+        this.$emit('close')
+        closeCallBack()
+      },
+      hiden(){
+        this.isShow = false
+      },
+      show(){
+        this.isShow = true
+      }
+    }
+  }
+</script>
+
+<style>
+.popup-root {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 750rpx;
+  height: 100%;
+  flex: 1;
+  background-color: rgba(0, 0, 0, 0.3);
+  justify-content: center;
+  align-items: center;
+  z-index: 99;
+}
+</style>
\ No newline at end of file
diff --git a/uni_modules/uni-popup/components/uni-popup/uni-popup.vue b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
new file mode 100644
index 0000000..5af55e0
--- /dev/null
+++ b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue
@@ -0,0 +1,518 @@
+<template>
+	<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']">
+		<view @touchstart="touchstart">
+			<uni-transition key="1" v-if="maskShow" name="mask" mode-class="fade" :styles="maskClass"
+				:duration="duration" :show="showTrans" @click="onTap" />
+			<uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration"
+				:show="showTrans" @click="onTap">
+				<view class="uni-popup__wrapper" :style="getStyles" :class="[popupstyle]" @click="clear">
+					<slot />
+				</view>
+			</uni-transition>
+		</view>
+		<!-- #ifdef H5 -->
+		<keypress v-if="maskShow" @esc="onTap" />
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	import keypress from './keypress.js'
+	// #endif
+
+	/**
+	 * PopUp 弹出层
+	 * @description 弹出层组件,为了解决遮罩弹层的问题
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
+	 * 	@value top 顶部弹出
+	 * 	@value center 中间弹出
+	 * 	@value bottom 底部弹出
+	 * 	@value left		左侧弹出
+	 * 	@value right  右侧弹出
+	 * 	@value message 消息提示
+	 * 	@value dialog 对话框
+	 * 	@value share 底部分享示例
+	 * @property {Boolean} animation = [true|false] 是否开启动画
+	 * @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
+	 * @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
+	 * @property {String}  backgroundColor 主窗口背景色
+	 * @property {String}  maskBackgroundColor 蒙版颜色
+	 * @property {String}  borderRadius 设置圆角(左上、右上、右下和左下) 示例:"10px 10px 10px 10px"
+	 * @property {Boolean} safeArea		   是否适配底部安全区
+	 * @event {Function} change 打开关闭弹窗触发,e={show: false}
+	 * @event {Function} maskClick 点击遮罩触发
+	 */
+
+	export default {
+		name: 'uniPopup',
+		components: {
+			// #ifdef H5
+			keypress
+			// #endif
+		},
+		emits: ['change', 'maskClick'],
+		props: {
+			// 开启动画
+			animation: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
+			// message: 消息提示 ; dialog : 对话框
+			type: {
+				type: String,
+				default: 'center'
+			},
+			// maskClick
+			isMaskClick: {
+				type: Boolean,
+				default: null
+			},
+			// TODO 2 个版本后废弃属性 ,使用 isMaskClick
+			maskClick: {
+				type: Boolean,
+				default: null
+			},
+			backgroundColor: {
+				type: String,
+				default: 'none'
+			},
+			safeArea: {
+				type: Boolean,
+				default: true
+			},
+			maskBackgroundColor: {
+				type: String,
+				default: 'rgba(0, 0, 0, 0.4)'
+			},
+			borderRadius:{
+				type: String,
+			}
+		},
+
+		watch: {
+			/**
+			 * 监听type类型
+			 */
+			type: {
+				handler: function(type) {
+					if (!this.config[type]) return
+					this[this.config[type]](true)
+				},
+				immediate: true
+			},
+			isDesktop: {
+				handler: function(newVal) {
+					if (!this.config[newVal]) return
+					this[this.config[this.type]](true)
+				},
+				immediate: true
+			},
+			/**
+			 * 监听遮罩是否可点击
+			 * @param {Object} val
+			 */
+			maskClick: {
+				handler: function(val) {
+					this.mkclick = val
+				},
+				immediate: true
+			},
+			isMaskClick: {
+				handler: function(val) {
+					this.mkclick = val
+				},
+				immediate: true
+			},
+			// H5 下禁止底部滚动
+			showPopup(show) {
+				// #ifdef H5
+				// fix by mehaotian 处理 h5 滚动穿透的问题
+				document.getElementsByTagName('body')[0].style.overflow = show ? 'hidden' : 'visible'
+				// #endif
+			}
+		},
+		data() {
+			return {
+				duration: 300,
+				ani: [],
+				showPopup: false,
+				showTrans: false,
+				popupWidth: 0,
+				popupHeight: 0,
+				config: {
+					top: 'top',
+					bottom: 'bottom',
+					center: 'center',
+					left: 'left',
+					right: 'right',
+					message: 'top',
+					dialog: 'center',
+					share: 'bottom'
+				},
+				maskClass: {
+					position: 'fixed',
+					bottom: 0,
+					top: 0,
+					left: 0,
+					right: 0,
+					backgroundColor: 'rgba(0, 0, 0, 0.4)'
+				},
+				transClass: {
+					backgroundColor: 'transparent',
+					borderRadius: this.borderRadius || "0",
+					position: 'fixed',
+					left: 0,
+					right: 0
+				},
+				maskShow: true,
+				mkclick: true,
+				popupstyle: 'top'
+			}
+		},
+		computed: {
+			getStyles() {
+				let res = { backgroundColor: this.bg };
+				if (this.borderRadius || "0") {
+					res = Object.assign(res, { borderRadius: this.borderRadius })
+				}
+				return res;
+			},
+			isDesktop() {
+				return this.popupWidth >= 500 && this.popupHeight >= 500
+			},
+			bg() {
+				if (this.backgroundColor === '' || this.backgroundColor === 'none') {
+					return 'transparent'
+				}
+				return this.backgroundColor
+			}
+		},
+		mounted() {
+			const fixSize = () => {
+				// #ifdef MP-WEIXIN
+				const {
+					windowWidth,
+					windowHeight,
+					windowTop,
+					safeArea,
+					screenHeight,
+					safeAreaInsets
+				} = uni.getWindowInfo()
+				// #endif
+				// #ifndef MP-WEIXIN
+				const {
+					windowWidth,
+					windowHeight,
+					windowTop,
+					safeArea,
+					screenHeight,
+					safeAreaInsets
+				} = uni.getSystemInfoSync()
+				// #endif
+				this.popupWidth = windowWidth
+				this.popupHeight = windowHeight + (windowTop || 0)
+				// TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复
+				if (safeArea && this.safeArea) {
+					// #ifdef MP-WEIXIN
+					this.safeAreaInsets = screenHeight - safeArea.bottom
+					// #endif
+					// #ifndef MP-WEIXIN
+					this.safeAreaInsets = safeAreaInsets.bottom
+					// #endif
+				} else {
+					this.safeAreaInsets = 0
+				}
+			}
+			fixSize()
+			// #ifdef H5
+			// window.addEventListener('resize', fixSize)
+			// this.$once('hook:beforeDestroy', () => {
+			// 	window.removeEventListener('resize', fixSize)
+			// })
+			// #endif
+		},
+		// #ifndef VUE3
+		// TODO vue2
+		destroyed() {
+			this.setH5Visible()
+		},
+		// #endif
+		// #ifdef VUE3
+		// TODO vue3
+		unmounted() {
+			this.setH5Visible()
+		},
+		// #endif
+		activated() {
+   	  this.setH5Visible(!this.showPopup);
+    },
+    deactivated() {
+      this.setH5Visible(true);
+    },
+		created() {
+			// this.mkclick =  this.isMaskClick || this.maskClick
+			if (this.isMaskClick === null && this.maskClick === null) {
+				this.mkclick = true
+			} else {
+				this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick
+			}
+			if (this.animation) {
+				this.duration = 300
+			} else {
+				this.duration = 0
+			}
+			// TODO 处理 message 组件生命周期异常的问题
+			this.messageChild = null
+			// TODO 解决头条冒泡的问题
+			this.clearPropagation = false
+			this.maskClass.backgroundColor = this.maskBackgroundColor
+		},
+		methods: {
+			setH5Visible(visible = true) {
+				// #ifdef H5
+				// fix by mehaotian 处理 h5 滚动穿透的问题
+				document.getElementsByTagName('body')[0].style.overflow =  visible ? "visible" : "hidden";
+				// #endif
+			},
+			/**
+			 * 公用方法,不显示遮罩层
+			 */
+			closeMask() {
+				this.maskShow = false
+			},
+			/**
+			 * 公用方法,遮罩层禁止点击
+			 */
+			disableMask() {
+				this.mkclick = false
+			},
+			// TODO nvue 取消冒泡
+			clear(e) {
+				// #ifndef APP-NVUE
+				e.stopPropagation()
+				// #endif
+				this.clearPropagation = true
+			},
+
+			open(direction) {
+				// fix by mehaotian 处理快速打开关闭的情况
+				if (this.showPopup) {
+					return
+				}
+				let innerType = ['top', 'center', 'bottom', 'left', 'right', 'message', 'dialog', 'share']
+				if (!(direction && innerType.indexOf(direction) !== -1)) {
+					direction = this.type
+				}
+				if (!this.config[direction]) {
+					console.error('缺少类型:', direction)
+					return
+				}
+				this[this.config[direction]]()
+				this.$emit('change', {
+					show: true,
+					type: direction
+				})
+			},
+			close(type) {
+				this.showTrans = false
+				this.$emit('change', {
+					show: false,
+					type: this.type
+				})
+				clearTimeout(this.timer)
+				// // 自定义关闭事件
+				// this.customOpen && this.customClose()
+				this.timer = setTimeout(() => {
+					this.showPopup = false
+				}, 300)
+			},
+			// TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
+			touchstart() {
+				this.clearPropagation = false
+			},
+
+			onTap() {
+				if (this.clearPropagation) {
+					// fix by mehaotian 兼容 nvue
+					this.clearPropagation = false
+					return
+				}
+				this.$emit('maskClick')
+				if (!this.mkclick) return
+				this.close()
+			},
+			/**
+			 * 顶部弹出样式处理
+			 */
+			top(type) {
+				this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
+				this.ani = ['slide-top']
+				this.transClass = {
+					position: 'fixed',
+					left: 0,
+					right: 0,
+					backgroundColor: this.bg,
+					borderRadius:this.borderRadius || "0"
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPopup = true
+				this.showTrans = true
+				this.$nextTick(() => {
+					this.showPoptrans()
+					if (this.messageChild && this.type === 'message') {
+						this.messageChild.timerClose()
+					}
+				})
+			},
+			/**
+			 * 底部弹出样式处理
+			 */
+			bottom(type) {
+				this.popupstyle = 'bottom'
+				this.ani = ['slide-bottom']
+				this.transClass = {
+					position: 'fixed',
+					left: 0,
+					right: 0,
+					bottom: 0,
+					paddingBottom: this.safeAreaInsets + 'px',
+					backgroundColor: this.bg,
+					borderRadius:this.borderRadius || "0",
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPoptrans()
+			},
+			/**
+			 * 中间弹出样式处理
+			 */
+			center(type) {
+				this.popupstyle = 'center'
+				//微信小程序下,组合动画会出现文字向上闪动问题,再此做特殊处理
+				// #ifdef MP-WEIXIN
+					this.ani = ['fade']
+				// #endif
+				// #ifndef MP-WEIXIN
+					this.ani = ['zoom-out', 'fade']
+				// #endif
+				this.transClass = {
+					position: 'fixed',
+					/* #ifndef APP-NVUE */
+					display: 'flex',
+					flexDirection: 'column',
+					/* #endif */
+					bottom: 0,
+					left: 0,
+					right: 0,
+					top: 0,
+					justifyContent: 'center',
+					alignItems: 'center',
+					borderRadius:this.borderRadius || "0"
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPoptrans()
+			},
+			left(type) {
+				this.popupstyle = 'left'
+				this.ani = ['slide-left']
+				this.transClass = {
+					position: 'fixed',
+					left: 0,
+					bottom: 0,
+					top: 0,
+					backgroundColor: this.bg,
+					borderRadius:this.borderRadius || "0",
+					/* #ifndef APP-NVUE */
+					display: 'flex',
+					flexDirection: 'column'
+					/* #endif */
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPoptrans()
+			},
+			right(type) {
+				this.popupstyle = 'right'
+				this.ani = ['slide-right']
+				this.transClass = {
+					position: 'fixed',
+					bottom: 0,
+					right: 0,
+					top: 0,
+					backgroundColor: this.bg,
+					borderRadius:this.borderRadius || "0",
+					/* #ifndef APP-NVUE */
+					display: 'flex',
+					flexDirection: 'column'
+					/* #endif */
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPoptrans()
+			},
+			showPoptrans(){
+				this.$nextTick(()=>{
+					this.showPopup = true
+					this.showTrans = true
+				})
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.uni-popup {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+
+		/* #endif */
+		&.top,
+		&.left,
+		&.right {
+			/* #ifdef H5 */
+			top: var(--window-top);
+			/* #endif */
+			/* #ifndef H5 */
+			top: 0;
+			/* #endif */
+		}
+
+		.uni-popup__wrapper {
+			/* #ifndef APP-NVUE */
+			display: block;
+			/* #endif */
+			position: relative;
+
+			/* iphonex 等安全区设置,底部安全区适配 */
+			/* #ifndef APP-NVUE */
+			// padding-bottom: constant(safe-area-inset-bottom);
+			// padding-bottom: env(safe-area-inset-bottom);
+			/* #endif */
+			&.left,
+			&.right {
+				/* #ifdef H5 */
+				padding-top: var(--window-top);
+				/* #endif */
+				/* #ifndef H5 */
+				padding-top: 0;
+				/* #endif */
+				flex: 1;
+			}
+		}
+	}
+
+	.fixforpc-z-index {
+		/* #ifndef APP-NVUE */
+		z-index: 999;
+		/* #endif */
+	}
+
+	.fixforpc-top {
+		top: 0;
+	}
+</style>
diff --git a/uni_modules/uni-popup/package.json b/uni_modules/uni-popup/package.json
new file mode 100644
index 0000000..2750803
--- /dev/null
+++ b/uni_modules/uni-popup/package.json
@@ -0,0 +1,88 @@
+{
+	"id": "uni-popup",
+	"displayName": "uni-popup 弹出层",
+	"version": "1.9.5",
+	"description": " Popup 组件,提供常用的弹层",
+	"keywords": [
+        "uni-ui",
+        "弹出层",
+        "弹窗",
+        "popup",
+        "弹框"
+    ],
+	"repository": "https://github.com/dcloudio/uni-ui",
+	"engines": {
+		"HBuilderX": ""
+	},
+	"directories": {
+		"example": "../../temps/example_temps"
+	},
+    "dcloudext": {
+        "sale": {
+			"regular": {
+				"price": "0.00"
+			},
+			"sourcecode": {
+				"price": "0.00"
+			}
+		},
+		"contact": {
+			"qq": ""
+		},
+		"declaration": {
+			"ads": "无",
+			"data": "无",
+			"permissions": "无"
+		},
+        "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+        "type": "component-vue"
+	},
+	"uni_modules": {
+		"dependencies": [
+			"uni-scss",
+			"uni-transition"
+		],
+		"encrypt": [],
+		"platforms": {
+			"cloud": {
+				"tcb": "y",
+                "aliyun": "y",
+                "alipay": "n"
+			},
+			"client": {
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "y"
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "y",
+					"Edge": "y",
+					"Firefox": "y",
+					"Safari": "y"
+				},
+				"小程序": {
+					"微信": "y",
+					"阿里": "y",
+					"百度": "y",
+					"字节跳动": "y",
+					"QQ": "y"
+				},
+				"快应用": {
+					"华为": "u",
+					"联盟": "u"
+                },
+                "Vue": {
+                    "vue2": "y",
+                    "vue3": "y"
+                }
+			}
+		}
+	}
+}
diff --git a/uni_modules/uni-popup/readme.md b/uni_modules/uni-popup/readme.md
new file mode 100644
index 0000000..fdad4b3
--- /dev/null
+++ b/uni_modules/uni-popup/readme.md
@@ -0,0 +1,17 @@
+
+
+## Popup 弹出层
+> **组件名:uni-popup**
+> 代码块: `uPopup`
+> 关联组件:`uni-transition`
+
+
+弹出层组件,在应用中弹出一个消息提示窗口、提示框等
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
+
+
+
diff --git a/uni_modules/uni-rate/changelog.md b/uni_modules/uni-rate/changelog.md
new file mode 100644
index 0000000..8a98a61
--- /dev/null
+++ b/uni_modules/uni-rate/changelog.md
@@ -0,0 +1,25 @@
+## 1.3.1(2022-02-25)
+- 修复 条件判断 `NaN` 错误的 bug
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-rate](https://uniapp.dcloud.io/component/uniui/uni-rate)
+## 1.2.2(2021-09-10)
+- 优化 默认值修改为 0 颗星
+## 1.2.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.2(2021-05-12)
+- 新增 组件示例地址
+## 1.1.1(2021-04-21)
+- 修复 布局变化后 uni-rate  星星计算不准确的 bug
+- 优化 添加依赖 uni-icons, 导入 uni-rate 自动下载依赖
+## 1.1.0(2021-04-16)
+- 修复 uni-rate 属性 margin 值为 string 组件失效的 bug
+
+## 1.0.9(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.8(2021-02-05)
+- 调整为uni_modules目录规范
+- 支持 pc 端
diff --git a/uni_modules/uni-rate/components/uni-rate/uni-rate.vue b/uni_modules/uni-rate/components/uni-rate/uni-rate.vue
new file mode 100644
index 0000000..857f5f9
--- /dev/null
+++ b/uni_modules/uni-rate/components/uni-rate/uni-rate.vue
@@ -0,0 +1,361 @@
+<template>
+	<view>
+		<view ref="uni-rate" class="uni-rate">
+			<view class="uni-rate__icon" :class="{'uni-cursor-not-allowed': disabled}"
+				:style="{ 'margin-right': marginNumber + 'px' }" v-for="(star, index) in stars" :key="index"
+				@touchstart.stop="touchstart" @touchmove.stop="touchmove" @mousedown.stop="mousedown"
+				@mousemove.stop="mousemove" @mouseleave="mouseleave">
+				<uni-icons :color="color" :size="size" :type="isFill ? 'star-filled' : 'star'" />
+				<!-- #ifdef APP-NVUE -->
+				<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on">
+					<uni-icons style="text-align: left;" :color="disabled?'#ccc':activeColor" :size="size"
+						type="star-filled" />
+				</view>
+				<!-- #endif -->
+				<!-- #ifndef APP-NVUE -->
+				<view :style="{ width: star.activeWitch}" class="uni-rate__icon-on">
+					<uni-icons :color="disabled?disabledColor:activeColor" :size="size" type="star-filled" />
+				</view>
+				<!-- #endif -->
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const dom = uni.requireNativePlugin('dom');
+	// #endif
+	/**
+	 * Rate 评分
+	 * @description 评分组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=33
+	 * @property {Boolean} 	isFill = [true|false] 		星星的类型,是否为实心类型, 默认为实心
+	 * @property {String} 	color 						未选中状态的星星颜色,默认为 "#ececec"
+	 * @property {String} 	activeColor 				选中状态的星星颜色,默认为 "#ffca3e"
+	 * @property {String} 	disabledColor 				禁用状态的星星颜色,默认为 "#c0c0c0"
+	 * @property {Number} 	size 						星星的大小
+	 * @property {Number} 	value/v-model 				当前评分
+	 * @property {Number} 	max 						最大评分评分数量,目前一分一颗星
+	 * @property {Number} 	margin 						星星的间距,单位 px
+	 * @property {Boolean} 	disabled = [true|false] 	是否为禁用状态,默认为 false
+	 * @property {Boolean} 	readonly = [true|false] 	是否为只读状态,默认为 false
+	 * @property {Boolean} 	allowHalf = [true|false] 	是否实现半星,默认为 false
+	 * @property {Boolean} 	touchable = [true|false] 	是否支持滑动手势,默认为 true
+	 * @event {Function} change 						uniRate 的 value 改变时触发事件,e={value:Number}
+	 */
+
+	export default {
+		name: "UniRate",
+		props: {
+			isFill: {
+				// 星星的类型,是否镂空
+				type: [Boolean, String],
+				default: true
+			},
+			color: {
+				// 星星未选中的颜色
+				type: String,
+				default: "#ececec"
+			},
+			activeColor: {
+				// 星星选中状态颜色
+				type: String,
+				default: "#ffca3e"
+			},
+			disabledColor: {
+				// 星星禁用状态颜色
+				type: String,
+				default: "#c0c0c0"
+			},
+			size: {
+				// 星星的大小
+				type: [Number, String],
+				default: 24
+			},
+			value: {
+				// 当前评分
+				type: [Number, String],
+				default: 0
+			},
+			modelValue: {
+				// 当前评分
+				type: [Number, String],
+				default: 0
+			},
+			max: {
+				// 最大评分
+				type: [Number, String],
+				default: 5
+			},
+			margin: {
+				// 星星的间距
+				type: [Number, String],
+				default: 0
+			},
+			disabled: {
+				// 是否可点击
+				type: [Boolean, String],
+				default: false
+			},
+			readonly: {
+				// 是否只读
+				type: [Boolean, String],
+				default: false
+			},
+			allowHalf: {
+				// 是否显示半星
+				type: [Boolean, String],
+				default: false
+			},
+			touchable: {
+				// 是否支持滑动手势
+				type: [Boolean, String],
+				default: true
+			}
+		},
+		data() {
+			return {
+				valueSync: "",
+				userMouseFristMove: true,
+				userRated: false,
+				userLastRate: 1
+			};
+		},
+		watch: {
+			value(newVal) {
+				this.valueSync = Number(newVal);
+			},
+			modelValue(newVal) {
+				this.valueSync = Number(newVal);
+			},
+		},
+		computed: {
+			stars() {
+				const value = this.valueSync ? this.valueSync : 0;
+				const starList = [];
+				const floorValue = Math.floor(value);
+				const ceilValue = Math.ceil(value);
+				for (let i = 0; i < this.max; i++) {
+					if (floorValue > i) {
+						starList.push({
+							activeWitch: "100%"
+						});
+					} else if (ceilValue - 1 === i) {
+						starList.push({
+							activeWitch: (value - floorValue) * 100 + "%"
+						});
+					} else {
+						starList.push({
+							activeWitch: "0"
+						});
+					}
+				}
+				return starList;
+			},
+
+			marginNumber() {
+				return Number(this.margin)
+			}
+		},
+		created() {
+			this.valueSync = Number(this.value || this.modelValue);
+			this._rateBoxLeft = 0
+			this._oldValue = null
+		},
+		mounted() {
+			setTimeout(() => {
+				this._getSize()
+			}, 100)
+			// #ifdef H5
+			this.PC = this.IsPC()
+			// #endif
+		},
+		methods: {
+			touchstart(e) {
+				// #ifdef H5
+				if (this.IsPC()) return
+				// #endif
+				if (this.readonly || this.disabled) return
+				const {
+					clientX,
+					screenX
+				} = e.changedTouches[0]
+				// TODO 做一下兼容,只有 Nvue 下才有 screenX,其他平台式 clientX
+				this._getRateCount(clientX || screenX)
+			},
+			touchmove(e) {
+				// #ifdef H5
+				if (this.IsPC()) return
+				// #endif
+				if (this.readonly || this.disabled || !this.touchable) return
+				const {
+					clientX,
+					screenX
+				} = e.changedTouches[0]
+				this._getRateCount(clientX || screenX)
+			},
+
+			/**
+			 * 兼容 PC @tian
+			 */
+
+			mousedown(e) {
+				// #ifdef H5
+				if (!this.IsPC()) return
+				if (this.readonly || this.disabled) return
+				const {
+					clientX,
+				} = e
+				this.userLastRate = this.valueSync
+				this._getRateCount(clientX)
+				this.userRated = true
+				// #endif
+			},
+			mousemove(e) {
+				// #ifdef H5
+				if (!this.IsPC()) return
+				if (this.userRated) return
+				if (this.userMouseFristMove) {
+					console.log('---mousemove----', this.valueSync);
+					this.userLastRate = this.valueSync
+					this.userMouseFristMove = false
+				}
+				if (this.readonly || this.disabled || !this.touchable) return
+				const {
+					clientX,
+				} = e
+				this._getRateCount(clientX)
+				// #endif
+			},
+			mouseleave(e) {
+				// #ifdef H5
+				if (!this.IsPC()) return
+				if (this.readonly || this.disabled || !this.touchable) return
+				if (this.userRated) {
+					this.userRated = false
+					return
+				}
+				this.valueSync = this.userLastRate
+				// #endif
+			},
+			// #ifdef H5
+			IsPC() {
+				var userAgentInfo = navigator.userAgent;
+				var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+				var flag = true;
+				for (let v = 0; v < Agents.length - 1; v++) {
+					if (userAgentInfo.indexOf(Agents[v]) > 0) {
+						flag = false;
+						break;
+					}
+				}
+				return flag;
+			},
+			// #endif
+
+			/**
+			 * 获取星星个数
+			 */
+			_getRateCount(clientX) {
+				this._getSize()
+				const size = Number(this.size)
+				if (isNaN(size)) {
+					return new Error('size 属性只能设置为数字')
+				}
+				const rateMoveRange = clientX - this._rateBoxLeft
+				let index = parseInt(rateMoveRange / (size + this.marginNumber))
+				index = index < 0 ? 0 : index;
+				index = index > this.max ? this.max : index;
+				const range = parseInt(rateMoveRange - (size + this.marginNumber) * index);
+				let value = 0;
+				if (this._oldValue === index && !this.PC) return;
+				this._oldValue = index;
+				if (this.allowHalf) {
+					if (range > (size / 2)) {
+						value = index + 1
+					} else {
+						value = index + 0.5
+					}
+				} else {
+					value = index + 1
+				}
+
+				value = Math.max(0.5, Math.min(value, this.max))
+				this.valueSync = value
+				this._onChange()
+			},
+
+			/**
+			 * 触发动态修改
+			 */
+			_onChange() {
+
+				this.$emit("input", this.valueSync);
+				this.$emit("update:modelValue", this.valueSync);
+				this.$emit("change", {
+					value: this.valueSync
+				});
+			},
+			/**
+			 * 获取星星距离屏幕左侧距离
+			 */
+			_getSize() {
+				// #ifndef APP-NVUE
+				uni.createSelectorQuery()
+					.in(this)
+					.select('.uni-rate')
+					.boundingClientRect()
+					.exec(ret => {
+						if (ret) {
+							this._rateBoxLeft = ret[0].left
+						}
+					})
+				// #endif
+				// #ifdef APP-NVUE
+				dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
+					const size = ret.size
+					if (size) {
+						this._rateBoxLeft = size.left
+					}
+				})
+				// #endif
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	.uni-rate {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		line-height: 1;
+		font-size: 0;
+		flex-direction: row;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-rate__icon {
+		position: relative;
+		line-height: 1;
+		font-size: 0;
+	}
+
+	.uni-rate__icon-on {
+		overflow: hidden;
+		position: absolute;
+		top: 0;
+		left: 0;
+		line-height: 1;
+		text-align: left;
+	}
+
+	.uni-cursor-not-allowed {
+		/* #ifdef H5 */
+		cursor: not-allowed !important;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-rate/package.json b/uni_modules/uni-rate/package.json
new file mode 100644
index 0000000..64e8e33
--- /dev/null
+++ b/uni_modules/uni-rate/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-rate",
+  "displayName": "uni-rate 评分",
+  "version": "1.3.1",
+  "description": "Rate 评分组件,可自定义评分星星图标的大小、间隔、评分数。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "评分"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-rate/readme.md b/uni_modules/uni-rate/readme.md
new file mode 100644
index 0000000..eae7b5c
--- /dev/null
+++ b/uni_modules/uni-rate/readme.md
@@ -0,0 +1,12 @@
+
+
+## Rate 评分
+> **组件名:uni-rate**
+> 代码块: `uRate`
+> 关联组件:`uni-icons`
+
+
+评分组件,多用于购买商品后,对商品进行评价等场景
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-rate)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-row/changelog.md b/uni_modules/uni-row/changelog.md
new file mode 100644
index 0000000..5b465bc
--- /dev/null
+++ b/uni_modules/uni-row/changelog.md
@@ -0,0 +1,10 @@
+## 1.0.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-row](https://uniapp.dcloud.io/component/uniui/uni-row)
+## 0.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.0.4(2021-05-12)
+- 新增 组件示例地址
+## 0.0.3(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增uni-row组件
diff --git a/uni_modules/uni-row/components/uni-col/uni-col.vue b/uni_modules/uni-row/components/uni-col/uni-col.vue
new file mode 100644
index 0000000..84e2deb
--- /dev/null
+++ b/uni_modules/uni-row/components/uni-col/uni-col.vue
@@ -0,0 +1,317 @@
+<template>
+	<!-- #ifndef APP-NVUE -->
+	<view :class="['uni-col', sizeClass, pointClassList]" :style="{
+		paddingLeft:`${Number(gutter)}rpx`,
+		paddingRight:`${Number(gutter)}rpx`,
+	}">
+		<slot></slot>
+	</view>
+	<!-- #endif -->
+	<!-- #ifdef APP-NVUE -->
+	<!-- 在nvue上,类名样式不生效,换为style -->
+	<!-- 设置right正值失效,设置 left 负值 -->
+	<view :class="['uni-col']" :style="{
+		paddingLeft:`${Number(gutter)}rpx`,
+		paddingRight:`${Number(gutter)}rpx`,
+		width:`${nvueWidth}rpx`,
+		position:'relative',
+		marginLeft:`${marginLeft}rpx`,
+		left:`${right === 0 ? left : -right}rpx`
+	}">
+		<slot></slot>
+	</view>
+	<!-- #endif -->
+</template>
+
+<script>
+	/**
+	 * Col	布局-列
+	 * @description	搭配uni-row使用,构建布局。
+	 * @tutorial	https://ext.dcloud.net.cn/plugin?id=3958
+	 *
+	 * @property	{span} type = Number 栅格占据的列数
+	 * 						默认 24
+	 * @property	{offset} type = Number 栅格左侧的间隔格数
+	 * @property	{push} type = Number 栅格向右移动格数
+	 * @property	{pull} type = Number 栅格向左移动格数
+	 * @property	{xs} type = [Number, Object] <768px 响应式栅格数或者栅格属性对象
+	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
+	 * @property	{sm} type = [Number, Object] ≥768px 响应式栅格数或者栅格属性对象
+	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
+	 * @property	{md} type = [Number, Object] ≥992px 响应式栅格数或者栅格属性对象
+	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
+	 * @property	{lg} type = [Number, Object] ≥1200px 响应式栅格数或者栅格属性对象
+	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
+	 * @property	{xl} type = [Number, Object] ≥1920px 响应式栅格数或者栅格属性对象
+	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4}
+	 */
+	const ComponentClass = 'uni-col';
+
+	// -1 默认值,因为在微信小程序端只给Number会有默认值0
+	export default {
+		name: 'uniCol',
+		// #ifdef MP-WEIXIN
+		options: {
+			virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现
+		},
+		// #endif
+		props: {
+			span: {
+				type: Number,
+				default: 24
+			},
+			offset: {
+				type: Number,
+				default: -1
+			},
+			pull: {
+				type: Number,
+				default: -1
+			},
+			push: {
+				type: Number,
+				default: -1
+			},
+			xs: [Number, Object],
+			sm: [Number, Object],
+			md: [Number, Object],
+			lg: [Number, Object],
+			xl: [Number, Object]
+		},
+		data() {
+			return {
+				gutter: 0,
+				sizeClass: '',
+				parentWidth: 0,
+				nvueWidth: 0,
+				marginLeft: 0,
+				right: 0,
+				left: 0
+			}
+		},
+		created() {
+			// 字节小程序中,在computed中读取$parent为undefined
+			let parent = this.$parent;
+
+			while (parent && parent.$options.componentName !== 'uniRow') {
+				parent = parent.$parent;
+			}
+
+			this.updateGutter(parent.gutter)
+			parent.$watch('gutter', (gutter) => {
+				this.updateGutter(gutter)
+			})
+
+			// #ifdef APP-NVUE
+			this.updateNvueWidth(parent.width)
+			parent.$watch('width', (width) => {
+				this.updateNvueWidth(width)
+			})
+			// #endif
+		},
+		computed: {
+			sizeList() {
+				let {
+					span,
+					offset,
+					pull,
+					push
+				} = this;
+
+				return {
+					span,
+					offset,
+					pull,
+					push
+				}
+			},
+			// #ifndef APP-NVUE
+			pointClassList() {
+				let classList = [];
+
+				['xs', 'sm', 'md', 'lg', 'xl'].forEach(point => {
+					const props = this[point];
+					if (typeof props === 'number') {
+						classList.push(`${ComponentClass}-${point}-${props}`)
+					} else if (typeof props === 'object' && props) {
+						Object.keys(props).forEach(pointProp => {
+							classList.push(
+								pointProp === 'span' ?
+								`${ComponentClass}-${point}-${props[pointProp]}` :
+								`${ComponentClass}-${point}-${pointProp}-${props[pointProp]}`
+							)
+						})
+					}
+				});
+
+				// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
+				return classList.join(' ');
+			}
+			// #endif
+		},
+		methods: {
+			updateGutter(parentGutter) {
+				parentGutter = Number(parentGutter);
+				if (!isNaN(parentGutter)) {
+					this.gutter = parentGutter / 2
+				}
+			},
+			// #ifdef APP-NVUE
+			updateNvueWidth(width) {
+				// 用于在nvue端,span,offset,pull,push的计算
+				this.parentWidth = width;
+				['span', 'offset', 'pull', 'push'].forEach(size => {
+					const curSize = this[size];
+					if ((curSize || curSize === 0) && curSize !== -1) {
+						let RPX = 1 / 24 * curSize * width
+						RPX = Number(RPX);
+						switch (size) {
+							case 'span':
+								this.nvueWidth = RPX
+								break;
+							case 'offset':
+								this.marginLeft = RPX
+								break;
+							case 'pull':
+								this.right = RPX
+								break;
+							case 'push':
+								this.left = RPX
+								break;
+						}
+					}
+				});
+			}
+			// #endif
+		},
+		watch: {
+			sizeList: {
+				immediate: true,
+				handler(newVal) {
+					// #ifndef APP-NVUE
+					let classList = [];
+					for (let size in newVal) {
+						const curSize = newVal[size];
+						if ((curSize || curSize === 0) && curSize !== -1) {
+							classList.push(
+								size === 'span' ?
+								`${ComponentClass}-${curSize}` :
+								`${ComponentClass}-${size}-${curSize}`
+							)
+						}
+					}
+					// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误
+					this.sizeClass = classList.join(' ');
+					// #endif
+					// #ifdef APP-NVUE
+					this.updateNvueWidth(this.parentWidth);
+					// #endif
+				}
+			}
+		}
+	}
+</script>
+
+<style lang='scss' scoped>
+	/* breakpoints */
+	$--sm: 768px !default;
+	$--md: 992px !default;
+	$--lg: 1200px !default;
+	$--xl: 1920px !default;
+
+	$breakpoints: ('xs' : (max-width: $--sm - 1),
+	'sm' : (min-width: $--sm),
+	'md' : (min-width: $--md),
+	'lg' : (min-width: $--lg),
+	'xl' : (min-width: $--xl));
+
+	$layout-namespace: ".uni-";
+	$col: $layout-namespace+"col";
+
+	@function getSize($size) {
+		/* TODO 1/24 * $size * 100 * 1%; 使用计算后的值,为了解决 vue3 控制台报错 */
+		@return 0.04166666666 * $size * 100 * 1%;
+	}
+
+	@mixin res($key, $map:$breakpoints) {
+		@if map-has-key($map, $key) {
+			@media screen and #{inspect(map-get($map,$key))} {
+				@content;
+			}
+		}
+
+		@else {
+			@warn "Undeinfed point: `#{$key}`";
+		}
+	}
+
+	/* #ifndef APP-NVUE */
+	#{$col} {
+		float: left;
+		box-sizing: border-box;
+	}
+
+	#{$col}-0 {
+		/* #ifdef APP-NVUE */
+		width: 0;
+		height: 0;
+		margin-top: 0;
+		margin-right: 0;
+		margin-bottom: 0;
+		margin-left: 0;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: none;
+		/* #endif */
+	}
+
+	@for $i from 0 through 24 {
+		#{$col}-#{$i} {
+			width: getSize($i);
+		}
+
+		#{$col}-offset-#{$i} {
+			margin-left: getSize($i);
+		}
+
+		#{$col}-pull-#{$i} {
+			position: relative;
+			right: getSize($i);
+		}
+
+		#{$col}-push-#{$i} {
+			position: relative;
+			left: getSize($i);
+		}
+	}
+
+	@each $point in map-keys($breakpoints) {
+		@include res($point) {
+			#{$col}-#{$point}-0 {
+				display: none;
+			}
+
+			@for $i from 0 through 24 {
+				#{$col}-#{$point}-#{$i} {
+					width: getSize($i);
+				}
+
+				#{$col}-#{$point}-offset-#{$i} {
+					margin-left: getSize($i);
+				}
+
+				#{$col}-#{$point}-pull-#{$i} {
+					position: relative;
+					right: getSize($i);
+				}
+
+				#{$col}-#{$point}-push-#{$i} {
+					position: relative;
+					left: getSize($i);
+				}
+			}
+		}
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-row/components/uni-row/uni-row.vue b/uni_modules/uni-row/components/uni-row/uni-row.vue
new file mode 100644
index 0000000..f8e8542
--- /dev/null
+++ b/uni_modules/uni-row/components/uni-row/uni-row.vue
@@ -0,0 +1,190 @@
+<template>
+	<view :class="[ 'uni-row', typeClass , justifyClass, alignClass, ]" :style="{
+		marginLeft:`${Number(marginValue)}rpx`,
+		marginRight:`${Number(marginValue)}rpx`,
+	}">
+		<slot></slot>
+	</view>
+</template>
+
+<script>
+	const ComponentClass = 'uni-row';
+	const modifierSeparator = '--';
+	/**
+	 * Row	布局-行
+	 * @description	流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。
+	 * @tutorial	https://ext.dcloud.net.cn/plugin?id=3958
+	 *
+	 * @property	{gutter} type = Number 栅格间隔
+	 * @property	{justify} type = String flex 布局下的水平排列方式
+	 * 						可选	start/end/center/space-around/space-between	start
+	 * 						默认值	start
+	 * @property	{align} type = String flex 布局下的垂直排列方式
+	 * 						可选	top/middle/bottom
+	 * 						默认值	top
+	 * @property	{width} type = String|Number nvue下需要自行配置宽度用于计算
+	 * 						默认值 750
+	 */
+
+
+	export default {
+		name: 'uniRow',
+		componentName: 'uniRow',
+		// #ifdef MP-WEIXIN
+		options: {
+			virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现,可使用flex布局
+		},
+		// #endif
+		props: {
+			type: String,
+			gutter: Number,
+			justify: {
+				type: String,
+				default: 'start'
+			},
+			align: {
+				type: String,
+				default: 'top'
+			},
+			// nvue如果使用span等属性,需要配置宽度
+			width: {
+				type: [String, Number],
+				default: 750
+			}
+		},
+		created() {
+			// #ifdef APP-NVUE
+			this.type = 'flex';
+			// #endif
+		},
+		computed: {
+			marginValue() {
+				// #ifndef APP-NVUE
+				if (this.gutter) {
+					return -(this.gutter / 2);
+				}
+				// #endif
+				return 0;
+			},
+			typeClass() {
+				return this.type === 'flex' ? `${ComponentClass + modifierSeparator}flex` : '';
+			},
+			justifyClass() {
+				return this.justify !== 'start' ? `${ComponentClass + modifierSeparator}flex-justify-${this.justify}` : ''
+			},
+			alignClass() {
+				return this.align !== 'top' ? `${ComponentClass + modifierSeparator}flex-align-${this.align}` : ''
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	$layout-namespace: ".uni-";
+	$row:$layout-namespace+"row";
+	$modifier-separator: "--";
+
+	@mixin utils-clearfix {
+		$selector: &;
+
+		@at-root {
+
+			/* #ifndef APP-NVUE */
+			#{$selector}::before,
+			#{$selector}::after {
+				display: table;
+				content: "";
+			}
+
+			#{$selector}::after {
+				clear: both;
+			}
+
+			/* #endif */
+		}
+
+	}
+
+	@mixin utils-flex ($direction: row) {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: $direction;
+	}
+
+	@mixin set-flex($state) {
+		@at-root &-#{$state} {
+			@content
+		}
+	}
+
+	#{$row} {
+		position: relative;
+		flex-direction: row;
+
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		/* #endif */
+
+		// 非nvue使用float布局
+		@include utils-clearfix;
+
+		// 在QQ、字节、百度小程序平台,编译后使用shadow dom,不可使用flex布局,使用float
+		@at-root {
+
+			/* #ifndef MP-QQ || MP-TOUTIAO || MP-BAIDU */
+			&#{$modifier-separator}flex {
+				@include utils-flex;
+				flex-wrap: wrap;
+				flex: 1;
+
+				&:before,
+				&:after {
+					/* #ifndef APP-NVUE */
+					display: none;
+					/* #endif */
+				}
+
+				@include set-flex(justify-center) {
+					justify-content: center;
+				}
+
+				@include set-flex(justify-end) {
+					justify-content: flex-end;
+				}
+
+				@include set-flex(justify-space-between) {
+					justify-content: space-between;
+				}
+
+				@include set-flex(justify-space-around) {
+					justify-content: space-around;
+				}
+
+				@include set-flex(align-middle) {
+					align-items: center;
+				}
+
+				@include set-flex(align-bottom) {
+					align-items: flex-end;
+				}
+			}
+
+			/* #endif */
+		}
+
+	}
+
+	// 字节、QQ配置后不生效
+	// 此处用法无法使用scoped
+	/* #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ */
+	:host {
+		display: block;
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-row/package.json b/uni_modules/uni-row/package.json
new file mode 100644
index 0000000..3f52fa6
--- /dev/null
+++ b/uni_modules/uni-row/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-row",
+  "displayName": "uni-row 布局-行",
+  "version": "1.0.0",
+  "description": "流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "栅格",
+    "布局",
+    "layout"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "u"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-row/readme.md b/uni_modules/uni-row/readme.md
new file mode 100644
index 0000000..3c9c8b9
--- /dev/null
+++ b/uni_modules/uni-row/readme.md
@@ -0,0 +1,10 @@
+## Layout 布局
+
+> **组件名 uni-row、uni-col**
+> 代码块: `uRow`、`uCol`
+
+
+流式栅格系统,随着屏幕或视口分为 24 份,可以迅速简便地创建布局。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-row)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-scss/changelog.md b/uni_modules/uni-scss/changelog.md
new file mode 100644
index 0000000..b863bb0
--- /dev/null
+++ b/uni_modules/uni-scss/changelog.md
@@ -0,0 +1,8 @@
+## 1.0.3(2022-01-21)
+- 优化 组件示例
+## 1.0.2(2021-11-22)
+- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
+## 1.0.1(2021-11-22)
+- 修复 vue3中scss语法兼容问题
+## 1.0.0(2021-11-18)
+- init
diff --git a/uni_modules/uni-scss/index.scss b/uni_modules/uni-scss/index.scss
new file mode 100644
index 0000000..1744a5f
--- /dev/null
+++ b/uni_modules/uni-scss/index.scss
@@ -0,0 +1 @@
+@import './styles/index.scss';
diff --git a/uni_modules/uni-scss/package.json b/uni_modules/uni-scss/package.json
new file mode 100644
index 0000000..7cc0ccb
--- /dev/null
+++ b/uni_modules/uni-scss/package.json
@@ -0,0 +1,82 @@
+{
+  "id": "uni-scss",
+  "displayName": "uni-scss 辅助样式",
+  "version": "1.0.3",
+  "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
+  "keywords": [
+    "uni-scss",
+    "uni-ui",
+    "辅助样式"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+        "JS SDK",
+        "通用 SDK"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-scss/readme.md b/uni_modules/uni-scss/readme.md
new file mode 100644
index 0000000..b7d1c25
--- /dev/null
+++ b/uni_modules/uni-scss/readme.md
@@ -0,0 +1,4 @@
+`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/index.scss b/uni_modules/uni-scss/styles/index.scss
new file mode 100644
index 0000000..ffac4fe
--- /dev/null
+++ b/uni_modules/uni-scss/styles/index.scss
@@ -0,0 +1,7 @@
+@import './setting/_variables.scss';
+@import './setting/_border.scss';
+@import './setting/_color.scss';
+@import './setting/_space.scss';
+@import './setting/_radius.scss';
+@import './setting/_text.scss';
+@import './setting/_styles.scss';
diff --git a/uni_modules/uni-scss/styles/setting/_border.scss b/uni_modules/uni-scss/styles/setting/_border.scss
new file mode 100644
index 0000000..12a11c3
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_border.scss
@@ -0,0 +1,3 @@
+.uni-border {
+	border: 1px $uni-border-1 solid;
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_color.scss b/uni_modules/uni-scss/styles/setting/_color.scss
new file mode 100644
index 0000000..1ededd9
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_color.scss
@@ -0,0 +1,66 @@
+
+// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
+// @mixin get-styles($k,$c) {
+// 	@if $k == size or $k == weight{
+// 		font-#{$k}:#{$c}
+// 	}@else{
+// 		#{$k}:#{$c}
+// 	}
+// }
+$uni-ui-color:(
+	// 主色
+	primary: $uni-primary,
+	primary-disable: $uni-primary-disable,
+	primary-light: $uni-primary-light,
+	// 辅助色
+	success: $uni-success,
+	success-disable: $uni-success-disable,
+	success-light: $uni-success-light,
+	warning: $uni-warning,
+	warning-disable: $uni-warning-disable,
+	warning-light: $uni-warning-light,
+	error: $uni-error,
+	error-disable: $uni-error-disable,
+	error-light: $uni-error-light,
+	info: $uni-info,
+	info-disable: $uni-info-disable,
+	info-light: $uni-info-light,
+	// 中性色
+	main-color: $uni-main-color,
+	base-color: $uni-base-color,
+	secondary-color: $uni-secondary-color,
+	extra-color: $uni-extra-color,
+	// 背景色
+	bg-color: $uni-bg-color,
+	// 边框颜色
+	border-1: $uni-border-1,
+	border-2: $uni-border-2,
+	border-3: $uni-border-3,
+	border-4: $uni-border-4,
+	// 黑色
+	black:$uni-black,
+	// 白色
+	white:$uni-white,
+	// 透明
+	transparent:$uni-transparent
+) !default;
+@each $key, $child in $uni-ui-color {
+	.uni-#{"" + $key} {
+		color: $child;
+	}
+	.uni-#{"" + $key}-bg {
+		background-color: $child;
+	}
+}
+.uni-shadow-sm {
+	box-shadow: $uni-shadow-sm;
+}
+.uni-shadow-base {
+	box-shadow: $uni-shadow-base;
+}
+.uni-shadow-lg {
+	box-shadow: $uni-shadow-lg;
+}
+.uni-mask {
+	background-color:$uni-mask;
+}
diff --git a/uni_modules/uni-scss/styles/setting/_radius.scss b/uni_modules/uni-scss/styles/setting/_radius.scss
new file mode 100644
index 0000000..9a0428b
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_radius.scss
@@ -0,0 +1,55 @@
+@mixin radius($r,$d:null ,$important: false){
+  $radius-value:map-get($uni-radius, $r) if($important, !important, null);
+  // Key exists within the $uni-radius variable
+  @if (map-has-key($uni-radius, $r) and  $d){
+		@if $d == t {
+				border-top-left-radius:$radius-value;
+				border-top-right-radius:$radius-value;
+		}@else if $d == r {
+				border-top-right-radius:$radius-value;
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == b {
+				border-bottom-left-radius:$radius-value;
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == l {
+				border-top-left-radius:$radius-value;
+				border-bottom-left-radius:$radius-value;
+		}@else if $d == tl {
+				border-top-left-radius:$radius-value;
+		}@else if $d == tr {
+				border-top-right-radius:$radius-value;
+		}@else if $d == br {
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == bl {
+				border-bottom-left-radius:$radius-value;
+		}
+  }@else{
+		border-radius:$radius-value;
+  }
+}
+
+@each $key, $child in $uni-radius {
+	@if($key){
+		.uni-radius-#{"" + $key} {
+				@include radius($key)
+		}
+	}@else{
+		.uni-radius {
+				@include radius($key)
+		}
+	}
+}
+
+@each $direction in t, r, b, l,tl, tr, br, bl {
+	@each $key, $child in $uni-radius {
+		@if($key){
+			.uni-radius-#{"" + $direction}-#{"" + $key} {
+				@include radius($key,$direction,false)
+			}
+		}@else{
+			.uni-radius-#{$direction} {
+				@include radius($key,$direction,false)
+			}
+		}
+	}
+}
diff --git a/uni_modules/uni-scss/styles/setting/_space.scss b/uni_modules/uni-scss/styles/setting/_space.scss
new file mode 100644
index 0000000..3c89528
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_space.scss
@@ -0,0 +1,56 @@
+
+@mixin fn($space,$direction,$size,$n) {
+	@if $n {
+		#{$space}-#{$direction}: #{$size*$uni-space-root}px
+	} @else {
+		 #{$space}-#{$direction}: #{-$size*$uni-space-root}px
+	}
+}
+@mixin get-styles($direction,$i,$space,$n){
+	@if $direction == t {
+		@include fn($space, top,$i,$n);
+	} 
+	@if $direction == r {
+		@include fn($space, right,$i,$n);
+	} 
+	@if $direction == b {
+		@include fn($space, bottom,$i,$n);
+	} 
+	@if $direction == l {
+	 @include fn($space, left,$i,$n);
+	} 
+	@if $direction == x {
+		@include fn($space, left,$i,$n);
+		@include fn($space, right,$i,$n);
+	} 
+	@if $direction == y {
+		@include fn($space, top,$i,$n);
+		@include fn($space, bottom,$i,$n);
+	} 
+	@if $direction == a {
+		@if $n {
+			#{$space}:#{$i*$uni-space-root}px;
+		} @else {
+			#{$space}:#{-$i*$uni-space-root}px;
+		}
+	} 
+}
+
+@each $orientation in m,p {
+	$space: margin;
+	@if $orientation == m {
+		$space: margin;
+	} @else {
+		$space: padding;
+	}
+	@for $i from 0 through 16 {
+		@each $direction in t, r, b, l, x, y, a {
+			.uni-#{$orientation}#{$direction}-#{$i} { 
+				@include  get-styles($direction,$i,$space,true);
+			} 
+			.uni-#{$orientation}#{$direction}-n#{$i} { 
+				@include  get-styles($direction,$i,$space,false);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_styles.scss b/uni_modules/uni-scss/styles/setting/_styles.scss
new file mode 100644
index 0000000..689afec
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_styles.scss
@@ -0,0 +1,167 @@
+/* #ifndef APP-NVUE */
+
+$-color-white:#fff;
+$-color-black:#000;
+@mixin base-style($color) {
+	color: #fff;
+	background-color: $color;
+	border-color: mix($-color-black, $color, 8%);
+	&:not([hover-class]):active {
+		background: mix($-color-black, $color, 10%);
+		border-color: mix($-color-black, $color, 20%);
+		color: $-color-white;
+		outline: none;
+	}
+}
+@mixin is-color($color) {
+	@include base-style($color);
+	&[loading] {
+		@include base-style($color);
+		&::before {
+			margin-right:5px;
+		}
+	}
+	&[disabled] {
+	  &,
+		&[loading],
+	  &:not([hover-class]):active {
+	    color: $-color-white;
+			border-color: mix(darken($color,10%), $-color-white);
+	    background-color: mix($color, $-color-white);
+	  }
+	}
+
+}
+@mixin base-plain-style($color) {
+	color:$color;
+	background-color: mix($-color-white, $color, 90%);
+	border-color: mix($-color-white, $color, 70%);
+	&:not([hover-class]):active {
+	  background: mix($-color-white, $color, 80%);
+	  color: $color;
+	  outline: none;
+		border-color: mix($-color-white, $color, 50%);
+	}
+}
+@mixin is-plain($color){
+	&[plain] {
+		@include base-plain-style($color);
+		&[loading] {
+			@include base-plain-style($color);
+			&::before {
+				margin-right:5px;
+			}
+		}
+		&[disabled] {
+		  &,
+		  &:active {
+		    color: mix($-color-white, $color, 40%);
+		    background-color: mix($-color-white, $color, 90%);
+				border-color: mix($-color-white, $color, 80%);
+		  }
+		}
+	}
+}
+
+
+.uni-btn {
+	margin: 5px;
+	color: #393939;
+	border:1px solid #ccc;
+	font-size: 16px;
+	font-weight: 200;
+	background-color: #F9F9F9;
+	// TODO 暂时处理边框隐藏一边的问题
+	overflow: visible;
+	&::after{
+		border: none;
+	}
+
+	&:not([type]),&[type=default] {
+		color: #999;
+		&[loading] {
+			background: none;
+			&::before {
+				margin-right:5px;
+			}
+		}
+
+
+
+		&[disabled]{
+			color: mix($-color-white, #999, 60%);
+		  &,
+			&[loading],
+		  &:active {
+				color: mix($-color-white, #999, 60%);
+		    background-color: mix($-color-white,$-color-black , 98%);
+				border-color: mix($-color-white,  #999, 85%);
+		  }
+		}
+
+		&[plain] {
+			color: #999;
+			background: none;
+			border-color: $uni-border-1;
+			&:not([hover-class]):active {
+				background: none;
+			  color: mix($-color-white, $-color-black, 80%);
+				border-color: mix($-color-white, $-color-black, 90%);
+			  outline: none;
+			}
+			&[disabled]{
+			  &,
+				&[loading],
+			  &:active {
+			    background: none;
+					color: mix($-color-white, #999, 60%);
+					border-color: mix($-color-white,  #999, 85%);
+			  }
+			}
+		}
+	}
+
+	&:not([hover-class]):active {
+	  color: mix($-color-white, $-color-black, 50%);
+	}
+
+	&[size=mini] {
+		font-size: 16px;
+		font-weight: 200;
+		border-radius: 8px;
+	}
+
+
+
+	&.uni-btn-small {
+		font-size: 14px;
+	}
+	&.uni-btn-mini {
+		font-size: 12px;
+	}
+
+	&.uni-btn-radius {
+		border-radius: 999px;
+	}
+	&[type=primary] {
+		@include is-color($uni-primary);
+		@include is-plain($uni-primary)
+	}
+	&[type=success] {
+		@include is-color($uni-success);
+		@include is-plain($uni-success)
+	}
+	&[type=error] {
+		@include is-color($uni-error);
+		@include is-plain($uni-error)
+	}
+	&[type=warning] {
+		@include is-color($uni-warning);
+		@include is-plain($uni-warning)
+	}
+	&[type=info] {
+		@include is-color($uni-info);
+		@include is-plain($uni-info)
+	}
+}
+/* #endif */
diff --git a/uni_modules/uni-scss/styles/setting/_text.scss b/uni_modules/uni-scss/styles/setting/_text.scss
new file mode 100644
index 0000000..a34d08f
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_text.scss
@@ -0,0 +1,24 @@
+@mixin get-styles($k,$c) {
+	@if $k == size or $k == weight{
+		font-#{$k}:#{$c}
+	}@else{
+		#{$k}:#{$c}
+	}
+}
+
+@each $key, $child in $uni-headings {
+	/* #ifndef APP-NVUE */
+	.uni-#{$key} {
+		@each $k, $c in $child {
+			@include get-styles($k,$c)
+		}
+	}
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	.container .uni-#{$key} {
+		@each $k, $c in $child {
+			@include get-styles($k,$c)
+		}
+	}
+	/* #endif */
+}
diff --git a/uni_modules/uni-scss/styles/setting/_variables.scss b/uni_modules/uni-scss/styles/setting/_variables.scss
new file mode 100644
index 0000000..557d3d7
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_variables.scss
@@ -0,0 +1,146 @@
+// @use "sass:math";
+@import  '../tools/functions.scss';
+// 间距基础倍数
+$uni-space-root: 2 !default;
+// 边框半径默认值
+$uni-radius-root:5px !default;
+$uni-radius: () !default;
+// 边框半径断点
+$uni-radius: map-deep-merge(
+  (
+    0: 0,
+		// TODO 当前版本暂时不支持 sm 属性
+    // 'sm': math.div($uni-radius-root, 2),
+    null: $uni-radius-root,
+    'lg': $uni-radius-root * 2,
+    'xl': $uni-radius-root * 6,
+    'pill': 9999px,
+    'circle': 50%
+  ),
+  $uni-radius
+);
+// 字体家族
+$body-font-family: 'Roboto', sans-serif !default;
+// 文本
+$heading-font-family: $body-font-family !default;
+$uni-headings: () !default;
+$letterSpacing: -0.01562em;
+$uni-headings: map-deep-merge(
+  (
+    'h1': (
+      size: 32px,
+			weight: 300,
+			line-height: 50px,
+			// letter-spacing:-0.01562em
+    ),
+    'h2': (
+      size: 28px,
+      weight: 300,
+      line-height: 40px,
+      // letter-spacing: -0.00833em
+    ),
+    'h3': (
+      size: 24px,
+      weight: 400,
+      line-height: 32px,
+      // letter-spacing: normal
+    ),
+    'h4': (
+      size: 20px,
+      weight: 400,
+      line-height: 30px,
+      // letter-spacing: 0.00735em
+    ),
+    'h5': (
+      size: 16px,
+      weight: 400,
+      line-height: 24px,
+      // letter-spacing: normal
+    ),
+    'h6': (
+      size: 14px,
+      weight: 500,
+      line-height: 18px,
+      // letter-spacing: 0.0125em
+    ),
+    'subtitle': (
+      size: 12px,
+      weight: 400,
+      line-height: 20px,
+      // letter-spacing: 0.00937em
+    ),
+    'body': (
+      font-size: 14px,
+			font-weight: 400,
+			line-height: 22px,
+			// letter-spacing: 0.03125em
+    ),
+    'caption': (
+      'size': 12px,
+      'weight': 400,
+      'line-height': 20px,
+      // 'letter-spacing': 0.03333em,
+      // 'text-transform': false
+    )
+  ),
+  $uni-headings
+);
+
+
+
+// 主色
+$uni-primary: #2979ff !default;
+$uni-primary-disable:lighten($uni-primary,20%) !default;
+$uni-primary-light: lighten($uni-primary,25%) !default;
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37 !default;
+$uni-success-disable:lighten($uni-success,20%) !default;
+$uni-success-light: lighten($uni-success,25%) !default;
+
+$uni-warning: #f3a73f !default;
+$uni-warning-disable:lighten($uni-warning,20%) !default;
+$uni-warning-light: lighten($uni-warning,25%) !default;
+
+$uni-error: #e43d33 !default;
+$uni-error-disable:lighten($uni-error,20%) !default;
+$uni-error-light: lighten($uni-error,25%) !default;
+
+$uni-info: #8f939c !default;
+$uni-info-disable:lighten($uni-info,20%) !default;
+$uni-info-light: lighten($uni-info,25%) !default;
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a !default; 			// 主要文字
+$uni-base-color: #6a6a6a !default;			// 常规文字
+$uni-secondary-color: #909399 !default;	// 次要文字
+$uni-extra-color: #c7c7c7 !default;			// 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0 !default;
+$uni-border-2: #EDEDED !default;
+$uni-border-3: #DCDCDC !default;
+$uni-border-4: #B9B9B9 !default;
+
+// 常规色
+$uni-black: #000000 !default;
+$uni-white: #ffffff !default;
+$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
+
+// 背景色
+$uni-bg-color: #f7f7f7 !default;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px !default;
+$uni-spacing-base: 15px !default;
+$uni-spacing-lg: 30px !default;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
diff --git a/uni_modules/uni-scss/styles/tools/functions.scss b/uni_modules/uni-scss/styles/tools/functions.scss
new file mode 100644
index 0000000..ac6f63e
--- /dev/null
+++ b/uni_modules/uni-scss/styles/tools/functions.scss
@@ -0,0 +1,19 @@
+// 合并 map
+@function map-deep-merge($parent-map, $child-map){
+	$result: $parent-map;
+	@each $key, $child in $child-map {
+		$parent-has-key: map-has-key($result, $key);
+		$parent-value: map-get($result, $key);
+		$parent-type: type-of($parent-value);
+		$child-type: type-of($child);
+		$parent-is-map: $parent-type == map;
+		$child-is-map: $child-type == map;
+			
+		@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
+			$result: map-merge($result, ( $key: $child ));
+		}@else {
+			$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
+		}
+	}
+	@return $result;
+};
diff --git a/uni_modules/uni-scss/theme.scss b/uni_modules/uni-scss/theme.scss
new file mode 100644
index 0000000..80ee62f
--- /dev/null
+++ b/uni_modules/uni-scss/theme.scss
@@ -0,0 +1,31 @@
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+// 主色
+$uni-primary: #2979ff;
+// 辅助色
+$uni-success: #4cd964;
+// 警告色
+$uni-warning: #f0ad4e;
+// 错误色
+$uni-error: #dd524d;
+// 描述色
+$uni-info: #909399;
+// 中性色
+$uni-main-color: #303133;
+$uni-base-color: #606266;
+$uni-secondary-color: #909399;
+$uni-extra-color: #C0C4CC;
+// 背景色
+$uni-bg-color: #f5f5f5;
+// 边框颜色
+$uni-border-1: #DCDFE6;
+$uni-border-2: #E4E7ED;
+$uni-border-3: #EBEEF5;
+$uni-border-4: #F2F6FC;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
diff --git a/uni_modules/uni-scss/variables.scss b/uni_modules/uni-scss/variables.scss
new file mode 100644
index 0000000..1c062d4
--- /dev/null
+++ b/uni_modules/uni-scss/variables.scss
@@ -0,0 +1,62 @@
+@import './styles/setting/_variables.scss';
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+
+// 主色
+$uni-primary: #2979ff;
+$uni-primary-disable:mix(#fff,$uni-primary,50%);
+$uni-primary-light: mix(#fff,$uni-primary,80%);
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37;
+$uni-success-disable:mix(#fff,$uni-success,50%);
+$uni-success-light: mix(#fff,$uni-success,80%);
+
+$uni-warning: #f3a73f;
+$uni-warning-disable:mix(#fff,$uni-warning,50%);
+$uni-warning-light: mix(#fff,$uni-warning,80%);
+
+$uni-error: #e43d33;
+$uni-error-disable:mix(#fff,$uni-error,50%);
+$uni-error-light: mix(#fff,$uni-error,80%);
+
+$uni-info: #8f939c;
+$uni-info-disable:mix(#fff,$uni-info,50%);
+$uni-info-light: mix(#fff,$uni-info,80%);
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a; 			// 主要文字
+$uni-base-color: #6a6a6a;			// 常规文字
+$uni-secondary-color: #909399;	// 次要文字
+$uni-extra-color: #c7c7c7;			// 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0;
+$uni-border-2: #EDEDED;
+$uni-border-3: #DCDCDC;
+$uni-border-4: #B9B9B9;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
+
+// 背景色
+$uni-bg-color: #f7f7f7;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px;
+$uni-spacing-base: 15px;
+$uni-spacing-lg: 30px;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4);
diff --git a/uni_modules/uni-search-bar/changelog.md b/uni_modules/uni-search-bar/changelog.md
new file mode 100644
index 0000000..2c6571c
--- /dev/null
+++ b/uni_modules/uni-search-bar/changelog.md
@@ -0,0 +1,47 @@
+## 1.3.0(2024-04-22)
+- 修复 textColor默认值导致的文字不显示的bug
+## 1.2.9(2024-04-17)
+- 修复 textColor不生效的bug
+## 1.2.8(2024-02-22)
+- 修复 清空按钮emit值错误的bug
+## 1.2.7(2024-02-21)
+- 新增 设置输入框字体颜色:textColor
+## 1.2.6(2024-02-20)
+- 修复 uni-search-bar在支付宝小程序下样式兼容问题
+## 1.2.5(2024-01-31)
+- 修复 uni-search-bar居中问题,现在默认居左,并修复样式偏移问题
+## 1.2.4(2023-05-09)
+- 修复 i18n 国际化不正确的 Bug
+## 1.2.3(2022-05-24)
+- 新增 readonly 属性,组件只读
+## 1.2.2(2022-05-06)
+- 修复  vue3 input 事件不生效的bug
+## 1.2.1(2022-05-06)
+- 修复 多余代码导致的bug
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-search-bar](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
+## 1.1.2(2021-08-30)
+- 修复 value 属性与 modelValue 属性不兼容的Bug
+## 1.1.1(2021-08-24)
+- 新增 支持国际化
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.9(2021-05-12)
+- 新增 项目示例地址
+## 1.0.8(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.7(2021-04-15)
+- uni-ui 新增 uni-search-bar 的 focus 事件
+
+## 1.0.6(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持双向绑定
+- 更改 input 事件的返回值,e={value:Number} --> e=value
+- 新增 支持图标插槽
+- 新增 支持 clear、blur 事件
+- 新增 支持 focus 属性
+- 去掉组件背景色
diff --git a/uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json
new file mode 100644
index 0000000..dd083a5
--- /dev/null
+++ b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json
@@ -0,0 +1,4 @@
+{
+	"uni-search-bar.cancel": "cancel",
+	"uni-search-bar.placeholder": "Search enter content"
+}
\ No newline at end of file
diff --git a/uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json
new file mode 100644
index 0000000..d2a1ced
--- /dev/null
+++ b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json
@@ -0,0 +1,4 @@
+{
+	"uni-search-bar.cancel": "取消",
+	"uni-search-bar.placeholder": "请输入搜索内容"
+}
diff --git a/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json
new file mode 100644
index 0000000..f1c96bc
--- /dev/null
+++ b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json
@@ -0,0 +1,4 @@
+{
+	"uni-search-bar.cancel": "取消",
+	"uni-search-bar.placeholder": "請輸入搜索內容"
+}
diff --git a/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue b/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue
new file mode 100644
index 0000000..6b9b9c1
--- /dev/null
+++ b/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue
@@ -0,0 +1,309 @@
+<template>
+	<view class="uni-searchbar">
+		<view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box"
+			@click="searchClick">
+			<view class="uni-searchbar__box-icon-search">
+				<slot name="searchIcon">
+					<uni-icons color="#c0c4cc" size="18" type="search" />
+				</slot>
+			</view>
+			<input v-if="show || searchVal" :focus="showSync" :disabled="readonly" :placeholder="placeholderText" :maxlength="maxlength"
+				class="uni-searchbar__box-search-input" confirm-type="search" type="text" v-model="searchVal" :style="{color:textColor}"
+				@confirm="confirm" @blur="blur" @focus="emitFocus"/>
+			<text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
+			<view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='') &&!readonly"
+				class="uni-searchbar__box-icon-clear" @click="clear">
+				<slot name="clearIcon">
+					<uni-icons color="#c0c4cc" size="20" type="clear" />
+				</slot>
+			</view>
+		</view>
+		<text @click="cancel" class="uni-searchbar__cancel"
+			v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelTextI18n}}</text>
+	</view>
+</template>
+
+<script>
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(messages)
+
+	/**
+	 * SearchBar 搜索栏
+	 * @description 搜索栏组件,通常用于搜索商品、文章等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=866
+	 * @property {Number} radius 搜索栏圆角
+	 * @property {Number} maxlength 输入最大长度
+	 * @property {String} placeholder 搜索栏Placeholder
+	 * @property {String} clearButton = [always|auto|none] 是否显示清除按钮
+	 * 	@value always 一直显示
+	 * 	@value auto 输入框不为空时显示
+	 * 	@value none 一直不显示
+	 * @property {String} cancelButton = [always|auto|none] 是否显示取消按钮
+	 * 	@value always 一直显示
+	 * 	@value auto 输入框不为空时显示
+	 * 	@value none 一直不显示
+	 * @property {String} cancelText 取消按钮的文字
+	 * @property {String} bgColor 输入框背景颜色
+	 * @property {String} textColor 输入文字颜色
+	 * @property {Boolean} focus 是否自动聚焦
+	 * @property {Boolean} readonly 组件只读,不能有任何操作,只做展示
+	 * @event {Function} confirm uniSearchBar 的输入框 confirm 事件,返回参数为uniSearchBar的value,e={value:Number}
+	 * @event {Function} input uniSearchBar 的 value 改变时触发事件,返回参数为uniSearchBar的value,e=value
+	 * @event {Function} cancel 点击取消按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
+	 * @event {Function} clear 点击清除按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
+	 * @event {Function} blur input失去焦点时触发事件,返回参数为uniSearchBar的value,e={value:Number}
+	 */
+
+	export default {
+		name: "UniSearchBar",
+		emits: ['input', 'update:modelValue', 'clear', 'cancel', 'confirm', 'blur', 'focus'],
+		props: {
+			placeholder: {
+				type: String,
+				default: ""
+			},
+			radius: {
+				type: [Number, String],
+				default: 5
+			},
+			clearButton: {
+				type: String,
+				default: "auto"
+			},
+			cancelButton: {
+				type: String,
+				default: "auto"
+			},
+			cancelText: {
+				type: String,
+				default: ""
+			},
+			bgColor: {
+				type: String,
+				default: "#F8F8F8"
+			},
+			textColor: {
+				type: String,
+				default: "#000000"
+			},
+			maxlength: {
+				type: [Number, String],
+				default: 100
+			},
+			value: {
+				type: [Number, String],
+				default: ""
+			},
+			modelValue: {
+				type: [Number, String],
+				default: ""
+			},
+			focus: {
+				type: Boolean,
+				default: false
+			},
+			readonly: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				show: false,
+				showSync: false,
+				searchVal: ''
+			}
+		},
+		computed: {
+			cancelTextI18n() {
+				return this.cancelText || t("uni-search-bar.cancel")
+			},
+			placeholderText() {
+				return this.placeholder || t("uni-search-bar.placeholder")
+			}
+		},
+		watch: {
+			// #ifndef VUE3
+			value: {
+				immediate: true,
+				handler(newVal) {
+					this.searchVal = newVal
+					if (newVal) {
+						this.show = true
+					}
+				}
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				immediate: true,
+				handler(newVal) {
+					this.searchVal = newVal
+					if (newVal) {
+						this.show = true
+					}
+				}
+			},
+			// #endif
+			focus: {
+				immediate: true,
+				handler(newVal) {
+					if (newVal) {
+						if(this.readonly) return
+						this.show = true;
+						this.$nextTick(() => {
+							this.showSync = true
+						})
+					}
+				}
+			},
+			searchVal(newVal, oldVal) {
+				this.$emit("input", newVal)
+				// #ifdef VUE3
+				this.$emit("update:modelValue", newVal)
+				// #endif
+			}
+		},
+		methods: {
+			searchClick() {
+				if(this.readonly) return
+				if (this.show) {
+					return
+				}
+				this.show = true;
+				this.$nextTick(() => {
+					this.showSync = true
+				})
+			},
+			clear() {
+				this.searchVal = ""
+				this.$nextTick(() => {
+					this.$emit("clear", { value: "" })
+				})
+			},
+			cancel() {
+				if(this.readonly) return
+				this.$emit("cancel", {
+					value: this.searchVal
+				});
+				this.searchVal = ""
+				this.show = false
+				this.showSync = false
+				// #ifndef APP-PLUS
+				uni.hideKeyboard()
+				// #endif
+				// #ifdef APP-PLUS
+				plus.key.hideSoftKeybord()
+				// #endif
+			},
+			confirm() {
+				// #ifndef APP-PLUS
+				uni.hideKeyboard();
+				// #endif
+				// #ifdef APP-PLUS
+				plus.key.hideSoftKeybord()
+				// #endif
+				this.$emit("confirm", {
+					value: this.searchVal
+				})
+			},
+			blur() {
+				// #ifndef APP-PLUS
+				uni.hideKeyboard();
+				// #endif
+				// #ifdef APP-PLUS
+				plus.key.hideSoftKeybord()
+				// #endif
+				this.$emit("blur", {
+					value: this.searchVal
+				})
+			},
+			emitFocus(e) {
+				this.$emit("focus", e.detail)
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	$uni-searchbar-height: 36px;
+
+	.uni-searchbar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		position: relative;
+		padding: 10px;
+		// background-color: #fff;
+	}
+
+	.uni-searchbar__box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		justify-content: left;
+		/* #endif */
+		overflow: hidden;
+		position: relative;
+		flex: 1;
+		flex-direction: row;
+		align-items: center;
+		height: $uni-searchbar-height;
+		padding: 5px 8px 5px 0px;
+	}
+
+	.uni-searchbar__box-icon-search {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		// width: 32px;
+		padding: 0 8px;
+		justify-content: center;
+		align-items: center;
+		color: #B3B3B3;
+	}
+
+	.uni-searchbar__box-search-input {
+		flex: 1;
+		font-size: 14px;
+		color: #333;
+		margin-left: 5px;
+		margin-top: 1px;
+		/* #ifndef APP-NVUE */
+		background-color: inherit;
+		/* #endif */
+	}
+
+	.uni-searchbar__box-icon-clear {
+		align-items: center;
+		line-height: 24px;
+		padding-left: 8px;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-searchbar__text-placeholder {
+		font-size: 14px;
+		color: #B3B3B3;
+		margin-left: 5px;
+		text-align: left;
+	}
+
+	.uni-searchbar__cancel {
+		padding-left: 10px;
+		line-height: $uni-searchbar-height;
+		font-size: 14px;
+		color: #333333;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+</style>
diff --git a/uni_modules/uni-search-bar/package.json b/uni_modules/uni-search-bar/package.json
new file mode 100644
index 0000000..1730d9d
--- /dev/null
+++ b/uni_modules/uni-search-bar/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-search-bar",
+  "displayName": "uni-search-bar 搜索栏",
+  "version": "1.3.0",
+  "description": "搜索栏组件,通常用于搜索商品、文章等",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "搜索框",
+    "搜索栏"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-search-bar/readme.md b/uni_modules/uni-search-bar/readme.md
new file mode 100644
index 0000000..253092f
--- /dev/null
+++ b/uni_modules/uni-search-bar/readme.md
@@ -0,0 +1,14 @@
+
+
+## SearchBar 搜索栏
+
+> **组件名:uni-search-bar**
+> 代码块: `uSearchBar`
+
+
+搜索栏组件
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-section/changelog.md b/uni_modules/uni-section/changelog.md
new file mode 100644
index 0000000..738f2b3
--- /dev/null
+++ b/uni_modules/uni-section/changelog.md
@@ -0,0 +1,2 @@
+## 0.0.1(2022-07-22)
+- 初始化
diff --git a/uni_modules/uni-section/components/uni-section/uni-section.vue b/uni_modules/uni-section/components/uni-section/uni-section.vue
new file mode 100644
index 0000000..9a52e0b
--- /dev/null
+++ b/uni_modules/uni-section/components/uni-section/uni-section.vue
@@ -0,0 +1,167 @@
+<template>
+	<view class="uni-section">
+		<view class="uni-section-header" @click="onClick">
+				<view class="uni-section-header__decoration" v-if="type" :class="type" />
+        <slot v-else name="decoration"></slot>
+
+        <view class="uni-section-header__content">
+          <text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
+          <text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
+        </view>
+
+        <view class="uni-section-header__slot-right">
+          <slot name="right"></slot>
+        </view>
+		</view>
+
+		<view class="uni-section-content" :style="{padding: _padding}">
+			<slot />
+		</view>
+	</view>
+</template>
+
+<script>
+
+	/**
+	 * Section 标题栏
+	 * @description 标题栏
+	 * @property {String} type = [line|circle|square] 标题装饰类型
+	 * 	@value line 竖线
+	 * 	@value circle 圆形
+	 * 	@value square 正方形
+	 * @property {String} title 主标题
+	 * @property {String} titleFontSize 主标题字体大小
+	 * @property {String} titleColor 主标题字体颜色
+	 * @property {String} subTitle 副标题
+	 * @property {String} subTitleFontSize 副标题字体大小
+	 * @property {String} subTitleColor 副标题字体颜色
+	 * @property {String} padding 默认插槽 padding
+	 */
+
+	export default {
+		name: 'UniSection',
+    emits:['click'],
+		props: {
+			type: {
+				type: String,
+				default: ''
+			},
+			title: {
+				type: String,
+				required: true,
+				default: ''
+			},
+      titleFontSize: {
+        type: String,
+        default: '14px'
+      },
+			titleColor:{
+				type: String,
+				default: '#333'
+			},
+			subTitle: {
+				type: String,
+				default: ''
+			},
+      subTitleFontSize: {
+        type: String,
+        default: '12px'
+      },
+      subTitleColor: {
+        type: String,
+        default: '#999'
+      },
+			padding: {
+				type: [Boolean, String],
+				default: false
+			}
+		},
+    computed:{
+      _padding(){
+        if(typeof this.padding === 'string'){
+          return this.padding
+        }
+
+        return this.padding?'10px':''
+      }
+    },
+		watch: {
+			title(newVal) {
+				if (uni.report && newVal !== '') {
+					uni.report('title', newVal)
+				}
+			}
+		},
+    methods: {
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	$uni-primary: #2979ff !default;
+
+	.uni-section {
+		background-color: #fff;
+    .uni-section-header {
+      position: relative;
+      /* #ifndef APP-NVUE */
+      display: flex;
+      /* #endif */
+      flex-direction: row;
+      align-items: center;
+      padding: 12px 10px;
+      font-weight: normal;
+
+      &__decoration{
+        margin-right: 6px;
+        background-color: $uni-primary;
+        &.line {
+          width: 4px;
+          height: 12px;
+          border-radius: 10px;
+        }
+
+        &.circle {
+          width: 8px;
+          height: 8px;
+          border-top-right-radius: 50px;
+          border-top-left-radius: 50px;
+          border-bottom-left-radius: 50px;
+          border-bottom-right-radius: 50px;
+        }
+
+        &.square {
+          width: 8px;
+          height: 8px;
+        }
+      }
+
+      &__content {
+        /* #ifndef APP-NVUE */
+        display: flex;
+        /* #endif */
+        flex-direction: column;
+        flex: 1;
+        color: #333;
+
+        .distraction {
+          flex-direction: row;
+          align-items: center;
+        }
+        &-sub {
+          margin-top: 2px;
+        }
+      }
+
+      &__slot-right{
+        font-size: 14px;
+      }
+    }
+
+    .uni-section-content{
+      font-size: 14px;
+    }
+	}
+</style>
diff --git a/uni_modules/uni-section/package.json b/uni_modules/uni-section/package.json
new file mode 100644
index 0000000..0a31fb5
--- /dev/null
+++ b/uni_modules/uni-section/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-section",
+  "displayName": "uni-section 标题栏",
+  "version": "0.0.1",
+  "description": "标题栏组件",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "标题栏"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+      "uni-scss"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-section/readme.md b/uni_modules/uni-section/readme.md
new file mode 100644
index 0000000..d47faab
--- /dev/null
+++ b/uni_modules/uni-section/readme.md
@@ -0,0 +1,8 @@
+## Section 标题栏
+> **组件名:uni-section**
+> 代码块: `uSection`
+
+uni-section 组件主要用于文章、列表详情等标题展示
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-section)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
diff --git a/uni_modules/uni-segmented-control/changelog.md b/uni_modules/uni-segmented-control/changelog.md
new file mode 100644
index 0000000..02d0c8a
--- /dev/null
+++ b/uni_modules/uni-segmented-control/changelog.md
@@ -0,0 +1,15 @@
+## 1.2.3(2024-04-02)
+- 修复 修复在微信小程序下inactiveColor失效bug
+## 1.2.2(2024-03-28)
+- 修复 在vue2下:style动态绑定导致编译失败的bug
+## 1.2.1(2024-03-20)
+- 新增 inActiveColor属性,可供配置未激活时的颜色
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-segmented-control](https://uniapp.dcloud.io/component/uniui/uni-segmented-control)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.5(2021-05-12)
+- 新增 项目示例地址
+## 1.0.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue b/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue
new file mode 100644
index 0000000..a69366a
--- /dev/null
+++ b/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue
@@ -0,0 +1,146 @@
+<template>
+	<view :class="[styleType === 'text'?'segmented-control--text' : 'segmented-control--button' ]"
+		:style="{ borderColor: styleType === 'text' ? '' : activeColor }" class="segmented-control">
+		<view v-for="(item, index) in values" :class="[styleType === 'text' ? '' : 'segmented-control__item--button',
+					index === 0 && styleType === 'button' ? 'segmented-control__item--button--first' : '',
+					index === values.length - 1 && styleType === 'button' ? 'segmented-control__item--button--last':'']" :key="index"
+			:style="{backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : styleType === 'button' ?inActiveColor:'transparent', borderColor: index === currentIndex && styleType === 'text' || styleType === 'button' ? activeColor : inActiveColor}"
+			class="segmented-control__item" @click="_onClick(index)">
+			<view>
+				<text
+					:style="{color:index === currentIndex? styleType === 'text'? activeColor: '#fff': styleType === 'text'? '#000': activeColor}"
+					class="segmented-control__text"
+					:class="styleType === 'text' && index === currentIndex ? 'segmented-control__item--text': ''">{{ item }}</text>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * SegmentedControl 分段器
+	 * @description 用作不同视图的显示
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=54
+	 * @property {Number} current 当前选中的tab索引值,从0计数
+	 * @property {String} styleType = [button|text] 分段器样式类型
+	 * 	@value button 按钮类型
+	 * 	@value text 文字类型
+	 * @property {String} activeColor 选中的标签背景色与边框颜色
+	 * @property {String} inActiveColor 未选中的标签背景色与边框颜色
+	 * @property {Array} values 选项数组
+	 * @event {Function} clickItem 组件触发点击事件时触发,e={currentIndex}
+	 */
+
+	export default {
+		name: 'UniSegmentedControl',
+		emits: ['clickItem'],
+		props: {
+			current: {
+				type: Number,
+				default: 0
+			},
+			values: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			activeColor: {
+				type: String,
+				default: '#2979FF'
+			},
+			inActiveColor: {
+				type: String,
+				default: 'transparent'
+			},
+			styleType: {
+				type: String,
+				default: 'button'
+			}
+		},
+		data() {
+			return {
+				currentIndex: 0
+			}
+		},
+		watch: {
+			current(val) {
+				if (val !== this.currentIndex) {
+					this.currentIndex = val
+				}
+			}
+		},
+		computed: {},
+		created() {
+			this.currentIndex = this.current
+		},
+		methods: {
+			_onClick(index) {
+				if (this.currentIndex !== index) {
+					this.currentIndex = index
+					this.$emit('clickItem', {
+						currentIndex: index
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.segmented-control {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+		height: 36px;
+		overflow: hidden;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.segmented-control__item {
+		/* #ifndef APP-NVUE */
+		display: inline-flex;
+		box-sizing: border-box;
+		/* #endif */
+		position: relative;
+		flex: 1;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.segmented-control__item--button {
+		border-style: solid;
+		border-top-width: 1px;
+		border-bottom-width: 1px;
+		border-right-width: 1px;
+		border-left-width: 0;
+	}
+
+	.segmented-control__item--button--first {
+		border-left-width: 1px;
+		border-top-left-radius: 5px;
+		border-bottom-left-radius: 5px;
+	}
+
+	.segmented-control__item--button--last {
+		border-top-right-radius: 5px;
+		border-bottom-right-radius: 5px;
+	}
+
+	.segmented-control__item--text {
+		border-bottom-style: solid;
+		border-bottom-width: 2px;
+		padding: 6px 0;
+	}
+
+	.segmented-control__text {
+		font-size: 14px;
+		line-height: 20px;
+		text-align: center;
+	}
+</style>
diff --git a/uni_modules/uni-segmented-control/package.json b/uni_modules/uni-segmented-control/package.json
new file mode 100644
index 0000000..49f9eff
--- /dev/null
+++ b/uni_modules/uni-segmented-control/package.json
@@ -0,0 +1,85 @@
+{
+  "id": "uni-segmented-control",
+  "displayName": "uni-segmented-control 分段器",
+  "version": "1.2.3",
+  "description": "分段器由至少 2 个分段控件组成,用作不同视图的显示",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "分段器",
+    "segement",
+    "顶部选择"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-segmented-control/readme.md b/uni_modules/uni-segmented-control/readme.md
new file mode 100644
index 0000000..3527b03
--- /dev/null
+++ b/uni_modules/uni-segmented-control/readme.md
@@ -0,0 +1,13 @@
+
+
+## SegmentedControl 分段器
+> **组件名:uni-segmented-control**
+> 代码块: `uSegmentedControl`
+
+
+用作不同视图的显示
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-segmented-control)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-steps/changelog.md b/uni_modules/uni-steps/changelog.md
new file mode 100644
index 0000000..04367d8
--- /dev/null
+++ b/uni_modules/uni-steps/changelog.md
@@ -0,0 +1,18 @@
+## 1.1.2(2024-03-28)
+- 修复 uni-steps为竖排列时,文本长度过长引起点错乱的bug
+## 1.1.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.1.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-steps](https://uniapp.dcloud.io/component/uniui/uni-steps)
+## 1.0.8(2021-05-12)
+- 新增 项目示例地址
+## 1.0.7(2021-05-06)
+- 修复 uni-steps 横向布局时,多行文字高度不合理的 bug
+## 1.0.6(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.5(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-steps/components/uni-steps/uni-steps.vue b/uni_modules/uni-steps/components/uni-steps/uni-steps.vue
new file mode 100644
index 0000000..81017fc
--- /dev/null
+++ b/uni_modules/uni-steps/components/uni-steps/uni-steps.vue
@@ -0,0 +1,280 @@
+<template>
+	<view class="uni-steps">
+		<view :class="[direction==='column'?'uni-steps__column':'uni-steps__row']">
+			<view :class="[direction==='column'?'uni-steps__column-text-container':'uni-steps__row-text-container']">
+				<view v-for="(item,index) in options" :key="index"
+					:class="[direction==='column'?'uni-steps__column-text':'uni-steps__row-text']">
+					<text :style="{color:index === active?activeColor:deactiveColor}"
+						:class="[direction==='column'?'uni-steps__column-title':'uni-steps__row-title']">{{item.title}}</text>
+					<text :style="{color: deactiveColor}"
+						:class="[direction==='column'?'uni-steps__column-desc':'uni-steps__row-desc']">{{item.desc}}</text>
+				</view>
+			</view>
+			<view :class="[direction==='column'?'uni-steps__column-container':'uni-steps__row-container']">
+				<view :class="[direction==='column'?'uni-steps__column-line-item':'uni-steps__row-line-item']"
+					v-for="(item,index) in options" :key="index" :style="{height: direction === 'column'?heightArr[index]+'px':'14px'}">
+					<view
+						:class="[direction==='column'?'uni-steps__column-line':'uni-steps__row-line',direction==='column'?'uni-steps__column-line--before':'uni-steps__row-line--before']"
+						:style="{backgroundColor:index<=active&&index!==0?activeColor:index===0?'transparent':deactiveColor}">
+					</view>
+					<view :class="[direction==='column'?'uni-steps__column-check':'uni-steps__row-check']"
+						v-if="index === active">
+						<uni-icons :color="activeColor" :type="activeIcon" size="14" />
+					</view>
+					<view v-else :class="[direction==='column'?'uni-steps__column-circle':'uni-steps__row-circle']"
+						:style="{backgroundColor:index<active?activeColor:deactiveColor}" />
+					<view
+						:class="[direction==='column'?'uni-steps__column-line':'uni-steps__row-line',direction==='column'?'uni-steps__column-line--after':'uni-steps__row-line--after']"
+						:style="{backgroundColor:index<active&&index!==options.length-1?activeColor:index===options.length-1?'transparent':deactiveColor}" />
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Steps 步骤条
+	 * @description 评分组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=34
+	 * @property {Number} active 当前步骤
+	 * @property {String} direction = [row|column] 当前步骤
+	 * 	@value row 横向
+	 * 	@value column 纵向
+	 * @property {String} activeColor 选中状态的颜色
+	 * @property {Array} options 数据源,格式为:[{title:'xxx',desc:'xxx'},{title:'xxx',desc:'xxx'}]
+	 */
+
+	export default {
+		name: 'UniSteps',
+		props: {
+			direction: {
+				// 排列方向 row column
+				type: String,
+				default: 'row'
+			},
+			activeColor: {
+				// 激活状态颜色
+				type: String,
+				default: '#2979FF'
+			},
+			deactiveColor: {
+				// 未激活状态颜色
+				type: String,
+				default: '#B7BDC6'
+			},
+			active: {
+				// 当前步骤
+				type: Number,
+				default: 0
+			},
+			activeIcon: {
+				// 当前步骤
+				type: String,
+				default: 'checkbox-filled'
+			},
+			options: {
+				type: Array,
+				default () {
+					return []
+				}
+			} // 数据
+		},
+		data() {
+			return {
+				heightArr: [],
+			}
+		},
+		mounted() {
+			//根据内容设置步骤条的长度
+			if (this.direction === 'column') {
+				let that = this;
+				//只能用类选择器,用id选择器所获取的元素信息不准确
+				uni.createSelectorQuery().in(this).selectAll('.uni-steps__column-text').boundingClientRect(data => {
+					that.heightArr = data.map(item => item.height + 1);
+				}).exec()
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #2979ff !default;
+	$uni-border-color: #EDEDED;
+
+	.uni-steps {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		width: 100%;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-steps__row {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-steps__column {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row-reverse;
+	}
+
+	.uni-steps__row-text-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: flex-end;
+		margin-bottom: 8px;
+	}
+
+	.uni-steps__column-text-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		flex: 1;
+	}
+
+	.uni-steps__row-text {
+		/* #ifndef APP-NVUE */
+		display: inline-flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: column;
+	}
+
+	.uni-steps__column-text {
+		padding: 6px 0px;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+		border-bottom-color: $uni-border-color;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-steps__row-title {
+		font-size: 14px;
+		line-height: 16px;
+		text-align: center;
+	}
+
+	.uni-steps__column-title {
+		font-size: 14px;
+		text-align: left;
+		line-height: 18px;
+	}
+
+	.uni-steps__row-desc {
+		font-size: 12px;
+		line-height: 14px;
+		text-align: center;
+	}
+
+	.uni-steps__column-desc {
+		font-size: 12px;
+		text-align: left;
+		line-height: 18px;
+	}
+
+	.uni-steps__row-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-steps__column-container {
+		/* #ifndef APP-NVUE */
+		display: inline-flex;
+		/* #endif */
+		width: 30px;
+		flex-direction: column;
+	}
+
+	.uni-steps__row-line-item {
+		/* #ifndef APP-NVUE */
+		display: inline-flex;
+		/* #endif */
+		flex-direction: row;
+		flex: 1;
+		height: 14px;
+		line-height: 14px;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.uni-steps__column-line-item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.uni-steps__row-line {
+		flex: 1;
+		height: 1px;
+		background-color: #B7BDC6;
+	}
+
+	.uni-steps__column-line {
+		width: 1px;
+		background-color: #B7BDC6;
+	}
+
+	.uni-steps__row-line--after {
+		transform: translateX(1px);
+	}
+
+	.uni-steps__column-line--after {
+		flex: 1;
+		transform: translate(0px, 1px);
+	}
+
+	.uni-steps__row-line--before {
+		transform: translateX(-1px);
+	}
+
+	.uni-steps__column-line--before {
+		height: 6px;
+		transform: translate(0px, -13px);
+	}
+
+	.uni-steps__row-circle {
+		width: 5px;
+		height: 5px;
+		border-radius: 50%;
+		background-color: #B7BDC6;
+		margin: 0px 3px;
+	}
+
+	.uni-steps__column-circle {
+		width: 5px;
+		height: 5px;
+		border-radius: 50%;
+		background-color: #B7BDC6;
+		margin: 4px 0px 5px 0px;
+	}
+
+	.uni-steps__row-check {
+		margin: 0px 6px;
+	}
+
+	.uni-steps__column-check {
+		height: 14px;
+		line-height: 14px;
+		margin: 2px 0px;
+	}
+</style>
diff --git a/uni_modules/uni-steps/package.json b/uni_modules/uni-steps/package.json
new file mode 100644
index 0000000..4145ce9
--- /dev/null
+++ b/uni_modules/uni-steps/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-steps",
+  "displayName": "uni-steps 步骤条",
+  "version": "1.1.2",
+  "description": "步骤条组件,提供横向和纵向两种布局格式。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "步骤条",
+    "时间轴"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-steps/readme.md b/uni_modules/uni-steps/readme.md
new file mode 100644
index 0000000..da7a4bf
--- /dev/null
+++ b/uni_modules/uni-steps/readme.md
@@ -0,0 +1,13 @@
+
+
+## Steps 步骤条
+> **组件名:uni-steps**
+> 代码块: `uSteps`
+
+
+步骤条,常用于显示进度
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-steps)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-swipe-action/changelog.md b/uni_modules/uni-swipe-action/changelog.md
new file mode 100644
index 0000000..e28472f
--- /dev/null
+++ b/uni_modules/uni-swipe-action/changelog.md
@@ -0,0 +1,47 @@
+## 1.3.10(2024-01-17)
+- 修复 点击按钮时,按钮会被点击穿透导致自动收缩的 bug(兼容阿里/百度/抖音小程序)
+## 1.3.9(2024-01-17)
+- 修复 点击按钮时,按钮会被点击穿透导致自动收缩的 bug
+## 1.3.8(2023-04-13)
+- 修复`uni-swipe-action`和`uni-swipe-action-item`不同时使用导致 closeOther 方法报错的 bug
+## 1.3.7(2022-06-06)
+- 修复 vue3 下使用组件不能正常运行的Bug
+## 1.3.6(2022-05-31)
+- 修复 h5端点击click触发两次的Bug
+## 1.3.5(2022-05-23)
+- 修复 isPC 找不到的Bug
+## 1.3.4(2022-05-19)
+-  修复 在 nvue 下 disabled 失效的bug
+## 1.3.3(2022-03-31)
+- 修复 按钮字体大小不能设置的bug
+## 1.3.2(2022-03-16)
+- 修复 h5和app端下报el错误的bug
+## 1.3.1(2022-03-07)
+- 修复 HBuilderX 1.4.X 版本中,h5和app端下报错的bug
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-swipe-action](https://uniapp.dcloud.io/component/uniui/uni-swipe-action)
+## 1.2.4(2021-08-20)
+- 优化 close-all 方法
+## 1.2.3(2021-08-20)
+- 新增 close-all 方法,关闭所有已打开的组件
+## 1.2.2(2021-08-17)
+- 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件
+- 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题 
+- 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
+## 1.2.1(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+- 修复 跨页面修改组件数据 ,导致不能滑动的问题
+## 1.1.10(2021-06-17)
+- 修复 按钮点击执行两次的bug
+## 1.1.9(2021-05-12)
+- 新增 项目示例地址
+## 1.1.8(2021-03-26)
+- 修复 微信小程序 nv_navigator is not defined 报错的bug
+## 1.1.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 左侧滑动
+- 新增 插槽使用方式
+- 新增 threshold 属性,可以控制滑动缺省值
+- 优化 长列表滚动性能
+- 修复 滚动页面时触发组件滑动的Bug
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js
new file mode 100644
index 0000000..707e432
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js
@@ -0,0 +1,302 @@
+let bindIngXMixins = {}
+
+// #ifdef APP-NVUE
+const BindingX = uni.requireNativePlugin('bindingx');
+const dom = uni.requireNativePlugin('dom');
+const animation = uni.requireNativePlugin('animation');
+
+bindIngXMixins = {
+	data() {
+		return {}
+	},
+
+	watch: {
+		show(newVal) {
+			if (this.autoClose) return
+			if (this.stop) return
+			this.stop = true
+			if (newVal) {
+				this.open(newVal)
+			} else {
+				this.close()
+			}
+		},
+		leftOptions() {
+			this.getSelectorQuery()
+			this.init()
+		},
+		rightOptions(newVal) {
+			this.init()
+		}
+	},
+	created() {
+		this.swipeaction = this.getSwipeAction()
+		if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
+			this.swipeaction.children.push(this)
+		}
+	},
+	mounted() {
+		this.box = this.getEl(this.$refs['selector-box--hock'])
+		this.selector = this.getEl(this.$refs['selector-content--hock']);
+		this.leftButton = this.getEl(this.$refs['selector-left-button--hock']);
+		this.rightButton = this.getEl(this.$refs['selector-right-button--hock']);
+		this.init()
+	},
+	// beforeDestroy() {
+	// 	this.swipeaction.children.forEach((item, index) => {
+	// 		if (item === this) {
+	// 			this.swipeaction.children.splice(index, 1)
+	// 		}
+	// 	})
+	// },
+	methods: {
+		init() {
+			this.$nextTick(() => {
+				this.x = 0
+				this.button = {
+					show: false
+				}
+				setTimeout(() => {
+					this.getSelectorQuery()
+				}, 200)
+			})
+		},
+		onClick(index, item, position) {
+			this.$emit('click', {
+				content: item,
+				index,
+				position
+			})
+		},
+		touchstart(e) {
+			// fix by mehaotian 禁止滑动
+			if (this.disabled) return
+			// 每次只触发一次,避免多次监听造成闪烁
+			if (this.stop) return
+			this.stop = true
+			if (this.autoClose && this.swipeaction) {
+				this.swipeaction.closeOther(this)
+			}
+
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			let expression = this.range(this.x, -rightWidth, leftWidth)
+			let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0)
+			let rightExpression = this.range(this.x + rightWidth, 0, rightWidth)
+
+			this.eventpan = BindingX.bind({
+				anchor: this.box,
+				eventType: 'pan',
+				props: [{
+					element: this.selector,
+					property: 'transform.translateX',
+					expression
+				}, {
+					element: this.leftButton,
+					property: 'transform.translateX',
+					expression: leftExpression
+				}, {
+					element: this.rightButton,
+					property: 'transform.translateX',
+					expression: rightExpression
+				}, ]
+			}, (e) => {
+				// nope
+				if (e.state === 'end') {
+					this.x = e.deltaX + this.x;
+					this.isclick = true
+					this.bindTiming(e.deltaX)
+				}
+			});
+		},
+		touchend(e) {
+			if (this.isopen !== 'none' && !this.isclick) {
+				this.open('none')
+			}
+		},
+		bindTiming(x) {
+			const left = this.x
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			const threshold = this.threshold
+			if (!this.isopen || this.isopen === 'none') {
+				if (left > threshold) {
+					this.open('left')
+				} else if (left < -threshold) {
+					this.open('right')
+				} else {
+					this.open('none')
+				}
+			} else {
+				if ((x > -leftWidth && x < 0) || x > rightWidth) {
+					if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) {
+						this.open('left')
+					} else {
+						this.open('none')
+					}
+				} else {
+					if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) {
+						this.open('right')
+					} else {
+						this.open('none')
+					}
+				}
+			}
+		},
+
+		/**
+		 * 移动范围
+		 * @param {Object} num
+		 * @param {Object} mix
+		 * @param {Object} max
+		 */
+		range(num, mix, max) {
+			return `min(max(x+${num}, ${mix}), ${max})`
+		},
+
+		/**
+		 * 开启swipe
+		 */
+		open(type) {
+			this.animation(type)
+		},
+
+		/**
+		 * 关闭swipe
+		 */
+		close() {
+			this.animation('none')
+		},
+
+		/**
+		 * 开启关闭动画
+		 * @param {Object} type
+		 */
+		animation(type) {
+			const time = 300
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			if (this.eventpan && this.eventpan.token) {
+				BindingX.unbind({
+					token: this.eventpan.token,
+					eventType: 'pan'
+				})
+			}
+
+			switch (type) {
+				case 'left':
+					Promise.all([
+						this.move(this.selector, leftWidth),
+						this.move(this.leftButton, 0),
+						this.move(this.rightButton, rightWidth * 2)
+					]).then(() => {
+						this.setEmit(leftWidth, type)
+					})
+					break
+				case 'right':
+					Promise.all([
+						this.move(this.selector, -rightWidth),
+						this.move(this.leftButton, -leftWidth * 2),
+						this.move(this.rightButton, 0)
+					]).then(() => {
+						this.setEmit(-rightWidth, type)
+					})
+					break
+				default:
+					Promise.all([
+						this.move(this.selector, 0),
+						this.move(this.leftButton, -leftWidth),
+						this.move(this.rightButton, rightWidth)
+					]).then(() => {
+						this.setEmit(0, type)
+					})
+
+			}
+		},
+		setEmit(x, type) {
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			this.isopen = this.isopen || 'none'
+			this.stop = false
+			this.isclick = false
+			// 只有状态不一致才会返回结果
+			if (this.isopen !== type && this.x !== x) {
+				if (type === 'left' && leftWidth > 0) {
+					this.$emit('change', 'left')
+				}
+				if (type === 'right' && rightWidth > 0) {
+					this.$emit('change', 'right')
+				}
+				if (type === 'none') {
+					this.$emit('change', 'none')
+				}
+			}
+			this.x = x
+			this.isopen = type
+		},
+		move(ref, value) {
+			return new Promise((resolve, reject) => {
+				animation.transition(ref, {
+					styles: {
+						transform: `translateX(${value})`,
+					},
+					duration: 150, //ms
+					timingFunction: 'linear',
+					needLayout: false,
+					delay: 0 //ms
+				}, function(res) {
+					resolve(res)
+				})
+			})
+
+		},
+
+		/**
+		 * 获取ref
+		 * @param {Object} el
+		 */
+		getEl(el) {
+			return el.ref
+		},
+		/**
+		 * 获取节点信息
+		 */
+		getSelectorQuery() {
+			Promise.all([
+				this.getDom('left'),
+				this.getDom('right'),
+			]).then((data) => {
+				let show = 'none'
+				if (this.autoClose) {
+					show = 'none'
+				} else {
+					show = this.show
+				}
+
+				if (show === 'none') {
+					// this.close()
+				} else {
+					this.open(show)
+				}
+
+			})
+
+		},
+		getDom(str) {
+			return new Promise((resolve, reject) => {
+				dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => {
+					if (data) {
+						this.button[str] = data.size
+						resolve(data)
+					} else {
+						reject()
+					}
+				})
+			})
+		}
+	}
+}
+
+// #endif
+
+export default bindIngXMixins
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js
new file mode 100644
index 0000000..917cb48
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js
@@ -0,0 +1,12 @@
+export function isPC() {
+	var userAgentInfo = navigator.userAgent;
+	var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+	var flag = true;
+	for (let v = 0; v < Agents.length - 1; v++) {
+		if (userAgentInfo.indexOf(Agents[v]) > 0) {
+			flag = false;
+			break;
+		}
+	}
+	return flag;
+}
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js
new file mode 100644
index 0000000..35c796b
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js
@@ -0,0 +1,195 @@
+export default {
+	data() {
+		return {
+			x: 0,
+			transition: false,
+			width: 0,
+			viewWidth: 0,
+			swipeShow: 0
+		}
+	},
+	watch: {
+		show(newVal) {
+			if (this.autoClose) return
+			if (newVal && newVal !== 'none') {
+				this.transition = true
+				this.open(newVal)
+			} else {
+				this.close()
+			}
+		}
+	},
+	created() {
+		this.swipeaction = this.getSwipeAction()
+		if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
+			this.swipeaction.children.push(this)
+		}
+	},
+	mounted() {
+		this.isopen = false
+		setTimeout(() => {
+			this.getQuerySelect()
+		}, 50)
+	},
+	methods: {
+		appTouchStart(e) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			this.clientX = clientX
+			this.timestamp = new Date().getTime()
+		},
+		appTouchEnd(e, index, item, position) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
+			let diff = Math.abs(this.clientX - clientX)
+			let time = (new Date().getTime()) - this.timestamp
+			if (diff < 40 && time < 300) {
+				this.$emit('click', {
+					content: item,
+					index,
+					position
+				})
+			}
+		},
+		/**
+		 * 移动触发
+		 * @param {Object} e
+		 */
+		onChange(e) {
+			this.moveX = e.detail.x
+			this.isclose = false
+		},
+		touchstart(e) {
+			this.transition = false
+			this.isclose = true
+			if (this.autoClose && this.swipeaction) {
+				this.swipeaction.closeOther(this)
+			}
+		},
+		touchmove(e) {},
+		touchend(e) {
+			// 0的位置什么都不执行
+			if (this.isclose && this.isopen === 'none') return
+			if (this.isclose && this.isopen !== 'none') {
+				this.transition = true
+				this.close()
+			} else {
+				this.move(this.moveX + this.leftWidth)
+			}
+		},
+
+		/**
+		 * 移动
+		 * @param {Object} moveX
+		 */
+		move(moveX) {
+			// 打开关闭的处理逻辑不太一样
+			this.transition = true
+			// 未打开状态
+			if (!this.isopen || this.isopen === 'none') {
+				if (moveX > this.threshold) {
+					this.open('left')
+				} else if (moveX < -this.threshold) {
+					this.open('right')
+				} else {
+					this.close()
+				}
+			} else {
+				if (moveX < 0 && moveX < this.rightWidth) {
+					const rightX = this.rightWidth + moveX
+					if (rightX < this.threshold) {
+						this.open('right')
+					} else {
+						this.close()
+					}
+				} else if (moveX > 0 && moveX < this.leftWidth) {
+					const leftX = this.leftWidth - moveX
+					if (leftX < this.threshold) {
+						this.open('left')
+					} else {
+						this.close()
+					}
+				}
+
+			}
+
+		},
+
+		/**
+		 * 打开
+		 */
+		open(type) {
+			this.x = this.moveX
+			this.animation(type)
+		},
+
+		/**
+		 * 关闭
+		 */
+		close() {
+			this.x = this.moveX
+			// TODO 解决 x 值不更新的问题,所以会多触发一次 nextTick ,待优化
+			this.$nextTick(() => {
+				this.x = -this.leftWidth
+				if (this.isopen !== 'none') {
+					this.$emit('change', 'none')
+				}
+				this.isopen = 'none'
+			})
+		},
+
+		/**
+		 * 执行结束动画
+		 * @param {Object} type
+		 */
+		animation(type) {
+			this.$nextTick(() => {
+				if (type === 'left') {
+					this.x = 0
+				} else {
+					this.x = -this.rightWidth - this.leftWidth
+				}
+
+				if (this.isopen !== type) {
+					this.$emit('change', type)
+				}
+				this.isopen = type
+			})
+
+		},
+		getSlide(x) {},
+		getQuerySelect() {
+			const query = uni.createSelectorQuery().in(this);
+			query.selectAll('.movable-view--hock').boundingClientRect(data => {
+				this.leftWidth = data[1].width
+				this.rightWidth = data[2].width
+				this.width = data[0].width
+				this.viewWidth = this.width + this.rightWidth + this.leftWidth
+				if (this.leftWidth === 0) {
+					// TODO 疑似bug ,初始化的时候如果x 是0,会导致移动位置错误,所以让元素超出一点
+					this.x = -0.1
+				} else {
+					this.x = -this.leftWidth
+				}
+				this.moveX = this.x
+				this.$nextTick(() => {
+					this.swipeShow = 1
+				})
+
+				if (!this.buttonWidth) {
+					this.disabledView = true
+				}
+
+				if (this.autoClose) return
+				if (this.show !== 'none') {
+					this.transition = true
+					this.open(this.shows)
+				}
+			}).exec();
+
+		}
+	}
+}
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js
new file mode 100644
index 0000000..d389bce
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js
@@ -0,0 +1,260 @@
+let otherMixins = {}
+
+// #ifndef APP-PLUS|| MP-WEIXIN  ||  H5
+const MIN_DISTANCE = 10;
+otherMixins = {
+	data() {
+		// TODO 随机生生元素ID,解决百度小程序获取同一个元素位置信息的bug
+		const elClass = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+		return {
+			uniShow: false,
+			left: 0,
+			buttonShow: 'none',
+			ani: false,
+			moveLeft: '',
+			elClass
+		}
+	},
+	watch: {
+		show(newVal) {
+			if (this.autoClose) return
+			this.openState(newVal)
+		},
+		left() {
+			this.moveLeft = `translateX(${this.left}px)`
+		},
+		buttonShow(newVal) {
+			if (this.autoClose) return
+			this.openState(newVal)
+		},
+		leftOptions() {
+			this.init()
+		},
+		rightOptions() {
+			this.init()
+		}
+	},
+	mounted() {
+		this.swipeaction = this.getSwipeAction()
+		if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
+			this.swipeaction.children.push(this)
+		}
+		this.init()
+	},
+	methods: {
+		init() {
+			clearTimeout(this.timer)
+			this.timer = setTimeout(() => {
+				this.getSelectorQuery()
+			}, 100)
+			// 移动距离
+			this.left = 0
+			this.x = 0
+		},
+
+		closeSwipe(e) {
+			if (this.autoClose && this.swipeaction) {
+				this.swipeaction.closeOther(this)
+			}
+		},
+		appTouchStart(e) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			this.clientX = clientX
+			this.timestamp = new Date().getTime()
+		},
+		appTouchEnd(e, index, item, position) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
+			let diff = Math.abs(this.clientX - clientX)
+			let time = (new Date().getTime()) - this.timestamp
+			if (diff < 40 && time < 300) {
+				this.$emit('click', {
+					content: item,
+					index,
+					position
+				})
+			}
+		},
+		touchstart(e) {
+			if (this.disabled) return
+			this.ani = false
+			this.x = this.left || 0
+			this.stopTouchStart(e)
+			this.autoClose && this.closeSwipe()
+		},
+		touchmove(e) {
+			if (this.disabled) return
+			// 是否可以滑动页面
+			this.stopTouchMove(e);
+			if (this.direction !== 'horizontal') {
+				return;
+			}
+			this.move(this.x + this.deltaX)
+			return false
+		},
+		touchend() {
+			if (this.disabled) return
+			this.moveDirection(this.left)
+		},
+		/**
+		 * 设置移动距离
+		 * @param {Object} value
+		 */
+		move(value) {
+			value = value || 0
+			const leftWidth = this.leftWidth
+			const rightWidth = this.rightWidth
+			// 获取可滑动范围
+			this.left = this.range(value, -rightWidth, leftWidth);
+		},
+
+		/**
+		 * 获取范围
+		 * @param {Object} num
+		 * @param {Object} min
+		 * @param {Object} max
+		 */
+		range(num, min, max) {
+			return Math.min(Math.max(num, min), max);
+		},
+		/**
+		 * 移动方向判断
+		 * @param {Object} left
+		 * @param {Object} value
+		 */
+		moveDirection(left) {
+			const threshold = this.threshold
+			const isopen = this.isopen || 'none'
+			const leftWidth = this.leftWidth
+			const rightWidth = this.rightWidth
+			if (this.deltaX === 0) {
+				this.openState('none')
+				return
+			}
+			if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth >
+					0 && rightWidth +
+					left < threshold)) {
+				// right
+				this.openState('right')
+			} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth >
+					0 &&
+					leftWidth - left < threshold)) {
+				// left
+				this.openState('left')
+			} else {
+				// default
+				this.openState('none')
+			}
+		},
+
+		/**
+		 * 开启状态
+		 * @param {Boolean} type
+		 */
+		openState(type) {
+			const leftWidth = this.leftWidth
+			const rightWidth = this.rightWidth
+			let left = ''
+			this.isopen = this.isopen ? this.isopen : 'none'
+			switch (type) {
+				case "left":
+					left = leftWidth
+					break
+				case "right":
+					left = -rightWidth
+					break
+				default:
+					left = 0
+			}
+
+
+			if (this.isopen !== type) {
+				this.throttle = true
+				this.$emit('change', type)
+			}
+
+			this.isopen = type
+			// 添加动画类
+			this.ani = true
+			this.$nextTick(() => {
+				this.move(left)
+			})
+			// 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
+		},
+		close() {
+			this.openState('none')
+		},
+		getDirection(x, y) {
+			if (x > y && x > MIN_DISTANCE) {
+				return 'horizontal';
+			}
+			if (y > x && y > MIN_DISTANCE) {
+				return 'vertical';
+			}
+			return '';
+		},
+
+		/**
+		 * 重置滑动状态
+		 * @param {Object} event
+		 */
+		resetTouchStatus() {
+			this.direction = '';
+			this.deltaX = 0;
+			this.deltaY = 0;
+			this.offsetX = 0;
+			this.offsetY = 0;
+		},
+
+		/**
+		 * 设置滑动开始位置
+		 * @param {Object} event
+		 */
+		stopTouchStart(event) {
+			this.resetTouchStatus();
+			const touch = event.touches[0];
+			this.startX = touch.clientX;
+			this.startY = touch.clientY;
+		},
+
+		/**
+		 * 滑动中,是否禁止打开
+		 * @param {Object} event
+		 */
+		stopTouchMove(event) {
+			const touch = event.touches[0];
+			this.deltaX = touch.clientX - this.startX;
+			this.deltaY = touch.clientY - this.startY;
+			this.offsetX = Math.abs(this.deltaX);
+			this.offsetY = Math.abs(this.deltaY);
+			this.direction = this.direction || this.getDirection(this.offsetX, this.offsetY);
+		},
+
+		getSelectorQuery() {
+			const views = uni.createSelectorQuery().in(this)
+			views
+				.selectAll('.' + this.elClass)
+				.boundingClientRect(data => {
+					if (data.length === 0) return
+					let show = 'none'
+					if (this.autoClose) {
+						show = 'none'
+					} else {
+						show = this.show
+					}
+					this.leftWidth = data[0].width || 0
+					this.rightWidth = data[1].width || 0
+					this.buttonShow = show
+				})
+				.exec()
+		}
+	}
+}
+
+// #endif
+
+export default otherMixins
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js
new file mode 100644
index 0000000..08de1c9
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js
@@ -0,0 +1,84 @@
+let mpMixins = {}
+let is_pc = null
+// #ifdef H5
+import {
+	isPC
+} from "./isPC"
+is_pc = isPC()
+// #endif
+// #ifdef APP-VUE|| MP-WEIXIN || H5
+
+mpMixins = {
+	data() {
+		return {
+			is_show: 'none'
+		}
+	},
+	watch: {
+		show(newVal) {
+			this.is_show = this.show
+		}
+	},
+	created() {
+		this.swipeaction = this.getSwipeAction()
+		if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
+			this.swipeaction.children.push(this)
+		}
+	},
+	mounted() {
+		this.is_show = this.show
+	},
+	methods: {
+		// wxs 中调用
+		closeSwipe(e) {
+			if (this.autoClose && this.swipeaction) {
+				this.swipeaction.closeOther(this)
+			}
+		},
+
+		change(e) {
+			this.$emit('change', e.open)
+			if (this.is_show !== e.open) {
+				this.is_show = e.open
+			}
+		},
+
+		appTouchStart(e) {
+			if (is_pc) return
+			const {
+				clientX
+			} = e.changedTouches[0]
+			this.clientX = clientX
+			this.timestamp = new Date().getTime()
+		},
+		appTouchEnd(e, index, item, position) {
+			if (is_pc) return
+			const {
+				clientX
+			} = e.changedTouches[0]
+			// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
+			let diff = Math.abs(this.clientX - clientX)
+			let time = (new Date().getTime()) - this.timestamp
+			if (diff < 40 && time < 300) {
+				this.$emit('click', {
+					content: item,
+					index,
+					position
+				})
+			}
+		},
+		onClickForPC(index, item, position) {
+			if (!is_pc) return
+			// #ifdef H5
+			this.$emit('click', {
+				content: item,
+				index,
+				position
+			})
+			// #endif
+		}
+	}
+}
+
+// #endif
+export default mpMixins
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js
new file mode 100644
index 0000000..78f0ec6
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js
@@ -0,0 +1,270 @@
+const MIN_DISTANCE = 10;
+export default {
+	showWatch(newVal, oldVal, ownerInstance, instance, self) {
+		var state = self.state
+		var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el
+		if (!$el) return
+		this.getDom(instance, ownerInstance, self)
+		if (newVal && newVal !== 'none') {
+			this.openState(newVal, instance, ownerInstance, self)
+			return
+		}
+
+		if (state.left) {
+			this.openState('none', instance, ownerInstance, self)
+		}
+		this.resetTouchStatus(instance, self)
+	},
+
+	/**
+	 * 开始触摸操作
+	 * @param {Object} e
+	 * @param {Object} ins
+	 */
+	touchstart(e, ownerInstance, self) {
+		let instance = e.instance;
+		let disabled = instance.getDataset().disabled
+		let state = self.state;
+		this.getDom(instance, ownerInstance, self)
+		// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+		disabled = this.getDisabledType(disabled)
+		if (disabled) return
+		// 开始触摸时移除动画类
+		instance.requestAnimationFrame(function() {
+			instance.removeClass('ani');
+			ownerInstance.callMethod('closeSwipe');
+		})
+
+		// 记录上次的位置
+		state.x = state.left || 0
+		// 计算滑动开始位置
+		this.stopTouchStart(e, ownerInstance, self)
+	},
+
+	/**
+	 * 开始滑动操作
+	 * @param {Object} e
+	 * @param {Object} ownerInstance
+	 */
+	touchmove(e, ownerInstance, self) {
+		let instance = e.instance;
+		// 删除之后已经那不到实例了
+		if (!instance) return;
+		let disabled = instance.getDataset().disabled
+		let state = self.state
+		// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+		disabled = this.getDisabledType(disabled)
+		if (disabled) return
+		// 是否可以滑动页面
+		this.stopTouchMove(e, self);
+		if (state.direction !== 'horizontal') {
+			return;
+		}
+		if (e.preventDefault) {
+			// 阻止页面滚动
+			e.preventDefault()
+		}
+		let x = state.x + state.deltaX
+		this.move(x, instance, ownerInstance, self)
+	},
+
+	/**
+	 * 结束触摸操作
+	 * @param {Object} e
+	 * @param {Object} ownerInstance
+	 */
+	touchend(e, ownerInstance, self) {
+		let instance = e.instance;
+		let disabled = instance.getDataset().disabled
+		let state = self.state
+		// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+		disabled = this.getDisabledType(disabled)
+
+		if (disabled) return
+		// 滑动过程中触摸结束,通过阙值判断是开启还是关闭
+		// fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13
+		this.moveDirection(state.left, instance, ownerInstance, self)
+
+	},
+
+	/**
+	 * 设置移动距离
+	 * @param {Object} value
+	 * @param {Object} instance
+	 * @param {Object} ownerInstance
+	 */
+	move(value, instance, ownerInstance, self) {
+		value = value || 0
+		let state = self.state
+		let leftWidth = state.leftWidth
+		let rightWidth = state.rightWidth
+		// 获取可滑动范围
+		state.left = this.range(value, -rightWidth, leftWidth);
+		instance.requestAnimationFrame(function() {
+			instance.setStyle({
+				transform: 'translateX(' + state.left + 'px)',
+				'-webkit-transform': 'translateX(' + state.left + 'px)'
+			})
+		})
+
+	},
+
+	/**
+	 * 获取元素信息
+	 * @param {Object} instance
+	 * @param {Object} ownerInstance
+	 */
+	getDom(instance, ownerInstance, self) {
+		var state = self.state
+		var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el
+		var leftDom = $el.querySelector('.button-group--left')
+		var rightDom = $el.querySelector('.button-group--right')
+
+		state.leftWidth = leftDom.offsetWidth || 0
+		state.rightWidth = rightDom.offsetWidth || 0
+		state.threshold = instance.getDataset().threshold
+	},
+
+	getDisabledType(value) {
+		return (typeof(value) === 'string' ? JSON.parse(value) : value) || false;
+	},
+
+	/**
+	 * 获取范围
+	 * @param {Object} num
+	 * @param {Object} min
+	 * @param {Object} max
+	 */
+	range(num, min, max) {
+		return Math.min(Math.max(num, min), max);
+	},
+
+
+	/**
+	 * 移动方向判断
+	 * @param {Object} left
+	 * @param {Object} value
+	 * @param {Object} ownerInstance
+	 * @param {Object} ins
+	 */
+	moveDirection(left, ins, ownerInstance, self) {
+		var state = self.state
+		var threshold = state.threshold
+		var position = state.position
+		var isopen = state.isopen || 'none'
+		var leftWidth = state.leftWidth
+		var rightWidth = state.rightWidth
+		if (state.deltaX === 0) {
+			this.openState('none', ins, ownerInstance, self)
+			return
+		}
+		if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 &&
+				rightWidth +
+				left < threshold)) {
+			// right
+			this.openState('right', ins, ownerInstance, self)
+		} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
+				leftWidth - left < threshold)) {
+			// left
+			this.openState('left', ins, ownerInstance, self)
+		} else {
+			// default
+			this.openState('none', ins, ownerInstance, self)
+		}
+	},
+
+
+	/**
+	 * 开启状态
+	 * @param {Boolean} type
+	 * @param {Object} ins
+	 * @param {Object} ownerInstance
+	 */
+	openState(type, ins, ownerInstance, self) {
+		let state = self.state
+		let leftWidth = state.leftWidth
+		let rightWidth = state.rightWidth
+		let left = ''
+		state.isopen = state.isopen ? state.isopen : 'none'
+		switch (type) {
+			case "left":
+				left = leftWidth
+				break
+			case "right":
+				left = -rightWidth
+				break
+			default:
+				left = 0
+		}
+
+		// && !state.throttle
+
+		if (state.isopen !== type) {
+			state.throttle = true
+			ownerInstance.callMethod('change', {
+				open: type
+			})
+
+		}
+
+		state.isopen = type
+		// 添加动画类
+		ins.requestAnimationFrame(() => {
+			ins.addClass('ani');
+			this.move(left, ins, ownerInstance, self)
+		})
+	},
+
+
+	getDirection(x, y) {
+		if (x > y && x > MIN_DISTANCE) {
+			return 'horizontal';
+		}
+		if (y > x && y > MIN_DISTANCE) {
+			return 'vertical';
+		}
+		return '';
+	},
+
+	/**
+	 * 重置滑动状态
+	 * @param {Object} event
+	 */
+	resetTouchStatus(instance, self) {
+		let state = self.state;
+		state.direction = '';
+		state.deltaX = 0;
+		state.deltaY = 0;
+		state.offsetX = 0;
+		state.offsetY = 0;
+	},
+
+	/**
+	 * 设置滑动开始位置
+	 * @param {Object} event
+	 */
+	stopTouchStart(event, ownerInstance, self) {
+		let instance = event.instance;
+		let state = self.state
+		this.resetTouchStatus(instance, self);
+		var touch = event.touches[0];
+		state.startX = touch.clientX;
+		state.startY = touch.clientY;
+	},
+
+	/**
+	 * 滑动中,是否禁止打开
+	 * @param {Object} event
+	 */
+	stopTouchMove(event, self) {
+		let instance = event.instance;
+		let state = self.state;
+		let touch = event.touches[0];
+
+		state.deltaX = touch.clientX - state.startX;
+		state.deltaY = touch.clientY - state.startY;
+		state.offsetY = Math.abs(state.deltaY);
+		state.offsetX = Math.abs(state.deltaX);
+		state.direction = state.direction || this.getDirection(state.offsetX, state.offsetY);
+	}
+}
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue
new file mode 100644
index 0000000..a816e92
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue
@@ -0,0 +1,348 @@
+<template>
+	<!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
+	<!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
+	<view class="uni-swipe">
+		<!--  #ifdef MP-WEIXIN || VUE3 -->
+		<view class="uni-swipe_box" :change:prop="wxsswipe.showWatch" :prop="is_show" :data-threshold="threshold"
+			:data-disabled="disabled" @touchstart="wxsswipe.touchstart" @touchmove="wxsswipe.touchmove"
+			@touchend="wxsswipe.touchend">
+		<!-- #endif -->
+			<!--  #ifndef MP-WEIXIN || VUE3 -->
+			<view class="uni-swipe_box" :change:prop="renderswipe.showWatch" :prop="is_show" :data-threshold="threshold"
+				:data-disabled="disabled+''" @touchstart="renderswipe.touchstart" @touchmove="renderswipe.touchmove"
+				@touchend="renderswipe.touchend">
+			<!-- #endif -->
+				<!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
+				<view class="uni-swipe_button-group button-group--left">
+					<slot name="left">
+						<view v-for="(item,index) in leftOptions" :key="index" :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
+					}" class="uni-swipe_button button-hock" @touchstart.stop="appTouchStart"
+							@touchend.stop="appTouchEnd($event,index,item,'left')" @click.stop="onClickForPC(index,item,'left')">
+							<text class="uni-swipe_button-text"
+								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text>
+						</view>
+					</slot>
+				</view>
+				<view class="uni-swipe_text--center">
+					<slot></slot>
+				</view>
+				<view class="uni-swipe_button-group button-group--right">
+					<slot name="right">
+						<view v-for="(item,index) in rightOptions" :key="index" :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
+					}" class="uni-swipe_button button-hock" @touchstart.stop="appTouchStart"
+							@touchend.stop="appTouchEnd($event,index,item,'right')" @click.stop="onClickForPC(index,item,'right')"><text
+								class="uni-swipe_button-text"
+								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text>
+						</view>
+					</slot>
+				</view>
+			</view>
+		</view>
+		<!-- #endif -->
+		<!-- app nvue端 使用 bindingx -->
+		<!-- #ifdef APP-NVUE -->
+		<view ref="selector-box--hock" class="uni-swipe" @horizontalpan="touchstart" @touchend="touchend">
+			<view ref='selector-left-button--hock' class="uni-swipe_button-group button-group--left">
+				<slot name="left">
+					<view v-for="(item,index) in leftOptions" :key="index" :style="{
+				  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
+				}" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'left')">
+						<text class="uni-swipe_button-text"
+							:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF', fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">
+							{{ item.text }}
+						</text>
+					</view>
+				</slot>
+			</view>
+			<view ref='selector-right-button--hock' class="uni-swipe_button-group button-group--right">
+				<slot name="right">
+					<view v-for="(item,index) in rightOptions" :key="index" :style="{
+				  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
+				}" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'right')"><text
+							class="uni-swipe_button-text"
+							:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text>
+					</view>
+				</slot>
+			</view>
+			<view ref='selector-content--hock' class="uni-swipe_box">
+				<slot></slot>
+			</view>
+		</view>
+		<!-- #endif -->
+		<!-- 其他平台使用 js ,长列表性能可能会有影响-->
+		<!-- #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ -->
+		<view class="uni-swipe">
+			<view class="uni-swipe_box" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"
+				:style="{transform:moveLeft}" :class="{ani:ani}">
+				<view class="uni-swipe_button-group button-group--left" :class="[elClass]">
+					<slot name="left">
+						<view v-for="(item,index) in leftOptions" :key="index" :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+					}" class="uni-swipe_button button-hock" @touchstart.stop="appTouchStart"
+							@touchend.stop="appTouchEnd($event,index,item,'left')"><text class="uni-swipe_button-text"
+								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
+						</view>
+					</slot>
+				</view>
+				<slot></slot>
+				<view class="uni-swipe_button-group button-group--right" :class="[elClass]">
+					<slot name="right">
+						<view v-for="(item,index) in rightOptions" :key="index" :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+					}" @touchstart.stop="appTouchStart" @touchend.stop="appTouchEnd($event,index,item,'right')"
+							class="uni-swipe_button button-hock"><text class="uni-swipe_button-text"
+								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
+						</view>
+					</slot>
+				</view>
+			</view>
+		</view>
+		<!-- #endif -->
+
+</template>
+<script src="./wx.wxs" module="wxsswipe" lang="wxs"></script>
+
+<script module="renderswipe" lang="renderjs">
+	import render from './render.js'
+	export default {
+		mounted(e, ins, owner) {
+			this.state = {}
+		},
+		methods: {
+			showWatch(newVal, oldVal, ownerInstance, instance) {
+				render.showWatch(newVal, oldVal, ownerInstance, instance, this)
+			},
+			touchstart(e, ownerInstance) {
+				render.touchstart(e, ownerInstance, this)
+			},
+			touchmove(e, ownerInstance) {
+				render.touchmove(e, ownerInstance, this)
+			},
+			touchend(e, ownerInstance) {
+				render.touchend(e, ownerInstance, this)
+			}
+		}
+	}
+</script>
+<script>
+	import mpwxs from './mpwxs'
+	import bindingx from './bindingx.js'
+	import mpother from './mpother'
+
+	/**
+	 * SwipeActionItem 滑动操作子组件
+	 * @description 通过滑动触发选项的容器
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=181
+	 * @property {Boolean} show = [left|right|none] 	开启关闭组件,auto-close = false 时生效
+	 * @property {Boolean} disabled = [true|false] 		是否禁止滑动
+	 * @property {Boolean} autoClose = [true|false] 	滑动打开当前组件,是否关闭其他组件
+	 * @property {Number}  threshold 					滑动缺省值
+	 * @property {Array} leftOptions 					左侧选项内容及样式
+	 * @property {Array} rgihtOptions 					右侧选项内容及样式
+	 * @event {Function} click 							点击选项按钮时触发事件,e = {content,index} ,content(点击内容)、index(下标)
+	 * @event {Function} change 						组件打开或关闭时触发,left\right\none
+	 */
+
+	export default {
+		mixins: [mpwxs, bindingx, mpother],
+		emits: ['click', 'change'],
+		props: {
+			// 控制开关
+			show: {
+				type: String,
+				default: 'none'
+			},
+
+			// 禁用
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+
+			// 是否自动关闭
+			autoClose: {
+				type: Boolean,
+				default: true
+			},
+
+			// 滑动缺省距离
+			threshold: {
+				type: Number,
+				default: 20
+			},
+
+			// 左侧按钮内容
+			leftOptions: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+
+			// 右侧按钮内容
+			rightOptions: {
+				type: Array,
+				default () {
+					return []
+				}
+			}
+
+		},
+		// #ifndef VUE3
+		// TODO vue2
+		destroyed() {
+			if (this.__isUnmounted) return
+			this.uninstall()
+		},
+		// #endif
+		// #ifdef VUE3
+		// TODO vue3
+		unmounted() {
+			this.__isUnmounted = true
+			this.uninstall()
+		},
+		// #endif
+
+		methods: {
+			uninstall() {
+				if (this.swipeaction) {
+					this.swipeaction.children.forEach((item, index) => {
+						if (item === this) {
+							this.swipeaction.children.splice(index, 1)
+						}
+					})
+				}
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getSwipeAction(name = 'uniSwipeAction') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false;
+					parentName = parent.$options.name;
+				}
+				return parent;
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.uni-swipe {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		/* #endif */
+	}
+
+	.uni-swipe_box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-shrink: 0;
+		// touch-action: none;
+		/* #endif */
+		position: relative;
+	}
+
+	.uni-swipe_content {
+		// border: 1px red solid;
+	}
+
+	.uni-swipe_text--center {
+		width: 100%;
+		/* #ifndef APP-NVUE */
+		cursor: grab;
+		/* #endif */
+	}
+
+	.uni-swipe_button-group {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.button-group--left {
+		left: 0;
+		transform: translateX(-100%)
+	}
+
+	.button-group--right {
+		right: 0;
+		transform: translateX(100%)
+	}
+
+	.uni-swipe_button {
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		padding: 0 20px;
+	}
+
+	.uni-swipe_button-text {
+		/* #ifndef APP-NVUE */
+		flex-shrink: 0;
+		/* #endif */
+		font-size: 14px;
+	}
+
+	.ani {
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
+	}
+
+	/* #ifdef MP-ALIPAY */
+	.movable-area {
+		/* width: 100%; */
+		height: 45px;
+	}
+
+	.movable-view {
+		display: flex;
+		/* justify-content: center; */
+		position: relative;
+		flex: 1;
+		height: 45px;
+		z-index: 2;
+	}
+
+	.movable-view-button {
+		display: flex;
+		flex-shrink: 0;
+		flex-direction: row;
+		height: 100%;
+		background: #C0C0C0;
+	}
+
+	/* .transition {
+		transition: all 0.3s;
+	} */
+
+	.movable-view-box {
+		flex-shrink: 0;
+		height: 100%;
+		background-color: #fff;
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs
new file mode 100644
index 0000000..b394244
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs
@@ -0,0 +1,341 @@
+var MIN_DISTANCE = 10;
+
+/**
+ * 判断当前是否为H5、app-vue
+ */
+var IS_HTML5 = false
+if (typeof window === 'object') IS_HTML5 = true
+
+/**
+ * 监听页面内值的变化,主要用于动态开关swipe-action
+ * @param {Object} newValue
+ * @param {Object} oldValue
+ * @param {Object} ownerInstance
+ * @param {Object} instance
+ */
+function showWatch(newVal, oldVal, ownerInstance, instance) {
+	var state = instance.getState()
+	getDom(instance, ownerInstance)
+	if (newVal && newVal !== 'none') {
+		openState(newVal, instance, ownerInstance)
+		return
+	}
+
+	if (state.left) {
+		openState('none', instance, ownerInstance)
+	}
+	resetTouchStatus(instance)
+}
+
+/**
+ * 开始触摸操作
+ * @param {Object} e
+ * @param {Object} ins
+ */
+function touchstart(e, ownerInstance) {
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState();
+	getDom(instance, ownerInstance)
+	// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+	disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
+	if (disabled) return
+	// 开始触摸时移除动画类
+	instance.requestAnimationFrame(function() {
+		instance.removeClass('ani');
+		ownerInstance.callMethod('closeSwipe');
+	})
+
+	// 记录上次的位置
+	state.x = state.left || 0
+	// 计算滑动开始位置
+	stopTouchStart(e, ownerInstance)
+}
+
+/**
+ * 开始滑动操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchmove(e, ownerInstance) {
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState()
+	// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+	disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
+	if (disabled) return
+	// 是否可以滑动页面
+	stopTouchMove(e);
+	if (state.direction !== 'horizontal') {
+		return;
+	}
+
+	if (e.preventDefault) {
+		// 阻止页面滚动
+		e.preventDefault()
+	}
+
+	move(state.x + state.deltaX, instance, ownerInstance)
+}
+
+/**
+ * 结束触摸操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchend(e, ownerInstance) {
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState()
+	// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+	disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
+
+	if (disabled) return
+	// 滑动过程中触摸结束,通过阙值判断是开启还是关闭
+	// fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13
+	moveDirection(state.left, instance, ownerInstance)
+
+}
+
+/**
+ * 设置移动距离
+ * @param {Object} value
+ * @param {Object} instance
+ * @param {Object} ownerInstance
+ */
+function move(value, instance, ownerInstance) {
+	value = value || 0
+	var state = instance.getState()
+	var leftWidth = state.leftWidth
+	var rightWidth = state.rightWidth
+	// 获取可滑动范围
+	state.left = range(value, -rightWidth, leftWidth);
+	instance.requestAnimationFrame(function() {
+		instance.setStyle({
+			transform: 'translateX(' + state.left + 'px)',
+			'-webkit-transform': 'translateX(' + state.left + 'px)'
+		})
+	})
+
+}
+
+/**
+ * 获取元素信息
+ * @param {Object} instance
+ * @param {Object} ownerInstance
+ */
+function getDom(instance, ownerInstance) {
+	var state = instance.getState()
+	var leftDom = ownerInstance.selectComponent('.button-group--left')
+	var rightDom = ownerInstance.selectComponent('.button-group--right')
+	var leftStyles = {
+		width: 0
+	}
+	var rightStyles = {
+		width: 0
+	}
+	leftStyles = leftDom.getBoundingClientRect()
+	rightStyles = rightDom.getBoundingClientRect()
+
+	state.leftWidth = leftStyles.width || 0
+	state.rightWidth = rightStyles.width || 0
+	state.threshold = instance.getDataset().threshold
+}
+
+/**
+ * 获取范围
+ * @param {Object} num
+ * @param {Object} min
+ * @param {Object} max
+ */
+function range(num, min, max) {
+	return Math.min(Math.max(num, min), max);
+}
+
+
+/**
+ * 移动方向判断
+ * @param {Object} left
+ * @param {Object} value
+ * @param {Object} ownerInstance
+ * @param {Object} ins
+ */
+function moveDirection(left, ins, ownerInstance) {
+	var state = ins.getState()
+	var threshold = state.threshold
+	var position = state.position
+	var isopen = state.isopen || 'none'
+	var leftWidth = state.leftWidth
+	var rightWidth = state.rightWidth
+	if (state.deltaX === 0) {
+		openState('none', ins, ownerInstance)
+		return
+	}
+	if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 &&
+			rightWidth +
+			left < threshold)) {
+		// right
+		openState('right', ins, ownerInstance)
+	} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
+			leftWidth - left < threshold)) {
+		// left
+		openState('left', ins, ownerInstance)
+	} else {
+		// default
+		openState('none', ins, ownerInstance)
+	}
+}
+
+
+/**
+ * 开启状态
+ * @param {Boolean} type
+ * @param {Object} ins
+ * @param {Object} ownerInstance
+ */
+function openState(type, ins, ownerInstance) {
+	var state = ins.getState()
+	var leftWidth = state.leftWidth
+	var rightWidth = state.rightWidth
+	var left = ''
+	state.isopen = state.isopen ? state.isopen : 'none'
+	switch (type) {
+		case "left":
+			left = leftWidth
+			break
+		case "right":
+			left = -rightWidth
+			break
+		default:
+			left = 0
+	}
+
+	// && !state.throttle
+
+	if (state.isopen !== type) {
+		state.throttle = true
+		ownerInstance.callMethod('change', {
+			open: type
+		})
+
+	}
+
+	state.isopen = type
+	// 添加动画类
+	ins.requestAnimationFrame(function() {
+		ins.addClass('ani');
+		move(left, ins, ownerInstance)
+	})
+	// 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
+}
+
+
+function getDirection(x, y) {
+	if (x > y && x > MIN_DISTANCE) {
+		return 'horizontal';
+	}
+	if (y > x && y > MIN_DISTANCE) {
+		return 'vertical';
+	}
+	return '';
+}
+
+/**
+ * 重置滑动状态
+ * @param {Object} event
+ */
+function resetTouchStatus(instance) {
+	var state = instance.getState();
+	state.direction = '';
+	state.deltaX = 0;
+	state.deltaY = 0;
+	state.offsetX = 0;
+	state.offsetY = 0;
+}
+
+/**
+ * 设置滑动开始位置
+ * @param {Object} event
+ */
+function stopTouchStart(event) {
+	var instance = event.instance;
+	var state = instance.getState();
+	resetTouchStatus(instance);
+	var touch = event.touches[0];
+	if (IS_HTML5 && isPC()) {
+		touch = event;
+	}
+	state.startX = touch.clientX;
+	state.startY = touch.clientY;
+}
+
+/**
+ * 滑动中,是否禁止打开
+ * @param {Object} event
+ */
+function stopTouchMove(event) {
+	var instance = event.instance;
+	var state = instance.getState();
+	var touch = event.touches[0];
+	if (IS_HTML5 && isPC()) {
+		touch = event;
+	}
+	state.deltaX = touch.clientX - state.startX;
+	state.deltaY = touch.clientY - state.startY;
+	state.offsetY = Math.abs(state.deltaY);
+	state.offsetX = Math.abs(state.deltaX);
+	state.direction = state.direction || getDirection(state.offsetX, state.offsetY);
+}
+
+function isPC() {
+	var userAgentInfo = navigator.userAgent;
+	var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+	var flag = true;
+	for (var v = 0; v < Agents.length - 1; v++) {
+		if (userAgentInfo.indexOf(Agents[v]) > 0) {
+			flag = false;
+			break;
+		}
+	}
+	return flag;
+}
+
+var movable = false
+
+function mousedown(e, ins) {
+	if (!IS_HTML5) return
+	if (!isPC()) return
+	touchstart(e, ins)
+	movable = true
+}
+
+function mousemove(e, ins) {
+	if (!IS_HTML5) return
+	if (!isPC()) return
+	if (!movable) return
+	touchmove(e, ins)
+}
+
+function mouseup(e, ins) {
+	if (!IS_HTML5) return
+	if (!isPC()) return
+	touchend(e, ins)
+	movable = false
+}
+
+function mouseleave(e, ins) {
+	if (!IS_HTML5) return
+	if (!isPC()) return
+	movable = false
+}
+
+module.exports = {
+	showWatch: showWatch,
+	touchstart: touchstart,
+	touchmove: touchmove,
+	touchend: touchend,
+	mousedown: mousedown,
+	mousemove: mousemove,
+	mouseup: mouseup,
+	mouseleave: mouseleave
+}
diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue b/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue
new file mode 100644
index 0000000..4971782
--- /dev/null
+++ b/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue
@@ -0,0 +1,60 @@
+<template>
+	<view>
+		<slot></slot>
+	</view>
+</template>
+
+<script>
+	/**
+	 * SwipeAction 滑动操作
+	 * @description 通过滑动触发选项的容器
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=181
+	 */
+	export default {
+		name:"uniSwipeAction",
+		data() {
+			return {};
+		},
+		created() {
+			this.children = [];
+		},
+		methods: {
+			// 公开给用户使用,重制组件样式
+			resize(){
+				// wxs 会自己计算组件大小,所以无需执行下面代码
+				// #ifndef APP-VUE || H5 || MP-WEIXIN
+				this.children.forEach(vm=>{
+					vm.init()
+				})
+				// #endif
+			},
+			// 公开给用户使用,关闭全部 已经打开的组件
+			closeAll(){
+				this.children.forEach(vm=>{
+					// #ifdef APP-VUE || H5 || MP-WEIXIN
+					vm.is_show = 'none'
+					// #endif
+
+					// #ifndef APP-VUE || H5 || MP-WEIXIN
+					vm.close()
+					// #endif
+				})
+			},
+			closeOther(vm) {
+				if (this.openItem && this.openItem !== vm) {
+					// #ifdef APP-VUE || H5 || MP-WEIXIN
+					this.openItem.is_show = 'none'
+					// #endif
+
+					// #ifndef APP-VUE || H5 || MP-WEIXIN
+					this.openItem.close()
+					// #endif
+				}
+				// 记录上一个打开的 swipe-action-item ,用于 auto-close
+				this.openItem = vm
+			}
+		}
+	};
+</script>
+
+<style></style>
diff --git a/uni_modules/uni-swipe-action/package.json b/uni_modules/uni-swipe-action/package.json
new file mode 100644
index 0000000..fc5dd8a
--- /dev/null
+++ b/uni_modules/uni-swipe-action/package.json
@@ -0,0 +1,84 @@
+{
+	"id": "uni-swipe-action",
+	"displayName": "uni-swipe-action 滑动操作",
+	"version": "1.3.10",
+	"description": "SwipeAction 滑动操作操作组件",
+	"keywords": [
+        "",
+        "uni-ui",
+        "uniui",
+        "滑动删除",
+        "侧滑删除"
+    ],
+	"repository": "https://github.com/dcloudio/uni-ui",
+	"engines": {
+		"HBuilderX": ""
+	},
+	"directories": {
+		"example": "../../temps/example_temps"
+	},
+    "dcloudext": {
+        "sale": {
+			"regular": {
+				"price": "0.00"
+			},
+			"sourcecode": {
+				"price": "0.00"
+			}
+		},
+		"contact": {
+			"qq": ""
+		},
+		"declaration": {
+			"ads": "无",
+			"data": "无",
+			"permissions": "无"
+		},
+        "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+        "type": "component-vue"
+	},
+	"uni_modules": {
+		"dependencies": ["uni-scss"],
+		"encrypt": [],
+		"platforms": {
+			"cloud": {
+				"tcb": "y",
+				"aliyun": "y"
+			},
+			"client": {
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "y"
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "y",
+					"Edge": "y",
+					"Firefox": "y",
+					"Safari": "y"
+				},
+				"小程序": {
+					"微信": "y",
+					"阿里": "y",
+					"百度": "y",
+					"字节跳动": "y",
+					"QQ": "y"
+				},
+				"快应用": {
+					"华为": "y",
+					"联盟": "u"
+				},
+				"Vue": {
+					"vue2": "y",
+					"vue3": "y"
+				}
+			}
+		}
+	}
+}
diff --git a/uni_modules/uni-swipe-action/readme.md b/uni_modules/uni-swipe-action/readme.md
new file mode 100644
index 0000000..93a5cac
--- /dev/null
+++ b/uni_modules/uni-swipe-action/readme.md
@@ -0,0 +1,11 @@
+
+
+## SwipeAction 滑动操作
+> **组件名:uni-swipe-action**
+> 代码块: `uSwipeAction`、`uSwipeActionItem`
+
+
+通过滑动触发选项的容器
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-swipe-action)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-swiper-dot/changelog.md b/uni_modules/uni-swiper-dot/changelog.md
new file mode 100644
index 0000000..85cf54d
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/changelog.md
@@ -0,0 +1,12 @@
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-swiper-dot](https://uniapp.dcloud.io/component/uniui/uni-swiper-dot)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.6(2021-05-12)
+- 新增 示例地址
+- 修复 示例项目缺少组件的Bug
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 clickItem 事件,支持指示点控制轮播
+- 新增 支持 pc 可用
diff --git a/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue b/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue
new file mode 100644
index 0000000..e66b6c7
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue
@@ -0,0 +1,218 @@
+<template>
+	<view class="uni-swiper__warp">
+		<slot />
+		<view v-if="mode === 'default'" :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box" key='default'>
+			<view v-for="(item,index) in info" @click="clickItem(index)" :style="{
+        'width': (index === current? dots.width*2:dots.width ) + 'px','height':dots.width/2 +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border-radius':'0px'}"
+			 :key="index" class="uni-swiper__dots-item uni-swiper__dots-bar" />
+		</view>
+		<view v-if="mode === 'dot'" :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box" key='dot'>
+			<view v-for="(item,index) in info" @click="clickItem(index)" :style="{
+        'width': dots.width + 'px','height':dots.height +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
+			 :key="index" class="uni-swiper__dots-item" />
+		</view>
+		<view v-if="mode === 'round'" :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box" key='round'>
+			<view v-for="(item,index) in info" @click="clickItem(index)" :class="[index === current&&'uni-swiper__dots-long']" :style="{
+		    'width':(index === current? dots.width*3:dots.width ) + 'px','height':dots.height +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
+			 :key="index" class="uni-swiper__dots-item " />
+		</view>
+		<view v-if="mode === 'nav'" key='nav' :style="{'background-color':dotsStyles.backgroundColor,'bottom':'0'}" class="uni-swiper__dots-box uni-swiper__dots-nav">
+			<text :style="{'color':dotsStyles.color}" class="uni-swiper__dots-nav-item">{{ (current+1)+"/"+info.length +' ' +info[current][field] }}</text>
+		</view>
+		<view v-if="mode === 'indexes'" key='indexes' :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box">
+			<view v-for="(item,index) in info" @click="clickItem(index)" :style="{
+        'width':dots.width + 'px','height':dots.height +'px' ,'color':index === current?dots.selectedColor:dots.color,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
+			 :key="index" class="uni-swiper__dots-item uni-swiper__dots-indexes"><text class="uni-swiper__dots-indexes-text">{{ index+1 }}</text></view>
+		</view>
+	</view>
+</template>
+
+<script>
+
+	/**
+	 * SwiperDod 轮播图指示点
+	 * @description 自定义轮播图指示点
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=284
+	 * @property {Number} current 当前指示点索引,必须是通过 `swiper` 的 `change` 事件获取到的 `e.detail.current`
+	 * @property {String} mode = [default|round|nav|indexes] 指示点的类型
+	 * 	@value defualt 默认指示点
+	 * 	@value round 圆形指示点
+	 * 	@value nav 条形指示点
+	 * 	@value indexes 索引指示点
+	 * @property {String} field mode 为 nav 时,显示的内容字段(mode = nav 时必填)
+	 * @property {String} info 轮播图的数据,通过数组长度决定指示点个数
+	 * @property {Object} dotsStyles 指示点样式
+	 * @event {Function} clickItem 组件触发点击事件时触发,e={currentIndex}
+	 */
+
+	export default {
+		name: 'UniSwiperDot',
+		emits:['clickItem'],
+		props: {
+			info: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			current: {
+				type: Number,
+				default: 0
+			},
+			dotsStyles: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			// 类型 :default(默认) indexes long nav
+			mode: {
+				type: String,
+				default: 'default'
+			},
+			// 只在 nav 模式下生效,变量名称
+			field: {
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				dots: {
+					width: 6,
+					height: 6,
+					bottom: 10,
+					color: '#fff',
+					backgroundColor: 'rgba(0, 0, 0, .3)',
+					border: '1px rgba(0, 0, 0, .3) solid',
+					selectedBackgroundColor: '#333',
+					selectedBorder: '1px rgba(0, 0, 0, .9) solid'
+				}
+			}
+		},
+		watch: {
+			dotsStyles(newVal) {
+				this.dots = Object.assign(this.dots, this.dotsStyles)
+			},
+			mode(newVal) {
+				if (newVal === 'indexes') {
+					this.dots.width = 14
+					this.dots.height = 14
+				} else {
+					this.dots.width = 6
+					this.dots.height = 6
+				}
+			}
+
+		},
+		created() {
+			if (this.mode === 'indexes') {
+				this.dots.width = 12
+				this.dots.height = 12
+			}
+			this.dots = Object.assign(this.dots, this.dotsStyles)
+		},
+		methods: {
+			clickItem(index) {
+				this.$emit('clickItem', index)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-swiper__warp {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: column;
+		position: relative;
+		overflow: hidden;
+	}
+
+	.uni-swiper__dots-box {
+		position: absolute;
+		bottom: 10px;
+		left: 0;
+		right: 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-swiper__dots-item {
+		width: 8px;
+		border-radius: 100px;
+		margin-left: 6px;
+		background-color: rgba(0, 0, 0, 0.4);
+		/* #ifndef APP-NVUE */
+		cursor: pointer;
+		/* #endif */
+		/* #ifdef H5 */
+		// border-width: 5px 0;
+		// border-style: solid;
+		// border-color: transparent;
+		// background-clip: padding-box;
+		/* #endif */
+		// transition: width 0.2s linear;  不要取消注释,不然会不能变色
+	}
+
+	.uni-swiper__dots-item:first-child {
+		margin: 0;
+	}
+
+	.uni-swiper__dots-default {
+		border-radius: 100px;
+	}
+
+	.uni-swiper__dots-long {
+		border-radius: 50px;
+	}
+
+	.uni-swiper__dots-bar {
+		border-radius: 50px;
+	}
+
+	.uni-swiper__dots-nav {
+		bottom: 0px;
+		// height: 26px;
+		padding: 8px 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		justify-content: flex-start;
+		align-items: center;
+		background-color: rgba(0, 0, 0, 0.2);
+	}
+
+	.uni-swiper__dots-nav-item {
+		/* overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap; */
+		font-size: 14px;
+		color: #fff;
+		margin: 0 15px;
+	}
+
+	.uni-swiper__dots-indexes {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		// flex: 1;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-swiper__dots-indexes-text {
+		color: #fff;
+		font-size: 12px;
+		line-height: 14px;
+	}
+</style>
diff --git a/uni_modules/uni-swiper-dot/package.json b/uni_modules/uni-swiper-dot/package.json
new file mode 100644
index 0000000..f2dd8d2
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/package.json
@@ -0,0 +1,87 @@
+{
+  "id": "uni-swiper-dot",
+  "displayName": "uni-swiper-dot 轮播图指示点",
+  "version": "1.2.0",
+  "description": "自定义轮播图指示点组件",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "轮播图指示点",
+    "dot",
+    "swiper"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-swiper-dot/readme.md b/uni_modules/uni-swiper-dot/readme.md
new file mode 100644
index 0000000..7d397e2
--- /dev/null
+++ b/uni_modules/uni-swiper-dot/readme.md
@@ -0,0 +1,11 @@
+
+
+## SwiperDot 轮播图指示点
+> **组件名:uni-swiper-dot**
+> 代码块: `uSwiperDot`
+
+
+自定义轮播图指示点
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-swiper-dot)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-table/changelog.md b/uni_modules/uni-table/changelog.md
new file mode 100644
index 0000000..943707b
--- /dev/null
+++ b/uni_modules/uni-table/changelog.md
@@ -0,0 +1,33 @@
+## 1.2.8(2024-10-15)
+- 修复 运行到抖音小程序上出现的问题
+## 1.2.7(2024-10-15)
+- 修复 微信小程序中的getSystemInfo警告
+## 1.2.4(2023-12-19)
+- 修复 uni-tr只有一列时minWidth计算错误,列变化实时计算更新
+## 1.2.3(2023-03-28)
+- 修复 在vue3模式下可能会出现错误的问题
+## 1.2.2(2022-11-29)
+- 优化 主题样式
+## 1.2.1(2022-06-06)
+- 修复 微信小程序存在无使用组件的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-table](https://uniapp.dcloud.io/component/uniui/uni-table)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-07-08)
+- 新增 uni-th 支持 date 日期筛选范围
+## 1.0.6(2021-07-05)
+- 新增 uni-th 支持 range 筛选范围
+## 1.0.5(2021-06-28)
+- 新增 uni-th 筛选功能
+## 1.0.4(2021-05-12)
+- 新增 示例地址
+- 修复 示例项目缺少组件的Bug
+## 1.0.3(2021-04-16)
+- 新增 sortable 属性,是否开启单列排序
+- 优化 表格多选逻辑
+## 1.0.2(2021-03-22)
+- uni-tr 添加 disabled 属性,用于 type=selection 时,设置某行是否可由全选按钮控制
+## 1.0.1(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-table/components/uni-table/uni-table.vue b/uni_modules/uni-table/components/uni-table/uni-table.vue
new file mode 100644
index 0000000..3ab0496
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-table/uni-table.vue
@@ -0,0 +1,460 @@
+<template>
+	<view class="uni-table-scroll" :class="{ 'table--border': border, 'border-none': !noData }">
+		<!-- #ifdef H5 -->
+		<table class="uni-table" border="0" cellpadding="0" cellspacing="0" :class="{ 'table--stripe': stripe }" :style="{ 'min-width': minWidth + 'px' }">
+			<slot></slot>
+			<tr v-if="noData" class="uni-table-loading">
+				<td class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</td>
+			</tr>
+			<view v-if="loading" class="uni-table-mask" :class="{ 'empty-border': border }"><div class="uni-table--loader"></div></view>
+		</table>
+		<!-- #endif -->
+		<!-- #ifndef H5 -->
+		<view class="uni-table" :style="{ 'min-width': minWidth + 'px' }" :class="{ 'table--stripe': stripe }">
+			<slot></slot>
+			<view v-if="noData" class="uni-table-loading">
+				<view class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</view>
+			</view>
+			<view v-if="loading" class="uni-table-mask" :class="{ 'empty-border': border }"><div class="uni-table--loader"></div></view>
+		</view>
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+/**
+ * Table 表格
+ * @description 用于展示多条结构类似的数据
+ * @tutorial https://ext.dcloud.net.cn/plugin?id=3270
+ * @property {Boolean} 	border 				是否带有纵向边框
+ * @property {Boolean} 	stripe 				是否显示斑马线
+ * @property {Boolean} 	type 					是否开启多选
+ * @property {String} 	emptyText 			空数据时显示的文本内容
+ * @property {Boolean} 	loading 			显示加载中
+ * @event {Function} 	selection-change 	开启多选时,当选择项发生变化时会触发该事件
+ */
+export default {
+	name: 'uniTable',
+	options: {
+		// #ifdef MP-TOUTIAO
+		virtualHost: false,
+		// #endif
+		// #ifndef MP-TOUTIAO
+		virtualHost: true
+		// #endif
+	},
+	emits:['selection-change'],
+	props: {
+		data: {
+			type: Array,
+			default() {
+				return []
+			}
+		},
+		// 是否有竖线
+		border: {
+			type: Boolean,
+			default: false
+		},
+		// 是否显示斑马线
+		stripe: {
+			type: Boolean,
+			default: false
+		},
+		// 多选
+		type: {
+			type: String,
+			default: ''
+		},
+		// 没有更多数据
+		emptyText: {
+			type: String,
+			default: '没有更多数据'
+		},
+		loading: {
+			type: Boolean,
+			default: false
+		},
+		rowKey: {
+			type: String,
+			default: ''
+		}
+	},
+	data() {
+		return {
+			noData: true,
+			minWidth: 0,
+			multiTableHeads: []
+		}
+	},
+	watch: {
+		loading(val) {},
+		data(newVal) {
+			let theadChildren = this.theadChildren
+			let rowspan = 1
+			if (this.theadChildren) {
+				rowspan = this.theadChildren.rowspan
+			}
+
+			// this.trChildren.length - rowspan
+			this.noData = false
+			// this.noData = newVal.length === 0
+		}
+	},
+	created() {
+		// 定义tr的实例数组
+		this.trChildren = []
+		this.thChildren = []
+		this.theadChildren = null
+		this.backData = []
+		this.backIndexData = []
+	},
+
+	methods: {
+		isNodata() {
+			let theadChildren = this.theadChildren
+			let rowspan = 1
+			if (this.theadChildren) {
+				rowspan = this.theadChildren.rowspan
+			}
+			this.noData = this.trChildren.length - rowspan <= 0
+		},
+		/**
+		 * 选中所有
+		 */
+		selectionAll() {
+			let startIndex = 1
+			let theadChildren = this.theadChildren
+			if (!this.theadChildren) {
+				theadChildren = this.trChildren[0]
+			} else {
+				startIndex = theadChildren.rowspan - 1
+			}
+			let isHaveData = this.data && this.data.length > 0
+			theadChildren.checked = true
+			theadChildren.indeterminate = false
+			this.trChildren.forEach((item, index) => {
+				if (!item.disabled) {
+					item.checked = true
+					if (isHaveData && item.keyValue) {
+						const row = this.data.find(v => v[this.rowKey] === item.keyValue)
+						if (!this.backData.find(v => v[this.rowKey] === row[this.rowKey])) {
+							this.backData.push(row)
+						}
+					}
+					if (index > (startIndex - 1) && this.backIndexData.indexOf(index - startIndex) === -1) {
+						this.backIndexData.push(index - startIndex)
+					}
+				}
+			})
+			// this.backData = JSON.parse(JSON.stringify(this.data))
+			this.$emit('selection-change', {
+				detail: {
+					value: this.backData,
+					index: this.backIndexData
+				}
+			})
+		},
+		/**
+		 * 用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中)
+		 */
+		toggleRowSelection(row, selected) {
+			// if (!this.theadChildren) return
+			row = [].concat(row)
+
+			this.trChildren.forEach((item, index) => {
+				// if (item.keyValue) {
+
+				const select = row.findIndex(v => {
+					//
+					if (typeof v === 'number') {
+						return v === index - 1
+					} else {
+						return v[this.rowKey] === item.keyValue
+					}
+				})
+				let ischeck = item.checked
+				if (select !== -1) {
+					if (typeof selected === 'boolean') {
+						item.checked = selected
+					} else {
+						item.checked = !item.checked
+					}
+					if (ischeck !== item.checked) {
+						this.check(item.rowData||item, item.checked, item.rowData?item.keyValue:null, true)
+					}
+				}
+				// }
+			})
+			this.$emit('selection-change', {
+				detail: {
+					value: this.backData,
+					index:this.backIndexData
+				}
+			})
+		},
+
+		/**
+		 * 用于多选表格,清空用户的选择
+		 */
+		clearSelection() {
+			let theadChildren = this.theadChildren
+			if (!this.theadChildren) {
+				theadChildren = this.trChildren[0]
+			}
+			// if (!this.theadChildren) return
+			theadChildren.checked = false
+			theadChildren.indeterminate = false
+			this.trChildren.forEach(item => {
+				// if (item.keyValue) {
+					item.checked = false
+				// }
+			})
+			this.backData = []
+			this.backIndexData = []
+			this.$emit('selection-change', {
+				detail: {
+					value: [],
+					index: []
+				}
+			})
+		},
+		/**
+		 * 用于多选表格,切换所有行的选中状态
+		 */
+		toggleAllSelection() {
+			let list = []
+			let startIndex = 1
+			let theadChildren = this.theadChildren
+			if (!this.theadChildren) {
+				theadChildren = this.trChildren[0]
+			} else {
+				startIndex = theadChildren.rowspan - 1
+			}
+			this.trChildren.forEach((item, index) => {
+				if (!item.disabled) {
+					if (index > (startIndex - 1) ) {
+						list.push(index-startIndex)
+					}
+				}
+			})
+			this.toggleRowSelection(list)
+		},
+
+		/**
+		 * 选中\取消选中
+		 * @param {Object} child
+		 * @param {Object} check
+		 * @param {Object} rowValue
+		 */
+		check(child, check, keyValue, emit) {
+			let theadChildren = this.theadChildren
+			if (!this.theadChildren) {
+				theadChildren = this.trChildren[0]
+			}
+
+
+
+			let childDomIndex = this.trChildren.findIndex((item, index) => child === item)
+			if(childDomIndex < 0){
+				childDomIndex = this.data.findIndex(v=>v[this.rowKey] === keyValue) + 1
+			}
+			const dataLen = this.trChildren.filter(v => !v.disabled && v.keyValue).length
+			if (childDomIndex === 0) {
+				check ? this.selectionAll() : this.clearSelection()
+				return
+			}
+
+			if (check) {
+				if (keyValue) {
+					this.backData.push(child)
+				}
+				this.backIndexData.push(childDomIndex - 1)
+			} else {
+				const index = this.backData.findIndex(v => v[this.rowKey] === keyValue)
+				const idx = this.backIndexData.findIndex(item => item === childDomIndex - 1)
+				if (keyValue) {
+					this.backData.splice(index, 1)
+				}
+				this.backIndexData.splice(idx, 1)
+			}
+
+			const domCheckAll = this.trChildren.find((item, index) => index > 0 && !item.checked && !item.disabled)
+			if (!domCheckAll) {
+				theadChildren.indeterminate = false
+				theadChildren.checked = true
+			} else {
+				theadChildren.indeterminate = true
+				theadChildren.checked = false
+			}
+
+			if (this.backIndexData.length === 0) {
+				theadChildren.indeterminate = false
+			}
+
+			if (!emit) {
+				this.$emit('selection-change', {
+					detail: {
+						value: this.backData,
+						index: this.backIndexData
+					}
+				})
+			}
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+$border-color: #ebeef5;
+
+.uni-table-scroll {
+	width: 100%;
+	/* #ifndef APP-NVUE */
+	overflow-x: auto;
+	/* #endif */
+}
+
+.uni-table {
+	position: relative;
+	width: 100%;
+	border-radius: 5px;
+	// box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.1);
+	background-color: #fff;
+	/* #ifndef APP-NVUE */
+	box-sizing: border-box;
+	display: table;
+	overflow-x: auto;
+	::v-deep .uni-table-tr:nth-child(n + 2) {
+		&:hover {
+			background-color: #f5f7fa;
+		}
+	}
+	::v-deep .uni-table-thead {
+		.uni-table-tr {
+			// background-color: #f5f7fa;
+			&:hover {
+				background-color:#fafafa;
+			}
+		}
+	}
+	/* #endif */
+}
+
+.table--border {
+	border: 1px $border-color solid;
+	border-right: none;
+}
+
+.border-none {
+	/* #ifndef APP-NVUE */
+	border-bottom: none;
+	/* #endif */
+}
+
+.table--stripe {
+	/* #ifndef APP-NVUE */
+	::v-deep .uni-table-tr:nth-child(2n + 3) {
+		background-color: #fafafa;
+	}
+	/* #endif */
+}
+
+/* 表格加载、无数据样式 */
+.uni-table-loading {
+	position: relative;
+	/* #ifndef APP-NVUE */
+	display: table-row;
+	/* #endif */
+	height: 50px;
+	line-height: 50px;
+	overflow: hidden;
+	box-sizing: border-box;
+}
+.empty-border {
+	border-right: 1px $border-color solid;
+}
+.uni-table-text {
+	position: absolute;
+	right: 0;
+	left: 0;
+	text-align: center;
+	font-size: 14px;
+	color: #999;
+}
+
+.uni-table-mask {
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	background-color: rgba(255, 255, 255, 0.8);
+	z-index: 99;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	margin: auto;
+	transition: all 0.5s;
+	/* #endif */
+	justify-content: center;
+	align-items: center;
+}
+
+.uni-table--loader {
+	width: 30px;
+	height: 30px;
+	border: 2px solid #aaa;
+	// border-bottom-color: transparent;
+	border-radius: 50%;
+	/* #ifndef APP-NVUE */
+	animation: 2s uni-table--loader linear infinite;
+	/* #endif */
+	position: relative;
+}
+
+@keyframes uni-table--loader {
+	0% {
+		transform: rotate(360deg);
+	}
+
+	10% {
+		border-left-color: transparent;
+	}
+
+	20% {
+		border-bottom-color: transparent;
+	}
+
+	30% {
+		border-right-color: transparent;
+	}
+
+	40% {
+		border-top-color: transparent;
+	}
+
+	50% {
+		transform: rotate(0deg);
+	}
+
+	60% {
+		border-top-color: transparent;
+	}
+
+	70% {
+		border-left-color: transparent;
+	}
+
+	80% {
+		border-bottom-color: transparent;
+	}
+
+	90% {
+		border-right-color: transparent;
+	}
+
+	100% {
+		transform: rotate(-360deg);
+	}
+}
+</style>
diff --git a/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue b/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
new file mode 100644
index 0000000..130f626
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
@@ -0,0 +1,34 @@
+<template>
+	<!-- #ifdef H5 -->
+	<tbody>
+		<slot></slot>
+	</tbody>
+	<!-- #endif -->
+	<!-- #ifndef H5 -->
+	<view><slot></slot></view>
+	<!-- #endif -->
+</template>
+
+<script>
+export default {
+	name: 'uniBody',
+	options: {
+		// #ifdef MP-TOUTIAO
+		virtualHost: false,
+		// #endif
+		// #ifndef MP-TOUTIAO
+		virtualHost: true
+		// #endif
+	},
+	data() {
+		return {
+
+		}
+	},
+	created() {},
+	methods: {}
+}
+</script>
+
+<style>
+</style>
diff --git a/uni_modules/uni-table/components/uni-td/uni-td.vue b/uni_modules/uni-table/components/uni-td/uni-td.vue
new file mode 100644
index 0000000..69e5e8a
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-td/uni-td.vue
@@ -0,0 +1,95 @@
+<template>
+	<!-- #ifdef H5 -->
+	<td class="uni-table-td" :rowspan="rowspan" :colspan="colspan" :class="{'table--border':border}" :style="{width:width + 'px','text-align':align}">
+		<slot></slot>
+	</td>
+	<!-- #endif -->
+	<!-- #ifndef H5 -->
+	<!-- :class="{'table--border':border}"  -->
+	<view class="uni-table-td" :class="{'table--border':border}" :style="{width:width + 'px','text-align':align}">
+		<slot></slot>
+	</view>
+	<!-- #endif -->
+
+</template>
+
+<script>
+	/**
+	 * Td 单元格
+	 * @description 表格中的标准单元格组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3270
+	 * @property {Number} 	align = [left|center|right]	单元格对齐方式
+	 */
+	export default {
+		name: 'uniTd',
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		props: {
+			width: {
+				type: [String, Number],
+				default: ''
+			},
+			align: {
+				type: String,
+				default: 'left'
+			},
+			rowspan: {
+				type: [Number,String],
+				default: 1
+			},
+			colspan: {
+					type: [Number,String],
+				default: 1
+			}
+		},
+		data() {
+			return {
+				border: false
+			};
+		},
+		created() {
+			this.root = this.getTable()
+			this.border = this.root.border
+		},
+		methods: {
+			/**
+			 * 获取父元素实例
+			 */
+			getTable() {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== 'uniTable') {
+					parent = parent.$parent;
+					if (!parent) return false;
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	$border-color:#EBEEF5;
+
+	.uni-table-td {
+		display: table-cell;
+		padding: 8px 10px;
+		font-size: 14px;
+		border-bottom: 1px $border-color solid;
+		font-weight: 400;
+		color: #606266;
+		line-height: 23px;
+		box-sizing: border-box;
+	}
+
+	.table--border {
+		border-right: 1px $border-color solid;
+	}
+</style>
diff --git a/uni_modules/uni-table/components/uni-th/filter-dropdown.vue b/uni_modules/uni-table/components/uni-th/filter-dropdown.vue
new file mode 100644
index 0000000..df22a71
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-th/filter-dropdown.vue
@@ -0,0 +1,511 @@
+<template>
+	<view class="uni-filter-dropdown">
+		<view class="dropdown-btn" @click="onDropdown">
+			<view class="icon-select" :class="{active: canReset}" v-if="isSelect || isRange"></view>
+			<view class="icon-search" :class="{active: canReset}" v-if="isSearch">
+				<view class="icon-search-0"></view>
+				<view class="icon-search-1"></view>
+			</view>
+			<view class="icon-calendar" :class="{active: canReset}" v-if="isDate">
+				<view class="icon-calendar-0"></view>
+				<view class="icon-calendar-1"></view>
+			</view>
+		</view>
+		<view class="uni-dropdown-cover" v-if="isOpened" @click="handleClose"></view>
+		<view class="dropdown-popup dropdown-popup-right" v-if="isOpened" @click.stop>
+			<!-- select-->
+			<view v-if="isSelect" class="list">
+				<label class="flex-r a-i-c list-item" v-for="(item,index) in dataList" :key="index"
+					@click="onItemClick($event, index)">
+					<check-box class="check" :checked="item.checked" />
+					<view class="checklist-content">
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
+					</view>
+				</label>
+			</view>
+			<view v-if="isSelect" class="flex-r opera-area">
+				<view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSelectReset">
+					{{resource.reset}}</view>
+				<view class="flex-f btn btn-submit" @click="handleSelectSubmit">{{resource.submit}}</view>
+			</view>
+			<!-- search -->
+			<view v-if="isSearch" class="search-area">
+				<input class="search-input" v-model="filterValue" />
+			</view>
+			<view v-if="isSearch" class="flex-r opera-area">
+				<view class="flex-f btn btn-submit" @click="handleSearchSubmit">{{resource.search}}</view>
+				<view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSearchReset">
+					{{resource.reset}}</view>
+			</view>
+			<!-- range -->
+			<view v-if="isRange">
+				<view class="input-label">{{resource.gt}}</view>
+				<input class="input" v-model="gtValue" />
+				<view class="input-label">{{resource.lt}}</view>
+				<input class="input" v-model="ltValue" />
+			</view>
+			<view v-if="isRange" class="flex-r opera-area">
+				<view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleRangeReset">
+					{{resource.reset}}</view>
+				<view class="flex-f btn btn-submit" @click="handleRangeSubmit">{{resource.submit}}</view>
+			</view>
+			<!-- date -->
+			<view v-if="isDate">
+				<uni-datetime-picker ref="datetimepicker" :value="dateRange" type="datetimerange" return-type="timestamp" @change="datetimechange" @maskClick="timepickerclose">
+					<view></view>
+				</uni-datetime-picker>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import checkBox from '../uni-tr/table-checkbox.vue'
+
+	const resource = {
+		"reset": "重置",
+		"search": "搜索",
+		"submit": "确定",
+		"filter": "筛选",
+		"gt": "大于等于",
+		"lt": "小于等于",
+		"date": "日期范围"
+	}
+
+	const DropdownType = {
+		Select: "select",
+		Search: "search",
+		Range: "range",
+		Date: "date",
+		Timestamp: "timestamp"
+	}
+
+	export default {
+		name: 'FilterDropdown',
+		emits:['change'],
+		components: {
+			checkBox
+		},
+		options: {
+			virtualHost: true
+		},
+		props: {
+			filterType: {
+				type: String,
+				default: DropdownType.Select
+			},
+			filterData: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			mode: {
+				type: String,
+				default: 'default'
+			},
+			map: {
+				type: Object,
+				default () {
+					return {
+						text: 'text',
+						value: 'value'
+					}
+				}
+			},
+			filterDefaultValue: {
+				type: [Array,String],
+				default () {
+					return ""
+				}
+			}
+		},
+		computed: {
+			canReset() {
+				if (this.isSearch) {
+					return this.filterValue.length > 0
+				}
+				if (this.isSelect) {
+					return this.checkedValues.length > 0
+				}
+				if (this.isRange) {
+					return (this.gtValue.length > 0 && this.ltValue.length > 0)
+				}
+				if (this.isDate) {
+					return this.dateSelect.length > 0
+				}
+				return false
+			},
+			isSelect() {
+				return this.filterType === DropdownType.Select
+			},
+			isSearch() {
+				return this.filterType === DropdownType.Search
+			},
+			isRange() {
+				return this.filterType === DropdownType.Range
+			},
+			isDate() {
+				return (this.filterType === DropdownType.Date || this.filterType === DropdownType.Timestamp)
+			}
+		},
+		watch: {
+			filterData(newVal) {
+				this._copyFilters()
+			},
+			indeterminate(newVal) {
+				this.isIndeterminate = newVal
+			}
+		},
+		data() {
+			return {
+				resource,
+				enabled: true,
+				isOpened: false,
+				dataList: [],
+				filterValue: this.filterDefaultValue,
+				checkedValues: [],
+				gtValue: '',
+				ltValue: '',
+				dateRange: [],
+				dateSelect: []
+			};
+		},
+		created() {
+			this._copyFilters()
+		},
+		methods: {
+			_copyFilters() {
+				let dl = JSON.parse(JSON.stringify(this.filterData))
+				for (let i = 0; i < dl.length; i++) {
+					if (dl[i].checked === undefined) {
+						dl[i].checked = false
+					}
+				}
+				this.dataList = dl
+			},
+			openPopup() {
+				this.isOpened = true
+				if (this.isDate) {
+					this.$nextTick(() => {
+						if (!this.dateRange.length) {
+							this.resetDate()
+						}
+						this.$refs.datetimepicker.show()
+					})
+				}
+			},
+			closePopup() {
+				this.isOpened = false
+			},
+			handleClose(e) {
+				this.closePopup()
+			},
+			resetDate() {
+				let date = new Date()
+				let dateText = date.toISOString().split('T')[0]
+				this.dateRange = [dateText + ' 0:00:00', dateText + ' 23:59:59']
+			},
+			onDropdown(e) {
+				this.openPopup()
+			},
+			onItemClick(e, index) {
+				let items = this.dataList
+				let listItem = items[index]
+				if (listItem.checked === undefined) {
+					items[index].checked = true
+				} else {
+					items[index].checked = !listItem.checked
+				}
+
+				let checkvalues = []
+				for (let i = 0; i < items.length; i++) {
+					const item = items[i]
+					if (item.checked) {
+						checkvalues.push(item.value)
+					}
+				}
+				this.checkedValues = checkvalues
+			},
+			datetimechange(e) {
+				this.closePopup()
+				this.dateRange = e
+				this.dateSelect = e
+				this.$emit('change', {
+					filterType: this.filterType,
+					filter: e
+				})
+			},
+			timepickerclose(e) {
+				this.closePopup()
+			},
+			handleSelectSubmit() {
+				this.closePopup()
+				this.$emit('change', {
+					filterType: this.filterType,
+					filter: this.checkedValues
+				})
+			},
+			handleSelectReset() {
+				if (!this.canReset) {
+					return;
+				}
+				var items = this.dataList
+				for (let i = 0; i < items.length; i++) {
+					let item = items[i]
+					this.$set(item, 'checked', false)
+				}
+				this.checkedValues = []
+				this.handleSelectSubmit()
+			},
+			handleSearchSubmit() {
+				this.closePopup()
+				this.$emit('change', {
+					filterType: this.filterType,
+					filter: this.filterValue
+				})
+			},
+			handleSearchReset() {
+				if (!this.canReset) {
+					return;
+				}
+				this.filterValue = ''
+				this.handleSearchSubmit()
+			},
+			handleRangeSubmit(isReset) {
+				this.closePopup()
+				this.$emit('change', {
+					filterType: this.filterType,
+					filter: isReset === true ? [] : [parseInt(this.gtValue), parseInt(this.ltValue)]
+				})
+			},
+			handleRangeReset() {
+				if (!this.canReset) {
+					return;
+				}
+				this.gtValue = ''
+				this.ltValue = ''
+				this.handleRangeSubmit(true)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #1890ff !default;
+	
+	.flex-r {
+		display: flex;
+		flex-direction: row;
+	}
+
+	.flex-f {
+		flex: 1;
+	}
+
+	.a-i-c {
+		align-items: center;
+	}
+
+	.j-c-c {
+		justify-content: center;
+	}
+
+	.icon-select {
+		width: 14px;
+		height: 16px;
+		border: solid 6px transparent;
+		border-top: solid 6px #ddd;
+		border-bottom: none;
+		background-color: #ddd;
+		background-clip: content-box;
+		box-sizing: border-box;
+	}
+
+	.icon-select.active {
+		background-color: $uni-primary;
+		border-top-color: $uni-primary;
+	}
+
+	.icon-search {
+		width: 12px;
+		height: 16px;
+		position: relative;
+	}
+
+	.icon-search-0 {
+		border: 2px solid #ddd;
+		border-radius: 8px;
+		width: 7px;
+		height: 7px;
+	}
+
+	.icon-search-1 {
+		position: absolute;
+		top: 8px;
+		right: 0;
+		width: 1px;
+		height: 7px;
+		background-color: #ddd;
+		transform: rotate(-45deg);
+	}
+
+	.icon-search.active .icon-search-0 {
+		border-color: $uni-primary;
+	}
+
+	.icon-search.active .icon-search-1 {
+		background-color: $uni-primary;
+	}
+
+	.icon-calendar {
+		color: #ddd;
+		width: 14px;
+		height: 16px;
+	}
+
+	.icon-calendar-0 {
+		height: 4px;
+		margin-top: 3px;
+		margin-bottom: 1px;
+		background-color: #ddd;
+		border-radius: 2px 2px 1px 1px;
+		position: relative;
+	}
+	.icon-calendar-0:before, .icon-calendar-0:after {
+		content: '';
+		position: absolute;
+		top: -3px;
+		width: 4px;
+		height: 3px;
+		border-radius: 1px;
+		background-color: #ddd;
+	}
+	.icon-calendar-0:before {
+		left: 2px;
+	}
+	.icon-calendar-0:after {
+		right: 2px;
+	}
+
+	.icon-calendar-1 {
+		height: 9px;
+		background-color: #ddd;
+		border-radius: 1px 1px 2px 2px;
+	}
+
+	.icon-calendar.active {
+		color: $uni-primary;
+	}
+
+	.icon-calendar.active .icon-calendar-0,
+	.icon-calendar.active .icon-calendar-1,
+	.icon-calendar.active .icon-calendar-0:before,
+	.icon-calendar.active .icon-calendar-0:after {
+		background-color: $uni-primary;
+	}
+
+	.uni-filter-dropdown {
+		position: relative;
+		font-weight: normal;
+	}
+
+	.dropdown-popup {
+		position: absolute;
+		top: 100%;
+		background-color: #fff;
+		box-shadow: 0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d;
+		min-width: 150px;
+		z-index: 1000;
+	}
+
+	.dropdown-popup-left {
+		left: 0;
+	}
+
+	.dropdown-popup-right {
+		right: 0;
+	}
+
+	.uni-dropdown-cover {
+		position: fixed;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		background-color: transparent;
+		z-index: 100;
+	}
+
+	.list {
+		margin-top: 5px;
+		margin-bottom: 5px;
+	}
+
+	.list-item {
+		padding: 5px 10px;
+		text-align: left;
+	}
+
+	.list-item:hover {
+		background-color: #f0f0f0;
+	}
+
+	.check {
+		margin-right: 5px;
+	}
+
+	.search-area {
+		padding: 10px;
+	}
+
+	.search-input {
+		font-size: 12px;
+		border: 1px solid #f0f0f0;
+		border-radius: 3px;
+		padding: 2px 5px;
+		min-width: 150px;
+		text-align: left;
+	}
+
+	.input-label {
+		margin: 10px 10px 5px 10px;
+		text-align: left;
+	}
+
+	.input {
+		font-size: 12px;
+		border: 1px solid #f0f0f0;
+		border-radius: 3px;
+		margin: 10px;
+		padding: 2px 5px;
+		min-width: 150px;
+		text-align: left;
+	}
+
+	.opera-area {
+		cursor: default;
+		border-top: 1px solid #ddd;
+		padding: 5px;
+	}
+
+	.opera-area .btn {
+		font-size: 12px;
+		border-radius: 3px;
+		margin: 5px;
+		padding: 4px 4px;
+	}
+
+	.btn-default {
+		border: 1px solid #ddd;
+	}
+
+	.btn-default.disable {
+		border-color: transparent;
+	}
+
+	.btn-submit {
+		background-color: $uni-primary;
+		color: #ffffff;
+	}
+</style>
diff --git a/uni_modules/uni-table/components/uni-th/uni-th.vue b/uni_modules/uni-table/components/uni-th/uni-th.vue
new file mode 100644
index 0000000..a39ae6c
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-th/uni-th.vue
@@ -0,0 +1,295 @@
+<template>
+	<!-- #ifdef H5 -->
+	<th :rowspan="rowspan" :colspan="colspan" class="uni-table-th" :class="{ 'table--border': border }" :style="{ width: customWidth + 'px', 'text-align': align }">
+		<view class="uni-table-th-row">
+			<view class="uni-table-th-content" :style="{ 'justify-content': contentAlign }" @click="sort">
+				<slot></slot>
+				<view v-if="sortable" class="arrow-box">
+					<text class="arrow up" :class="{ active: ascending }" @click.stop="ascendingFn"></text>
+					<text class="arrow down" :class="{ active: descending }" @click.stop="descendingFn"></text>
+				</view>
+			</view>
+			<dropdown v-if="filterType || filterData.length" :filterDefaultValue="filterDefaultValue" :filterData="filterData" :filterType="filterType" @change="ondropdown"></dropdown>
+		</view>
+	</th>
+	<!-- #endif -->
+	<!-- #ifndef H5 -->
+	<view class="uni-table-th" :class="{ 'table--border': border }" :style="{ width: customWidth + 'px', 'text-align': align }"><slot></slot></view>
+	<!-- #endif -->
+</template>
+
+<script>
+	// #ifdef H5
+	import dropdown from './filter-dropdown.vue'
+	// #endif
+/**
+ * Th 表头
+ * @description 表格内的表头单元格组件
+ * @tutorial https://ext.dcloud.net.cn/plugin?id=3270
+ * @property {Number | String} 	width 	单元格宽度(支持纯数字、携带单位px或rpx)
+ * @property {Boolean} 	sortable 					是否启用排序
+ * @property {Number} 	align = [left|center|right]	单元格对齐方式
+ * @value left   	单元格文字左侧对齐
+ * @value center	单元格文字居中
+ * @value right		单元格文字右侧对齐
+ * @property {Array}	filterData 筛选数据
+ * @property {String}	filterType	[search|select] 筛选类型
+ * @value search	关键字搜素
+ * @value select	条件选择
+ * @event {Function} sort-change 排序触发事件
+ */
+export default {
+	name: 'uniTh',
+	options: {
+		// #ifdef MP-TOUTIAO
+		virtualHost: false,
+		// #endif
+		// #ifndef MP-TOUTIAO
+		virtualHost: true
+		// #endif
+	},
+	components: {
+		// #ifdef H5
+		dropdown
+		// #endif
+	},
+	emits:['sort-change','filter-change'],
+	props: {
+		width: {
+			type: [String, Number],
+			default: ''
+		},
+		align: {
+			type: String,
+			default: 'left'
+		},
+		rowspan: {
+			type: [Number, String],
+			default: 1
+		},
+		colspan: {
+			type: [Number, String],
+			default: 1
+		},
+		sortable: {
+			type: Boolean,
+			default: false
+		},
+		filterType: {
+			type: String,
+			default: ""
+		},
+		filterData: {
+			type: Array,
+			default () {
+				return []
+			}
+		},
+		filterDefaultValue: {
+			type: [Array,String],
+			default () {
+				return ""
+			}
+		}
+	},
+	data() {
+		return {
+			border: false,
+			ascending: false,
+			descending: false
+		}
+	},
+	computed: {
+		// 根据props中的width属性 自动匹配当前th的宽度(px)
+		customWidth(){
+			if(typeof this.width === 'number'){
+				return this.width
+			} else if(typeof this.width === 'string') {
+				let regexHaveUnitPx = new RegExp(/^[1-9][0-9]*px$/g)
+				let regexHaveUnitRpx = new RegExp(/^[1-9][0-9]*rpx$/g)
+				let regexHaveNotUnit = new RegExp(/^[1-9][0-9]*$/g)
+				if (this.width.match(regexHaveUnitPx) !== null) { // 携带了 px
+					return this.width.replace('px', '')
+				} else if (this.width.match(regexHaveUnitRpx) !== null) { // 携带了 rpx
+					let numberRpx = Number(this.width.replace('rpx', ''))
+					// #ifdef MP-WEIXIN
+					let widthCoe = uni.getWindowInfo().screenWidth / 750
+					// #endif
+					// #ifndef MP-WEIXIN
+					let widthCoe = uni.getSystemInfoSync().screenWidth / 750
+					// #endif
+					return Math.round(numberRpx * widthCoe)
+				} else if (this.width.match(regexHaveNotUnit) !== null) { // 未携带 rpx或px 的纯数字 String
+					return this.width
+				} else { // 不符合格式
+					return ''
+				}
+			} else {
+				return ''
+			}
+		},
+		contentAlign() {
+			let align = 'left'
+			switch (this.align) {
+				case 'left':
+					align = 'flex-start'
+					break
+				case 'center':
+					align = 'center'
+					break
+				case 'right':
+					align = 'flex-end'
+					break
+			}
+			return align
+		}
+	},
+	created() {
+		this.root = this.getTable('uniTable')
+		this.rootTr = this.getTable('uniTr')
+		this.rootTr.minWidthUpdate(this.customWidth ? this.customWidth : 140)
+		this.border = this.root.border
+		this.root.thChildren.push(this)
+	},
+	methods: {
+		sort() {
+			if (!this.sortable) return
+			this.clearOther()
+			if (!this.ascending && !this.descending) {
+				this.ascending = true
+				this.$emit('sort-change', { order: 'ascending' })
+				return
+			}
+			if (this.ascending && !this.descending) {
+				this.ascending = false
+				this.descending = true
+				this.$emit('sort-change', { order: 'descending' })
+				return
+			}
+
+			if (!this.ascending && this.descending) {
+				this.ascending = false
+				this.descending = false
+				this.$emit('sort-change', { order: null })
+			}
+		},
+		ascendingFn() {
+			this.clearOther()
+			this.ascending = !this.ascending
+			this.descending = false
+			this.$emit('sort-change', { order: this.ascending ? 'ascending' : null })
+		},
+		descendingFn() {
+			this.clearOther()
+			this.descending = !this.descending
+			this.ascending = false
+			this.$emit('sort-change', { order: this.descending ? 'descending' : null })
+		},
+		clearOther() {
+			this.root.thChildren.map(item => {
+				if (item !== this) {
+					item.ascending = false
+					item.descending = false
+				}
+				return item
+			})
+		},
+		ondropdown(e) {
+			this.$emit("filter-change", e)
+		},
+		/**
+		 * 获取父元素实例
+		 */
+		getTable(name) {
+			let parent = this.$parent
+			let parentName = parent.$options.name
+			while (parentName !== name) {
+				parent = parent.$parent
+				if (!parent) return false
+				parentName = parent.$options.name
+			}
+			return parent
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+$border-color: #ebeef5;
+$uni-primary: #007aff !default;
+
+.uni-table-th {
+	padding: 12px 10px;
+	/* #ifndef APP-NVUE */
+	display: table-cell;
+	box-sizing: border-box;
+	/* #endif */
+	font-size: 14px;
+	font-weight: bold;
+	color: #909399;
+	border-bottom: 1px $border-color solid;
+}
+
+.uni-table-th-row {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: row;
+}
+
+.table--border {
+	border-right: 1px $border-color solid;
+}
+.uni-table-th-content {
+	display: flex;
+	align-items: center;
+	flex: 1;
+}
+.arrow-box {
+}
+.arrow {
+	display: block;
+	position: relative;
+	width: 10px;
+	height: 8px;
+	// border: 1px red solid;
+	left: 5px;
+	overflow: hidden;
+	cursor: pointer;
+}
+.down {
+	top: 3px;
+	::after {
+		content: '';
+		width: 8px;
+		height: 8px;
+		position: absolute;
+		left: 2px;
+		top: -5px;
+		transform: rotate(45deg);
+		background-color: #ccc;
+	}
+	&.active {
+		::after {
+			background-color: $uni-primary;
+		}
+	}
+}
+.up {
+	::after {
+		content: '';
+		width: 8px;
+		height: 8px;
+		position: absolute;
+		left: 2px;
+		top: 5px;
+		transform: rotate(45deg);
+		background-color: #ccc;
+	}
+	&.active {
+		::after {
+			background-color: $uni-primary;
+		}
+	}
+}
+</style>
diff --git a/uni_modules/uni-table/components/uni-thead/uni-thead.vue b/uni_modules/uni-table/components/uni-thead/uni-thead.vue
new file mode 100644
index 0000000..53b5c4c
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-thead/uni-thead.vue
@@ -0,0 +1,137 @@
+<template>
+	<!-- #ifdef H5 -->
+	<thead class="uni-table-thead">
+		<tr class="uni-table-tr">
+			<th :rowspan="rowspan" colspan="1" class="checkbox" :class="{ 'tr-table--border': border }">
+				<table-checkbox :indeterminate="indeterminate" :checked="checked"
+					@checkboxSelected="checkboxSelected"></table-checkbox>
+			</th>
+		</tr>
+		<slot></slot>
+	</thead>
+	<!-- #endif -->
+	<!-- #ifndef H5 -->
+	<view class="uni-table-thead">
+		<slot></slot>
+	</view>
+	<!-- #endif -->
+</template>
+
+<script>
+	import tableCheckbox from '../uni-tr/table-checkbox.vue'
+	export default {
+		name: 'uniThead',
+		components: {
+			tableCheckbox
+		},
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		data() {
+			return {
+				border: false,
+				selection: false,
+				rowspan: 1,
+				indeterminate: false,
+				checked: false
+			}
+		},
+		created() {
+			this.root = this.getTable()
+			// #ifdef H5
+			this.root.theadChildren = this
+			// #endif
+			this.border = this.root.border
+			this.selection = this.root.type
+		},
+		methods: {
+			init(self) {
+				this.rowspan++
+			},
+			checkboxSelected(e) {
+				this.indeterminate = false
+				const backIndexData = this.root.backIndexData
+				const data = this.root.trChildren.filter(v => !v.disabled && v.keyValue)
+				if (backIndexData.length === data.length) {
+					this.checked = false
+					this.root.clearSelection()
+				} else {
+					this.checked = true
+					this.root.selectionAll()
+				}
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getTable(name = 'uniTable') {
+				let parent = this.$parent
+				let parentName = parent.$options.name
+				while (parentName !== name) {
+					parent = parent.$parent
+					if (!parent) return false
+					parentName = parent.$options.name
+				}
+				return parent
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$border-color: #ebeef5;
+
+	.uni-table-thead {
+		display: table-header-group;
+	}
+
+	.uni-table-tr {
+		/* #ifndef APP-NVUE */
+		display: table-row;
+		transition: all 0.3s;
+		box-sizing: border-box;
+		/* #endif */
+		border: 1px red solid;
+		background-color: #fafafa;
+	}
+
+	.checkbox {
+		padding: 0 8px;
+		width: 26px;
+		padding-left: 12px;
+		/* #ifndef APP-NVUE */
+		display: table-cell;
+		vertical-align: middle;
+		/* #endif */
+		color: #333;
+		font-weight: 500;
+		border-bottom: 1px $border-color solid;
+		font-size: 14px;
+		// text-align: center;
+	}
+
+	.tr-table--border {
+		border-right: 1px $border-color solid;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-table-tr {
+		::v-deep .uni-table-th {
+			&.table--border:last-child {
+				// border-right: none;
+			}
+		}
+
+		::v-deep .uni-table-td {
+			&.table--border:last-child {
+				// border-right: none;
+			}
+		}
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-table/components/uni-tr/table-checkbox.vue b/uni_modules/uni-table/components/uni-tr/table-checkbox.vue
new file mode 100644
index 0000000..1089187
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-tr/table-checkbox.vue
@@ -0,0 +1,179 @@
+<template>
+	<view class="uni-table-checkbox" @click="selected">
+		<view v-if="!indeterminate" class="checkbox__inner" :class="{'is-checked':isChecked,'is-disable':isDisabled}">
+			<view class="checkbox__inner-icon"></view>
+		</view>
+		<view v-else class="checkbox__inner checkbox--indeterminate">
+			<view class="checkbox__inner-icon"></view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'TableCheckbox',
+		emits:['checkboxSelected'],
+		props: {
+			indeterminate: {
+				type: Boolean,
+				default: false
+			},
+			checked: {
+				type: [Boolean,String],
+				default: false
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			index: {
+				type: Number,
+				default: -1
+			},
+			cellData: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		watch:{
+			checked(newVal){
+				if(typeof this.checked === 'boolean'){
+					this.isChecked = newVal
+				}else{
+					this.isChecked = true
+				}
+			},
+			indeterminate(newVal){
+				this.isIndeterminate = newVal
+			}
+		},
+		data() {
+			return {
+				isChecked: false,
+				isDisabled: false,
+				isIndeterminate:false
+			}
+		},
+		created() {
+			if(typeof this.checked === 'boolean'){
+				this.isChecked = this.checked
+			}
+			this.isDisabled = this.disabled
+		},
+		methods: {
+			selected() {
+				if (this.isDisabled) return
+				this.isIndeterminate = false
+				this.isChecked = !this.isChecked
+				this.$emit('checkboxSelected', {
+					checked: this.isChecked,
+					data: this.cellData
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$uni-primary: #007aff !default;
+	$border-color: #DCDFE6;
+	$disable:0.4;
+
+	.uni-table-checkbox {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		position: relative;
+		margin: 5px 0;
+		cursor: pointer;
+
+		// 多选样式
+		.checkbox__inner {
+			/* #ifndef APP-NVUE */
+			flex-shrink: 0;
+			box-sizing: border-box;
+			/* #endif */
+			position: relative;
+			width: 16px;
+			height: 16px;
+			border: 1px solid $border-color;
+			border-radius: 2px;
+			background-color: #fff;
+			z-index: 1;
+
+			.checkbox__inner-icon {
+				position: absolute;
+				/* #ifdef APP-NVUE */
+				top: 2px;
+				/* #endif */
+				/* #ifndef APP-NVUE */
+				top: 2px;
+				/* #endif */
+				left: 5px;
+				height: 7px;
+				width: 3px;
+				border: 1px solid #fff;
+				border-left: 0;
+				border-top: 0;
+				opacity: 0;
+				transform-origin: center;
+				transform: rotate(45deg);
+				box-sizing: content-box;
+			}
+
+			&.checkbox--indeterminate {
+				border-color: $uni-primary;
+				background-color: $uni-primary;
+
+				.checkbox__inner-icon {
+					position: absolute;
+					opacity: 1;
+					transform: rotate(0deg);
+					height: 2px;
+					top: 0;
+					bottom: 0;
+					margin: auto;
+					left: 0px;
+					right: 0px;
+					bottom: 0;
+					width: auto;
+					border: none;
+					border-radius: 2px;
+					transform: scale(0.5);
+					background-color: #fff;
+				}
+			}
+			&:hover{
+				border-color: $uni-primary;
+			}
+			// 禁用
+			&.is-disable {
+				/* #ifdef H5 */
+				cursor: not-allowed;
+				/* #endif */
+				background-color: #F2F6FC;
+				border-color: $border-color;
+			}
+
+			// 选中
+			&.is-checked {
+				border-color: $uni-primary;
+				background-color: $uni-primary;
+
+				.checkbox__inner-icon {
+					opacity: 1;
+					transform: rotate(45deg);
+				}
+
+				// 选中禁用
+				&.is-disable {
+					opacity: $disable;
+				}
+			}
+			
+		}
+	}
+</style>
diff --git a/uni_modules/uni-table/components/uni-tr/uni-tr.vue b/uni_modules/uni-table/components/uni-tr/uni-tr.vue
new file mode 100644
index 0000000..3fb76f4
--- /dev/null
+++ b/uni_modules/uni-table/components/uni-tr/uni-tr.vue
@@ -0,0 +1,184 @@
+<template>
+	<!-- #ifdef H5 -->
+	<tr class="uni-table-tr">
+		<th v-if="selection === 'selection' && ishead" class="checkbox" :class="{ 'tr-table--border': border }">
+			<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled"
+				@checkboxSelected="checkboxSelected"></table-checkbox>
+		</th>
+		<slot></slot>
+		<!-- <uni-th class="th-fixed">123</uni-th> -->
+	</tr>
+	<!-- #endif -->
+	<!-- #ifndef H5 -->
+	<view class="uni-table-tr">
+		<view v-if="selection === 'selection' " class="checkbox" :class="{ 'tr-table--border': border }">
+			<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled"
+				@checkboxSelected="checkboxSelected"></table-checkbox>
+		</view>
+		<slot></slot>
+	</view>
+	<!-- #endif -->
+</template>
+
+<script>
+	import tableCheckbox from './table-checkbox.vue'
+	/**
+	 * Tr 表格行组件
+	 * @description 表格行组件 仅包含 th,td 组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=
+	 */
+	export default {
+		name: 'uniTr',
+		components: {
+			tableCheckbox
+		},
+		props: {
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			keyValue: {
+				type: [String, Number],
+				default: ''
+			}
+		},
+		options: {
+			// #ifdef MP-TOUTIAO
+			virtualHost: false,
+			// #endif
+			// #ifndef MP-TOUTIAO
+			virtualHost: true
+			// #endif
+		},
+		data() {
+			return {
+				value: false,
+				border: false,
+				selection: false,
+				widthThArr: [],
+				ishead: true,
+				checked: false,
+				indeterminate: false
+			}
+		},
+		created() {
+			this.root = this.getTable()
+			this.head = this.getTable('uniThead')
+			if (this.head) {
+				this.ishead = false
+				this.head.init(this)
+			}
+			this.border = this.root.border
+			this.selection = this.root.type
+			this.root.trChildren.push(this)
+			const rowData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
+			if (rowData) {
+				this.rowData = rowData
+			}
+			this.root.isNodata()
+		},
+		mounted() {
+			if (this.widthThArr.length > 0) {
+				const selectionWidth = this.selection === 'selection' ? 50 : 0
+				this.root.minWidth = Number(this.widthThArr.reduce((a, b) => Number(a) + Number(b))) + selectionWidth;
+			}
+		},
+		// #ifndef VUE3
+		destroyed() {
+			const index = this.root.trChildren.findIndex(i => i === this)
+			this.root.trChildren.splice(index, 1)
+			this.root.isNodata()
+		},
+		// #endif
+		// #ifdef VUE3
+		unmounted() {
+			const index = this.root.trChildren.findIndex(i => i === this)
+			this.root.trChildren.splice(index, 1)
+			this.root.isNodata()
+		},
+		// #endif
+		methods: {
+			minWidthUpdate(width) {
+				this.widthThArr.push(width)
+				if (this.widthThArr.length > 0) {
+					const selectionWidth = this.selection === 'selection' ? 50 : 0;
+					this.root.minWidth = Number(this.widthThArr.reduce((a, b) => Number(a) + Number(b))) + selectionWidth;
+				}
+			},
+			// 选中
+			checkboxSelected(e) {
+				let rootData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
+				this.checked = e.checked
+				this.root.check(rootData || this, e.checked, rootData ? this.keyValue : null)
+			},
+			change(e) {
+				this.root.trChildren.forEach(item => {
+					if (item === this) {
+						this.root.check(this, e.detail.value.length > 0 ? true : false)
+					}
+				})
+			},
+			/**
+			 * 获取父元素实例
+			 */
+			getTable(name = 'uniTable') {
+				let parent = this.$parent
+				let parentName = parent.$options.name
+				while (parentName !== name) {
+					parent = parent.$parent
+					if (!parent) return false
+					parentName = parent.$options.name
+				}
+				return parent
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$border-color: #ebeef5;
+
+	.uni-table-tr {
+		/* #ifndef APP-NVUE */
+		display: table-row;
+		transition: all 0.3s;
+		box-sizing: border-box;
+		/* #endif */
+	}
+
+	.checkbox {
+		padding: 0 8px;
+		width: 26px;
+		padding-left: 12px;
+		/* #ifndef APP-NVUE */
+		display: table-cell;
+		vertical-align: middle;
+		/* #endif */
+		color: #333;
+		font-weight: 500;
+		border-bottom: 1px $border-color solid;
+		font-size: 14px;
+		// text-align: center;
+	}
+
+	.tr-table--border {
+		border-right: 1px $border-color solid;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-table-tr {
+		::v-deep .uni-table-th {
+			&.table--border:last-child {
+				// border-right: none;
+			}
+		}
+
+		::v-deep .uni-table-td {
+			&.table--border:last-child {
+				// border-right: none;
+			}
+		}
+	}
+
+	/* #endif */
+</style>
diff --git a/uni_modules/uni-table/i18n/en.json b/uni_modules/uni-table/i18n/en.json
new file mode 100644
index 0000000..e32023c
--- /dev/null
+++ b/uni_modules/uni-table/i18n/en.json
@@ -0,0 +1,9 @@
+{
+	"filter-dropdown.reset": "Reset",
+	"filter-dropdown.search": "Search",
+	"filter-dropdown.submit": "Submit",
+	"filter-dropdown.filter": "Filter",
+	"filter-dropdown.gt": "Greater or equal to",
+	"filter-dropdown.lt": "Less than or equal to",
+	"filter-dropdown.date": "Date"
+}
diff --git a/uni_modules/uni-table/i18n/es.json b/uni_modules/uni-table/i18n/es.json
new file mode 100644
index 0000000..9afd04b
--- /dev/null
+++ b/uni_modules/uni-table/i18n/es.json
@@ -0,0 +1,9 @@
+{
+	"filter-dropdown.reset": "Reiniciar",
+	"filter-dropdown.search": "Búsqueda",
+	"filter-dropdown.submit": "Entregar",
+	"filter-dropdown.filter": "Filtrar",
+	"filter-dropdown.gt": "Mayor o igual a",
+	"filter-dropdown.lt": "Menos que o igual a",
+	"filter-dropdown.date": "Fecha"
+}
diff --git a/uni_modules/uni-table/i18n/fr.json b/uni_modules/uni-table/i18n/fr.json
new file mode 100644
index 0000000..b006237
--- /dev/null
+++ b/uni_modules/uni-table/i18n/fr.json
@@ -0,0 +1,9 @@
+{
+	"filter-dropdown.reset": "Réinitialiser",
+	"filter-dropdown.search": "Chercher",
+	"filter-dropdown.submit": "Soumettre",
+	"filter-dropdown.filter": "Filtre",
+	"filter-dropdown.gt": "Supérieur ou égal à",
+	"filter-dropdown.lt": "Inférieur ou égal à",
+	"filter-dropdown.date": "Date"
+}
diff --git a/uni_modules/uni-table/i18n/index.js b/uni_modules/uni-table/i18n/index.js
new file mode 100644
index 0000000..2469dd0
--- /dev/null
+++ b/uni_modules/uni-table/i18n/index.js
@@ -0,0 +1,12 @@
+import en from './en.json'
+import es from './es.json'
+import fr from './fr.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	es,
+	fr,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}
diff --git a/uni_modules/uni-table/i18n/zh-Hans.json b/uni_modules/uni-table/i18n/zh-Hans.json
new file mode 100644
index 0000000..862af17
--- /dev/null
+++ b/uni_modules/uni-table/i18n/zh-Hans.json
@@ -0,0 +1,9 @@
+{
+	"filter-dropdown.reset": "重置",
+	"filter-dropdown.search": "搜索",
+	"filter-dropdown.submit": "确定",
+	"filter-dropdown.filter": "筛选",
+	"filter-dropdown.gt": "大于等于",
+	"filter-dropdown.lt": "小于等于",
+	"filter-dropdown.date": "日期范围"
+}
diff --git a/uni_modules/uni-table/i18n/zh-Hant.json b/uni_modules/uni-table/i18n/zh-Hant.json
new file mode 100644
index 0000000..64f8061
--- /dev/null
+++ b/uni_modules/uni-table/i18n/zh-Hant.json
@@ -0,0 +1,9 @@
+{
+	"filter-dropdown.reset": "重置",
+	"filter-dropdown.search": "搜索",
+	"filter-dropdown.submit": "確定",
+	"filter-dropdown.filter": "篩選",
+	"filter-dropdown.gt": "大於等於",
+	"filter-dropdown.lt": "小於等於",
+	"filter-dropdown.date": "日期範圍"
+}
diff --git a/uni_modules/uni-table/package.json b/uni_modules/uni-table/package.json
new file mode 100644
index 0000000..19454c7
--- /dev/null
+++ b/uni_modules/uni-table/package.json
@@ -0,0 +1,84 @@
+{
+  "id": "uni-table",
+  "displayName": "uni-table 表格",
+  "version": "1.2.8",
+  "description": "表格组件,多用于展示多条结构类似的数据,如",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "table",
+    "表格"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss","uni-datetime-picker"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "n",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
diff --git a/uni_modules/uni-table/readme.md b/uni_modules/uni-table/readme.md
new file mode 100644
index 0000000..bb08c79
--- /dev/null
+++ b/uni_modules/uni-table/readme.md
@@ -0,0 +1,13 @@
+
+
+## Table 表单
+> 组件名:``uni-table``,代码块: `uTable`。
+
+用于展示多条结构类似的数据
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-table)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
+
+
diff --git a/uni_modules/uni-tag/changelog.md b/uni_modules/uni-tag/changelog.md
new file mode 100644
index 0000000..ddee87a
--- /dev/null
+++ b/uni_modules/uni-tag/changelog.md
@@ -0,0 +1,23 @@
+## 2.1.1(2024-03-20)
+- 优化 app下边框过窄导致不显示的bug
+## 2.1.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-tag](https://uniapp.dcloud.io/component/uniui/uni-tag)
+## 2.0.0(2021-11-09)
+- 新增 提供组件设计资源,组件样式调整
+- 移除 插槽
+- 移除 type 属性的 royal 选项
+## 1.1.1(2021-08-11)
+- type 不是 default 时,size 为 small 字体大小显示不正确
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-06-18)
+- 修复 uni-tag 在字节跳动小程序上 css 类名编译错误的 bug
+## 1.0.6(2021-06-04)
+- 修复 未定义 sass 变量 "$uni-color-royal" 的bug
+## 1.0.5(2021-05-10)
+- 修复 royal 类型无效的bug
+- 修复 uni-tag 宽度不自适应的bug
+- 新增 uni-tag 支持属性 custom-style 自定义样式
+## 1.0.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-tag/components/uni-tag/uni-tag.vue b/uni_modules/uni-tag/components/uni-tag/uni-tag.vue
new file mode 100644
index 0000000..7274436
--- /dev/null
+++ b/uni_modules/uni-tag/components/uni-tag/uni-tag.vue
@@ -0,0 +1,252 @@
+<template>
+	<text class="uni-tag" v-if="text" :class="classes" :style="customStyle" @click="onClick">{{text}}</text>
+</template>
+
+<script>
+	/**
+	 * Tag 标签
+	 * @description 用于展示1个或多个文字标签,可点击切换选中、不选中的状态
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=35
+	 * @property {String} text 标签内容
+	 * @property {String} size = [default|small|mini] 大小尺寸
+	 * 	@value default 正常
+	 * 	@value small 小尺寸
+	 * 	@value mini 迷你尺寸
+	 * @property {String} type = [default|primary|success|warning|error]  颜色类型
+	 * 	@value default 灰色
+	 * 	@value primary 蓝色
+	 * 	@value success 绿色
+	 * 	@value warning 黄色
+	 * 	@value error 红色
+	 * @property {Boolean} disabled = [true|false] 是否为禁用状态
+	 * @property {Boolean} inverted = [true|false] 是否无需背景颜色(空心标签)
+	 * @property {Boolean} circle = [true|false] 是否为圆角
+	 * @event {Function} click 点击 Tag 触发事件
+	 */
+
+	export default {
+		name: "UniTag",
+		emits: ['click'],
+		props: {
+			type: {
+				// 标签类型default、primary、success、warning、error、royal
+				type: String,
+				default: "default"
+			},
+			size: {
+				// 标签大小 normal, small
+				type: String,
+				default: "normal"
+			},
+			// 标签内容
+			text: {
+				type: String,
+				default: ""
+			},
+			disabled: {
+				// 是否为禁用状态
+				type: [Boolean, String],
+				default: false
+			},
+			inverted: {
+				// 是否为空心
+				type: [Boolean, String],
+				default: false
+			},
+			circle: {
+				// 是否为圆角样式
+				type: [Boolean, String],
+				default: false
+			},
+			mark: {
+				// 是否为标记样式
+				type: [Boolean, String],
+				default: false
+			},
+			customStyle: {
+				type: String,
+				default: ''
+			}
+		},
+		computed: {
+			classes() {
+				const {
+					type,
+					disabled,
+					inverted,
+					circle,
+					mark,
+					size,
+					isTrue
+				} = this
+				const classArr = [
+					'uni-tag--' + type,
+					'uni-tag--' + size,
+					isTrue(disabled) ? 'uni-tag--disabled' : '',
+					isTrue(inverted) ? 'uni-tag--' + type + '--inverted' : '',
+					isTrue(circle) ? 'uni-tag--circle' : '',
+					isTrue(mark) ? 'uni-tag--mark' : '',
+					// type === 'default' ? 'uni-tag--default' : 'uni-tag-text',
+					isTrue(inverted) ? 'uni-tag--inverted uni-tag-text--' + type : '',
+					size === 'small' ? 'uni-tag-text--small' : ''
+				]
+				// 返回类的字符串,兼容字节小程序
+				return classArr.join(' ')
+			}
+		},
+		methods: {
+			isTrue(value) {
+				return value === true || value === 'true'
+			},
+			onClick() {
+				if (this.isTrue(this.disabled)) return
+				this.$emit("click");
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$uni-primary: #2979ff !default;
+	$uni-success: #18bc37 !default;
+	$uni-warning: #f3a73f !default;
+	$uni-error: #e43d33 !default;
+	$uni-info: #8f939c !default;
+
+
+	$tag-default-pd: 4px 7px;
+	$tag-small-pd: 2px 5px;
+	$tag-mini-pd: 1px 3px;
+
+	.uni-tag {
+		line-height: 14px;
+		font-size: 12px;
+		font-weight: 200;
+		padding: $tag-default-pd;
+		color: #fff;
+		border-radius: 3px;
+		background-color: $uni-info;
+		border-width: 1px;
+		border-style: solid;
+		border-color: $uni-info;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+
+		// size attr
+		&--default {
+			font-size: 12px;
+		}
+
+		&--default--inverted {
+			color: $uni-info;
+			border-color: $uni-info;
+		}
+
+		&--small {
+			padding: $tag-small-pd;
+			font-size: 12px;
+			border-radius: 2px;
+		}
+
+		&--mini {
+			padding: $tag-mini-pd;
+			font-size: 12px;
+			border-radius: 2px;
+		}
+
+		// type attr
+		&--primary {
+			background-color: $uni-primary;
+			border-color: $uni-primary;
+			color: #fff;
+		}
+
+		&--success {
+			color: #fff;
+			background-color: $uni-success;
+			border-color: $uni-success;
+		}
+
+		&--warning {
+			color: #fff;
+			background-color: $uni-warning;
+			border-color: $uni-warning;
+		}
+
+		&--error {
+			color: #fff;
+			background-color: $uni-error;
+			border-color: $uni-error;
+		}
+
+		&--primary--inverted {
+			color: $uni-primary;
+			border-color: $uni-primary;
+		}
+
+		&--success--inverted {
+			color: $uni-success;
+			border-color: $uni-success;
+		}
+
+		&--warning--inverted {
+			color: $uni-warning;
+			border-color: $uni-warning;
+		}
+
+		&--error--inverted {
+			color: $uni-error;
+			border-color: $uni-error;
+		}
+
+		&--inverted {
+			background-color: #fff;
+		}
+
+		// other attr
+		&--circle {
+			border-radius: 15px;
+		}
+
+		&--mark {
+			border-top-left-radius: 0;
+			border-bottom-left-radius: 0;
+			border-top-right-radius: 15px;
+			border-bottom-right-radius: 15px;
+		}
+
+		&--disabled {
+			opacity: 0.5;
+			/* #ifdef H5 */
+			cursor: not-allowed;
+			/* #endif */
+		}
+	}
+
+
+	.uni-tag-text {
+		color: #fff;
+		font-size: 14px;
+
+		&--primary {
+			color: $uni-primary;
+		}
+
+		&--success {
+			color: $uni-success;
+		}
+
+		&--warning {
+			color: $uni-warning;
+		}
+
+		&--error {
+			color: $uni-error;
+		}
+
+		&--small {
+			font-size: 12px;
+		}
+	}
+</style>
diff --git a/uni_modules/uni-tag/package.json b/uni_modules/uni-tag/package.json
new file mode 100644
index 0000000..71b41eb
--- /dev/null
+++ b/uni_modules/uni-tag/package.json
@@ -0,0 +1,84 @@
+{
+  "id": "uni-tag",
+  "displayName": "uni-tag 标签",
+  "version": "2.1.1",
+  "description": "Tag 组件,用于展示1个或多个文字标签,可点击切换选中、不选中的状态。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "",
+    "tag",
+    "标签"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-tag/readme.md b/uni_modules/uni-tag/readme.md
new file mode 100644
index 0000000..6e78ff5
--- /dev/null
+++ b/uni_modules/uni-tag/readme.md
@@ -0,0 +1,13 @@
+
+
+## Tag 标签
+> **组件名:uni-tag**
+> 代码块: `uTag`
+
+
+用于展示1个或多个文字标签,可点击切换选中、不选中的状态 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-tag)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
diff --git a/uni_modules/uni-title/changelog.md b/uni_modules/uni-title/changelog.md
new file mode 100644
index 0000000..7626216
--- /dev/null
+++ b/uni_modules/uni-title/changelog.md
@@ -0,0 +1,10 @@
+## 1.1.1(2022-05-19)
+- 修改组件描述
+## 1.1.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-title](https://uniapp.dcloud.io/component/uniui/uni-title)
+## 1.0.2(2021-05-12)
+- 新增 示例地址
+- 修复 示例项目缺少组件的Bug
+## 1.0.1(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-title/components/uni-title/uni-title.vue b/uni_modules/uni-title/components/uni-title/uni-title.vue
new file mode 100644
index 0000000..bf4f926
--- /dev/null
+++ b/uni_modules/uni-title/components/uni-title/uni-title.vue
@@ -0,0 +1,171 @@
+<template>
+	<view class="uni-title__box" :style="{'align-items':textAlign}">
+		<text class="uni-title__base" :class="['uni-'+type]" :style="{'color':color}">{{title}}</text>
+	</view>
+</template>
+
+<script>
+	/**
+	 * Title 标题
+	 * @description 标题,通常用于记录页面标题,使用当前组件,uni-app 如果开启统计,将会自动统计页面标题
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=1066
+	 * @property {String} type = [h1|h2|h3|h4|h5] 标题类型
+	 * 	@value h1 一级标题
+	 * 	@value h2 二级标题
+	 * 	@value h3 三级标题
+	 * 	@value h4 四级标题
+	 * 	@value h5 五级标题
+	 * @property {String} title 标题内容
+	 * @property {String} align = [left|center|right] 对齐方式
+	 * 	@value left 做对齐
+	 * 	@value center 居中对齐
+	 * 	@value right 右对齐
+	 * @property {String} color 字体颜色
+	 * @property {Boolean} stat = [true|false] 是否开启统计功能呢,如不填写type值,默认为开启,填写 type 属性,默认为关闭
+	 */
+	export default {
+		name:"UniTitle",
+		props: {
+			type: {
+				type: String,
+				default: ''
+			},
+			title: {
+				type: String,
+				default: ''
+			},
+			align: {
+				type: String,
+				default: 'left'
+			},
+			color: {
+				type: String,
+				default: '#333333'
+			},
+			stat: {
+				type: [Boolean, String],
+				default: ''
+			}
+		},
+		data() {
+			return {
+
+			};
+		},
+		computed: {
+			textAlign() {
+				let align = 'center';
+				switch (this.align) {
+					case 'left':
+						align = 'flex-start'
+						break;
+					case 'center':
+						align = 'center'
+						break;
+					case 'right':
+						align = 'flex-end'
+						break;
+				}
+				return align
+			}
+		},
+		watch: {
+			title(newVal) {
+				if (this.isOpenStat()) {
+					// 上报数据
+					if (uni.report) {
+						uni.report('title', this.title)
+					}
+				}
+			}
+		},
+		mounted() {
+			if (this.isOpenStat()) {
+				// 上报数据
+				if (uni.report) {
+					uni.report('title', this.title)
+				}
+			}
+		},
+		methods: {
+			isOpenStat() {
+				if (this.stat === '') {
+					this.isStat = false
+				}
+				let stat_type = (typeof(this.stat) === 'boolean' && this.stat) || (typeof(this.stat) === 'string' && this.stat !==
+					'')
+				if (this.type === "") {
+					this.isStat = true
+					if (this.stat.toString() === 'false') {
+						this.isStat = false
+					}
+				}
+
+				if (this.type !== '') {
+					this.isStat = true
+					if (stat_type) {
+						this.isStat = true
+					} else {
+						this.isStat = false
+					}
+				}
+				return this.isStat
+			}
+		}
+	}
+</script>
+
+<style>
+	/* .uni-title {
+
+	} */
+	.uni-title__box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		align-items: flex-start;
+		justify-content: center;
+		padding: 8px 0;
+		flex: 1;
+	}
+
+	.uni-title__base {
+		font-size: 15px;
+		color: #333;
+		font-weight: 500;
+	}
+
+	.uni-h1 {
+		font-size: 20px;
+		color: #333;
+		font-weight: bold;
+	}
+
+	.uni-h2 {
+		font-size: 18px;
+		color: #333;
+		font-weight: bold;
+	}
+
+	.uni-h3 {
+		font-size: 16px;
+		color: #333;
+		font-weight: bold;
+		/* font-weight: 400; */
+	}
+
+	.uni-h4 {
+		font-size: 14px;
+		color: #333;
+		font-weight: bold;
+		/* font-weight: 300; */
+	}
+
+	.uni-h5 {
+		font-size: 12px;
+		color: #333;
+		font-weight: bold;
+		/* font-weight: 200; */
+	}
+</style>
diff --git a/uni_modules/uni-title/package.json b/uni_modules/uni-title/package.json
new file mode 100644
index 0000000..2249f5a
--- /dev/null
+++ b/uni_modules/uni-title/package.json
@@ -0,0 +1,88 @@
+{
+  "id": "uni-title",
+  "displayName": "uni-title 章节标题",
+  "version": "1.1.1",
+  "description": "章节标题,通常用于记录页面标题,使用当前组件,uni-app 如果开启统计,将会自动统计页面标题",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "标题",
+    "章节",
+    "章节标题",
+    ""
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-title/readme.md b/uni_modules/uni-title/readme.md
new file mode 100644
index 0000000..0e60b1b
--- /dev/null
+++ b/uni_modules/uni-title/readme.md
@@ -0,0 +1,14 @@
+
+
+## Title 标题
+> **组件名:uni-title**
+> 代码块: `uTitle`
+
+
+章节标题,通常用于记录页面标题,使用当前组件,uni-app 如果开启统计,将会自动统计页面标题 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-title)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
+
diff --git a/uni_modules/uni-tooltip/changelog.md b/uni_modules/uni-tooltip/changelog.md
new file mode 100644
index 0000000..285b676
--- /dev/null
+++ b/uni_modules/uni-tooltip/changelog.md
@@ -0,0 +1,16 @@
+## 0.2.4(2024-04-23)
+- 修复 弹出位置默认值不一致导致的错位
+## 0.2.3(2024-03-20)
+- 修复 弹出位置修正
+## 0.2.2(2024-01-15)
+- 新增 placement支持设置四个方向:top bottom left right
+## 0.2.1(2022-05-09)
+- 修复 content 为空时仍然弹出的bug
+## 0.2.0(2022-05-07)
+**注意:破坏性更新**
+- 更新 text 属性变更为 content
+- 更新 移除 width 属性
+## 0.1.1(2022-04-27)
+- 修复 组件根 text 嵌套组件 warning
+## 0.1.0(2022-04-21)
+- 初始化
diff --git a/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue b/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue
new file mode 100644
index 0000000..476a7dd
--- /dev/null
+++ b/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue
@@ -0,0 +1,108 @@
+<template>
+	<view class="uni-tooltip">
+		<slot></slot>
+		<view v-if="content || $slots.content" class="uni-tooltip-popup" :style="initPlacement">
+			<slot name="content">
+				{{content}}
+			</slot>
+		</view>
+	</view>
+</template>
+
+
+<script>
+	/**
+	 * Tooltip 提示文字
+	 * @description 常用于展示鼠标 hover 时的提示信息。
+	 * @tutorial https://uniapp.dcloud.io/component/uniui/uni-tooltip
+	 * @property {String} content   弹出层显示的内容
+	 * @property {String}  placement出现位置, 目前支持:left right top bottom
+	 */
+	export default {
+		name: "uni-tooltip",
+		data() {
+			return {
+
+			};
+		},
+		methods: {},
+		computed: {
+			initPlacement() {
+				let style = {};
+				switch (this.placement) {
+					case 'left':
+						style = {
+							top: '50%',
+							transform: 'translateY(-50%)',
+							right: '100%',
+							"margin-right": '10rpx',
+						}
+						break;
+					case 'right':
+						style = {
+							top: '50%',
+							transform: 'translateY(-50%)',
+							left: '100%',
+							"margin-left": '10rpx',
+						}
+						break;
+					case 'top':
+						style = {
+							bottom: '100%',
+							transform: 'translateX(-50%)',
+							left: '50%',
+							"margin-bottom": '10rpx',
+						}
+						break;
+					case 'bottom':
+						style = {
+							top: '100%',
+							transform: 'translateX(-50%)',
+							left: '50%',
+							"margin-top": '10rpx',
+						}
+						break;
+				}
+				return style;
+			}
+		},
+		props: {
+			content: {
+				type: String,
+				default: ''
+			},
+
+			placement: {
+				type: String,
+				default: 'bottom'
+			},
+		}
+	}
+</script>
+
+<style>
+	.uni-tooltip {
+		position: relative;
+		cursor: pointer;
+		display: inline-block;
+	}
+
+	.uni-tooltip-popup {
+		z-index: 1;
+		display: none;
+		position: absolute;
+		background-color: #333;
+		border-radius: 8px;
+		color: #fff;
+		font-size: 12px;
+		text-align: left;
+		line-height: 16px;
+		padding: 12px;
+		overflow: auto;
+	}
+
+
+	.uni-tooltip:hover .uni-tooltip-popup {
+		display: block;
+	}
+</style>
diff --git a/uni_modules/uni-tooltip/package.json b/uni_modules/uni-tooltip/package.json
new file mode 100644
index 0000000..44158e1
--- /dev/null
+++ b/uni_modules/uni-tooltip/package.json
@@ -0,0 +1,86 @@
+{
+  "id": "uni-tooltip",
+  "displayName": "uni-tooltip 提示文字",
+  "version": "0.2.4",
+  "description": "Tooltip 提示文字",
+  "keywords": [
+    "uni-tooltip",
+    "uni-ui",
+    "tooltip",
+    "tip",
+    "文字提示"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无 ",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u",
+          "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-tooltip/readme.md b/uni_modules/uni-tooltip/readme.md
new file mode 100644
index 0000000..faafa2e
--- /dev/null
+++ b/uni_modules/uni-tooltip/readme.md
@@ -0,0 +1,8 @@
+## Badge 数字角标
+> **组件名:uni-tooltip**
+> 代码块: `uTooltip`
+
+数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景,
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-tooltip)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
diff --git a/uni_modules/uni-transition/changelog.md b/uni_modules/uni-transition/changelog.md
new file mode 100644
index 0000000..faaf336
--- /dev/null
+++ b/uni_modules/uni-transition/changelog.md
@@ -0,0 +1,24 @@
+## 1.3.3(2024-04-23)
+- 修复 当元素会受变量影响自动隐藏的bug
+## 1.3.2(2023-05-04)
+- 修复 NVUE 平台报错的问题
+## 1.3.1(2021-11-23)
+- 修复 init 方法初始化问题
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
+## 1.2.1(2021-09-27)
+- 修复 init 方法不生效的 Bug
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.1(2021-05-12)
+- 新增 示例地址
+- 修复 示例项目缺少组件的 Bug
+## 1.1.0(2021-04-22)
+- 新增 通过方法自定义动画
+- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
+- 优化 动画触发逻辑,使动画更流畅
+- 优化 支持单独的动画类型
+- 优化 文档示例
+## 1.0.2(2021-02-05)
+- 调整为 uni_modules 目录规范
diff --git a/uni_modules/uni-transition/components/uni-transition/createAnimation.js b/uni_modules/uni-transition/components/uni-transition/createAnimation.js
new file mode 100644
index 0000000..8f89b18
--- /dev/null
+++ b/uni_modules/uni-transition/components/uni-transition/createAnimation.js
@@ -0,0 +1,131 @@
+// const defaultOption = {
+// 	duration: 300,
+// 	timingFunction: 'linear',
+// 	delay: 0,
+// 	transformOrigin: '50% 50% 0'
+// }
+// #ifdef APP-NVUE
+const nvueAnimation = uni.requireNativePlugin('animation')
+// #endif
+class MPAnimation {
+	constructor(options, _this) {
+		this.options = options
+		// 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
+		this.animation = uni.createAnimation({
+			...options
+		})
+		this.currentStepAnimates = {}
+		this.next = 0
+		this.$ = _this
+
+	}
+
+	_nvuePushAnimates(type, args) {
+		let aniObj = this.currentStepAnimates[this.next]
+		let styles = {}
+		if (!aniObj) {
+			styles = {
+				styles: {},
+				config: {}
+			}
+		} else {
+			styles = aniObj
+		}
+		if (animateTypes1.includes(type)) {
+			if (!styles.styles.transform) {
+				styles.styles.transform = ''
+			}
+			let unit = ''
+			if(type === 'rotate'){
+				unit = 'deg'
+			}
+			styles.styles.transform += `${type}(${args+unit}) `
+		} else {
+			styles.styles[type] = `${args}`
+		}
+		this.currentStepAnimates[this.next] = styles
+	}
+	_animateRun(styles = {}, config = {}) {
+		let ref = this.$.$refs['ani'].ref
+		if (!ref) return
+		return new Promise((resolve, reject) => {
+			nvueAnimation.transition(ref, {
+				styles,
+				...config
+			}, res => {
+				resolve()
+			})
+		})
+	}
+
+	_nvueNextAnimate(animates, step = 0, fn) {
+		let obj = animates[step]
+		if (obj) {
+			let {
+				styles,
+				config
+			} = obj
+			this._animateRun(styles, config).then(() => {
+				step += 1
+				this._nvueNextAnimate(animates, step, fn)
+			})
+		} else {
+			this.currentStepAnimates = {}
+			typeof fn === 'function' && fn()
+			this.isEnd = true
+		}
+	}
+
+	step(config = {}) {
+		// #ifndef APP-NVUE
+		this.animation.step(config)
+		// #endif
+		// #ifdef APP-NVUE
+		this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
+		this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
+		this.next++
+		// #endif
+		return this
+	}
+
+	run(fn) {
+		// #ifndef APP-NVUE
+		this.$.animationData = this.animation.export()
+		this.$.timer = setTimeout(() => {
+			typeof fn === 'function' && fn()
+		}, this.$.durationTime)
+		// #endif
+		// #ifdef APP-NVUE
+		this.isEnd = false
+		let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
+		if(!ref) return
+		this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
+		this.next = 0
+		// #endif
+	}
+}
+
+
+const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
+	'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
+	'translateZ'
+]
+const animateTypes2 = ['opacity', 'backgroundColor']
+const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
+animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
+	MPAnimation.prototype[type] = function(...args) {
+		// #ifndef APP-NVUE
+		this.animation[type](...args)
+		// #endif
+		// #ifdef APP-NVUE
+		this._nvuePushAnimates(type, args)
+		// #endif
+		return this
+	}
+})
+
+export function createAnimation(option, _this) {
+	if(!_this) return
+	clearTimeout(_this.timer)
+	return new MPAnimation(option, _this)
+}
diff --git a/uni_modules/uni-transition/components/uni-transition/uni-transition.vue b/uni_modules/uni-transition/components/uni-transition/uni-transition.vue
new file mode 100644
index 0000000..f3ddd1f
--- /dev/null
+++ b/uni_modules/uni-transition/components/uni-transition/uni-transition.vue
@@ -0,0 +1,286 @@
+<template>
+  <!-- #ifndef APP-NVUE -->
+  <view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
+  <!-- #endif -->
+  <!-- #ifdef APP-NVUE -->
+  <view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
+  <!-- #endif -->
+</template>
+
+<script>
+import { createAnimation } from './createAnimation'
+
+/**
+ * Transition 过渡动画
+ * @description 简单过渡动画组件
+ * @tutorial https://ext.dcloud.net.cn/plugin?id=985
+ * @property {Boolean} show = [false|true] 控制组件显示或隐藏
+ * @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
+ *  @value fade 渐隐渐出过渡
+ *  @value slide-top 由上至下过渡
+ *  @value slide-right 由右至左过渡
+ *  @value slide-bottom 由下至上过渡
+ *  @value slide-left 由左至右过渡
+ *  @value zoom-in 由小到大过渡
+ *  @value zoom-out 由大到小过渡
+ * @property {Number} duration 过渡动画持续时间
+ * @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
+ */
+export default {
+	name: 'uniTransition',
+	emits:['click','change'],
+	props: {
+		show: {
+			type: Boolean,
+			default: false
+		},
+		modeClass: {
+			type: [Array, String],
+			default() {
+				return 'fade'
+			}
+		},
+		duration: {
+			type: Number,
+			default: 300
+		},
+		styles: {
+			type: Object,
+			default() {
+				return {}
+			}
+		},
+		customClass:{
+			type: String,
+			default: ''
+		},
+		onceRender:{
+			type:Boolean,
+			default:false
+		},
+	},
+	data() {
+		return {
+			isShow: false,
+			transform: '',
+			opacity: 1,
+			animationData: {},
+			durationTime: 300,
+			config: {}
+		}
+	},
+	watch: {
+		show: {
+			handler(newVal) {
+				if (newVal) {
+					this.open()
+				} else {
+					// 避免上来就执行 close,导致动画错乱
+					if (this.isShow) {
+						this.close()
+					}
+				}
+			},
+			immediate: true
+		}
+	},
+	computed: {
+		// 生成样式数据
+		stylesObject() {
+			let styles = {
+				...this.styles,
+				'transition-duration': this.duration / 1000 + 's'
+			}
+			let transform = ''
+			for (let i in styles) {
+				let line = this.toLine(i)
+				transform += line + ':' + styles[i] + ';'
+			}
+			return transform
+		},
+		// 初始化动画条件
+		transformStyles() {
+			return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
+		}
+	},
+	created() {
+		// 动画默认配置
+		this.config = {
+			duration: this.duration,
+			timingFunction: 'ease',
+			transformOrigin: '50% 50%',
+			delay: 0
+		}
+		this.durationTime = this.duration
+	},
+	methods: {
+		/**
+		 *  ref 触发 初始化动画
+		 */
+		init(obj = {}) {
+			if (obj.duration) {
+				this.durationTime = obj.duration
+			}
+			this.animation = createAnimation(Object.assign(this.config, obj),this)
+		},
+		/**
+		 * 点击组件触发回调
+		 */
+		onClick() {
+			this.$emit('click', {
+				detail: this.isShow
+			})
+		},
+		/**
+		 * ref 触发 动画分组
+		 * @param {Object} obj
+		 */
+		step(obj, config = {}) {
+			if (!this.animation) return
+			for (let i in obj) {
+				try {
+					if(typeof obj[i] === 'object'){
+						this.animation[i](...obj[i])
+					}else{
+						this.animation[i](obj[i])
+					}
+				} catch (e) {
+					console.error(`方法 ${i} 不存在`)
+				}
+			}
+			this.animation.step(config)
+			return this
+		},
+		/**
+		 *  ref 触发 执行动画
+		 */
+		run(fn) {
+			if (!this.animation) return
+			this.animation.run(fn)
+		},
+		// 开始过度动画
+		open() {
+			clearTimeout(this.timer)
+			this.transform = ''
+			this.isShow = true
+			let { opacity, transform } = this.styleInit(false)
+			if (typeof opacity !== 'undefined') {
+				this.opacity = opacity
+			}
+			this.transform = transform
+			// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
+			this.$nextTick(() => {
+				// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
+				this.timer = setTimeout(() => {
+					this.animation = createAnimation(this.config, this)
+					this.tranfromInit(false).step()
+					this.animation.run()
+					this.$emit('change', {
+						detail: this.isShow
+					})
+				}, 20)
+			})
+		},
+		// 关闭过度动画
+		close(type) {
+			if (!this.animation) return
+			this.tranfromInit(true)
+				.step()
+				.run(() => {
+					this.isShow = false
+					this.animationData = null
+					this.animation = null
+					let { opacity, transform } = this.styleInit(false)
+					this.opacity = opacity || 1
+					this.transform = transform
+					this.$emit('change', {
+						detail: this.isShow
+					})
+				})
+		},
+		// 处理动画开始前的默认样式
+		styleInit(type) {
+			let styles = {
+				transform: ''
+			}
+			let buildStyle = (type, mode) => {
+				if (mode === 'fade') {
+					styles.opacity = this.animationType(type)[mode]
+				} else {
+					styles.transform += this.animationType(type)[mode] + ' '
+				}
+			}
+			if (typeof this.modeClass === 'string') {
+				buildStyle(type, this.modeClass)
+			} else {
+				this.modeClass.forEach(mode => {
+					buildStyle(type, mode)
+				})
+			}
+			return styles
+		},
+		// 处理内置组合动画
+		tranfromInit(type) {
+			let buildTranfrom = (type, mode) => {
+				let aniNum = null
+				if (mode === 'fade') {
+					aniNum = type ? 0 : 1
+				} else {
+					aniNum = type ? '-100%' : '0'
+					if (mode === 'zoom-in') {
+						aniNum = type ? 0.8 : 1
+					}
+					if (mode === 'zoom-out') {
+						aniNum = type ? 1.2 : 1
+					}
+					if (mode === 'slide-right') {
+						aniNum = type ? '100%' : '0'
+					}
+					if (mode === 'slide-bottom') {
+						aniNum = type ? '100%' : '0'
+					}
+				}
+				this.animation[this.animationMode()[mode]](aniNum)
+			}
+			if (typeof this.modeClass === 'string') {
+				buildTranfrom(type, this.modeClass)
+			} else {
+				this.modeClass.forEach(mode => {
+					buildTranfrom(type, mode)
+				})
+			}
+
+			return this.animation
+		},
+		animationType(type) {
+			return {
+				fade: type ? 0 : 1,
+				'slide-top': `translateY(${type ? '0' : '-100%'})`,
+				'slide-right': `translateX(${type ? '0' : '100%'})`,
+				'slide-bottom': `translateY(${type ? '0' : '100%'})`,
+				'slide-left': `translateX(${type ? '0' : '-100%'})`,
+				'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
+				'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
+			}
+		},
+		// 内置动画类型与实际动画对应字典
+		animationMode() {
+			return {
+				fade: 'opacity',
+				'slide-top': 'translateY',
+				'slide-right': 'translateX',
+				'slide-bottom': 'translateY',
+				'slide-left': 'translateX',
+				'zoom-in': 'scale',
+				'zoom-out': 'scale'
+			}
+		},
+		// 驼峰转中横线
+		toLine(name) {
+			return name.replace(/([A-Z])/g, '-$1').toLowerCase()
+		}
+	}
+}
+</script>
+
+<style></style>
diff --git a/uni_modules/uni-transition/package.json b/uni_modules/uni-transition/package.json
new file mode 100644
index 0000000..d5c20e1
--- /dev/null
+++ b/uni_modules/uni-transition/package.json
@@ -0,0 +1,85 @@
+{
+  "id": "uni-transition",
+  "displayName": "uni-transition 过渡动画",
+  "version": "1.3.3",
+  "description": "元素的简单过渡动画",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "动画",
+    "过渡",
+    "过渡动画"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-transition/readme.md b/uni_modules/uni-transition/readme.md
new file mode 100644
index 0000000..2f8a77e
--- /dev/null
+++ b/uni_modules/uni-transition/readme.md
@@ -0,0 +1,11 @@
+
+
+## Transition 过渡动画
+> **组件名:uni-transition**
+> 代码块: `uTransition`
+
+
+元素过渡动画
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
\ No newline at end of file
diff --git a/uni_modules/uni-ui/changelog.md b/uni_modules/uni-ui/changelog.md
new file mode 100644
index 0000000..6d477cf
--- /dev/null
+++ b/uni_modules/uni-ui/changelog.md
@@ -0,0 +1,578 @@
+## 1.5.6(2024-07-08)
+- uni-datetime-picker 新增 日期点击事件,在点击日期时会触发该事件。
+- uni-datetime-picker 修复 抖音小程序事件传递失效bug
+- uni-easyinput 修复 easyinput组件双向绑定问题
+- uni-number-box 修复 在vue2下H5黑边的bug
+- uni-number-box 修复 在vue2手动输入后失焦导致清空数值的严重bug
+- uni-popup 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法)
+- uni-search-bar 修复 textColor默认值导致的文字不显示的bug
+- uni-search-bar 修复 textColor不生效的bug
+- uni-segmented-control 修复 修复在微信小程序下inactiveColor失效bug
+- uni-tooltip 修复 弹出位置默认值不一致导致的错位
+- uni-transition 修复 当元素会受变量影响自动隐藏的bug
+## 1.5.0(2024-01-13)
+- 修复 npm包结构目录错误的问题
+- uni-calendar 修复 回到今天时,月份显示不一致问题
+- uni-data-picker 新增 支持 uni-app-x
+- uni-datetime-picker 优化 增加noChange事件,当进行日期范围选择时,若有空值,则触发该事件 [详情](https://github.com/dcloudio/uni-ui/issues/815)
+- uni-datetime-picker 修复 字节小程序时间选择范围器失效问题 [详情](https://github.com/dcloudio/uni-ui/issues/834)
+- uni-datetime-picker 修复 PC端初次修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
+- uni-datetime-picker 修复 部分情况修改时间,开始、结束时间显示异常的Bug [详情](https://ask.dcloud.net.cn/question/171146)
+- uni-datetime-picker 优化 当前月可以选择上月、下月的日期的Bug
+- uni-file-picker 新增 微信小程序不再调用chooseImage,而是调用chooseMedia
+- uni-file-picker 新增 上传文件至云存储携带本地文件名称
+- uni-forms 优化 labelWidth 描述错误
+fix: 修复图标大小默认值错误的问题
+- uni-icons 修复 项目未使用 ts 情况下,打包报错的bug
+- uni-icons 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
+- uni-icons 优化 兼容老版本icon类型,如 top ,bottom 等
+- uni-icons 优化 兼容老版本icon类型,如 top ,bottom 等
+- uni-icons 优化 uni-app x 下示例项目图标排序
+- uni-icons 修复 nvue下引入组件报错的bug
+-优化 size 属性支持单位
+- uni-icons 新增 uni-app x 支持定义图标
+- uni-notice-bar 修复动态绑定title时,滚动速度不一致的问题
+更新示例工程
+- uni-popup 新增 uni-popup 支持uni-app-x 注意暂时仅支持 `maskClick` `@open` `@close`
+- uni-table 修复 uni-tr只有一列时minWidth计算错误,列变化实时计算更新
+## 1.4.27(2023-04-21)
+- uni-calendar 修复 某些情况 monthSwitch 未触发的Bug
+- uni-calendar 修复 某些情况切换月份错误的Bug
+- uni-data-picker 修复 更改 modelValue 报错的 bug
+- uni-data-picker 修复 v-for 未使用 key 值控制台 warning
+- uni-data-picker 修复代码合并时引发 value 属性为空时不渲染数据的问题
+- uni-data-picker 修复 localdata 不支持动态更新的bug
+- uni-data-select 修复 微信小程序点击时会改变背景颜色的 bug
+- uni-data-select 修复 禁用时会显示清空按钮
+- uni-data-select 优化 查询条件短期内多次变更只查询最后一次变更后的结果
+- uni-data-select 调整 内部缓存键名调整为 uni-data-select-lastSelectedValue
+- uni-datetime-picker 修复 日历 picker 修改年月后,自动选中当月1日 [详情](https://ask.dcloud.net.cn/question/165937)
+- uni-datetime-picker 修复 小程序端 低版本 ios NaN [详情](https://ask.dcloud.net.cn/question/162979)
+- uni-datetime-picker 修复 firefox 浏览器显示区域点击无法拉起日历弹框的Bug [详情](https://ask.dcloud.net.cn/question/163362)
+- uni-datetime-picker 优化 值为空依然选中当天问题
+- uni-datetime-picker 优化 提供 default-value 属性支持配置选择器打开时默认显示的时间
+- uni-datetime-picker 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间
+- uni-datetime-picker 优化 字节小程序日期时间范围选择,底部日期换行问题
+- uni-datetime-picker 修复 2.2.18 引起范围选择配置 end 选择无效的Bug [详情](https://github.com/dcloudio/uni-ui/issues/686)
+- uni-datetime-picker 修复 移动端范围选择change事件触发异常的Bug [详情](https://github.com/dcloudio/uni-ui/issues/684)
+- uni-datetime-picker 优化 PC端输入日期格式错误时返回当前日期时间
+- uni-datetime-picker 优化 PC端输入日期时间超出 start、end 限制的Bug
+- uni-datetime-picker 优化 移动端日期时间范围用法时间展示不完整问题
+- uni-datetime-picker 修复 小程序端绑定 Date 类型报错的Bug [详情](https://github.com/dcloudio/uni-ui/issues/679)
+- uni-datetime-picker 修复 vue3 time-picker 无法显示绑定时分秒的Bug
+- uni-datetime-picker 修复 字节小程序报错的Bug
+- uni-datetime-picker 修复 某些情况切换月份错误的Bug
+- uni-easyinput 修复 vue3 下 keyboardheightchange 事件报错的bug
+- uni-easyinput 优化 trim 属性默认值
+- uni-easyinput 新增 cursor-spacing 属性
+- uni-fab 新增 pattern.icon 属性,可自定义图标
+- uni-file-picker 修复 手动上传删除一个文件后不能再上传的bug
+- uni-forms 修复 required 参数无法动态绑定
+- uni-list 优化 uni-list-chat 具名插槽`header` 非app端套一层元素,方便使用时通过外层元素定位实现样式修改
+- uni-list uni-list-chat 新增 支持具名插槽`header`
+- uni-list 新增 列表图标新增 customPrefix 属性 ,用法 [详见](https://uniapp.dcloud.net.cn/component/uniui/uni-icons.html#icons-props)
+- uni-nav-bar 修复 自定义状态栏高度闪动BUG
+- uni-nav-bar 修复 暗黑模式下边线颜色错误的bug
+- uni-popup 修复 uni-popup 重复打开时的 bug
+- uni-popup uni-popup-dialog 组件新增 inputType 属性
+- uni-swipe-action 修复`uni-swipe-action`和`uni-swipe-action-item`不同时使用导致 closeOther 方法报错的 bug
+- uni-table 修复 在vue3模式下可能会出现错误的问题
+## 1.4.26(2023-01-31)
+- uni-badge 修复 运行/打包 控制台警告问题
+- uni-calendar 修复 某些情况切换月份错误问题
+- uni-data-select 修复 不关联服务空间报错的问题
+- uni-data-select 新增  属性 `format` 可用于格式化显示选项内容
+- uni-datetime-picker 修复 某些情况切换月份错误问题
+- uni-easyinput 新增 keyboardheightchange 事件,可监听键盘高度变化
+- uni-list 修复 无反馈效果呈现的bug
+## 1.4.25(2023-01-11)
+- uni-file-picker 新增 sourceType 属性, 可以自定义图片和视频选择的来源
+## 1.4.24(2023-01-11)
+- uni-data-select 修复  当where变化时,数据不会自动更新的问题
+- uni-datetime-picker 修复 多次加载组件造成内存占用的 bug
+- uni-datetime-picker 修复 vue3 下 i18n 国际化初始值不正确的 bug
+- uni-easyinput 修复 props 中背景颜色无默认值的bug
+- uni-list 修复 uni-list-chat 在vue3下跳转报错的bug
+- uni-list 修复 uni-list-chat avatar属性 值为本地路径时错误的问题
+- uni-list 修复 uni-list-chat avatar属性 在腾讯云版uniCloud下错误的问题
+- uni-list 修复 uni-list-chat note属性 支持:“草稿”字样功能 文本少1位的问题
+- uni-list 修复 uni-list-item 的 customStyle 属性 padding值在 H5端 无效的bug
+- uni-list 修复 uni-list-item 的 customStyle 属性 padding值在nvue(vue2)下无效的bug
+- uni-list uni-list-chat 新增 avatar 支持 fileId
+- uni-list uni-list 新增属性 render-reverse 详情参考:[https://uniapp.dcloud.net.cn/component/list.html](https://uniapp.dcloud.net.cn/component/list.html)
+- uni-list uni-list-chat note属性 支持:“草稿”字样 加红显示 详情参考uni-im:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im)
+- uni-list uni-list-item 新增属性 customStyle 支持设置padding、backgroundColor
+- uni-popup 修复 nvue 下 v-show 报错
+## 1.4.23(2022-10-25)
+- uni-datetime-picker 修复,支付宝小程序样式错乱,[详情](https://github.com/dcloudio/uni-app/issues/3861)
+
+- uni-nav-bar 修复 条件编译错误的bug
+- uni-nav-bar 修复 nvue 环境 fixed 为 true 的情况下,无法置顶的 bug
+## 1.4.22(2022-09-19)
+- 优化 部分组件适配 uni-scss 主题色
+- uni-badge 修复 当 text 超过 max-num 时,badge 的宽度计算是根据 text 的长度计算,更改为 css 计算实际展示宽度,详见:[https://ask.dcloud.net.cn/question/150473](https://ask.dcloud.net.cn/question/150473)
+- uni-calendar 修复 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件
+- uni-data-select 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框
+- uni-data-select 修复 点击的位置不准确
+- uni-data-select 新增 支持 disabled 属性
+- uni-datetime-picker 修复,反向选择日期范围,日期显示异常,[详情](https://ask.dcloud.net.cn/question/153401?item_id=212892&rf=false)
+- uni-datetime-picker 修复 close事件无效的 bug
+- uni-datetime-picker 修复 移动端 maskClick 无效的 bug,详见:[https://ask.dcloud.net.cn/question/140824?item_id=209458&rf=false](https://ask.dcloud.net.cn/question/140824?item_id=209458&rf=false)
+- uni-fab 修复 小程序端由于 style 使用了对象导致报错,[详情](https://ask.dcloud.net.cn/question/152790?item_id=211778&rf=false)
+- uni-fab 修复 nvue 环境下,具有 tabBar 时,fab 组件下部位置无法正常获取 --window-bottom 的bug,详见:[https://ask.dcloud.net.cn/question/110638?notification_id=826310](https://ask.dcloud.net.cn/question/110638?notification_id=826310)
+- uni-forms 优化 根据 rules 自动添加 required 的问题
+- uni-forms 修复 item 未设置 require 属性,rules 设置 require 后,星号也显示的 bug,详见:[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540)
+- uni-nav-bar 修复 nvue 环境下 fixed 为 true 的情况下,无法置顶的 bug
+- uni-notice-bar 新增 属性 fontSize,可修改文字大小。
+- uni-pagination 修复,未对主题色设置默认色,导致未引入 uni-scss 变量文件报错。
+- uni-pagination 修复,未对移动端当前页文字做主题色适配。
+- uni-pagination 修复 es 语言 i18n 错误
+## 1.4.21(2022-09-19)
+- 修复,安装时未导入 uni-data-select 和 uni-tooltip 的问题。
+## 1.4.20(2022-07-25)
+- uni-section 新增组件
+- uni-forms 修复 model 需要校验的值没有声明对应字段时,导致第一次不触发校验的bug
+
+## 1.4.19(2022-07-07)
+- uni-data-picker 优化 pc端图标位置不正确的问题
+- uni-data-select 修复 pc端宽度异常的bug
+## 1.4.18(2022-07-06)
+- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
+- uni-forms 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
+- uni-forms 新增 更多表单示例
+- uni-forms 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
+- uni-forms 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
+- uni-forms 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
+- uni-forms 新增 子表单的 setRules 方法,配合自定义校验函数使用
+- uni-forms 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
+- uni-forms 修复 由 1.4.0 引发的 label 插槽不生效的bug
+- uni-forms 修复 子组件找不到 setValue 报错的bug
+- uni-forms 修复 uni-data-picker 在 uni-forms-item 中报错的bug
+- uni-forms 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+- uni-forms 修复 表单校验顺序无序问题
+- uni-forms 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
+- uni-forms 优化 动态表单校验方式,废弃拼接name的方式
+- uni-breadcrumb 修复 微信小程序 separator 不显示问题
+- uni-data-checkbox 优化 在 uni-forms 中的依赖注入方式
+- uni-data-picker 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+- uni-data-picker 优化 显示样式
+- uni-data-select 优化 显示样式
+- uni-datetime-picker 修复 日历顶部年月及底部确认未国际化 bug
+- uni-datetime-picker 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
+- uni-easyinput 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
+- uni-easyinput 新增 clear 事件,点击右侧叉号图标触发
+- uni-easyinput 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
+- uni-easyinput 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
+- uni-easyinput 优化 clearable 显示策略
+- uni-file-picker 修复 在uni-forms下样式不生效的bug
+- uni-nav-bar 修复 组件示例中插槽用法无法显示内容的bug
+- uni-swipe-action 修复 vue3 下使用组件不能正常运行的Bug
+- uni-swipe-action 修复 h5端点击click触发两次的Bug
+- uni-table 修复 微信小程序存在无使用组件的问题
+## 1.4.17(2022-06-30)
+- 支持 ios 安全区
+## 1.4.16(2022-06-06)
+- uni-breadcrumb 新增 支持 uni.scss 修改颜色
+- uni-data-select 修复 localdata 赋值不生效的 bug
+- uni-data-select 新增 支持选项禁用(数据选项设置 disabled: true 即禁用)
+- uni-data-select 修复 当 value 为 0 时选择不生效的 bug
+- uni-easyinput 修复 关闭图标某些情况下无法取消的bug
+- uni-fav 新增 stat 属性 ,是否开启uni统计功能
+- uni-goods-nav 新增 stat属性,是否开启uni统计功能
+- uni-group 新增 stat属性,是否开启uni统计功能
+- uni-nav-bar 新增 stat 属性 ,可开启统计 title 上报 ,仅使用了title 属性且项目开启了uni统计生效
+- uni-search-bar 新增 readonly 属性,组件只读
+- uni-swipe-action 修复 isPC 找不到的Bug
+- uni-swipe-action  修复 在 nvue 下 disabled 失效的bug
+- uni-tooltip 修复 content 为空时仍然弹出的bug
+## 1.4.15(2022-05-07)
+- uni-data-picker 修复 字节小程序 本地数据无法选择下一级的Bug
+- uni-data-select 新增 记住上次的选项(仅 collection 存在时有效)
+- uni-search-bar 修复  vue3 input 事件不生效的bug
+- uni-search-bar 修复 多余代码导致的bug
+- uni-tooltip 更新 text 属性变更为 content
+- uni-tooltip 更新 移除 width 属性
+- uni-tooltip 修复 组件根 text 嵌套组件 warning
+## 1.4.14(2022-04-18)
+- uni-datetime-picker 修复 Vue3 下动态赋值,单选类型未响应的 bug
+- uni-easyinput 修复 默认值不生效的bug
+## 1.4.13(2022-04-02)
+- uni-calendar 修复 条件编译 nvue 不支持的 css 样式
+- uni-calendar 修复 startDate、 endDate 属性失效的 bug
+- uni-data-picker 修复 nvue 不支持的 v-show 的 bug
+- uni-data-picker 修复 条件编译 nvue 不支持的 css 样式
+- uni-datetime-picker 修复 Vue3 下动态赋值未响应的 bug
+- uni-easyinput 修复 value不能为0的bug
+- uni-popup 修复 弹出层内部无法滚动的bug
+- uni-popup 修复 小程序中高度错误的bug
+- uni-popup 修复 快速调用open出现问题的Bug
+- uni-rate 修复 条件判断 `NaN` 错误的 bug
+- uni-swipe-action 修复 按钮字体大小不能设置的bug
+- uni-swipe-action 修复 h5和app端下报el错误的bug
+- uni-swipe-action 修复 HBuilderX 1.4.X 版本中,h5和app端下报错的bug
+## 1.4.12(2022-02-19)
+- uni-collapse 修复 初始化的时候 ,open 属性失效的bug
+- uni-data-checkbox 修复 multiple 为 true 时,v-model 的值为 null 报错的 bug
+- uni-icons 优化 size 属性可以传入不带单位的字符串数值
+- uni-icons 优化 size 支持其他单位
+- uni-nav-bar 新增 left-width/right-width属性 ,可修改左右两侧的宽度
+- uni-popup 修复 safeArea 属性不能设置为false的bug
+## 1.4.11(2022-01-21)
+- uni-collapse 修复 微信小程序resize后组件收起的bug
+- uni-countdown 修复 在微信小程序中样式不生效的bug
+- uni-countdown 新增 update 方法 ,在动态更新时间后,刷新组件
+- uni-load-more 新增 showText属性 ,是否显示文本
+- uni-load-more 修复 nvue 平台下不显示文本的bug
+- uni-load-more 修复 微信小程序平台样式选择器报警告的问题
+- uni-nav-bar 修复 在vue下,标题不垂直居中的bug
+- uni-nav-bar 修复 height 属性类型错误
+- uni-nav-bar 新增 height 属性,可修改组件高度
+- uni-nav-bar 新增 dark 属性可可开启暗黑模式
+- uni-nav-bar 优化 标题字数过多显示省略号
+- uni-nav-bar 优化 插槽,插入内容可完全覆盖
+- uni-popup 修复 isMaskClick 失效的bug
+- uni-popup 新增 cancelText \ confirmText 属性 ,可自定义文本
+- uni-popup 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
+- uni-popup 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
+
+## 1.4.10(2022-01-17)
+- uni-card 修复 在vue页面下略缩图显示不正常的bug
+- uni-datetime-picker 修复 clear-icon 属性在小程序平台不生效的 bug
+- uni-datetime-picker 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的 bug
+- uni-fab 更新 组件依赖
+-
+- uni-icons 修复 nvue 有些图标不显示的bug,兼容老版本图标
+- uni-icons 优化 示例可复制图标名称
+- uni-nav-bar 修复 color 属性不生效的bug
+- uni-popup 修复 设置 safeArea 属性不生效的bug
+- uni-popup 优化 组件示例
+- uni-popup 修复 vuedoc 文字错误
+## 1.4.9(2021-11-23)
+- uni-ui 修复 vue3中某些scss变量无法找到的问题
+- uni-combox 优化 label、label-width 属性
+- uni-data-picker 修复 由上个版本引发的map、v-model等属性不生效的bug
+- uni-file-picker 修复 参数为对象的情况下,url在某些情况显示错误的bug
+- uni-icons 优化 兼容旧组件 type 值
+- uni-list 修复 在vue3中to属性在发行应用的时候报错的bug
+- uni-scss 修复 vue3中scss语法兼容问题
+- uni-transition 修复 init 方法初始化问题
+## 1.4.8(2021-11-19)
+- uni-fab 修复 阴影颜色不正确的bug
+## 1.4.7(2021-11-19)
+- uni-ui 新增 支持国际化
+- uni-ui 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- uni-ui 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-ui](https://uniapp.dcloud.io/component/uniui/uni-ui)
+- uni-badge 修改 size 属性默认值调整为 small
+- uni-badge 修改 type 属性,默认值调整为 error,info 替换 default
+- uni-badge 修复 在字节小程序上样式不生效的 bug
+- uni-calendar 修复 弹出层被 tabbar 遮盖 bug
+- uni-card 重构插槽的用法 ,header 替换为 title
+- uni-card 新增 actions 插槽
+- uni-card 新增 cover 封面图属性和插槽
+- uni-card 新增 padding 内容默认内边距离
+- uni-card 新增 margin 卡片默认外边距离
+- uni-card 新增 spacing 卡片默认内边距
+- uni-card 新增 shadow 卡片阴影属性
+- uni-card 取消 mode 属性,可使用组合插槽代替
+- uni-card 取消 note 属性 ,使用actions插槽代替
+- uni-collapse 优化 show-arrow 属性默认为true
+- uni-collapse 新增 show-arrow 属性,控制是否显示右侧箭头
+- uni-countdown 新增 font-size 支持自定义字体大小
+- uni-data-checkbox 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
+- uni-data-checkbox 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
+- uni-data-checkbox 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+- uni-dateformat 优化 默认时间不再是当前时间,而是显示'-'字符
+- uni-datetime-picker 修复 hide-second 在移动端的 bug
+- uni-datetime-picker 修复 单选赋默认值时,赋值日期未高亮的 bug
+- uni-datetime-picker 修复 赋默认值时,移动端未正确显示时间的 bug
+- uni-datetime-picker 新增 hide-second 属性,支持只使用时分,隐藏秒
+- uni-datetime-picker 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
+- uni-datetime-picker 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
+- uni-datetime-picker 优化 调整字号大小,美化日历界面
+- uni-datetime-picker 优化 范围选择器在 pc 端过宽的问题
+- uni-datetime-picker 新增 支持作为 uni-forms 子组件相关功能
+- uni-datetime-picker 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
+- uni-datetime-picker 修复 type 属性动态赋值无效的 bug
+- uni-datetime-picker 修复 ‘确认’按钮被 tabbar 遮盖 bug
+- uni-datetime-picker 修复 组件未赋值时范围选左、右日历相同的 bug
+- uni-datetime-picker 修复 范围选未正确显示当前值的 bug
+- uni-datetime-picker 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
+- uni-easyinput 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
+- uni-easyinput 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+- uni-file-picker 新增 参数中返回 fileID 字段
+- uni-file-picker 修复 腾讯云传入fileID 不能回显的bug
+- uni-file-picker 修复 选择图片后,不能放大的问题
+- uni-file-picker 修复 由于 0.2.11 版本引起的不能回显图片的Bug
+- uni-file-picker 新增 clearFiles(index) 方法,可以手动删除指定文件
+- uni-file-picker 修复 v-model 值设为 null 报错的Bug
+- uni-file-picker 修复 return-type="object" 时,无法删除文件的Bug
+- uni-file-picker 修复 auto-upload 属性失效的Bug
+- uni-forms 修复 label 插槽不生效的bug
+- uni-forms 修复 没有添加校验规则的字段依然报错的Bug
+- uni-forms 修复 重置表单错误信息无法清除的问题
+- uni-forms 修复 表单验证只生效一次的问题
+- uni-icons 新增 更多图标
+- uni-icons 优化 自定义图标使用方式
+- uni-link 修复 在 nvue 下不显示的 bug
+- uni-pagination 修复 current 、value 属性未监听,导致高亮样式失效的 bug
+- uni-rate 优化 默认值修改为 0 颗星
+- uni-search-bar 修复 value 属性与 modelValue 属性不兼容的Bug
+- uni-swipe-action 新增 close-all 方法,关闭所有已打开的组件
+- uni-swipe-action 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件
+- uni-swipe-action 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题
+- uni-swipe-action 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
+- uni-tag 新增 提供组件设计资源,组件样式调整
+- uni-tag 移除 插槽
+- uni-tag 移除 type 属性的 royal 选项
+- uni-tag type 不是 default 时,size 为 small 字体大小显示不正确
+## 1.4.2(2021-08-20)
+- 新增 uni-ui 组件支持国际化 i18n
+- uni-collapse 优化 show-arrow 属性默认为true
+- uni-collapse 新增 show-arrow 属性,控制是否显示右侧箭头
+- uni-data-checkbox 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
+- uni-easyinput 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
+- uni-file-picker 修复 由于 0.2.11 版本引起的不能回显图片的Bug
+- uni-file-picker 新增 clearFiles(index) 方法,可以手动删除指定文件
+- uni-file-picker 修复 v-model 值设为 null 报错的Bug
+- uni-swipe-action 新增 close-all 方法,关闭所有已打开的组件
+- uni-swipe-action 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件
+- uni-swipe-action 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题
+- uni-swipe-action 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
+## 1.4.0(2021-08-13)
+- uni-calendar 修复 弹出层被 tabbar 遮盖 bug
+- uni-data-checkbox 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+- uni-dateformat 调整 默认时间不再是当前时间,而是显示'-'字符
+- uni-datetime-picker 新增 适配 vue3
+- uni-datetime-picker 新增 支持作为 uni-forms 子组件相关功能
+- uni-datetime-picker 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
+- uni-datetime-picker 修复 type 属性动态赋值无效的 bug
+- uni-datetime-picker 修复 ‘确认’按钮被 tabbar 遮盖 bug
+- uni-datetime-picker 修复 组件未赋值时范围选左、右日历相同的 bug
+- uni-datetime-picker 修复 范围选未正确显示当前值的 bug
+- uni-datetime-picker 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
+- uni-easyinput 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+- uni-file-picker 修复 return-type="object" 时,无法删除文件的Bug
+- uni-file-picker 修复 auto-upload 属性失效的Bug
+- uni-forms 修复 没有添加校验规则的字段依然报错的Bug
+- uni-forms 修复 重置表单错误信息无法清除的问题
+- uni-forms 优化 组件文档
+- uni-forms 修复 表单验证只生效一次的问题
+- uni-tag type 不是 default 时,size 为 small 字体大小显示不正确
+## 1.3.9(2021-08-02)
+- uni-datetime-picker 新增 return-type 属性支持返回 date 日期对象
+- uni-file-picker 修复 fileExtname属性不指定值报错的Bug
+- uni-file-picker 修复 在某种场景下图片不回显的Bug
+- uni-link 支持自定义插槽
+## 1.3.8(2021-07-31)
+- uni-ui 组件兼容 vue3
+- uni-collapse 修复 由1.2.0版本引起的 change 事件返回 undefined 的Bug
+- uni-collapse 优化 组件示例
+- uni-collapse 新增 组件折叠动画
+- uni-collapse 新增 value\v-model 属性 ,动态修改面板折叠状态
+- uni-collapse 新增 title 插槽 ,可定义面板标题
+- uni-collapse 新增 border 属性 ,显示隐藏面板内容分隔线
+- uni-collapse 新增 title-border 属性 ,显示隐藏面板标题分隔线
+- uni-collapse 修复 resize 方法失效的Bug
+- uni-collapse 修复 change 事件返回参数不正确的Bug
+- uni-collapse 优化 H5、App 平台自动更具内容更新高度,无需调用 reszie() 方法
+- uni-data-checkbox 优化 在uni-forms组件,与label不对齐的问题
+- uni-data-checkbox 修复 单选默认值为0不能选中的Bug
+- uni-easyinput 优化 errorMessage 属性支持 Boolean 类型
+- uni-file-picker 修复 return-type为object下,返回值不正确的Bug
+- uni-file-picker 修复(重要) H5 平台下如果和uni-forms组件一同使用导致页面卡死的问题
+- uni-file-picker 优化 h5平台下上传文件导致页面卡死的问题
+- uni-forms 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
+- uni-forms 修复 1.2.1 引起的示例在小程序平台报错的Bug
+- uni-forms 修复 动态校验表单,默认值为空的情况下校验失效的Bug
+- uni-forms 修复 不指定name属性时,运行报错的Bug
+- uni-forms 优化 label默认宽度从65调整至70,使required为true且四字时不换行
+- uni-forms 优化 组件示例,新增动态校验示例代码
+- uni-forms 优化 组件文档,使用方式更清晰
+- uni-list 修复 与其他组件嵌套使用时,点击失效的Bug
+- uni-swipe-action 修复 跨页面修改组件数据 ,导致不能滑动的问题
+## 1.3.7(2021-07-16)
+- uni-ui 兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+- uni-datetime-picker 修复 单选日期类型,初始赋值后不在当前日历的 bug
+- uni-datetime-picker 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效)
+- uni-datetime-picker 优化 移动端移除显示框的清空按钮,无实际用途
+- uni-datetime-picker 修复 组件赋值为空,界面未更新的 bug
+- uni-datetime-picker 修复 start 和 end 不能动态赋值的 bug
+- uni-datetime-picker 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的 bug
+## 1.3.6(2021-07-09)
+- uni-data-checkbox 优化 删除无用日志
+- uni-data-checkbox 修复 由 0.1.9 引起的非 nvue 端图标不显示的问题
+- uni-data-checkbox 修复 nvue 黑框样式问题
+- uni-datetime-picker 修复 范围选择不能动态赋值的 bug
+- uni-datetime-picker 修复 范围选择的初始时间在一个月内时,造成无法选择的bug
+- uni-datetime-picker 优化 弹出层在超出视窗边缘定位不准确的问题
+- uni-datetime-picker 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的 bug
+- uni-datetime-picker 优化 弹出层在超出视窗边缘被遮盖的问题
+- uni-datetime-picker 新增 maskClick 事件
+- uni-datetime-picker 修复 特殊情况日历 rpx 布局错误的 bug,rpx -> px
+- uni-datetime-picker 修复 范围选择时清空返回值不合理的bug,['', ''] -> []
+- uni-datetime-picker 新增 日期时间显示框支持插槽
+- uni-file-picker 修复 sourceType 缺少默认值导致 ios 无法选择文件
+- uni-file-picker 优化 解耦与uniCloud的强绑定关系 ,如不绑定服务空间,默认autoUpload为false且不可更改
+- uni-table 新增 uni-th 支持 date 日期筛选范围
+- uni-table 新增 uni-th 支持 range 筛选范围
+- uni-table 新增 uni-th 筛选功能
+## 1.3.5(2021-07-02)
+- uni-card 优化 图文卡片无图片加载时,提供占位图标
+- uni-card 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持)
+- uni-card 修复 thumbnail 不存在仍然占位的 bug
+- uni-data-checkbox 修复 selectedTextColor 属性不生效的Bug
+- uni-datetime-picker 优化 添加 uni-icons 依赖
+- uni-easyinput 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug
+- uni-file-picker 修复 由 0.0.10 版本引发的 returnType 属性失效的问题
+- uni-file-picker 优化 文件上传后进度条消失时机
+- uni-file-picker 修复 在uni-forms 中,删除文件 ,获取的值不对的Bug
+- uni-forms 修复 pattern 属性在微信小程序平台无效的问题
+## 1.3.4(2021-06-25)
+- uni-badge 优化 示例项目
+- uni-countdown 修复 uni-countdown 重复赋值跳两秒的 bug
+- uni-easyinput 修复 passwordIcon 属性拼写错误的 bug
+- uni-forms 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
+- uni-forms 修复 只写setRules方法而导致校验不生效的Bug
+- uni-forms 修复 由上个办法引发的错误提示文字错位的Bug
+- uni-forms 修复 不设置 label 属性 ,无法设置label插槽的问题
+- uni-forms 修复 不设置label属性,label-width属性不生效的bug
+- uni-forms 修复 setRules 方法与rules属性冲突的问题
+- uni-link 新增 download 属性,H5平台下载文件名
+- uni-popup 新增 mask-click 遮罩层点击事件
+- uni-popup 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+- uni-tag 修复 uni-tag 在字节跳动小程序上 css 类名编译错误的 bug
+## 1.3.3(2021-06-18)
+- uni-easyinput 新增 passwordIcon 属性,当type=password时是否显示小眼睛图标
+- uni-easyinput 修复 confirmType 属性不生效的问题
+- uni-easyinput 修复 disabled 状态可清出内容的 bug
+- uni-file-picker 修复 删除文件时无法触发 v-model 的Bug
+- uni-popup 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+- uni-popup 修复 错误的 watch 字段
+- uni-popup 修复 safeArea 属性不生效的问题
+- uni-popup 修复 点击内容,再点击遮罩无法关闭的Bug
+## 1.3.2(2021-06-04)
+- uni-data-checkbox 新增 map 属性,可以方便映射text/value属性
+- uni-data-checkbox 修复 不关联服务空间的情况下组件报错的Bug
+- uni-data-picker 修复 上个版本引出的本地数据无法选择带有children的2级节点
+- uni-forms 修复 动态删减数据导致报错的问题
+- uni-forms 新增 modelValue 属性 ,value 即将废弃
+- uni-forms 新增 uni-forms-item 可以设置单独的 rules
+- uni-forms 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
+- uni-forms 优化 submit 事件重命名为 validate
+- uni-data-picker 修复 无法加载云端数据的问题
+- uni-data-picker 修复 v-model无效问题
+- uni-data-picker 修复 loaddata 为空数据组时加载时间过长问题
+- uni-datetime-picker 修复 图标在小程序上不显示的 bug
+- uni-datetime-picker 优化 重命名引用组件,避免潜在组件命名冲突
+- uni-datetime-picker 优化 代码目录扁平化
+- uni-tag 修复 未定义 sass 变量 "$uni-color-royal" 的bug
+## 1.3.1(2021-05-14)
+- uni-badge 新增 uni-badge 的 absolute 属性,支持定位
+- uni-badge 新增 uni-badge 的 offset 属性,支持定位偏移
+- uni-badge 新增 uni-badge 的 is-dot 属性,支持仅显示有一个小点
+- uni-badge 新增 uni-badge 的 max-num 属性,支持自定义封顶的数字值,超过 99 显示99+
+- uni-badge 优化 uni-badge 属性 custom-style, 支持以对象形式自定义样式
+- uni-badge 修复 uni-badge 在 App 端,数字小于10时不是圆形的bug
+- uni-badge 修复 uni-badge 在父元素不是 flex 布局时,宽度缩小的bug
+- uni-badge 新增 uni-badge 属性 custom-style, 支持自定义样式
+- uni-datetime-picker 修复 ios 下不识别 '-' 日期格式的 bug
+- uni-datetime-picker 优化 pc 下弹出层添加边框和阴影
+- uni-datetime-picker 修复 在 admin 中获取弹出层定位错误的bug
+- uni-datetime-picker 修复 type 属性向下兼容,默认值从 date 变更为 datetime
+- uni-datetime-picker 支持日历形式的日期+时间的范围选择
+- uni-steps 修复 uni-steps 横向布局时,多行文字高度不合理的 bug
+- uni-countdown 修复 uni-countdown 不能控制倒计时的 bug
+- uni-tag 修复 royal 类型无效的bug
+- uni-tag 修复 uni-tag 宽度不自适应的bug
+- uni-tag 新增 uni-tag 支持属性 custom-style 自定义样式
+- uni-link 新增 href 属性支持 tel:|mailto:
+- uni-popup 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
+- uni-popup 新增 type 属性的 left\right 值,支持左右弹出
+- uni-popup 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
+- uni-popup 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
+- uni-popup 新增 safeArea 属性,是否适配底部安全区
+- uni-popup 修复 App\h5\微信小程序底部安全区占位不对的Bug
+- uni-popup 修复 App 端弹出等待的Bug
+- uni-popup 优化 提升低配设备性能,优化动画卡顿问题
+- uni-popup 优化 更简单的组件自定义方式
+- uni-table 修复 示例项目缺少组件的Bug
+- uni-forms 修复 自定义检验器失效的问题
+- uni-title 修复 示例项目缺少组件的Bug
+- uni-transition 修复 示例项目缺少组件的Bug
+- uni-swiper-dot 修复 示例项目缺少组件的Bug
+- uni-ui 新增 组件示例地址
+## 1.3.0(2021-04-23)
+- uni-combox 优化 添加依赖 uni-icons, 导入后自动下载依赖
+- uni-data-picker 修复 非树形数据有 where 属性查询报错的问题
+- uni-fav 优化 添加依赖 uni-icons, 导入后自动下载依赖
+- uni-goods-nav 优化 添加依赖 uni-icons, 导入后自动下载依赖
+- uni-nav-bar 优化 添加依赖 uni-icons, 导入后自动下载依赖
+- uni-notice-bar 优化 添加依赖 uni-icons, 导入后自动下载依赖
+- uni-number-box 修复 uni-number-box 浮点数运算不精确的 bug
+- uni-number-box 修复 uni-number-box change 事件触发不正确的 bug
+- uni-number-box 新增 uni-number-box v-model 双向绑定
+- uni-rate 修复 布局变化后 uni-rate  星星计算不准确的 bug
+- uni-rate 优化 添加依赖 uni-icons, 导入 uni-rate 自动下载依赖
+- uni-search-bar 优化 添加依赖 uni-icons, 导入后自动下载依赖
+- uni-steps 优化 添加依赖 uni-icons, 导入后自动下载依赖
+- uni-transition 新增 通过方法自定义动画
+- uni-transition 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
+- uni-transition 优化 动画触发逻辑,使动画更流畅
+- uni-transition 优化 支持单独的动画类型
+- uni-transition 优化 文档示例
+## 1.2.13(2021-04-16)
+- uni-ui 新增 uni-data-picker 支持云端非树形表结构数据
+- uni-ui 修复 uni-data-checkbox nvue 下无法选中的问题
+- uni-ui 修复 uni-data-picker 根节点 parent_field 字段等于null时选择界面错乱问题
+- uni-ui 修复 uni-file-picker 选择的文件非 file-extname 字段指定的扩展名报错的Bug
+- uni-ui 修复 uni-swipe-action 报错 nv_navigator is not defined 的bug
+- uni-ui 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
+- uni-ui 优化 uni-file-picker file-extname 字段支持字符串写法,多个扩展名需要用逗号分隔
+- uni-ui 优化 uni-pagination PC 和 移动端适配不同的 ui
+- uni-ui 更新 uni-file-picker 组件示例
+- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
+- uni-ui 新增 uni-search-bar 的 focus 事件
+- uni-ui 修复 uni-rate 属性 margin 值为 string 组件失效的 bug
+- uni-data-picker 修复 本地数据概率无法回显时问题
+- uni-table 新增 sortable 属性,是否开启单列排序
+- uni-table 优化 表格多选逻辑
+## 1.2.12(2021-03-23)
+- uni-ui 新增 uni-datetime-picker 的 hide-second 属性、border 属性;
+- uni-ui 修复 uni-datetime-picker 选择跟显示的日期不一样的 bug,
+- uni-ui 修复 uni-datetime-picker change事件触发2次的 bug
+- uni-ui 修复 uni-datetime-picker 分、秒 end 范围错误的 bug
+- uni-ui 新增 uni-tr selectable 属性,用于 type=selection 时,设置某行是否可由全选按钮控制
+- uni-ui 新增 uni-data-checkbox 新增 disabled属性,支持nvue
+- uni-ui 优化 uni-data-checkbox  无选项时提示“暂无数据”
+- uni-ui 优化 uni-data-checkbox  默认颜色显示
+- uni-ui 新增 uni-link href 属性支持 tel:|mailto:
+- uni-ui 新增 uni-table 示例demo
+- uni-ui 修复 uni-data-picker 微信小程序某些情况下无法选择的问题,事件无法触发的问题
+- uni-ui 修复 uni-nav-bar easycom 下,找不到 uni-status-bar 的bug
+- uni-ui 修复 uni-easyinput 示例在 qq 小程序上的bug
+- uni-ui 修复 uni-forms 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug
+- uni-ui 调整 cli 项目 建议使用 easycom 方式引用组件,如使用按需引用,需手动维护组件内部引用
+
+## 1.2.11(2021-02-24)
+- 调整为uni_modules目录规范
+- uni-data-picker 新增  数据驱动的picker选择器
+- uni-file-picker 新增  文件选择上传
+- uni-row 新增 栅格系统
+- uni-data-checkbox 优化 支持 nvue
+- uni-forms 修复 偶发性获取表单值错误的Bug
+- uni-forms 修复 校验 uni-data-picker value 为 0 时,返回值错误的Bug
+- uni-forms 修复 uni-forms-item 组件隐藏时依然触发校验的bug
+- uni-forms 优化 实时校验
+- uni-forms 优化 兼容nvue页面
+- uni-easyinput 优化 兼容nvue页面
+- uni-group 优化 兼容nvue页面
+- uni-popup 优化 组件适配 PC
+- uni-fab 优化 适配 PC
+- uni-swiper-dot 优化 适配 PC
+- uni-rate 优化 适配 PC
+- uni-notice-bar 优化 适配 PC
+- uni-indexed-list 优化 适配 PC
+- uni-combox 优化 适配 PC
+- uni-transition 优化 适配 PC
+- uni-nav-bar 优化 适配 PC
+- uni-swipe-action 优化 适配 PC
diff --git a/uni_modules/uni-ui/components/uni-ui/uni-ui.vue b/uni_modules/uni-ui/components/uni-ui/uni-ui.vue
new file mode 100644
index 0000000..0970892
--- /dev/null
+++ b/uni_modules/uni-ui/components/uni-ui/uni-ui.vue
@@ -0,0 +1,7 @@
+<template>
+	<view>占位组件,请勿使用</view>
+</template>
+<script>
+</script>
+<style>
+</style>
diff --git a/uni_modules/uni-ui/package.json b/uni_modules/uni-ui/package.json
new file mode 100644
index 0000000..d31a390
--- /dev/null
+++ b/uni_modules/uni-ui/package.json
@@ -0,0 +1,130 @@
+{
+  "id": "uni-ui",
+  "displayName": "uni-ui",
+  "version": "1.5.6",
+  "description": "uni-ui 是基于uni-app的、全端兼容的、高性能UI框架",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "UI组件库",
+    "ui框架",
+    "ui库"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.2.10"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+      "uni-badge",
+      "uni-calendar",
+      "uni-card",
+      "uni-collapse",
+      "uni-combox",
+      "uni-countdown",
+      "uni-data-checkbox",
+      "uni-data-picker",
+      "uni-data-select",
+      "uni-dateformat",
+      "uni-datetime-picker",
+      "uni-drawer",
+      "uni-easyinput",
+      "uni-fab",
+      "uni-fav",
+      "uni-file-picker",
+      "uni-forms",
+      "uni-goods-nav",
+      "uni-grid",
+      "uni-group",
+      "uni-icons",
+      "uni-indexed-list",
+      "uni-link",
+      "uni-list",
+      "uni-load-more",
+      "uni-nav-bar",
+      "uni-notice-bar",
+      "uni-number-box",
+      "uni-pagination",
+      "uni-popup",
+      "uni-rate",
+      "uni-row",
+      "uni-search-bar",
+      "uni-section",
+      "uni-segmented-control",
+      "uni-steps",
+      "uni-swipe-action",
+      "uni-swiper-dot",
+      "uni-table",
+      "uni-tag",
+      "uni-title",
+      "uni-tooltip",
+      "uni-transition"
+    ],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y",
+          "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-ui/readme.md b/uni_modules/uni-ui/readme.md
new file mode 100644
index 0000000..23f8456
--- /dev/null
+++ b/uni_modules/uni-ui/readme.md
@@ -0,0 +1,247 @@
+> 当前插件不包含示例页面 ,如需示例请在 HBuiderX 中新建 `hello uni-app > 扩展组件` 中查看
+> 
+> 代码示例地址 :[https://ext.dcloud.net.cn/plugin?id=4941](https://ext.dcloud.net.cn/plugin?id=4941)
+> 
+> 组件演示地址:[https://hellouniapp.dcloud.net.cn](https://hellouniapp.dcloud.net.cn/pages/extUI/badge/badge)
+> 
+> 组件文档地址:[https://uniapp.dcloud.io/component/uniui/uni-ui](https://uniapp.dcloud.io/component/uniui/uni-ui)
+
+# uni-ui 介绍
+
+## uni-ui产品特点
+
+### 1. 高性能
+
+目前为止,在小程序和混合app领域,暂时还没有比 `uni-ui` 更高性能的框架。
+- 自动差量更新数据
+
+虽然uni-app支持小程序自定义组件,所有小程序的ui库都可以用。但小程序自定义组件的ui库都需要使用setData手动更新数据,在大数据量时、或高频更新数据时,很容易产生性能问题。
+
+而 `uni-ui` 属于vue组件,uni-app引擎底层自动diff更新数据。当然其实插件市场里众多vue组件都具备这个特点。
+- 优化逻辑层和视图层通讯折损
+
+非H5,不管是小程序还是App,不管是app的webview渲染还是原生渲染,全都是逻辑层和视图层分离的。这里就有一个逻辑层和视图层通讯的折损问题。
+比如在视图层拖动一个可跟手的组件,由于通讯的损耗,用js监听很难做到实时跟手。
+
+这时就需要使用css动画以及平台底层提供的wxs、bindingx等技术。不过这些技术都比较复杂,所以 `uni-ui` 里做了封装,在需要跟手式操作的ui组件,比如swiperaction列表项左滑菜单,就在底层使用了这些技术,实现了高性能的交互体验
+- 背景停止
+
+很多ui组件是会一直动的,比如轮播图、跑马灯。即便这个窗体被新窗体挡住,它在背景层仍然在消耗着硬件资源。在Android的webview版本为chrome66以上,背景操作ui会引发很严重的性能问题,造成前台界面明显卡顿。
+
+而 `uni-ui` 的组件,会自动判断自己的显示状态,在组件不再可见时,不会再消耗硬件资源。
+
+### 2. 全端
+
+ `uni-ui` 的组件都是多端自适应的,底层会抹平很多小程序平台的差异或bug。
+
+比如导航栏navbar组件,会自动处理不同端的状态栏。
+比如swiperaction组件,在app和微信小程序上会使用交互体验更好的wxs技术,但在不支持wxs的其他小程序端会使用js模拟类似效果。
+
+ `uni-ui` 还支持nvue原生渲染,[详见](https://github.com/dcloudio/uni-ui/tree/nvue-uni-ui)
+
+未来 `uni-ui` 还会支持pc等大屏设备。
+
+### 3. 与uni统计自动集成实现免打点
+
+uni统计是优秀的多端统计平台,见[tongji.dcloud.net.cn](https://tongji.dcloud.net.cn)。
+
+除了一张报表看全端,它的另一个重要特点是免打点。
+比如使用 `uni-ui` 的navbar标题栏、收藏、购物车等组件,均可实现自动打点,统计页面标题等各种行为数据。
+当然你也可以关闭uni统计,这不是强制的。
+
+### 4. 主题扩展
+
+ `uni-ui` 支持[uni.scss](https://uniapp.dcloud.io/collocation/uni-scss),可以方便的切换App的风格。
+
+ui是一种需求非常发散的产品,DCloud官方也无意用 `uni-ui` 压制第三方ui插件的空间,但官方有义务在性能和多端方面提供一个开源的标杆给大家。
+
+我们欢迎更多优秀的ui组件出现,也欢迎更多人贡献 `uni-ui` 的主题风格,满足更多用户的需求。
+
+
+## 快速开始
+
+uni-ui支持 HBuilderX直接新建项目模板、npm安装和单独导入个别组件等多种使用方式
+
+### 在HBuilderX 新建uni-app项目的模板中,选择uni-ui模板
+![HBuilderX内创建uni-ui项目](https://img.cdn.aliyun.dcloud.net.cn/uni-app/doc/create-uni-ui-project.jpg)
+
+由于uni-app独特的[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)技术,可以免引用、注册,直接使用各种符合规则的vue组件。
+
+在代码区键入`u`,拉出各种内置或uni-ui的组件列表,选择其中一个,即可使用该组件。
+
+光标放在组件名称上,按F1,可以查阅组件的文档。
+
+![uni-ui代码块](https://img.cdn.aliyun.dcloud.net.cn/uni-app/doc/uni-ui-snippet.jpg)
+
+### 通过 uni_modules 单独安装组件
+如果你没有创建uni-ui项目模板,也可以在你的工程里,通过 uni_modules 单独安装需要的某个组件。下表为uni-ui的扩展组件清单,点击每个组件在详情页面可以导入组件到项目下,导入后直接使用即可,无需import和注册。
+
+|组件名|组件说明|
+|---|---|
+|uni-badge|[数字角标](https://ext.dcloud.net.cn/plugin?name=uni-badge)|
+|uni-calendar|[日历](https://ext.dcloud.net.cn/plugin?name=uni-calendar)|
+|uni-card|[卡片](https://ext.dcloud.net.cn/plugin?name=uni-card)|
+|uni-collapse|[折叠面板](https://ext.dcloud.net.cn/plugin?name=uni-collapse)|
+|uni-combox|[组合框](https://ext.dcloud.net.cn/plugin?name=uni-combox)|
+|uni-countdown|[倒计时](https://ext.dcloud.net.cn/plugin?name=uni-countdown)|
+|uni-data-checkbox|[数据选择器](https://ext.dcloud.net.cn/plugin?name=uni-data-checkbox)|
+|uni-data-picker|[数据驱动的picker选择器](https://ext.dcloud.net.cn/plugin?name=uni-data-picker)|
+|uni-dateformat|[日期格式化](https://ext.dcloud.net.cn/plugin?name=uni-dateformat)|
+|uni-datetime-picker|[日期选择器](https://ext.dcloud.net.cn/plugin?name=uni-datetime-picker)|
+|uni-drawer|[抽屉](https://ext.dcloud.net.cn/plugin?name=uni-drawer)|
+|uni-easyinput|[增强输入框](https://ext.dcloud.net.cn/plugin?name=uni-easyinput)|
+|uni-fab|[悬浮按钮](https://ext.dcloud.net.cn/plugin?name=uni-fab)|
+|uni-fav|[收藏按钮](https://ext.dcloud.net.cn/plugin?name=uni-fav)|
+|uni-file-picker|[文件选择上传](https://ext.dcloud.net.cn/plugin?name=uni-file-picker)|
+|uni-forms|[表单](https://ext.dcloud.net.cn/plugin?name=uni-forms)|
+|uni-goods-nav|[商品导航](https://ext.dcloud.net.cn/plugin?name=uni-goods-nav)|
+|uni-grid|[宫格](https://ext.dcloud.net.cn/plugin?name=uni-grid)|
+|uni-group|[分组](https://ext.dcloud.net.cn/plugin?name=uni-group)|
+|uni-icons|[图标](https://ext.dcloud.net.cn/plugin?name=uni-icons)|
+|uni-indexed-list|[索引列表](https://ext.dcloud.net.cn/plugin?name=uni-indexed-list)|
+|uni-link|[超链接](https://ext.dcloud.net.cn/plugin?name=uni-link)|
+|uni-list|[列表](https://ext.dcloud.net.cn/plugin?name=uni-list)|
+|uni-load-more|[加载更多](https://ext.dcloud.net.cn/plugin?name=uni-load-more)|
+|uni-nav-bar|[自定义导航栏](https://ext.dcloud.net.cn/plugin?name=uni-nav-bar)|
+|uni-notice-bar|[通告栏](https://ext.dcloud.net.cn/plugin?name=uni-notice-bar)|
+|uni-number-box|[数字输入框](https://ext.dcloud.net.cn/plugin?name=uni-number-box)|
+|uni-pagination|[分页器](https://ext.dcloud.net.cn/plugin?name=uni-pagination)|
+|uni-popup|[弹出层](https://ext.dcloud.net.cn/plugin?name=uni-popup)|
+|uni-rate|[评分](https://ext.dcloud.net.cn/plugin?name=uni-rate)|
+|uni-row|[布局-行](https://ext.dcloud.net.cn/plugin?name=uni-row)|
+|uni-search-bar|[搜索栏](https://ext.dcloud.net.cn/plugin?name=uni-search-bar)|
+|uni-segmented-control|[分段器](https://ext.dcloud.net.cn/plugin?name=uni-segmented-control)|
+|uni-steps|[步骤条](https://ext.dcloud.net.cn/plugin?name=uni-steps)|
+|uni-swipe-action|[滑动操作](https://ext.dcloud.net.cn/plugin?name=uni-swipe-action)|
+|uni-swiper-dot|[轮播图指示点](https://ext.dcloud.net.cn/plugin?name=uni-swiper-dot)|
+|uni-table|[表格](https://ext.dcloud.net.cn/plugin?name=uni-table)|
+|uni-tag|[标签](https://ext.dcloud.net.cn/plugin?name=uni-tag)|
+|uni-title|[章节标题](https://ext.dcloud.net.cn/plugin?name=uni-title)|
+|uni-transition|[过渡动画](https://ext.dcloud.net.cn/plugin?name=uni-transition)|
+
+
+使用 `uni_modules` 方式安装组件库,可以直接通过插件市场导入,通过右键菜单快速更新组件,不需要引用、注册,直接在页面中使用 `uni-ui` 组件。[点击安装 uni-ui 组件库](https://ext.dcloud.net.cn/plugin?id=55)
+
+**注意:下载最新的组件目前仅支持 uni_modules ,非 uni_modules 版本最高支持到组件的1.2.10版本**
+
+如不能升级到 `uni_modules` 版本,可以使用 `uni_modules` 安装好对应组件,将组件拷贝到对应目录。
+
+例如需更新 `uni-list`和`uni-badge` ,将 `uni_modules>uni-list>components`和`uni_modules>uni-badege>components`下所有目录拷贝到如下目录即可:
+
+
+**目录示例**
+
+```json
+┌─components              组件目录
+│  ├─uni-list             list 列表目录
+│  │  └─uni-list.vue      list 组件文件
+│  ├─uni-list-item        list-item 列表目录
+│  │  └─uni-list-item.vue list 组件文件
+│  ├─uni-badge         	  badge 角标目录
+│  │  └─uni-badge.vue     badge 组件文件
+│  └─ //....              更多组件文件
+├─pages                   业务页面文件存放的目录
+│  ├─index
+│  │  └─index.vue         index示例页面
+├─main.js                 Vue初始化入口文件
+├─App.vue                 应用配置,用来配置App全局样式以及监听 应用生命周期
+├─manifest.json           配置应用名称、appid、logo、版本等打包信息,详见
+└─pages.json              配置页
+
+```
+
+### 通过  `uni_modules` 导入全部组件
+如果想一次把所有uni-ui组件导入到项目中,只需要导入一个 `uni-ui` 组件即可 [点击去导入](https://ext.dcloud.net.cn/plugin?id=55)。
+
+如果没有自动导入其他组件,可以在 uni-ui 组件目录上右键选择 `安装三方插件依赖` 即可。
+
+
+
+### npm安装 
+在 `vue-cli` 项目中可以使用 `npm` 安装 `uni-ui` 库 ,或者直接在 `HBuilderX` 项目中使用 `npm` 。
+
+> **注意**
+> cli 项目默认是不编译 `node_modules` 下的组件的,导致条件编译等功能失效 ,导致组件异常
+> 需要在根目录创建 `vue.config.js` 文件 ,增加 `@dcloudio/uni-ui` 包的编译即可正常
+> ```javascript
+> // vue.config.js
+> module.exports = {
+> 		transpileDependencies:['@dcloudio/uni-ui']
+> }
+> ```
+
+
+
+**准备 sass**
+
+`vue-cli` 项目请先安装 sass 及 sass-loader,如在 HBuliderX 中使用,可跳过此步。
+
+- 安装 sass
+```
+ npm i sass -D   或   yarn add sass -D  
+```
+
+- 安装 sass-loader
+```
+npm i sass-loader@10.1.1 -D   或   yarn add sass-loader@10.1.1 -D
+```
+
+> 如果 `node` 版本小于 16 ,sass-loader 请使用低于 @11.0.0 的版本,[sass-loader@11.0.0 不支持 vue@2.6.12 ](https://stackoverflow.com/questions/66082397/typeerror-this-getoptions-is-not-a-function)
+> 如果 `node` 版本大于 16 , `sass-loader` 建议使用 `v8.x` 版本
+
+**安装 uni-ui**
+
+```
+npm i @dcloudio/uni-ui   或   yarn add @dcloudio/uni-ui
+```
+
+
+
+**配置easycom**
+
+使用 `npm` 安装好 `uni-ui` 之后,需要配置 `easycom` 规则,让 `npm` 安装的组件支持  `easycom`
+
+打开项目根目录下的 `pages.json` 并添加 `easycom` 节点:
+
+```javascript
+// pages.json
+{
+	"easycom": {
+		"autoscan": true,
+		"custom": {
+			// uni-ui 规则如下配置
+			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
+		}
+	},
+	
+	// 其他内容
+	pages:[
+		// ...
+	]
+}
+
+```
+
+在 ``template`` 中使用组件: 
+
+```html
+<uni-badge text="1"></uni-badge>
+<uni-badge text="2" type="success" @click="bindClick"></uni-badge>
+<uni-badge text="3" type="primary" :inverted="true"></uni-badge>
+```
+
+ **注意**
+ - uni-ui 现在只推荐使用 `easycom` ,如自己引用组件,可能会出现组件找不到的问题
+ - 使用 npm 安装的组件,默认情况下 babel-loader 会忽略所有 node_modules 中的文件 ,导致条件编译失效,需要通过配置 `vue.config.js` 解决:
+	 ```javascript
+	 // 在根目录创建 vue.config.js 文件,并配置如下
+	 module.exports = {
+		transpileDependencies: ['@dcloudio/uni-ui']
+	 }
+	 ```
+ - uni-ui 是uni-app内置组件的扩展。注意与web开发不同,uni-ui不包括基础组件,它是基础组件的补充。web开发中有的开发者习惯用一个ui库完成所有开发,但在uni-app体系中,推荐开发者首先使用性能更高的基础组件,然后按需引入必要的扩展组件。
+ - `uni-ui` 不支持使用 `Vue.use()` 的方式安装
+
+
+### 贡献代码
+在使用 `uni-ui` 中,如遇到无法解决的问题,请提 [Issues](https://github.com/dcloudio/uni-ui/issues) 给我们,假如您有更好的点子或更好的实现方式,也欢迎给我们提交 [PR](https://github.com/dcloudio/uni-ui/pulls)
\ No newline at end of file
diff --git a/unpackage/dist/cache/.vite/deps/_metadata.json b/unpackage/dist/cache/.vite/deps/_metadata.json
deleted file mode 100644
index 74eb13c..0000000
--- a/unpackage/dist/cache/.vite/deps/_metadata.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "hash": "675162bf",
-  "configHash": "14deb472",
-  "lockfileHash": "8b439a23",
-  "browserHash": "8f4b50d7",
-  "optimized": {},
-  "chunks": {}
-}
\ No newline at end of file
diff --git a/unpackage/dist/cache/.vite/deps/package.json b/unpackage/dist/cache/.vite/deps/package.json
deleted file mode 100644
index 3dbc1ca..0000000
--- a/unpackage/dist/cache/.vite/deps/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "type": "module"
-}
diff --git a/unpackage/dist/dev/mp-weixin/api/index.js b/unpackage/dist/dev/mp-weixin/api/index.js
deleted file mode 100644
index 42471dc..0000000
--- a/unpackage/dist/dev/mp-weixin/api/index.js
+++ /dev/null
@@ -1,222 +0,0 @@
-"use strict";
-const util_request = require("../util/request.js");
-function wxLoginApi(data) {
-  return util_request.request("/user/wxLogin", data, "POST");
-}
-function getVipInfoApi() {
-  return util_request.request("/waterCard/getUserCard", {}, "GET");
-}
-function getUserInfo() {
-  return util_request.request("/user/loginUser", {}, "GET");
-}
-function getRegionApi(code) {
-  return util_request.request(`/sysRegion/getListChild?code=${code}`, {}, "GET");
-}
-function creatUserArchive(data) {
-  return util_request.request("/userArchives/realName", data, "POST");
-}
-function searchAddress(data) {
-  return util_request.request("/userAddress/search", data, "POST");
-}
-function editAddressApi(data) {
-  return util_request.request("/userAddress/modify", data, "POST");
-}
-function getAddressApi(id) {
-  return util_request.request(`/userAddress/get?id=${id}`, {}, "GET");
-}
-function deleteAddressApi(id) {
-  return util_request.request(`/userAddress/remove?id=${id}`, {}, "GET");
-}
-function setAddressDefaultApi(id) {
-  return util_request.request(`/userAddress/editDefault?id=${id}`, {}, "GET");
-}
-function searchFacilityApi(data) {
-  return util_request.request("/waterFacility/search", data, "POST");
-}
-function siteApi(data) {
-  return util_request.request("/waterDrinkingSite/getSearchList", data, "POST");
-}
-function editUserInfoApi(data) {
-  return util_request.request("/userArchives/modify", data, "POST");
-}
-function wxPayApi(data) {
-  return util_request.request("/pay/service/wxPay", data, "POST");
-}
-function balanceChangeApi(date) {
-  return util_request.request(`/userCapitalChange/getListByUser?date=${date}`, {}, "GET");
-}
-function balanceStatisticsApi(date) {
-  return util_request.request(`/userCapitalChange/getAmountStatistics?date=${date}`, {}, "GET");
-}
-function paymentChangeApi(date) {
-  return util_request.request(`/paymentRecords/getListByUser?date=${date}`, {}, "GET");
-}
-function rechargeChangeApi(date) {
-  return util_request.request(`/rechargeRecords/getListByUser?date=${date}`, {}, "GET");
-}
-function reportLossApi(cardNumber) {
-  return util_request.request(`/waterCard/reportLoss?cardNumber=${cardNumber}`, {}, "GET");
-}
-function removeBindingApi(cardNumber) {
-  return util_request.request(`/waterCard/removeBinding?cardNumber=${cardNumber}`, {}, "GET");
-}
-function infoBreakdownApi(data) {
-  return util_request.request("/waterFacilityMalfunction/create", data, "POST");
-}
-function askShareApi(data) {
-  return util_request.request("/waterCardShare/askShare", data, "POST");
-}
-function askShareListApi(id) {
-  return util_request.request(`/waterCardShare/getListByUser?userId=${id}`, {}, "GET");
-}
-function editShareTypeApi(data) {
-  return util_request.request("/waterCardShare/editShareType", data, "POST");
-}
-function buyWaterApi(data) {
-  return util_request.request("/api/facility/buyWater", data, "POST");
-}
-function getPriceBySnApi(sn) {
-  return util_request.request(`/waterFacility/getPriceBySn?sn=${sn}`, {}, "GET");
-}
-function rechargeApi(data) {
-  return util_request.request("/rechargeRecords/fees", data, "POST");
-}
-function pointsSearchApi(data) {
-  return util_request.request("/userIntegralAcquire/search", data, "POST");
-}
-function pointsExchangeApi(data) {
-  return util_request.request("/userIntegralConvert/search", data, "POST");
-}
-function goodsGetApi(id) {
-  return util_request.request(`/shopGoods/getListByCategoryId?categoryId=${id}`, {}, "GET");
-}
-function goodsGetByIdApi(id) {
-  return util_request.request(`/shopGoods/get?id=${id}`, {}, "GET");
-}
-function goodsSearchTypeApi(data) {
-  return util_request.request("/shopGoodsCategory/search", data, "POST");
-}
-function integralConvertApi(data) {
-  return util_request.request("/userIntegralConvert/create", data, "POST");
-}
-function getRuleDetailApi(data) {
-  return util_request.request("/userIntegralRuleDetail/search", data, "POST");
-}
-function adminLoginApi(data) {
-  return util_request.request("/admin/user/login", data, "POST");
-}
-function adminDetailApi(id) {
-  return util_request.request(`/admin/user/detail?userId=${id}`, {}, "GET");
-}
-function getRunStateApi(data) {
-  return util_request.request(`/homePage/getFacilityRunState`, data, "POST");
-}
-function getTotalRevenueApi(data) {
-  return util_request.request(`/homePage/getTotalRevenue`, data, "POST");
-}
-function getWaterConsumptionApi(data) {
-  return util_request.request(`/homePage/getWaterConsumption`, data, "POST");
-}
-function getParentAreaApi() {
-  return util_request.request(`/waterArea/getParentArea`, {}, "GET");
-}
-function searchWaterFacilityApi(data) {
-  return util_request.request(`/waterFacility/search`, data, "POST");
-}
-function getFacilityApi(id) {
-  return util_request.request(`/waterFacility/get?id=${id}`, {}, "GET");
-}
-function openFacilityApi(data) {
-  return util_request.request("/api/facility/open", data, "POST");
-}
-function closeFacilityApi(data) {
-  return util_request.request("/api/facility/close", data, "POST");
-}
-function getParameterApi(sn) {
-  return util_request.request(`/waterFacility/getParameter?sn=${sn}`, {}, "GET");
-}
-function getParameter1Api(sn) {
-  return util_request.request(`/waterFacility/getWaterControlParameter?sn=${sn}`, {}, "GET");
-}
-function editParameterApi(data) {
-  return util_request.request("/waterFacility/editParameter", data, "POST");
-}
-function editParameter1Api(data) {
-  return util_request.request("/waterFacility/editWaterControlParameter", data, "POST");
-}
-function searchBreakdownApi(data) {
-  return util_request.request("/waterFacilityMalfunction/search", data, "POST");
-}
-function searchMaintainApi(data) {
-  return util_request.request("/facilityMaintainRecord/search", data, "POST");
-}
-function createMaintainApi(data) {
-  return util_request.request("/facilityMaintainRecord/create", data, "POST");
-}
-function searchExamineApi(data) {
-  return util_request.request("/facilityExamineRecord/search", data, "POST");
-}
-function createExamineApi(data) {
-  return util_request.request("/facilityExamineRecord/create", data, "POST");
-}
-function editExamineApi(data) {
-  return util_request.request("/waterFacilityMalfunction/modify", data, "POST");
-}
-function changePasswordApi(data) {
-  return util_request.request("/admin/user/changePassword", data, "POST");
-}
-exports.adminDetailApi = adminDetailApi;
-exports.adminLoginApi = adminLoginApi;
-exports.askShareApi = askShareApi;
-exports.askShareListApi = askShareListApi;
-exports.balanceChangeApi = balanceChangeApi;
-exports.balanceStatisticsApi = balanceStatisticsApi;
-exports.buyWaterApi = buyWaterApi;
-exports.changePasswordApi = changePasswordApi;
-exports.closeFacilityApi = closeFacilityApi;
-exports.creatUserArchive = creatUserArchive;
-exports.createExamineApi = createExamineApi;
-exports.createMaintainApi = createMaintainApi;
-exports.deleteAddressApi = deleteAddressApi;
-exports.editAddressApi = editAddressApi;
-exports.editExamineApi = editExamineApi;
-exports.editParameter1Api = editParameter1Api;
-exports.editParameterApi = editParameterApi;
-exports.editShareTypeApi = editShareTypeApi;
-exports.editUserInfoApi = editUserInfoApi;
-exports.getAddressApi = getAddressApi;
-exports.getFacilityApi = getFacilityApi;
-exports.getParameter1Api = getParameter1Api;
-exports.getParameterApi = getParameterApi;
-exports.getParentAreaApi = getParentAreaApi;
-exports.getPriceBySnApi = getPriceBySnApi;
-exports.getRegionApi = getRegionApi;
-exports.getRuleDetailApi = getRuleDetailApi;
-exports.getRunStateApi = getRunStateApi;
-exports.getTotalRevenueApi = getTotalRevenueApi;
-exports.getUserInfo = getUserInfo;
-exports.getVipInfoApi = getVipInfoApi;
-exports.getWaterConsumptionApi = getWaterConsumptionApi;
-exports.goodsGetApi = goodsGetApi;
-exports.goodsGetByIdApi = goodsGetByIdApi;
-exports.goodsSearchTypeApi = goodsSearchTypeApi;
-exports.infoBreakdownApi = infoBreakdownApi;
-exports.integralConvertApi = integralConvertApi;
-exports.openFacilityApi = openFacilityApi;
-exports.paymentChangeApi = paymentChangeApi;
-exports.pointsExchangeApi = pointsExchangeApi;
-exports.pointsSearchApi = pointsSearchApi;
-exports.rechargeApi = rechargeApi;
-exports.rechargeChangeApi = rechargeChangeApi;
-exports.removeBindingApi = removeBindingApi;
-exports.reportLossApi = reportLossApi;
-exports.searchAddress = searchAddress;
-exports.searchBreakdownApi = searchBreakdownApi;
-exports.searchExamineApi = searchExamineApi;
-exports.searchFacilityApi = searchFacilityApi;
-exports.searchMaintainApi = searchMaintainApi;
-exports.searchWaterFacilityApi = searchWaterFacilityApi;
-exports.setAddressDefaultApi = setAddressDefaultApi;
-exports.siteApi = siteApi;
-exports.wxLoginApi = wxLoginApi;
-exports.wxPayApi = wxPayApi;
diff --git a/unpackage/dist/dev/mp-weixin/app.js b/unpackage/dist/dev/mp-weixin/app.js
deleted file mode 100644
index 78b067c..0000000
--- a/unpackage/dist/dev/mp-weixin/app.js
+++ /dev/null
@@ -1,65 +0,0 @@
-"use strict";
-Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
-const common_vendor = require("./common/vendor.js");
-if (!Math) {
-  "./pages/login/index.js";
-  "./pages/index/index.js";
-  "./pages/addCard/index.js";
-  "./pages/userInfo/index.js";
-  "./pages/functionList/balanceRecord/index.js";
-  "./pages/functionList/paymentRecord/index.js";
-  "./pages/functionList/rechargeRecord/index.js";
-  "./pages/functionList/share/cardShare/index.js";
-  "./pages/functionList/share/shareConfirm/index.js";
-  "./pages/functionList/share/shareList/index.js";
-  "./pages/scanWater/index.js";
-  "./pages/recharge/index.js";
-  "./pages/sendWater/index.js";
-  "./pages/preSendWater/index.js";
-  "./pages/address/index.js";
-  "./pages/addressAdd/index.js";
-  "./pages/addressLocate/index.js";
-  "./pages/success/index.js";
-  "./pages/facilityList/index.js";
-  "./pages/station/index.js";
-  "./pages/infoBreakdown/index.js";
-  "./pages/scanRecharge/index.js";
-  "./pages/scanSuccess/index.js";
-  "./pages/counterRecharge/index.js";
-  "./pages/wxScanWater/index.js";
-  "./pagesAdmin/adminPlatform/home.js";
-  "./pagesAdmin/adminPlatform/facility.js";
-  "./pagesAdmin/adminPlatform/facilityDetail.js";
-  "./pagesAdmin/adminPlatform/inspect.js";
-  "./pagesAdmin/adminPlatform/params.js";
-  "./pagesAdmin/adminPlatform/params1.js";
-  "./pagesAdmin/adminPlatform/breakdown.js";
-  "./pagesAdmin/adminPlatform/maintain.js";
-  "./pagesPoints/pointsMall/index.js";
-  "./pagesPoints/pointsMall/pointsGetRecord/index.js";
-  "./pagesPoints/pointsMall/pointsExchangeRecord/index.js";
-  "./pagesPoints/pointsMall/pointsGoodsDetail/index.js";
-  "./pagesPoints/pointsMall/pointsrule/index.js";
-}
-const _sfc_main = {
-  __name: "App",
-  setup(__props) {
-    common_vendor.onLaunch(async () => {
-      console.log("进入APP.vue");
-    });
-    return () => {
-    };
-  }
-};
-const navbar = () => "./components/navbar/navbar.js";
-const pointNavbar = () => "./components/pointNavbar/pointNavbar.js";
-const DaTree = () => "./components/da-tree/index.js";
-function createApp() {
-  const app = common_vendor.createSSRApp(_sfc_main);
-  app.component("navbar", navbar).component("pointNavbar", pointNavbar).component("DaTree", DaTree);
-  return {
-    app
-  };
-}
-createApp().app.mount("#app");
-exports.createApp = createApp;
diff --git a/unpackage/dist/dev/mp-weixin/app.json b/unpackage/dist/dev/mp-weixin/app.json
deleted file mode 100644
index 0d8d940..0000000
--- a/unpackage/dist/dev/mp-weixin/app.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
-  "pages": [
-    "pages/login/index",
-    "pages/index/index",
-    "pages/addCard/index",
-    "pages/userInfo/index",
-    "pages/functionList/balanceRecord/index",
-    "pages/functionList/paymentRecord/index",
-    "pages/functionList/rechargeRecord/index",
-    "pages/functionList/share/cardShare/index",
-    "pages/functionList/share/shareConfirm/index",
-    "pages/functionList/share/shareList/index",
-    "pages/scanWater/index",
-    "pages/recharge/index",
-    "pages/sendWater/index",
-    "pages/preSendWater/index",
-    "pages/address/index",
-    "pages/addressAdd/index",
-    "pages/addressLocate/index",
-    "pages/success/index",
-    "pages/facilityList/index",
-    "pages/station/index",
-    "pages/infoBreakdown/index",
-    "pages/scanRecharge/index",
-    "pages/scanSuccess/index",
-    "pages/counterRecharge/index",
-    "pages/wxScanWater/index"
-  ],
-  "subPackages": [
-    {
-      "root": "pagesAdmin",
-      "pages": [
-        "adminPlatform/home",
-        "adminPlatform/facility",
-        "adminPlatform/facilityDetail",
-        "adminPlatform/inspect",
-        "adminPlatform/params",
-        "adminPlatform/params1",
-        "adminPlatform/breakdown",
-        "adminPlatform/maintain"
-      ]
-    },
-    {
-      "root": "pagesPoints",
-      "pages": [
-        "pointsMall/index",
-        "pointsMall/pointsGetRecord/index",
-        "pointsMall/pointsExchangeRecord/index",
-        "pointsMall/pointsGoodsDetail/index",
-        "pointsMall/pointsrule/index"
-      ]
-    }
-  ],
-  "window": {
-    "navigationStyle": "custom"
-  },
-  "permission": {
-    "scope.userLocation": {
-      "desc": "你的位置信息将用于计算直饮水设备与您的距离"
-    }
-  },
-  "requiredPrivateInfos": [
-    "getLocation"
-  ],
-  "usingComponents": {
-    "navbar": "/components/navbar/navbar",
-    "point-navbar": "/components/pointNavbar/pointNavbar",
-    "da-tree": "/components/da-tree/index"
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/app.wxss b/unpackage/dist/dev/mp-weixin/app.wxss
deleted file mode 100644
index c1b6251..0000000
--- a/unpackage/dist/dev/mp-weixin/app.wxss
+++ /dev/null
@@ -1 +0,0 @@
-page{--status-bar-height:25px;--top-window-height:0px;--window-top:0px;--window-bottom:0px;--window-left:0px;--window-right:0px;--window-magin:0px}[data-c-h="true"]{display: none !important;}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/common/assets.js b/unpackage/dist/dev/mp-weixin/common/assets.js
deleted file mode 100644
index 28b3018..0000000
--- a/unpackage/dist/dev/mp-weixin/common/assets.js
+++ /dev/null
@@ -1,95 +0,0 @@
-"use strict";
-const _imports_0$h = "/static/images/login/logo.png";
-const _imports_1$9 = "/static/images/login/wx.png";
-const _imports_2$2 = "/static/images/login/close_pwd.png";
-const _imports_3$3 = "/static/images/login/open_pwd.png";
-const _imports_4$2 = "/static/images/login/switchto.svg";
-const _imports_0$g = "/static/images/index/head.png";
-const _imports_1$8 = "/static/images/index/back.png";
-const _imports_0$f = "/static/images/index/card11.png";
-const _imports_3$2 = "/static/images/index/home21.svg";
-const _imports_1$7 = "/static/images/index/icon22.svg";
-const _imports_5$1 = "/static/images/index/scan.png";
-const _imports_6$1 = "/static/images/index/point-banner.png";
-const _imports_7 = "/static/images/index/icon51.svg";
-const _imports_8$1 = "/static/images/index/more-info5.png";
-const _imports_9$1 = "/static/images/index/notice5.svg";
-const _imports_0$e = "/static/images/addCard/code.svg";
-const _imports_1$6 = "/static/images/other/more.png";
-const _imports_0$d = "/static/images/other/expand.png";
-const _imports_0$c = "/static/images/other/nodata.png";
-const _imports_0$b = "/static/images/other/code-none.png";
-const _imports_0$a = "/static/images/address/edit.png";
-const _imports_1$5 = "/static/images/address/delete.png";
-const _imports_0$9 = "/static/images/address/expand.png";
-const _imports_0$8 = "/static/images/other/success.png";
-const _imports_0$7 = "/static/images/station/facilityImg.svg";
-const _imports_1$4 = "/static/images/other/img-add.png";
-const _imports_0$6 = "/static/images/other/home.svg";
-const _imports_0$5 = "/static/images/maintain/maintenance-head.svg";
-const _imports_1$3 = "/static/images/maintain/fun-icon1.svg";
-const _imports_2$1 = "/static/images/maintain/fun-icon2.svg";
-const _imports_3$1 = "/static/images/maintain/fun-icon3.svg";
-const _imports_4$1 = "/static/images/maintain/fun-icon4.svg";
-const _imports_0$4 = "/static/images/maintain/expand.svg";
-const _imports_0$3 = "/static/images/maintain/switch-on.png";
-const _imports_1$2 = "/static/images/maintain/switch-off.png";
-const _imports_0$2 = "/static/images/pointMall/back.svg";
-const _imports_1$1 = "/static/images/pointMall/points.svg";
-const _imports_2 = "/static/images/pointMall/points-icon.svg";
-const _imports_3 = "/static/images/pointMall/advert/gift1.svg";
-const _imports_4 = "/static/images/pointMall/advert/gift2.svg";
-const _imports_5 = "/static/images/pointMall/advert/bag.svg";
-const _imports_6 = "/static/images/pointMall/advert/money.svg";
-const _imports_0$1 = "/static/images/pointMall/advert/money1.svg";
-const _imports_8 = "/static/images/pointMall/nav1.svg";
-const _imports_9 = "/static/images/pointMall/nav2.svg";
-const _imports_1 = "/static/images/pointMall/noRecord.svg";
-const _imports_0 = "/static/images/other/navBack.svg";
-exports._imports_0 = _imports_0;
-exports._imports_0$1 = _imports_0$2;
-exports._imports_0$10 = _imports_0$9;
-exports._imports_0$11 = _imports_0$8;
-exports._imports_0$12 = _imports_0$7;
-exports._imports_0$13 = _imports_0$6;
-exports._imports_0$14 = _imports_0$5;
-exports._imports_0$15 = _imports_0$4;
-exports._imports_0$16 = _imports_0$3;
-exports._imports_0$17 = _imports_0$1;
-exports._imports_0$2 = _imports_0$h;
-exports._imports_0$3 = _imports_0$f;
-exports._imports_0$4 = _imports_0$g;
-exports._imports_0$5 = _imports_0$e;
-exports._imports_0$6 = _imports_0$c;
-exports._imports_0$7 = _imports_0$d;
-exports._imports_0$8 = _imports_0$b;
-exports._imports_0$9 = _imports_0$a;
-exports._imports_1 = _imports_1$9;
-exports._imports_1$1 = _imports_1$7;
-exports._imports_1$2 = _imports_1$8;
-exports._imports_1$3 = _imports_1$6;
-exports._imports_1$4 = _imports_1$5;
-exports._imports_1$5 = _imports_1$4;
-exports._imports_1$6 = _imports_1$3;
-exports._imports_1$7 = _imports_1$2;
-exports._imports_1$8 = _imports_1$1;
-exports._imports_1$9 = _imports_1;
-exports._imports_2 = _imports_2$2;
-exports._imports_2$1 = _imports_2$1;
-exports._imports_2$2 = _imports_2;
-exports._imports_3 = _imports_3$3;
-exports._imports_3$1 = _imports_3$2;
-exports._imports_3$2 = _imports_3$1;
-exports._imports_3$3 = _imports_3;
-exports._imports_4 = _imports_4$2;
-exports._imports_4$1 = _imports_4$1;
-exports._imports_4$2 = _imports_4;
-exports._imports_5 = _imports_5$1;
-exports._imports_5$1 = _imports_5;
-exports._imports_6 = _imports_6$1;
-exports._imports_6$1 = _imports_6;
-exports._imports_7 = _imports_7;
-exports._imports_8 = _imports_8$1;
-exports._imports_8$1 = _imports_8;
-exports._imports_9 = _imports_9$1;
-exports._imports_9$1 = _imports_9;
diff --git a/unpackage/dist/dev/mp-weixin/common/vendor.js b/unpackage/dist/dev/mp-weixin/common/vendor.js
deleted file mode 100644
index 03d24d8..0000000
--- a/unpackage/dist/dev/mp-weixin/common/vendor.js
+++ /dev/null
@@ -1,10953 +0,0 @@
-"use strict";
-const _export_sfc = (sfc, props) => {
-  const target = sfc.__vccOpts || sfc;
-  for (const [key, val] of props) {
-    target[key] = val;
-  }
-  return target;
-};
-/**
-* @vue/shared v3.4.21
-* (c) 2018-present Yuxi (Evan) You and Vue contributors
-* @license MIT
-**/
-function makeMap(str, expectsLowerCase) {
-  const set2 = new Set(str.split(","));
-  return expectsLowerCase ? (val) => set2.has(val.toLowerCase()) : (val) => set2.has(val);
-}
-const EMPTY_OBJ = Object.freeze({});
-const EMPTY_ARR = Object.freeze([]);
-const NOOP = () => {
-};
-const NO = () => false;
-const isOn = (key) => key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && // uppercase letter
-(key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97);
-const isModelListener = (key) => key.startsWith("onUpdate:");
-const extend = Object.assign;
-const remove = (arr, el) => {
-  const i2 = arr.indexOf(el);
-  if (i2 > -1) {
-    arr.splice(i2, 1);
-  }
-};
-const hasOwnProperty$2 = Object.prototype.hasOwnProperty;
-const hasOwn$1 = (val, key) => hasOwnProperty$2.call(val, key);
-const isArray = Array.isArray;
-const isMap = (val) => toTypeString(val) === "[object Map]";
-const isSet = (val) => toTypeString(val) === "[object Set]";
-const isFunction = (val) => typeof val === "function";
-const isString = (val) => typeof val === "string";
-const isSymbol = (val) => typeof val === "symbol";
-const isObject$1 = (val) => val !== null && typeof val === "object";
-const isPromise = (val) => {
-  return (isObject$1(val) || isFunction(val)) && isFunction(val.then) && isFunction(val.catch);
-};
-const objectToString = Object.prototype.toString;
-const toTypeString = (value) => objectToString.call(value);
-const toRawType = (value) => {
-  return toTypeString(value).slice(8, -1);
-};
-const isPlainObject = (val) => toTypeString(val) === "[object Object]";
-const isIntegerKey = (key) => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key;
-const isReservedProp = /* @__PURE__ */ makeMap(
-  // the leading comma is intentional so empty string "" is also included
-  ",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"
-);
-const isBuiltInDirective = /* @__PURE__ */ makeMap(
-  "bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo"
-);
-const cacheStringFunction = (fn) => {
-  const cache = /* @__PURE__ */ Object.create(null);
-  return (str) => {
-    const hit = cache[str];
-    return hit || (cache[str] = fn(str));
-  };
-};
-const camelizeRE = /-(\w)/g;
-const camelize = cacheStringFunction((str) => {
-  return str.replace(camelizeRE, (_2, c2) => c2 ? c2.toUpperCase() : "");
-});
-const hyphenateRE = /\B([A-Z])/g;
-const hyphenate = cacheStringFunction(
-  (str) => str.replace(hyphenateRE, "-$1").toLowerCase()
-);
-const capitalize = cacheStringFunction((str) => {
-  return str.charAt(0).toUpperCase() + str.slice(1);
-});
-const toHandlerKey = cacheStringFunction((str) => {
-  const s2 = str ? `on${capitalize(str)}` : ``;
-  return s2;
-});
-const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
-const invokeArrayFns$1 = (fns, arg) => {
-  for (let i2 = 0; i2 < fns.length; i2++) {
-    fns[i2](arg);
-  }
-};
-const def = (obj, key, value) => {
-  Object.defineProperty(obj, key, {
-    configurable: true,
-    enumerable: false,
-    value
-  });
-};
-const looseToNumber = (val) => {
-  const n2 = parseFloat(val);
-  return isNaN(n2) ? val : n2;
-};
-let _globalThis;
-const getGlobalThis = () => {
-  return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {});
-};
-function normalizeStyle(value) {
-  if (isArray(value)) {
-    const res = {};
-    for (let i2 = 0; i2 < value.length; i2++) {
-      const item = value[i2];
-      const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item);
-      if (normalized) {
-        for (const key in normalized) {
-          res[key] = normalized[key];
-        }
-      }
-    }
-    return res;
-  } else if (isString(value) || isObject$1(value)) {
-    return value;
-  }
-}
-const listDelimiterRE = /;(?![^(]*\))/g;
-const propertyDelimiterRE = /:([^]+)/;
-const styleCommentRE = /\/\*[^]*?\*\//g;
-function parseStringStyle(cssText) {
-  const ret = {};
-  cssText.replace(styleCommentRE, "").split(listDelimiterRE).forEach((item) => {
-    if (item) {
-      const tmp = item.split(propertyDelimiterRE);
-      tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
-    }
-  });
-  return ret;
-}
-function normalizeClass(value) {
-  let res = "";
-  if (isString(value)) {
-    res = value;
-  } else if (isArray(value)) {
-    for (let i2 = 0; i2 < value.length; i2++) {
-      const normalized = normalizeClass(value[i2]);
-      if (normalized) {
-        res += normalized + " ";
-      }
-    }
-  } else if (isObject$1(value)) {
-    for (const name in value) {
-      if (value[name]) {
-        res += name + " ";
-      }
-    }
-  }
-  return res.trim();
-}
-const toDisplayString = (val) => {
-  return isString(val) ? val : val == null ? "" : isArray(val) || isObject$1(val) && (val.toString === objectToString || !isFunction(val.toString)) ? JSON.stringify(val, replacer, 2) : String(val);
-};
-const replacer = (_key, val) => {
-  if (val && val.__v_isRef) {
-    return replacer(_key, val.value);
-  } else if (isMap(val)) {
-    return {
-      [`Map(${val.size})`]: [...val.entries()].reduce(
-        (entries, [key, val2], i2) => {
-          entries[stringifySymbol(key, i2) + " =>"] = val2;
-          return entries;
-        },
-        {}
-      )
-    };
-  } else if (isSet(val)) {
-    return {
-      [`Set(${val.size})`]: [...val.values()].map((v2) => stringifySymbol(v2))
-    };
-  } else if (isSymbol(val)) {
-    return stringifySymbol(val);
-  } else if (isObject$1(val) && !isArray(val) && !isPlainObject(val)) {
-    return String(val);
-  }
-  return val;
-};
-const stringifySymbol = (v2, i2 = "") => {
-  var _a;
-  return isSymbol(v2) ? `Symbol(${(_a = v2.description) != null ? _a : i2})` : v2;
-};
-const SLOT_DEFAULT_NAME = "d";
-const ON_SHOW = "onShow";
-const ON_HIDE = "onHide";
-const ON_LAUNCH = "onLaunch";
-const ON_ERROR = "onError";
-const ON_THEME_CHANGE = "onThemeChange";
-const ON_PAGE_NOT_FOUND = "onPageNotFound";
-const ON_UNHANDLE_REJECTION = "onUnhandledRejection";
-const ON_EXIT = "onExit";
-const ON_LOAD = "onLoad";
-const ON_READY = "onReady";
-const ON_UNLOAD = "onUnload";
-const ON_INIT = "onInit";
-const ON_SAVE_EXIT_STATE = "onSaveExitState";
-const ON_RESIZE = "onResize";
-const ON_BACK_PRESS = "onBackPress";
-const ON_PAGE_SCROLL = "onPageScroll";
-const ON_TAB_ITEM_TAP = "onTabItemTap";
-const ON_REACH_BOTTOM = "onReachBottom";
-const ON_PULL_DOWN_REFRESH = "onPullDownRefresh";
-const ON_SHARE_TIMELINE = "onShareTimeline";
-const ON_ADD_TO_FAVORITES = "onAddToFavorites";
-const ON_SHARE_APP_MESSAGE = "onShareAppMessage";
-const ON_NAVIGATION_BAR_BUTTON_TAP = "onNavigationBarButtonTap";
-const ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED = "onNavigationBarSearchInputClicked";
-const ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED = "onNavigationBarSearchInputChanged";
-const ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED = "onNavigationBarSearchInputConfirmed";
-const ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED = "onNavigationBarSearchInputFocusChanged";
-const customizeRE = /:/g;
-function customizeEvent(str) {
-  return camelize(str.replace(customizeRE, "-"));
-}
-function hasLeadingSlash(str) {
-  return str.indexOf("/") === 0;
-}
-function addLeadingSlash(str) {
-  return hasLeadingSlash(str) ? str : "/" + str;
-}
-const invokeArrayFns = (fns, arg) => {
-  let ret;
-  for (let i2 = 0; i2 < fns.length; i2++) {
-    ret = fns[i2](arg);
-  }
-  return ret;
-};
-function once(fn, ctx = null) {
-  let res;
-  return (...args) => {
-    if (fn) {
-      res = fn.apply(ctx, args);
-      fn = null;
-    }
-    return res;
-  };
-}
-function getValueByDataPath(obj, path) {
-  if (!isString(path)) {
-    return;
-  }
-  path = path.replace(/\[(\d+)\]/g, ".$1");
-  const parts = path.split(".");
-  let key = parts[0];
-  if (!obj) {
-    obj = {};
-  }
-  if (parts.length === 1) {
-    return obj[key];
-  }
-  return getValueByDataPath(obj[key], parts.slice(1).join("."));
-}
-function sortObject(obj) {
-  let sortObj = {};
-  if (isPlainObject(obj)) {
-    Object.keys(obj).sort().forEach((key) => {
-      const _key = key;
-      sortObj[_key] = obj[_key];
-    });
-  }
-  return !Object.keys(sortObj) ? obj : sortObj;
-}
-const encode = encodeURIComponent;
-function stringifyQuery(obj, encodeStr = encode) {
-  const res = obj ? Object.keys(obj).map((key) => {
-    let val = obj[key];
-    if (typeof val === void 0 || val === null) {
-      val = "";
-    } else if (isPlainObject(val)) {
-      val = JSON.stringify(val);
-    }
-    return encodeStr(key) + "=" + encodeStr(val);
-  }).filter((x) => x.length > 0).join("&") : null;
-  return res ? `?${res}` : "";
-}
-const PAGE_HOOKS = [
-  ON_INIT,
-  ON_LOAD,
-  ON_SHOW,
-  ON_HIDE,
-  ON_UNLOAD,
-  ON_BACK_PRESS,
-  ON_PAGE_SCROLL,
-  ON_TAB_ITEM_TAP,
-  ON_REACH_BOTTOM,
-  ON_PULL_DOWN_REFRESH,
-  ON_SHARE_TIMELINE,
-  ON_SHARE_APP_MESSAGE,
-  ON_ADD_TO_FAVORITES,
-  ON_SAVE_EXIT_STATE,
-  ON_NAVIGATION_BAR_BUTTON_TAP,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED
-];
-function isRootHook(name) {
-  return PAGE_HOOKS.indexOf(name) > -1;
-}
-const UniLifecycleHooks = [
-  ON_SHOW,
-  ON_HIDE,
-  ON_LAUNCH,
-  ON_ERROR,
-  ON_THEME_CHANGE,
-  ON_PAGE_NOT_FOUND,
-  ON_UNHANDLE_REJECTION,
-  ON_EXIT,
-  ON_INIT,
-  ON_LOAD,
-  ON_READY,
-  ON_UNLOAD,
-  ON_RESIZE,
-  ON_BACK_PRESS,
-  ON_PAGE_SCROLL,
-  ON_TAB_ITEM_TAP,
-  ON_REACH_BOTTOM,
-  ON_PULL_DOWN_REFRESH,
-  ON_SHARE_TIMELINE,
-  ON_ADD_TO_FAVORITES,
-  ON_SHARE_APP_MESSAGE,
-  ON_SAVE_EXIT_STATE,
-  ON_NAVIGATION_BAR_BUTTON_TAP,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED,
-  ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED
-];
-const MINI_PROGRAM_PAGE_RUNTIME_HOOKS = /* @__PURE__ */ (() => {
-  return {
-    onPageScroll: 1,
-    onShareAppMessage: 1 << 1,
-    onShareTimeline: 1 << 2
-  };
-})();
-function isUniLifecycleHook(name, value, checkType = true) {
-  if (checkType && !isFunction(value)) {
-    return false;
-  }
-  if (UniLifecycleHooks.indexOf(name) > -1) {
-    return true;
-  } else if (name.indexOf("on") === 0) {
-    return true;
-  }
-  return false;
-}
-let vueApp;
-const createVueAppHooks = [];
-function onCreateVueApp(hook) {
-  if (vueApp) {
-    return hook(vueApp);
-  }
-  createVueAppHooks.push(hook);
-}
-function invokeCreateVueAppHook(app) {
-  vueApp = app;
-  createVueAppHooks.forEach((hook) => hook(app));
-}
-const invokeCreateErrorHandler = once((app, createErrorHandler2) => {
-  if (isFunction(app._component.onError)) {
-    return createErrorHandler2(app);
-  }
-});
-const E$1 = function() {
-};
-E$1.prototype = {
-  on: function(name, callback, ctx) {
-    var e2 = this.e || (this.e = {});
-    (e2[name] || (e2[name] = [])).push({
-      fn: callback,
-      ctx
-    });
-    return this;
-  },
-  once: function(name, callback, ctx) {
-    var self2 = this;
-    function listener() {
-      self2.off(name, listener);
-      callback.apply(ctx, arguments);
-    }
-    listener._ = callback;
-    return this.on(name, listener, ctx);
-  },
-  emit: function(name) {
-    var data = [].slice.call(arguments, 1);
-    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
-    var i2 = 0;
-    var len = evtArr.length;
-    for (i2; i2 < len; i2++) {
-      evtArr[i2].fn.apply(evtArr[i2].ctx, data);
-    }
-    return this;
-  },
-  off: function(name, callback) {
-    var e2 = this.e || (this.e = {});
-    var evts = e2[name];
-    var liveEvents = [];
-    if (evts && callback) {
-      for (var i2 = evts.length - 1; i2 >= 0; i2--) {
-        if (evts[i2].fn === callback || evts[i2].fn._ === callback) {
-          evts.splice(i2, 1);
-          break;
-        }
-      }
-      liveEvents = evts;
-    }
-    liveEvents.length ? e2[name] = liveEvents : delete e2[name];
-    return this;
-  }
-};
-var E$1$1 = E$1;
-const isObject = (val) => val !== null && typeof val === "object";
-const defaultDelimiters = ["{", "}"];
-class BaseFormatter {
-  constructor() {
-    this._caches = /* @__PURE__ */ Object.create(null);
-  }
-  interpolate(message, values, delimiters = defaultDelimiters) {
-    if (!values) {
-      return [message];
-    }
-    let tokens = this._caches[message];
-    if (!tokens) {
-      tokens = parse(message, delimiters);
-      this._caches[message] = tokens;
-    }
-    return compile$1(tokens, values);
-  }
-}
-const RE_TOKEN_LIST_VALUE = /^(?:\d)+/;
-const RE_TOKEN_NAMED_VALUE = /^(?:\w)+/;
-function parse(format, [startDelimiter, endDelimiter]) {
-  const tokens = [];
-  let position = 0;
-  let text = "";
-  while (position < format.length) {
-    let char = format[position++];
-    if (char === startDelimiter) {
-      if (text) {
-        tokens.push({ type: "text", value: text });
-      }
-      text = "";
-      let sub = "";
-      char = format[position++];
-      while (char !== void 0 && char !== endDelimiter) {
-        sub += char;
-        char = format[position++];
-      }
-      const isClosed = char === endDelimiter;
-      const type = RE_TOKEN_LIST_VALUE.test(sub) ? "list" : isClosed && RE_TOKEN_NAMED_VALUE.test(sub) ? "named" : "unknown";
-      tokens.push({ value: sub, type });
-    } else {
-      text += char;
-    }
-  }
-  text && tokens.push({ type: "text", value: text });
-  return tokens;
-}
-function compile$1(tokens, values) {
-  const compiled = [];
-  let index2 = 0;
-  const mode = Array.isArray(values) ? "list" : isObject(values) ? "named" : "unknown";
-  if (mode === "unknown") {
-    return compiled;
-  }
-  while (index2 < tokens.length) {
-    const token = tokens[index2];
-    switch (token.type) {
-      case "text":
-        compiled.push(token.value);
-        break;
-      case "list":
-        compiled.push(values[parseInt(token.value, 10)]);
-        break;
-      case "named":
-        if (mode === "named") {
-          compiled.push(values[token.value]);
-        } else {
-          {
-            console.warn(`Type of token '${token.type}' and format of value '${mode}' don't match!`);
-          }
-        }
-        break;
-      case "unknown":
-        {
-          console.warn(`Detect 'unknown' type of token!`);
-        }
-        break;
-    }
-    index2++;
-  }
-  return compiled;
-}
-const LOCALE_ZH_HANS = "zh-Hans";
-const LOCALE_ZH_HANT = "zh-Hant";
-const LOCALE_EN = "en";
-const LOCALE_FR = "fr";
-const LOCALE_ES = "es";
-const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
-const hasOwn = (val, key) => hasOwnProperty$1.call(val, key);
-const defaultFormatter = new BaseFormatter();
-function include(str, parts) {
-  return !!parts.find((part) => str.indexOf(part) !== -1);
-}
-function startsWith(str, parts) {
-  return parts.find((part) => str.indexOf(part) === 0);
-}
-function normalizeLocale(locale, messages) {
-  if (!locale) {
-    return;
-  }
-  locale = locale.trim().replace(/_/g, "-");
-  if (messages && messages[locale]) {
-    return locale;
-  }
-  locale = locale.toLowerCase();
-  if (locale === "chinese") {
-    return LOCALE_ZH_HANS;
-  }
-  if (locale.indexOf("zh") === 0) {
-    if (locale.indexOf("-hans") > -1) {
-      return LOCALE_ZH_HANS;
-    }
-    if (locale.indexOf("-hant") > -1) {
-      return LOCALE_ZH_HANT;
-    }
-    if (include(locale, ["-tw", "-hk", "-mo", "-cht"])) {
-      return LOCALE_ZH_HANT;
-    }
-    return LOCALE_ZH_HANS;
-  }
-  let locales = [LOCALE_EN, LOCALE_FR, LOCALE_ES];
-  if (messages && Object.keys(messages).length > 0) {
-    locales = Object.keys(messages);
-  }
-  const lang = startsWith(locale, locales);
-  if (lang) {
-    return lang;
-  }
-}
-class I18n {
-  constructor({ locale, fallbackLocale, messages, watcher, formater: formater2 }) {
-    this.locale = LOCALE_EN;
-    this.fallbackLocale = LOCALE_EN;
-    this.message = {};
-    this.messages = {};
-    this.watchers = [];
-    if (fallbackLocale) {
-      this.fallbackLocale = fallbackLocale;
-    }
-    this.formater = formater2 || defaultFormatter;
-    this.messages = messages || {};
-    this.setLocale(locale || LOCALE_EN);
-    if (watcher) {
-      this.watchLocale(watcher);
-    }
-  }
-  setLocale(locale) {
-    const oldLocale = this.locale;
-    this.locale = normalizeLocale(locale, this.messages) || this.fallbackLocale;
-    if (!this.messages[this.locale]) {
-      this.messages[this.locale] = {};
-    }
-    this.message = this.messages[this.locale];
-    if (oldLocale !== this.locale) {
-      this.watchers.forEach((watcher) => {
-        watcher(this.locale, oldLocale);
-      });
-    }
-  }
-  getLocale() {
-    return this.locale;
-  }
-  watchLocale(fn) {
-    const index2 = this.watchers.push(fn) - 1;
-    return () => {
-      this.watchers.splice(index2, 1);
-    };
-  }
-  add(locale, message, override = true) {
-    const curMessages = this.messages[locale];
-    if (curMessages) {
-      if (override) {
-        Object.assign(curMessages, message);
-      } else {
-        Object.keys(message).forEach((key) => {
-          if (!hasOwn(curMessages, key)) {
-            curMessages[key] = message[key];
-          }
-        });
-      }
-    } else {
-      this.messages[locale] = message;
-    }
-  }
-  f(message, values, delimiters) {
-    return this.formater.interpolate(message, values, delimiters).join("");
-  }
-  t(key, locale, values) {
-    let message = this.message;
-    if (typeof locale === "string") {
-      locale = normalizeLocale(locale, this.messages);
-      locale && (message = this.messages[locale]);
-    } else {
-      values = locale;
-    }
-    if (!hasOwn(message, key)) {
-      console.warn(`Cannot translate the value of keypath ${key}. Use the value of keypath as default.`);
-      return key;
-    }
-    return this.formater.interpolate(message[key], values).join("");
-  }
-}
-function watchAppLocale(appVm, i18n) {
-  if (appVm.$watchLocale) {
-    appVm.$watchLocale((newLocale) => {
-      i18n.setLocale(newLocale);
-    });
-  } else {
-    appVm.$watch(() => appVm.$locale, (newLocale) => {
-      i18n.setLocale(newLocale);
-    });
-  }
-}
-function getDefaultLocale() {
-  if (typeof index !== "undefined" && index.getLocale) {
-    return index.getLocale();
-  }
-  if (typeof global !== "undefined" && global.getLocale) {
-    return global.getLocale();
-  }
-  return LOCALE_EN;
-}
-function initVueI18n(locale, messages = {}, fallbackLocale, watcher) {
-  if (typeof locale !== "string") {
-    const options = [
-      messages,
-      locale
-    ];
-    locale = options[0];
-    messages = options[1];
-  }
-  if (typeof locale !== "string") {
-    locale = getDefaultLocale();
-  }
-  if (typeof fallbackLocale !== "string") {
-    fallbackLocale = typeof __uniConfig !== "undefined" && __uniConfig.fallbackLocale || LOCALE_EN;
-  }
-  const i18n = new I18n({
-    locale,
-    fallbackLocale,
-    messages,
-    watcher
-  });
-  let t2 = (key, values) => {
-    if (typeof getApp !== "function") {
-      t2 = function(key2, values2) {
-        return i18n.t(key2, values2);
-      };
-    } else {
-      let isWatchedAppLocale = false;
-      t2 = function(key2, values2) {
-        const appVm = getApp().$vm;
-        if (appVm) {
-          appVm.$locale;
-          if (!isWatchedAppLocale) {
-            isWatchedAppLocale = true;
-            watchAppLocale(appVm, i18n);
-          }
-        }
-        return i18n.t(key2, values2);
-      };
-    }
-    return t2(key, values);
-  };
-  return {
-    i18n,
-    f(message, values, delimiters) {
-      return i18n.f(message, values, delimiters);
-    },
-    t(key, values) {
-      return t2(key, values);
-    },
-    add(locale2, message, override = true) {
-      return i18n.add(locale2, message, override);
-    },
-    watch(fn) {
-      return i18n.watchLocale(fn);
-    },
-    getLocale() {
-      return i18n.getLocale();
-    },
-    setLocale(newLocale) {
-      return i18n.setLocale(newLocale);
-    }
-  };
-}
-function getBaseSystemInfo() {
-  return wx.getSystemInfoSync();
-}
-function validateProtocolFail(name, msg) {
-  console.warn(`${name}: ${msg}`);
-}
-function validateProtocol(name, data, protocol, onFail) {
-  if (!onFail) {
-    onFail = validateProtocolFail;
-  }
-  for (const key in protocol) {
-    const errMsg = validateProp$1(key, data[key], protocol[key], !hasOwn$1(data, key));
-    if (isString(errMsg)) {
-      onFail(name, errMsg);
-    }
-  }
-}
-function validateProtocols(name, args, protocol, onFail) {
-  if (!protocol) {
-    return;
-  }
-  if (!isArray(protocol)) {
-    return validateProtocol(name, args[0] || /* @__PURE__ */ Object.create(null), protocol, onFail);
-  }
-  const len = protocol.length;
-  const argsLen = args.length;
-  for (let i2 = 0; i2 < len; i2++) {
-    const opts = protocol[i2];
-    const data = /* @__PURE__ */ Object.create(null);
-    if (argsLen > i2) {
-      data[opts.name] = args[i2];
-    }
-    validateProtocol(name, data, { [opts.name]: opts }, onFail);
-  }
-}
-function validateProp$1(name, value, prop, isAbsent) {
-  if (!isPlainObject(prop)) {
-    prop = { type: prop };
-  }
-  const { type, required, validator } = prop;
-  if (required && isAbsent) {
-    return 'Missing required args: "' + name + '"';
-  }
-  if (value == null && !required) {
-    return;
-  }
-  if (type != null) {
-    let isValid = false;
-    const types = isArray(type) ? type : [type];
-    const expectedTypes = [];
-    for (let i2 = 0; i2 < types.length && !isValid; i2++) {
-      const { valid, expectedType } = assertType$1(value, types[i2]);
-      expectedTypes.push(expectedType || "");
-      isValid = valid;
-    }
-    if (!isValid) {
-      return getInvalidTypeMessage$1(name, value, expectedTypes);
-    }
-  }
-  if (validator) {
-    return validator(value);
-  }
-}
-const isSimpleType$1 = /* @__PURE__ */ makeMap("String,Number,Boolean,Function,Symbol");
-function assertType$1(value, type) {
-  let valid;
-  const expectedType = getType$1(type);
-  if (isSimpleType$1(expectedType)) {
-    const t2 = typeof value;
-    valid = t2 === expectedType.toLowerCase();
-    if (!valid && t2 === "object") {
-      valid = value instanceof type;
-    }
-  } else if (expectedType === "Object") {
-    valid = isObject$1(value);
-  } else if (expectedType === "Array") {
-    valid = isArray(value);
-  } else {
-    {
-      valid = value instanceof type;
-    }
-  }
-  return {
-    valid,
-    expectedType
-  };
-}
-function getInvalidTypeMessage$1(name, value, expectedTypes) {
-  let message = `Invalid args: type check failed for args "${name}". Expected ${expectedTypes.map(capitalize).join(", ")}`;
-  const expectedType = expectedTypes[0];
-  const receivedType = toRawType(value);
-  const expectedValue = styleValue$1(value, expectedType);
-  const receivedValue = styleValue$1(value, receivedType);
-  if (expectedTypes.length === 1 && isExplicable$1(expectedType) && !isBoolean$1(expectedType, receivedType)) {
-    message += ` with value ${expectedValue}`;
-  }
-  message += `, got ${receivedType} `;
-  if (isExplicable$1(receivedType)) {
-    message += `with value ${receivedValue}.`;
-  }
-  return message;
-}
-function getType$1(ctor) {
-  const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
-  return match ? match[1] : "";
-}
-function styleValue$1(value, type) {
-  if (type === "String") {
-    return `"${value}"`;
-  } else if (type === "Number") {
-    return `${Number(value)}`;
-  } else {
-    return `${value}`;
-  }
-}
-function isExplicable$1(type) {
-  const explicitTypes = ["string", "number", "boolean"];
-  return explicitTypes.some((elem) => type.toLowerCase() === elem);
-}
-function isBoolean$1(...args) {
-  return args.some((elem) => elem.toLowerCase() === "boolean");
-}
-function tryCatch(fn) {
-  return function() {
-    try {
-      return fn.apply(fn, arguments);
-    } catch (e2) {
-      console.error(e2);
-    }
-  };
-}
-let invokeCallbackId = 1;
-const invokeCallbacks = {};
-function addInvokeCallback(id, name, callback, keepAlive = false) {
-  invokeCallbacks[id] = {
-    name,
-    keepAlive,
-    callback
-  };
-  return id;
-}
-function invokeCallback(id, res, extras) {
-  if (typeof id === "number") {
-    const opts = invokeCallbacks[id];
-    if (opts) {
-      if (!opts.keepAlive) {
-        delete invokeCallbacks[id];
-      }
-      return opts.callback(res, extras);
-    }
-  }
-  return res;
-}
-const API_SUCCESS = "success";
-const API_FAIL = "fail";
-const API_COMPLETE = "complete";
-function getApiCallbacks(args) {
-  const apiCallbacks = {};
-  for (const name in args) {
-    const fn = args[name];
-    if (isFunction(fn)) {
-      apiCallbacks[name] = tryCatch(fn);
-      delete args[name];
-    }
-  }
-  return apiCallbacks;
-}
-function normalizeErrMsg(errMsg, name) {
-  if (!errMsg || errMsg.indexOf(":fail") === -1) {
-    return name + ":ok";
-  }
-  return name + errMsg.substring(errMsg.indexOf(":fail"));
-}
-function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = {}) {
-  if (!isPlainObject(args)) {
-    args = {};
-  }
-  const { success, fail, complete } = getApiCallbacks(args);
-  const hasSuccess = isFunction(success);
-  const hasFail = isFunction(fail);
-  const hasComplete = isFunction(complete);
-  const callbackId = invokeCallbackId++;
-  addInvokeCallback(callbackId, name, (res) => {
-    res = res || {};
-    res.errMsg = normalizeErrMsg(res.errMsg, name);
-    isFunction(beforeAll) && beforeAll(res);
-    if (res.errMsg === name + ":ok") {
-      isFunction(beforeSuccess) && beforeSuccess(res, args);
-      hasSuccess && success(res);
-    } else {
-      hasFail && fail(res);
-    }
-    hasComplete && complete(res);
-  });
-  return callbackId;
-}
-const HOOK_SUCCESS = "success";
-const HOOK_FAIL = "fail";
-const HOOK_COMPLETE = "complete";
-const globalInterceptors = {};
-const scopedInterceptors = {};
-function wrapperHook(hook, params) {
-  return function(data) {
-    return hook(data, params) || data;
-  };
-}
-function queue$2(hooks, data, params) {
-  let promise = false;
-  for (let i2 = 0; i2 < hooks.length; i2++) {
-    const hook = hooks[i2];
-    if (promise) {
-      promise = Promise.resolve(wrapperHook(hook, params));
-    } else {
-      const res = hook(data, params);
-      if (isPromise(res)) {
-        promise = Promise.resolve(res);
-      }
-      if (res === false) {
-        return {
-          then() {
-          },
-          catch() {
-          }
-        };
-      }
-    }
-  }
-  return promise || {
-    then(callback) {
-      return callback(data);
-    },
-    catch() {
-    }
-  };
-}
-function wrapperOptions(interceptors2, options = {}) {
-  [HOOK_SUCCESS, HOOK_FAIL, HOOK_COMPLETE].forEach((name) => {
-    const hooks = interceptors2[name];
-    if (!isArray(hooks)) {
-      return;
-    }
-    const oldCallback = options[name];
-    options[name] = function callbackInterceptor(res) {
-      queue$2(hooks, res, options).then((res2) => {
-        return isFunction(oldCallback) && oldCallback(res2) || res2;
-      });
-    };
-  });
-  return options;
-}
-function wrapperReturnValue(method, returnValue) {
-  const returnValueHooks = [];
-  if (isArray(globalInterceptors.returnValue)) {
-    returnValueHooks.push(...globalInterceptors.returnValue);
-  }
-  const interceptor = scopedInterceptors[method];
-  if (interceptor && isArray(interceptor.returnValue)) {
-    returnValueHooks.push(...interceptor.returnValue);
-  }
-  returnValueHooks.forEach((hook) => {
-    returnValue = hook(returnValue) || returnValue;
-  });
-  return returnValue;
-}
-function getApiInterceptorHooks(method) {
-  const interceptor = /* @__PURE__ */ Object.create(null);
-  Object.keys(globalInterceptors).forEach((hook) => {
-    if (hook !== "returnValue") {
-      interceptor[hook] = globalInterceptors[hook].slice();
-    }
-  });
-  const scopedInterceptor = scopedInterceptors[method];
-  if (scopedInterceptor) {
-    Object.keys(scopedInterceptor).forEach((hook) => {
-      if (hook !== "returnValue") {
-        interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]);
-      }
-    });
-  }
-  return interceptor;
-}
-function invokeApi(method, api, options, params) {
-  const interceptor = getApiInterceptorHooks(method);
-  if (interceptor && Object.keys(interceptor).length) {
-    if (isArray(interceptor.invoke)) {
-      const res = queue$2(interceptor.invoke, options);
-      return res.then((options2) => {
-        return api(wrapperOptions(getApiInterceptorHooks(method), options2), ...params);
-      });
-    } else {
-      return api(wrapperOptions(interceptor, options), ...params);
-    }
-  }
-  return api(options, ...params);
-}
-function hasCallback(args) {
-  if (isPlainObject(args) && [API_SUCCESS, API_FAIL, API_COMPLETE].find((cb) => isFunction(args[cb]))) {
-    return true;
-  }
-  return false;
-}
-function handlePromise(promise) {
-  return promise;
-}
-function promisify$1(name, fn) {
-  return (args = {}, ...rest) => {
-    if (hasCallback(args)) {
-      return wrapperReturnValue(name, invokeApi(name, fn, args, rest));
-    }
-    return wrapperReturnValue(name, handlePromise(new Promise((resolve2, reject) => {
-      invokeApi(name, fn, extend(args, { success: resolve2, fail: reject }), rest);
-    })));
-  };
-}
-function formatApiArgs(args, options) {
-  const params = args[0];
-  if (!options || !options.formatArgs || !isPlainObject(options.formatArgs) && isPlainObject(params)) {
-    return;
-  }
-  const formatArgs = options.formatArgs;
-  const keys = Object.keys(formatArgs);
-  for (let i2 = 0; i2 < keys.length; i2++) {
-    const name = keys[i2];
-    const formatterOrDefaultValue = formatArgs[name];
-    if (isFunction(formatterOrDefaultValue)) {
-      const errMsg = formatterOrDefaultValue(args[0][name], params);
-      if (isString(errMsg)) {
-        return errMsg;
-      }
-    } else {
-      if (!hasOwn$1(params, name)) {
-        params[name] = formatterOrDefaultValue;
-      }
-    }
-  }
-}
-function invokeSuccess(id, name, res) {
-  const result = {
-    errMsg: name + ":ok"
-  };
-  return invokeCallback(id, extend(res || {}, result));
-}
-function invokeFail(id, name, errMsg, errRes = {}) {
-  const apiErrMsg = name + ":fail" + (errMsg ? " " + errMsg : "");
-  delete errRes.errCode;
-  let res = extend({ errMsg: apiErrMsg }, errRes);
-  return invokeCallback(id, res);
-}
-function beforeInvokeApi(name, args, protocol, options) {
-  {
-    validateProtocols(name, args, protocol);
-  }
-  if (options && options.beforeInvoke) {
-    const errMsg2 = options.beforeInvoke(args);
-    if (isString(errMsg2)) {
-      return errMsg2;
-    }
-  }
-  const errMsg = formatApiArgs(args, options);
-  if (errMsg) {
-    return errMsg;
-  }
-}
-function parseErrMsg(errMsg) {
-  if (!errMsg || isString(errMsg)) {
-    return errMsg;
-  }
-  if (errMsg.stack) {
-    console.error(errMsg.message + "\n" + errMsg.stack);
-    return errMsg.message;
-  }
-  return errMsg;
-}
-function wrapperTaskApi(name, fn, protocol, options) {
-  return (args) => {
-    const id = createAsyncApiCallback(name, args, options);
-    const errMsg = beforeInvokeApi(name, [args], protocol, options);
-    if (errMsg) {
-      return invokeFail(id, name, errMsg);
-    }
-    return fn(args, {
-      resolve: (res) => invokeSuccess(id, name, res),
-      reject: (errMsg2, errRes) => invokeFail(id, name, parseErrMsg(errMsg2), errRes)
-    });
-  };
-}
-function wrapperSyncApi(name, fn, protocol, options) {
-  return (...args) => {
-    const errMsg = beforeInvokeApi(name, args, protocol, options);
-    if (errMsg) {
-      throw new Error(errMsg);
-    }
-    return fn.apply(null, args);
-  };
-}
-function wrapperAsyncApi(name, fn, protocol, options) {
-  return wrapperTaskApi(name, fn, protocol, options);
-}
-function defineSyncApi(name, fn, protocol, options) {
-  return wrapperSyncApi(name, fn, protocol, options);
-}
-function defineAsyncApi(name, fn, protocol, options) {
-  return promisify$1(name, wrapperAsyncApi(name, fn, protocol, options));
-}
-const API_UPX2PX = "upx2px";
-const Upx2pxProtocol = [
-  {
-    name: "upx",
-    type: [Number, String],
-    required: true
-  }
-];
-const EPS = 1e-4;
-const BASE_DEVICE_WIDTH = 750;
-let isIOS = false;
-let deviceWidth = 0;
-let deviceDPR = 0;
-function checkDeviceWidth() {
-  const { platform, pixelRatio, windowWidth } = getBaseSystemInfo();
-  deviceWidth = windowWidth;
-  deviceDPR = pixelRatio;
-  isIOS = platform === "ios";
-}
-const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => {
-  if (deviceWidth === 0) {
-    checkDeviceWidth();
-  }
-  number = Number(number);
-  if (number === 0) {
-    return 0;
-  }
-  let width = newDeviceWidth || deviceWidth;
-  let result = number / BASE_DEVICE_WIDTH * width;
-  if (result < 0) {
-    result = -result;
-  }
-  result = Math.floor(result + EPS);
-  if (result === 0) {
-    if (deviceDPR === 1 || !isIOS) {
-      result = 1;
-    } else {
-      result = 0.5;
-    }
-  }
-  return number < 0 ? -result : result;
-}, Upx2pxProtocol);
-const API_ADD_INTERCEPTOR = "addInterceptor";
-const API_REMOVE_INTERCEPTOR = "removeInterceptor";
-const AddInterceptorProtocol = [
-  {
-    name: "method",
-    type: [String, Object],
-    required: true
-  }
-];
-const RemoveInterceptorProtocol = AddInterceptorProtocol;
-function mergeInterceptorHook(interceptors2, interceptor) {
-  Object.keys(interceptor).forEach((hook) => {
-    if (isFunction(interceptor[hook])) {
-      interceptors2[hook] = mergeHook(interceptors2[hook], interceptor[hook]);
-    }
-  });
-}
-function removeInterceptorHook(interceptors2, interceptor) {
-  if (!interceptors2 || !interceptor) {
-    return;
-  }
-  Object.keys(interceptor).forEach((name) => {
-    const hooks = interceptors2[name];
-    const hook = interceptor[name];
-    if (isArray(hooks) && isFunction(hook)) {
-      remove(hooks, hook);
-    }
-  });
-}
-function mergeHook(parentVal, childVal) {
-  const res = childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal;
-  return res ? dedupeHooks(res) : res;
-}
-function dedupeHooks(hooks) {
-  const res = [];
-  for (let i2 = 0; i2 < hooks.length; i2++) {
-    if (res.indexOf(hooks[i2]) === -1) {
-      res.push(hooks[i2]);
-    }
-  }
-  return res;
-}
-const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => {
-  if (isString(method) && isPlainObject(interceptor)) {
-    mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor);
-  } else if (isPlainObject(method)) {
-    mergeInterceptorHook(globalInterceptors, method);
-  }
-}, AddInterceptorProtocol);
-const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => {
-  if (isString(method)) {
-    if (isPlainObject(interceptor)) {
-      removeInterceptorHook(scopedInterceptors[method], interceptor);
-    } else {
-      delete scopedInterceptors[method];
-    }
-  } else if (isPlainObject(method)) {
-    removeInterceptorHook(globalInterceptors, method);
-  }
-}, RemoveInterceptorProtocol);
-const interceptors = {};
-const API_ON = "$on";
-const OnProtocol = [
-  {
-    name: "event",
-    type: String,
-    required: true
-  },
-  {
-    name: "callback",
-    type: Function,
-    required: true
-  }
-];
-const API_ONCE = "$once";
-const OnceProtocol = OnProtocol;
-const API_OFF = "$off";
-const OffProtocol = [
-  {
-    name: "event",
-    type: [String, Array]
-  },
-  {
-    name: "callback",
-    type: Function
-  }
-];
-const API_EMIT = "$emit";
-const EmitProtocol = [
-  {
-    name: "event",
-    type: String,
-    required: true
-  }
-];
-const emitter = new E$1$1();
-const $on = defineSyncApi(API_ON, (name, callback) => {
-  emitter.on(name, callback);
-  return () => emitter.off(name, callback);
-}, OnProtocol);
-const $once = defineSyncApi(API_ONCE, (name, callback) => {
-  emitter.once(name, callback);
-  return () => emitter.off(name, callback);
-}, OnceProtocol);
-const $off = defineSyncApi(API_OFF, (name, callback) => {
-  if (!name) {
-    emitter.e = {};
-    return;
-  }
-  if (!isArray(name))
-    name = [name];
-  name.forEach((n2) => emitter.off(n2, callback));
-}, OffProtocol);
-const $emit = defineSyncApi(API_EMIT, (name, ...args) => {
-  emitter.emit(name, ...args);
-}, EmitProtocol);
-let cid;
-let cidErrMsg;
-let enabled;
-function normalizePushMessage(message) {
-  try {
-    return JSON.parse(message);
-  } catch (e2) {
-  }
-  return message;
-}
-function invokePushCallback(args) {
-  if (args.type === "enabled") {
-    enabled = true;
-  } else if (args.type === "clientId") {
-    cid = args.cid;
-    cidErrMsg = args.errMsg;
-    invokeGetPushCidCallbacks(cid, args.errMsg);
-  } else if (args.type === "pushMsg") {
-    const message = {
-      type: "receive",
-      data: normalizePushMessage(args.message)
-    };
-    for (let i2 = 0; i2 < onPushMessageCallbacks.length; i2++) {
-      const callback = onPushMessageCallbacks[i2];
-      callback(message);
-      if (message.stopped) {
-        break;
-      }
-    }
-  } else if (args.type === "click") {
-    onPushMessageCallbacks.forEach((callback) => {
-      callback({
-        type: "click",
-        data: normalizePushMessage(args.message)
-      });
-    });
-  }
-}
-const getPushCidCallbacks = [];
-function invokeGetPushCidCallbacks(cid2, errMsg) {
-  getPushCidCallbacks.forEach((callback) => {
-    callback(cid2, errMsg);
-  });
-  getPushCidCallbacks.length = 0;
-}
-const API_GET_PUSH_CLIENT_ID = "getPushClientId";
-const getPushClientId = defineAsyncApi(API_GET_PUSH_CLIENT_ID, (_2, { resolve: resolve2, reject }) => {
-  Promise.resolve().then(() => {
-    if (typeof enabled === "undefined") {
-      enabled = false;
-      cid = "";
-      cidErrMsg = "uniPush is not enabled";
-    }
-    getPushCidCallbacks.push((cid2, errMsg) => {
-      if (cid2) {
-        resolve2({ cid: cid2 });
-      } else {
-        reject(errMsg);
-      }
-    });
-    if (typeof cid !== "undefined") {
-      invokeGetPushCidCallbacks(cid, cidErrMsg);
-    }
-  });
-});
-const onPushMessageCallbacks = [];
-const onPushMessage = (fn) => {
-  if (onPushMessageCallbacks.indexOf(fn) === -1) {
-    onPushMessageCallbacks.push(fn);
-  }
-};
-const offPushMessage = (fn) => {
-  if (!fn) {
-    onPushMessageCallbacks.length = 0;
-  } else {
-    const index2 = onPushMessageCallbacks.indexOf(fn);
-    if (index2 > -1) {
-      onPushMessageCallbacks.splice(index2, 1);
-    }
-  }
-};
-const SYNC_API_RE = /^\$|getLocale|setLocale|sendNativeEvent|restoreGlobal|requireGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64|getDeviceInfo|getAppBaseInfo|getWindowInfo|getSystemSetting|getAppAuthorizeSetting/;
-const CONTEXT_API_RE = /^create|Manager$/;
-const CONTEXT_API_RE_EXC = ["createBLEConnection"];
-const ASYNC_API = ["createBLEConnection"];
-const CALLBACK_API_RE = /^on|^off/;
-function isContextApi(name) {
-  return CONTEXT_API_RE.test(name) && CONTEXT_API_RE_EXC.indexOf(name) === -1;
-}
-function isSyncApi(name) {
-  return SYNC_API_RE.test(name) && ASYNC_API.indexOf(name) === -1;
-}
-function isCallbackApi(name) {
-  return CALLBACK_API_RE.test(name) && name !== "onPush";
-}
-function shouldPromise(name) {
-  if (isContextApi(name) || isSyncApi(name) || isCallbackApi(name)) {
-    return false;
-  }
-  return true;
-}
-if (!Promise.prototype.finally) {
-  Promise.prototype.finally = function(onfinally) {
-    const promise = this.constructor;
-    return this.then((value) => promise.resolve(onfinally && onfinally()).then(() => value), (reason) => promise.resolve(onfinally && onfinally()).then(() => {
-      throw reason;
-    }));
-  };
-}
-function promisify(name, api) {
-  if (!shouldPromise(name)) {
-    return api;
-  }
-  if (!isFunction(api)) {
-    return api;
-  }
-  return function promiseApi(options = {}, ...rest) {
-    if (isFunction(options.success) || isFunction(options.fail) || isFunction(options.complete)) {
-      return wrapperReturnValue(name, invokeApi(name, api, options, rest));
-    }
-    return wrapperReturnValue(name, handlePromise(new Promise((resolve2, reject) => {
-      invokeApi(name, api, extend({}, options, {
-        success: resolve2,
-        fail: reject
-      }), rest);
-    })));
-  };
-}
-const CALLBACKS = ["success", "fail", "cancel", "complete"];
-function initWrapper(protocols2) {
-  function processCallback(methodName, method, returnValue) {
-    return function(res) {
-      return method(processReturnValue(methodName, res, returnValue));
-    };
-  }
-  function processArgs(methodName, fromArgs, argsOption = {}, returnValue = {}, keepFromArgs = false) {
-    if (isPlainObject(fromArgs)) {
-      const toArgs = keepFromArgs === true ? fromArgs : {};
-      if (isFunction(argsOption)) {
-        argsOption = argsOption(fromArgs, toArgs) || {};
-      }
-      for (const key in fromArgs) {
-        if (hasOwn$1(argsOption, key)) {
-          let keyOption = argsOption[key];
-          if (isFunction(keyOption)) {
-            keyOption = keyOption(fromArgs[key], fromArgs, toArgs);
-          }
-          if (!keyOption) {
-            console.warn(`微信小程序 ${methodName} 暂不支持 ${key}`);
-          } else if (isString(keyOption)) {
-            toArgs[keyOption] = fromArgs[key];
-          } else if (isPlainObject(keyOption)) {
-            toArgs[keyOption.name ? keyOption.name : key] = keyOption.value;
-          }
-        } else if (CALLBACKS.indexOf(key) !== -1) {
-          const callback = fromArgs[key];
-          if (isFunction(callback)) {
-            toArgs[key] = processCallback(methodName, callback, returnValue);
-          }
-        } else {
-          if (!keepFromArgs && !hasOwn$1(toArgs, key)) {
-            toArgs[key] = fromArgs[key];
-          }
-        }
-      }
-      return toArgs;
-    } else if (isFunction(fromArgs)) {
-      fromArgs = processCallback(methodName, fromArgs, returnValue);
-    }
-    return fromArgs;
-  }
-  function processReturnValue(methodName, res, returnValue, keepReturnValue = false) {
-    if (isFunction(protocols2.returnValue)) {
-      res = protocols2.returnValue(methodName, res);
-    }
-    return processArgs(methodName, res, returnValue, {}, keepReturnValue);
-  }
-  return function wrapper(methodName, method) {
-    if (!hasOwn$1(protocols2, methodName)) {
-      return method;
-    }
-    const protocol = protocols2[methodName];
-    if (!protocol) {
-      return function() {
-        console.error(`微信小程序 暂不支持${methodName}`);
-      };
-    }
-    return function(arg1, arg2) {
-      let options = protocol;
-      if (isFunction(protocol)) {
-        options = protocol(arg1);
-      }
-      arg1 = processArgs(methodName, arg1, options.args, options.returnValue);
-      const args = [arg1];
-      if (typeof arg2 !== "undefined") {
-        args.push(arg2);
-      }
-      const returnValue = wx[options.name || methodName].apply(wx, args);
-      if (isSyncApi(methodName)) {
-        return processReturnValue(methodName, returnValue, options.returnValue, isContextApi(methodName));
-      }
-      return returnValue;
-    };
-  };
-}
-const getLocale = () => {
-  const app = isFunction(getApp) && getApp({ allowDefault: true });
-  if (app && app.$vm) {
-    return app.$vm.$locale;
-  }
-  return normalizeLocale(wx.getSystemInfoSync().language) || LOCALE_EN;
-};
-const setLocale = (locale) => {
-  const app = isFunction(getApp) && getApp();
-  if (!app) {
-    return false;
-  }
-  const oldLocale = app.$vm.$locale;
-  if (oldLocale !== locale) {
-    app.$vm.$locale = locale;
-    onLocaleChangeCallbacks.forEach((fn) => fn({ locale }));
-    return true;
-  }
-  return false;
-};
-const onLocaleChangeCallbacks = [];
-const onLocaleChange = (fn) => {
-  if (onLocaleChangeCallbacks.indexOf(fn) === -1) {
-    onLocaleChangeCallbacks.push(fn);
-  }
-};
-if (typeof global !== "undefined") {
-  global.getLocale = getLocale;
-}
-const UUID_KEY = "__DC_STAT_UUID";
-let deviceId;
-function useDeviceId(global2 = wx) {
-  return function addDeviceId(_2, toRes) {
-    deviceId = deviceId || global2.getStorageSync(UUID_KEY);
-    if (!deviceId) {
-      deviceId = Date.now() + "" + Math.floor(Math.random() * 1e7);
-      wx.setStorage({
-        key: UUID_KEY,
-        data: deviceId
-      });
-    }
-    toRes.deviceId = deviceId;
-  };
-}
-function addSafeAreaInsets(fromRes, toRes) {
-  if (fromRes.safeArea) {
-    const safeArea = fromRes.safeArea;
-    toRes.safeAreaInsets = {
-      top: safeArea.top,
-      left: safeArea.left,
-      right: fromRes.windowWidth - safeArea.right,
-      bottom: fromRes.screenHeight - safeArea.bottom
-    };
-  }
-}
-function populateParameters(fromRes, toRes) {
-  const { brand = "", model = "", system = "", language = "", theme, version: version2, platform, fontSizeSetting, SDKVersion, pixelRatio, deviceOrientation } = fromRes;
-  let osName = "";
-  let osVersion = "";
-  {
-    osName = system.split(" ")[0] || "";
-    osVersion = system.split(" ")[1] || "";
-  }
-  let hostVersion = version2;
-  let deviceType = getGetDeviceType(fromRes, model);
-  let deviceBrand = getDeviceBrand(brand);
-  let _hostName = getHostName(fromRes);
-  let _deviceOrientation = deviceOrientation;
-  let _devicePixelRatio = pixelRatio;
-  let _SDKVersion = SDKVersion;
-  const hostLanguage = language.replace(/_/g, "-");
-  const parameters = {
-    appId: "__UNI__97986D6",
-    appName: "water-drinking-uniapp",
-    appVersion: "1.0.0",
-    appVersionCode: "100",
-    appLanguage: getAppLanguage(hostLanguage),
-    uniCompileVersion: "4.28",
-    uniRuntimeVersion: "4.28",
-    uniPlatform: "mp-weixin",
-    deviceBrand,
-    deviceModel: model,
-    deviceType,
-    devicePixelRatio: _devicePixelRatio,
-    deviceOrientation: _deviceOrientation,
-    osName: osName.toLocaleLowerCase(),
-    osVersion,
-    hostTheme: theme,
-    hostVersion,
-    hostLanguage,
-    hostName: _hostName,
-    hostSDKVersion: _SDKVersion,
-    hostFontSizeSetting: fontSizeSetting,
-    windowTop: 0,
-    windowBottom: 0,
-    // TODO
-    osLanguage: void 0,
-    osTheme: void 0,
-    ua: void 0,
-    hostPackageName: void 0,
-    browserName: void 0,
-    browserVersion: void 0
-  };
-  extend(toRes, parameters);
-}
-function getGetDeviceType(fromRes, model) {
-  let deviceType = fromRes.deviceType || "phone";
-  {
-    const deviceTypeMaps = {
-      ipad: "pad",
-      windows: "pc",
-      mac: "pc"
-    };
-    const deviceTypeMapsKeys = Object.keys(deviceTypeMaps);
-    const _model = model.toLocaleLowerCase();
-    for (let index2 = 0; index2 < deviceTypeMapsKeys.length; index2++) {
-      const _m = deviceTypeMapsKeys[index2];
-      if (_model.indexOf(_m) !== -1) {
-        deviceType = deviceTypeMaps[_m];
-        break;
-      }
-    }
-  }
-  return deviceType;
-}
-function getDeviceBrand(brand) {
-  let deviceBrand = brand;
-  if (deviceBrand) {
-    deviceBrand = deviceBrand.toLocaleLowerCase();
-  }
-  return deviceBrand;
-}
-function getAppLanguage(defaultLanguage) {
-  return getLocale ? getLocale() : defaultLanguage;
-}
-function getHostName(fromRes) {
-  const _platform = "WeChat";
-  let _hostName = fromRes.hostName || _platform;
-  {
-    if (fromRes.environment) {
-      _hostName = fromRes.environment;
-    } else if (fromRes.host && fromRes.host.env) {
-      _hostName = fromRes.host.env;
-    }
-  }
-  return _hostName;
-}
-const getSystemInfo = {
-  returnValue: (fromRes, toRes) => {
-    addSafeAreaInsets(fromRes, toRes);
-    useDeviceId()(fromRes, toRes);
-    populateParameters(fromRes, toRes);
-  }
-};
-const getSystemInfoSync = getSystemInfo;
-const redirectTo = {};
-const previewImage = {
-  args(fromArgs, toArgs) {
-    let currentIndex = parseInt(fromArgs.current);
-    if (isNaN(currentIndex)) {
-      return;
-    }
-    const urls = fromArgs.urls;
-    if (!isArray(urls)) {
-      return;
-    }
-    const len = urls.length;
-    if (!len) {
-      return;
-    }
-    if (currentIndex < 0) {
-      currentIndex = 0;
-    } else if (currentIndex >= len) {
-      currentIndex = len - 1;
-    }
-    if (currentIndex > 0) {
-      toArgs.current = urls[currentIndex];
-      toArgs.urls = urls.filter((item, index2) => index2 < currentIndex ? item !== urls[currentIndex] : true);
-    } else {
-      toArgs.current = urls[0];
-    }
-    return {
-      indicator: false,
-      loop: false
-    };
-  }
-};
-const showActionSheet = {
-  args(fromArgs, toArgs) {
-    toArgs.alertText = fromArgs.title;
-  }
-};
-const getDeviceInfo = {
-  returnValue: (fromRes, toRes) => {
-    const { brand, model } = fromRes;
-    let deviceType = getGetDeviceType(fromRes, model);
-    let deviceBrand = getDeviceBrand(brand);
-    useDeviceId()(fromRes, toRes);
-    toRes = sortObject(extend(toRes, {
-      deviceType,
-      deviceBrand,
-      deviceModel: model
-    }));
-  }
-};
-const getAppBaseInfo = {
-  returnValue: (fromRes, toRes) => {
-    const { version: version2, language, SDKVersion, theme } = fromRes;
-    let _hostName = getHostName(fromRes);
-    let hostLanguage = language.replace(/_/g, "-");
-    toRes = sortObject(extend(toRes, {
-      hostVersion: version2,
-      hostLanguage,
-      hostName: _hostName,
-      hostSDKVersion: SDKVersion,
-      hostTheme: theme,
-      appId: "__UNI__97986D6",
-      appName: "water-drinking-uniapp",
-      appVersion: "1.0.0",
-      appVersionCode: "100",
-      appLanguage: getAppLanguage(hostLanguage)
-    }));
-  }
-};
-const getWindowInfo = {
-  returnValue: (fromRes, toRes) => {
-    addSafeAreaInsets(fromRes, toRes);
-    toRes = sortObject(extend(toRes, {
-      windowTop: 0,
-      windowBottom: 0
-    }));
-  }
-};
-const getAppAuthorizeSetting = {
-  returnValue: function(fromRes, toRes) {
-    const { locationReducedAccuracy } = fromRes;
-    toRes.locationAccuracy = "unsupported";
-    if (locationReducedAccuracy === true) {
-      toRes.locationAccuracy = "reduced";
-    } else if (locationReducedAccuracy === false) {
-      toRes.locationAccuracy = "full";
-    }
-  }
-};
-const baseApis = {
-  $on,
-  $off,
-  $once,
-  $emit,
-  upx2px,
-  interceptors,
-  addInterceptor,
-  removeInterceptor,
-  onCreateVueApp,
-  invokeCreateVueAppHook,
-  getLocale,
-  setLocale,
-  onLocaleChange,
-  getPushClientId,
-  onPushMessage,
-  offPushMessage,
-  invokePushCallback
-};
-function initUni(api, protocols2, platform = wx) {
-  const wrapper = initWrapper(protocols2);
-  const UniProxyHandlers = {
-    get(target, key) {
-      if (hasOwn$1(target, key)) {
-        return target[key];
-      }
-      if (hasOwn$1(api, key)) {
-        return promisify(key, api[key]);
-      }
-      if (hasOwn$1(baseApis, key)) {
-        return promisify(key, baseApis[key]);
-      }
-      return promisify(key, wrapper(key, platform[key]));
-    }
-  };
-  return new Proxy({}, UniProxyHandlers);
-}
-function initGetProvider(providers) {
-  return function getProvider2({ service, success, fail, complete }) {
-    let res;
-    if (providers[service]) {
-      res = {
-        errMsg: "getProvider:ok",
-        service,
-        provider: providers[service]
-      };
-      isFunction(success) && success(res);
-    } else {
-      res = {
-        errMsg: "getProvider:fail:服务[" + service + "]不存在"
-      };
-      isFunction(fail) && fail(res);
-    }
-    isFunction(complete) && complete(res);
-  };
-}
-const objectKeys = [
-  "qy",
-  "env",
-  "error",
-  "version",
-  "lanDebug",
-  "cloud",
-  "serviceMarket",
-  "router",
-  "worklet",
-  "__webpack_require_UNI_MP_PLUGIN__"
-];
-const singlePageDisableKey = ["lanDebug", "router", "worklet"];
-const launchOption = wx.getLaunchOptionsSync ? wx.getLaunchOptionsSync() : null;
-function isWxKey(key) {
-  if (launchOption && launchOption.scene === 1154 && singlePageDisableKey.includes(key)) {
-    return false;
-  }
-  return objectKeys.indexOf(key) > -1 || typeof wx[key] === "function";
-}
-function initWx() {
-  const newWx = {};
-  for (const key in wx) {
-    if (isWxKey(key)) {
-      newWx[key] = wx[key];
-    }
-  }
-  if (typeof globalThis !== "undefined" && typeof requireMiniProgram === "undefined") {
-    globalThis.wx = newWx;
-  }
-  return newWx;
-}
-const mocks$1 = ["__route__", "__wxExparserNodeId__", "__wxWebviewId__"];
-const getProvider = initGetProvider({
-  oauth: ["weixin"],
-  share: ["weixin"],
-  payment: ["wxpay"],
-  push: ["weixin"]
-});
-function initComponentMocks(component) {
-  const res = /* @__PURE__ */ Object.create(null);
-  mocks$1.forEach((name) => {
-    res[name] = component[name];
-  });
-  return res;
-}
-function createSelectorQuery() {
-  const query = wx$2.createSelectorQuery();
-  const oldIn = query.in;
-  query.in = function newIn(component) {
-    return oldIn.call(this, initComponentMocks(component));
-  };
-  return query;
-}
-const wx$2 = initWx();
-let baseInfo = wx$2.getAppBaseInfo && wx$2.getAppBaseInfo();
-if (!baseInfo) {
-  baseInfo = wx$2.getSystemInfoSync();
-}
-const host = baseInfo ? baseInfo.host : null;
-const shareVideoMessage = host && host.env === "SAAASDK" ? wx$2.miniapp.shareVideoMessage : wx$2.shareVideoMessage;
-var shims = /* @__PURE__ */ Object.freeze({
-  __proto__: null,
-  createSelectorQuery,
-  getProvider,
-  shareVideoMessage
-});
-const compressImage = {
-  args(fromArgs, toArgs) {
-    if (fromArgs.compressedHeight && !toArgs.compressHeight) {
-      toArgs.compressHeight = fromArgs.compressedHeight;
-    }
-    if (fromArgs.compressedWidth && !toArgs.compressWidth) {
-      toArgs.compressWidth = fromArgs.compressedWidth;
-    }
-  }
-};
-var protocols = /* @__PURE__ */ Object.freeze({
-  __proto__: null,
-  compressImage,
-  getAppAuthorizeSetting,
-  getAppBaseInfo,
-  getDeviceInfo,
-  getSystemInfo,
-  getSystemInfoSync,
-  getWindowInfo,
-  previewImage,
-  redirectTo,
-  showActionSheet
-});
-const wx$1 = initWx();
-var index = initUni(shims, protocols, wx$1);
-new Set(
-  /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol)
-);
-function toRaw$1(observed) {
-  const raw = observed && observed["__v_raw"];
-  return raw ? toRaw$1(raw) : observed;
-}
-function isRef$1(r2) {
-  return !!(r2 && r2.__v_isRef === true);
-}
-/**
-* @vue/runtime-core v3.4.21
-* (c) 2018-present Yuxi (Evan) You and Vue contributors
-* @license MIT
-**/
-const stack$1 = [];
-function pushWarningContext$1(vnode) {
-  stack$1.push(vnode);
-}
-function popWarningContext$1() {
-  stack$1.pop();
-}
-function warn$1$1(msg, ...args) {
-  const instance = stack$1.length ? stack$1[stack$1.length - 1].component : null;
-  const appWarnHandler = instance && instance.appContext.config.warnHandler;
-  const trace = getComponentTrace$1();
-  if (appWarnHandler) {
-    callWithErrorHandling$1(
-      appWarnHandler,
-      instance,
-      11,
-      [
-        msg + args.map((a2) => {
-          var _a, _b;
-          return (_b = (_a = a2.toString) == null ? void 0 : _a.call(a2)) != null ? _b : JSON.stringify(a2);
-        }).join(""),
-        instance && instance.proxy,
-        trace.map(
-          ({ vnode }) => `at <${formatComponentName$1(instance, vnode.type)}>`
-        ).join("\n"),
-        trace
-      ]
-    );
-  } else {
-    const warnArgs = [`[Vue warn]: ${msg}`, ...args];
-    if (trace.length && // avoid spamming console during tests
-    true) {
-      warnArgs.push(`
-`, ...formatTrace$1(trace));
-    }
-    console.warn(...warnArgs);
-  }
-}
-function getComponentTrace$1() {
-  let currentVNode = stack$1[stack$1.length - 1];
-  if (!currentVNode) {
-    return [];
-  }
-  const normalizedStack = [];
-  while (currentVNode) {
-    const last = normalizedStack[0];
-    if (last && last.vnode === currentVNode) {
-      last.recurseCount++;
-    } else {
-      normalizedStack.push({
-        vnode: currentVNode,
-        recurseCount: 0
-      });
-    }
-    const parentInstance = currentVNode.component && currentVNode.component.parent;
-    currentVNode = parentInstance && parentInstance.vnode;
-  }
-  return normalizedStack;
-}
-function formatTrace$1(trace) {
-  const logs = [];
-  trace.forEach((entry, i2) => {
-    logs.push(...i2 === 0 ? [] : [`
-`], ...formatTraceEntry$1(entry));
-  });
-  return logs;
-}
-function formatTraceEntry$1({ vnode, recurseCount }) {
-  const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
-  const isRoot = vnode.component ? vnode.component.parent == null : false;
-  const open = ` at <${formatComponentName$1(
-    vnode.component,
-    vnode.type,
-    isRoot
-  )}`;
-  const close = `>` + postfix;
-  return vnode.props ? [open, ...formatProps$1(vnode.props), close] : [open + close];
-}
-function formatProps$1(props) {
-  const res = [];
-  const keys = Object.keys(props);
-  keys.slice(0, 3).forEach((key) => {
-    res.push(...formatProp$1(key, props[key]));
-  });
-  if (keys.length > 3) {
-    res.push(` ...`);
-  }
-  return res;
-}
-function formatProp$1(key, value, raw) {
-  if (isString(value)) {
-    value = JSON.stringify(value);
-    return raw ? value : [`${key}=${value}`];
-  } else if (typeof value === "number" || typeof value === "boolean" || value == null) {
-    return raw ? value : [`${key}=${value}`];
-  } else if (isRef$1(value)) {
-    value = formatProp$1(key, toRaw$1(value.value), true);
-    return raw ? value : [`${key}=Ref<`, value, `>`];
-  } else if (isFunction(value)) {
-    return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
-  } else {
-    value = toRaw$1(value);
-    return raw ? value : [`${key}=`, value];
-  }
-}
-const ErrorTypeStrings$1 = {
-  ["sp"]: "serverPrefetch hook",
-  ["bc"]: "beforeCreate hook",
-  ["c"]: "created hook",
-  ["bm"]: "beforeMount hook",
-  ["m"]: "mounted hook",
-  ["bu"]: "beforeUpdate hook",
-  ["u"]: "updated",
-  ["bum"]: "beforeUnmount hook",
-  ["um"]: "unmounted hook",
-  ["a"]: "activated hook",
-  ["da"]: "deactivated hook",
-  ["ec"]: "errorCaptured hook",
-  ["rtc"]: "renderTracked hook",
-  ["rtg"]: "renderTriggered hook",
-  [0]: "setup function",
-  [1]: "render function",
-  [2]: "watcher getter",
-  [3]: "watcher callback",
-  [4]: "watcher cleanup function",
-  [5]: "native event handler",
-  [6]: "component event handler",
-  [7]: "vnode hook",
-  [8]: "directive hook",
-  [9]: "transition hook",
-  [10]: "app errorHandler",
-  [11]: "app warnHandler",
-  [12]: "ref function",
-  [13]: "async component loader",
-  [14]: "scheduler flush. This is likely a Vue internals bug. Please open an issue at https://github.com/vuejs/core ."
-};
-function callWithErrorHandling$1(fn, instance, type, args) {
-  try {
-    return args ? fn(...args) : fn();
-  } catch (err) {
-    handleError$1(err, instance, type);
-  }
-}
-function handleError$1(err, instance, type, throwInDev = true) {
-  const contextVNode = instance ? instance.vnode : null;
-  if (instance) {
-    let cur = instance.parent;
-    const exposedInstance = instance.proxy;
-    const errorInfo = ErrorTypeStrings$1[type];
-    while (cur) {
-      const errorCapturedHooks = cur.ec;
-      if (errorCapturedHooks) {
-        for (let i2 = 0; i2 < errorCapturedHooks.length; i2++) {
-          if (errorCapturedHooks[i2](err, exposedInstance, errorInfo) === false) {
-            return;
-          }
-        }
-      }
-      cur = cur.parent;
-    }
-    const appErrorHandler = instance.appContext.config.errorHandler;
-    if (appErrorHandler) {
-      callWithErrorHandling$1(
-        appErrorHandler,
-        null,
-        10,
-        [err, exposedInstance, errorInfo]
-      );
-      return;
-    }
-  }
-  logError$1(err, type, contextVNode, throwInDev);
-}
-function logError$1(err, type, contextVNode, throwInDev = true) {
-  {
-    const info = ErrorTypeStrings$1[type];
-    if (contextVNode) {
-      pushWarningContext$1(contextVNode);
-    }
-    warn$1$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
-    if (contextVNode) {
-      popWarningContext$1();
-    }
-    if (throwInDev) {
-      throw err;
-    } else {
-      console.error(err);
-    }
-  }
-}
-let isFlushing$1 = false;
-let isFlushPending$1 = false;
-const queue$1 = [];
-let flushIndex$1 = 0;
-const pendingPostFlushCbs$1 = [];
-let activePostFlushCbs$1 = null;
-let postFlushIndex$1 = 0;
-const resolvedPromise$1 = /* @__PURE__ */ Promise.resolve();
-const RECURSION_LIMIT$1 = 100;
-function findInsertionIndex$1(id) {
-  let start = flushIndex$1 + 1;
-  let end = queue$1.length;
-  while (start < end) {
-    const middle = start + end >>> 1;
-    const middleJob = queue$1[middle];
-    const middleJobId = getId$1(middleJob);
-    if (middleJobId < id || middleJobId === id && middleJob.pre) {
-      start = middle + 1;
-    } else {
-      end = middle;
-    }
-  }
-  return start;
-}
-function queueJob$1(job) {
-  if (!queue$1.length || !queue$1.includes(
-    job,
-    isFlushing$1 && job.allowRecurse ? flushIndex$1 + 1 : flushIndex$1
-  )) {
-    if (job.id == null) {
-      queue$1.push(job);
-    } else {
-      queue$1.splice(findInsertionIndex$1(job.id), 0, job);
-    }
-    queueFlush$1();
-  }
-}
-function queueFlush$1() {
-  if (!isFlushing$1 && !isFlushPending$1) {
-    isFlushPending$1 = true;
-    resolvedPromise$1.then(flushJobs$1);
-  }
-}
-function queuePostFlushCb$1(cb) {
-  if (!isArray(cb)) {
-    if (!activePostFlushCbs$1 || !activePostFlushCbs$1.includes(
-      cb,
-      cb.allowRecurse ? postFlushIndex$1 + 1 : postFlushIndex$1
-    )) {
-      pendingPostFlushCbs$1.push(cb);
-    }
-  } else {
-    pendingPostFlushCbs$1.push(...cb);
-  }
-  queueFlush$1();
-}
-function flushPostFlushCbs$1(seen) {
-  if (pendingPostFlushCbs$1.length) {
-    const deduped = [...new Set(pendingPostFlushCbs$1)].sort(
-      (a2, b2) => getId$1(a2) - getId$1(b2)
-    );
-    pendingPostFlushCbs$1.length = 0;
-    if (activePostFlushCbs$1) {
-      activePostFlushCbs$1.push(...deduped);
-      return;
-    }
-    activePostFlushCbs$1 = deduped;
-    {
-      seen = seen || /* @__PURE__ */ new Map();
-    }
-    for (postFlushIndex$1 = 0; postFlushIndex$1 < activePostFlushCbs$1.length; postFlushIndex$1++) {
-      if (checkRecursiveUpdates$1(seen, activePostFlushCbs$1[postFlushIndex$1])) {
-        continue;
-      }
-      activePostFlushCbs$1[postFlushIndex$1]();
-    }
-    activePostFlushCbs$1 = null;
-    postFlushIndex$1 = 0;
-  }
-}
-const getId$1 = (job) => job.id == null ? Infinity : job.id;
-const comparator$1 = (a2, b2) => {
-  const diff2 = getId$1(a2) - getId$1(b2);
-  if (diff2 === 0) {
-    if (a2.pre && !b2.pre)
-      return -1;
-    if (b2.pre && !a2.pre)
-      return 1;
-  }
-  return diff2;
-};
-function flushJobs$1(seen) {
-  isFlushPending$1 = false;
-  isFlushing$1 = true;
-  {
-    seen = seen || /* @__PURE__ */ new Map();
-  }
-  queue$1.sort(comparator$1);
-  const check = (job) => checkRecursiveUpdates$1(seen, job);
-  try {
-    for (flushIndex$1 = 0; flushIndex$1 < queue$1.length; flushIndex$1++) {
-      const job = queue$1[flushIndex$1];
-      if (job && job.active !== false) {
-        if (check(job)) {
-          continue;
-        }
-        callWithErrorHandling$1(job, null, 14);
-      }
-    }
-  } finally {
-    flushIndex$1 = 0;
-    queue$1.length = 0;
-    flushPostFlushCbs$1(seen);
-    isFlushing$1 = false;
-    if (queue$1.length || pendingPostFlushCbs$1.length) {
-      flushJobs$1(seen);
-    }
-  }
-}
-function checkRecursiveUpdates$1(seen, fn) {
-  if (!seen.has(fn)) {
-    seen.set(fn, 1);
-  } else {
-    const count = seen.get(fn);
-    if (count > RECURSION_LIMIT$1) {
-      const instance = fn.ownerInstance;
-      const componentName = instance && getComponentName$1(instance.type);
-      handleError$1(
-        `Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.`,
-        null,
-        10
-      );
-      return true;
-    } else {
-      seen.set(fn, count + 1);
-    }
-  }
-}
-const hmrDirtyComponents = /* @__PURE__ */ new Set();
-{
-  getGlobalThis().__VUE_HMR_RUNTIME__ = {
-    createRecord: tryWrap(createRecord),
-    rerender: tryWrap(rerender),
-    reload: tryWrap(reload)
-  };
-}
-const map = /* @__PURE__ */ new Map();
-function createRecord(id, initialDef) {
-  if (map.has(id)) {
-    return false;
-  }
-  map.set(id, {
-    initialDef: normalizeClassComponent(initialDef),
-    instances: /* @__PURE__ */ new Set()
-  });
-  return true;
-}
-function normalizeClassComponent(component) {
-  return isClassComponent$1(component) ? component.__vccOpts : component;
-}
-function rerender(id, newRender) {
-  const record = map.get(id);
-  if (!record) {
-    return;
-  }
-  record.initialDef.render = newRender;
-  [...record.instances].forEach((instance) => {
-    if (newRender) {
-      instance.render = newRender;
-      normalizeClassComponent(instance.type).render = newRender;
-    }
-    instance.renderCache = [];
-    instance.effect.dirty = true;
-    instance.update();
-  });
-}
-function reload(id, newComp) {
-  const record = map.get(id);
-  if (!record)
-    return;
-  newComp = normalizeClassComponent(newComp);
-  updateComponentDef(record.initialDef, newComp);
-  const instances = [...record.instances];
-  for (const instance of instances) {
-    const oldComp = normalizeClassComponent(instance.type);
-    if (!hmrDirtyComponents.has(oldComp)) {
-      if (oldComp !== record.initialDef) {
-        updateComponentDef(oldComp, newComp);
-      }
-      hmrDirtyComponents.add(oldComp);
-    }
-    instance.appContext.propsCache.delete(instance.type);
-    instance.appContext.emitsCache.delete(instance.type);
-    instance.appContext.optionsCache.delete(instance.type);
-    if (instance.ceReload) {
-      hmrDirtyComponents.add(oldComp);
-      instance.ceReload(newComp.styles);
-      hmrDirtyComponents.delete(oldComp);
-    } else if (instance.parent) {
-      instance.parent.effect.dirty = true;
-      queueJob$1(instance.parent.update);
-    } else if (instance.appContext.reload) {
-      instance.appContext.reload();
-    } else if (typeof window !== "undefined") {
-      window.location.reload();
-    } else {
-      console.warn(
-        "[HMR] Root or manually mounted instance modified. Full reload required."
-      );
-    }
-  }
-  queuePostFlushCb$1(() => {
-    for (const instance of instances) {
-      hmrDirtyComponents.delete(
-        normalizeClassComponent(instance.type)
-      );
-    }
-  });
-}
-function updateComponentDef(oldComp, newComp) {
-  extend(oldComp, newComp);
-  for (const key in oldComp) {
-    if (key !== "__file" && !(key in newComp)) {
-      delete oldComp[key];
-    }
-  }
-}
-function tryWrap(fn) {
-  return (id, arg) => {
-    try {
-      return fn(id, arg);
-    } catch (e2) {
-      console.error(e2);
-      console.warn(
-        `[HMR] Something went wrong during Vue component hot-reload. Full reload required.`
-      );
-    }
-  };
-}
-{
-  const g2 = getGlobalThis();
-  const registerGlobalSetter = (key, setter) => {
-    let setters;
-    if (!(setters = g2[key]))
-      setters = g2[key] = [];
-    setters.push(setter);
-    return (v2) => {
-      if (setters.length > 1)
-        setters.forEach((set2) => set2(v2));
-      else
-        setters[0](v2);
-    };
-  };
-  registerGlobalSetter(
-    `__VUE_INSTANCE_SETTERS__`,
-    (v2) => v2
-  );
-  registerGlobalSetter(
-    `__VUE_SSR_SETTERS__`,
-    (v2) => v2
-  );
-}
-const classifyRE$1 = /(?:^|[-_])(\w)/g;
-const classify$1 = (str) => str.replace(classifyRE$1, (c2) => c2.toUpperCase()).replace(/[-_]/g, "");
-function getComponentName$1(Component2, includeInferred = true) {
-  return isFunction(Component2) ? Component2.displayName || Component2.name : Component2.name || includeInferred && Component2.__name;
-}
-function formatComponentName$1(instance, Component2, isRoot = false) {
-  let name = getComponentName$1(Component2);
-  if (!name && Component2.__file) {
-    const match = Component2.__file.match(/([^/\\]+)\.\w+$/);
-    if (match) {
-      name = match[1];
-    }
-  }
-  if (!name && instance && instance.parent) {
-    const inferFromRegistry = (registry) => {
-      for (const key in registry) {
-        if (registry[key] === Component2) {
-          return key;
-        }
-      }
-    };
-    name = inferFromRegistry(
-      instance.components || instance.parent.type.components
-    ) || inferFromRegistry(instance.appContext.components);
-  }
-  return name ? classify$1(name) : isRoot ? `App` : `Anonymous`;
-}
-function isClassComponent$1(value) {
-  return isFunction(value) && "__vccOpts" in value;
-}
-/**
-* @dcloudio/uni-mp-vue v3.4.21
-* (c) 2018-present Yuxi (Evan) You and Vue contributors
-* @license MIT
-**/
-function warn$2(msg, ...args) {
-  console.warn(`[Vue warn] ${msg}`, ...args);
-}
-let activeEffectScope;
-class EffectScope {
-  constructor(detached = false) {
-    this.detached = detached;
-    this._active = true;
-    this.effects = [];
-    this.cleanups = [];
-    this.parent = activeEffectScope;
-    if (!detached && activeEffectScope) {
-      this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(
-        this
-      ) - 1;
-    }
-  }
-  get active() {
-    return this._active;
-  }
-  run(fn) {
-    if (this._active) {
-      const currentEffectScope = activeEffectScope;
-      try {
-        activeEffectScope = this;
-        return fn();
-      } finally {
-        activeEffectScope = currentEffectScope;
-      }
-    } else {
-      warn$2(`cannot run an inactive effect scope.`);
-    }
-  }
-  /**
-   * This should only be called on non-detached scopes
-   * @internal
-   */
-  on() {
-    activeEffectScope = this;
-  }
-  /**
-   * This should only be called on non-detached scopes
-   * @internal
-   */
-  off() {
-    activeEffectScope = this.parent;
-  }
-  stop(fromParent) {
-    if (this._active) {
-      let i2, l2;
-      for (i2 = 0, l2 = this.effects.length; i2 < l2; i2++) {
-        this.effects[i2].stop();
-      }
-      for (i2 = 0, l2 = this.cleanups.length; i2 < l2; i2++) {
-        this.cleanups[i2]();
-      }
-      if (this.scopes) {
-        for (i2 = 0, l2 = this.scopes.length; i2 < l2; i2++) {
-          this.scopes[i2].stop(true);
-        }
-      }
-      if (!this.detached && this.parent && !fromParent) {
-        const last = this.parent.scopes.pop();
-        if (last && last !== this) {
-          this.parent.scopes[this.index] = last;
-          last.index = this.index;
-        }
-      }
-      this.parent = void 0;
-      this._active = false;
-    }
-  }
-}
-function recordEffectScope(effect2, scope = activeEffectScope) {
-  if (scope && scope.active) {
-    scope.effects.push(effect2);
-  }
-}
-function getCurrentScope() {
-  return activeEffectScope;
-}
-let activeEffect;
-class ReactiveEffect2 {
-  constructor(fn, trigger2, scheduler, scope) {
-    this.fn = fn;
-    this.trigger = trigger2;
-    this.scheduler = scheduler;
-    this.active = true;
-    this.deps = [];
-    this._dirtyLevel = 4;
-    this._trackId = 0;
-    this._runnings = 0;
-    this._shouldSchedule = false;
-    this._depsLength = 0;
-    recordEffectScope(this, scope);
-  }
-  get dirty() {
-    if (this._dirtyLevel === 2 || this._dirtyLevel === 3) {
-      this._dirtyLevel = 1;
-      pauseTracking();
-      for (let i2 = 0; i2 < this._depsLength; i2++) {
-        const dep = this.deps[i2];
-        if (dep.computed) {
-          triggerComputed(dep.computed);
-          if (this._dirtyLevel >= 4) {
-            break;
-          }
-        }
-      }
-      if (this._dirtyLevel === 1) {
-        this._dirtyLevel = 0;
-      }
-      resetTracking();
-    }
-    return this._dirtyLevel >= 4;
-  }
-  set dirty(v2) {
-    this._dirtyLevel = v2 ? 4 : 0;
-  }
-  run() {
-    this._dirtyLevel = 0;
-    if (!this.active) {
-      return this.fn();
-    }
-    let lastShouldTrack = shouldTrack;
-    let lastEffect = activeEffect;
-    try {
-      shouldTrack = true;
-      activeEffect = this;
-      this._runnings++;
-      preCleanupEffect(this);
-      return this.fn();
-    } finally {
-      postCleanupEffect(this);
-      this._runnings--;
-      activeEffect = lastEffect;
-      shouldTrack = lastShouldTrack;
-    }
-  }
-  stop() {
-    var _a;
-    if (this.active) {
-      preCleanupEffect(this);
-      postCleanupEffect(this);
-      (_a = this.onStop) == null ? void 0 : _a.call(this);
-      this.active = false;
-    }
-  }
-}
-function triggerComputed(computed2) {
-  return computed2.value;
-}
-function preCleanupEffect(effect2) {
-  effect2._trackId++;
-  effect2._depsLength = 0;
-}
-function postCleanupEffect(effect2) {
-  if (effect2.deps.length > effect2._depsLength) {
-    for (let i2 = effect2._depsLength; i2 < effect2.deps.length; i2++) {
-      cleanupDepEffect(effect2.deps[i2], effect2);
-    }
-    effect2.deps.length = effect2._depsLength;
-  }
-}
-function cleanupDepEffect(dep, effect2) {
-  const trackId = dep.get(effect2);
-  if (trackId !== void 0 && effect2._trackId !== trackId) {
-    dep.delete(effect2);
-    if (dep.size === 0) {
-      dep.cleanup();
-    }
-  }
-}
-let shouldTrack = true;
-let pauseScheduleStack = 0;
-const trackStack = [];
-function pauseTracking() {
-  trackStack.push(shouldTrack);
-  shouldTrack = false;
-}
-function resetTracking() {
-  const last = trackStack.pop();
-  shouldTrack = last === void 0 ? true : last;
-}
-function pauseScheduling() {
-  pauseScheduleStack++;
-}
-function resetScheduling() {
-  pauseScheduleStack--;
-  while (!pauseScheduleStack && queueEffectSchedulers.length) {
-    queueEffectSchedulers.shift()();
-  }
-}
-function trackEffect(effect2, dep, debuggerEventExtraInfo) {
-  var _a;
-  if (dep.get(effect2) !== effect2._trackId) {
-    dep.set(effect2, effect2._trackId);
-    const oldDep = effect2.deps[effect2._depsLength];
-    if (oldDep !== dep) {
-      if (oldDep) {
-        cleanupDepEffect(oldDep, effect2);
-      }
-      effect2.deps[effect2._depsLength++] = dep;
-    } else {
-      effect2._depsLength++;
-    }
-    {
-      (_a = effect2.onTrack) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
-    }
-  }
-}
-const queueEffectSchedulers = [];
-function triggerEffects(dep, dirtyLevel, debuggerEventExtraInfo) {
-  var _a;
-  pauseScheduling();
-  for (const effect2 of dep.keys()) {
-    let tracking;
-    if (effect2._dirtyLevel < dirtyLevel && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
-      effect2._shouldSchedule || (effect2._shouldSchedule = effect2._dirtyLevel === 0);
-      effect2._dirtyLevel = dirtyLevel;
-    }
-    if (effect2._shouldSchedule && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
-      {
-        (_a = effect2.onTrigger) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
-      }
-      effect2.trigger();
-      if ((!effect2._runnings || effect2.allowRecurse) && effect2._dirtyLevel !== 2) {
-        effect2._shouldSchedule = false;
-        if (effect2.scheduler) {
-          queueEffectSchedulers.push(effect2.scheduler);
-        }
-      }
-    }
-  }
-  resetScheduling();
-}
-const createDep = (cleanup, computed2) => {
-  const dep = /* @__PURE__ */ new Map();
-  dep.cleanup = cleanup;
-  dep.computed = computed2;
-  return dep;
-};
-const targetMap = /* @__PURE__ */ new WeakMap();
-const ITERATE_KEY = Symbol("iterate");
-const MAP_KEY_ITERATE_KEY = Symbol("Map key iterate");
-function track(target, type, key) {
-  if (shouldTrack && activeEffect) {
-    let depsMap = targetMap.get(target);
-    if (!depsMap) {
-      targetMap.set(target, depsMap = /* @__PURE__ */ new Map());
-    }
-    let dep = depsMap.get(key);
-    if (!dep) {
-      depsMap.set(key, dep = createDep(() => depsMap.delete(key)));
-    }
-    trackEffect(
-      activeEffect,
-      dep,
-      {
-        target,
-        type,
-        key
-      }
-    );
-  }
-}
-function trigger(target, type, key, newValue, oldValue, oldTarget) {
-  const depsMap = targetMap.get(target);
-  if (!depsMap) {
-    return;
-  }
-  let deps = [];
-  if (type === "clear") {
-    deps = [...depsMap.values()];
-  } else if (key === "length" && isArray(target)) {
-    const newLength = Number(newValue);
-    depsMap.forEach((dep, key2) => {
-      if (key2 === "length" || !isSymbol(key2) && key2 >= newLength) {
-        deps.push(dep);
-      }
-    });
-  } else {
-    if (key !== void 0) {
-      deps.push(depsMap.get(key));
-    }
-    switch (type) {
-      case "add":
-        if (!isArray(target)) {
-          deps.push(depsMap.get(ITERATE_KEY));
-          if (isMap(target)) {
-            deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
-          }
-        } else if (isIntegerKey(key)) {
-          deps.push(depsMap.get("length"));
-        }
-        break;
-      case "delete":
-        if (!isArray(target)) {
-          deps.push(depsMap.get(ITERATE_KEY));
-          if (isMap(target)) {
-            deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
-          }
-        }
-        break;
-      case "set":
-        if (isMap(target)) {
-          deps.push(depsMap.get(ITERATE_KEY));
-        }
-        break;
-    }
-  }
-  pauseScheduling();
-  for (const dep of deps) {
-    if (dep) {
-      triggerEffects(
-        dep,
-        4,
-        {
-          target,
-          type,
-          key,
-          newValue,
-          oldValue,
-          oldTarget
-        }
-      );
-    }
-  }
-  resetScheduling();
-}
-const isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);
-const builtInSymbols = new Set(
-  /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol)
-);
-const arrayInstrumentations = /* @__PURE__ */ createArrayInstrumentations();
-function createArrayInstrumentations() {
-  const instrumentations = {};
-  ["includes", "indexOf", "lastIndexOf"].forEach((key) => {
-    instrumentations[key] = function(...args) {
-      const arr = toRaw(this);
-      for (let i2 = 0, l2 = this.length; i2 < l2; i2++) {
-        track(arr, "get", i2 + "");
-      }
-      const res = arr[key](...args);
-      if (res === -1 || res === false) {
-        return arr[key](...args.map(toRaw));
-      } else {
-        return res;
-      }
-    };
-  });
-  ["push", "pop", "shift", "unshift", "splice"].forEach((key) => {
-    instrumentations[key] = function(...args) {
-      pauseTracking();
-      pauseScheduling();
-      const res = toRaw(this)[key].apply(this, args);
-      resetScheduling();
-      resetTracking();
-      return res;
-    };
-  });
-  return instrumentations;
-}
-function hasOwnProperty(key) {
-  const obj = toRaw(this);
-  track(obj, "has", key);
-  return obj.hasOwnProperty(key);
-}
-class BaseReactiveHandler2 {
-  constructor(_isReadonly = false, _isShallow = false) {
-    this._isReadonly = _isReadonly;
-    this._isShallow = _isShallow;
-  }
-  get(target, key, receiver) {
-    const isReadonly2 = this._isReadonly, isShallow2 = this._isShallow;
-    if (key === "__v_isReactive") {
-      return !isReadonly2;
-    } else if (key === "__v_isReadonly") {
-      return isReadonly2;
-    } else if (key === "__v_isShallow") {
-      return isShallow2;
-    } else if (key === "__v_raw") {
-      if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || // receiver is not the reactive proxy, but has the same prototype
-      // this means the reciever is a user proxy of the reactive proxy
-      Object.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) {
-        return target;
-      }
-      return;
-    }
-    const targetIsArray = isArray(target);
-    if (!isReadonly2) {
-      if (targetIsArray && hasOwn$1(arrayInstrumentations, key)) {
-        return Reflect.get(arrayInstrumentations, key, receiver);
-      }
-      if (key === "hasOwnProperty") {
-        return hasOwnProperty;
-      }
-    }
-    const res = Reflect.get(target, key, receiver);
-    if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
-      return res;
-    }
-    if (!isReadonly2) {
-      track(target, "get", key);
-    }
-    if (isShallow2) {
-      return res;
-    }
-    if (isRef(res)) {
-      return targetIsArray && isIntegerKey(key) ? res : res.value;
-    }
-    if (isObject$1(res)) {
-      return isReadonly2 ? readonly(res) : reactive(res);
-    }
-    return res;
-  }
-}
-class MutableReactiveHandler2 extends BaseReactiveHandler2 {
-  constructor(isShallow2 = false) {
-    super(false, isShallow2);
-  }
-  set(target, key, value, receiver) {
-    let oldValue = target[key];
-    if (!this._isShallow) {
-      const isOldValueReadonly = isReadonly(oldValue);
-      if (!isShallow(value) && !isReadonly(value)) {
-        oldValue = toRaw(oldValue);
-        value = toRaw(value);
-      }
-      if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
-        if (isOldValueReadonly) {
-          return false;
-        } else {
-          oldValue.value = value;
-          return true;
-        }
-      }
-    }
-    const hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn$1(target, key);
-    const result = Reflect.set(target, key, value, receiver);
-    if (target === toRaw(receiver)) {
-      if (!hadKey) {
-        trigger(target, "add", key, value);
-      } else if (hasChanged(value, oldValue)) {
-        trigger(target, "set", key, value, oldValue);
-      }
-    }
-    return result;
-  }
-  deleteProperty(target, key) {
-    const hadKey = hasOwn$1(target, key);
-    const oldValue = target[key];
-    const result = Reflect.deleteProperty(target, key);
-    if (result && hadKey) {
-      trigger(target, "delete", key, void 0, oldValue);
-    }
-    return result;
-  }
-  has(target, key) {
-    const result = Reflect.has(target, key);
-    if (!isSymbol(key) || !builtInSymbols.has(key)) {
-      track(target, "has", key);
-    }
-    return result;
-  }
-  ownKeys(target) {
-    track(
-      target,
-      "iterate",
-      isArray(target) ? "length" : ITERATE_KEY
-    );
-    return Reflect.ownKeys(target);
-  }
-}
-class ReadonlyReactiveHandler2 extends BaseReactiveHandler2 {
-  constructor(isShallow2 = false) {
-    super(true, isShallow2);
-  }
-  set(target, key) {
-    {
-      warn$2(
-        `Set operation on key "${String(key)}" failed: target is readonly.`,
-        target
-      );
-    }
-    return true;
-  }
-  deleteProperty(target, key) {
-    {
-      warn$2(
-        `Delete operation on key "${String(key)}" failed: target is readonly.`,
-        target
-      );
-    }
-    return true;
-  }
-}
-const mutableHandlers = /* @__PURE__ */ new MutableReactiveHandler2();
-const readonlyHandlers = /* @__PURE__ */ new ReadonlyReactiveHandler2();
-const shallowReactiveHandlers = /* @__PURE__ */ new MutableReactiveHandler2(
-  true
-);
-const shallowReadonlyHandlers = /* @__PURE__ */ new ReadonlyReactiveHandler2(true);
-const toShallow = (value) => value;
-const getProto = (v2) => Reflect.getPrototypeOf(v2);
-function get(target, key, isReadonly2 = false, isShallow2 = false) {
-  target = target["__v_raw"];
-  const rawTarget = toRaw(target);
-  const rawKey = toRaw(key);
-  if (!isReadonly2) {
-    if (hasChanged(key, rawKey)) {
-      track(rawTarget, "get", key);
-    }
-    track(rawTarget, "get", rawKey);
-  }
-  const { has: has2 } = getProto(rawTarget);
-  const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive;
-  if (has2.call(rawTarget, key)) {
-    return wrap(target.get(key));
-  } else if (has2.call(rawTarget, rawKey)) {
-    return wrap(target.get(rawKey));
-  } else if (target !== rawTarget) {
-    target.get(key);
-  }
-}
-function has(key, isReadonly2 = false) {
-  const target = this["__v_raw"];
-  const rawTarget = toRaw(target);
-  const rawKey = toRaw(key);
-  if (!isReadonly2) {
-    if (hasChanged(key, rawKey)) {
-      track(rawTarget, "has", key);
-    }
-    track(rawTarget, "has", rawKey);
-  }
-  return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey);
-}
-function size(target, isReadonly2 = false) {
-  target = target["__v_raw"];
-  !isReadonly2 && track(toRaw(target), "iterate", ITERATE_KEY);
-  return Reflect.get(target, "size", target);
-}
-function add(value) {
-  value = toRaw(value);
-  const target = toRaw(this);
-  const proto = getProto(target);
-  const hadKey = proto.has.call(target, value);
-  if (!hadKey) {
-    target.add(value);
-    trigger(target, "add", value, value);
-  }
-  return this;
-}
-function set$1(key, value) {
-  value = toRaw(value);
-  const target = toRaw(this);
-  const { has: has2, get: get2 } = getProto(target);
-  let hadKey = has2.call(target, key);
-  if (!hadKey) {
-    key = toRaw(key);
-    hadKey = has2.call(target, key);
-  } else {
-    checkIdentityKeys(target, has2, key);
-  }
-  const oldValue = get2.call(target, key);
-  target.set(key, value);
-  if (!hadKey) {
-    trigger(target, "add", key, value);
-  } else if (hasChanged(value, oldValue)) {
-    trigger(target, "set", key, value, oldValue);
-  }
-  return this;
-}
-function deleteEntry(key) {
-  const target = toRaw(this);
-  const { has: has2, get: get2 } = getProto(target);
-  let hadKey = has2.call(target, key);
-  if (!hadKey) {
-    key = toRaw(key);
-    hadKey = has2.call(target, key);
-  } else {
-    checkIdentityKeys(target, has2, key);
-  }
-  const oldValue = get2 ? get2.call(target, key) : void 0;
-  const result = target.delete(key);
-  if (hadKey) {
-    trigger(target, "delete", key, void 0, oldValue);
-  }
-  return result;
-}
-function clear() {
-  const target = toRaw(this);
-  const hadItems = target.size !== 0;
-  const oldTarget = isMap(target) ? new Map(target) : new Set(target);
-  const result = target.clear();
-  if (hadItems) {
-    trigger(target, "clear", void 0, void 0, oldTarget);
-  }
-  return result;
-}
-function createForEach(isReadonly2, isShallow2) {
-  return function forEach(callback, thisArg) {
-    const observed = this;
-    const target = observed["__v_raw"];
-    const rawTarget = toRaw(target);
-    const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive;
-    !isReadonly2 && track(rawTarget, "iterate", ITERATE_KEY);
-    return target.forEach((value, key) => {
-      return callback.call(thisArg, wrap(value), wrap(key), observed);
-    });
-  };
-}
-function createIterableMethod(method, isReadonly2, isShallow2) {
-  return function(...args) {
-    const target = this["__v_raw"];
-    const rawTarget = toRaw(target);
-    const targetIsMap = isMap(rawTarget);
-    const isPair = method === "entries" || method === Symbol.iterator && targetIsMap;
-    const isKeyOnly = method === "keys" && targetIsMap;
-    const innerIterator = target[method](...args);
-    const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive;
-    !isReadonly2 && track(
-      rawTarget,
-      "iterate",
-      isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY
-    );
-    return {
-      // iterator protocol
-      next() {
-        const { value, done } = innerIterator.next();
-        return done ? { value, done } : {
-          value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
-          done
-        };
-      },
-      // iterable protocol
-      [Symbol.iterator]() {
-        return this;
-      }
-    };
-  };
-}
-function createReadonlyMethod(type) {
-  return function(...args) {
-    {
-      const key = args[0] ? `on key "${args[0]}" ` : ``;
-      warn$2(
-        `${capitalize(type)} operation ${key}failed: target is readonly.`,
-        toRaw(this)
-      );
-    }
-    return type === "delete" ? false : type === "clear" ? void 0 : this;
-  };
-}
-function createInstrumentations() {
-  const mutableInstrumentations2 = {
-    get(key) {
-      return get(this, key);
-    },
-    get size() {
-      return size(this);
-    },
-    has,
-    add,
-    set: set$1,
-    delete: deleteEntry,
-    clear,
-    forEach: createForEach(false, false)
-  };
-  const shallowInstrumentations2 = {
-    get(key) {
-      return get(this, key, false, true);
-    },
-    get size() {
-      return size(this);
-    },
-    has,
-    add,
-    set: set$1,
-    delete: deleteEntry,
-    clear,
-    forEach: createForEach(false, true)
-  };
-  const readonlyInstrumentations2 = {
-    get(key) {
-      return get(this, key, true);
-    },
-    get size() {
-      return size(this, true);
-    },
-    has(key) {
-      return has.call(this, key, true);
-    },
-    add: createReadonlyMethod("add"),
-    set: createReadonlyMethod("set"),
-    delete: createReadonlyMethod("delete"),
-    clear: createReadonlyMethod("clear"),
-    forEach: createForEach(true, false)
-  };
-  const shallowReadonlyInstrumentations2 = {
-    get(key) {
-      return get(this, key, true, true);
-    },
-    get size() {
-      return size(this, true);
-    },
-    has(key) {
-      return has.call(this, key, true);
-    },
-    add: createReadonlyMethod("add"),
-    set: createReadonlyMethod("set"),
-    delete: createReadonlyMethod("delete"),
-    clear: createReadonlyMethod("clear"),
-    forEach: createForEach(true, true)
-  };
-  const iteratorMethods = [
-    "keys",
-    "values",
-    "entries",
-    Symbol.iterator
-  ];
-  iteratorMethods.forEach((method) => {
-    mutableInstrumentations2[method] = createIterableMethod(method, false, false);
-    readonlyInstrumentations2[method] = createIterableMethod(method, true, false);
-    shallowInstrumentations2[method] = createIterableMethod(method, false, true);
-    shallowReadonlyInstrumentations2[method] = createIterableMethod(
-      method,
-      true,
-      true
-    );
-  });
-  return [
-    mutableInstrumentations2,
-    readonlyInstrumentations2,
-    shallowInstrumentations2,
-    shallowReadonlyInstrumentations2
-  ];
-}
-const [
-  mutableInstrumentations,
-  readonlyInstrumentations,
-  shallowInstrumentations,
-  shallowReadonlyInstrumentations
-] = /* @__PURE__ */ createInstrumentations();
-function createInstrumentationGetter(isReadonly2, shallow) {
-  const instrumentations = shallow ? isReadonly2 ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly2 ? readonlyInstrumentations : mutableInstrumentations;
-  return (target, key, receiver) => {
-    if (key === "__v_isReactive") {
-      return !isReadonly2;
-    } else if (key === "__v_isReadonly") {
-      return isReadonly2;
-    } else if (key === "__v_raw") {
-      return target;
-    }
-    return Reflect.get(
-      hasOwn$1(instrumentations, key) && key in target ? instrumentations : target,
-      key,
-      receiver
-    );
-  };
-}
-const mutableCollectionHandlers = {
-  get: /* @__PURE__ */ createInstrumentationGetter(false, false)
-};
-const shallowCollectionHandlers = {
-  get: /* @__PURE__ */ createInstrumentationGetter(false, true)
-};
-const readonlyCollectionHandlers = {
-  get: /* @__PURE__ */ createInstrumentationGetter(true, false)
-};
-const shallowReadonlyCollectionHandlers = {
-  get: /* @__PURE__ */ createInstrumentationGetter(true, true)
-};
-function checkIdentityKeys(target, has2, key) {
-  const rawKey = toRaw(key);
-  if (rawKey !== key && has2.call(target, rawKey)) {
-    const type = toRawType(target);
-    warn$2(
-      `Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`
-    );
-  }
-}
-const reactiveMap = /* @__PURE__ */ new WeakMap();
-const shallowReactiveMap = /* @__PURE__ */ new WeakMap();
-const readonlyMap = /* @__PURE__ */ new WeakMap();
-const shallowReadonlyMap = /* @__PURE__ */ new WeakMap();
-function targetTypeMap(rawType) {
-  switch (rawType) {
-    case "Object":
-    case "Array":
-      return 1;
-    case "Map":
-    case "Set":
-    case "WeakMap":
-    case "WeakSet":
-      return 2;
-    default:
-      return 0;
-  }
-}
-function getTargetType(value) {
-  return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(toRawType(value));
-}
-function reactive(target) {
-  if (isReadonly(target)) {
-    return target;
-  }
-  return createReactiveObject(
-    target,
-    false,
-    mutableHandlers,
-    mutableCollectionHandlers,
-    reactiveMap
-  );
-}
-function shallowReactive(target) {
-  return createReactiveObject(
-    target,
-    false,
-    shallowReactiveHandlers,
-    shallowCollectionHandlers,
-    shallowReactiveMap
-  );
-}
-function readonly(target) {
-  return createReactiveObject(
-    target,
-    true,
-    readonlyHandlers,
-    readonlyCollectionHandlers,
-    readonlyMap
-  );
-}
-function shallowReadonly(target) {
-  return createReactiveObject(
-    target,
-    true,
-    shallowReadonlyHandlers,
-    shallowReadonlyCollectionHandlers,
-    shallowReadonlyMap
-  );
-}
-function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) {
-  if (!isObject$1(target)) {
-    {
-      warn$2(`value cannot be made reactive: ${String(target)}`);
-    }
-    return target;
-  }
-  if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) {
-    return target;
-  }
-  const existingProxy = proxyMap.get(target);
-  if (existingProxy) {
-    return existingProxy;
-  }
-  const targetType = getTargetType(target);
-  if (targetType === 0) {
-    return target;
-  }
-  const proxy = new Proxy(
-    target,
-    targetType === 2 ? collectionHandlers : baseHandlers
-  );
-  proxyMap.set(target, proxy);
-  return proxy;
-}
-function isReactive(value) {
-  if (isReadonly(value)) {
-    return isReactive(value["__v_raw"]);
-  }
-  return !!(value && value["__v_isReactive"]);
-}
-function isReadonly(value) {
-  return !!(value && value["__v_isReadonly"]);
-}
-function isShallow(value) {
-  return !!(value && value["__v_isShallow"]);
-}
-function isProxy(value) {
-  return isReactive(value) || isReadonly(value);
-}
-function toRaw(observed) {
-  const raw = observed && observed["__v_raw"];
-  return raw ? toRaw(raw) : observed;
-}
-function markRaw(value) {
-  if (Object.isExtensible(value)) {
-    def(value, "__v_skip", true);
-  }
-  return value;
-}
-const toReactive = (value) => isObject$1(value) ? reactive(value) : value;
-const toReadonly = (value) => isObject$1(value) ? readonly(value) : value;
-const COMPUTED_SIDE_EFFECT_WARN = `Computed is still dirty after getter evaluation, likely because a computed is mutating its own dependency in its getter. State mutations in computed getters should be avoided.  Check the docs for more details: https://vuejs.org/guide/essentials/computed.html#getters-should-be-side-effect-free`;
-class ComputedRefImpl {
-  constructor(getter, _setter, isReadonly2, isSSR) {
-    this.getter = getter;
-    this._setter = _setter;
-    this.dep = void 0;
-    this.__v_isRef = true;
-    this["__v_isReadonly"] = false;
-    this.effect = new ReactiveEffect2(
-      () => getter(this._value),
-      () => triggerRefValue(
-        this,
-        this.effect._dirtyLevel === 2 ? 2 : 3
-      )
-    );
-    this.effect.computed = this;
-    this.effect.active = this._cacheable = !isSSR;
-    this["__v_isReadonly"] = isReadonly2;
-  }
-  get value() {
-    const self2 = toRaw(this);
-    if ((!self2._cacheable || self2.effect.dirty) && hasChanged(self2._value, self2._value = self2.effect.run())) {
-      triggerRefValue(self2, 4);
-    }
-    trackRefValue(self2);
-    if (self2.effect._dirtyLevel >= 2) {
-      if (this._warnRecursive) {
-        warn$2(COMPUTED_SIDE_EFFECT_WARN, `
-
-getter: `, this.getter);
-      }
-      triggerRefValue(self2, 2);
-    }
-    return self2._value;
-  }
-  set value(newValue) {
-    this._setter(newValue);
-  }
-  // #region polyfill _dirty for backward compatibility third party code for Vue <= 3.3.x
-  get _dirty() {
-    return this.effect.dirty;
-  }
-  set _dirty(v2) {
-    this.effect.dirty = v2;
-  }
-  // #endregion
-}
-function computed$1(getterOrOptions, debugOptions, isSSR = false) {
-  let getter;
-  let setter;
-  const onlyGetter = isFunction(getterOrOptions);
-  if (onlyGetter) {
-    getter = getterOrOptions;
-    setter = () => {
-      warn$2("Write operation failed: computed value is readonly");
-    };
-  } else {
-    getter = getterOrOptions.get;
-    setter = getterOrOptions.set;
-  }
-  const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
-  if (debugOptions && !isSSR) {
-    cRef.effect.onTrack = debugOptions.onTrack;
-    cRef.effect.onTrigger = debugOptions.onTrigger;
-  }
-  return cRef;
-}
-function trackRefValue(ref2) {
-  var _a;
-  if (shouldTrack && activeEffect) {
-    ref2 = toRaw(ref2);
-    trackEffect(
-      activeEffect,
-      (_a = ref2.dep) != null ? _a : ref2.dep = createDep(
-        () => ref2.dep = void 0,
-        ref2 instanceof ComputedRefImpl ? ref2 : void 0
-      ),
-      {
-        target: ref2,
-        type: "get",
-        key: "value"
-      }
-    );
-  }
-}
-function triggerRefValue(ref2, dirtyLevel = 4, newVal) {
-  ref2 = toRaw(ref2);
-  const dep = ref2.dep;
-  if (dep) {
-    triggerEffects(
-      dep,
-      dirtyLevel,
-      {
-        target: ref2,
-        type: "set",
-        key: "value",
-        newValue: newVal
-      }
-    );
-  }
-}
-function isRef(r2) {
-  return !!(r2 && r2.__v_isRef === true);
-}
-function ref(value) {
-  return createRef(value, false);
-}
-function createRef(rawValue, shallow) {
-  if (isRef(rawValue)) {
-    return rawValue;
-  }
-  return new RefImpl(rawValue, shallow);
-}
-class RefImpl {
-  constructor(value, __v_isShallow) {
-    this.__v_isShallow = __v_isShallow;
-    this.dep = void 0;
-    this.__v_isRef = true;
-    this._rawValue = __v_isShallow ? value : toRaw(value);
-    this._value = __v_isShallow ? value : toReactive(value);
-  }
-  get value() {
-    trackRefValue(this);
-    return this._value;
-  }
-  set value(newVal) {
-    const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
-    newVal = useDirectValue ? newVal : toRaw(newVal);
-    if (hasChanged(newVal, this._rawValue)) {
-      this._rawValue = newVal;
-      this._value = useDirectValue ? newVal : toReactive(newVal);
-      triggerRefValue(this, 4, newVal);
-    }
-  }
-}
-function unref(ref2) {
-  return isRef(ref2) ? ref2.value : ref2;
-}
-const shallowUnwrapHandlers = {
-  get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
-  set: (target, key, value, receiver) => {
-    const oldValue = target[key];
-    if (isRef(oldValue) && !isRef(value)) {
-      oldValue.value = value;
-      return true;
-    } else {
-      return Reflect.set(target, key, value, receiver);
-    }
-  }
-};
-function proxyRefs(objectWithRefs) {
-  return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers);
-}
-const stack = [];
-function pushWarningContext(vnode) {
-  stack.push(vnode);
-}
-function popWarningContext() {
-  stack.pop();
-}
-function warn$1(msg, ...args) {
-  pauseTracking();
-  const instance = stack.length ? stack[stack.length - 1].component : null;
-  const appWarnHandler = instance && instance.appContext.config.warnHandler;
-  const trace = getComponentTrace();
-  if (appWarnHandler) {
-    callWithErrorHandling(
-      appWarnHandler,
-      instance,
-      11,
-      [
-        msg + args.map((a2) => {
-          var _a, _b;
-          return (_b = (_a = a2.toString) == null ? void 0 : _a.call(a2)) != null ? _b : JSON.stringify(a2);
-        }).join(""),
-        instance && instance.proxy,
-        trace.map(
-          ({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`
-        ).join("\n"),
-        trace
-      ]
-    );
-  } else {
-    const warnArgs = [`[Vue warn]: ${msg}`, ...args];
-    if (trace.length && // avoid spamming console during tests
-    true) {
-      warnArgs.push(`
-`, ...formatTrace(trace));
-    }
-    console.warn(...warnArgs);
-  }
-  resetTracking();
-}
-function getComponentTrace() {
-  let currentVNode = stack[stack.length - 1];
-  if (!currentVNode) {
-    return [];
-  }
-  const normalizedStack = [];
-  while (currentVNode) {
-    const last = normalizedStack[0];
-    if (last && last.vnode === currentVNode) {
-      last.recurseCount++;
-    } else {
-      normalizedStack.push({
-        vnode: currentVNode,
-        recurseCount: 0
-      });
-    }
-    const parentInstance = currentVNode.component && currentVNode.component.parent;
-    currentVNode = parentInstance && parentInstance.vnode;
-  }
-  return normalizedStack;
-}
-function formatTrace(trace) {
-  const logs = [];
-  trace.forEach((entry, i2) => {
-    logs.push(...i2 === 0 ? [] : [`
-`], ...formatTraceEntry(entry));
-  });
-  return logs;
-}
-function formatTraceEntry({ vnode, recurseCount }) {
-  const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
-  const isRoot = vnode.component ? vnode.component.parent == null : false;
-  const open = ` at <${formatComponentName(
-    vnode.component,
-    vnode.type,
-    isRoot
-  )}`;
-  const close = `>` + postfix;
-  return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close];
-}
-function formatProps(props) {
-  const res = [];
-  const keys = Object.keys(props);
-  keys.slice(0, 3).forEach((key) => {
-    res.push(...formatProp(key, props[key]));
-  });
-  if (keys.length > 3) {
-    res.push(` ...`);
-  }
-  return res;
-}
-function formatProp(key, value, raw) {
-  if (isString(value)) {
-    value = JSON.stringify(value);
-    return raw ? value : [`${key}=${value}`];
-  } else if (typeof value === "number" || typeof value === "boolean" || value == null) {
-    return raw ? value : [`${key}=${value}`];
-  } else if (isRef(value)) {
-    value = formatProp(key, toRaw(value.value), true);
-    return raw ? value : [`${key}=Ref<`, value, `>`];
-  } else if (isFunction(value)) {
-    return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
-  } else {
-    value = toRaw(value);
-    return raw ? value : [`${key}=`, value];
-  }
-}
-const ErrorTypeStrings = {
-  ["sp"]: "serverPrefetch hook",
-  ["bc"]: "beforeCreate hook",
-  ["c"]: "created hook",
-  ["bm"]: "beforeMount hook",
-  ["m"]: "mounted hook",
-  ["bu"]: "beforeUpdate hook",
-  ["u"]: "updated",
-  ["bum"]: "beforeUnmount hook",
-  ["um"]: "unmounted hook",
-  ["a"]: "activated hook",
-  ["da"]: "deactivated hook",
-  ["ec"]: "errorCaptured hook",
-  ["rtc"]: "renderTracked hook",
-  ["rtg"]: "renderTriggered hook",
-  [0]: "setup function",
-  [1]: "render function",
-  [2]: "watcher getter",
-  [3]: "watcher callback",
-  [4]: "watcher cleanup function",
-  [5]: "native event handler",
-  [6]: "component event handler",
-  [7]: "vnode hook",
-  [8]: "directive hook",
-  [9]: "transition hook",
-  [10]: "app errorHandler",
-  [11]: "app warnHandler",
-  [12]: "ref function",
-  [13]: "async component loader",
-  [14]: "scheduler flush. This is likely a Vue internals bug. Please open an issue at https://github.com/vuejs/core ."
-};
-function callWithErrorHandling(fn, instance, type, args) {
-  try {
-    return args ? fn(...args) : fn();
-  } catch (err) {
-    handleError(err, instance, type);
-  }
-}
-function callWithAsyncErrorHandling(fn, instance, type, args) {
-  if (isFunction(fn)) {
-    const res = callWithErrorHandling(fn, instance, type, args);
-    if (res && isPromise(res)) {
-      res.catch((err) => {
-        handleError(err, instance, type);
-      });
-    }
-    return res;
-  }
-  const values = [];
-  for (let i2 = 0; i2 < fn.length; i2++) {
-    values.push(callWithAsyncErrorHandling(fn[i2], instance, type, args));
-  }
-  return values;
-}
-function handleError(err, instance, type, throwInDev = true) {
-  const contextVNode = instance ? instance.vnode : null;
-  if (instance) {
-    let cur = instance.parent;
-    const exposedInstance = instance.proxy;
-    const errorInfo = ErrorTypeStrings[type] || type;
-    while (cur) {
-      const errorCapturedHooks = cur.ec;
-      if (errorCapturedHooks) {
-        for (let i2 = 0; i2 < errorCapturedHooks.length; i2++) {
-          if (errorCapturedHooks[i2](err, exposedInstance, errorInfo) === false) {
-            return;
-          }
-        }
-      }
-      cur = cur.parent;
-    }
-    const appErrorHandler = instance.appContext.config.errorHandler;
-    if (appErrorHandler) {
-      callWithErrorHandling(
-        appErrorHandler,
-        null,
-        10,
-        [err, exposedInstance, errorInfo]
-      );
-      return;
-    }
-  }
-  logError(err, type, contextVNode, throwInDev);
-}
-function logError(err, type, contextVNode, throwInDev = true) {
-  {
-    const info = ErrorTypeStrings[type] || type;
-    if (contextVNode) {
-      pushWarningContext(contextVNode);
-    }
-    warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
-    if (contextVNode) {
-      popWarningContext();
-    }
-    if (throwInDev) {
-      console.error(err);
-    } else {
-      console.error(err);
-    }
-  }
-}
-let isFlushing = false;
-let isFlushPending = false;
-const queue = [];
-let flushIndex = 0;
-const pendingPostFlushCbs = [];
-let activePostFlushCbs = null;
-let postFlushIndex = 0;
-const resolvedPromise = /* @__PURE__ */ Promise.resolve();
-let currentFlushPromise = null;
-const RECURSION_LIMIT = 100;
-function nextTick$1(fn) {
-  const p2 = currentFlushPromise || resolvedPromise;
-  return fn ? p2.then(this ? fn.bind(this) : fn) : p2;
-}
-function findInsertionIndex(id) {
-  let start = flushIndex + 1;
-  let end = queue.length;
-  while (start < end) {
-    const middle = start + end >>> 1;
-    const middleJob = queue[middle];
-    const middleJobId = getId(middleJob);
-    if (middleJobId < id || middleJobId === id && middleJob.pre) {
-      start = middle + 1;
-    } else {
-      end = middle;
-    }
-  }
-  return start;
-}
-function queueJob(job) {
-  if (!queue.length || !queue.includes(
-    job,
-    isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex
-  )) {
-    if (job.id == null) {
-      queue.push(job);
-    } else {
-      queue.splice(findInsertionIndex(job.id), 0, job);
-    }
-    queueFlush();
-  }
-}
-function queueFlush() {
-  if (!isFlushing && !isFlushPending) {
-    isFlushPending = true;
-    currentFlushPromise = resolvedPromise.then(flushJobs);
-  }
-}
-function hasQueueJob(job) {
-  return queue.indexOf(job) > -1;
-}
-function invalidateJob(job) {
-  const i2 = queue.indexOf(job);
-  if (i2 > flushIndex) {
-    queue.splice(i2, 1);
-  }
-}
-function queuePostFlushCb(cb) {
-  if (!isArray(cb)) {
-    if (!activePostFlushCbs || !activePostFlushCbs.includes(
-      cb,
-      cb.allowRecurse ? postFlushIndex + 1 : postFlushIndex
-    )) {
-      pendingPostFlushCbs.push(cb);
-    }
-  } else {
-    pendingPostFlushCbs.push(...cb);
-  }
-  queueFlush();
-}
-function flushPreFlushCbs(instance, seen, i2 = isFlushing ? flushIndex + 1 : 0) {
-  {
-    seen = seen || /* @__PURE__ */ new Map();
-  }
-  for (; i2 < queue.length; i2++) {
-    const cb = queue[i2];
-    if (cb && cb.pre) {
-      if (instance && cb.id !== instance.uid) {
-        continue;
-      }
-      if (checkRecursiveUpdates(seen, cb)) {
-        continue;
-      }
-      queue.splice(i2, 1);
-      i2--;
-      cb();
-    }
-  }
-}
-function flushPostFlushCbs(seen) {
-  if (pendingPostFlushCbs.length) {
-    const deduped = [...new Set(pendingPostFlushCbs)].sort(
-      (a2, b2) => getId(a2) - getId(b2)
-    );
-    pendingPostFlushCbs.length = 0;
-    if (activePostFlushCbs) {
-      activePostFlushCbs.push(...deduped);
-      return;
-    }
-    activePostFlushCbs = deduped;
-    {
-      seen = seen || /* @__PURE__ */ new Map();
-    }
-    for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
-      if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
-        continue;
-      }
-      activePostFlushCbs[postFlushIndex]();
-    }
-    activePostFlushCbs = null;
-    postFlushIndex = 0;
-  }
-}
-const getId = (job) => job.id == null ? Infinity : job.id;
-const comparator = (a2, b2) => {
-  const diff2 = getId(a2) - getId(b2);
-  if (diff2 === 0) {
-    if (a2.pre && !b2.pre)
-      return -1;
-    if (b2.pre && !a2.pre)
-      return 1;
-  }
-  return diff2;
-};
-function flushJobs(seen) {
-  isFlushPending = false;
-  isFlushing = true;
-  {
-    seen = seen || /* @__PURE__ */ new Map();
-  }
-  queue.sort(comparator);
-  const check = (job) => checkRecursiveUpdates(seen, job);
-  try {
-    for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
-      const job = queue[flushIndex];
-      if (job && job.active !== false) {
-        if (check(job)) {
-          continue;
-        }
-        callWithErrorHandling(job, null, 14);
-      }
-    }
-  } finally {
-    flushIndex = 0;
-    queue.length = 0;
-    flushPostFlushCbs(seen);
-    isFlushing = false;
-    currentFlushPromise = null;
-    if (queue.length || pendingPostFlushCbs.length) {
-      flushJobs(seen);
-    }
-  }
-}
-function checkRecursiveUpdates(seen, fn) {
-  if (!seen.has(fn)) {
-    seen.set(fn, 1);
-  } else {
-    const count = seen.get(fn);
-    if (count > RECURSION_LIMIT) {
-      const instance = fn.ownerInstance;
-      const componentName = instance && getComponentName(instance.type);
-      handleError(
-        `Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.`,
-        null,
-        10
-      );
-      return true;
-    } else {
-      seen.set(fn, count + 1);
-    }
-  }
-}
-let devtools;
-let buffer = [];
-let devtoolsNotInstalled = false;
-function emit$1(event, ...args) {
-  if (devtools) {
-    devtools.emit(event, ...args);
-  } else if (!devtoolsNotInstalled) {
-    buffer.push({ event, args });
-  }
-}
-function setDevtoolsHook(hook, target) {
-  var _a, _b;
-  devtools = hook;
-  if (devtools) {
-    devtools.enabled = true;
-    buffer.forEach(({ event, args }) => devtools.emit(event, ...args));
-    buffer = [];
-  } else if (
-    // handle late devtools injection - only do this if we are in an actual
-    // browser environment to avoid the timer handle stalling test runner exit
-    // (#4815)
-    typeof window !== "undefined" && // some envs mock window but not fully
-    window.HTMLElement && // also exclude jsdom
-    !((_b = (_a = window.navigator) == null ? void 0 : _a.userAgent) == null ? void 0 : _b.includes("jsdom"))
-  ) {
-    const replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || [];
-    replay.push((newHook) => {
-      setDevtoolsHook(newHook, target);
-    });
-    setTimeout(() => {
-      if (!devtools) {
-        target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
-        devtoolsNotInstalled = true;
-        buffer = [];
-      }
-    }, 3e3);
-  } else {
-    devtoolsNotInstalled = true;
-    buffer = [];
-  }
-}
-function devtoolsInitApp(app, version2) {
-  emit$1("app:init", app, version2, {
-    Fragment,
-    Text,
-    Comment,
-    Static
-  });
-}
-const devtoolsComponentAdded = /* @__PURE__ */ createDevtoolsComponentHook(
-  "component:added"
-  /* COMPONENT_ADDED */
-);
-const devtoolsComponentUpdated = /* @__PURE__ */ createDevtoolsComponentHook(
-  "component:updated"
-  /* COMPONENT_UPDATED */
-);
-const _devtoolsComponentRemoved = /* @__PURE__ */ createDevtoolsComponentHook(
-  "component:removed"
-  /* COMPONENT_REMOVED */
-);
-const devtoolsComponentRemoved = (component) => {
-  if (devtools && typeof devtools.cleanupBuffer === "function" && // remove the component if it wasn't buffered
-  !devtools.cleanupBuffer(component)) {
-    _devtoolsComponentRemoved(component);
-  }
-};
-/*! #__NO_SIDE_EFFECTS__ */
-// @__NO_SIDE_EFFECTS__
-function createDevtoolsComponentHook(hook) {
-  return (component) => {
-    emit$1(
-      hook,
-      component.appContext.app,
-      component.uid,
-      // fixed by xxxxxx
-      // 为 0 是 App,无 parent 是 Page 指向 App
-      component.uid === 0 ? void 0 : component.parent ? component.parent.uid : 0,
-      component
-    );
-  };
-}
-const devtoolsPerfStart = /* @__PURE__ */ createDevtoolsPerformanceHook(
-  "perf:start"
-  /* PERFORMANCE_START */
-);
-const devtoolsPerfEnd = /* @__PURE__ */ createDevtoolsPerformanceHook(
-  "perf:end"
-  /* PERFORMANCE_END */
-);
-function createDevtoolsPerformanceHook(hook) {
-  return (component, type, time) => {
-    emit$1(hook, component.appContext.app, component.uid, component, type, time);
-  };
-}
-function devtoolsComponentEmit(component, event, params) {
-  emit$1(
-    "component:emit",
-    component.appContext.app,
-    component,
-    event,
-    params
-  );
-}
-function emit(instance, event, ...rawArgs) {
-  if (instance.isUnmounted)
-    return;
-  const props = instance.vnode.props || EMPTY_OBJ;
-  {
-    const {
-      emitsOptions,
-      propsOptions: [propsOptions]
-    } = instance;
-    if (emitsOptions) {
-      if (!(event in emitsOptions) && true) {
-        if (!propsOptions || !(toHandlerKey(event) in propsOptions)) {
-          warn$1(
-            `Component emitted event "${event}" but it is neither declared in the emits option nor as an "${toHandlerKey(event)}" prop.`
-          );
-        }
-      } else {
-        const validator = emitsOptions[event];
-        if (isFunction(validator)) {
-          const isValid = validator(...rawArgs);
-          if (!isValid) {
-            warn$1(
-              `Invalid event arguments: event validation failed for event "${event}".`
-            );
-          }
-        }
-      }
-    }
-  }
-  let args = rawArgs;
-  const isModelListener2 = event.startsWith("update:");
-  const modelArg = isModelListener2 && event.slice(7);
-  if (modelArg && modelArg in props) {
-    const modifiersKey = `${modelArg === "modelValue" ? "model" : modelArg}Modifiers`;
-    const { number, trim } = props[modifiersKey] || EMPTY_OBJ;
-    if (trim) {
-      args = rawArgs.map((a2) => isString(a2) ? a2.trim() : a2);
-    }
-    if (number) {
-      args = rawArgs.map(looseToNumber);
-    }
-  }
-  {
-    devtoolsComponentEmit(instance, event, args);
-  }
-  {
-    const lowerCaseEvent = event.toLowerCase();
-    if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) {
-      warn$1(
-        `Event "${lowerCaseEvent}" is emitted in component ${formatComponentName(
-          instance,
-          instance.type
-        )} but the handler is registered for "${event}". Note that HTML attributes are case-insensitive and you cannot use v-on to listen to camelCase events when using in-DOM templates. You should probably use "${hyphenate(
-          event
-        )}" instead of "${event}".`
-      );
-    }
-  }
-  let handlerName;
-  let handler = props[handlerName = toHandlerKey(event)] || // also try camelCase event handler (#2249)
-  props[handlerName = toHandlerKey(camelize(event))];
-  if (!handler && isModelListener2) {
-    handler = props[handlerName = toHandlerKey(hyphenate(event))];
-  }
-  if (handler) {
-    callWithAsyncErrorHandling(
-      handler,
-      instance,
-      6,
-      args
-    );
-  }
-  const onceHandler = props[handlerName + `Once`];
-  if (onceHandler) {
-    if (!instance.emitted) {
-      instance.emitted = {};
-    } else if (instance.emitted[handlerName]) {
-      return;
-    }
-    instance.emitted[handlerName] = true;
-    callWithAsyncErrorHandling(
-      onceHandler,
-      instance,
-      6,
-      args
-    );
-  }
-}
-function normalizeEmitsOptions(comp, appContext, asMixin = false) {
-  const cache = appContext.emitsCache;
-  const cached = cache.get(comp);
-  if (cached !== void 0) {
-    return cached;
-  }
-  const raw = comp.emits;
-  let normalized = {};
-  let hasExtends = false;
-  if (!isFunction(comp)) {
-    const extendEmits = (raw2) => {
-      const normalizedFromExtend = normalizeEmitsOptions(raw2, appContext, true);
-      if (normalizedFromExtend) {
-        hasExtends = true;
-        extend(normalized, normalizedFromExtend);
-      }
-    };
-    if (!asMixin && appContext.mixins.length) {
-      appContext.mixins.forEach(extendEmits);
-    }
-    if (comp.extends) {
-      extendEmits(comp.extends);
-    }
-    if (comp.mixins) {
-      comp.mixins.forEach(extendEmits);
-    }
-  }
-  if (!raw && !hasExtends) {
-    if (isObject$1(comp)) {
-      cache.set(comp, null);
-    }
-    return null;
-  }
-  if (isArray(raw)) {
-    raw.forEach((key) => normalized[key] = null);
-  } else {
-    extend(normalized, raw);
-  }
-  if (isObject$1(comp)) {
-    cache.set(comp, normalized);
-  }
-  return normalized;
-}
-function isEmitListener(options, key) {
-  if (!options || !isOn(key)) {
-    return false;
-  }
-  key = key.slice(2).replace(/Once$/, "");
-  return hasOwn$1(options, key[0].toLowerCase() + key.slice(1)) || hasOwn$1(options, hyphenate(key)) || hasOwn$1(options, key);
-}
-let currentRenderingInstance = null;
-function setCurrentRenderingInstance(instance) {
-  const prev = currentRenderingInstance;
-  currentRenderingInstance = instance;
-  instance && instance.type.__scopeId || null;
-  return prev;
-}
-const COMPONENTS = "components";
-function resolveComponent(name, maybeSelfReference) {
-  return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
-}
-function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
-  const instance = currentRenderingInstance || currentInstance;
-  if (instance) {
-    const Component2 = instance.type;
-    if (type === COMPONENTS) {
-      const selfName = getComponentName(
-        Component2,
-        false
-      );
-      if (selfName && (selfName === name || selfName === camelize(name) || selfName === capitalize(camelize(name)))) {
-        return Component2;
-      }
-    }
-    const res = (
-      // local registration
-      // check instance[type] first which is resolved for options API
-      resolve(instance[type] || Component2[type], name) || // global registration
-      resolve(instance.appContext[type], name)
-    );
-    if (!res && maybeSelfReference) {
-      return Component2;
-    }
-    if (warnMissing && !res) {
-      const extra = type === COMPONENTS ? `
-If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.` : ``;
-      warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
-    }
-    return res;
-  } else {
-    warn$1(
-      `resolve${capitalize(type.slice(0, -1))} can only be used in render() or setup().`
-    );
-  }
-}
-function resolve(registry, name) {
-  return registry && (registry[name] || registry[camelize(name)] || registry[capitalize(camelize(name))]);
-}
-const INITIAL_WATCHER_VALUE = {};
-function watch(source, cb, options) {
-  if (!isFunction(cb)) {
-    warn$1(
-      `\`watch(fn, options?)\` signature has been moved to a separate API. Use \`watchEffect(fn, options?)\` instead. \`watch\` now only supports \`watch(source, cb, options?) signature.`
-    );
-  }
-  return doWatch(source, cb, options);
-}
-function doWatch(source, cb, {
-  immediate,
-  deep,
-  flush,
-  once: once2,
-  onTrack,
-  onTrigger
-} = EMPTY_OBJ) {
-  if (cb && once2) {
-    const _cb = cb;
-    cb = (...args) => {
-      _cb(...args);
-      unwatch();
-    };
-  }
-  if (deep !== void 0 && typeof deep === "number") {
-    warn$1(
-      `watch() "deep" option with number value will be used as watch depth in future versions. Please use a boolean instead to avoid potential breakage.`
-    );
-  }
-  if (!cb) {
-    if (immediate !== void 0) {
-      warn$1(
-        `watch() "immediate" option is only respected when using the watch(source, callback, options?) signature.`
-      );
-    }
-    if (deep !== void 0) {
-      warn$1(
-        `watch() "deep" option is only respected when using the watch(source, callback, options?) signature.`
-      );
-    }
-    if (once2 !== void 0) {
-      warn$1(
-        `watch() "once" option is only respected when using the watch(source, callback, options?) signature.`
-      );
-    }
-  }
-  const warnInvalidSource = (s2) => {
-    warn$1(
-      `Invalid watch source: `,
-      s2,
-      `A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.`
-    );
-  };
-  const instance = currentInstance;
-  const reactiveGetter = (source2) => deep === true ? source2 : (
-    // for deep: false, only traverse root-level properties
-    traverse(source2, deep === false ? 1 : void 0)
-  );
-  let getter;
-  let forceTrigger = false;
-  let isMultiSource = false;
-  if (isRef(source)) {
-    getter = () => source.value;
-    forceTrigger = isShallow(source);
-  } else if (isReactive(source)) {
-    getter = () => reactiveGetter(source);
-    forceTrigger = true;
-  } else if (isArray(source)) {
-    isMultiSource = true;
-    forceTrigger = source.some((s2) => isReactive(s2) || isShallow(s2));
-    getter = () => source.map((s2) => {
-      if (isRef(s2)) {
-        return s2.value;
-      } else if (isReactive(s2)) {
-        return reactiveGetter(s2);
-      } else if (isFunction(s2)) {
-        return callWithErrorHandling(s2, instance, 2);
-      } else {
-        warnInvalidSource(s2);
-      }
-    });
-  } else if (isFunction(source)) {
-    if (cb) {
-      getter = () => callWithErrorHandling(source, instance, 2);
-    } else {
-      getter = () => {
-        if (cleanup) {
-          cleanup();
-        }
-        return callWithAsyncErrorHandling(
-          source,
-          instance,
-          3,
-          [onCleanup]
-        );
-      };
-    }
-  } else {
-    getter = NOOP;
-    warnInvalidSource(source);
-  }
-  if (cb && deep) {
-    const baseGetter = getter;
-    getter = () => traverse(baseGetter());
-  }
-  let cleanup;
-  let onCleanup = (fn) => {
-    cleanup = effect2.onStop = () => {
-      callWithErrorHandling(fn, instance, 4);
-      cleanup = effect2.onStop = void 0;
-    };
-  };
-  let oldValue = isMultiSource ? new Array(source.length).fill(INITIAL_WATCHER_VALUE) : INITIAL_WATCHER_VALUE;
-  const job = () => {
-    if (!effect2.active || !effect2.dirty) {
-      return;
-    }
-    if (cb) {
-      const newValue = effect2.run();
-      if (deep || forceTrigger || (isMultiSource ? newValue.some((v2, i2) => hasChanged(v2, oldValue[i2])) : hasChanged(newValue, oldValue)) || false) {
-        if (cleanup) {
-          cleanup();
-        }
-        callWithAsyncErrorHandling(cb, instance, 3, [
-          newValue,
-          // pass undefined as the old value when it's changed for the first time
-          oldValue === INITIAL_WATCHER_VALUE ? void 0 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE ? [] : oldValue,
-          onCleanup
-        ]);
-        oldValue = newValue;
-      }
-    } else {
-      effect2.run();
-    }
-  };
-  job.allowRecurse = !!cb;
-  let scheduler;
-  if (flush === "sync") {
-    scheduler = job;
-  } else if (flush === "post") {
-    scheduler = () => queuePostRenderEffect$1(job, instance && instance.suspense);
-  } else {
-    job.pre = true;
-    if (instance)
-      job.id = instance.uid;
-    scheduler = () => queueJob(job);
-  }
-  const effect2 = new ReactiveEffect2(getter, NOOP, scheduler);
-  const scope = getCurrentScope();
-  const unwatch = () => {
-    effect2.stop();
-    if (scope) {
-      remove(scope.effects, effect2);
-    }
-  };
-  {
-    effect2.onTrack = onTrack;
-    effect2.onTrigger = onTrigger;
-  }
-  if (cb) {
-    if (immediate) {
-      job();
-    } else {
-      oldValue = effect2.run();
-    }
-  } else if (flush === "post") {
-    queuePostRenderEffect$1(
-      effect2.run.bind(effect2),
-      instance && instance.suspense
-    );
-  } else {
-    effect2.run();
-  }
-  return unwatch;
-}
-function instanceWatch(source, value, options) {
-  const publicThis = this.proxy;
-  const getter = isString(source) ? source.includes(".") ? createPathGetter(publicThis, source) : () => publicThis[source] : source.bind(publicThis, publicThis);
-  let cb;
-  if (isFunction(value)) {
-    cb = value;
-  } else {
-    cb = value.handler;
-    options = value;
-  }
-  const reset = setCurrentInstance(this);
-  const res = doWatch(getter, cb.bind(publicThis), options);
-  reset();
-  return res;
-}
-function createPathGetter(ctx, path) {
-  const segments = path.split(".");
-  return () => {
-    let cur = ctx;
-    for (let i2 = 0; i2 < segments.length && cur; i2++) {
-      cur = cur[segments[i2]];
-    }
-    return cur;
-  };
-}
-function traverse(value, depth, currentDepth = 0, seen) {
-  if (!isObject$1(value) || value["__v_skip"]) {
-    return value;
-  }
-  if (depth && depth > 0) {
-    if (currentDepth >= depth) {
-      return value;
-    }
-    currentDepth++;
-  }
-  seen = seen || /* @__PURE__ */ new Set();
-  if (seen.has(value)) {
-    return value;
-  }
-  seen.add(value);
-  if (isRef(value)) {
-    traverse(value.value, depth, currentDepth, seen);
-  } else if (isArray(value)) {
-    for (let i2 = 0; i2 < value.length; i2++) {
-      traverse(value[i2], depth, currentDepth, seen);
-    }
-  } else if (isSet(value) || isMap(value)) {
-    value.forEach((v2) => {
-      traverse(v2, depth, currentDepth, seen);
-    });
-  } else if (isPlainObject(value)) {
-    for (const key in value) {
-      traverse(value[key], depth, currentDepth, seen);
-    }
-  }
-  return value;
-}
-function validateDirectiveName(name) {
-  if (isBuiltInDirective(name)) {
-    warn$1("Do not use built-in directive ids as custom directive id: " + name);
-  }
-}
-function createAppContext() {
-  return {
-    app: null,
-    config: {
-      isNativeTag: NO,
-      performance: false,
-      globalProperties: {},
-      optionMergeStrategies: {},
-      errorHandler: void 0,
-      warnHandler: void 0,
-      compilerOptions: {}
-    },
-    mixins: [],
-    components: {},
-    directives: {},
-    provides: /* @__PURE__ */ Object.create(null),
-    optionsCache: /* @__PURE__ */ new WeakMap(),
-    propsCache: /* @__PURE__ */ new WeakMap(),
-    emitsCache: /* @__PURE__ */ new WeakMap()
-  };
-}
-let uid$1 = 0;
-function createAppAPI(render, hydrate) {
-  return function createApp2(rootComponent, rootProps = null) {
-    if (!isFunction(rootComponent)) {
-      rootComponent = extend({}, rootComponent);
-    }
-    if (rootProps != null && !isObject$1(rootProps)) {
-      warn$1(`root props passed to app.mount() must be an object.`);
-      rootProps = null;
-    }
-    const context = createAppContext();
-    const installedPlugins = /* @__PURE__ */ new WeakSet();
-    const app = context.app = {
-      _uid: uid$1++,
-      _component: rootComponent,
-      _props: rootProps,
-      _container: null,
-      _context: context,
-      _instance: null,
-      version,
-      get config() {
-        return context.config;
-      },
-      set config(v2) {
-        {
-          warn$1(
-            `app.config cannot be replaced. Modify individual options instead.`
-          );
-        }
-      },
-      use(plugin2, ...options) {
-        if (installedPlugins.has(plugin2)) {
-          warn$1(`Plugin has already been applied to target app.`);
-        } else if (plugin2 && isFunction(plugin2.install)) {
-          installedPlugins.add(plugin2);
-          plugin2.install(app, ...options);
-        } else if (isFunction(plugin2)) {
-          installedPlugins.add(plugin2);
-          plugin2(app, ...options);
-        } else {
-          warn$1(
-            `A plugin must either be a function or an object with an "install" function.`
-          );
-        }
-        return app;
-      },
-      mixin(mixin) {
-        {
-          if (!context.mixins.includes(mixin)) {
-            context.mixins.push(mixin);
-          } else {
-            warn$1(
-              "Mixin has already been applied to target app" + (mixin.name ? `: ${mixin.name}` : "")
-            );
-          }
-        }
-        return app;
-      },
-      component(name, component) {
-        {
-          validateComponentName(name, context.config);
-        }
-        if (!component) {
-          return context.components[name];
-        }
-        if (context.components[name]) {
-          warn$1(`Component "${name}" has already been registered in target app.`);
-        }
-        context.components[name] = component;
-        return app;
-      },
-      directive(name, directive) {
-        {
-          validateDirectiveName(name);
-        }
-        if (!directive) {
-          return context.directives[name];
-        }
-        if (context.directives[name]) {
-          warn$1(`Directive "${name}" has already been registered in target app.`);
-        }
-        context.directives[name] = directive;
-        return app;
-      },
-      // fixed by xxxxxx
-      mount() {
-      },
-      // fixed by xxxxxx
-      unmount() {
-      },
-      provide(key, value) {
-        if (key in context.provides) {
-          warn$1(
-            `App already provides property with key "${String(key)}". It will be overwritten with the new value.`
-          );
-        }
-        context.provides[key] = value;
-        return app;
-      },
-      runWithContext(fn) {
-        const lastApp = currentApp;
-        currentApp = app;
-        try {
-          return fn();
-        } finally {
-          currentApp = lastApp;
-        }
-      }
-    };
-    return app;
-  };
-}
-let currentApp = null;
-function provide(key, value) {
-  if (!currentInstance) {
-    {
-      warn$1(`provide() can only be used inside setup().`);
-    }
-  } else {
-    let provides = currentInstance.provides;
-    const parentProvides = currentInstance.parent && currentInstance.parent.provides;
-    if (parentProvides === provides) {
-      provides = currentInstance.provides = Object.create(parentProvides);
-    }
-    provides[key] = value;
-    if (currentInstance.type.mpType === "app") {
-      currentInstance.appContext.app.provide(key, value);
-    }
-  }
-}
-function inject(key, defaultValue, treatDefaultAsFactory = false) {
-  const instance = currentInstance || currentRenderingInstance;
-  if (instance || currentApp) {
-    const provides = instance ? instance.parent == null ? instance.vnode.appContext && instance.vnode.appContext.provides : instance.parent.provides : currentApp._context.provides;
-    if (provides && key in provides) {
-      return provides[key];
-    } else if (arguments.length > 1) {
-      return treatDefaultAsFactory && isFunction(defaultValue) ? defaultValue.call(instance && instance.proxy) : defaultValue;
-    } else {
-      warn$1(`injection "${String(key)}" not found.`);
-    }
-  } else {
-    warn$1(`inject() can only be used inside setup() or functional components.`);
-  }
-}
-/*! #__NO_SIDE_EFFECTS__ */
-// @__NO_SIDE_EFFECTS__
-function defineComponent(options, extraOptions) {
-  return isFunction(options) ? (
-    // #8326: extend call and options.name access are considered side-effects
-    // by Rollup, so we have to wrap it in a pure-annotated IIFE.
-    /* @__PURE__ */ (() => extend({ name: options.name }, extraOptions, { setup: options }))()
-  ) : options;
-}
-const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
-function onActivated(hook, target) {
-  registerKeepAliveHook(hook, "a", target);
-}
-function onDeactivated(hook, target) {
-  registerKeepAliveHook(hook, "da", target);
-}
-function registerKeepAliveHook(hook, type, target = currentInstance) {
-  const wrappedHook = hook.__wdc || (hook.__wdc = () => {
-    let current = target;
-    while (current) {
-      if (current.isDeactivated) {
-        return;
-      }
-      current = current.parent;
-    }
-    return hook();
-  });
-  injectHook(type, wrappedHook, target);
-  if (target) {
-    let current = target.parent;
-    while (current && current.parent) {
-      if (isKeepAlive(current.parent.vnode)) {
-        injectToKeepAliveRoot(wrappedHook, type, target, current);
-      }
-      current = current.parent;
-    }
-  }
-}
-function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
-  const injected = injectHook(
-    type,
-    hook,
-    keepAliveRoot,
-    true
-    /* prepend */
-  );
-  onUnmounted(() => {
-    remove(keepAliveRoot[type], injected);
-  }, target);
-}
-function injectHook(type, hook, target = currentInstance, prepend = false) {
-  if (target) {
-    if (isRootHook(type)) {
-      target = target.root;
-    }
-    const hooks = target[type] || (target[type] = []);
-    const wrappedHook = hook.__weh || (hook.__weh = (...args) => {
-      if (target.isUnmounted) {
-        return;
-      }
-      pauseTracking();
-      const reset = setCurrentInstance(target);
-      const res = callWithAsyncErrorHandling(hook, target, type, args);
-      reset();
-      resetTracking();
-      return res;
-    });
-    if (prepend) {
-      hooks.unshift(wrappedHook);
-    } else {
-      hooks.push(wrappedHook);
-    }
-    return wrappedHook;
-  } else {
-    const apiName = toHandlerKey(
-      (ErrorTypeStrings[type] || type.replace(/^on/, "")).replace(/ hook$/, "")
-    );
-    warn$1(
-      `${apiName} is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup().`
-    );
-  }
-}
-const createHook$1 = (lifecycle) => (hook, target = currentInstance) => (
-  // post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
-  (!isInSSRComponentSetup || lifecycle === "sp") && injectHook(lifecycle, (...args) => hook(...args), target)
-);
-const onBeforeMount = createHook$1("bm");
-const onMounted = createHook$1("m");
-const onBeforeUpdate = createHook$1("bu");
-const onUpdated = createHook$1("u");
-const onBeforeUnmount = createHook$1("bum");
-const onUnmounted = createHook$1("um");
-const onServerPrefetch = createHook$1("sp");
-const onRenderTriggered = createHook$1(
-  "rtg"
-);
-const onRenderTracked = createHook$1(
-  "rtc"
-);
-function onErrorCaptured(hook, target = currentInstance) {
-  injectHook("ec", hook, target);
-}
-const getPublicInstance = (i2) => {
-  if (!i2)
-    return null;
-  if (isStatefulComponent(i2))
-    return getExposeProxy(i2) || i2.proxy;
-  return getPublicInstance(i2.parent);
-};
-const publicPropertiesMap = (
-  // Move PURE marker to new line to workaround compiler discarding it
-  // due to type annotation
-  /* @__PURE__ */ extend(/* @__PURE__ */ Object.create(null), {
-    $: (i2) => i2,
-    // fixed by xxxxxx vue-i18n 在 dev 模式,访问了 $el,故模拟一个假的
-    // $el: i => i.vnode.el,
-    $el: (i2) => i2.__$el || (i2.__$el = {}),
-    $data: (i2) => i2.data,
-    $props: (i2) => shallowReadonly(i2.props),
-    $attrs: (i2) => shallowReadonly(i2.attrs),
-    $slots: (i2) => shallowReadonly(i2.slots),
-    $refs: (i2) => shallowReadonly(i2.refs),
-    $parent: (i2) => getPublicInstance(i2.parent),
-    $root: (i2) => getPublicInstance(i2.root),
-    $emit: (i2) => i2.emit,
-    $options: (i2) => resolveMergedOptions(i2),
-    $forceUpdate: (i2) => i2.f || (i2.f = () => {
-      i2.effect.dirty = true;
-      queueJob(i2.update);
-    }),
-    // $nextTick: i => i.n || (i.n = nextTick.bind(i.proxy!)),// fixed by xxxxxx
-    $watch: (i2) => instanceWatch.bind(i2)
-  })
-);
-const isReservedPrefix = (key) => key === "_" || key === "$";
-const hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn$1(state, key);
-const PublicInstanceProxyHandlers = {
-  get({ _: instance }, key) {
-    const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
-    if (key === "__isVue") {
-      return true;
-    }
-    let normalizedProps;
-    if (key[0] !== "$") {
-      const n2 = accessCache[key];
-      if (n2 !== void 0) {
-        switch (n2) {
-          case 1:
-            return setupState[key];
-          case 2:
-            return data[key];
-          case 4:
-            return ctx[key];
-          case 3:
-            return props[key];
-        }
-      } else if (hasSetupBinding(setupState, key)) {
-        accessCache[key] = 1;
-        return setupState[key];
-      } else if (data !== EMPTY_OBJ && hasOwn$1(data, key)) {
-        accessCache[key] = 2;
-        return data[key];
-      } else if (
-        // only cache other properties when instance has declared (thus stable)
-        // props
-        (normalizedProps = instance.propsOptions[0]) && hasOwn$1(normalizedProps, key)
-      ) {
-        accessCache[key] = 3;
-        return props[key];
-      } else if (ctx !== EMPTY_OBJ && hasOwn$1(ctx, key)) {
-        accessCache[key] = 4;
-        return ctx[key];
-      } else if (shouldCacheAccess) {
-        accessCache[key] = 0;
-      }
-    }
-    const publicGetter = publicPropertiesMap[key];
-    let cssModule, globalProperties;
-    if (publicGetter) {
-      if (key === "$attrs") {
-        track(instance, "get", key);
-      } else if (key === "$slots") {
-        track(instance, "get", key);
-      }
-      return publicGetter(instance);
-    } else if (
-      // css module (injected by vue-loader)
-      (cssModule = type.__cssModules) && (cssModule = cssModule[key])
-    ) {
-      return cssModule;
-    } else if (ctx !== EMPTY_OBJ && hasOwn$1(ctx, key)) {
-      accessCache[key] = 4;
-      return ctx[key];
-    } else if (
-      // global properties
-      globalProperties = appContext.config.globalProperties, hasOwn$1(globalProperties, key)
-    ) {
-      {
-        return globalProperties[key];
-      }
-    } else if (currentRenderingInstance && (!isString(key) || // #1091 avoid internal isRef/isVNode checks on component instance leading
-    // to infinite warning loop
-    key.indexOf("__v") !== 0)) {
-      if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn$1(data, key)) {
-        warn$1(
-          `Property ${JSON.stringify(
-            key
-          )} must be accessed via $data because it starts with a reserved character ("$" or "_") and is not proxied on the render context.`
-        );
-      } else if (instance === currentRenderingInstance) {
-        warn$1(
-          `Property ${JSON.stringify(key)} was accessed during render but is not defined on instance.`
-        );
-      }
-    }
-  },
-  set({ _: instance }, key, value) {
-    const { data, setupState, ctx } = instance;
-    if (hasSetupBinding(setupState, key)) {
-      setupState[key] = value;
-      return true;
-    } else if (setupState.__isScriptSetup && hasOwn$1(setupState, key)) {
-      warn$1(`Cannot mutate <script setup> binding "${key}" from Options API.`);
-      return false;
-    } else if (data !== EMPTY_OBJ && hasOwn$1(data, key)) {
-      data[key] = value;
-      return true;
-    } else if (hasOwn$1(instance.props, key)) {
-      warn$1(`Attempting to mutate prop "${key}". Props are readonly.`);
-      return false;
-    }
-    if (key[0] === "$" && key.slice(1) in instance) {
-      warn$1(
-        `Attempting to mutate public property "${key}". Properties starting with $ are reserved and readonly.`
-      );
-      return false;
-    } else {
-      if (key in instance.appContext.config.globalProperties) {
-        Object.defineProperty(ctx, key, {
-          enumerable: true,
-          configurable: true,
-          value
-        });
-      } else {
-        ctx[key] = value;
-      }
-    }
-    return true;
-  },
-  has({
-    _: { data, setupState, accessCache, ctx, appContext, propsOptions }
-  }, key) {
-    let normalizedProps;
-    return !!accessCache[key] || data !== EMPTY_OBJ && hasOwn$1(data, key) || hasSetupBinding(setupState, key) || (normalizedProps = propsOptions[0]) && hasOwn$1(normalizedProps, key) || hasOwn$1(ctx, key) || hasOwn$1(publicPropertiesMap, key) || hasOwn$1(appContext.config.globalProperties, key);
-  },
-  defineProperty(target, key, descriptor) {
-    if (descriptor.get != null) {
-      target._.accessCache[key] = 0;
-    } else if (hasOwn$1(descriptor, "value")) {
-      this.set(target, key, descriptor.value, null);
-    }
-    return Reflect.defineProperty(target, key, descriptor);
-  }
-};
-{
-  PublicInstanceProxyHandlers.ownKeys = (target) => {
-    warn$1(
-      `Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead.`
-    );
-    return Reflect.ownKeys(target);
-  };
-}
-function createDevRenderContext(instance) {
-  const target = {};
-  Object.defineProperty(target, `_`, {
-    configurable: true,
-    enumerable: false,
-    get: () => instance
-  });
-  Object.keys(publicPropertiesMap).forEach((key) => {
-    Object.defineProperty(target, key, {
-      configurable: true,
-      enumerable: false,
-      get: () => publicPropertiesMap[key](instance),
-      // intercepted by the proxy so no need for implementation,
-      // but needed to prevent set errors
-      set: NOOP
-    });
-  });
-  return target;
-}
-function exposePropsOnRenderContext(instance) {
-  const {
-    ctx,
-    propsOptions: [propsOptions]
-  } = instance;
-  if (propsOptions) {
-    Object.keys(propsOptions).forEach((key) => {
-      Object.defineProperty(ctx, key, {
-        enumerable: true,
-        configurable: true,
-        get: () => instance.props[key],
-        set: NOOP
-      });
-    });
-  }
-}
-function exposeSetupStateOnRenderContext(instance) {
-  const { ctx, setupState } = instance;
-  Object.keys(toRaw(setupState)).forEach((key) => {
-    if (!setupState.__isScriptSetup) {
-      if (isReservedPrefix(key[0])) {
-        warn$1(
-          `setup() return property ${JSON.stringify(
-            key
-          )} should not start with "$" or "_" which are reserved prefixes for Vue internals.`
-        );
-        return;
-      }
-      Object.defineProperty(ctx, key, {
-        enumerable: true,
-        configurable: true,
-        get: () => setupState[key],
-        set: NOOP
-      });
-    }
-  });
-}
-function normalizePropsOrEmits(props) {
-  return isArray(props) ? props.reduce(
-    (normalized, p2) => (normalized[p2] = null, normalized),
-    {}
-  ) : props;
-}
-function createDuplicateChecker() {
-  const cache = /* @__PURE__ */ Object.create(null);
-  return (type, key) => {
-    if (cache[key]) {
-      warn$1(`${type} property "${key}" is already defined in ${cache[key]}.`);
-    } else {
-      cache[key] = type;
-    }
-  };
-}
-let shouldCacheAccess = true;
-function applyOptions$1(instance) {
-  const options = resolveMergedOptions(instance);
-  const publicThis = instance.proxy;
-  const ctx = instance.ctx;
-  shouldCacheAccess = false;
-  if (options.beforeCreate) {
-    callHook$1(options.beforeCreate, instance, "bc");
-  }
-  const {
-    // state
-    data: dataOptions,
-    computed: computedOptions,
-    methods,
-    watch: watchOptions,
-    provide: provideOptions,
-    inject: injectOptions,
-    // lifecycle
-    created,
-    beforeMount,
-    mounted,
-    beforeUpdate,
-    updated,
-    activated,
-    deactivated,
-    beforeDestroy,
-    beforeUnmount,
-    destroyed,
-    unmounted,
-    render,
-    renderTracked,
-    renderTriggered,
-    errorCaptured,
-    serverPrefetch,
-    // public API
-    expose,
-    inheritAttrs,
-    // assets
-    components,
-    directives,
-    filters
-  } = options;
-  const checkDuplicateProperties = createDuplicateChecker();
-  {
-    const [propsOptions] = instance.propsOptions;
-    if (propsOptions) {
-      for (const key in propsOptions) {
-        checkDuplicateProperties("Props", key);
-      }
-    }
-  }
-  if (injectOptions) {
-    resolveInjections(injectOptions, ctx, checkDuplicateProperties);
-  }
-  if (methods) {
-    for (const key in methods) {
-      const methodHandler = methods[key];
-      if (isFunction(methodHandler)) {
-        {
-          Object.defineProperty(ctx, key, {
-            value: methodHandler.bind(publicThis),
-            configurable: true,
-            enumerable: true,
-            writable: true
-          });
-        }
-        {
-          checkDuplicateProperties("Methods", key);
-        }
-      } else {
-        warn$1(
-          `Method "${key}" has type "${typeof methodHandler}" in the component definition. Did you reference the function correctly?`
-        );
-      }
-    }
-  }
-  if (dataOptions) {
-    if (!isFunction(dataOptions)) {
-      warn$1(
-        `The data option must be a function. Plain object usage is no longer supported.`
-      );
-    }
-    const data = dataOptions.call(publicThis, publicThis);
-    if (isPromise(data)) {
-      warn$1(
-        `data() returned a Promise - note data() cannot be async; If you intend to perform data fetching before component renders, use async setup() + <Suspense>.`
-      );
-    }
-    if (!isObject$1(data)) {
-      warn$1(`data() should return an object.`);
-    } else {
-      instance.data = reactive(data);
-      {
-        for (const key in data) {
-          checkDuplicateProperties("Data", key);
-          if (!isReservedPrefix(key[0])) {
-            Object.defineProperty(ctx, key, {
-              configurable: true,
-              enumerable: true,
-              get: () => data[key],
-              set: NOOP
-            });
-          }
-        }
-      }
-    }
-  }
-  shouldCacheAccess = true;
-  if (computedOptions) {
-    for (const key in computedOptions) {
-      const opt = computedOptions[key];
-      const get2 = isFunction(opt) ? opt.bind(publicThis, publicThis) : isFunction(opt.get) ? opt.get.bind(publicThis, publicThis) : NOOP;
-      if (get2 === NOOP) {
-        warn$1(`Computed property "${key}" has no getter.`);
-      }
-      const set2 = !isFunction(opt) && isFunction(opt.set) ? opt.set.bind(publicThis) : () => {
-        warn$1(
-          `Write operation failed: computed property "${key}" is readonly.`
-        );
-      };
-      const c2 = computed({
-        get: get2,
-        set: set2
-      });
-      Object.defineProperty(ctx, key, {
-        enumerable: true,
-        configurable: true,
-        get: () => c2.value,
-        set: (v2) => c2.value = v2
-      });
-      {
-        checkDuplicateProperties("Computed", key);
-      }
-    }
-  }
-  if (watchOptions) {
-    for (const key in watchOptions) {
-      createWatcher(watchOptions[key], ctx, publicThis, key);
-    }
-  }
-  {
-    if (provideOptions) {
-      const provides = isFunction(provideOptions) ? provideOptions.call(publicThis) : provideOptions;
-      Reflect.ownKeys(provides).forEach((key) => {
-        provide(key, provides[key]);
-      });
-    }
-  }
-  {
-    if (created) {
-      callHook$1(created, instance, "c");
-    }
-  }
-  function registerLifecycleHook(register, hook) {
-    if (isArray(hook)) {
-      hook.forEach((_hook) => register(_hook.bind(publicThis)));
-    } else if (hook) {
-      register(hook.bind(publicThis));
-    }
-  }
-  registerLifecycleHook(onBeforeMount, beforeMount);
-  registerLifecycleHook(onMounted, mounted);
-  registerLifecycleHook(onBeforeUpdate, beforeUpdate);
-  registerLifecycleHook(onUpdated, updated);
-  registerLifecycleHook(onActivated, activated);
-  registerLifecycleHook(onDeactivated, deactivated);
-  registerLifecycleHook(onErrorCaptured, errorCaptured);
-  registerLifecycleHook(onRenderTracked, renderTracked);
-  registerLifecycleHook(onRenderTriggered, renderTriggered);
-  registerLifecycleHook(onBeforeUnmount, beforeUnmount);
-  registerLifecycleHook(onUnmounted, unmounted);
-  registerLifecycleHook(onServerPrefetch, serverPrefetch);
-  if (isArray(expose)) {
-    if (expose.length) {
-      const exposed = instance.exposed || (instance.exposed = {});
-      expose.forEach((key) => {
-        Object.defineProperty(exposed, key, {
-          get: () => publicThis[key],
-          set: (val) => publicThis[key] = val
-        });
-      });
-    } else if (!instance.exposed) {
-      instance.exposed = {};
-    }
-  }
-  if (render && instance.render === NOOP) {
-    instance.render = render;
-  }
-  if (inheritAttrs != null) {
-    instance.inheritAttrs = inheritAttrs;
-  }
-  if (components)
-    instance.components = components;
-  if (directives)
-    instance.directives = directives;
-  if (instance.ctx.$onApplyOptions) {
-    instance.ctx.$onApplyOptions(options, instance, publicThis);
-  }
-}
-function resolveInjections(injectOptions, ctx, checkDuplicateProperties = NOOP) {
-  if (isArray(injectOptions)) {
-    injectOptions = normalizeInject(injectOptions);
-  }
-  for (const key in injectOptions) {
-    const opt = injectOptions[key];
-    let injected;
-    if (isObject$1(opt)) {
-      if ("default" in opt) {
-        injected = inject(
-          opt.from || key,
-          opt.default,
-          true
-        );
-      } else {
-        injected = inject(opt.from || key);
-      }
-    } else {
-      injected = inject(opt);
-    }
-    if (isRef(injected)) {
-      Object.defineProperty(ctx, key, {
-        enumerable: true,
-        configurable: true,
-        get: () => injected.value,
-        set: (v2) => injected.value = v2
-      });
-    } else {
-      ctx[key] = injected;
-    }
-    {
-      checkDuplicateProperties("Inject", key);
-    }
-  }
-}
-function callHook$1(hook, instance, type) {
-  callWithAsyncErrorHandling(
-    isArray(hook) ? hook.map((h2) => h2.bind(instance.proxy)) : hook.bind(instance.proxy),
-    instance,
-    type
-  );
-}
-function createWatcher(raw, ctx, publicThis, key) {
-  const getter = key.includes(".") ? createPathGetter(publicThis, key) : () => publicThis[key];
-  if (isString(raw)) {
-    const handler = ctx[raw];
-    if (isFunction(handler)) {
-      watch(getter, handler);
-    } else {
-      warn$1(`Invalid watch handler specified by key "${raw}"`, handler);
-    }
-  } else if (isFunction(raw)) {
-    watch(getter, raw.bind(publicThis));
-  } else if (isObject$1(raw)) {
-    if (isArray(raw)) {
-      raw.forEach((r2) => createWatcher(r2, ctx, publicThis, key));
-    } else {
-      const handler = isFunction(raw.handler) ? raw.handler.bind(publicThis) : ctx[raw.handler];
-      if (isFunction(handler)) {
-        watch(getter, handler, raw);
-      } else {
-        warn$1(`Invalid watch handler specified by key "${raw.handler}"`, handler);
-      }
-    }
-  } else {
-    warn$1(`Invalid watch option: "${key}"`, raw);
-  }
-}
-function resolveMergedOptions(instance) {
-  const base = instance.type;
-  const { mixins, extends: extendsOptions } = base;
-  const {
-    mixins: globalMixins,
-    optionsCache: cache,
-    config: { optionMergeStrategies }
-  } = instance.appContext;
-  const cached = cache.get(base);
-  let resolved;
-  if (cached) {
-    resolved = cached;
-  } else if (!globalMixins.length && !mixins && !extendsOptions) {
-    {
-      resolved = base;
-    }
-  } else {
-    resolved = {};
-    if (globalMixins.length) {
-      globalMixins.forEach(
-        (m2) => mergeOptions(resolved, m2, optionMergeStrategies, true)
-      );
-    }
-    mergeOptions(resolved, base, optionMergeStrategies);
-  }
-  if (isObject$1(base)) {
-    cache.set(base, resolved);
-  }
-  return resolved;
-}
-function mergeOptions(to, from, strats, asMixin = false) {
-  const { mixins, extends: extendsOptions } = from;
-  if (extendsOptions) {
-    mergeOptions(to, extendsOptions, strats, true);
-  }
-  if (mixins) {
-    mixins.forEach(
-      (m2) => mergeOptions(to, m2, strats, true)
-    );
-  }
-  for (const key in from) {
-    if (asMixin && key === "expose") {
-      warn$1(
-        `"expose" option is ignored when declared in mixins or extends. It should only be declared in the base component itself.`
-      );
-    } else {
-      const strat = internalOptionMergeStrats[key] || strats && strats[key];
-      to[key] = strat ? strat(to[key], from[key]) : from[key];
-    }
-  }
-  return to;
-}
-const internalOptionMergeStrats = {
-  data: mergeDataFn,
-  props: mergeEmitsOrPropsOptions,
-  emits: mergeEmitsOrPropsOptions,
-  // objects
-  methods: mergeObjectOptions,
-  computed: mergeObjectOptions,
-  // lifecycle
-  beforeCreate: mergeAsArray$1,
-  created: mergeAsArray$1,
-  beforeMount: mergeAsArray$1,
-  mounted: mergeAsArray$1,
-  beforeUpdate: mergeAsArray$1,
-  updated: mergeAsArray$1,
-  beforeDestroy: mergeAsArray$1,
-  beforeUnmount: mergeAsArray$1,
-  destroyed: mergeAsArray$1,
-  unmounted: mergeAsArray$1,
-  activated: mergeAsArray$1,
-  deactivated: mergeAsArray$1,
-  errorCaptured: mergeAsArray$1,
-  serverPrefetch: mergeAsArray$1,
-  // assets
-  components: mergeObjectOptions,
-  directives: mergeObjectOptions,
-  // watch
-  watch: mergeWatchOptions,
-  // provide / inject
-  provide: mergeDataFn,
-  inject: mergeInject
-};
-function mergeDataFn(to, from) {
-  if (!from) {
-    return to;
-  }
-  if (!to) {
-    return from;
-  }
-  return function mergedDataFn() {
-    return extend(
-      isFunction(to) ? to.call(this, this) : to,
-      isFunction(from) ? from.call(this, this) : from
-    );
-  };
-}
-function mergeInject(to, from) {
-  return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
-}
-function normalizeInject(raw) {
-  if (isArray(raw)) {
-    const res = {};
-    for (let i2 = 0; i2 < raw.length; i2++) {
-      res[raw[i2]] = raw[i2];
-    }
-    return res;
-  }
-  return raw;
-}
-function mergeAsArray$1(to, from) {
-  return to ? [...new Set([].concat(to, from))] : from;
-}
-function mergeObjectOptions(to, from) {
-  return to ? extend(/* @__PURE__ */ Object.create(null), to, from) : from;
-}
-function mergeEmitsOrPropsOptions(to, from) {
-  if (to) {
-    if (isArray(to) && isArray(from)) {
-      return [.../* @__PURE__ */ new Set([...to, ...from])];
-    }
-    return extend(
-      /* @__PURE__ */ Object.create(null),
-      normalizePropsOrEmits(to),
-      normalizePropsOrEmits(from != null ? from : {})
-    );
-  } else {
-    return from;
-  }
-}
-function mergeWatchOptions(to, from) {
-  if (!to)
-    return from;
-  if (!from)
-    return to;
-  const merged = extend(/* @__PURE__ */ Object.create(null), to);
-  for (const key in from) {
-    merged[key] = mergeAsArray$1(to[key], from[key]);
-  }
-  return merged;
-}
-function initProps$1(instance, rawProps, isStateful, isSSR = false) {
-  const props = {};
-  const attrs = {};
-  instance.propsDefaults = /* @__PURE__ */ Object.create(null);
-  setFullProps(instance, rawProps, props, attrs);
-  for (const key in instance.propsOptions[0]) {
-    if (!(key in props)) {
-      props[key] = void 0;
-    }
-  }
-  {
-    validateProps(rawProps || {}, props, instance);
-  }
-  if (isStateful) {
-    instance.props = isSSR ? props : shallowReactive(props);
-  } else {
-    if (!instance.type.props) {
-      instance.props = attrs;
-    } else {
-      instance.props = props;
-    }
-  }
-  instance.attrs = attrs;
-}
-function isInHmrContext(instance) {
-  while (instance) {
-    if (instance.type.__hmrId)
-      return true;
-    instance = instance.parent;
-  }
-}
-function updateProps(instance, rawProps, rawPrevProps, optimized) {
-  const {
-    props,
-    attrs,
-    vnode: { patchFlag }
-  } = instance;
-  const rawCurrentProps = toRaw(props);
-  const [options] = instance.propsOptions;
-  let hasAttrsChanged = false;
-  if (
-    // always force full diff in dev
-    // - #1942 if hmr is enabled with sfc component
-    // - vite#872 non-sfc component used by sfc component
-    !isInHmrContext(instance) && (optimized || patchFlag > 0) && !(patchFlag & 16)
-  ) {
-    if (patchFlag & 8) {
-      const propsToUpdate = instance.vnode.dynamicProps;
-      for (let i2 = 0; i2 < propsToUpdate.length; i2++) {
-        let key = propsToUpdate[i2];
-        if (isEmitListener(instance.emitsOptions, key)) {
-          continue;
-        }
-        const value = rawProps[key];
-        if (options) {
-          if (hasOwn$1(attrs, key)) {
-            if (value !== attrs[key]) {
-              attrs[key] = value;
-              hasAttrsChanged = true;
-            }
-          } else {
-            const camelizedKey = camelize(key);
-            props[camelizedKey] = resolvePropValue(
-              options,
-              rawCurrentProps,
-              camelizedKey,
-              value,
-              instance,
-              false
-            );
-          }
-        } else {
-          if (value !== attrs[key]) {
-            attrs[key] = value;
-            hasAttrsChanged = true;
-          }
-        }
-      }
-    }
-  } else {
-    if (setFullProps(instance, rawProps, props, attrs)) {
-      hasAttrsChanged = true;
-    }
-    let kebabKey;
-    for (const key in rawCurrentProps) {
-      if (!rawProps || // for camelCase
-      !hasOwn$1(rawProps, key) && // it's possible the original props was passed in as kebab-case
-      // and converted to camelCase (#955)
-      ((kebabKey = hyphenate(key)) === key || !hasOwn$1(rawProps, kebabKey))) {
-        if (options) {
-          if (rawPrevProps && // for camelCase
-          (rawPrevProps[key] !== void 0 || // for kebab-case
-          rawPrevProps[kebabKey] !== void 0)) {
-            props[key] = resolvePropValue(
-              options,
-              rawCurrentProps,
-              key,
-              void 0,
-              instance,
-              true
-            );
-          }
-        } else {
-          delete props[key];
-        }
-      }
-    }
-    if (attrs !== rawCurrentProps) {
-      for (const key in attrs) {
-        if (!rawProps || !hasOwn$1(rawProps, key) && true) {
-          delete attrs[key];
-          hasAttrsChanged = true;
-        }
-      }
-    }
-  }
-  if (hasAttrsChanged) {
-    trigger(instance, "set", "$attrs");
-  }
-  {
-    validateProps(rawProps || {}, props, instance);
-  }
-}
-function setFullProps(instance, rawProps, props, attrs) {
-  const [options, needCastKeys] = instance.propsOptions;
-  let hasAttrsChanged = false;
-  let rawCastValues;
-  if (rawProps) {
-    for (let key in rawProps) {
-      if (isReservedProp(key)) {
-        continue;
-      }
-      const value = rawProps[key];
-      let camelKey;
-      if (options && hasOwn$1(options, camelKey = camelize(key))) {
-        if (!needCastKeys || !needCastKeys.includes(camelKey)) {
-          props[camelKey] = value;
-        } else {
-          (rawCastValues || (rawCastValues = {}))[camelKey] = value;
-        }
-      } else if (!isEmitListener(instance.emitsOptions, key)) {
-        if (!(key in attrs) || value !== attrs[key]) {
-          attrs[key] = value;
-          hasAttrsChanged = true;
-        }
-      }
-    }
-  }
-  if (needCastKeys) {
-    const rawCurrentProps = toRaw(props);
-    const castValues = rawCastValues || EMPTY_OBJ;
-    for (let i2 = 0; i2 < needCastKeys.length; i2++) {
-      const key = needCastKeys[i2];
-      props[key] = resolvePropValue(
-        options,
-        rawCurrentProps,
-        key,
-        castValues[key],
-        instance,
-        !hasOwn$1(castValues, key)
-      );
-    }
-  }
-  return hasAttrsChanged;
-}
-function resolvePropValue(options, props, key, value, instance, isAbsent) {
-  const opt = options[key];
-  if (opt != null) {
-    const hasDefault = hasOwn$1(opt, "default");
-    if (hasDefault && value === void 0) {
-      const defaultValue = opt.default;
-      if (opt.type !== Function && !opt.skipFactory && isFunction(defaultValue)) {
-        const { propsDefaults } = instance;
-        if (key in propsDefaults) {
-          value = propsDefaults[key];
-        } else {
-          const reset = setCurrentInstance(instance);
-          value = propsDefaults[key] = defaultValue.call(
-            null,
-            props
-          );
-          reset();
-        }
-      } else {
-        value = defaultValue;
-      }
-    }
-    if (opt[
-      0
-      /* shouldCast */
-    ]) {
-      if (isAbsent && !hasDefault) {
-        value = false;
-      } else if (opt[
-        1
-        /* shouldCastTrue */
-      ] && (value === "" || value === hyphenate(key))) {
-        value = true;
-      }
-    }
-  }
-  return value;
-}
-function normalizePropsOptions(comp, appContext, asMixin = false) {
-  const cache = appContext.propsCache;
-  const cached = cache.get(comp);
-  if (cached) {
-    return cached;
-  }
-  const raw = comp.props;
-  const normalized = {};
-  const needCastKeys = [];
-  let hasExtends = false;
-  if (!isFunction(comp)) {
-    const extendProps = (raw2) => {
-      hasExtends = true;
-      const [props, keys] = normalizePropsOptions(raw2, appContext, true);
-      extend(normalized, props);
-      if (keys)
-        needCastKeys.push(...keys);
-    };
-    if (!asMixin && appContext.mixins.length) {
-      appContext.mixins.forEach(extendProps);
-    }
-    if (comp.extends) {
-      extendProps(comp.extends);
-    }
-    if (comp.mixins) {
-      comp.mixins.forEach(extendProps);
-    }
-  }
-  if (!raw && !hasExtends) {
-    if (isObject$1(comp)) {
-      cache.set(comp, EMPTY_ARR);
-    }
-    return EMPTY_ARR;
-  }
-  if (isArray(raw)) {
-    for (let i2 = 0; i2 < raw.length; i2++) {
-      if (!isString(raw[i2])) {
-        warn$1(`props must be strings when using array syntax.`, raw[i2]);
-      }
-      const normalizedKey = camelize(raw[i2]);
-      if (validatePropName(normalizedKey)) {
-        normalized[normalizedKey] = EMPTY_OBJ;
-      }
-    }
-  } else if (raw) {
-    if (!isObject$1(raw)) {
-      warn$1(`invalid props options`, raw);
-    }
-    for (const key in raw) {
-      const normalizedKey = camelize(key);
-      if (validatePropName(normalizedKey)) {
-        const opt = raw[key];
-        const prop = normalized[normalizedKey] = isArray(opt) || isFunction(opt) ? { type: opt } : extend({}, opt);
-        if (prop) {
-          const booleanIndex = getTypeIndex(Boolean, prop.type);
-          const stringIndex = getTypeIndex(String, prop.type);
-          prop[
-            0
-            /* shouldCast */
-          ] = booleanIndex > -1;
-          prop[
-            1
-            /* shouldCastTrue */
-          ] = stringIndex < 0 || booleanIndex < stringIndex;
-          if (booleanIndex > -1 || hasOwn$1(prop, "default")) {
-            needCastKeys.push(normalizedKey);
-          }
-        }
-      }
-    }
-  }
-  const res = [normalized, needCastKeys];
-  if (isObject$1(comp)) {
-    cache.set(comp, res);
-  }
-  return res;
-}
-function validatePropName(key) {
-  if (key[0] !== "$" && !isReservedProp(key)) {
-    return true;
-  } else {
-    warn$1(`Invalid prop name: "${key}" is a reserved property.`);
-  }
-  return false;
-}
-function getType(ctor) {
-  if (ctor === null) {
-    return "null";
-  }
-  if (typeof ctor === "function") {
-    return ctor.name || "";
-  } else if (typeof ctor === "object") {
-    const name = ctor.constructor && ctor.constructor.name;
-    return name || "";
-  }
-  return "";
-}
-function isSameType(a2, b2) {
-  return getType(a2) === getType(b2);
-}
-function getTypeIndex(type, expectedTypes) {
-  if (isArray(expectedTypes)) {
-    return expectedTypes.findIndex((t2) => isSameType(t2, type));
-  } else if (isFunction(expectedTypes)) {
-    return isSameType(expectedTypes, type) ? 0 : -1;
-  }
-  return -1;
-}
-function validateProps(rawProps, props, instance) {
-  const resolvedValues = toRaw(props);
-  const options = instance.propsOptions[0];
-  for (const key in options) {
-    let opt = options[key];
-    if (opt == null)
-      continue;
-    validateProp(
-      key,
-      resolvedValues[key],
-      opt,
-      shallowReadonly(resolvedValues),
-      !hasOwn$1(rawProps, key) && !hasOwn$1(rawProps, hyphenate(key))
-    );
-  }
-}
-function validateProp(name, value, prop, props, isAbsent) {
-  const { type, required, validator, skipCheck } = prop;
-  if (required && isAbsent) {
-    warn$1('Missing required prop: "' + name + '"');
-    return;
-  }
-  if (value == null && !required) {
-    return;
-  }
-  if (type != null && type !== true && !skipCheck) {
-    let isValid = false;
-    const types = isArray(type) ? type : [type];
-    const expectedTypes = [];
-    for (let i2 = 0; i2 < types.length && !isValid; i2++) {
-      const { valid, expectedType } = assertType(value, types[i2]);
-      expectedTypes.push(expectedType || "");
-      isValid = valid;
-    }
-    if (!isValid) {
-      warn$1(getInvalidTypeMessage(name, value, expectedTypes));
-      return;
-    }
-  }
-  if (validator && !validator(value, props)) {
-    warn$1('Invalid prop: custom validator check failed for prop "' + name + '".');
-  }
-}
-const isSimpleType = /* @__PURE__ */ makeMap(
-  "String,Number,Boolean,Function,Symbol,BigInt"
-);
-function assertType(value, type) {
-  let valid;
-  const expectedType = getType(type);
-  if (isSimpleType(expectedType)) {
-    const t2 = typeof value;
-    valid = t2 === expectedType.toLowerCase();
-    if (!valid && t2 === "object") {
-      valid = value instanceof type;
-    }
-  } else if (expectedType === "Object") {
-    valid = isObject$1(value);
-  } else if (expectedType === "Array") {
-    valid = isArray(value);
-  } else if (expectedType === "null") {
-    valid = value === null;
-  } else {
-    valid = value instanceof type;
-  }
-  return {
-    valid,
-    expectedType
-  };
-}
-function getInvalidTypeMessage(name, value, expectedTypes) {
-  if (expectedTypes.length === 0) {
-    return `Prop type [] for prop "${name}" won't match anything. Did you mean to use type Array instead?`;
-  }
-  let message = `Invalid prop: type check failed for prop "${name}". Expected ${expectedTypes.map(capitalize).join(" | ")}`;
-  const expectedType = expectedTypes[0];
-  const receivedType = toRawType(value);
-  const expectedValue = styleValue(value, expectedType);
-  const receivedValue = styleValue(value, receivedType);
-  if (expectedTypes.length === 1 && isExplicable(expectedType) && !isBoolean(expectedType, receivedType)) {
-    message += ` with value ${expectedValue}`;
-  }
-  message += `, got ${receivedType} `;
-  if (isExplicable(receivedType)) {
-    message += `with value ${receivedValue}.`;
-  }
-  return message;
-}
-function styleValue(value, type) {
-  if (type === "String") {
-    return `"${value}"`;
-  } else if (type === "Number") {
-    return `${Number(value)}`;
-  } else {
-    return `${value}`;
-  }
-}
-function isExplicable(type) {
-  const explicitTypes = ["string", "number", "boolean"];
-  return explicitTypes.some((elem) => type.toLowerCase() === elem);
-}
-function isBoolean(...args) {
-  return args.some((elem) => elem.toLowerCase() === "boolean");
-}
-let supported;
-let perf;
-function startMeasure(instance, type) {
-  if (instance.appContext.config.performance && isSupported()) {
-    perf.mark(`vue-${type}-${instance.uid}`);
-  }
-  {
-    devtoolsPerfStart(instance, type, isSupported() ? perf.now() : Date.now());
-  }
-}
-function endMeasure(instance, type) {
-  if (instance.appContext.config.performance && isSupported()) {
-    const startTag = `vue-${type}-${instance.uid}`;
-    const endTag = startTag + `:end`;
-    perf.mark(endTag);
-    perf.measure(
-      `<${formatComponentName(instance, instance.type)}> ${type}`,
-      startTag,
-      endTag
-    );
-    perf.clearMarks(startTag);
-    perf.clearMarks(endTag);
-  }
-  {
-    devtoolsPerfEnd(instance, type, isSupported() ? perf.now() : Date.now());
-  }
-}
-function isSupported() {
-  if (supported !== void 0) {
-    return supported;
-  }
-  if (typeof window !== "undefined" && window.performance) {
-    supported = true;
-    perf = window.performance;
-  } else {
-    supported = false;
-  }
-  return supported;
-}
-const queuePostRenderEffect$1 = queuePostFlushCb;
-const Fragment = Symbol.for("v-fgt");
-const Text = Symbol.for("v-txt");
-const Comment = Symbol.for("v-cmt");
-const Static = Symbol.for("v-stc");
-function isVNode(value) {
-  return value ? value.__v_isVNode === true : false;
-}
-const InternalObjectKey = `__vInternal`;
-function guardReactiveProps(props) {
-  if (!props)
-    return null;
-  return isProxy(props) || InternalObjectKey in props ? extend({}, props) : props;
-}
-const emptyAppContext = createAppContext();
-let uid = 0;
-function createComponentInstance(vnode, parent, suspense) {
-  const type = vnode.type;
-  const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
-  const instance = {
-    uid: uid++,
-    vnode,
-    type,
-    parent,
-    appContext,
-    root: null,
-    // to be immediately set
-    next: null,
-    subTree: null,
-    // will be set synchronously right after creation
-    effect: null,
-    update: null,
-    // will be set synchronously right after creation
-    scope: new EffectScope(
-      true
-      /* detached */
-    ),
-    render: null,
-    proxy: null,
-    exposed: null,
-    exposeProxy: null,
-    withProxy: null,
-    provides: parent ? parent.provides : Object.create(appContext.provides),
-    accessCache: null,
-    renderCache: [],
-    // local resolved assets
-    components: null,
-    directives: null,
-    // resolved props and emits options
-    propsOptions: normalizePropsOptions(type, appContext),
-    emitsOptions: normalizeEmitsOptions(type, appContext),
-    // emit
-    emit: null,
-    // to be set immediately
-    emitted: null,
-    // props default value
-    propsDefaults: EMPTY_OBJ,
-    // inheritAttrs
-    inheritAttrs: type.inheritAttrs,
-    // state
-    ctx: EMPTY_OBJ,
-    data: EMPTY_OBJ,
-    props: EMPTY_OBJ,
-    attrs: EMPTY_OBJ,
-    slots: EMPTY_OBJ,
-    refs: EMPTY_OBJ,
-    setupState: EMPTY_OBJ,
-    setupContext: null,
-    attrsProxy: null,
-    slotsProxy: null,
-    // suspense related
-    suspense,
-    suspenseId: suspense ? suspense.pendingId : 0,
-    asyncDep: null,
-    asyncResolved: false,
-    // lifecycle hooks
-    // not using enums here because it results in computed properties
-    isMounted: false,
-    isUnmounted: false,
-    isDeactivated: false,
-    bc: null,
-    c: null,
-    bm: null,
-    m: null,
-    bu: null,
-    u: null,
-    um: null,
-    bum: null,
-    da: null,
-    a: null,
-    rtg: null,
-    rtc: null,
-    ec: null,
-    sp: null
-  };
-  {
-    instance.ctx = createDevRenderContext(instance);
-  }
-  instance.root = parent ? parent.root : instance;
-  instance.emit = emit.bind(null, instance);
-  if (vnode.ce) {
-    vnode.ce(instance);
-  }
-  return instance;
-}
-let currentInstance = null;
-const getCurrentInstance = () => currentInstance || currentRenderingInstance;
-let internalSetCurrentInstance;
-let setInSSRSetupState;
-{
-  internalSetCurrentInstance = (i2) => {
-    currentInstance = i2;
-  };
-  setInSSRSetupState = (v2) => {
-    isInSSRComponentSetup = v2;
-  };
-}
-const setCurrentInstance = (instance) => {
-  const prev = currentInstance;
-  internalSetCurrentInstance(instance);
-  instance.scope.on();
-  return () => {
-    instance.scope.off();
-    internalSetCurrentInstance(prev);
-  };
-};
-const unsetCurrentInstance = () => {
-  currentInstance && currentInstance.scope.off();
-  internalSetCurrentInstance(null);
-};
-const isBuiltInTag = /* @__PURE__ */ makeMap("slot,component");
-function validateComponentName(name, { isNativeTag }) {
-  if (isBuiltInTag(name) || isNativeTag(name)) {
-    warn$1(
-      "Do not use built-in or reserved HTML elements as component id: " + name
-    );
-  }
-}
-function isStatefulComponent(instance) {
-  return instance.vnode.shapeFlag & 4;
-}
-let isInSSRComponentSetup = false;
-function setupComponent(instance, isSSR = false) {
-  isSSR && setInSSRSetupState(isSSR);
-  const {
-    props
-    /*, children*/
-  } = instance.vnode;
-  const isStateful = isStatefulComponent(instance);
-  initProps$1(instance, props, isStateful, isSSR);
-  const setupResult = isStateful ? setupStatefulComponent(instance, isSSR) : void 0;
-  isSSR && setInSSRSetupState(false);
-  return setupResult;
-}
-function setupStatefulComponent(instance, isSSR) {
-  const Component2 = instance.type;
-  {
-    if (Component2.name) {
-      validateComponentName(Component2.name, instance.appContext.config);
-    }
-    if (Component2.components) {
-      const names = Object.keys(Component2.components);
-      for (let i2 = 0; i2 < names.length; i2++) {
-        validateComponentName(names[i2], instance.appContext.config);
-      }
-    }
-    if (Component2.directives) {
-      const names = Object.keys(Component2.directives);
-      for (let i2 = 0; i2 < names.length; i2++) {
-        validateDirectiveName(names[i2]);
-      }
-    }
-    if (Component2.compilerOptions && isRuntimeOnly()) {
-      warn$1(
-        `"compilerOptions" is only supported when using a build of Vue that includes the runtime compiler. Since you are using a runtime-only build, the options should be passed via your build tool config instead.`
-      );
-    }
-  }
-  instance.accessCache = /* @__PURE__ */ Object.create(null);
-  instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
-  {
-    exposePropsOnRenderContext(instance);
-  }
-  const { setup } = Component2;
-  if (setup) {
-    const setupContext = instance.setupContext = setup.length > 1 ? createSetupContext(instance) : null;
-    const reset = setCurrentInstance(instance);
-    pauseTracking();
-    const setupResult = callWithErrorHandling(
-      setup,
-      instance,
-      0,
-      [
-        shallowReadonly(instance.props),
-        setupContext
-      ]
-    );
-    resetTracking();
-    reset();
-    if (isPromise(setupResult)) {
-      setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
-      {
-        warn$1(
-          `setup() returned a Promise, but the version of Vue you are using does not support it yet.`
-        );
-      }
-    } else {
-      handleSetupResult(instance, setupResult, isSSR);
-    }
-  } else {
-    finishComponentSetup(instance, isSSR);
-  }
-}
-function handleSetupResult(instance, setupResult, isSSR) {
-  if (isFunction(setupResult)) {
-    {
-      instance.render = setupResult;
-    }
-  } else if (isObject$1(setupResult)) {
-    if (isVNode(setupResult)) {
-      warn$1(
-        `setup() should not return VNodes directly - return a render function instead.`
-      );
-    }
-    {
-      instance.devtoolsRawSetupState = setupResult;
-    }
-    instance.setupState = proxyRefs(setupResult);
-    {
-      exposeSetupStateOnRenderContext(instance);
-    }
-  } else if (setupResult !== void 0) {
-    warn$1(
-      `setup() should return an object. Received: ${setupResult === null ? "null" : typeof setupResult}`
-    );
-  }
-  finishComponentSetup(instance, isSSR);
-}
-let compile;
-const isRuntimeOnly = () => !compile;
-function finishComponentSetup(instance, isSSR, skipOptions) {
-  const Component2 = instance.type;
-  if (!instance.render) {
-    instance.render = Component2.render || NOOP;
-  }
-  {
-    const reset = setCurrentInstance(instance);
-    pauseTracking();
-    try {
-      applyOptions$1(instance);
-    } finally {
-      resetTracking();
-      reset();
-    }
-  }
-  if (!Component2.render && instance.render === NOOP && !isSSR) {
-    if (Component2.template) {
-      warn$1(
-        `Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".`
-      );
-    } else {
-      warn$1(`Component is missing template or render function.`);
-    }
-  }
-}
-function getAttrsProxy(instance) {
-  return instance.attrsProxy || (instance.attrsProxy = new Proxy(
-    instance.attrs,
-    {
-      get(target, key) {
-        track(instance, "get", "$attrs");
-        return target[key];
-      },
-      set() {
-        warn$1(`setupContext.attrs is readonly.`);
-        return false;
-      },
-      deleteProperty() {
-        warn$1(`setupContext.attrs is readonly.`);
-        return false;
-      }
-    }
-  ));
-}
-function getSlotsProxy(instance) {
-  return instance.slotsProxy || (instance.slotsProxy = new Proxy(instance.slots, {
-    get(target, key) {
-      track(instance, "get", "$slots");
-      return target[key];
-    }
-  }));
-}
-function createSetupContext(instance) {
-  const expose = (exposed) => {
-    {
-      if (instance.exposed) {
-        warn$1(`expose() should be called only once per setup().`);
-      }
-      if (exposed != null) {
-        let exposedType = typeof exposed;
-        if (exposedType === "object") {
-          if (isArray(exposed)) {
-            exposedType = "array";
-          } else if (isRef(exposed)) {
-            exposedType = "ref";
-          }
-        }
-        if (exposedType !== "object") {
-          warn$1(
-            `expose() should be passed a plain object, received ${exposedType}.`
-          );
-        }
-      }
-    }
-    instance.exposed = exposed || {};
-  };
-  {
-    return Object.freeze({
-      get attrs() {
-        return getAttrsProxy(instance);
-      },
-      get slots() {
-        return getSlotsProxy(instance);
-      },
-      get emit() {
-        return (event, ...args) => instance.emit(event, ...args);
-      },
-      expose
-    });
-  }
-}
-function getExposeProxy(instance) {
-  if (instance.exposed) {
-    return instance.exposeProxy || (instance.exposeProxy = new Proxy(proxyRefs(markRaw(instance.exposed)), {
-      get(target, key) {
-        if (key in target) {
-          return target[key];
-        }
-        return instance.proxy[key];
-      },
-      has(target, key) {
-        return key in target || key in publicPropertiesMap;
-      }
-    }));
-  }
-}
-const classifyRE = /(?:^|[-_])(\w)/g;
-const classify = (str) => str.replace(classifyRE, (c2) => c2.toUpperCase()).replace(/[-_]/g, "");
-function getComponentName(Component2, includeInferred = true) {
-  return isFunction(Component2) ? Component2.displayName || Component2.name : Component2.name || includeInferred && Component2.__name;
-}
-function formatComponentName(instance, Component2, isRoot = false) {
-  let name = getComponentName(Component2);
-  if (!name && Component2.__file) {
-    const match = Component2.__file.match(/([^/\\]+)\.\w+$/);
-    if (match) {
-      name = match[1];
-    }
-  }
-  if (!name && instance && instance.parent) {
-    const inferFromRegistry = (registry) => {
-      for (const key in registry) {
-        if (registry[key] === Component2) {
-          return key;
-        }
-      }
-    };
-    name = inferFromRegistry(
-      instance.components || instance.parent.type.components
-    ) || inferFromRegistry(instance.appContext.components);
-  }
-  return name ? classify(name) : isRoot ? `App` : `Anonymous`;
-}
-const computed = (getterOrOptions, debugOptions) => {
-  const c2 = computed$1(getterOrOptions, debugOptions, isInSSRComponentSetup);
-  {
-    const i2 = getCurrentInstance();
-    if (i2 && i2.appContext.config.warnRecursiveComputed) {
-      c2._warnRecursive = true;
-    }
-  }
-  return c2;
-};
-const version = "3.4.21";
-const warn = warn$1;
-function unwrapper(target) {
-  return unref(target);
-}
-const ARRAYTYPE = "[object Array]";
-const OBJECTTYPE = "[object Object]";
-function diff(current, pre) {
-  const result = {};
-  syncKeys(current, pre);
-  _diff(current, pre, "", result);
-  return result;
-}
-function syncKeys(current, pre) {
-  current = unwrapper(current);
-  if (current === pre)
-    return;
-  const rootCurrentType = toTypeString(current);
-  const rootPreType = toTypeString(pre);
-  if (rootCurrentType == OBJECTTYPE && rootPreType == OBJECTTYPE) {
-    for (let key in pre) {
-      const currentValue = current[key];
-      if (currentValue === void 0) {
-        current[key] = null;
-      } else {
-        syncKeys(currentValue, pre[key]);
-      }
-    }
-  } else if (rootCurrentType == ARRAYTYPE && rootPreType == ARRAYTYPE) {
-    if (current.length >= pre.length) {
-      pre.forEach((item, index2) => {
-        syncKeys(current[index2], item);
-      });
-    }
-  }
-}
-function _diff(current, pre, path, result) {
-  current = unwrapper(current);
-  if (current === pre)
-    return;
-  const rootCurrentType = toTypeString(current);
-  const rootPreType = toTypeString(pre);
-  if (rootCurrentType == OBJECTTYPE) {
-    if (rootPreType != OBJECTTYPE || Object.keys(current).length < Object.keys(pre).length) {
-      setResult(result, path, current);
-    } else {
-      for (let key in current) {
-        const currentValue = unwrapper(current[key]);
-        const preValue = pre[key];
-        const currentType = toTypeString(currentValue);
-        const preType = toTypeString(preValue);
-        if (currentType != ARRAYTYPE && currentType != OBJECTTYPE) {
-          if (currentValue != preValue) {
-            setResult(
-              result,
-              (path == "" ? "" : path + ".") + key,
-              currentValue
-            );
-          }
-        } else if (currentType == ARRAYTYPE) {
-          if (preType != ARRAYTYPE) {
-            setResult(
-              result,
-              (path == "" ? "" : path + ".") + key,
-              currentValue
-            );
-          } else {
-            if (currentValue.length < preValue.length) {
-              setResult(
-                result,
-                (path == "" ? "" : path + ".") + key,
-                currentValue
-              );
-            } else {
-              currentValue.forEach((item, index2) => {
-                _diff(
-                  item,
-                  preValue[index2],
-                  (path == "" ? "" : path + ".") + key + "[" + index2 + "]",
-                  result
-                );
-              });
-            }
-          }
-        } else if (currentType == OBJECTTYPE) {
-          if (preType != OBJECTTYPE || Object.keys(currentValue).length < Object.keys(preValue).length) {
-            setResult(
-              result,
-              (path == "" ? "" : path + ".") + key,
-              currentValue
-            );
-          } else {
-            for (let subKey in currentValue) {
-              _diff(
-                currentValue[subKey],
-                preValue[subKey],
-                (path == "" ? "" : path + ".") + key + "." + subKey,
-                result
-              );
-            }
-          }
-        }
-      }
-    }
-  } else if (rootCurrentType == ARRAYTYPE) {
-    if (rootPreType != ARRAYTYPE) {
-      setResult(result, path, current);
-    } else {
-      if (current.length < pre.length) {
-        setResult(result, path, current);
-      } else {
-        current.forEach((item, index2) => {
-          _diff(item, pre[index2], path + "[" + index2 + "]", result);
-        });
-      }
-    }
-  } else {
-    setResult(result, path, current);
-  }
-}
-function setResult(result, k, v2) {
-  result[k] = v2;
-}
-function hasComponentEffect(instance) {
-  return queue.includes(instance.update);
-}
-function flushCallbacks(instance) {
-  const ctx = instance.ctx;
-  const callbacks = ctx.__next_tick_callbacks;
-  if (callbacks && callbacks.length) {
-    const copies = callbacks.slice(0);
-    callbacks.length = 0;
-    for (let i2 = 0; i2 < copies.length; i2++) {
-      copies[i2]();
-    }
-  }
-}
-function nextTick(instance, fn) {
-  const ctx = instance.ctx;
-  if (!ctx.__next_tick_pending && !hasComponentEffect(instance)) {
-    return nextTick$1(fn && fn.bind(instance.proxy));
-  }
-  let _resolve;
-  if (!ctx.__next_tick_callbacks) {
-    ctx.__next_tick_callbacks = [];
-  }
-  ctx.__next_tick_callbacks.push(() => {
-    if (fn) {
-      callWithErrorHandling(
-        fn.bind(instance.proxy),
-        instance,
-        14
-      );
-    } else if (_resolve) {
-      _resolve(instance.proxy);
-    }
-  });
-  return new Promise((resolve2) => {
-    _resolve = resolve2;
-  });
-}
-function clone(src, seen) {
-  src = unwrapper(src);
-  const type = typeof src;
-  if (type === "object" && src !== null) {
-    let copy = seen.get(src);
-    if (typeof copy !== "undefined") {
-      return copy;
-    }
-    if (isArray(src)) {
-      const len = src.length;
-      copy = new Array(len);
-      seen.set(src, copy);
-      for (let i2 = 0; i2 < len; i2++) {
-        copy[i2] = clone(src[i2], seen);
-      }
-    } else {
-      copy = {};
-      seen.set(src, copy);
-      for (const name in src) {
-        if (hasOwn$1(src, name)) {
-          copy[name] = clone(src[name], seen);
-        }
-      }
-    }
-    return copy;
-  }
-  if (type !== "symbol") {
-    return src;
-  }
-}
-function deepCopy(src) {
-  return clone(src, typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : /* @__PURE__ */ new Map());
-}
-function getMPInstanceData(instance, keys) {
-  const data = instance.data;
-  const ret = /* @__PURE__ */ Object.create(null);
-  keys.forEach((key) => {
-    ret[key] = data[key];
-  });
-  return ret;
-}
-function patch(instance, data, oldData) {
-  if (!data) {
-    return;
-  }
-  data = deepCopy(data);
-  const ctx = instance.ctx;
-  const mpType = ctx.mpType;
-  if (mpType === "page" || mpType === "component") {
-    data.r0 = 1;
-    const mpInstance = ctx.$scope;
-    const keys = Object.keys(data);
-    const diffData = diff(data, oldData || getMPInstanceData(mpInstance, keys));
-    if (Object.keys(diffData).length) {
-      ctx.__next_tick_pending = true;
-      mpInstance.setData(diffData, () => {
-        ctx.__next_tick_pending = false;
-        flushCallbacks(instance);
-      });
-      flushPreFlushCbs();
-    } else {
-      flushCallbacks(instance);
-    }
-  }
-}
-function initAppConfig(appConfig) {
-  appConfig.globalProperties.$nextTick = function $nextTick(fn) {
-    return nextTick(this.$, fn);
-  };
-}
-function onApplyOptions(options, instance, publicThis) {
-  instance.appContext.config.globalProperties.$applyOptions(
-    options,
-    instance,
-    publicThis
-  );
-  const computedOptions = options.computed;
-  if (computedOptions) {
-    const keys = Object.keys(computedOptions);
-    if (keys.length) {
-      const ctx = instance.ctx;
-      if (!ctx.$computedKeys) {
-        ctx.$computedKeys = [];
-      }
-      ctx.$computedKeys.push(...keys);
-    }
-  }
-  delete instance.ctx.$onApplyOptions;
-}
-function setRef$1(instance, isUnmount = false) {
-  const {
-    setupState,
-    $templateRefs,
-    ctx: { $scope, $mpPlatform }
-  } = instance;
-  if ($mpPlatform === "mp-alipay") {
-    return;
-  }
-  if (!$templateRefs || !$scope) {
-    return;
-  }
-  if (isUnmount) {
-    return $templateRefs.forEach(
-      (templateRef) => setTemplateRef(templateRef, null, setupState)
-    );
-  }
-  const check = $mpPlatform === "mp-baidu" || $mpPlatform === "mp-toutiao";
-  const doSetByRefs = (refs) => {
-    const mpComponents = (
-      // 字节小程序 selectAllComponents 可能返回 null
-      // https://github.com/dcloudio/uni-app/issues/3954
-      ($scope.selectAllComponents(".r") || []).concat(
-        $scope.selectAllComponents(".r-i-f") || []
-      )
-    );
-    return refs.filter((templateRef) => {
-      const refValue = findComponentPublicInstance(mpComponents, templateRef.i);
-      if (check && refValue === null) {
-        return true;
-      }
-      setTemplateRef(templateRef, refValue, setupState);
-      return false;
-    });
-  };
-  const doSet = () => {
-    const refs = doSetByRefs($templateRefs);
-    if (refs.length && instance.proxy && instance.proxy.$scope) {
-      instance.proxy.$scope.setData({ r1: 1 }, () => {
-        doSetByRefs(refs);
-      });
-    }
-  };
-  if ($scope._$setRef) {
-    $scope._$setRef(doSet);
-  } else {
-    nextTick(instance, doSet);
-  }
-}
-function toSkip(value) {
-  if (isObject$1(value)) {
-    markRaw(value);
-  }
-  return value;
-}
-function findComponentPublicInstance(mpComponents, id) {
-  const mpInstance = mpComponents.find(
-    (com) => com && (com.properties || com.props).uI === id
-  );
-  if (mpInstance) {
-    const vm = mpInstance.$vm;
-    if (vm) {
-      return getExposeProxy(vm.$) || vm;
-    }
-    return toSkip(mpInstance);
-  }
-  return null;
-}
-function setTemplateRef({ r: r2, f: f2 }, refValue, setupState) {
-  if (isFunction(r2)) {
-    r2(refValue, {});
-  } else {
-    const _isString = isString(r2);
-    const _isRef = isRef(r2);
-    if (_isString || _isRef) {
-      if (f2) {
-        if (!_isRef) {
-          return;
-        }
-        if (!isArray(r2.value)) {
-          r2.value = [];
-        }
-        const existing = r2.value;
-        if (existing.indexOf(refValue) === -1) {
-          existing.push(refValue);
-          if (!refValue) {
-            return;
-          }
-          onBeforeUnmount(() => remove(existing, refValue), refValue.$);
-        }
-      } else if (_isString) {
-        if (hasOwn$1(setupState, r2)) {
-          setupState[r2] = refValue;
-        }
-      } else if (isRef(r2)) {
-        r2.value = refValue;
-      } else {
-        warnRef(r2);
-      }
-    } else {
-      warnRef(r2);
-    }
-  }
-}
-function warnRef(ref2) {
-  warn("Invalid template ref type:", ref2, `(${typeof ref2})`);
-}
-const queuePostRenderEffect = queuePostFlushCb;
-function mountComponent(initialVNode, options) {
-  const instance = initialVNode.component = createComponentInstance(initialVNode, options.parentComponent, null);
-  {
-    instance.ctx.$onApplyOptions = onApplyOptions;
-    instance.ctx.$children = [];
-  }
-  if (options.mpType === "app") {
-    instance.render = NOOP;
-  }
-  if (options.onBeforeSetup) {
-    options.onBeforeSetup(instance, options);
-  }
-  {
-    pushWarningContext(initialVNode);
-    startMeasure(instance, `mount`);
-  }
-  {
-    startMeasure(instance, `init`);
-  }
-  setupComponent(instance);
-  {
-    endMeasure(instance, `init`);
-  }
-  {
-    if (options.parentComponent && instance.proxy) {
-      options.parentComponent.ctx.$children.push(getExposeProxy(instance) || instance.proxy);
-    }
-  }
-  setupRenderEffect(instance);
-  {
-    popWarningContext();
-    endMeasure(instance, `mount`);
-  }
-  return instance.proxy;
-}
-const getFunctionalFallthrough = (attrs) => {
-  let res;
-  for (const key in attrs) {
-    if (key === "class" || key === "style" || isOn(key)) {
-      (res || (res = {}))[key] = attrs[key];
-    }
-  }
-  return res;
-};
-function renderComponentRoot(instance) {
-  const {
-    type: Component2,
-    vnode,
-    proxy,
-    withProxy,
-    props,
-    propsOptions: [propsOptions],
-    slots,
-    attrs,
-    emit: emit2,
-    render,
-    renderCache,
-    data,
-    setupState,
-    ctx,
-    uid: uid2,
-    appContext: {
-      app: {
-        config: {
-          globalProperties: { pruneComponentPropsCache: pruneComponentPropsCache2 }
-        }
-      }
-    },
-    inheritAttrs
-  } = instance;
-  instance.$templateRefs = [];
-  instance.$ei = 0;
-  pruneComponentPropsCache2(uid2);
-  instance.__counter = instance.__counter === 0 ? 1 : 0;
-  let result;
-  const prev = setCurrentRenderingInstance(instance);
-  try {
-    if (vnode.shapeFlag & 4) {
-      fallthroughAttrs(inheritAttrs, props, propsOptions, attrs);
-      const proxyToUse = withProxy || proxy;
-      result = render.call(
-        proxyToUse,
-        proxyToUse,
-        renderCache,
-        props,
-        setupState,
-        data,
-        ctx
-      );
-    } else {
-      fallthroughAttrs(
-        inheritAttrs,
-        props,
-        propsOptions,
-        Component2.props ? attrs : getFunctionalFallthrough(attrs)
-      );
-      const render2 = Component2;
-      result = render2.length > 1 ? render2(props, { attrs, slots, emit: emit2 }) : render2(
-        props,
-        null
-        /* we know it doesn't need it */
-      );
-    }
-  } catch (err) {
-    handleError(err, instance, 1);
-    result = false;
-  }
-  setRef$1(instance);
-  setCurrentRenderingInstance(prev);
-  return result;
-}
-function fallthroughAttrs(inheritAttrs, props, propsOptions, fallthroughAttrs2) {
-  if (props && fallthroughAttrs2 && inheritAttrs !== false) {
-    const keys = Object.keys(fallthroughAttrs2).filter(
-      (key) => key !== "class" && key !== "style"
-    );
-    if (!keys.length) {
-      return;
-    }
-    if (propsOptions && keys.some(isModelListener)) {
-      keys.forEach((key) => {
-        if (!isModelListener(key) || !(key.slice(9) in propsOptions)) {
-          props[key] = fallthroughAttrs2[key];
-        }
-      });
-    } else {
-      keys.forEach((key) => props[key] = fallthroughAttrs2[key]);
-    }
-  }
-}
-const updateComponentPreRender = (instance) => {
-  pauseTracking();
-  flushPreFlushCbs();
-  resetTracking();
-};
-function componentUpdateScopedSlotsFn() {
-  const scopedSlotsData = this.$scopedSlotsData;
-  if (!scopedSlotsData || scopedSlotsData.length === 0) {
-    return;
-  }
-  const mpInstance = this.ctx.$scope;
-  const oldData = mpInstance.data;
-  const diffData = /* @__PURE__ */ Object.create(null);
-  scopedSlotsData.forEach(({ path, index: index2, data }) => {
-    const oldScopedSlotData = getValueByDataPath(oldData, path);
-    const diffPath = isString(index2) ? `${path}.${index2}` : `${path}[${index2}]`;
-    if (typeof oldScopedSlotData === "undefined" || typeof oldScopedSlotData[index2] === "undefined") {
-      diffData[diffPath] = data;
-    } else {
-      const diffScopedSlotData = diff(
-        data,
-        oldScopedSlotData[index2]
-      );
-      Object.keys(diffScopedSlotData).forEach((name) => {
-        diffData[diffPath + "." + name] = diffScopedSlotData[name];
-      });
-    }
-  });
-  scopedSlotsData.length = 0;
-  if (Object.keys(diffData).length) {
-    mpInstance.setData(diffData);
-  }
-}
-function toggleRecurse({ effect: effect2, update }, allowed) {
-  effect2.allowRecurse = update.allowRecurse = allowed;
-}
-function setupRenderEffect(instance) {
-  const updateScopedSlots = componentUpdateScopedSlotsFn.bind(
-    instance
-  );
-  instance.$updateScopedSlots = () => nextTick$1(() => queueJob(updateScopedSlots));
-  const componentUpdateFn = () => {
-    if (!instance.isMounted) {
-      onBeforeUnmount(() => {
-        setRef$1(instance, true);
-      }, instance);
-      {
-        startMeasure(instance, `patch`);
-      }
-      patch(instance, renderComponentRoot(instance));
-      {
-        endMeasure(instance, `patch`);
-      }
-      {
-        devtoolsComponentAdded(instance);
-      }
-    } else {
-      const { next, bu, u: u2 } = instance;
-      {
-        pushWarningContext(next || instance.vnode);
-      }
-      toggleRecurse(instance, false);
-      updateComponentPreRender();
-      if (bu) {
-        invokeArrayFns$1(bu);
-      }
-      toggleRecurse(instance, true);
-      {
-        startMeasure(instance, `patch`);
-      }
-      patch(instance, renderComponentRoot(instance));
-      {
-        endMeasure(instance, `patch`);
-      }
-      if (u2) {
-        queuePostRenderEffect(u2);
-      }
-      {
-        devtoolsComponentUpdated(instance);
-      }
-      {
-        popWarningContext();
-      }
-    }
-  };
-  const effect2 = instance.effect = new ReactiveEffect2(
-    componentUpdateFn,
-    NOOP,
-    () => queueJob(update),
-    instance.scope
-    // track it in component's effect scope
-  );
-  const update = instance.update = () => {
-    if (effect2.dirty) {
-      effect2.run();
-    }
-  };
-  update.id = instance.uid;
-  toggleRecurse(instance, true);
-  {
-    effect2.onTrack = instance.rtc ? (e2) => invokeArrayFns$1(instance.rtc, e2) : void 0;
-    effect2.onTrigger = instance.rtg ? (e2) => invokeArrayFns$1(instance.rtg, e2) : void 0;
-    update.ownerInstance = instance;
-  }
-  update();
-}
-function unmountComponent(instance) {
-  const { bum, scope, update, um } = instance;
-  if (bum) {
-    invokeArrayFns$1(bum);
-  }
-  scope.stop();
-  if (update) {
-    update.active = false;
-  }
-  if (um) {
-    queuePostRenderEffect(um);
-  }
-  queuePostRenderEffect(() => {
-    instance.isUnmounted = true;
-  });
-  {
-    devtoolsComponentRemoved(instance);
-  }
-}
-const oldCreateApp = createAppAPI();
-function getTarget() {
-  if (typeof window !== "undefined") {
-    return window;
-  }
-  if (typeof globalThis !== "undefined") {
-    return globalThis;
-  }
-  if (typeof global !== "undefined") {
-    return global;
-  }
-  if (typeof my !== "undefined") {
-    return my;
-  }
-}
-function createVueApp(rootComponent, rootProps = null) {
-  const target = getTarget();
-  target.__VUE__ = true;
-  {
-    setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__, target);
-  }
-  const app = oldCreateApp(rootComponent, rootProps);
-  const appContext = app._context;
-  initAppConfig(appContext.config);
-  const createVNode2 = (initialVNode) => {
-    initialVNode.appContext = appContext;
-    initialVNode.shapeFlag = 6;
-    return initialVNode;
-  };
-  const createComponent2 = function createComponent22(initialVNode, options) {
-    return mountComponent(createVNode2(initialVNode), options);
-  };
-  const destroyComponent = function destroyComponent2(component) {
-    return component && unmountComponent(component.$);
-  };
-  app.mount = function mount() {
-    rootComponent.render = NOOP;
-    const instance = mountComponent(
-      createVNode2({ type: rootComponent }),
-      {
-        mpType: "app",
-        mpInstance: null,
-        parentComponent: null,
-        slots: [],
-        props: null
-      }
-    );
-    app._instance = instance.$;
-    {
-      devtoolsInitApp(app, version);
-    }
-    instance.$app = app;
-    instance.$createComponent = createComponent2;
-    instance.$destroyComponent = destroyComponent;
-    appContext.$appInstance = instance;
-    return instance;
-  };
-  app.unmount = function unmount() {
-    warn(`Cannot unmount an app.`);
-  };
-  return app;
-}
-function injectLifecycleHook(name, hook, publicThis, instance) {
-  if (isFunction(hook)) {
-    injectHook(name, hook.bind(publicThis), instance);
-  }
-}
-function initHooks$1(options, instance, publicThis) {
-  const mpType = options.mpType || publicThis.$mpType;
-  if (!mpType || mpType === "component") {
-    return;
-  }
-  Object.keys(options).forEach((name) => {
-    if (isUniLifecycleHook(name, options[name], false)) {
-      const hooks = options[name];
-      if (isArray(hooks)) {
-        hooks.forEach((hook) => injectLifecycleHook(name, hook, publicThis, instance));
-      } else {
-        injectLifecycleHook(name, hooks, publicThis, instance);
-      }
-    }
-  });
-}
-function applyOptions$2(options, instance, publicThis) {
-  initHooks$1(options, instance, publicThis);
-}
-function set(target, key, val) {
-  return target[key] = val;
-}
-function $callMethod(method, ...args) {
-  const fn = this[method];
-  if (fn) {
-    return fn(...args);
-  }
-  console.error(`method ${method} not found`);
-  return null;
-}
-function createErrorHandler(app) {
-  return function errorHandler(err, instance, _info) {
-    if (!instance) {
-      throw err;
-    }
-    const appInstance = app._instance;
-    if (!appInstance || !appInstance.proxy) {
-      throw err;
-    }
-    {
-      appInstance.proxy.$callHook(ON_ERROR, err);
-    }
-  };
-}
-function mergeAsArray(to, from) {
-  return to ? [...new Set([].concat(to, from))] : from;
-}
-function initOptionMergeStrategies(optionMergeStrategies) {
-  UniLifecycleHooks.forEach((name) => {
-    optionMergeStrategies[name] = mergeAsArray;
-  });
-}
-let realAtob;
-const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/;
-if (typeof atob !== "function") {
-  realAtob = function(str) {
-    str = String(str).replace(/[\t\n\f\r ]+/g, "");
-    if (!b64re.test(str)) {
-      throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
-    }
-    str += "==".slice(2 - (str.length & 3));
-    var bitmap;
-    var result = "";
-    var r1;
-    var r2;
-    var i2 = 0;
-    for (; i2 < str.length; ) {
-      bitmap = b64.indexOf(str.charAt(i2++)) << 18 | b64.indexOf(str.charAt(i2++)) << 12 | (r1 = b64.indexOf(str.charAt(i2++))) << 6 | (r2 = b64.indexOf(str.charAt(i2++)));
-      result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
-    }
-    return result;
-  };
-} else {
-  realAtob = atob;
-}
-function b64DecodeUnicode(str) {
-  return decodeURIComponent(realAtob(str).split("").map(function(c2) {
-    return "%" + ("00" + c2.charCodeAt(0).toString(16)).slice(-2);
-  }).join(""));
-}
-function getCurrentUserInfo() {
-  const token = index.getStorageSync("uni_id_token") || "";
-  const tokenArr = token.split(".");
-  if (!token || tokenArr.length !== 3) {
-    return {
-      uid: null,
-      role: [],
-      permission: [],
-      tokenExpired: 0
-    };
-  }
-  let userInfo;
-  try {
-    userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1]));
-  } catch (error) {
-    throw new Error("获取当前用户信息出错,详细错误信息为:" + error.message);
-  }
-  userInfo.tokenExpired = userInfo.exp * 1e3;
-  delete userInfo.exp;
-  delete userInfo.iat;
-  return userInfo;
-}
-function uniIdMixin(globalProperties) {
-  globalProperties.uniIDHasRole = function(roleId) {
-    const { role } = getCurrentUserInfo();
-    return role.indexOf(roleId) > -1;
-  };
-  globalProperties.uniIDHasPermission = function(permissionId) {
-    const { permission } = getCurrentUserInfo();
-    return this.uniIDHasRole("admin") || permission.indexOf(permissionId) > -1;
-  };
-  globalProperties.uniIDTokenValid = function() {
-    const { tokenExpired } = getCurrentUserInfo();
-    return tokenExpired > Date.now();
-  };
-}
-function initApp(app) {
-  const appConfig = app._context.config;
-  appConfig.errorHandler = invokeCreateErrorHandler(app, createErrorHandler);
-  initOptionMergeStrategies(appConfig.optionMergeStrategies);
-  const globalProperties = appConfig.globalProperties;
-  {
-    uniIdMixin(globalProperties);
-  }
-  {
-    globalProperties.$set = set;
-    globalProperties.$applyOptions = applyOptions$2;
-    globalProperties.$callMethod = $callMethod;
-  }
-  {
-    index.invokeCreateVueAppHook(app);
-  }
-}
-const propsCaches = /* @__PURE__ */ Object.create(null);
-function renderProps(props) {
-  const { uid: uid2, __counter } = getCurrentInstance();
-  const propsId = (propsCaches[uid2] || (propsCaches[uid2] = [])).push(guardReactiveProps(props)) - 1;
-  return uid2 + "," + propsId + "," + __counter;
-}
-function pruneComponentPropsCache(uid2) {
-  delete propsCaches[uid2];
-}
-function findComponentPropsData(up) {
-  if (!up) {
-    return;
-  }
-  const [uid2, propsId] = up.split(",");
-  if (!propsCaches[uid2]) {
-    return;
-  }
-  return propsCaches[uid2][parseInt(propsId)];
-}
-var plugin = {
-  install(app) {
-    initApp(app);
-    app.config.globalProperties.pruneComponentPropsCache = pruneComponentPropsCache;
-    const oldMount = app.mount;
-    app.mount = function mount(rootContainer) {
-      const instance = oldMount.call(app, rootContainer);
-      const createApp2 = getCreateApp();
-      if (createApp2) {
-        createApp2(instance);
-      } else {
-        if (typeof createMiniProgramApp !== "undefined") {
-          createMiniProgramApp(instance);
-        }
-      }
-      return instance;
-    };
-  }
-};
-function getCreateApp() {
-  const method = "createApp";
-  if (typeof global !== "undefined" && typeof global[method] !== "undefined") {
-    return global[method];
-  } else if (typeof my !== "undefined") {
-    return my[method];
-  }
-}
-function vOn(value, key) {
-  const instance = getCurrentInstance();
-  const ctx = instance.ctx;
-  const extraKey = typeof key !== "undefined" && (ctx.$mpPlatform === "mp-weixin" || ctx.$mpPlatform === "mp-qq" || ctx.$mpPlatform === "mp-xhs") && (isString(key) || typeof key === "number") ? "_" + key : "";
-  const name = "e" + instance.$ei++ + extraKey;
-  const mpInstance = ctx.$scope;
-  if (!value) {
-    delete mpInstance[name];
-    return name;
-  }
-  const existingInvoker = mpInstance[name];
-  if (existingInvoker) {
-    existingInvoker.value = value;
-  } else {
-    mpInstance[name] = createInvoker(value, instance);
-  }
-  return name;
-}
-function createInvoker(initialValue, instance) {
-  const invoker = (e2) => {
-    patchMPEvent(e2);
-    let args = [e2];
-    if (e2.detail && e2.detail.__args__) {
-      args = e2.detail.__args__;
-    }
-    const eventValue = invoker.value;
-    const invoke = () => callWithAsyncErrorHandling(patchStopImmediatePropagation(e2, eventValue), instance, 5, args);
-    const eventTarget = e2.target;
-    const eventSync = eventTarget ? eventTarget.dataset ? String(eventTarget.dataset.eventsync) === "true" : false : false;
-    if (bubbles.includes(e2.type) && !eventSync) {
-      setTimeout(invoke);
-    } else {
-      const res = invoke();
-      if (e2.type === "input" && (isArray(res) || isPromise(res))) {
-        return;
-      }
-      return res;
-    }
-  };
-  invoker.value = initialValue;
-  return invoker;
-}
-const bubbles = [
-  // touch事件暂不做延迟,否则在 Android 上会影响性能,比如一些拖拽跟手手势等
-  // 'touchstart',
-  // 'touchmove',
-  // 'touchcancel',
-  // 'touchend',
-  "tap",
-  "longpress",
-  "longtap",
-  "transitionend",
-  "animationstart",
-  "animationiteration",
-  "animationend",
-  "touchforcechange"
-];
-function patchMPEvent(event) {
-  if (event.type && event.target) {
-    event.preventDefault = NOOP;
-    event.stopPropagation = NOOP;
-    event.stopImmediatePropagation = NOOP;
-    if (!hasOwn$1(event, "detail")) {
-      event.detail = {};
-    }
-    if (hasOwn$1(event, "markerId")) {
-      event.detail = typeof event.detail === "object" ? event.detail : {};
-      event.detail.markerId = event.markerId;
-    }
-    if (isPlainObject(event.detail) && hasOwn$1(event.detail, "checked") && !hasOwn$1(event.detail, "value")) {
-      event.detail.value = event.detail.checked;
-    }
-    if (isPlainObject(event.detail)) {
-      event.target = extend({}, event.target, event.detail);
-    }
-  }
-}
-function patchStopImmediatePropagation(e2, value) {
-  if (isArray(value)) {
-    const originalStop = e2.stopImmediatePropagation;
-    e2.stopImmediatePropagation = () => {
-      originalStop && originalStop.call(e2);
-      e2._stopped = true;
-    };
-    return value.map((fn) => (e3) => !e3._stopped && fn(e3));
-  } else {
-    return value;
-  }
-}
-function vFor(source, renderItem) {
-  let ret;
-  if (isArray(source) || isString(source)) {
-    ret = new Array(source.length);
-    for (let i2 = 0, l2 = source.length; i2 < l2; i2++) {
-      ret[i2] = renderItem(source[i2], i2, i2);
-    }
-  } else if (typeof source === "number") {
-    if (!Number.isInteger(source)) {
-      warn(`The v-for range expect an integer value but got ${source}.`);
-      return [];
-    }
-    ret = new Array(source);
-    for (let i2 = 0; i2 < source; i2++) {
-      ret[i2] = renderItem(i2 + 1, i2, i2);
-    }
-  } else if (isObject$1(source)) {
-    if (source[Symbol.iterator]) {
-      ret = Array.from(source, (item, i2) => renderItem(item, i2, i2));
-    } else {
-      const keys = Object.keys(source);
-      ret = new Array(keys.length);
-      for (let i2 = 0, l2 = keys.length; i2 < l2; i2++) {
-        const key = keys[i2];
-        ret[i2] = renderItem(source[key], key, i2);
-      }
-    }
-  } else {
-    ret = [];
-  }
-  return ret;
-}
-function stringifyStyle(value) {
-  if (isString(value)) {
-    return value;
-  }
-  return stringify(normalizeStyle(value));
-}
-function stringify(styles) {
-  let ret = "";
-  if (!styles || isString(styles)) {
-    return ret;
-  }
-  for (const key in styles) {
-    ret += `${key.startsWith(`--`) ? key : hyphenate(key)}:${styles[key]};`;
-  }
-  return ret;
-}
-function setRef(ref2, id, opts = {}) {
-  const { $templateRefs } = getCurrentInstance();
-  $templateRefs.push({ i: id, r: ref2, k: opts.k, f: opts.f });
-}
-const o$1 = (value, key) => vOn(value, key);
-const f$1 = (source, renderItem) => vFor(source, renderItem);
-const s$1 = (value) => stringifyStyle(value);
-const e$1 = (target, ...sources) => extend(target, ...sources);
-const n$1 = (value) => normalizeClass(value);
-const t$1 = (val) => toDisplayString(val);
-const p$1 = (props) => renderProps(props);
-const sr = (ref2, id, opts) => setRef(ref2, id, opts);
-function createApp$1(rootComponent, rootProps = null) {
-  rootComponent && (rootComponent.mpType = "app");
-  return createVueApp(rootComponent, rootProps).use(plugin);
-}
-const createSSRApp = createApp$1;
-const MP_METHODS = [
-  "createSelectorQuery",
-  "createIntersectionObserver",
-  "selectAllComponents",
-  "selectComponent"
-];
-function createEmitFn(oldEmit, ctx) {
-  return function emit2(event, ...args) {
-    const scope = ctx.$scope;
-    if (scope && event) {
-      const detail = { __args__: args };
-      {
-        scope.triggerEvent(event, detail);
-      }
-    }
-    return oldEmit.apply(this, [event, ...args]);
-  };
-}
-function initBaseInstance(instance, options) {
-  const ctx = instance.ctx;
-  ctx.mpType = options.mpType;
-  ctx.$mpType = options.mpType;
-  ctx.$mpPlatform = "mp-weixin";
-  ctx.$scope = options.mpInstance;
-  ctx.$mp = {};
-  {
-    ctx._self = {};
-  }
-  instance.slots = {};
-  if (isArray(options.slots) && options.slots.length) {
-    options.slots.forEach((name) => {
-      instance.slots[name] = true;
-    });
-    if (instance.slots[SLOT_DEFAULT_NAME]) {
-      instance.slots.default = true;
-    }
-  }
-  ctx.getOpenerEventChannel = function() {
-    {
-      return options.mpInstance.getOpenerEventChannel();
-    }
-  };
-  ctx.$hasHook = hasHook;
-  ctx.$callHook = callHook;
-  instance.emit = createEmitFn(instance.emit, ctx);
-}
-function initComponentInstance(instance, options) {
-  initBaseInstance(instance, options);
-  const ctx = instance.ctx;
-  MP_METHODS.forEach((method) => {
-    ctx[method] = function(...args) {
-      const mpInstance = ctx.$scope;
-      if (mpInstance && mpInstance[method]) {
-        return mpInstance[method].apply(mpInstance, args);
-      }
-    };
-  });
-}
-function initMocks(instance, mpInstance, mocks2) {
-  const ctx = instance.ctx;
-  mocks2.forEach((mock) => {
-    if (hasOwn$1(mpInstance, mock)) {
-      instance[mock] = ctx[mock] = mpInstance[mock];
-    }
-  });
-}
-function hasHook(name) {
-  const hooks = this.$[name];
-  if (hooks && hooks.length) {
-    return true;
-  }
-  return false;
-}
-function callHook(name, args) {
-  if (name === "mounted") {
-    callHook.call(this, "bm");
-    this.$.isMounted = true;
-    name = "m";
-  }
-  const hooks = this.$[name];
-  return hooks && invokeArrayFns(hooks, args);
-}
-const PAGE_INIT_HOOKS = [
-  ON_LOAD,
-  ON_SHOW,
-  ON_HIDE,
-  ON_UNLOAD,
-  ON_RESIZE,
-  ON_TAB_ITEM_TAP,
-  ON_REACH_BOTTOM,
-  ON_PULL_DOWN_REFRESH,
-  ON_ADD_TO_FAVORITES
-  // 'onReady', // lifetimes.ready
-  // 'onPageScroll', // 影响性能,开发者手动注册
-  // 'onShareTimeline', // 右上角菜单,开发者手动注册
-  // 'onShareAppMessage' // 右上角菜单,开发者手动注册
-];
-function findHooks(vueOptions, hooks = /* @__PURE__ */ new Set()) {
-  if (vueOptions) {
-    Object.keys(vueOptions).forEach((name) => {
-      if (isUniLifecycleHook(name, vueOptions[name])) {
-        hooks.add(name);
-      }
-    });
-    {
-      const { extends: extendsOptions, mixins } = vueOptions;
-      if (mixins) {
-        mixins.forEach((mixin) => findHooks(mixin, hooks));
-      }
-      if (extendsOptions) {
-        findHooks(extendsOptions, hooks);
-      }
-    }
-  }
-  return hooks;
-}
-function initHook(mpOptions, hook, excludes) {
-  if (excludes.indexOf(hook) === -1 && !hasOwn$1(mpOptions, hook)) {
-    mpOptions[hook] = function(args) {
-      return this.$vm && this.$vm.$callHook(hook, args);
-    };
-  }
-}
-const EXCLUDE_HOOKS = [ON_READY];
-function initHooks(mpOptions, hooks, excludes = EXCLUDE_HOOKS) {
-  hooks.forEach((hook) => initHook(mpOptions, hook, excludes));
-}
-function initUnknownHooks(mpOptions, vueOptions, excludes = EXCLUDE_HOOKS) {
-  findHooks(vueOptions).forEach((hook) => initHook(mpOptions, hook, excludes));
-}
-function initRuntimeHooks(mpOptions, runtimeHooks) {
-  if (!runtimeHooks) {
-    return;
-  }
-  const hooks = Object.keys(MINI_PROGRAM_PAGE_RUNTIME_HOOKS);
-  hooks.forEach((hook) => {
-    if (runtimeHooks & MINI_PROGRAM_PAGE_RUNTIME_HOOKS[hook]) {
-      initHook(mpOptions, hook, []);
-    }
-  });
-}
-const findMixinRuntimeHooks = /* @__PURE__ */ once(() => {
-  const runtimeHooks = [];
-  const app = isFunction(getApp) && getApp({ allowDefault: true });
-  if (app && app.$vm && app.$vm.$) {
-    const mixins = app.$vm.$.appContext.mixins;
-    if (isArray(mixins)) {
-      const hooks = Object.keys(MINI_PROGRAM_PAGE_RUNTIME_HOOKS);
-      mixins.forEach((mixin) => {
-        hooks.forEach((hook) => {
-          if (hasOwn$1(mixin, hook) && !runtimeHooks.includes(hook)) {
-            runtimeHooks.push(hook);
-          }
-        });
-      });
-    }
-  }
-  return runtimeHooks;
-});
-function initMixinRuntimeHooks(mpOptions) {
-  initHooks(mpOptions, findMixinRuntimeHooks());
-}
-const HOOKS = [
-  ON_SHOW,
-  ON_HIDE,
-  ON_ERROR,
-  ON_THEME_CHANGE,
-  ON_PAGE_NOT_FOUND,
-  ON_UNHANDLE_REJECTION
-];
-function parseApp(instance, parseAppOptions) {
-  const internalInstance = instance.$;
-  const appOptions = {
-    globalData: instance.$options && instance.$options.globalData || {},
-    $vm: instance,
-    // mp-alipay 组件 data 初始化比 onLaunch 早,提前挂载
-    onLaunch(options) {
-      this.$vm = instance;
-      const ctx = internalInstance.ctx;
-      if (this.$vm && ctx.$scope) {
-        return;
-      }
-      initBaseInstance(internalInstance, {
-        mpType: "app",
-        mpInstance: this,
-        slots: []
-      });
-      ctx.globalData = this.globalData;
-      instance.$callHook(ON_LAUNCH, options);
-    }
-  };
-  const { onError } = internalInstance;
-  if (onError) {
-    internalInstance.appContext.config.errorHandler = (err) => {
-      instance.$callHook(ON_ERROR, err);
-    };
-  }
-  initLocale(instance);
-  const vueOptions = instance.$.type;
-  initHooks(appOptions, HOOKS);
-  initUnknownHooks(appOptions, vueOptions);
-  {
-    const methods = vueOptions.methods;
-    methods && extend(appOptions, methods);
-  }
-  if (parseAppOptions) {
-    parseAppOptions.parse(appOptions);
-  }
-  return appOptions;
-}
-function initCreateApp(parseAppOptions) {
-  return function createApp2(vm) {
-    return App(parseApp(vm, parseAppOptions));
-  };
-}
-function initCreateSubpackageApp(parseAppOptions) {
-  return function createApp2(vm) {
-    const appOptions = parseApp(vm, parseAppOptions);
-    const app = isFunction(getApp) && getApp({
-      allowDefault: true
-    });
-    if (!app)
-      return;
-    vm.$.ctx.$scope = app;
-    const globalData = app.globalData;
-    if (globalData) {
-      Object.keys(appOptions.globalData).forEach((name) => {
-        if (!hasOwn$1(globalData, name)) {
-          globalData[name] = appOptions.globalData[name];
-        }
-      });
-    }
-    Object.keys(appOptions).forEach((name) => {
-      if (!hasOwn$1(app, name)) {
-        app[name] = appOptions[name];
-      }
-    });
-    initAppLifecycle(appOptions, vm);
-  };
-}
-function initAppLifecycle(appOptions, vm) {
-  if (isFunction(appOptions.onLaunch)) {
-    const args = wx.getLaunchOptionsSync && wx.getLaunchOptionsSync();
-    appOptions.onLaunch(args);
-  }
-  if (isFunction(appOptions.onShow) && wx.onAppShow) {
-    wx.onAppShow((args) => {
-      vm.$callHook("onShow", args);
-    });
-  }
-  if (isFunction(appOptions.onHide) && wx.onAppHide) {
-    wx.onAppHide((args) => {
-      vm.$callHook("onHide", args);
-    });
-  }
-}
-function initLocale(appVm) {
-  const locale = ref(normalizeLocale(wx.getSystemInfoSync().language) || LOCALE_EN);
-  Object.defineProperty(appVm, "$locale", {
-    get() {
-      return locale.value;
-    },
-    set(v2) {
-      locale.value = v2;
-    }
-  });
-}
-function initVueIds(vueIds, mpInstance) {
-  if (!vueIds) {
-    return;
-  }
-  const ids = vueIds.split(",");
-  const len = ids.length;
-  if (len === 1) {
-    mpInstance._$vueId = ids[0];
-  } else if (len === 2) {
-    mpInstance._$vueId = ids[0];
-    mpInstance._$vuePid = ids[1];
-  }
-}
-const EXTRAS = ["externalClasses"];
-function initExtraOptions(miniProgramComponentOptions, vueOptions) {
-  EXTRAS.forEach((name) => {
-    if (hasOwn$1(vueOptions, name)) {
-      miniProgramComponentOptions[name] = vueOptions[name];
-    }
-  });
-}
-const WORKLET_RE = /_(.*)_worklet_factory_/;
-function initWorkletMethods(mpMethods, vueMethods) {
-  if (vueMethods) {
-    Object.keys(vueMethods).forEach((name) => {
-      const matches = name.match(WORKLET_RE);
-      if (matches) {
-        const workletName = matches[1];
-        mpMethods[name] = vueMethods[name];
-        mpMethods[workletName] = vueMethods[workletName];
-      }
-    });
-  }
-}
-function initWxsCallMethods(methods, wxsCallMethods) {
-  if (!isArray(wxsCallMethods)) {
-    return;
-  }
-  wxsCallMethods.forEach((callMethod) => {
-    methods[callMethod] = function(args) {
-      return this.$vm[callMethod](args);
-    };
-  });
-}
-function selectAllComponents(mpInstance, selector, $refs) {
-  const components = mpInstance.selectAllComponents(selector);
-  components.forEach((component) => {
-    const ref2 = component.properties.uR;
-    $refs[ref2] = component.$vm || component;
-  });
-}
-function initRefs(instance, mpInstance) {
-  Object.defineProperty(instance, "refs", {
-    get() {
-      const $refs = {};
-      selectAllComponents(mpInstance, ".r", $refs);
-      const forComponents = mpInstance.selectAllComponents(".r-i-f");
-      forComponents.forEach((component) => {
-        const ref2 = component.properties.uR;
-        if (!ref2) {
-          return;
-        }
-        if (!$refs[ref2]) {
-          $refs[ref2] = [];
-        }
-        $refs[ref2].push(component.$vm || component);
-      });
-      return $refs;
-    }
-  });
-}
-function findVmByVueId(instance, vuePid) {
-  const $children = instance.$children;
-  for (let i2 = $children.length - 1; i2 >= 0; i2--) {
-    const childVm = $children[i2];
-    if (childVm.$scope._$vueId === vuePid) {
-      return childVm;
-    }
-  }
-  let parentVm;
-  for (let i2 = $children.length - 1; i2 >= 0; i2--) {
-    parentVm = findVmByVueId($children[i2], vuePid);
-    if (parentVm) {
-      return parentVm;
-    }
-  }
-}
-const builtInProps = [
-  // 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
-  // event-opts
-  "eO",
-  // 组件 ref
-  "uR",
-  // 组件 ref-in-for
-  "uRIF",
-  // 组件 id
-  "uI",
-  // 组件类型 m: 小程序组件
-  "uT",
-  // 组件 props
-  "uP",
-  // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
-  "uS"
-];
-function initDefaultProps(options, isBehavior = false) {
-  const properties = {};
-  if (!isBehavior) {
-    builtInProps.forEach((name) => {
-      properties[name] = {
-        type: null,
-        value: ""
-      };
-    });
-    properties.uS = {
-      type: null,
-      value: [],
-      observer: function(newVal) {
-        const $slots = /* @__PURE__ */ Object.create(null);
-        newVal && newVal.forEach((slotName) => {
-          $slots[slotName] = true;
-        });
-        this.setData({
-          $slots
-        });
-      }
-    };
-  }
-  if (options.behaviors) {
-    if (options.behaviors.includes("wx://form-field")) {
-      if (!options.properties || !options.properties.name) {
-        properties.name = {
-          type: null,
-          value: ""
-        };
-      }
-      if (!options.properties || !options.properties.value) {
-        properties.value = {
-          type: null,
-          value: ""
-        };
-      }
-    }
-  }
-  return properties;
-}
-function initVirtualHostProps(options) {
-  const properties = {};
-  {
-    if (options && options.virtualHost) {
-      properties.virtualHostStyle = {
-        type: null,
-        value: ""
-      };
-      properties.virtualHostClass = {
-        type: null,
-        value: ""
-      };
-    }
-  }
-  return properties;
-}
-function initProps(mpComponentOptions) {
-  if (!mpComponentOptions.properties) {
-    mpComponentOptions.properties = {};
-  }
-  extend(mpComponentOptions.properties, initDefaultProps(mpComponentOptions), initVirtualHostProps(mpComponentOptions.options));
-}
-const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
-function parsePropType(type, defaultValue) {
-  if (isArray(type) && type.length === 1) {
-    return type[0];
-  }
-  return type;
-}
-function normalizePropType(type, defaultValue) {
-  const res = parsePropType(type);
-  return PROP_TYPES.indexOf(res) !== -1 ? res : null;
-}
-function initPageProps({ properties }, rawProps) {
-  if (isArray(rawProps)) {
-    rawProps.forEach((key) => {
-      properties[key] = {
-        type: String,
-        value: ""
-      };
-    });
-  } else if (isPlainObject(rawProps)) {
-    Object.keys(rawProps).forEach((key) => {
-      const opts = rawProps[key];
-      if (isPlainObject(opts)) {
-        let value = opts.default;
-        if (isFunction(value)) {
-          value = value();
-        }
-        const type = opts.type;
-        opts.type = normalizePropType(type);
-        properties[key] = {
-          type: opts.type,
-          value
-        };
-      } else {
-        properties[key] = {
-          type: normalizePropType(opts)
-        };
-      }
-    });
-  }
-}
-function findPropsData(properties, isPage2) {
-  return (isPage2 ? findPagePropsData(properties) : findComponentPropsData(properties.uP)) || {};
-}
-function findPagePropsData(properties) {
-  const propsData = {};
-  if (isPlainObject(properties)) {
-    Object.keys(properties).forEach((name) => {
-      if (builtInProps.indexOf(name) === -1) {
-        propsData[name] = properties[name];
-      }
-    });
-  }
-  return propsData;
-}
-function initFormField(vm) {
-  const vueOptions = vm.$options;
-  if (isArray(vueOptions.behaviors) && vueOptions.behaviors.includes("uni://form-field")) {
-    vm.$watch("modelValue", () => {
-      vm.$scope && vm.$scope.setData({
-        name: vm.name,
-        value: vm.modelValue
-      });
-    }, {
-      immediate: true
-    });
-  }
-}
-function initData(_2) {
-  return {};
-}
-function initPropsObserver(componentOptions) {
-  const observe = function observe2() {
-    const up = this.properties.uP;
-    if (!up) {
-      return;
-    }
-    if (this.$vm) {
-      updateComponentProps(up, this.$vm.$);
-    } else if (this.properties.uT === "m") {
-      updateMiniProgramComponentProperties(up, this);
-    }
-  };
-  {
-    if (!componentOptions.observers) {
-      componentOptions.observers = {};
-    }
-    componentOptions.observers.uP = observe;
-  }
-}
-function updateMiniProgramComponentProperties(up, mpInstance) {
-  const prevProps = mpInstance.properties;
-  const nextProps = findComponentPropsData(up) || {};
-  if (hasPropsChanged(prevProps, nextProps, false)) {
-    mpInstance.setData(nextProps);
-  }
-}
-function updateComponentProps(up, instance) {
-  const prevProps = toRaw(instance.props);
-  const nextProps = findComponentPropsData(up) || {};
-  if (hasPropsChanged(prevProps, nextProps)) {
-    updateProps(instance, nextProps, prevProps, false);
-    if (hasQueueJob(instance.update)) {
-      invalidateJob(instance.update);
-    }
-    {
-      instance.update();
-    }
-  }
-}
-function hasPropsChanged(prevProps, nextProps, checkLen = true) {
-  const nextKeys = Object.keys(nextProps);
-  if (checkLen && nextKeys.length !== Object.keys(prevProps).length) {
-    return true;
-  }
-  for (let i2 = 0; i2 < nextKeys.length; i2++) {
-    const key = nextKeys[i2];
-    if (nextProps[key] !== prevProps[key]) {
-      return true;
-    }
-  }
-  return false;
-}
-function initBehaviors(vueOptions) {
-  const vueBehaviors = vueOptions.behaviors;
-  let vueProps = vueOptions.props;
-  if (!vueProps) {
-    vueOptions.props = vueProps = [];
-  }
-  const behaviors = [];
-  if (isArray(vueBehaviors)) {
-    vueBehaviors.forEach((behavior) => {
-      behaviors.push(behavior.replace("uni://", "wx://"));
-      if (behavior === "uni://form-field") {
-        if (isArray(vueProps)) {
-          vueProps.push("name");
-          vueProps.push("modelValue");
-        } else {
-          vueProps.name = {
-            type: String,
-            default: ""
-          };
-          vueProps.modelValue = {
-            type: [String, Number, Boolean, Array, Object, Date],
-            default: ""
-          };
-        }
-      }
-    });
-  }
-  return behaviors;
-}
-function applyOptions(componentOptions, vueOptions) {
-  componentOptions.data = initData();
-  componentOptions.behaviors = initBehaviors(vueOptions);
-}
-function parseComponent(vueOptions, { parse: parse2, mocks: mocks2, isPage: isPage2, initRelation: initRelation2, handleLink: handleLink2, initLifetimes: initLifetimes2 }) {
-  vueOptions = vueOptions.default || vueOptions;
-  const options = {
-    multipleSlots: true,
-    // styleIsolation: 'apply-shared',
-    addGlobalClass: true,
-    pureDataPattern: /^uP$/
-  };
-  if (isArray(vueOptions.mixins)) {
-    vueOptions.mixins.forEach((item) => {
-      if (isObject$1(item.options)) {
-        extend(options, item.options);
-      }
-    });
-  }
-  if (vueOptions.options) {
-    extend(options, vueOptions.options);
-  }
-  const mpComponentOptions = {
-    options,
-    lifetimes: initLifetimes2({ mocks: mocks2, isPage: isPage2, initRelation: initRelation2, vueOptions }),
-    pageLifetimes: {
-      show() {
-        this.$vm && this.$vm.$callHook("onPageShow");
-      },
-      hide() {
-        this.$vm && this.$vm.$callHook("onPageHide");
-      },
-      resize(size2) {
-        this.$vm && this.$vm.$callHook("onPageResize", size2);
-      }
-    },
-    methods: {
-      __l: handleLink2
-    }
-  };
-  {
-    applyOptions(mpComponentOptions, vueOptions);
-  }
-  initProps(mpComponentOptions);
-  initPropsObserver(mpComponentOptions);
-  initExtraOptions(mpComponentOptions, vueOptions);
-  initWxsCallMethods(mpComponentOptions.methods, vueOptions.wxsCallMethods);
-  {
-    initWorkletMethods(mpComponentOptions.methods, vueOptions.methods);
-  }
-  if (parse2) {
-    parse2(mpComponentOptions, { handleLink: handleLink2 });
-  }
-  return mpComponentOptions;
-}
-function initCreateComponent(parseOptions2) {
-  return function createComponent2(vueComponentOptions) {
-    return Component(parseComponent(vueComponentOptions, parseOptions2));
-  };
-}
-let $createComponentFn;
-let $destroyComponentFn;
-function getAppVm() {
-  return getApp().$vm;
-}
-function $createComponent(initialVNode, options) {
-  if (!$createComponentFn) {
-    $createComponentFn = getAppVm().$createComponent;
-  }
-  const proxy = $createComponentFn(initialVNode, options);
-  return getExposeProxy(proxy.$) || proxy;
-}
-function $destroyComponent(instance) {
-  if (!$destroyComponentFn) {
-    $destroyComponentFn = getAppVm().$destroyComponent;
-  }
-  return $destroyComponentFn(instance);
-}
-function parsePage(vueOptions, parseOptions2) {
-  const { parse: parse2, mocks: mocks2, isPage: isPage2, initRelation: initRelation2, handleLink: handleLink2, initLifetimes: initLifetimes2 } = parseOptions2;
-  const miniProgramPageOptions = parseComponent(vueOptions, {
-    mocks: mocks2,
-    isPage: isPage2,
-    initRelation: initRelation2,
-    handleLink: handleLink2,
-    initLifetimes: initLifetimes2
-  });
-  initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
-  const methods = miniProgramPageOptions.methods;
-  methods.onLoad = function(query) {
-    this.options = query;
-    this.$page = {
-      fullPath: addLeadingSlash(this.route + stringifyQuery(query))
-    };
-    return this.$vm && this.$vm.$callHook(ON_LOAD, query);
-  };
-  initHooks(methods, PAGE_INIT_HOOKS);
-  {
-    initUnknownHooks(methods, vueOptions);
-  }
-  initRuntimeHooks(methods, vueOptions.__runtimeHooks);
-  initMixinRuntimeHooks(methods);
-  parse2 && parse2(miniProgramPageOptions, { handleLink: handleLink2 });
-  return miniProgramPageOptions;
-}
-function initCreatePage(parseOptions2) {
-  return function createPage2(vuePageOptions) {
-    return Component(parsePage(vuePageOptions, parseOptions2));
-  };
-}
-function initCreatePluginApp(parseAppOptions) {
-  return function createApp2(vm) {
-    initAppLifecycle(parseApp(vm, parseAppOptions), vm);
-  };
-}
-const MPPage = Page;
-const MPComponent = Component;
-function initTriggerEvent(mpInstance) {
-  const oldTriggerEvent = mpInstance.triggerEvent;
-  const newTriggerEvent = function(event, ...args) {
-    return oldTriggerEvent.apply(mpInstance, [customizeEvent(event), ...args]);
-  };
-  try {
-    mpInstance.triggerEvent = newTriggerEvent;
-  } catch (error) {
-    mpInstance._triggerEvent = newTriggerEvent;
-  }
-}
-function initMiniProgramHook(name, options, isComponent) {
-  const oldHook = options[name];
-  if (!oldHook) {
-    options[name] = function() {
-      initTriggerEvent(this);
-    };
-  } else {
-    options[name] = function(...args) {
-      initTriggerEvent(this);
-      return oldHook.apply(this, args);
-    };
-  }
-}
-Page = function(options) {
-  initMiniProgramHook(ON_LOAD, options);
-  return MPPage(options);
-};
-Component = function(options) {
-  initMiniProgramHook("created", options);
-  const isVueComponent = options.properties && options.properties.uP;
-  if (!isVueComponent) {
-    initProps(options);
-    initPropsObserver(options);
-  }
-  return MPComponent(options);
-};
-function initLifetimes({ mocks: mocks2, isPage: isPage2, initRelation: initRelation2, vueOptions }) {
-  return {
-    attached() {
-      let properties = this.properties;
-      initVueIds(properties.uI, this);
-      const relationOptions = {
-        vuePid: this._$vuePid
-      };
-      initRelation2(this, relationOptions);
-      const mpInstance = this;
-      const isMiniProgramPage = isPage2(mpInstance);
-      let propsData = properties;
-      this.$vm = $createComponent({
-        type: vueOptions,
-        props: findPropsData(propsData, isMiniProgramPage)
-      }, {
-        mpType: isMiniProgramPage ? "page" : "component",
-        mpInstance,
-        slots: properties.uS || {},
-        // vueSlots
-        parentComponent: relationOptions.parent && relationOptions.parent.$,
-        onBeforeSetup(instance, options) {
-          initRefs(instance, mpInstance);
-          initMocks(instance, mpInstance, mocks2);
-          initComponentInstance(instance, options);
-        }
-      });
-      if (!isMiniProgramPage) {
-        initFormField(this.$vm);
-      }
-    },
-    ready() {
-      if (this.$vm) {
-        {
-          this.$vm.$callHook("mounted");
-          this.$vm.$callHook(ON_READY);
-        }
-      }
-    },
-    detached() {
-      if (this.$vm) {
-        pruneComponentPropsCache(this.$vm.$.uid);
-        $destroyComponent(this.$vm);
-      }
-    }
-  };
-}
-const mocks = ["__route__", "__wxExparserNodeId__", "__wxWebviewId__"];
-function isPage(mpInstance) {
-  return !!mpInstance.route;
-}
-function initRelation(mpInstance, detail) {
-  mpInstance.triggerEvent("__l", detail);
-}
-function handleLink(event) {
-  const detail = event.detail || event.value;
-  const vuePid = detail.vuePid;
-  let parentVm;
-  if (vuePid) {
-    parentVm = findVmByVueId(this.$vm, vuePid);
-  }
-  if (!parentVm) {
-    parentVm = this.$vm;
-  }
-  detail.parent = parentVm;
-}
-var parseOptions = /* @__PURE__ */ Object.freeze({
-  __proto__: null,
-  handleLink,
-  initLifetimes,
-  initRelation,
-  isPage,
-  mocks
-});
-const createApp = initCreateApp();
-const createPage = initCreatePage(parseOptions);
-const createComponent = initCreateComponent(parseOptions);
-const createPluginApp = initCreatePluginApp();
-const createSubpackageApp = initCreateSubpackageApp();
-{
-  wx.createApp = global.createApp = createApp;
-  wx.createPage = createPage;
-  wx.createComponent = createComponent;
-  wx.createPluginApp = global.createPluginApp = createPluginApp;
-  wx.createSubpackageApp = global.createSubpackageApp = createSubpackageApp;
-}
-const createHook = (lifecycle) => (hook, target = getCurrentInstance()) => {
-  !isInSSRComponentSetup && injectHook(lifecycle, hook, target);
-};
-const onShow = /* @__PURE__ */ createHook(ON_SHOW);
-const onLaunch = /* @__PURE__ */ createHook(ON_LAUNCH);
-const onLoad = /* @__PURE__ */ createHook(ON_LOAD);
-const pages = [
-  {
-    path: "pages/login/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/index/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/addCard/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/userInfo/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/functionList/balanceRecord/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/functionList/paymentRecord/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/functionList/rechargeRecord/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/functionList/share/cardShare/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/functionList/share/shareConfirm/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/functionList/share/shareList/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/scanWater/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/recharge/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/sendWater/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/preSendWater/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/address/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/addressAdd/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/addressLocate/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/success/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/facilityList/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/station/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/infoBreakdown/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/scanRecharge/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/scanSuccess/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/counterRecharge/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  },
-  {
-    path: "pages/wxScanWater/index",
-    style: {
-      navigationStyle: "custom"
-    }
-  }
-];
-const subPackages = [
-  {
-    root: "pagesAdmin",
-    pages: [
-      {
-        path: "adminPlatform/home",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "adminPlatform/facility",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "adminPlatform/facilityDetail",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "adminPlatform/inspect",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "adminPlatform/params",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "adminPlatform/params1",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "adminPlatform/breakdown",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "adminPlatform/maintain",
-        style: {
-          navigationStyle: "custom"
-        }
-      }
-    ]
-  },
-  {
-    root: "pagesPoints",
-    pages: [
-      {
-        path: "pointsMall/index",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "pointsMall/pointsGetRecord/index",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "pointsMall/pointsExchangeRecord/index",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "pointsMall/pointsGoodsDetail/index",
-        style: {
-          navigationStyle: "custom"
-        }
-      },
-      {
-        path: "pointsMall/pointsrule/index",
-        style: {
-          navigationStyle: "custom"
-        }
-      }
-    ]
-  }
-];
-const globalStyle = {
-  navigationStyle: "custom"
-};
-const easycom = {
-  autoscan: true,
-  custom: {
-    "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
-  }
-};
-const e = {
-  pages,
-  subPackages,
-  globalStyle,
-  easycom
-};
-var define_process_env_UNI_SECURE_NETWORK_CONFIG_default = [];
-function t(e2) {
-  return e2 && e2.__esModule && Object.prototype.hasOwnProperty.call(e2, "default") ? e2.default : e2;
-}
-function n(e2, t2, n2) {
-  return e2(n2 = { path: t2, exports: {}, require: function(e3, t3) {
-    return function() {
-      throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs");
-    }(null == t3 && n2.path);
-  } }, n2.exports), n2.exports;
-}
-var s = n(function(e2, t2) {
-  var n2;
-  e2.exports = (n2 = n2 || function(e3, t3) {
-    var n3 = Object.create || /* @__PURE__ */ function() {
-      function e4() {
-      }
-      return function(t4) {
-        var n4;
-        return e4.prototype = t4, n4 = new e4(), e4.prototype = null, n4;
-      };
-    }(), s2 = {}, r2 = s2.lib = {}, i2 = r2.Base = { extend: function(e4) {
-      var t4 = n3(this);
-      return e4 && t4.mixIn(e4), t4.hasOwnProperty("init") && this.init !== t4.init || (t4.init = function() {
-        t4.$super.init.apply(this, arguments);
-      }), t4.init.prototype = t4, t4.$super = this, t4;
-    }, create: function() {
-      var e4 = this.extend();
-      return e4.init.apply(e4, arguments), e4;
-    }, init: function() {
-    }, mixIn: function(e4) {
-      for (var t4 in e4)
-        e4.hasOwnProperty(t4) && (this[t4] = e4[t4]);
-      e4.hasOwnProperty("toString") && (this.toString = e4.toString);
-    }, clone: function() {
-      return this.init.prototype.extend(this);
-    } }, o2 = r2.WordArray = i2.extend({ init: function(e4, n4) {
-      e4 = this.words = e4 || [], this.sigBytes = n4 != t3 ? n4 : 4 * e4.length;
-    }, toString: function(e4) {
-      return (e4 || c2).stringify(this);
-    }, concat: function(e4) {
-      var t4 = this.words, n4 = e4.words, s3 = this.sigBytes, r3 = e4.sigBytes;
-      if (this.clamp(), s3 % 4)
-        for (var i3 = 0; i3 < r3; i3++) {
-          var o3 = n4[i3 >>> 2] >>> 24 - i3 % 4 * 8 & 255;
-          t4[s3 + i3 >>> 2] |= o3 << 24 - (s3 + i3) % 4 * 8;
-        }
-      else
-        for (i3 = 0; i3 < r3; i3 += 4)
-          t4[s3 + i3 >>> 2] = n4[i3 >>> 2];
-      return this.sigBytes += r3, this;
-    }, clamp: function() {
-      var t4 = this.words, n4 = this.sigBytes;
-      t4[n4 >>> 2] &= 4294967295 << 32 - n4 % 4 * 8, t4.length = e3.ceil(n4 / 4);
-    }, clone: function() {
-      var e4 = i2.clone.call(this);
-      return e4.words = this.words.slice(0), e4;
-    }, random: function(t4) {
-      for (var n4, s3 = [], r3 = function(t5) {
-        t5 = t5;
-        var n5 = 987654321, s4 = 4294967295;
-        return function() {
-          var r4 = ((n5 = 36969 * (65535 & n5) + (n5 >> 16) & s4) << 16) + (t5 = 18e3 * (65535 & t5) + (t5 >> 16) & s4) & s4;
-          return r4 /= 4294967296, (r4 += 0.5) * (e3.random() > 0.5 ? 1 : -1);
-        };
-      }, i3 = 0; i3 < t4; i3 += 4) {
-        var a3 = r3(4294967296 * (n4 || e3.random()));
-        n4 = 987654071 * a3(), s3.push(4294967296 * a3() | 0);
-      }
-      return new o2.init(s3, t4);
-    } }), a2 = s2.enc = {}, c2 = a2.Hex = { stringify: function(e4) {
-      for (var t4 = e4.words, n4 = e4.sigBytes, s3 = [], r3 = 0; r3 < n4; r3++) {
-        var i3 = t4[r3 >>> 2] >>> 24 - r3 % 4 * 8 & 255;
-        s3.push((i3 >>> 4).toString(16)), s3.push((15 & i3).toString(16));
-      }
-      return s3.join("");
-    }, parse: function(e4) {
-      for (var t4 = e4.length, n4 = [], s3 = 0; s3 < t4; s3 += 2)
-        n4[s3 >>> 3] |= parseInt(e4.substr(s3, 2), 16) << 24 - s3 % 8 * 4;
-      return new o2.init(n4, t4 / 2);
-    } }, u2 = a2.Latin1 = { stringify: function(e4) {
-      for (var t4 = e4.words, n4 = e4.sigBytes, s3 = [], r3 = 0; r3 < n4; r3++) {
-        var i3 = t4[r3 >>> 2] >>> 24 - r3 % 4 * 8 & 255;
-        s3.push(String.fromCharCode(i3));
-      }
-      return s3.join("");
-    }, parse: function(e4) {
-      for (var t4 = e4.length, n4 = [], s3 = 0; s3 < t4; s3++)
-        n4[s3 >>> 2] |= (255 & e4.charCodeAt(s3)) << 24 - s3 % 4 * 8;
-      return new o2.init(n4, t4);
-    } }, l2 = a2.Utf8 = { stringify: function(e4) {
-      try {
-        return decodeURIComponent(escape(u2.stringify(e4)));
-      } catch (e5) {
-        throw new Error("Malformed UTF-8 data");
-      }
-    }, parse: function(e4) {
-      return u2.parse(unescape(encodeURIComponent(e4)));
-    } }, h2 = r2.BufferedBlockAlgorithm = i2.extend({ reset: function() {
-      this._data = new o2.init(), this._nDataBytes = 0;
-    }, _append: function(e4) {
-      "string" == typeof e4 && (e4 = l2.parse(e4)), this._data.concat(e4), this._nDataBytes += e4.sigBytes;
-    }, _process: function(t4) {
-      var n4 = this._data, s3 = n4.words, r3 = n4.sigBytes, i3 = this.blockSize, a3 = r3 / (4 * i3), c3 = (a3 = t4 ? e3.ceil(a3) : e3.max((0 | a3) - this._minBufferSize, 0)) * i3, u3 = e3.min(4 * c3, r3);
-      if (c3) {
-        for (var l3 = 0; l3 < c3; l3 += i3)
-          this._doProcessBlock(s3, l3);
-        var h3 = s3.splice(0, c3);
-        n4.sigBytes -= u3;
-      }
-      return new o2.init(h3, u3);
-    }, clone: function() {
-      var e4 = i2.clone.call(this);
-      return e4._data = this._data.clone(), e4;
-    }, _minBufferSize: 0 });
-    r2.Hasher = h2.extend({ cfg: i2.extend(), init: function(e4) {
-      this.cfg = this.cfg.extend(e4), this.reset();
-    }, reset: function() {
-      h2.reset.call(this), this._doReset();
-    }, update: function(e4) {
-      return this._append(e4), this._process(), this;
-    }, finalize: function(e4) {
-      return e4 && this._append(e4), this._doFinalize();
-    }, blockSize: 16, _createHelper: function(e4) {
-      return function(t4, n4) {
-        return new e4.init(n4).finalize(t4);
-      };
-    }, _createHmacHelper: function(e4) {
-      return function(t4, n4) {
-        return new d2.HMAC.init(e4, n4).finalize(t4);
-      };
-    } });
-    var d2 = s2.algo = {};
-    return s2;
-  }(Math), n2);
-}), r = s, i = (n(function(e2, t2) {
-  var n2;
-  e2.exports = (n2 = r, function(e3) {
-    var t3 = n2, s2 = t3.lib, r2 = s2.WordArray, i2 = s2.Hasher, o2 = t3.algo, a2 = [];
-    !function() {
-      for (var t4 = 0; t4 < 64; t4++)
-        a2[t4] = 4294967296 * e3.abs(e3.sin(t4 + 1)) | 0;
-    }();
-    var c2 = o2.MD5 = i2.extend({ _doReset: function() {
-      this._hash = new r2.init([1732584193, 4023233417, 2562383102, 271733878]);
-    }, _doProcessBlock: function(e4, t4) {
-      for (var n3 = 0; n3 < 16; n3++) {
-        var s3 = t4 + n3, r3 = e4[s3];
-        e4[s3] = 16711935 & (r3 << 8 | r3 >>> 24) | 4278255360 & (r3 << 24 | r3 >>> 8);
-      }
-      var i3 = this._hash.words, o3 = e4[t4 + 0], c3 = e4[t4 + 1], p2 = e4[t4 + 2], f2 = e4[t4 + 3], g2 = e4[t4 + 4], m2 = e4[t4 + 5], y2 = e4[t4 + 6], _2 = e4[t4 + 7], w2 = e4[t4 + 8], v2 = e4[t4 + 9], I2 = e4[t4 + 10], S2 = e4[t4 + 11], b2 = e4[t4 + 12], k2 = e4[t4 + 13], A2 = e4[t4 + 14], C2 = e4[t4 + 15], P2 = i3[0], T2 = i3[1], x2 = i3[2], O2 = i3[3];
-      P2 = u2(P2, T2, x2, O2, o3, 7, a2[0]), O2 = u2(O2, P2, T2, x2, c3, 12, a2[1]), x2 = u2(x2, O2, P2, T2, p2, 17, a2[2]), T2 = u2(T2, x2, O2, P2, f2, 22, a2[3]), P2 = u2(P2, T2, x2, O2, g2, 7, a2[4]), O2 = u2(O2, P2, T2, x2, m2, 12, a2[5]), x2 = u2(x2, O2, P2, T2, y2, 17, a2[6]), T2 = u2(T2, x2, O2, P2, _2, 22, a2[7]), P2 = u2(P2, T2, x2, O2, w2, 7, a2[8]), O2 = u2(O2, P2, T2, x2, v2, 12, a2[9]), x2 = u2(x2, O2, P2, T2, I2, 17, a2[10]), T2 = u2(T2, x2, O2, P2, S2, 22, a2[11]), P2 = u2(P2, T2, x2, O2, b2, 7, a2[12]), O2 = u2(O2, P2, T2, x2, k2, 12, a2[13]), x2 = u2(x2, O2, P2, T2, A2, 17, a2[14]), P2 = l2(P2, T2 = u2(T2, x2, O2, P2, C2, 22, a2[15]), x2, O2, c3, 5, a2[16]), O2 = l2(O2, P2, T2, x2, y2, 9, a2[17]), x2 = l2(x2, O2, P2, T2, S2, 14, a2[18]), T2 = l2(T2, x2, O2, P2, o3, 20, a2[19]), P2 = l2(P2, T2, x2, O2, m2, 5, a2[20]), O2 = l2(O2, P2, T2, x2, I2, 9, a2[21]), x2 = l2(x2, O2, P2, T2, C2, 14, a2[22]), T2 = l2(T2, x2, O2, P2, g2, 20, a2[23]), P2 = l2(P2, T2, x2, O2, v2, 5, a2[24]), O2 = l2(O2, P2, T2, x2, A2, 9, a2[25]), x2 = l2(x2, O2, P2, T2, f2, 14, a2[26]), T2 = l2(T2, x2, O2, P2, w2, 20, a2[27]), P2 = l2(P2, T2, x2, O2, k2, 5, a2[28]), O2 = l2(O2, P2, T2, x2, p2, 9, a2[29]), x2 = l2(x2, O2, P2, T2, _2, 14, a2[30]), P2 = h2(P2, T2 = l2(T2, x2, O2, P2, b2, 20, a2[31]), x2, O2, m2, 4, a2[32]), O2 = h2(O2, P2, T2, x2, w2, 11, a2[33]), x2 = h2(x2, O2, P2, T2, S2, 16, a2[34]), T2 = h2(T2, x2, O2, P2, A2, 23, a2[35]), P2 = h2(P2, T2, x2, O2, c3, 4, a2[36]), O2 = h2(O2, P2, T2, x2, g2, 11, a2[37]), x2 = h2(x2, O2, P2, T2, _2, 16, a2[38]), T2 = h2(T2, x2, O2, P2, I2, 23, a2[39]), P2 = h2(P2, T2, x2, O2, k2, 4, a2[40]), O2 = h2(O2, P2, T2, x2, o3, 11, a2[41]), x2 = h2(x2, O2, P2, T2, f2, 16, a2[42]), T2 = h2(T2, x2, O2, P2, y2, 23, a2[43]), P2 = h2(P2, T2, x2, O2, v2, 4, a2[44]), O2 = h2(O2, P2, T2, x2, b2, 11, a2[45]), x2 = h2(x2, O2, P2, T2, C2, 16, a2[46]), P2 = d2(P2, T2 = h2(T2, x2, O2, P2, p2, 23, a2[47]), x2, O2, o3, 6, a2[48]), O2 = d2(O2, P2, T2, x2, _2, 10, a2[49]), x2 = d2(x2, O2, P2, T2, A2, 15, a2[50]), T2 = d2(T2, x2, O2, P2, m2, 21, a2[51]), P2 = d2(P2, T2, x2, O2, b2, 6, a2[52]), O2 = d2(O2, P2, T2, x2, f2, 10, a2[53]), x2 = d2(x2, O2, P2, T2, I2, 15, a2[54]), T2 = d2(T2, x2, O2, P2, c3, 21, a2[55]), P2 = d2(P2, T2, x2, O2, w2, 6, a2[56]), O2 = d2(O2, P2, T2, x2, C2, 10, a2[57]), x2 = d2(x2, O2, P2, T2, y2, 15, a2[58]), T2 = d2(T2, x2, O2, P2, k2, 21, a2[59]), P2 = d2(P2, T2, x2, O2, g2, 6, a2[60]), O2 = d2(O2, P2, T2, x2, S2, 10, a2[61]), x2 = d2(x2, O2, P2, T2, p2, 15, a2[62]), T2 = d2(T2, x2, O2, P2, v2, 21, a2[63]), i3[0] = i3[0] + P2 | 0, i3[1] = i3[1] + T2 | 0, i3[2] = i3[2] + x2 | 0, i3[3] = i3[3] + O2 | 0;
-    }, _doFinalize: function() {
-      var t4 = this._data, n3 = t4.words, s3 = 8 * this._nDataBytes, r3 = 8 * t4.sigBytes;
-      n3[r3 >>> 5] |= 128 << 24 - r3 % 32;
-      var i3 = e3.floor(s3 / 4294967296), o3 = s3;
-      n3[15 + (r3 + 64 >>> 9 << 4)] = 16711935 & (i3 << 8 | i3 >>> 24) | 4278255360 & (i3 << 24 | i3 >>> 8), n3[14 + (r3 + 64 >>> 9 << 4)] = 16711935 & (o3 << 8 | o3 >>> 24) | 4278255360 & (o3 << 24 | o3 >>> 8), t4.sigBytes = 4 * (n3.length + 1), this._process();
-      for (var a3 = this._hash, c3 = a3.words, u3 = 0; u3 < 4; u3++) {
-        var l3 = c3[u3];
-        c3[u3] = 16711935 & (l3 << 8 | l3 >>> 24) | 4278255360 & (l3 << 24 | l3 >>> 8);
-      }
-      return a3;
-    }, clone: function() {
-      var e4 = i2.clone.call(this);
-      return e4._hash = this._hash.clone(), e4;
-    } });
-    function u2(e4, t4, n3, s3, r3, i3, o3) {
-      var a3 = e4 + (t4 & n3 | ~t4 & s3) + r3 + o3;
-      return (a3 << i3 | a3 >>> 32 - i3) + t4;
-    }
-    function l2(e4, t4, n3, s3, r3, i3, o3) {
-      var a3 = e4 + (t4 & s3 | n3 & ~s3) + r3 + o3;
-      return (a3 << i3 | a3 >>> 32 - i3) + t4;
-    }
-    function h2(e4, t4, n3, s3, r3, i3, o3) {
-      var a3 = e4 + (t4 ^ n3 ^ s3) + r3 + o3;
-      return (a3 << i3 | a3 >>> 32 - i3) + t4;
-    }
-    function d2(e4, t4, n3, s3, r3, i3, o3) {
-      var a3 = e4 + (n3 ^ (t4 | ~s3)) + r3 + o3;
-      return (a3 << i3 | a3 >>> 32 - i3) + t4;
-    }
-    t3.MD5 = i2._createHelper(c2), t3.HmacMD5 = i2._createHmacHelper(c2);
-  }(Math), n2.MD5);
-}), n(function(e2, t2) {
-  var n2;
-  e2.exports = (n2 = r, void function() {
-    var e3 = n2, t3 = e3.lib.Base, s2 = e3.enc.Utf8;
-    e3.algo.HMAC = t3.extend({ init: function(e4, t4) {
-      e4 = this._hasher = new e4.init(), "string" == typeof t4 && (t4 = s2.parse(t4));
-      var n3 = e4.blockSize, r2 = 4 * n3;
-      t4.sigBytes > r2 && (t4 = e4.finalize(t4)), t4.clamp();
-      for (var i2 = this._oKey = t4.clone(), o2 = this._iKey = t4.clone(), a2 = i2.words, c2 = o2.words, u2 = 0; u2 < n3; u2++)
-        a2[u2] ^= 1549556828, c2[u2] ^= 909522486;
-      i2.sigBytes = o2.sigBytes = r2, this.reset();
-    }, reset: function() {
-      var e4 = this._hasher;
-      e4.reset(), e4.update(this._iKey);
-    }, update: function(e4) {
-      return this._hasher.update(e4), this;
-    }, finalize: function(e4) {
-      var t4 = this._hasher, n3 = t4.finalize(e4);
-      return t4.reset(), t4.finalize(this._oKey.clone().concat(n3));
-    } });
-  }());
-}), n(function(e2, t2) {
-  e2.exports = r.HmacMD5;
-})), o = n(function(e2, t2) {
-  e2.exports = r.enc.Utf8;
-}), a = n(function(e2, t2) {
-  var n2;
-  e2.exports = (n2 = r, function() {
-    var e3 = n2, t3 = e3.lib.WordArray;
-    function s2(e4, n3, s3) {
-      for (var r2 = [], i2 = 0, o2 = 0; o2 < n3; o2++)
-        if (o2 % 4) {
-          var a2 = s3[e4.charCodeAt(o2 - 1)] << o2 % 4 * 2, c2 = s3[e4.charCodeAt(o2)] >>> 6 - o2 % 4 * 2;
-          r2[i2 >>> 2] |= (a2 | c2) << 24 - i2 % 4 * 8, i2++;
-        }
-      return t3.create(r2, i2);
-    }
-    e3.enc.Base64 = { stringify: function(e4) {
-      var t4 = e4.words, n3 = e4.sigBytes, s3 = this._map;
-      e4.clamp();
-      for (var r2 = [], i2 = 0; i2 < n3; i2 += 3)
-        for (var o2 = (t4[i2 >>> 2] >>> 24 - i2 % 4 * 8 & 255) << 16 | (t4[i2 + 1 >>> 2] >>> 24 - (i2 + 1) % 4 * 8 & 255) << 8 | t4[i2 + 2 >>> 2] >>> 24 - (i2 + 2) % 4 * 8 & 255, a2 = 0; a2 < 4 && i2 + 0.75 * a2 < n3; a2++)
-          r2.push(s3.charAt(o2 >>> 6 * (3 - a2) & 63));
-      var c2 = s3.charAt(64);
-      if (c2)
-        for (; r2.length % 4; )
-          r2.push(c2);
-      return r2.join("");
-    }, parse: function(e4) {
-      var t4 = e4.length, n3 = this._map, r2 = this._reverseMap;
-      if (!r2) {
-        r2 = this._reverseMap = [];
-        for (var i2 = 0; i2 < n3.length; i2++)
-          r2[n3.charCodeAt(i2)] = i2;
-      }
-      var o2 = n3.charAt(64);
-      if (o2) {
-        var a2 = e4.indexOf(o2);
-        -1 !== a2 && (t4 = a2);
-      }
-      return s2(e4, t4, r2);
-    }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" };
-  }(), n2.enc.Base64);
-});
-const c = "FUNCTION", u = "OBJECT", l = "CLIENT_DB", h = "pending", d = "fulfilled", p = "rejected";
-function f(e2) {
-  return Object.prototype.toString.call(e2).slice(8, -1).toLowerCase();
-}
-function g(e2) {
-  return "object" === f(e2);
-}
-function m(e2) {
-  return "function" == typeof e2;
-}
-function y(e2) {
-  return function() {
-    try {
-      return e2.apply(e2, arguments);
-    } catch (e3) {
-      console.error(e3);
-    }
-  };
-}
-const _ = "REJECTED", w = "NOT_PENDING";
-class v {
-  constructor({ createPromise: e2, retryRule: t2 = _ } = {}) {
-    this.createPromise = e2, this.status = null, this.promise = null, this.retryRule = t2;
-  }
-  get needRetry() {
-    if (!this.status)
-      return true;
-    switch (this.retryRule) {
-      case _:
-        return this.status === p;
-      case w:
-        return this.status !== h;
-    }
-  }
-  exec() {
-    return this.needRetry ? (this.status = h, this.promise = this.createPromise().then((e2) => (this.status = d, Promise.resolve(e2)), (e2) => (this.status = p, Promise.reject(e2))), this.promise) : this.promise;
-  }
-}
-function I(e2) {
-  return e2 && "string" == typeof e2 ? JSON.parse(e2) : e2;
-}
-const S = true, b = "mp-weixin", A = I(define_process_env_UNI_SECURE_NETWORK_CONFIG_default), C = b, P = I(""), T = I("[]") || [];
-let O = "";
-try {
-  O = "__UNI__97986D6";
-} catch (e2) {
-}
-let E = {};
-function L(e2, t2 = {}) {
-  var n2, s2;
-  return n2 = E, s2 = e2, Object.prototype.hasOwnProperty.call(n2, s2) || (E[e2] = t2), E[e2];
-}
-const R = ["invoke", "success", "fail", "complete"], U = L("_globalUniCloudInterceptor");
-function N(e2, t2) {
-  U[e2] || (U[e2] = {}), g(t2) && Object.keys(t2).forEach((n2) => {
-    R.indexOf(n2) > -1 && function(e3, t3, n3) {
-      let s2 = U[e3][t3];
-      s2 || (s2 = U[e3][t3] = []), -1 === s2.indexOf(n3) && m(n3) && s2.push(n3);
-    }(e2, n2, t2[n2]);
-  });
-}
-function D(e2, t2) {
-  U[e2] || (U[e2] = {}), g(t2) ? Object.keys(t2).forEach((n2) => {
-    R.indexOf(n2) > -1 && function(e3, t3, n3) {
-      const s2 = U[e3][t3];
-      if (!s2)
-        return;
-      const r2 = s2.indexOf(n3);
-      r2 > -1 && s2.splice(r2, 1);
-    }(e2, n2, t2[n2]);
-  }) : delete U[e2];
-}
-function M(e2, t2) {
-  return e2 && 0 !== e2.length ? e2.reduce((e3, n2) => e3.then(() => n2(t2)), Promise.resolve()) : Promise.resolve();
-}
-function q(e2, t2) {
-  return U[e2] && U[e2][t2] || [];
-}
-function F(e2) {
-  N("callObject", e2);
-}
-const K = L("_globalUniCloudListener"), j = "response", $ = "needLogin", B = "refreshToken", W = "clientdb", H = "cloudfunction", J = "cloudobject";
-function z(e2) {
-  return K[e2] || (K[e2] = []), K[e2];
-}
-function V(e2, t2) {
-  const n2 = z(e2);
-  n2.includes(t2) || n2.push(t2);
-}
-function G(e2, t2) {
-  const n2 = z(e2), s2 = n2.indexOf(t2);
-  -1 !== s2 && n2.splice(s2, 1);
-}
-function Y(e2, t2) {
-  const n2 = z(e2);
-  for (let e3 = 0; e3 < n2.length; e3++) {
-    (0, n2[e3])(t2);
-  }
-}
-let Q, X = false;
-function Z() {
-  return Q || (Q = new Promise((e2) => {
-    X && e2(), function t2() {
-      if ("function" == typeof getCurrentPages) {
-        const t3 = getCurrentPages();
-        t3 && t3[0] && (X = true, e2());
-      }
-      X || setTimeout(() => {
-        t2();
-      }, 30);
-    }();
-  }), Q);
-}
-function ee(e2) {
-  const t2 = {};
-  for (const n2 in e2) {
-    const s2 = e2[n2];
-    m(s2) && (t2[n2] = y(s2));
-  }
-  return t2;
-}
-class te extends Error {
-  constructor(e2) {
-    super(e2.message), this.errMsg = e2.message || e2.errMsg || "unknown system error", this.code = this.errCode = e2.code || e2.errCode || "SYSTEM_ERROR", this.errSubject = this.subject = e2.subject || e2.errSubject, this.cause = e2.cause, this.requestId = e2.requestId;
-  }
-  toJson(e2 = 0) {
-    if (!(e2 >= 10))
-      return e2++, { errCode: this.errCode, errMsg: this.errMsg, errSubject: this.errSubject, cause: this.cause && this.cause.toJson ? this.cause.toJson(e2) : this.cause };
-  }
-}
-var ne = { request: (e2) => index.request(e2), uploadFile: (e2) => index.uploadFile(e2), setStorageSync: (e2, t2) => index.setStorageSync(e2, t2), getStorageSync: (e2) => index.getStorageSync(e2), removeStorageSync: (e2) => index.removeStorageSync(e2), clearStorageSync: () => index.clearStorageSync(), connectSocket: (e2) => index.connectSocket(e2) };
-function se(e2) {
-  return e2 && se(e2.__v_raw) || e2;
-}
-function re() {
-  return { token: ne.getStorageSync("uni_id_token") || ne.getStorageSync("uniIdToken"), tokenExpired: ne.getStorageSync("uni_id_token_expired") };
-}
-function ie({ token: e2, tokenExpired: t2 } = {}) {
-  e2 && ne.setStorageSync("uni_id_token", e2), t2 && ne.setStorageSync("uni_id_token_expired", t2);
-}
-let oe, ae;
-function ce() {
-  return oe || (oe = index.getSystemInfoSync()), oe;
-}
-function ue() {
-  let e2, t2;
-  try {
-    if (index.getLaunchOptionsSync) {
-      if (index.getLaunchOptionsSync.toString().indexOf("not yet implemented") > -1)
-        return;
-      const { scene: n2, channel: s2 } = index.getLaunchOptionsSync();
-      e2 = s2, t2 = n2;
-    }
-  } catch (e3) {
-  }
-  return { channel: e2, scene: t2 };
-}
-let le = {};
-function he() {
-  const e2 = index.getLocale && index.getLocale() || "en";
-  if (ae)
-    return { ...le, ...ae, locale: e2, LOCALE: e2 };
-  const t2 = ce(), { deviceId: n2, osName: s2, uniPlatform: r2, appId: i2 } = t2, o2 = ["appId", "appLanguage", "appName", "appVersion", "appVersionCode", "appWgtVersion", "browserName", "browserVersion", "deviceBrand", "deviceId", "deviceModel", "deviceType", "osName", "osVersion", "romName", "romVersion", "ua", "hostName", "hostVersion", "uniPlatform", "uniRuntimeVersion", "uniRuntimeVersionCode", "uniCompilerVersion", "uniCompilerVersionCode"];
-  for (const e3 in t2)
-    Object.hasOwnProperty.call(t2, e3) && -1 === o2.indexOf(e3) && delete t2[e3];
-  return ae = { PLATFORM: r2, OS: s2, APPID: i2, DEVICEID: n2, ...ue(), ...t2 }, { ...le, ...ae, locale: e2, LOCALE: e2 };
-}
-var de = { sign: function(e2, t2) {
-  let n2 = "";
-  return Object.keys(e2).sort().forEach(function(t3) {
-    e2[t3] && (n2 = n2 + "&" + t3 + "=" + e2[t3]);
-  }), n2 = n2.slice(1), i(n2, t2).toString();
-}, wrappedRequest: function(e2, t2) {
-  return new Promise((n2, s2) => {
-    t2(Object.assign(e2, { complete(e3) {
-      e3 || (e3 = {});
-      const t3 = e3.data && e3.data.header && e3.data.header["x-serverless-request-id"] || e3.header && e3.header["request-id"];
-      if (!e3.statusCode || e3.statusCode >= 400) {
-        const n3 = e3.data && e3.data.error && e3.data.error.code || "SYS_ERR", r3 = e3.data && e3.data.error && e3.data.error.message || e3.errMsg || "request:fail";
-        return s2(new te({ code: n3, message: r3, requestId: t3 }));
-      }
-      const r2 = e3.data;
-      if (r2.error)
-        return s2(new te({ code: r2.error.code, message: r2.error.message, requestId: t3 }));
-      r2.result = r2.data, r2.requestId = t3, delete r2.data, n2(r2);
-    } }));
-  });
-}, toBase64: function(e2) {
-  return a.stringify(o.parse(e2));
-} };
-var pe = class {
-  constructor(e2) {
-    ["spaceId", "clientSecret"].forEach((t2) => {
-      if (!Object.prototype.hasOwnProperty.call(e2, t2))
-        throw new Error(`${t2} required`);
-    }), this.config = Object.assign({}, { endpoint: 0 === e2.spaceId.indexOf("mp-") ? "https://api.next.bspapp.com" : "https://api.bspapp.com" }, e2), this.config.provider = "aliyun", this.config.requestUrl = this.config.endpoint + "/client", this.config.envType = this.config.envType || "public", this.config.accessTokenKey = "access_token_" + this.config.spaceId, this.adapter = ne, this._getAccessTokenPromiseHub = new v({ createPromise: () => this.requestAuth(this.setupRequest({ method: "serverless.auth.user.anonymousAuthorize", params: "{}" }, "auth")).then((e3) => {
-      if (!e3.result || !e3.result.accessToken)
-        throw new te({ code: "AUTH_FAILED", message: "获取accessToken失败" });
-      this.setAccessToken(e3.result.accessToken);
-    }), retryRule: w });
-  }
-  get hasAccessToken() {
-    return !!this.accessToken;
-  }
-  setAccessToken(e2) {
-    this.accessToken = e2;
-  }
-  requestWrapped(e2) {
-    return de.wrappedRequest(e2, this.adapter.request);
-  }
-  requestAuth(e2) {
-    return this.requestWrapped(e2);
-  }
-  request(e2, t2) {
-    return Promise.resolve().then(() => this.hasAccessToken ? t2 ? this.requestWrapped(e2) : this.requestWrapped(e2).catch((t3) => new Promise((e3, n2) => {
-      !t3 || "GATEWAY_INVALID_TOKEN" !== t3.code && "InvalidParameter.InvalidToken" !== t3.code ? n2(t3) : e3();
-    }).then(() => this.getAccessToken()).then(() => {
-      const t4 = this.rebuildRequest(e2);
-      return this.request(t4, true);
-    })) : this.getAccessToken().then(() => {
-      const t3 = this.rebuildRequest(e2);
-      return this.request(t3, true);
-    }));
-  }
-  rebuildRequest(e2) {
-    const t2 = Object.assign({}, e2);
-    return t2.data.token = this.accessToken, t2.header["x-basement-token"] = this.accessToken, t2.header["x-serverless-sign"] = de.sign(t2.data, this.config.clientSecret), t2;
-  }
-  setupRequest(e2, t2) {
-    const n2 = Object.assign({}, e2, { spaceId: this.config.spaceId, timestamp: Date.now() }), s2 = { "Content-Type": "application/json" };
-    return "auth" !== t2 && (n2.token = this.accessToken, s2["x-basement-token"] = this.accessToken), s2["x-serverless-sign"] = de.sign(n2, this.config.clientSecret), { url: this.config.requestUrl, method: "POST", data: n2, dataType: "json", header: s2 };
-  }
-  getAccessToken() {
-    return this._getAccessTokenPromiseHub.exec();
-  }
-  async authorize() {
-    await this.getAccessToken();
-  }
-  callFunction(e2) {
-    const t2 = { method: "serverless.function.runtime.invoke", params: JSON.stringify({ functionTarget: e2.name, functionArgs: e2.data || {} }) };
-    return this.request({ ...this.setupRequest(t2), timeout: e2.timeout });
-  }
-  getOSSUploadOptionsFromPath(e2) {
-    const t2 = { method: "serverless.file.resource.generateProximalSign", params: JSON.stringify(e2) };
-    return this.request(this.setupRequest(t2));
-  }
-  uploadFileToOSS({ url: e2, formData: t2, name: n2, filePath: s2, fileType: r2, onUploadProgress: i2 }) {
-    return new Promise((o2, a2) => {
-      const c2 = this.adapter.uploadFile({ url: e2, formData: t2, name: n2, filePath: s2, fileType: r2, header: { "X-OSS-server-side-encrpytion": "AES256" }, success(e3) {
-        e3 && e3.statusCode < 400 ? o2(e3) : a2(new te({ code: "UPLOAD_FAILED", message: "文件上传失败" }));
-      }, fail(e3) {
-        a2(new te({ code: e3.code || "UPLOAD_FAILED", message: e3.message || e3.errMsg || "文件上传失败" }));
-      } });
-      "function" == typeof i2 && c2 && "function" == typeof c2.onProgressUpdate && c2.onProgressUpdate((e3) => {
-        i2({ loaded: e3.totalBytesSent, total: e3.totalBytesExpectedToSend });
-      });
-    });
-  }
-  reportOSSUpload(e2) {
-    const t2 = { method: "serverless.file.resource.report", params: JSON.stringify(e2) };
-    return this.request(this.setupRequest(t2));
-  }
-  async uploadFile({ filePath: e2, cloudPath: t2, fileType: n2 = "image", cloudPathAsRealPath: s2 = false, onUploadProgress: r2, config: i2 }) {
-    if ("string" !== f(t2))
-      throw new te({ code: "INVALID_PARAM", message: "cloudPath必须为字符串类型" });
-    if (!(t2 = t2.trim()))
-      throw new te({ code: "INVALID_PARAM", message: "cloudPath不可为空" });
-    if (/:\/\//.test(t2))
-      throw new te({ code: "INVALID_PARAM", message: "cloudPath不合法" });
-    const o2 = i2 && i2.envType || this.config.envType;
-    if (s2 && ("/" !== t2[0] && (t2 = "/" + t2), t2.indexOf("\\") > -1))
-      throw new te({ code: "INVALID_PARAM", message: "使用cloudPath作为路径时,cloudPath不可包含“\\”" });
-    const a2 = (await this.getOSSUploadOptionsFromPath({ env: o2, filename: s2 ? t2.split("/").pop() : t2, fileId: s2 ? t2 : void 0 })).result, c2 = "https://" + a2.cdnDomain + "/" + a2.ossPath, { securityToken: u2, accessKeyId: l2, signature: h2, host: d2, ossPath: p2, id: g2, policy: m2, ossCallbackUrl: y2 } = a2, _2 = { "Cache-Control": "max-age=2592000", "Content-Disposition": "attachment", OSSAccessKeyId: l2, Signature: h2, host: d2, id: g2, key: p2, policy: m2, success_action_status: 200 };
-    if (u2 && (_2["x-oss-security-token"] = u2), y2) {
-      const e3 = JSON.stringify({ callbackUrl: y2, callbackBody: JSON.stringify({ fileId: g2, spaceId: this.config.spaceId }), callbackBodyType: "application/json" });
-      _2.callback = de.toBase64(e3);
-    }
-    const w2 = { url: "https://" + a2.host, formData: _2, fileName: "file", name: "file", filePath: e2, fileType: n2 };
-    if (await this.uploadFileToOSS(Object.assign({}, w2, { onUploadProgress: r2 })), y2)
-      return { success: true, filePath: e2, fileID: c2 };
-    if ((await this.reportOSSUpload({ id: g2 })).success)
-      return { success: true, filePath: e2, fileID: c2 };
-    throw new te({ code: "UPLOAD_FAILED", message: "文件上传失败" });
-  }
-  getTempFileURL({ fileList: e2 } = {}) {
-    return new Promise((t2, n2) => {
-      Array.isArray(e2) && 0 !== e2.length || n2(new te({ code: "INVALID_PARAM", message: "fileList的元素必须是非空的字符串" })), t2({ fileList: e2.map((e3) => ({ fileID: e3, tempFileURL: e3 })) });
-    });
-  }
-  async getFileInfo({ fileList: e2 } = {}) {
-    if (!Array.isArray(e2) || 0 === e2.length)
-      throw new te({ code: "INVALID_PARAM", message: "fileList的元素必须是非空的字符串" });
-    const t2 = { method: "serverless.file.resource.info", params: JSON.stringify({ id: e2.map((e3) => e3.split("?")[0]).join(",") }) };
-    return { fileList: (await this.request(this.setupRequest(t2))).result };
-  }
-};
-var fe = { init(e2) {
-  const t2 = new pe(e2), n2 = { signInAnonymously: function() {
-    return t2.authorize();
-  }, getLoginState: function() {
-    return Promise.resolve(false);
-  } };
-  return t2.auth = function() {
-    return n2;
-  }, t2.customAuth = t2.auth, t2;
-} };
-const ge = "undefined" != typeof location && "http:" === location.protocol ? "http:" : "https:";
-var me;
-!function(e2) {
-  e2.local = "local", e2.none = "none", e2.session = "session";
-}(me || (me = {}));
-var ye = function() {
-}, _e = n(function(e2, t2) {
-  var n2;
-  e2.exports = (n2 = r, function(e3) {
-    var t3 = n2, s2 = t3.lib, r2 = s2.WordArray, i2 = s2.Hasher, o2 = t3.algo, a2 = [], c2 = [];
-    !function() {
-      function t4(t5) {
-        for (var n4 = e3.sqrt(t5), s4 = 2; s4 <= n4; s4++)
-          if (!(t5 % s4))
-            return false;
-        return true;
-      }
-      function n3(e4) {
-        return 4294967296 * (e4 - (0 | e4)) | 0;
-      }
-      for (var s3 = 2, r3 = 0; r3 < 64; )
-        t4(s3) && (r3 < 8 && (a2[r3] = n3(e3.pow(s3, 0.5))), c2[r3] = n3(e3.pow(s3, 1 / 3)), r3++), s3++;
-    }();
-    var u2 = [], l2 = o2.SHA256 = i2.extend({ _doReset: function() {
-      this._hash = new r2.init(a2.slice(0));
-    }, _doProcessBlock: function(e4, t4) {
-      for (var n3 = this._hash.words, s3 = n3[0], r3 = n3[1], i3 = n3[2], o3 = n3[3], a3 = n3[4], l3 = n3[5], h2 = n3[6], d2 = n3[7], p2 = 0; p2 < 64; p2++) {
-        if (p2 < 16)
-          u2[p2] = 0 | e4[t4 + p2];
-        else {
-          var f2 = u2[p2 - 15], g2 = (f2 << 25 | f2 >>> 7) ^ (f2 << 14 | f2 >>> 18) ^ f2 >>> 3, m2 = u2[p2 - 2], y2 = (m2 << 15 | m2 >>> 17) ^ (m2 << 13 | m2 >>> 19) ^ m2 >>> 10;
-          u2[p2] = g2 + u2[p2 - 7] + y2 + u2[p2 - 16];
-        }
-        var _2 = s3 & r3 ^ s3 & i3 ^ r3 & i3, w2 = (s3 << 30 | s3 >>> 2) ^ (s3 << 19 | s3 >>> 13) ^ (s3 << 10 | s3 >>> 22), v2 = d2 + ((a3 << 26 | a3 >>> 6) ^ (a3 << 21 | a3 >>> 11) ^ (a3 << 7 | a3 >>> 25)) + (a3 & l3 ^ ~a3 & h2) + c2[p2] + u2[p2];
-        d2 = h2, h2 = l3, l3 = a3, a3 = o3 + v2 | 0, o3 = i3, i3 = r3, r3 = s3, s3 = v2 + (w2 + _2) | 0;
-      }
-      n3[0] = n3[0] + s3 | 0, n3[1] = n3[1] + r3 | 0, n3[2] = n3[2] + i3 | 0, n3[3] = n3[3] + o3 | 0, n3[4] = n3[4] + a3 | 0, n3[5] = n3[5] + l3 | 0, n3[6] = n3[6] + h2 | 0, n3[7] = n3[7] + d2 | 0;
-    }, _doFinalize: function() {
-      var t4 = this._data, n3 = t4.words, s3 = 8 * this._nDataBytes, r3 = 8 * t4.sigBytes;
-      return n3[r3 >>> 5] |= 128 << 24 - r3 % 32, n3[14 + (r3 + 64 >>> 9 << 4)] = e3.floor(s3 / 4294967296), n3[15 + (r3 + 64 >>> 9 << 4)] = s3, t4.sigBytes = 4 * n3.length, this._process(), this._hash;
-    }, clone: function() {
-      var e4 = i2.clone.call(this);
-      return e4._hash = this._hash.clone(), e4;
-    } });
-    t3.SHA256 = i2._createHelper(l2), t3.HmacSHA256 = i2._createHmacHelper(l2);
-  }(Math), n2.SHA256);
-}), we = _e, ve = n(function(e2, t2) {
-  e2.exports = r.HmacSHA256;
-});
-const Ie = () => {
-  let e2;
-  if (!Promise) {
-    e2 = () => {
-    }, e2.promise = {};
-    const t3 = () => {
-      throw new te({ message: 'Your Node runtime does support ES6 Promises. Set "global.Promise" to your preferred implementation of promises.' });
-    };
-    return Object.defineProperty(e2.promise, "then", { get: t3 }), Object.defineProperty(e2.promise, "catch", { get: t3 }), e2;
-  }
-  const t2 = new Promise((t3, n2) => {
-    e2 = (e3, s2) => e3 ? n2(e3) : t3(s2);
-  });
-  return e2.promise = t2, e2;
-};
-function Se(e2) {
-  return void 0 === e2;
-}
-function be(e2) {
-  return "[object Null]" === Object.prototype.toString.call(e2);
-}
-var ke;
-function Ae(e2) {
-  const t2 = (n2 = e2, "[object Array]" === Object.prototype.toString.call(n2) ? e2 : [e2]);
-  var n2;
-  for (const e3 of t2) {
-    const { isMatch: t3, genAdapter: n3, runtime: s2 } = e3;
-    if (t3())
-      return { adapter: n3(), runtime: s2 };
-  }
-}
-!function(e2) {
-  e2.WEB = "web", e2.WX_MP = "wx_mp";
-}(ke || (ke = {}));
-const Ce = { adapter: null, runtime: void 0 }, Pe = ["anonymousUuidKey"];
-class Te extends ye {
-  constructor() {
-    super(), Ce.adapter.root.tcbObject || (Ce.adapter.root.tcbObject = {});
-  }
-  setItem(e2, t2) {
-    Ce.adapter.root.tcbObject[e2] = t2;
-  }
-  getItem(e2) {
-    return Ce.adapter.root.tcbObject[e2];
-  }
-  removeItem(e2) {
-    delete Ce.adapter.root.tcbObject[e2];
-  }
-  clear() {
-    delete Ce.adapter.root.tcbObject;
-  }
-}
-function xe(e2, t2) {
-  switch (e2) {
-    case "local":
-      return t2.localStorage || new Te();
-    case "none":
-      return new Te();
-    default:
-      return t2.sessionStorage || new Te();
-  }
-}
-class Oe {
-  constructor(e2) {
-    if (!this._storage) {
-      this._persistence = Ce.adapter.primaryStorage || e2.persistence, this._storage = xe(this._persistence, Ce.adapter);
-      const t2 = `access_token_${e2.env}`, n2 = `access_token_expire_${e2.env}`, s2 = `refresh_token_${e2.env}`, r2 = `anonymous_uuid_${e2.env}`, i2 = `login_type_${e2.env}`, o2 = `user_info_${e2.env}`;
-      this.keys = { accessTokenKey: t2, accessTokenExpireKey: n2, refreshTokenKey: s2, anonymousUuidKey: r2, loginTypeKey: i2, userInfoKey: o2 };
-    }
-  }
-  updatePersistence(e2) {
-    if (e2 === this._persistence)
-      return;
-    const t2 = "local" === this._persistence;
-    this._persistence = e2;
-    const n2 = xe(e2, Ce.adapter);
-    for (const e3 in this.keys) {
-      const s2 = this.keys[e3];
-      if (t2 && Pe.includes(e3))
-        continue;
-      const r2 = this._storage.getItem(s2);
-      Se(r2) || be(r2) || (n2.setItem(s2, r2), this._storage.removeItem(s2));
-    }
-    this._storage = n2;
-  }
-  setStore(e2, t2, n2) {
-    if (!this._storage)
-      return;
-    const s2 = { version: n2 || "localCachev1", content: t2 }, r2 = JSON.stringify(s2);
-    try {
-      this._storage.setItem(e2, r2);
-    } catch (e3) {
-      throw e3;
-    }
-  }
-  getStore(e2, t2) {
-    try {
-      if (!this._storage)
-        return;
-    } catch (e3) {
-      return "";
-    }
-    t2 = t2 || "localCachev1";
-    const n2 = this._storage.getItem(e2);
-    if (!n2)
-      return "";
-    if (n2.indexOf(t2) >= 0) {
-      return JSON.parse(n2).content;
-    }
-    return "";
-  }
-  removeStore(e2) {
-    this._storage.removeItem(e2);
-  }
-}
-const Ee = {}, Le = {};
-function Re(e2) {
-  return Ee[e2];
-}
-class Ue {
-  constructor(e2, t2) {
-    this.data = t2 || null, this.name = e2;
-  }
-}
-class Ne extends Ue {
-  constructor(e2, t2) {
-    super("error", { error: e2, data: t2 }), this.error = e2;
-  }
-}
-const De = new class {
-  constructor() {
-    this._listeners = {};
-  }
-  on(e2, t2) {
-    return function(e3, t3, n2) {
-      n2[e3] = n2[e3] || [], n2[e3].push(t3);
-    }(e2, t2, this._listeners), this;
-  }
-  off(e2, t2) {
-    return function(e3, t3, n2) {
-      if (n2 && n2[e3]) {
-        const s2 = n2[e3].indexOf(t3);
-        -1 !== s2 && n2[e3].splice(s2, 1);
-      }
-    }(e2, t2, this._listeners), this;
-  }
-  fire(e2, t2) {
-    if (e2 instanceof Ne)
-      return console.error(e2.error), this;
-    const n2 = "string" == typeof e2 ? new Ue(e2, t2 || {}) : e2;
-    const s2 = n2.name;
-    if (this._listens(s2)) {
-      n2.target = this;
-      const e3 = this._listeners[s2] ? [...this._listeners[s2]] : [];
-      for (const t3 of e3)
-        t3.call(this, n2);
-    }
-    return this;
-  }
-  _listens(e2) {
-    return this._listeners[e2] && this._listeners[e2].length > 0;
-  }
-}();
-function Me(e2, t2) {
-  De.on(e2, t2);
-}
-function qe(e2, t2 = {}) {
-  De.fire(e2, t2);
-}
-function Fe(e2, t2) {
-  De.off(e2, t2);
-}
-const Ke = "loginStateChanged", je = "loginStateExpire", $e = "loginTypeChanged", Be = "anonymousConverted", We = "refreshAccessToken";
-var He;
-!function(e2) {
-  e2.ANONYMOUS = "ANONYMOUS", e2.WECHAT = "WECHAT", e2.WECHAT_PUBLIC = "WECHAT-PUBLIC", e2.WECHAT_OPEN = "WECHAT-OPEN", e2.CUSTOM = "CUSTOM", e2.EMAIL = "EMAIL", e2.USERNAME = "USERNAME", e2.NULL = "NULL";
-}(He || (He = {}));
-const Je = ["auth.getJwt", "auth.logout", "auth.signInWithTicket", "auth.signInAnonymously", "auth.signIn", "auth.fetchAccessTokenWithRefreshToken", "auth.signUpWithEmailAndPassword", "auth.activateEndUserMail", "auth.sendPasswordResetEmail", "auth.resetPasswordWithToken", "auth.isUsernameRegistered"], ze = { "X-SDK-Version": "1.3.5" };
-function Ve(e2, t2, n2) {
-  const s2 = e2[t2];
-  e2[t2] = function(t3) {
-    const r2 = {}, i2 = {};
-    n2.forEach((n3) => {
-      const { data: s3, headers: o3 } = n3.call(e2, t3);
-      Object.assign(r2, s3), Object.assign(i2, o3);
-    });
-    const o2 = t3.data;
-    return o2 && (() => {
-      var e3;
-      if (e3 = o2, "[object FormData]" !== Object.prototype.toString.call(e3))
-        t3.data = { ...o2, ...r2 };
-      else
-        for (const e4 in r2)
-          o2.append(e4, r2[e4]);
-    })(), t3.headers = { ...t3.headers || {}, ...i2 }, s2.call(e2, t3);
-  };
-}
-function Ge() {
-  const e2 = Math.random().toString(16).slice(2);
-  return { data: { seqId: e2 }, headers: { ...ze, "x-seqid": e2 } };
-}
-class Ye {
-  constructor(e2 = {}) {
-    var t2;
-    this.config = e2, this._reqClass = new Ce.adapter.reqClass({ timeout: this.config.timeout, timeoutMsg: `请求在${this.config.timeout / 1e3}s内未完成,已中断`, restrictedMethods: ["post"] }), this._cache = Re(this.config.env), this._localCache = (t2 = this.config.env, Le[t2]), Ve(this._reqClass, "post", [Ge]), Ve(this._reqClass, "upload", [Ge]), Ve(this._reqClass, "download", [Ge]);
-  }
-  async post(e2) {
-    return await this._reqClass.post(e2);
-  }
-  async upload(e2) {
-    return await this._reqClass.upload(e2);
-  }
-  async download(e2) {
-    return await this._reqClass.download(e2);
-  }
-  async refreshAccessToken() {
-    let e2, t2;
-    this._refreshAccessTokenPromise || (this._refreshAccessTokenPromise = this._refreshAccessToken());
-    try {
-      e2 = await this._refreshAccessTokenPromise;
-    } catch (e3) {
-      t2 = e3;
-    }
-    if (this._refreshAccessTokenPromise = null, this._shouldRefreshAccessTokenHook = null, t2)
-      throw t2;
-    return e2;
-  }
-  async _refreshAccessToken() {
-    const { accessTokenKey: e2, accessTokenExpireKey: t2, refreshTokenKey: n2, loginTypeKey: s2, anonymousUuidKey: r2 } = this._cache.keys;
-    this._cache.removeStore(e2), this._cache.removeStore(t2);
-    let i2 = this._cache.getStore(n2);
-    if (!i2)
-      throw new te({ message: "未登录CloudBase" });
-    const o2 = { refresh_token: i2 }, a2 = await this.request("auth.fetchAccessTokenWithRefreshToken", o2);
-    if (a2.data.code) {
-      const { code: e3 } = a2.data;
-      if ("SIGN_PARAM_INVALID" === e3 || "REFRESH_TOKEN_EXPIRED" === e3 || "INVALID_REFRESH_TOKEN" === e3) {
-        if (this._cache.getStore(s2) === He.ANONYMOUS && "INVALID_REFRESH_TOKEN" === e3) {
-          const e4 = this._cache.getStore(r2), t3 = this._cache.getStore(n2), s3 = await this.send("auth.signInAnonymously", { anonymous_uuid: e4, refresh_token: t3 });
-          return this.setRefreshToken(s3.refresh_token), this._refreshAccessToken();
-        }
-        qe(je), this._cache.removeStore(n2);
-      }
-      throw new te({ code: a2.data.code, message: `刷新access token失败:${a2.data.code}` });
-    }
-    if (a2.data.access_token)
-      return qe(We), this._cache.setStore(e2, a2.data.access_token), this._cache.setStore(t2, a2.data.access_token_expire + Date.now()), { accessToken: a2.data.access_token, accessTokenExpire: a2.data.access_token_expire };
-    a2.data.refresh_token && (this._cache.removeStore(n2), this._cache.setStore(n2, a2.data.refresh_token), this._refreshAccessToken());
-  }
-  async getAccessToken() {
-    const { accessTokenKey: e2, accessTokenExpireKey: t2, refreshTokenKey: n2 } = this._cache.keys;
-    if (!this._cache.getStore(n2))
-      throw new te({ message: "refresh token不存在,登录状态异常" });
-    let s2 = this._cache.getStore(e2), r2 = this._cache.getStore(t2), i2 = true;
-    return this._shouldRefreshAccessTokenHook && !await this._shouldRefreshAccessTokenHook(s2, r2) && (i2 = false), (!s2 || !r2 || r2 < Date.now()) && i2 ? this.refreshAccessToken() : { accessToken: s2, accessTokenExpire: r2 };
-  }
-  async request(e2, t2, n2) {
-    const s2 = `x-tcb-trace_${this.config.env}`;
-    let r2 = "application/x-www-form-urlencoded";
-    const i2 = { action: e2, env: this.config.env, dataVersion: "2019-08-16", ...t2 };
-    if (-1 === Je.indexOf(e2)) {
-      const { refreshTokenKey: e3 } = this._cache.keys;
-      this._cache.getStore(e3) && (i2.access_token = (await this.getAccessToken()).accessToken);
-    }
-    let o2;
-    if ("storage.uploadFile" === e2) {
-      o2 = new FormData();
-      for (let e3 in o2)
-        o2.hasOwnProperty(e3) && void 0 !== o2[e3] && o2.append(e3, i2[e3]);
-      r2 = "multipart/form-data";
-    } else {
-      r2 = "application/json", o2 = {};
-      for (let e3 in i2)
-        void 0 !== i2[e3] && (o2[e3] = i2[e3]);
-    }
-    let a2 = { headers: { "content-type": r2 } };
-    n2 && n2.timeout && (a2.timeout = n2.timeout), n2 && n2.onUploadProgress && (a2.onUploadProgress = n2.onUploadProgress);
-    const c2 = this._localCache.getStore(s2);
-    c2 && (a2.headers["X-TCB-Trace"] = c2);
-    const { parse: u2, inQuery: l2, search: h2 } = t2;
-    let d2 = { env: this.config.env };
-    u2 && (d2.parse = true), l2 && (d2 = { ...l2, ...d2 });
-    let p2 = function(e3, t3, n3 = {}) {
-      const s3 = /\?/.test(t3);
-      let r3 = "";
-      for (let e4 in n3)
-        "" === r3 ? !s3 && (t3 += "?") : r3 += "&", r3 += `${e4}=${encodeURIComponent(n3[e4])}`;
-      return /^http(s)?\:\/\//.test(t3 += r3) ? t3 : `${e3}${t3}`;
-    }(ge, "//tcb-api.tencentcloudapi.com/web", d2);
-    h2 && (p2 += h2);
-    const f2 = await this.post({ url: p2, data: o2, ...a2 }), g2 = f2.header && f2.header["x-tcb-trace"];
-    if (g2 && this._localCache.setStore(s2, g2), 200 !== Number(f2.status) && 200 !== Number(f2.statusCode) || !f2.data)
-      throw new te({ code: "NETWORK_ERROR", message: "network request error" });
-    return f2;
-  }
-  async send(e2, t2 = {}, n2 = {}) {
-    const s2 = await this.request(e2, t2, { ...n2, onUploadProgress: t2.onUploadProgress });
-    if ("ACCESS_TOKEN_EXPIRED" === s2.data.code && -1 === Je.indexOf(e2)) {
-      await this.refreshAccessToken();
-      const s3 = await this.request(e2, t2, { ...n2, onUploadProgress: t2.onUploadProgress });
-      if (s3.data.code)
-        throw new te({ code: s3.data.code, message: s3.data.message });
-      return s3.data;
-    }
-    if (s2.data.code)
-      throw new te({ code: s2.data.code, message: s2.data.message });
-    return s2.data;
-  }
-  setRefreshToken(e2) {
-    const { accessTokenKey: t2, accessTokenExpireKey: n2, refreshTokenKey: s2 } = this._cache.keys;
-    this._cache.removeStore(t2), this._cache.removeStore(n2), this._cache.setStore(s2, e2);
-  }
-}
-const Qe = {};
-function Xe(e2) {
-  return Qe[e2];
-}
-class Ze {
-  constructor(e2) {
-    this.config = e2, this._cache = Re(e2.env), this._request = Xe(e2.env);
-  }
-  setRefreshToken(e2) {
-    const { accessTokenKey: t2, accessTokenExpireKey: n2, refreshTokenKey: s2 } = this._cache.keys;
-    this._cache.removeStore(t2), this._cache.removeStore(n2), this._cache.setStore(s2, e2);
-  }
-  setAccessToken(e2, t2) {
-    const { accessTokenKey: n2, accessTokenExpireKey: s2 } = this._cache.keys;
-    this._cache.setStore(n2, e2), this._cache.setStore(s2, t2);
-  }
-  async refreshUserInfo() {
-    const { data: e2 } = await this._request.send("auth.getUserInfo", {});
-    return this.setLocalUserInfo(e2), e2;
-  }
-  setLocalUserInfo(e2) {
-    const { userInfoKey: t2 } = this._cache.keys;
-    this._cache.setStore(t2, e2);
-  }
-}
-class et {
-  constructor(e2) {
-    if (!e2)
-      throw new te({ code: "PARAM_ERROR", message: "envId is not defined" });
-    this._envId = e2, this._cache = Re(this._envId), this._request = Xe(this._envId), this.setUserInfo();
-  }
-  linkWithTicket(e2) {
-    if ("string" != typeof e2)
-      throw new te({ code: "PARAM_ERROR", message: "ticket must be string" });
-    return this._request.send("auth.linkWithTicket", { ticket: e2 });
-  }
-  linkWithRedirect(e2) {
-    e2.signInWithRedirect();
-  }
-  updatePassword(e2, t2) {
-    return this._request.send("auth.updatePassword", { oldPassword: t2, newPassword: e2 });
-  }
-  updateEmail(e2) {
-    return this._request.send("auth.updateEmail", { newEmail: e2 });
-  }
-  updateUsername(e2) {
-    if ("string" != typeof e2)
-      throw new te({ code: "PARAM_ERROR", message: "username must be a string" });
-    return this._request.send("auth.updateUsername", { username: e2 });
-  }
-  async getLinkedUidList() {
-    const { data: e2 } = await this._request.send("auth.getLinkedUidList", {});
-    let t2 = false;
-    const { users: n2 } = e2;
-    return n2.forEach((e3) => {
-      e3.wxOpenId && e3.wxPublicId && (t2 = true);
-    }), { users: n2, hasPrimaryUid: t2 };
-  }
-  setPrimaryUid(e2) {
-    return this._request.send("auth.setPrimaryUid", { uid: e2 });
-  }
-  unlink(e2) {
-    return this._request.send("auth.unlink", { platform: e2 });
-  }
-  async update(e2) {
-    const { nickName: t2, gender: n2, avatarUrl: s2, province: r2, country: i2, city: o2 } = e2, { data: a2 } = await this._request.send("auth.updateUserInfo", { nickName: t2, gender: n2, avatarUrl: s2, province: r2, country: i2, city: o2 });
-    this.setLocalUserInfo(a2);
-  }
-  async refresh() {
-    const { data: e2 } = await this._request.send("auth.getUserInfo", {});
-    return this.setLocalUserInfo(e2), e2;
-  }
-  setUserInfo() {
-    const { userInfoKey: e2 } = this._cache.keys, t2 = this._cache.getStore(e2);
-    ["uid", "loginType", "openid", "wxOpenId", "wxPublicId", "unionId", "qqMiniOpenId", "email", "hasPassword", "customUserId", "nickName", "gender", "avatarUrl"].forEach((e3) => {
-      this[e3] = t2[e3];
-    }), this.location = { country: t2.country, province: t2.province, city: t2.city };
-  }
-  setLocalUserInfo(e2) {
-    const { userInfoKey: t2 } = this._cache.keys;
-    this._cache.setStore(t2, e2), this.setUserInfo();
-  }
-}
-class tt {
-  constructor(e2) {
-    if (!e2)
-      throw new te({ code: "PARAM_ERROR", message: "envId is not defined" });
-    this._cache = Re(e2);
-    const { refreshTokenKey: t2, accessTokenKey: n2, accessTokenExpireKey: s2 } = this._cache.keys, r2 = this._cache.getStore(t2), i2 = this._cache.getStore(n2), o2 = this._cache.getStore(s2);
-    this.credential = { refreshToken: r2, accessToken: i2, accessTokenExpire: o2 }, this.user = new et(e2);
-  }
-  get isAnonymousAuth() {
-    return this.loginType === He.ANONYMOUS;
-  }
-  get isCustomAuth() {
-    return this.loginType === He.CUSTOM;
-  }
-  get isWeixinAuth() {
-    return this.loginType === He.WECHAT || this.loginType === He.WECHAT_OPEN || this.loginType === He.WECHAT_PUBLIC;
-  }
-  get loginType() {
-    return this._cache.getStore(this._cache.keys.loginTypeKey);
-  }
-}
-class nt extends Ze {
-  async signIn() {
-    this._cache.updatePersistence("local");
-    const { anonymousUuidKey: e2, refreshTokenKey: t2 } = this._cache.keys, n2 = this._cache.getStore(e2) || void 0, s2 = this._cache.getStore(t2) || void 0, r2 = await this._request.send("auth.signInAnonymously", { anonymous_uuid: n2, refresh_token: s2 });
-    if (r2.uuid && r2.refresh_token) {
-      this._setAnonymousUUID(r2.uuid), this.setRefreshToken(r2.refresh_token), await this._request.refreshAccessToken(), qe(Ke), qe($e, { env: this.config.env, loginType: He.ANONYMOUS, persistence: "local" });
-      const e3 = new tt(this.config.env);
-      return await e3.user.refresh(), e3;
-    }
-    throw new te({ message: "匿名登录失败" });
-  }
-  async linkAndRetrieveDataWithTicket(e2) {
-    const { anonymousUuidKey: t2, refreshTokenKey: n2 } = this._cache.keys, s2 = this._cache.getStore(t2), r2 = this._cache.getStore(n2), i2 = await this._request.send("auth.linkAndRetrieveDataWithTicket", { anonymous_uuid: s2, refresh_token: r2, ticket: e2 });
-    if (i2.refresh_token)
-      return this._clearAnonymousUUID(), this.setRefreshToken(i2.refresh_token), await this._request.refreshAccessToken(), qe(Be, { env: this.config.env }), qe($e, { loginType: He.CUSTOM, persistence: "local" }), { credential: { refreshToken: i2.refresh_token } };
-    throw new te({ message: "匿名转化失败" });
-  }
-  _setAnonymousUUID(e2) {
-    const { anonymousUuidKey: t2, loginTypeKey: n2 } = this._cache.keys;
-    this._cache.removeStore(t2), this._cache.setStore(t2, e2), this._cache.setStore(n2, He.ANONYMOUS);
-  }
-  _clearAnonymousUUID() {
-    this._cache.removeStore(this._cache.keys.anonymousUuidKey);
-  }
-}
-class st extends Ze {
-  async signIn(e2) {
-    if ("string" != typeof e2)
-      throw new te({ code: "PARAM_ERROR", message: "ticket must be a string" });
-    const { refreshTokenKey: t2 } = this._cache.keys, n2 = await this._request.send("auth.signInWithTicket", { ticket: e2, refresh_token: this._cache.getStore(t2) || "" });
-    if (n2.refresh_token)
-      return this.setRefreshToken(n2.refresh_token), await this._request.refreshAccessToken(), qe(Ke), qe($e, { env: this.config.env, loginType: He.CUSTOM, persistence: this.config.persistence }), await this.refreshUserInfo(), new tt(this.config.env);
-    throw new te({ message: "自定义登录失败" });
-  }
-}
-class rt extends Ze {
-  async signIn(e2, t2) {
-    if ("string" != typeof e2)
-      throw new te({ code: "PARAM_ERROR", message: "email must be a string" });
-    const { refreshTokenKey: n2 } = this._cache.keys, s2 = await this._request.send("auth.signIn", { loginType: "EMAIL", email: e2, password: t2, refresh_token: this._cache.getStore(n2) || "" }), { refresh_token: r2, access_token: i2, access_token_expire: o2 } = s2;
-    if (r2)
-      return this.setRefreshToken(r2), i2 && o2 ? this.setAccessToken(i2, o2) : await this._request.refreshAccessToken(), await this.refreshUserInfo(), qe(Ke), qe($e, { env: this.config.env, loginType: He.EMAIL, persistence: this.config.persistence }), new tt(this.config.env);
-    throw s2.code ? new te({ code: s2.code, message: `邮箱登录失败: ${s2.message}` }) : new te({ message: "邮箱登录失败" });
-  }
-  async activate(e2) {
-    return this._request.send("auth.activateEndUserMail", { token: e2 });
-  }
-  async resetPasswordWithToken(e2, t2) {
-    return this._request.send("auth.resetPasswordWithToken", { token: e2, newPassword: t2 });
-  }
-}
-class it extends Ze {
-  async signIn(e2, t2) {
-    if ("string" != typeof e2)
-      throw new te({ code: "PARAM_ERROR", message: "username must be a string" });
-    "string" != typeof t2 && (t2 = "", console.warn("password is empty"));
-    const { refreshTokenKey: n2 } = this._cache.keys, s2 = await this._request.send("auth.signIn", { loginType: He.USERNAME, username: e2, password: t2, refresh_token: this._cache.getStore(n2) || "" }), { refresh_token: r2, access_token_expire: i2, access_token: o2 } = s2;
-    if (r2)
-      return this.setRefreshToken(r2), o2 && i2 ? this.setAccessToken(o2, i2) : await this._request.refreshAccessToken(), await this.refreshUserInfo(), qe(Ke), qe($e, { env: this.config.env, loginType: He.USERNAME, persistence: this.config.persistence }), new tt(this.config.env);
-    throw s2.code ? new te({ code: s2.code, message: `用户名密码登录失败: ${s2.message}` }) : new te({ message: "用户名密码登录失败" });
-  }
-}
-class ot {
-  constructor(e2) {
-    this.config = e2, this._cache = Re(e2.env), this._request = Xe(e2.env), this._onAnonymousConverted = this._onAnonymousConverted.bind(this), this._onLoginTypeChanged = this._onLoginTypeChanged.bind(this), Me($e, this._onLoginTypeChanged);
-  }
-  get currentUser() {
-    const e2 = this.hasLoginState();
-    return e2 && e2.user || null;
-  }
-  get loginType() {
-    return this._cache.getStore(this._cache.keys.loginTypeKey);
-  }
-  anonymousAuthProvider() {
-    return new nt(this.config);
-  }
-  customAuthProvider() {
-    return new st(this.config);
-  }
-  emailAuthProvider() {
-    return new rt(this.config);
-  }
-  usernameAuthProvider() {
-    return new it(this.config);
-  }
-  async signInAnonymously() {
-    return new nt(this.config).signIn();
-  }
-  async signInWithEmailAndPassword(e2, t2) {
-    return new rt(this.config).signIn(e2, t2);
-  }
-  signInWithUsernameAndPassword(e2, t2) {
-    return new it(this.config).signIn(e2, t2);
-  }
-  async linkAndRetrieveDataWithTicket(e2) {
-    this._anonymousAuthProvider || (this._anonymousAuthProvider = new nt(this.config)), Me(Be, this._onAnonymousConverted);
-    return await this._anonymousAuthProvider.linkAndRetrieveDataWithTicket(e2);
-  }
-  async signOut() {
-    if (this.loginType === He.ANONYMOUS)
-      throw new te({ message: "匿名用户不支持登出操作" });
-    const { refreshTokenKey: e2, accessTokenKey: t2, accessTokenExpireKey: n2 } = this._cache.keys, s2 = this._cache.getStore(e2);
-    if (!s2)
-      return;
-    const r2 = await this._request.send("auth.logout", { refresh_token: s2 });
-    return this._cache.removeStore(e2), this._cache.removeStore(t2), this._cache.removeStore(n2), qe(Ke), qe($e, { env: this.config.env, loginType: He.NULL, persistence: this.config.persistence }), r2;
-  }
-  async signUpWithEmailAndPassword(e2, t2) {
-    return this._request.send("auth.signUpWithEmailAndPassword", { email: e2, password: t2 });
-  }
-  async sendPasswordResetEmail(e2) {
-    return this._request.send("auth.sendPasswordResetEmail", { email: e2 });
-  }
-  onLoginStateChanged(e2) {
-    Me(Ke, () => {
-      const t3 = this.hasLoginState();
-      e2.call(this, t3);
-    });
-    const t2 = this.hasLoginState();
-    e2.call(this, t2);
-  }
-  onLoginStateExpired(e2) {
-    Me(je, e2.bind(this));
-  }
-  onAccessTokenRefreshed(e2) {
-    Me(We, e2.bind(this));
-  }
-  onAnonymousConverted(e2) {
-    Me(Be, e2.bind(this));
-  }
-  onLoginTypeChanged(e2) {
-    Me($e, () => {
-      const t2 = this.hasLoginState();
-      e2.call(this, t2);
-    });
-  }
-  async getAccessToken() {
-    return { accessToken: (await this._request.getAccessToken()).accessToken, env: this.config.env };
-  }
-  hasLoginState() {
-    const { refreshTokenKey: e2 } = this._cache.keys;
-    return this._cache.getStore(e2) ? new tt(this.config.env) : null;
-  }
-  async isUsernameRegistered(e2) {
-    if ("string" != typeof e2)
-      throw new te({ code: "PARAM_ERROR", message: "username must be a string" });
-    const { data: t2 } = await this._request.send("auth.isUsernameRegistered", { username: e2 });
-    return t2 && t2.isRegistered;
-  }
-  getLoginState() {
-    return Promise.resolve(this.hasLoginState());
-  }
-  async signInWithTicket(e2) {
-    return new st(this.config).signIn(e2);
-  }
-  shouldRefreshAccessToken(e2) {
-    this._request._shouldRefreshAccessTokenHook = e2.bind(this);
-  }
-  getUserInfo() {
-    return this._request.send("auth.getUserInfo", {}).then((e2) => e2.code ? e2 : { ...e2.data, requestId: e2.seqId });
-  }
-  getAuthHeader() {
-    const { refreshTokenKey: e2, accessTokenKey: t2 } = this._cache.keys, n2 = this._cache.getStore(e2);
-    return { "x-cloudbase-credentials": this._cache.getStore(t2) + "/@@/" + n2 };
-  }
-  _onAnonymousConverted(e2) {
-    const { env: t2 } = e2.data;
-    t2 === this.config.env && this._cache.updatePersistence(this.config.persistence);
-  }
-  _onLoginTypeChanged(e2) {
-    const { loginType: t2, persistence: n2, env: s2 } = e2.data;
-    s2 === this.config.env && (this._cache.updatePersistence(n2), this._cache.setStore(this._cache.keys.loginTypeKey, t2));
-  }
-}
-const at = function(e2, t2) {
-  t2 = t2 || Ie();
-  const n2 = Xe(this.config.env), { cloudPath: s2, filePath: r2, onUploadProgress: i2, fileType: o2 = "image" } = e2;
-  return n2.send("storage.getUploadMetadata", { path: s2 }).then((e3) => {
-    const { data: { url: a2, authorization: c2, token: u2, fileId: l2, cosFileId: h2 }, requestId: d2 } = e3, p2 = { key: s2, signature: c2, "x-cos-meta-fileid": h2, success_action_status: "201", "x-cos-security-token": u2 };
-    n2.upload({ url: a2, data: p2, file: r2, name: s2, fileType: o2, onUploadProgress: i2 }).then((e4) => {
-      201 === e4.statusCode ? t2(null, { fileID: l2, requestId: d2 }) : t2(new te({ code: "STORAGE_REQUEST_FAIL", message: `STORAGE_REQUEST_FAIL: ${e4.data}` }));
-    }).catch((e4) => {
-      t2(e4);
-    });
-  }).catch((e3) => {
-    t2(e3);
-  }), t2.promise;
-}, ct = function(e2, t2) {
-  t2 = t2 || Ie();
-  const n2 = Xe(this.config.env), { cloudPath: s2 } = e2;
-  return n2.send("storage.getUploadMetadata", { path: s2 }).then((e3) => {
-    t2(null, e3);
-  }).catch((e3) => {
-    t2(e3);
-  }), t2.promise;
-}, ut = function({ fileList: e2 }, t2) {
-  if (t2 = t2 || Ie(), !e2 || !Array.isArray(e2))
-    return { code: "INVALID_PARAM", message: "fileList必须是非空的数组" };
-  for (let t3 of e2)
-    if (!t3 || "string" != typeof t3)
-      return { code: "INVALID_PARAM", message: "fileList的元素必须是非空的字符串" };
-  const n2 = { fileid_list: e2 };
-  return Xe(this.config.env).send("storage.batchDeleteFile", n2).then((e3) => {
-    e3.code ? t2(null, e3) : t2(null, { fileList: e3.data.delete_list, requestId: e3.requestId });
-  }).catch((e3) => {
-    t2(e3);
-  }), t2.promise;
-}, lt = function({ fileList: e2 }, t2) {
-  t2 = t2 || Ie(), e2 && Array.isArray(e2) || t2(null, { code: "INVALID_PARAM", message: "fileList必须是非空的数组" });
-  let n2 = [];
-  for (let s3 of e2)
-    "object" == typeof s3 ? (s3.hasOwnProperty("fileID") && s3.hasOwnProperty("maxAge") || t2(null, { code: "INVALID_PARAM", message: "fileList的元素必须是包含fileID和maxAge的对象" }), n2.push({ fileid: s3.fileID, max_age: s3.maxAge })) : "string" == typeof s3 ? n2.push({ fileid: s3 }) : t2(null, { code: "INVALID_PARAM", message: "fileList的元素必须是字符串" });
-  const s2 = { file_list: n2 };
-  return Xe(this.config.env).send("storage.batchGetDownloadUrl", s2).then((e3) => {
-    e3.code ? t2(null, e3) : t2(null, { fileList: e3.data.download_list, requestId: e3.requestId });
-  }).catch((e3) => {
-    t2(e3);
-  }), t2.promise;
-}, ht = async function({ fileID: e2 }, t2) {
-  const n2 = (await lt.call(this, { fileList: [{ fileID: e2, maxAge: 600 }] })).fileList[0];
-  if ("SUCCESS" !== n2.code)
-    return t2 ? t2(n2) : new Promise((e3) => {
-      e3(n2);
-    });
-  const s2 = Xe(this.config.env);
-  let r2 = n2.download_url;
-  if (r2 = encodeURI(r2), !t2)
-    return s2.download({ url: r2 });
-  t2(await s2.download({ url: r2 }));
-}, dt = function({ name: e2, data: t2, query: n2, parse: s2, search: r2, timeout: i2 }, o2) {
-  const a2 = o2 || Ie();
-  let c2;
-  try {
-    c2 = t2 ? JSON.stringify(t2) : "";
-  } catch (e3) {
-    return Promise.reject(e3);
-  }
-  if (!e2)
-    return Promise.reject(new te({ code: "PARAM_ERROR", message: "函数名不能为空" }));
-  const u2 = { inQuery: n2, parse: s2, search: r2, function_name: e2, request_data: c2 };
-  return Xe(this.config.env).send("functions.invokeFunction", u2, { timeout: i2 }).then((e3) => {
-    if (e3.code)
-      a2(null, e3);
-    else {
-      let t3 = e3.data.response_data;
-      if (s2)
-        a2(null, { result: t3, requestId: e3.requestId });
-      else
-        try {
-          t3 = JSON.parse(e3.data.response_data), a2(null, { result: t3, requestId: e3.requestId });
-        } catch (e4) {
-          a2(new te({ message: "response data must be json" }));
-        }
-    }
-    return a2.promise;
-  }).catch((e3) => {
-    a2(e3);
-  }), a2.promise;
-}, pt = { timeout: 15e3, persistence: "session" }, ft = {};
-class gt {
-  constructor(e2) {
-    this.config = e2 || this.config, this.authObj = void 0;
-  }
-  init(e2) {
-    switch (Ce.adapter || (this.requestClient = new Ce.adapter.reqClass({ timeout: e2.timeout || 5e3, timeoutMsg: `请求在${(e2.timeout || 5e3) / 1e3}s内未完成,已中断` })), this.config = { ...pt, ...e2 }, true) {
-      case this.config.timeout > 6e5:
-        console.warn("timeout大于可配置上限[10分钟],已重置为上限数值"), this.config.timeout = 6e5;
-        break;
-      case this.config.timeout < 100:
-        console.warn("timeout小于可配置下限[100ms],已重置为下限数值"), this.config.timeout = 100;
-    }
-    return new gt(this.config);
-  }
-  auth({ persistence: e2 } = {}) {
-    if (this.authObj)
-      return this.authObj;
-    const t2 = e2 || Ce.adapter.primaryStorage || pt.persistence;
-    var n2;
-    return t2 !== this.config.persistence && (this.config.persistence = t2), function(e3) {
-      const { env: t3 } = e3;
-      Ee[t3] = new Oe(e3), Le[t3] = new Oe({ ...e3, persistence: "local" });
-    }(this.config), n2 = this.config, Qe[n2.env] = new Ye(n2), this.authObj = new ot(this.config), this.authObj;
-  }
-  on(e2, t2) {
-    return Me.apply(this, [e2, t2]);
-  }
-  off(e2, t2) {
-    return Fe.apply(this, [e2, t2]);
-  }
-  callFunction(e2, t2) {
-    return dt.apply(this, [e2, t2]);
-  }
-  deleteFile(e2, t2) {
-    return ut.apply(this, [e2, t2]);
-  }
-  getTempFileURL(e2, t2) {
-    return lt.apply(this, [e2, t2]);
-  }
-  downloadFile(e2, t2) {
-    return ht.apply(this, [e2, t2]);
-  }
-  uploadFile(e2, t2) {
-    return at.apply(this, [e2, t2]);
-  }
-  getUploadMetadata(e2, t2) {
-    return ct.apply(this, [e2, t2]);
-  }
-  registerExtension(e2) {
-    ft[e2.name] = e2;
-  }
-  async invokeExtension(e2, t2) {
-    const n2 = ft[e2];
-    if (!n2)
-      throw new te({ message: `扩展${e2} 必须先注册` });
-    return await n2.invoke(t2, this);
-  }
-  useAdapters(e2) {
-    const { adapter: t2, runtime: n2 } = Ae(e2) || {};
-    t2 && (Ce.adapter = t2), n2 && (Ce.runtime = n2);
-  }
-}
-var mt = new gt();
-function yt(e2, t2, n2) {
-  void 0 === n2 && (n2 = {});
-  var s2 = /\?/.test(t2), r2 = "";
-  for (var i2 in n2)
-    "" === r2 ? !s2 && (t2 += "?") : r2 += "&", r2 += i2 + "=" + encodeURIComponent(n2[i2]);
-  return /^http(s)?:\/\//.test(t2 += r2) ? t2 : "" + e2 + t2;
-}
-class _t {
-  post(e2) {
-    const { url: t2, data: n2, headers: s2, timeout: r2 } = e2;
-    return new Promise((e3, i2) => {
-      ne.request({ url: yt("https:", t2), data: n2, method: "POST", header: s2, timeout: r2, success(t3) {
-        e3(t3);
-      }, fail(e4) {
-        i2(e4);
-      } });
-    });
-  }
-  upload(e2) {
-    return new Promise((t2, n2) => {
-      const { url: s2, file: r2, data: i2, headers: o2, fileType: a2 } = e2, c2 = ne.uploadFile({ url: yt("https:", s2), name: "file", formData: Object.assign({}, i2), filePath: r2, fileType: a2, header: o2, success(e3) {
-        const n3 = { statusCode: e3.statusCode, data: e3.data || {} };
-        200 === e3.statusCode && i2.success_action_status && (n3.statusCode = parseInt(i2.success_action_status, 10)), t2(n3);
-      }, fail(e3) {
-        n2(new Error(e3.errMsg || "uploadFile:fail"));
-      } });
-      "function" == typeof e2.onUploadProgress && c2 && "function" == typeof c2.onProgressUpdate && c2.onProgressUpdate((t3) => {
-        e2.onUploadProgress({ loaded: t3.totalBytesSent, total: t3.totalBytesExpectedToSend });
-      });
-    });
-  }
-}
-const wt = { setItem(e2, t2) {
-  ne.setStorageSync(e2, t2);
-}, getItem: (e2) => ne.getStorageSync(e2), removeItem(e2) {
-  ne.removeStorageSync(e2);
-}, clear() {
-  ne.clearStorageSync();
-} };
-var vt = { genAdapter: function() {
-  return { root: {}, reqClass: _t, localStorage: wt, primaryStorage: "local" };
-}, isMatch: function() {
-  return true;
-}, runtime: "uni_app" };
-mt.useAdapters(vt);
-const It = mt, St = It.init;
-It.init = function(e2) {
-  e2.env = e2.spaceId;
-  const t2 = St.call(this, e2);
-  t2.config.provider = "tencent", t2.config.spaceId = e2.spaceId;
-  const n2 = t2.auth;
-  return t2.auth = function(e3) {
-    const t3 = n2.call(this, e3);
-    return ["linkAndRetrieveDataWithTicket", "signInAnonymously", "signOut", "getAccessToken", "getLoginState", "signInWithTicket", "getUserInfo"].forEach((e4) => {
-      var n3;
-      t3[e4] = (n3 = t3[e4], function(e5) {
-        e5 = e5 || {};
-        const { success: t4, fail: s2, complete: r2 } = ee(e5);
-        if (!(t4 || s2 || r2))
-          return n3.call(this, e5);
-        n3.call(this, e5).then((e6) => {
-          t4 && t4(e6), r2 && r2(e6);
-        }, (e6) => {
-          s2 && s2(e6), r2 && r2(e6);
-        });
-      }).bind(t3);
-    }), t3;
-  }, t2.customAuth = t2.auth, t2;
-};
-var bt = It;
-async function kt(e2, t2) {
-  const n2 = `http://${e2}:${t2}/system/ping`;
-  try {
-    const e3 = await (s2 = { url: n2, timeout: 500 }, new Promise((e4, t3) => {
-      ne.request({ ...s2, success(t4) {
-        e4(t4);
-      }, fail(e5) {
-        t3(e5);
-      } });
-    }));
-    return !(!e3.data || 0 !== e3.data.code);
-  } catch (e3) {
-    return false;
-  }
-  var s2;
-}
-async function At(e2, t2) {
-  let n2;
-  for (let s2 = 0; s2 < e2.length; s2++) {
-    const r2 = e2[s2];
-    if (await kt(r2, t2)) {
-      n2 = r2;
-      break;
-    }
-  }
-  return { address: n2, port: t2 };
-}
-const Ct = { "serverless.file.resource.generateProximalSign": "storage/generate-proximal-sign", "serverless.file.resource.report": "storage/report", "serverless.file.resource.delete": "storage/delete", "serverless.file.resource.getTempFileURL": "storage/get-temp-file-url" };
-var Pt = class {
-  constructor(e2) {
-    if (["spaceId", "clientSecret"].forEach((t2) => {
-      if (!Object.prototype.hasOwnProperty.call(e2, t2))
-        throw new Error(`${t2} required`);
-    }), !e2.endpoint)
-      throw new Error("集群空间未配置ApiEndpoint,配置后需要重新关联服务空间后生效");
-    this.config = Object.assign({}, e2), this.config.provider = "dcloud", this.config.requestUrl = this.config.endpoint + "/client", this.config.envType = this.config.envType || "public", this.adapter = ne;
-  }
-  async request(e2, t2 = true) {
-    const n2 = t2;
-    return e2 = n2 ? await this.setupLocalRequest(e2) : this.setupRequest(e2), Promise.resolve().then(() => n2 ? this.requestLocal(e2) : de.wrappedRequest(e2, this.adapter.request));
-  }
-  requestLocal(e2) {
-    return new Promise((t2, n2) => {
-      this.adapter.request(Object.assign(e2, { complete(e3) {
-        if (e3 || (e3 = {}), !e3.statusCode || e3.statusCode >= 400) {
-          const t3 = e3.data && e3.data.code || "SYS_ERR", s2 = e3.data && e3.data.message || "request:fail";
-          return n2(new te({ code: t3, message: s2 }));
-        }
-        t2({ success: true, result: e3.data });
-      } }));
-    });
-  }
-  setupRequest(e2) {
-    const t2 = Object.assign({}, e2, { spaceId: this.config.spaceId, timestamp: Date.now() }), n2 = { "Content-Type": "application/json" };
-    n2["x-serverless-sign"] = de.sign(t2, this.config.clientSecret);
-    const s2 = he();
-    n2["x-client-info"] = encodeURIComponent(JSON.stringify(s2));
-    const { token: r2 } = re();
-    return n2["x-client-token"] = r2, { url: this.config.requestUrl, method: "POST", data: t2, dataType: "json", header: JSON.parse(JSON.stringify(n2)) };
-  }
-  async setupLocalRequest(e2) {
-    const t2 = he(), { token: n2 } = re(), s2 = Object.assign({}, e2, { spaceId: this.config.spaceId, timestamp: Date.now(), clientInfo: t2, token: n2 }), { address: r2, servePort: i2 } = Ys.__dev__.debugInfo, { address: o2 } = await At(r2, i2);
-    return { url: `http://${o2}:${i2}/${Ct[e2.method]}`, method: "POST", data: s2, dataType: "json", header: JSON.parse(JSON.stringify({ "Content-Type": "application/json" })) };
-  }
-  callFunction(e2) {
-    const t2 = { method: "serverless.function.runtime.invoke", params: JSON.stringify({ functionTarget: e2.name, functionArgs: e2.data || {} }) };
-    return this.request(t2, false);
-  }
-  getUploadFileOptions(e2) {
-    const t2 = { method: "serverless.file.resource.generateProximalSign", params: JSON.stringify(e2) };
-    return this.request(t2);
-  }
-  reportUploadFile(e2) {
-    const t2 = { method: "serverless.file.resource.report", params: JSON.stringify(e2) };
-    return this.request(t2);
-  }
-  uploadFile({ filePath: e2, cloudPath: t2, fileType: n2 = "image", onUploadProgress: s2 }) {
-    if (!t2)
-      throw new te({ code: "CLOUDPATH_REQUIRED", message: "cloudPath不可为空" });
-    let r2;
-    return this.getUploadFileOptions({ cloudPath: t2 }).then((t3) => {
-      const { url: i2, formData: o2, name: a2 } = t3.result;
-      return r2 = t3.result.fileUrl, new Promise((t4, r3) => {
-        const c2 = this.adapter.uploadFile({ url: i2, formData: o2, name: a2, filePath: e2, fileType: n2, success(e3) {
-          e3 && e3.statusCode < 400 ? t4(e3) : r3(new te({ code: "UPLOAD_FAILED", message: "文件上传失败" }));
-        }, fail(e3) {
-          r3(new te({ code: e3.code || "UPLOAD_FAILED", message: e3.message || e3.errMsg || "文件上传失败" }));
-        } });
-        "function" == typeof s2 && c2 && "function" == typeof c2.onProgressUpdate && c2.onProgressUpdate((e3) => {
-          s2({ loaded: e3.totalBytesSent, total: e3.totalBytesExpectedToSend });
-        });
-      });
-    }).then(() => this.reportUploadFile({ cloudPath: t2 })).then((t3) => new Promise((n3, s3) => {
-      t3.success ? n3({ success: true, filePath: e2, fileID: r2 }) : s3(new te({ code: "UPLOAD_FAILED", message: "文件上传失败" }));
-    }));
-  }
-  deleteFile({ fileList: e2 }) {
-    const t2 = { method: "serverless.file.resource.delete", params: JSON.stringify({ fileList: e2 }) };
-    return this.request(t2).then((e3) => {
-      if (e3.success)
-        return e3.result;
-      throw new te({ code: "DELETE_FILE_FAILED", message: "删除文件失败" });
-    });
-  }
-  getTempFileURL({ fileList: e2, maxAge: t2 } = {}) {
-    if (!Array.isArray(e2) || 0 === e2.length)
-      throw new te({ code: "INVALID_PARAM", message: "fileList的元素必须是非空的字符串" });
-    const n2 = { method: "serverless.file.resource.getTempFileURL", params: JSON.stringify({ fileList: e2, maxAge: t2 }) };
-    return this.request(n2).then((e3) => {
-      if (e3.success)
-        return { fileList: e3.result.fileList.map((e4) => ({ fileID: e4.fileID, tempFileURL: e4.tempFileURL })) };
-      throw new te({ code: "GET_TEMP_FILE_URL_FAILED", message: "获取临时文件链接失败" });
-    });
-  }
-};
-var Tt = { init(e2) {
-  const t2 = new Pt(e2), n2 = { signInAnonymously: function() {
-    return Promise.resolve();
-  }, getLoginState: function() {
-    return Promise.resolve(false);
-  } };
-  return t2.auth = function() {
-    return n2;
-  }, t2.customAuth = t2.auth, t2;
-} }, xt = n(function(e2, t2) {
-  e2.exports = r.enc.Hex;
-});
-function Ot() {
-  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(e2) {
-    var t2 = 16 * Math.random() | 0;
-    return ("x" === e2 ? t2 : 3 & t2 | 8).toString(16);
-  });
-}
-function Et(e2 = "", t2 = {}) {
-  const { data: n2, functionName: s2, method: r2, headers: i2, signHeaderKeys: o2 = [], config: a2 } = t2, c2 = Date.now(), u2 = Ot(), l2 = Object.assign({}, i2, { "x-from-app-id": a2.spaceAppId, "x-from-env-id": a2.spaceId, "x-to-env-id": a2.spaceId, "x-from-instance-id": c2, "x-from-function-name": s2, "x-client-timestamp": c2, "x-alipay-source": "client", "x-request-id": u2, "x-alipay-callid": u2, "x-trace-id": u2 }), h2 = ["x-from-app-id", "x-from-env-id", "x-to-env-id", "x-from-instance-id", "x-from-function-name", "x-client-timestamp"].concat(o2), [d2 = "", p2 = ""] = e2.split("?") || [], f2 = function(e3) {
-    const t3 = e3.signedHeaders.join(";"), n3 = e3.signedHeaders.map((t4) => `${t4.toLowerCase()}:${e3.headers[t4]}
-`).join(""), s3 = we(e3.body).toString(xt), r3 = `${e3.method.toUpperCase()}
-${e3.path}
-${e3.query}
-${n3}
-${t3}
-${s3}
-`, i3 = we(r3).toString(xt), o3 = `HMAC-SHA256
-${e3.timestamp}
-${i3}
-`, a3 = ve(o3, e3.secretKey).toString(xt);
-    return `HMAC-SHA256 Credential=${e3.secretId}, SignedHeaders=${t3}, Signature=${a3}`;
-  }({ path: d2, query: p2, method: r2, headers: l2, timestamp: c2, body: JSON.stringify(n2), secretId: a2.accessKey, secretKey: a2.secretKey, signedHeaders: h2.sort() });
-  return { url: `${a2.endpoint}${e2}`, headers: Object.assign({}, l2, { Authorization: f2 }) };
-}
-function Lt({ url: e2, data: t2, method: n2 = "POST", headers: s2 = {}, timeout: r2 }) {
-  return new Promise((i2, o2) => {
-    ne.request({ url: e2, method: n2, data: "object" == typeof t2 ? JSON.stringify(t2) : t2, header: s2, dataType: "json", timeout: r2, complete: (e3 = {}) => {
-      const t3 = s2["x-trace-id"] || "";
-      if (!e3.statusCode || e3.statusCode >= 400) {
-        const { message: n3, errMsg: s3, trace_id: r3 } = e3.data || {};
-        return o2(new te({ code: "SYS_ERR", message: n3 || s3 || "request:fail", requestId: r3 || t3 }));
-      }
-      i2({ status: e3.statusCode, data: e3.data, headers: e3.header, requestId: t3 });
-    } });
-  });
-}
-function Rt(e2, t2) {
-  const { path: n2, data: s2, method: r2 = "GET" } = e2, { url: i2, headers: o2 } = Et(n2, { functionName: "", data: s2, method: r2, headers: { "x-alipay-cloud-mode": "oss", "x-data-api-type": "oss", "x-expire-timestamp": Date.now() + 6e4 }, signHeaderKeys: ["x-data-api-type", "x-expire-timestamp"], config: t2 });
-  return Lt({ url: i2, data: s2, method: r2, headers: o2 }).then((e3) => {
-    const t3 = e3.data || {};
-    if (!t3.success)
-      throw new te({ code: e3.errCode, message: e3.errMsg, requestId: e3.requestId });
-    return t3.data || {};
-  }).catch((e3) => {
-    throw new te({ code: e3.errCode, message: e3.errMsg, requestId: e3.requestId });
-  });
-}
-function Ut(e2 = "") {
-  const t2 = e2.trim().replace(/^cloud:\/\//, ""), n2 = t2.indexOf("/");
-  if (n2 <= 0)
-    throw new te({ code: "INVALID_PARAM", message: "fileID不合法" });
-  const s2 = t2.substring(0, n2), r2 = t2.substring(n2 + 1);
-  return s2 !== this.config.spaceId && console.warn("file ".concat(e2, " does not belong to env ").concat(this.config.spaceId)), r2;
-}
-function Nt(e2 = "") {
-  return "cloud://".concat(this.config.spaceId, "/").concat(e2.replace(/^\/+/, ""));
-}
-class Dt {
-  constructor(e2) {
-    this.config = e2;
-  }
-  signedURL(e2, t2 = {}) {
-    const n2 = `/ws/function/${e2}`, s2 = this.config.wsEndpoint.replace(/^ws(s)?:\/\//, ""), r2 = Object.assign({}, t2, { accessKeyId: this.config.accessKey, signatureNonce: Ot(), timestamp: "" + Date.now() }), i2 = [n2, ["accessKeyId", "authorization", "signatureNonce", "timestamp"].sort().map(function(e3) {
-      return r2[e3] ? "".concat(e3, "=").concat(r2[e3]) : null;
-    }).filter(Boolean).join("&"), `host:${s2}`].join("\n"), o2 = ["HMAC-SHA256", we(i2).toString(xt)].join("\n"), a2 = ve(o2, this.config.secretKey).toString(xt), c2 = Object.keys(r2).map((e3) => `${e3}=${encodeURIComponent(r2[e3])}`).join("&");
-    return `${this.config.wsEndpoint}${n2}?${c2}&signature=${a2}`;
-  }
-}
-var Mt = class {
-  constructor(e2) {
-    if (["spaceId", "spaceAppId", "accessKey", "secretKey"].forEach((t2) => {
-      if (!Object.prototype.hasOwnProperty.call(e2, t2))
-        throw new Error(`${t2} required`);
-    }), e2.endpoint) {
-      if ("string" != typeof e2.endpoint)
-        throw new Error("endpoint must be string");
-      if (!/^https:\/\//.test(e2.endpoint))
-        throw new Error("endpoint must start with https://");
-      e2.endpoint = e2.endpoint.replace(/\/$/, "");
-    }
-    this.config = Object.assign({}, e2, { endpoint: e2.endpoint || `https://${e2.spaceId}.api-hz.cloudbasefunction.cn`, wsEndpoint: e2.wsEndpoint || `wss://${e2.spaceId}.api-hz.cloudbasefunction.cn` }), this._websocket = new Dt(this.config);
-  }
-  callFunction(e2) {
-    return function(e3, t2) {
-      const { name: n2, data: s2, async: r2 = false, timeout: i2 } = e3, o2 = "POST", a2 = { "x-to-function-name": n2 };
-      r2 && (a2["x-function-invoke-type"] = "async");
-      const { url: c2, headers: u2 } = Et("/functions/invokeFunction", { functionName: n2, data: s2, method: o2, headers: a2, signHeaderKeys: ["x-to-function-name"], config: t2 });
-      return Lt({ url: c2, data: s2, method: o2, headers: u2, timeout: i2 }).then((e4) => {
-        let t3 = 0;
-        if (r2) {
-          const n3 = e4.data || {};
-          t3 = "200" === n3.errCode ? 0 : n3.errCode, e4.data = n3.data || {}, e4.errMsg = n3.errMsg;
-        }
-        if (0 !== t3)
-          throw new te({ code: t3, message: e4.errMsg, requestId: e4.requestId });
-        return { errCode: t3, success: 0 === t3, requestId: e4.requestId, result: e4.data };
-      }).catch((e4) => {
-        throw new te({ code: e4.errCode, message: e4.errMsg, requestId: e4.requestId });
-      });
-    }(e2, this.config);
-  }
-  uploadFileToOSS({ url: e2, filePath: t2, fileType: n2, formData: s2, onUploadProgress: r2 }) {
-    return new Promise((i2, o2) => {
-      const a2 = ne.uploadFile({ url: e2, filePath: t2, fileType: n2, formData: s2, name: "file", success(e3) {
-        e3 && e3.statusCode < 400 ? i2(e3) : o2(new te({ code: "UPLOAD_FAILED", message: "文件上传失败" }));
-      }, fail(e3) {
-        o2(new te({ code: e3.code || "UPLOAD_FAILED", message: e3.message || e3.errMsg || "文件上传失败" }));
-      } });
-      "function" == typeof r2 && a2 && "function" == typeof a2.onProgressUpdate && a2.onProgressUpdate((e3) => {
-        r2({ loaded: e3.totalBytesSent, total: e3.totalBytesExpectedToSend });
-      });
-    });
-  }
-  async uploadFile({ filePath: e2, cloudPath: t2 = "", fileType: n2 = "image", onUploadProgress: s2 }) {
-    if ("string" !== f(t2))
-      throw new te({ code: "INVALID_PARAM", message: "cloudPath必须为字符串类型" });
-    if (!(t2 = t2.trim()))
-      throw new te({ code: "INVALID_PARAM", message: "cloudPath不可为空" });
-    if (/:\/\//.test(t2))
-      throw new te({ code: "INVALID_PARAM", message: "cloudPath不合法" });
-    const r2 = await Rt({ path: "/".concat(t2.replace(/^\//, ""), "?post_url") }, this.config), { file_id: i2, upload_url: o2, form_data: a2 } = r2, c2 = a2 && a2.reduce((e3, t3) => (e3[t3.key] = t3.value, e3), {});
-    return this.uploadFileToOSS({ url: o2, filePath: e2, fileType: n2, formData: c2, onUploadProgress: s2 }).then(() => ({ fileID: i2 }));
-  }
-  async getTempFileURL({ fileList: e2 }) {
-    return new Promise((t2, n2) => {
-      (!e2 || e2.length < 0) && n2(new te({ errCode: "INVALID_PARAM", errMsg: "fileList不能为空数组" })), e2.length > 50 && n2(new te({ errCode: "INVALID_PARAM", errMsg: "fileList数组长度不能超过50" }));
-      const s2 = [];
-      for (const t3 of e2) {
-        "string" !== f(t3) && n2(new te({ errCode: "INVALID_PARAM", errMsg: "fileList的元素必须是非空的字符串" }));
-        const e3 = Ut.call(this, t3);
-        s2.push({ file_id: e3, expire: 600 });
-      }
-      Rt({ path: "/?download_url", data: { file_list: s2 }, method: "POST" }, this.config).then((e3) => {
-        const { file_list: n3 = [] } = e3;
-        t2({ fileList: n3.map((e4) => ({ fileID: Nt.call(this, e4.file_id), tempFileURL: e4.download_url })) });
-      }).catch((e3) => n2(e3));
-    });
-  }
-  async connectWebSocket(e2) {
-    const { name: t2, query: n2 } = e2;
-    return ne.connectSocket({ url: this._websocket.signedURL(t2, n2), complete: () => {
-    } });
-  }
-};
-var qt = { init: (e2) => {
-  e2.provider = "alipay";
-  const t2 = new Mt(e2);
-  return t2.auth = function() {
-    return { signInAnonymously: function() {
-      return Promise.resolve();
-    }, getLoginState: function() {
-      return Promise.resolve(true);
-    } };
-  }, t2;
-} };
-function Ft({ data: e2 }) {
-  let t2;
-  t2 = he();
-  const n2 = JSON.parse(JSON.stringify(e2 || {}));
-  if (Object.assign(n2, { clientInfo: t2 }), !n2.uniIdToken) {
-    const { token: e3 } = re();
-    e3 && (n2.uniIdToken = e3);
-  }
-  return n2;
-}
-async function Kt(e2 = {}) {
-  await this.__dev__.initLocalNetwork();
-  const { localAddress: t2, localPort: n2 } = this.__dev__, s2 = { aliyun: "aliyun", tencent: "tcb", alipay: "alipay", dcloud: "dcloud" }[this.config.provider], r2 = this.config.spaceId, i2 = `http://${t2}:${n2}/system/check-function`, o2 = `http://${t2}:${n2}/cloudfunctions/${e2.name}`;
-  return new Promise((t3, n3) => {
-    ne.request({ method: "POST", url: i2, data: { name: e2.name, platform: C, provider: s2, spaceId: r2 }, timeout: 3e3, success(e3) {
-      t3(e3);
-    }, fail() {
-      t3({ data: { code: "NETWORK_ERROR", message: "连接本地调试服务失败,请检查客户端是否和主机在同一局域网下,自动切换为已部署的云函数。" } });
-    } });
-  }).then(({ data: e3 } = {}) => {
-    const { code: t3, message: n3 } = e3 || {};
-    return { code: 0 === t3 ? 0 : t3 || "SYS_ERR", message: n3 || "SYS_ERR" };
-  }).then(({ code: t3, message: n3 }) => {
-    if (0 !== t3) {
-      switch (t3) {
-        case "MODULE_ENCRYPTED":
-          console.error(`此云函数(${e2.name})依赖加密公共模块不可本地调试,自动切换为云端已部署的云函数`);
-          break;
-        case "FUNCTION_ENCRYPTED":
-          console.error(`此云函数(${e2.name})已加密不可本地调试,自动切换为云端已部署的云函数`);
-          break;
-        case "ACTION_ENCRYPTED":
-          console.error(n3 || "需要访问加密的uni-clientDB-action,自动切换为云端环境");
-          break;
-        case "NETWORK_ERROR":
-          console.error(n3 || "连接本地调试服务失败,请检查客户端是否和主机在同一局域网下");
-          break;
-        case "SWITCH_TO_CLOUD":
-          break;
-        default: {
-          const e3 = `检测本地调试服务出现错误:${n3},请检查网络环境或重启客户端再试`;
-          throw console.error(e3), new Error(e3);
-        }
-      }
-      return this._callCloudFunction(e2);
-    }
-    return new Promise((t4, n4) => {
-      const r3 = Ft.call(this, { data: e2.data });
-      ne.request({ method: "POST", url: o2, data: { provider: s2, platform: C, param: r3 }, timeout: e2.timeout, success: ({ statusCode: e3, data: s3 } = {}) => !e3 || e3 >= 400 ? n4(new te({ code: s3.code || "SYS_ERR", message: s3.message || "request:fail" })) : t4({ result: s3 }), fail(e3) {
-        n4(new te({ code: e3.code || e3.errCode || "SYS_ERR", message: e3.message || e3.errMsg || "request:fail" }));
-      } });
-    });
-  });
-}
-const jt = [{ rule: /fc_function_not_found|FUNCTION_NOT_FOUND/, content: ",云函数[{functionName}]在云端不存在,请检查此云函数名称是否正确以及该云函数是否已上传到服务空间", mode: "append" }];
-var $t = /[\\^$.*+?()[\]{}|]/g, Bt = RegExp($t.source);
-function Wt(e2, t2, n2) {
-  return e2.replace(new RegExp((s2 = t2) && Bt.test(s2) ? s2.replace($t, "\\$&") : s2, "g"), n2);
-  var s2;
-}
-const Jt = "request", zt = "response", Vt = "both";
-const En = { code: 2e4, message: "System error" }, Ln = { code: 20101, message: "Invalid client" };
-function Nn(e2) {
-  const { errSubject: t2, subject: n2, errCode: s2, errMsg: r2, code: i2, message: o2, cause: a2 } = e2 || {};
-  return new te({ subject: t2 || n2 || "uni-secure-network", code: s2 || i2 || En.code, message: r2 || o2, cause: a2 });
-}
-let Mn;
-function $n({ secretType: e2 } = {}) {
-  return e2 === Jt || e2 === zt || e2 === Vt;
-}
-function Bn({ name: e2, data: t2 = {} } = {}) {
-  return "app" === C;
-}
-function Wn({ provider: e2, spaceId: t2, functionName: n2 } = {}) {
-  const { appId: s2, uniPlatform: r2, osName: i2 } = ce();
-  let o2 = r2;
-  "app" === r2 && (o2 = i2);
-  const a2 = function({ provider: e3, spaceId: t3 } = {}) {
-    const n3 = A;
-    if (!n3)
-      return {};
-    e3 = /* @__PURE__ */ function(e4) {
-      return "tencent" === e4 ? "tcb" : e4;
-    }(e3);
-    const s3 = n3.find((n4) => n4.provider === e3 && n4.spaceId === t3);
-    return s3 && s3.config;
-  }({ provider: e2, spaceId: t2 });
-  if (!a2 || !a2.accessControl || !a2.accessControl.enable)
-    return false;
-  const c2 = a2.accessControl.function || {}, u2 = Object.keys(c2);
-  if (0 === u2.length)
-    return true;
-  const l2 = function(e3, t3) {
-    let n3, s3, r3;
-    for (let i3 = 0; i3 < e3.length; i3++) {
-      const o3 = e3[i3];
-      o3 !== t3 ? "*" !== o3 ? o3.split(",").map((e4) => e4.trim()).indexOf(t3) > -1 && (s3 = o3) : r3 = o3 : n3 = o3;
-    }
-    return n3 || s3 || r3;
-  }(u2, n2);
-  if (!l2)
-    return false;
-  if ((c2[l2] || []).find((e3 = {}) => e3.appId === s2 && (e3.platform || "").toLowerCase() === o2.toLowerCase()))
-    return true;
-  throw console.error(`此应用[appId: ${s2}, platform: ${o2}]不在云端配置的允许访问的应用列表内,参考:https://uniapp.dcloud.net.cn/uniCloud/secure-network.html#verify-client`), Nn(Ln);
-}
-function Hn({ functionName: e2, result: t2, logPvd: n2 }) {
-  if (this.__dev__.debugLog && t2 && t2.requestId) {
-    const s2 = JSON.stringify({ spaceId: this.config.spaceId, functionName: e2, requestId: t2.requestId });
-    console.log(`[${n2}-request]${s2}[/${n2}-request]`);
-  }
-}
-function Jn(e2) {
-  const t2 = e2.callFunction, n2 = function(n3) {
-    const s2 = n3.name;
-    n3.data = Ft.call(e2, { data: n3.data });
-    const r2 = { aliyun: "aliyun", tencent: "tcb", tcb: "tcb", alipay: "alipay", dcloud: "dcloud" }[this.config.provider], i2 = $n(n3), o2 = Bn(n3), a2 = i2 || o2;
-    return t2.call(this, n3).then((e3) => (e3.errCode = 0, !a2 && Hn.call(this, { functionName: s2, result: e3, logPvd: r2 }), Promise.resolve(e3)), (e3) => (!a2 && Hn.call(this, { functionName: s2, result: e3, logPvd: r2 }), e3 && e3.message && (e3.message = function({ message: e4 = "", extraInfo: t3 = {}, formatter: n4 = [] } = {}) {
-      for (let s3 = 0; s3 < n4.length; s3++) {
-        const { rule: r3, content: i3, mode: o3 } = n4[s3], a3 = e4.match(r3);
-        if (!a3)
-          continue;
-        let c2 = i3;
-        for (let e5 = 1; e5 < a3.length; e5++)
-          c2 = Wt(c2, `{$${e5}}`, a3[e5]);
-        for (const e5 in t3)
-          c2 = Wt(c2, `{${e5}}`, t3[e5]);
-        return "replace" === o3 ? c2 : e4 + c2;
-      }
-      return e4;
-    }({ message: `[${n3.name}]: ${e3.message}`, formatter: jt, extraInfo: { functionName: s2 } })), Promise.reject(e3)));
-  };
-  e2.callFunction = function(t3) {
-    const { provider: s2, spaceId: r2 } = e2.config, i2 = t3.name;
-    let o2, a2;
-    if (t3.data = t3.data || {}, e2.__dev__.debugInfo && !e2.__dev__.debugInfo.forceRemote && T ? (e2._callCloudFunction || (e2._callCloudFunction = n2, e2._callLocalFunction = Kt), o2 = Kt) : o2 = n2, o2 = o2.bind(e2), Bn(t3))
-      ;
-    else if (function({ name: e3, data: t4 = {} }) {
-      return "uni-id-co" === e3 && "secureNetworkHandshakeByWeixin" === t4.method;
-    }(t3))
-      a2 = o2.call(e2, t3);
-    else if ($n(t3)) {
-      a2 = new Mn({ secretType: t3.secretType, uniCloudIns: e2 }).wrapEncryptDataCallFunction(n2.bind(e2))(t3);
-    } else if (Wn({ provider: s2, spaceId: r2, functionName: i2 })) {
-      a2 = new Mn({ secretType: t3.secretType, uniCloudIns: e2 }).wrapVerifyClientCallFunction(n2.bind(e2))(t3);
-    } else
-      a2 = o2(t3);
-    return Object.defineProperty(a2, "result", { get: () => (console.warn("当前返回结果为Promise类型,不可直接访问其result属性,详情请参考:https://uniapp.dcloud.net.cn/uniCloud/faq?id=promise"), {}) }), a2.then((e3) => ("undefined" != typeof UTSJSONObject && (e3.result = new UTSJSONObject(e3.result)), e3));
-  };
-}
-Mn = class {
-  constructor() {
-    throw Nn({ message: `Platform ${C} is not enabled, please check whether secure network module is enabled in your manifest.json` });
-  }
-};
-const zn = Symbol("CLIENT_DB_INTERNAL");
-function Vn(e2, t2) {
-  return e2.then = "DoNotReturnProxyWithAFunctionNamedThen", e2._internalType = zn, e2.inspect = null, e2.__v_raw = void 0, new Proxy(e2, { get(e3, n2, s2) {
-    if ("_uniClient" === n2)
-      return null;
-    if ("symbol" == typeof n2)
-      return e3[n2];
-    if (n2 in e3 || "string" != typeof n2) {
-      const t3 = e3[n2];
-      return "function" == typeof t3 ? t3.bind(e3) : t3;
-    }
-    return t2.get(e3, n2, s2);
-  } });
-}
-function Gn(e2) {
-  return { on: (t2, n2) => {
-    e2[t2] = e2[t2] || [], e2[t2].indexOf(n2) > -1 || e2[t2].push(n2);
-  }, off: (t2, n2) => {
-    e2[t2] = e2[t2] || [];
-    const s2 = e2[t2].indexOf(n2);
-    -1 !== s2 && e2[t2].splice(s2, 1);
-  } };
-}
-const Yn = ["db.Geo", "db.command", "command.aggregate"];
-function Qn(e2, t2) {
-  return Yn.indexOf(`${e2}.${t2}`) > -1;
-}
-function Xn(e2) {
-  switch (f(e2 = se(e2))) {
-    case "array":
-      return e2.map((e3) => Xn(e3));
-    case "object":
-      return e2._internalType === zn || Object.keys(e2).forEach((t2) => {
-        e2[t2] = Xn(e2[t2]);
-      }), e2;
-    case "regexp":
-      return { $regexp: { source: e2.source, flags: e2.flags } };
-    case "date":
-      return { $date: e2.toISOString() };
-    default:
-      return e2;
-  }
-}
-function Zn(e2) {
-  return e2 && e2.content && e2.content.$method;
-}
-class es {
-  constructor(e2, t2, n2) {
-    this.content = e2, this.prevStage = t2 || null, this.udb = null, this._database = n2;
-  }
-  toJSON() {
-    let e2 = this;
-    const t2 = [e2.content];
-    for (; e2.prevStage; )
-      e2 = e2.prevStage, t2.push(e2.content);
-    return { $db: t2.reverse().map((e3) => ({ $method: e3.$method, $param: Xn(e3.$param) })) };
-  }
-  toString() {
-    return JSON.stringify(this.toJSON());
-  }
-  getAction() {
-    const e2 = this.toJSON().$db.find((e3) => "action" === e3.$method);
-    return e2 && e2.$param && e2.$param[0];
-  }
-  getCommand() {
-    return { $db: this.toJSON().$db.filter((e2) => "action" !== e2.$method) };
-  }
-  get isAggregate() {
-    let e2 = this;
-    for (; e2; ) {
-      const t2 = Zn(e2), n2 = Zn(e2.prevStage);
-      if ("aggregate" === t2 && "collection" === n2 || "pipeline" === t2)
-        return true;
-      e2 = e2.prevStage;
-    }
-    return false;
-  }
-  get isCommand() {
-    let e2 = this;
-    for (; e2; ) {
-      if ("command" === Zn(e2))
-        return true;
-      e2 = e2.prevStage;
-    }
-    return false;
-  }
-  get isAggregateCommand() {
-    let e2 = this;
-    for (; e2; ) {
-      const t2 = Zn(e2), n2 = Zn(e2.prevStage);
-      if ("aggregate" === t2 && "command" === n2)
-        return true;
-      e2 = e2.prevStage;
-    }
-    return false;
-  }
-  getNextStageFn(e2) {
-    const t2 = this;
-    return function() {
-      return ts({ $method: e2, $param: Xn(Array.from(arguments)) }, t2, t2._database);
-    };
-  }
-  get count() {
-    return this.isAggregate ? this.getNextStageFn("count") : function() {
-      return this._send("count", Array.from(arguments));
-    };
-  }
-  get remove() {
-    return this.isCommand ? this.getNextStageFn("remove") : function() {
-      return this._send("remove", Array.from(arguments));
-    };
-  }
-  get() {
-    return this._send("get", Array.from(arguments));
-  }
-  get add() {
-    return this.isCommand ? this.getNextStageFn("add") : function() {
-      return this._send("add", Array.from(arguments));
-    };
-  }
-  update() {
-    return this._send("update", Array.from(arguments));
-  }
-  end() {
-    return this._send("end", Array.from(arguments));
-  }
-  get set() {
-    return this.isCommand ? this.getNextStageFn("set") : function() {
-      throw new Error("JQL禁止使用set方法");
-    };
-  }
-  _send(e2, t2) {
-    const n2 = this.getAction(), s2 = this.getCommand();
-    if (s2.$db.push({ $method: e2, $param: Xn(t2) }), S) {
-      const e3 = s2.$db.find((e4) => "collection" === e4.$method), t3 = e3 && e3.$param;
-      t3 && 1 === t3.length && "string" == typeof e3.$param[0] && e3.$param[0].indexOf(",") > -1 && console.warn("检测到使用JQL语法联表查询时,未使用getTemp先过滤主表数据,在主表数据量大的情况下可能会查询缓慢。\n- 如何优化请参考此文档:https://uniapp.dcloud.net.cn/uniCloud/jql?id=lookup-with-temp \n- 如果主表数据量很小请忽略此信息,项目发行时不会出现此提示。");
-    }
-    return this._database._callCloudFunction({ action: n2, command: s2 });
-  }
-}
-function ts(e2, t2, n2) {
-  return Vn(new es(e2, t2, n2), { get(e3, t3) {
-    let s2 = "db";
-    return e3 && e3.content && (s2 = e3.content.$method), Qn(s2, t3) ? ts({ $method: t3 }, e3, n2) : function() {
-      return ts({ $method: t3, $param: Xn(Array.from(arguments)) }, e3, n2);
-    };
-  } });
-}
-function ns({ path: e2, method: t2 }) {
-  return class {
-    constructor() {
-      this.param = Array.from(arguments);
-    }
-    toJSON() {
-      return { $newDb: [...e2.map((e3) => ({ $method: e3 })), { $method: t2, $param: this.param }] };
-    }
-    toString() {
-      return JSON.stringify(this.toJSON());
-    }
-  };
-}
-function ss(e2, t2 = {}) {
-  return Vn(new e2(t2), { get: (e3, t3) => Qn("db", t3) ? ts({ $method: t3 }, null, e3) : function() {
-    return ts({ $method: t3, $param: Xn(Array.from(arguments)) }, null, e3);
-  } });
-}
-class rs extends class {
-  constructor({ uniClient: e2 = {}, isJQL: t2 = false } = {}) {
-    this._uniClient = e2, this._authCallBacks = {}, this._dbCallBacks = {}, e2._isDefault && (this._dbCallBacks = L("_globalUniCloudDatabaseCallback")), t2 || (this.auth = Gn(this._authCallBacks)), this._isJQL = t2, Object.assign(this, Gn(this._dbCallBacks)), this.env = Vn({}, { get: (e3, t3) => ({ $env: t3 }) }), this.Geo = Vn({}, { get: (e3, t3) => ns({ path: ["Geo"], method: t3 }) }), this.serverDate = ns({ path: [], method: "serverDate" }), this.RegExp = ns({ path: [], method: "RegExp" });
-  }
-  getCloudEnv(e2) {
-    if ("string" != typeof e2 || !e2.trim())
-      throw new Error("getCloudEnv参数错误");
-    return { $env: e2.replace("$cloudEnv_", "") };
-  }
-  _callback(e2, t2) {
-    const n2 = this._dbCallBacks;
-    n2[e2] && n2[e2].forEach((e3) => {
-      e3(...t2);
-    });
-  }
-  _callbackAuth(e2, t2) {
-    const n2 = this._authCallBacks;
-    n2[e2] && n2[e2].forEach((e3) => {
-      e3(...t2);
-    });
-  }
-  multiSend() {
-    const e2 = Array.from(arguments), t2 = e2.map((e3) => {
-      const t3 = e3.getAction(), n2 = e3.getCommand();
-      if ("getTemp" !== n2.$db[n2.$db.length - 1].$method)
-        throw new Error("multiSend只支持子命令内使用getTemp");
-      return { action: t3, command: n2 };
-    });
-    return this._callCloudFunction({ multiCommand: t2, queryList: e2 });
-  }
-} {
-  _parseResult(e2) {
-    return this._isJQL ? e2.result : e2;
-  }
-  _callCloudFunction({ action: e2, command: t2, multiCommand: n2, queryList: s2 }) {
-    function r2(e3, t3) {
-      if (n2 && s2)
-        for (let n3 = 0; n3 < s2.length; n3++) {
-          const r3 = s2[n3];
-          r3.udb && "function" == typeof r3.udb.setResult && (t3 ? r3.udb.setResult(t3) : r3.udb.setResult(e3.result.dataList[n3]));
-        }
-    }
-    const i2 = this, o2 = this._isJQL ? "databaseForJQL" : "database";
-    function a2(e3) {
-      return i2._callback("error", [e3]), M(q(o2, "fail"), e3).then(() => M(q(o2, "complete"), e3)).then(() => (r2(null, e3), Y(j, { type: W, content: e3 }), Promise.reject(e3)));
-    }
-    const c2 = M(q(o2, "invoke")), u2 = this._uniClient;
-    return c2.then(() => u2.callFunction({ name: "DCloud-clientDB", type: l, data: { action: e2, command: t2, multiCommand: n2 } })).then((e3) => {
-      const { code: t3, message: n3, token: s3, tokenExpired: c3, systemInfo: u3 = [] } = e3.result;
-      if (u3)
-        for (let e4 = 0; e4 < u3.length; e4++) {
-          const { level: t4, message: n4, detail: s4 } = u3[e4], r3 = console[t4] || console.log;
-          let i3 = "[System Info]" + n4;
-          s4 && (i3 = `${i3}
-详细信息:${s4}`), r3(i3);
-        }
-      if (t3) {
-        return a2(new te({ code: t3, message: n3, requestId: e3.requestId }));
-      }
-      e3.result.errCode = e3.result.errCode || e3.result.code, e3.result.errMsg = e3.result.errMsg || e3.result.message, s3 && c3 && (ie({ token: s3, tokenExpired: c3 }), this._callbackAuth("refreshToken", [{ token: s3, tokenExpired: c3 }]), this._callback("refreshToken", [{ token: s3, tokenExpired: c3 }]), Y(B, { token: s3, tokenExpired: c3 }));
-      const l2 = [{ prop: "affectedDocs", tips: "affectedDocs不再推荐使用,请使用inserted/deleted/updated/data.length替代" }, { prop: "code", tips: "code不再推荐使用,请使用errCode替代" }, { prop: "message", tips: "message不再推荐使用,请使用errMsg替代" }];
-      for (let t4 = 0; t4 < l2.length; t4++) {
-        const { prop: n4, tips: s4 } = l2[t4];
-        if (n4 in e3.result) {
-          const t5 = e3.result[n4];
-          Object.defineProperty(e3.result, n4, { get: () => (console.warn(s4), t5) });
-        }
-      }
-      return function(e4) {
-        return M(q(o2, "success"), e4).then(() => M(q(o2, "complete"), e4)).then(() => {
-          r2(e4, null);
-          const t4 = i2._parseResult(e4);
-          return Y(j, { type: W, content: t4 }), Promise.resolve(t4);
-        });
-      }(e3);
-    }, (e3) => {
-      /fc_function_not_found|FUNCTION_NOT_FOUND/g.test(e3.message) && console.warn("clientDB未初始化,请在web控制台保存一次schema以开启clientDB");
-      return a2(new te({ code: e3.code || "SYSTEM_ERROR", message: e3.message, requestId: e3.requestId }));
-    });
-  }
-}
-const is = "token无效,跳转登录页面", os = "token过期,跳转登录页面", as = { TOKEN_INVALID_TOKEN_EXPIRED: os, TOKEN_INVALID_INVALID_CLIENTID: is, TOKEN_INVALID: is, TOKEN_INVALID_WRONG_TOKEN: is, TOKEN_INVALID_ANONYMOUS_USER: is }, cs = { "uni-id-token-expired": os, "uni-id-check-token-failed": is, "uni-id-token-not-exist": is, "uni-id-check-device-feature-failed": is };
-function us(e2, t2) {
-  let n2 = "";
-  return n2 = e2 ? `${e2}/${t2}` : t2, n2.replace(/^\//, "");
-}
-function ls(e2 = [], t2 = "") {
-  const n2 = [], s2 = [];
-  return e2.forEach((e3) => {
-    true === e3.needLogin ? n2.push(us(t2, e3.path)) : false === e3.needLogin && s2.push(us(t2, e3.path));
-  }), { needLoginPage: n2, notNeedLoginPage: s2 };
-}
-function hs(e2) {
-  return e2.split("?")[0].replace(/^\//, "");
-}
-function ds() {
-  return function(e2) {
-    let t2 = e2 && e2.$page && e2.$page.fullPath || "";
-    return t2 ? ("/" !== t2.charAt(0) && (t2 = "/" + t2), t2) : t2;
-  }(function() {
-    const e2 = getCurrentPages();
-    return e2[e2.length - 1];
-  }());
-}
-function ps() {
-  return hs(ds());
-}
-function fs(e2 = "", t2 = {}) {
-  if (!e2)
-    return false;
-  if (!(t2 && t2.list && t2.list.length))
-    return false;
-  const n2 = t2.list, s2 = hs(e2);
-  return n2.some((e3) => e3.pagePath === s2);
-}
-const gs = !!e.uniIdRouter;
-const { loginPage: ms, routerNeedLogin: ys, resToLogin: _s, needLoginPage: ws, notNeedLoginPage: vs, loginPageInTabBar: Is } = function({ pages: t2 = [], subPackages: n2 = [], uniIdRouter: s2 = {}, tabBar: r2 = {} } = e) {
-  const { loginPage: i2, needLogin: o2 = [], resToLogin: a2 = true } = s2, { needLoginPage: c2, notNeedLoginPage: u2 } = ls(t2), { needLoginPage: l2, notNeedLoginPage: h2 } = function(e2 = []) {
-    const t3 = [], n3 = [];
-    return e2.forEach((e3) => {
-      const { root: s3, pages: r3 = [] } = e3, { needLoginPage: i3, notNeedLoginPage: o3 } = ls(r3, s3);
-      t3.push(...i3), n3.push(...o3);
-    }), { needLoginPage: t3, notNeedLoginPage: n3 };
-  }(n2);
-  return { loginPage: i2, routerNeedLogin: o2, resToLogin: a2, needLoginPage: [...c2, ...l2], notNeedLoginPage: [...u2, ...h2], loginPageInTabBar: fs(i2, r2) };
-}();
-if (ws.indexOf(ms) > -1)
-  throw new Error(`Login page [${ms}] should not be "needLogin", please check your pages.json`);
-function Ss(e2) {
-  const t2 = ps();
-  if ("/" === e2.charAt(0))
-    return e2;
-  const [n2, s2] = e2.split("?"), r2 = n2.replace(/^\//, "").split("/"), i2 = t2.split("/");
-  i2.pop();
-  for (let e3 = 0; e3 < r2.length; e3++) {
-    const t3 = r2[e3];
-    ".." === t3 ? i2.pop() : "." !== t3 && i2.push(t3);
-  }
-  return "" === i2[0] && i2.shift(), "/" + i2.join("/") + (s2 ? "?" + s2 : "");
-}
-function bs(e2) {
-  const t2 = hs(Ss(e2));
-  return !(vs.indexOf(t2) > -1) && (ws.indexOf(t2) > -1 || ys.some((t3) => function(e3, t4) {
-    return new RegExp(t4).test(e3);
-  }(e2, t3)));
-}
-function ks({ redirect: e2 }) {
-  const t2 = hs(e2), n2 = hs(ms);
-  return ps() !== n2 && t2 !== n2;
-}
-function As({ api: e2, redirect: t2 } = {}) {
-  if (!t2 || !ks({ redirect: t2 }))
-    return;
-  const n2 = function(e3, t3) {
-    return "/" !== e3.charAt(0) && (e3 = "/" + e3), t3 ? e3.indexOf("?") > -1 ? e3 + `&uniIdRedirectUrl=${encodeURIComponent(t3)}` : e3 + `?uniIdRedirectUrl=${encodeURIComponent(t3)}` : e3;
-  }(ms, t2);
-  Is ? "navigateTo" !== e2 && "redirectTo" !== e2 || (e2 = "switchTab") : "switchTab" === e2 && (e2 = "navigateTo");
-  const s2 = { navigateTo: index.navigateTo, redirectTo: index.redirectTo, switchTab: index.switchTab, reLaunch: index.reLaunch };
-  setTimeout(() => {
-    s2[e2]({ url: n2 });
-  }, 0);
-}
-function Cs({ url: e2 } = {}) {
-  const t2 = { abortLoginPageJump: false, autoToLoginPage: false }, n2 = function() {
-    const { token: e3, tokenExpired: t3 } = re();
-    let n3;
-    if (e3) {
-      if (t3 < Date.now()) {
-        const e4 = "uni-id-token-expired";
-        n3 = { errCode: e4, errMsg: cs[e4] };
-      }
-    } else {
-      const e4 = "uni-id-check-token-failed";
-      n3 = { errCode: e4, errMsg: cs[e4] };
-    }
-    return n3;
-  }();
-  if (bs(e2) && n2) {
-    n2.uniIdRedirectUrl = e2;
-    if (z($).length > 0)
-      return setTimeout(() => {
-        Y($, n2);
-      }, 0), t2.abortLoginPageJump = true, t2;
-    t2.autoToLoginPage = true;
-  }
-  return t2;
-}
-function Ps() {
-  !function() {
-    const e3 = ds(), { abortLoginPageJump: t2, autoToLoginPage: n2 } = Cs({ url: e3 });
-    t2 || n2 && As({ api: "redirectTo", redirect: e3 });
-  }();
-  const e2 = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
-  for (let t2 = 0; t2 < e2.length; t2++) {
-    const n2 = e2[t2];
-    index.addInterceptor(n2, { invoke(e3) {
-      const { abortLoginPageJump: t3, autoToLoginPage: s2 } = Cs({ url: e3.url });
-      return t3 ? e3 : s2 ? (As({ api: n2, redirect: Ss(e3.url) }), false) : e3;
-    } });
-  }
-}
-function Ts() {
-  this.onResponse((e2) => {
-    const { type: t2, content: n2 } = e2;
-    let s2 = false;
-    switch (t2) {
-      case "cloudobject":
-        s2 = function(e3) {
-          if ("object" != typeof e3)
-            return false;
-          const { errCode: t3 } = e3 || {};
-          return t3 in cs;
-        }(n2);
-        break;
-      case "clientdb":
-        s2 = function(e3) {
-          if ("object" != typeof e3)
-            return false;
-          const { errCode: t3 } = e3 || {};
-          return t3 in as;
-        }(n2);
-    }
-    s2 && function(e3 = {}) {
-      const t3 = z($);
-      Z().then(() => {
-        const n3 = ds();
-        if (n3 && ks({ redirect: n3 }))
-          return t3.length > 0 ? Y($, Object.assign({ uniIdRedirectUrl: n3 }, e3)) : void (ms && As({ api: "navigateTo", redirect: n3 }));
-      });
-    }(n2);
-  });
-}
-function xs(e2) {
-  !function(e3) {
-    e3.onResponse = function(e4) {
-      V(j, e4);
-    }, e3.offResponse = function(e4) {
-      G(j, e4);
-    };
-  }(e2), function(e3) {
-    e3.onNeedLogin = function(e4) {
-      V($, e4);
-    }, e3.offNeedLogin = function(e4) {
-      G($, e4);
-    }, gs && (L("_globalUniCloudStatus").needLoginInit || (L("_globalUniCloudStatus").needLoginInit = true, Z().then(() => {
-      Ps.call(e3);
-    }), _s && Ts.call(e3)));
-  }(e2), function(e3) {
-    e3.onRefreshToken = function(e4) {
-      V(B, e4);
-    }, e3.offRefreshToken = function(e4) {
-      G(B, e4);
-    };
-  }(e2);
-}
-let Os;
-const Es = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", Ls = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/;
-function Rs() {
-  const e2 = re().token || "", t2 = e2.split(".");
-  if (!e2 || 3 !== t2.length)
-    return { uid: null, role: [], permission: [], tokenExpired: 0 };
-  let n2;
-  try {
-    n2 = JSON.parse((s2 = t2[1], decodeURIComponent(Os(s2).split("").map(function(e3) {
-      return "%" + ("00" + e3.charCodeAt(0).toString(16)).slice(-2);
-    }).join(""))));
-  } catch (e3) {
-    throw new Error("获取当前用户信息出错,详细错误信息为:" + e3.message);
-  }
-  var s2;
-  return n2.tokenExpired = 1e3 * n2.exp, delete n2.exp, delete n2.iat, n2;
-}
-Os = "function" != typeof atob ? function(e2) {
-  if (e2 = String(e2).replace(/[\t\n\f\r ]+/g, ""), !Ls.test(e2))
-    throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
-  var t2;
-  e2 += "==".slice(2 - (3 & e2.length));
-  for (var n2, s2, r2 = "", i2 = 0; i2 < e2.length; )
-    t2 = Es.indexOf(e2.charAt(i2++)) << 18 | Es.indexOf(e2.charAt(i2++)) << 12 | (n2 = Es.indexOf(e2.charAt(i2++))) << 6 | (s2 = Es.indexOf(e2.charAt(i2++))), r2 += 64 === n2 ? String.fromCharCode(t2 >> 16 & 255) : 64 === s2 ? String.fromCharCode(t2 >> 16 & 255, t2 >> 8 & 255) : String.fromCharCode(t2 >> 16 & 255, t2 >> 8 & 255, 255 & t2);
-  return r2;
-} : atob;
-var Us = n(function(e2, t2) {
-  Object.defineProperty(t2, "__esModule", { value: true });
-  const n2 = "chooseAndUploadFile:ok", s2 = "chooseAndUploadFile:fail";
-  function r2(e3, t3) {
-    return e3.tempFiles.forEach((e4, n3) => {
-      e4.name || (e4.name = e4.path.substring(e4.path.lastIndexOf("/") + 1)), t3 && (e4.fileType = t3), e4.cloudPath = Date.now() + "_" + n3 + e4.name.substring(e4.name.lastIndexOf("."));
-    }), e3.tempFilePaths || (e3.tempFilePaths = e3.tempFiles.map((e4) => e4.path)), e3;
-  }
-  function i2(e3, t3, { onChooseFile: s3, onUploadProgress: r3 }) {
-    return t3.then((e4) => {
-      if (s3) {
-        const t4 = s3(e4);
-        if (void 0 !== t4)
-          return Promise.resolve(t4).then((t5) => void 0 === t5 ? e4 : t5);
-      }
-      return e4;
-    }).then((t4) => false === t4 ? { errMsg: n2, tempFilePaths: [], tempFiles: [] } : function(e4, t5, s4 = 5, r4) {
-      (t5 = Object.assign({}, t5)).errMsg = n2;
-      const i3 = t5.tempFiles, o2 = i3.length;
-      let a2 = 0;
-      return new Promise((n3) => {
-        for (; a2 < s4; )
-          c2();
-        function c2() {
-          const s5 = a2++;
-          if (s5 >= o2)
-            return void (!i3.find((e5) => !e5.url && !e5.errMsg) && n3(t5));
-          const u2 = i3[s5];
-          e4.uploadFile({ provider: u2.provider, filePath: u2.path, cloudPath: u2.cloudPath, fileType: u2.fileType, cloudPathAsRealPath: u2.cloudPathAsRealPath, onUploadProgress(e5) {
-            e5.index = s5, e5.tempFile = u2, e5.tempFilePath = u2.path, r4 && r4(e5);
-          } }).then((e5) => {
-            u2.url = e5.fileID, s5 < o2 && c2();
-          }).catch((e5) => {
-            u2.errMsg = e5.errMsg || e5.message, s5 < o2 && c2();
-          });
-        }
-      });
-    }(e3, t4, 5, r3));
-  }
-  t2.initChooseAndUploadFile = function(e3) {
-    return function(t3 = { type: "all" }) {
-      return "image" === t3.type ? i2(e3, function(e4) {
-        const { count: t4, sizeType: n3, sourceType: i3 = ["album", "camera"], extension: o2 } = e4;
-        return new Promise((e5, a2) => {
-          index.chooseImage({ count: t4, sizeType: n3, sourceType: i3, extension: o2, success(t5) {
-            e5(r2(t5, "image"));
-          }, fail(e6) {
-            a2({ errMsg: e6.errMsg.replace("chooseImage:fail", s2) });
-          } });
-        });
-      }(t3), t3) : "video" === t3.type ? i2(e3, function(e4) {
-        const { camera: t4, compressed: n3, maxDuration: i3, sourceType: o2 = ["album", "camera"], extension: a2 } = e4;
-        return new Promise((e5, c2) => {
-          index.chooseVideo({ camera: t4, compressed: n3, maxDuration: i3, sourceType: o2, extension: a2, success(t5) {
-            const { tempFilePath: n4, duration: s3, size: i4, height: o3, width: a3 } = t5;
-            e5(r2({ errMsg: "chooseVideo:ok", tempFilePaths: [n4], tempFiles: [{ name: t5.tempFile && t5.tempFile.name || "", path: n4, size: i4, type: t5.tempFile && t5.tempFile.type || "", width: a3, height: o3, duration: s3, fileType: "video", cloudPath: "" }] }, "video"));
-          }, fail(e6) {
-            c2({ errMsg: e6.errMsg.replace("chooseVideo:fail", s2) });
-          } });
-        });
-      }(t3), t3) : i2(e3, function(e4) {
-        const { count: t4, extension: n3 } = e4;
-        return new Promise((e5, i3) => {
-          let o2 = index.chooseFile;
-          if ("undefined" != typeof wx$1 && "function" == typeof wx$1.chooseMessageFile && (o2 = wx$1.chooseMessageFile), "function" != typeof o2)
-            return i3({ errMsg: s2 + " 请指定 type 类型,该平台仅支持选择 image 或 video。" });
-          o2({ type: "all", count: t4, extension: n3, success(t5) {
-            e5(r2(t5));
-          }, fail(e6) {
-            i3({ errMsg: e6.errMsg.replace("chooseFile:fail", s2) });
-          } });
-        });
-      }(t3), t3);
-    };
-  };
-}), Ns = t(Us);
-const Ds = "manual";
-function Ms(e2) {
-  return { props: { localdata: { type: Array, default: () => [] }, options: { type: [Object, Array], default: () => ({}) }, spaceInfo: { type: Object, default: () => ({}) }, collection: { type: [String, Array], default: "" }, action: { type: String, default: "" }, field: { type: String, default: "" }, orderby: { type: String, default: "" }, where: { type: [String, Object], default: "" }, pageData: { type: String, default: "add" }, pageCurrent: { type: Number, default: 1 }, pageSize: { type: Number, default: 20 }, getcount: { type: [Boolean, String], default: false }, gettree: { type: [Boolean, String], default: false }, gettreepath: { type: [Boolean, String], default: false }, startwith: { type: String, default: "" }, limitlevel: { type: Number, default: 10 }, groupby: { type: String, default: "" }, groupField: { type: String, default: "" }, distinct: { type: [Boolean, String], default: false }, foreignKey: { type: String, default: "" }, loadtime: { type: String, default: "auto" }, manual: { type: Boolean, default: false } }, data: () => ({ mixinDatacomLoading: false, mixinDatacomHasMore: false, mixinDatacomResData: [], mixinDatacomErrorMessage: "", mixinDatacomPage: {}, mixinDatacomError: null }), created() {
-    this.mixinDatacomPage = { current: this.pageCurrent, size: this.pageSize, count: 0 }, this.$watch(() => {
-      var e3 = [];
-      return ["pageCurrent", "pageSize", "localdata", "collection", "action", "field", "orderby", "where", "getont", "getcount", "gettree", "groupby", "groupField", "distinct"].forEach((t2) => {
-        e3.push(this[t2]);
-      }), e3;
-    }, (e3, t2) => {
-      if (this.loadtime === Ds)
-        return;
-      let n2 = false;
-      const s2 = [];
-      for (let r2 = 2; r2 < e3.length; r2++)
-        e3[r2] !== t2[r2] && (s2.push(e3[r2]), n2 = true);
-      e3[0] !== t2[0] && (this.mixinDatacomPage.current = this.pageCurrent), this.mixinDatacomPage.size = this.pageSize, this.onMixinDatacomPropsChange(n2, s2);
-    });
-  }, methods: { onMixinDatacomPropsChange(e3, t2) {
-  }, mixinDatacomEasyGet({ getone: e3 = false, success: t2, fail: n2 } = {}) {
-    this.mixinDatacomLoading || (this.mixinDatacomLoading = true, this.mixinDatacomErrorMessage = "", this.mixinDatacomError = null, this.mixinDatacomGet().then((n3) => {
-      this.mixinDatacomLoading = false;
-      const { data: s2, count: r2 } = n3.result;
-      this.getcount && (this.mixinDatacomPage.count = r2), this.mixinDatacomHasMore = s2.length < this.pageSize;
-      const i2 = e3 ? s2.length ? s2[0] : void 0 : s2;
-      this.mixinDatacomResData = i2, t2 && t2(i2);
-    }).catch((e4) => {
-      this.mixinDatacomLoading = false, this.mixinDatacomErrorMessage = e4, this.mixinDatacomError = e4, n2 && n2(e4);
-    }));
-  }, mixinDatacomGet(t2 = {}) {
-    let n2;
-    t2 = t2 || {}, n2 = "undefined" != typeof __uniX && __uniX ? e2.databaseForJQL(this.spaceInfo) : e2.database(this.spaceInfo);
-    const s2 = t2.action || this.action;
-    s2 && (n2 = n2.action(s2));
-    const r2 = t2.collection || this.collection;
-    n2 = Array.isArray(r2) ? n2.collection(...r2) : n2.collection(r2);
-    const i2 = t2.where || this.where;
-    i2 && Object.keys(i2).length && (n2 = n2.where(i2));
-    const o2 = t2.field || this.field;
-    o2 && (n2 = n2.field(o2));
-    const a2 = t2.foreignKey || this.foreignKey;
-    a2 && (n2 = n2.foreignKey(a2));
-    const c2 = t2.groupby || this.groupby;
-    c2 && (n2 = n2.groupBy(c2));
-    const u2 = t2.groupField || this.groupField;
-    u2 && (n2 = n2.groupField(u2));
-    true === (void 0 !== t2.distinct ? t2.distinct : this.distinct) && (n2 = n2.distinct());
-    const l2 = t2.orderby || this.orderby;
-    l2 && (n2 = n2.orderBy(l2));
-    const h2 = void 0 !== t2.pageCurrent ? t2.pageCurrent : this.mixinDatacomPage.current, d2 = void 0 !== t2.pageSize ? t2.pageSize : this.mixinDatacomPage.size, p2 = void 0 !== t2.getcount ? t2.getcount : this.getcount, f2 = void 0 !== t2.gettree ? t2.gettree : this.gettree, g2 = void 0 !== t2.gettreepath ? t2.gettreepath : this.gettreepath, m2 = { getCount: p2 }, y2 = { limitLevel: void 0 !== t2.limitlevel ? t2.limitlevel : this.limitlevel, startWith: void 0 !== t2.startwith ? t2.startwith : this.startwith };
-    return f2 && (m2.getTree = y2), g2 && (m2.getTreePath = y2), n2 = n2.skip(d2 * (h2 - 1)).limit(d2).get(m2), n2;
-  } } };
-}
-function qs(e2) {
-  return function(t2, n2 = {}) {
-    n2 = function(e3, t3 = {}) {
-      return e3.customUI = t3.customUI || e3.customUI, e3.parseSystemError = t3.parseSystemError || e3.parseSystemError, Object.assign(e3.loadingOptions, t3.loadingOptions), Object.assign(e3.errorOptions, t3.errorOptions), "object" == typeof t3.secretMethods && (e3.secretMethods = t3.secretMethods), e3;
-    }({ customUI: false, loadingOptions: { title: "加载中...", mask: true }, errorOptions: { type: "modal", retry: false } }, n2);
-    const { customUI: s2, loadingOptions: r2, errorOptions: i2, parseSystemError: o2 } = n2, a2 = !s2;
-    return new Proxy({}, { get(s3, c2) {
-      switch (c2) {
-        case "toString":
-          return "[object UniCloudObject]";
-        case "toJSON":
-          return {};
-      }
-      return function({ fn: e3, interceptorName: t3, getCallbackArgs: n3 } = {}) {
-        return async function(...s4) {
-          const r3 = n3 ? n3({ params: s4 }) : {};
-          let i3, o3;
-          try {
-            return await M(q(t3, "invoke"), { ...r3 }), i3 = await e3(...s4), await M(q(t3, "success"), { ...r3, result: i3 }), i3;
-          } catch (e4) {
-            throw o3 = e4, await M(q(t3, "fail"), { ...r3, error: o3 }), o3;
-          } finally {
-            await M(q(t3, "complete"), o3 ? { ...r3, error: o3 } : { ...r3, result: i3 });
-          }
-        };
-      }({ fn: async function s4(...l2) {
-        let h2;
-        a2 && index.showLoading({ title: r2.title, mask: r2.mask });
-        const d2 = { name: t2, type: u, data: { method: c2, params: l2 } };
-        "object" == typeof n2.secretMethods && function(e3, t3) {
-          const n3 = t3.data.method, s5 = e3.secretMethods || {}, r3 = s5[n3] || s5["*"];
-          r3 && (t3.secretType = r3);
-        }(n2, d2);
-        let p2 = false;
-        try {
-          h2 = await e2.callFunction(d2);
-        } catch (e3) {
-          p2 = true, h2 = { result: new te(e3) };
-        }
-        const { errSubject: f2, errCode: g2, errMsg: m2, newToken: y2 } = h2.result || {};
-        if (a2 && index.hideLoading(), y2 && y2.token && y2.tokenExpired && (ie(y2), Y(B, { ...y2 })), g2) {
-          let e3 = m2;
-          if (p2 && o2) {
-            e3 = (await o2({ objectName: t2, methodName: c2, params: l2, errSubject: f2, errCode: g2, errMsg: m2 })).errMsg || m2;
-          }
-          if (a2)
-            if ("toast" === i2.type)
-              index.showToast({ title: e3, icon: "none" });
-            else {
-              if ("modal" !== i2.type)
-                throw new Error(`Invalid errorOptions.type: ${i2.type}`);
-              {
-                const { confirm: t3 } = await async function({ title: e4, content: t4, showCancel: n4, cancelText: s5, confirmText: r3 } = {}) {
-                  return new Promise((i3, o3) => {
-                    index.showModal({ title: e4, content: t4, showCancel: n4, cancelText: s5, confirmText: r3, success(e5) {
-                      i3(e5);
-                    }, fail() {
-                      i3({ confirm: false, cancel: true });
-                    } });
-                  });
-                }({ title: "提示", content: e3, showCancel: i2.retry, cancelText: "取消", confirmText: i2.retry ? "重试" : "确定" });
-                if (i2.retry && t3)
-                  return s4(...l2);
-              }
-            }
-          const n3 = new te({ subject: f2, code: g2, message: m2, requestId: h2.requestId });
-          throw n3.detail = h2.result, Y(j, { type: J, content: n3 }), n3;
-        }
-        return Y(j, { type: J, content: h2.result }), h2.result;
-      }, interceptorName: "callObject", getCallbackArgs: function({ params: e3 } = {}) {
-        return { objectName: t2, methodName: c2, params: e3 };
-      } });
-    } });
-  };
-}
-function Fs(e2) {
-  return L("_globalUniCloudSecureNetworkCache__{spaceId}".replace("{spaceId}", e2.config.spaceId));
-}
-async function Ks({ openid: e2, callLoginByWeixin: t2 = false } = {}) {
-  const n2 = Fs(this);
-  if (e2 && t2)
-    throw new Error("[SecureNetwork] openid and callLoginByWeixin cannot be passed at the same time");
-  if (e2)
-    return n2.mpWeixinOpenid = e2, {};
-  const s2 = await new Promise((e3, t3) => {
-    index.login({ success(t4) {
-      e3(t4.code);
-    }, fail(e4) {
-      t3(new Error(e4.errMsg));
-    } });
-  }), r2 = this.importObject("uni-id-co", { customUI: true });
-  return await r2.secureNetworkHandshakeByWeixin({ code: s2, callLoginByWeixin: t2 }), n2.mpWeixinCode = s2, { code: s2 };
-}
-async function js(e2) {
-  const t2 = Fs(this);
-  return t2.initPromise || (t2.initPromise = Ks.call(this, e2).then((e3) => e3).catch((e3) => {
-    throw delete t2.initPromise, e3;
-  })), t2.initPromise;
-}
-function $s(e2) {
-  return function({ openid: t2, callLoginByWeixin: n2 = false } = {}) {
-    return js.call(e2, { openid: t2, callLoginByWeixin: n2 });
-  };
-}
-function Bs(e2) {
-  !function(e3) {
-    le = e3;
-  }(e2);
-}
-function Ws(e2) {
-  const t2 = { getSystemInfo: index.getSystemInfo, getPushClientId: index.getPushClientId };
-  return function(n2) {
-    return new Promise((s2, r2) => {
-      t2[e2]({ ...n2, success(e3) {
-        s2(e3);
-      }, fail(e3) {
-        r2(e3);
-      } });
-    });
-  };
-}
-class Hs extends class {
-  constructor() {
-    this._callback = {};
-  }
-  addListener(e2, t2) {
-    this._callback[e2] || (this._callback[e2] = []), this._callback[e2].push(t2);
-  }
-  on(e2, t2) {
-    return this.addListener(e2, t2);
-  }
-  removeListener(e2, t2) {
-    if (!t2)
-      throw new Error('The "listener" argument must be of type function. Received undefined');
-    const n2 = this._callback[e2];
-    if (!n2)
-      return;
-    const s2 = function(e3, t3) {
-      for (let n3 = e3.length - 1; n3 >= 0; n3--)
-        if (e3[n3] === t3)
-          return n3;
-      return -1;
-    }(n2, t2);
-    n2.splice(s2, 1);
-  }
-  off(e2, t2) {
-    return this.removeListener(e2, t2);
-  }
-  removeAllListener(e2) {
-    delete this._callback[e2];
-  }
-  emit(e2, ...t2) {
-    const n2 = this._callback[e2];
-    if (n2)
-      for (let e3 = 0; e3 < n2.length; e3++)
-        n2[e3](...t2);
-  }
-} {
-  constructor() {
-    super(), this._uniPushMessageCallback = this._receivePushMessage.bind(this), this._currentMessageId = -1, this._payloadQueue = [];
-  }
-  init() {
-    return Promise.all([Ws("getSystemInfo")(), Ws("getPushClientId")()]).then(([{ appId: e2 } = {}, { cid: t2 } = {}] = []) => {
-      if (!e2)
-        throw new Error("Invalid appId, please check the manifest.json file");
-      if (!t2)
-        throw new Error("Invalid push client id");
-      this._appId = e2, this._pushClientId = t2, this._seqId = Date.now() + "-" + Math.floor(9e5 * Math.random() + 1e5), this.emit("open"), this._initMessageListener();
-    }, (e2) => {
-      throw this.emit("error", e2), this.close(), e2;
-    });
-  }
-  async open() {
-    return this.init();
-  }
-  _isUniCloudSSE(e2) {
-    if ("receive" !== e2.type)
-      return false;
-    const t2 = e2 && e2.data && e2.data.payload;
-    return !(!t2 || "UNI_CLOUD_SSE" !== t2.channel || t2.seqId !== this._seqId);
-  }
-  _receivePushMessage(e2) {
-    if (!this._isUniCloudSSE(e2))
-      return;
-    const t2 = e2 && e2.data && e2.data.payload, { action: n2, messageId: s2, message: r2 } = t2;
-    this._payloadQueue.push({ action: n2, messageId: s2, message: r2 }), this._consumMessage();
-  }
-  _consumMessage() {
-    for (; ; ) {
-      const e2 = this._payloadQueue.find((e3) => e3.messageId === this._currentMessageId + 1);
-      if (!e2)
-        break;
-      this._currentMessageId++, this._parseMessagePayload(e2);
-    }
-  }
-  _parseMessagePayload(e2) {
-    const { action: t2, messageId: n2, message: s2 } = e2;
-    "end" === t2 ? this._end({ messageId: n2, message: s2 }) : "message" === t2 && this._appendMessage({ messageId: n2, message: s2 });
-  }
-  _appendMessage({ messageId: e2, message: t2 } = {}) {
-    this.emit("message", t2);
-  }
-  _end({ messageId: e2, message: t2 } = {}) {
-    this.emit("end", t2), this.close();
-  }
-  _initMessageListener() {
-    index.onPushMessage(this._uniPushMessageCallback);
-  }
-  _destroy() {
-    index.offPushMessage(this._uniPushMessageCallback);
-  }
-  toJSON() {
-    return { appId: this._appId, pushClientId: this._pushClientId, seqId: this._seqId };
-  }
-  close() {
-    this._destroy(), this.emit("close");
-  }
-}
-async function Js(e2) {
-  const t2 = e2.__dev__;
-  if (!t2.debugInfo)
-    return;
-  const { address: n2, servePort: s2 } = t2.debugInfo, { address: r2 } = await At(n2, s2);
-  if (r2)
-    return t2.localAddress = r2, void (t2.localPort = s2);
-  const i2 = console["warn"];
-  let o2 = "";
-  if ("remote" === t2.debugInfo.initialLaunchType ? (t2.debugInfo.forceRemote = true, o2 = "当前客户端和HBuilderX不在同一局域网下(或其他网络原因无法连接HBuilderX),uniCloud本地调试服务不对当前客户端生效。\n- 如果不使用uniCloud本地调试服务,请直接忽略此信息。\n- 如需使用uniCloud本地调试服务,请将客户端与主机连接到同一局域网下并重新运行到客户端。") : o2 = "无法连接uniCloud本地调试服务,请检查当前客户端是否与主机在同一局域网下。\n- 如需使用uniCloud本地调试服务,请将客户端与主机连接到同一局域网下并重新运行到客户端。", o2 += "\n- 如果在HBuilderX开启的状态下切换过网络环境,请重启HBuilderX后再试\n- 检查系统防火墙是否拦截了HBuilderX自带的nodejs\n- 检查是否错误的使用拦截器修改uni.request方法的参数", 0 === C.indexOf("mp-") && (o2 += "\n- 小程序中如何使用uniCloud,请参考:https://uniapp.dcloud.net.cn/uniCloud/publish.html#useinmp"), !t2.debugInfo.forceRemote)
-    throw new Error(o2);
-  i2(o2);
-}
-function zs(e2) {
-  e2._initPromiseHub || (e2._initPromiseHub = new v({ createPromise: function() {
-    let t2 = Promise.resolve();
-    var n2;
-    n2 = 1, t2 = new Promise((e3) => {
-      setTimeout(() => {
-        e3();
-      }, n2);
-    });
-    const s2 = e2.auth();
-    return t2.then(() => s2.getLoginState()).then((e3) => e3 ? Promise.resolve() : s2.signInAnonymously());
-  } }));
-}
-const Vs = { tcb: bt, tencent: bt, aliyun: fe, private: Tt, dcloud: Tt, alipay: qt };
-let Gs = new class {
-  init(e2) {
-    let t2 = {};
-    const n2 = Vs[e2.provider];
-    if (!n2)
-      throw new Error("未提供正确的provider参数");
-    t2 = n2.init(e2), function(e3) {
-      const t3 = {};
-      e3.__dev__ = t3, t3.debugLog = "app" === C;
-      const n3 = P;
-      n3 && !n3.code && (t3.debugInfo = n3);
-      const s2 = new v({ createPromise: function() {
-        return Js(e3);
-      } });
-      t3.initLocalNetwork = function() {
-        return s2.exec();
-      };
-    }(t2), zs(t2), Jn(t2), function(e3) {
-      const t3 = e3.uploadFile;
-      e3.uploadFile = function(e4) {
-        return t3.call(this, e4);
-      };
-    }(t2), function(e3) {
-      e3.database = function(t3) {
-        if (t3 && Object.keys(t3).length > 0)
-          return e3.init(t3).database();
-        if (this._database)
-          return this._database;
-        const n3 = ss(rs, { uniClient: e3 });
-        return this._database = n3, n3;
-      }, e3.databaseForJQL = function(t3) {
-        if (t3 && Object.keys(t3).length > 0)
-          return e3.init(t3).databaseForJQL();
-        if (this._databaseForJQL)
-          return this._databaseForJQL;
-        const n3 = ss(rs, { uniClient: e3, isJQL: true });
-        return this._databaseForJQL = n3, n3;
-      };
-    }(t2), function(e3) {
-      e3.getCurrentUserInfo = Rs, e3.chooseAndUploadFile = Ns.initChooseAndUploadFile(e3), Object.assign(e3, { get mixinDatacom() {
-        return Ms(e3);
-      } }), e3.SSEChannel = Hs, e3.initSecureNetworkByWeixin = $s(e3), e3.setCustomClientInfo = Bs, e3.importObject = qs(e3);
-    }(t2);
-    return ["callFunction", "uploadFile", "deleteFile", "getTempFileURL", "downloadFile", "chooseAndUploadFile"].forEach((e3) => {
-      if (!t2[e3])
-        return;
-      const n3 = t2[e3];
-      t2[e3] = function() {
-        return n3.apply(t2, Array.from(arguments));
-      }, t2[e3] = (/* @__PURE__ */ function(e4, t3) {
-        return function(n4) {
-          let s2 = false;
-          if ("callFunction" === t3) {
-            const e5 = n4 && n4.type || c;
-            s2 = e5 !== c;
-          }
-          const r2 = "callFunction" === t3 && !s2, i2 = this._initPromiseHub.exec();
-          n4 = n4 || {};
-          const { success: o2, fail: a2, complete: u2 } = ee(n4), l2 = i2.then(() => s2 ? Promise.resolve() : M(q(t3, "invoke"), n4)).then(() => e4.call(this, n4)).then((e5) => s2 ? Promise.resolve(e5) : M(q(t3, "success"), e5).then(() => M(q(t3, "complete"), e5)).then(() => (r2 && Y(j, { type: H, content: e5 }), Promise.resolve(e5))), (e5) => s2 ? Promise.reject(e5) : M(q(t3, "fail"), e5).then(() => M(q(t3, "complete"), e5)).then(() => (Y(j, { type: H, content: e5 }), Promise.reject(e5))));
-          if (!(o2 || a2 || u2))
-            return l2;
-          l2.then((e5) => {
-            o2 && o2(e5), u2 && u2(e5), r2 && Y(j, { type: H, content: e5 });
-          }, (e5) => {
-            a2 && a2(e5), u2 && u2(e5), r2 && Y(j, { type: H, content: e5 });
-          });
-        };
-      }(t2[e3], e3)).bind(t2);
-    }), t2.init = this.init, t2;
-  }
-}();
-(() => {
-  const e2 = T;
-  let t2 = {};
-  if (e2 && 1 === e2.length)
-    t2 = e2[0], Gs = Gs.init(t2), Gs._isDefault = true;
-  else {
-    const t3 = ["auth", "callFunction", "uploadFile", "deleteFile", "getTempFileURL", "downloadFile", "database", "getCurrentUSerInfo", "importObject"];
-    let n2;
-    n2 = e2 && e2.length > 0 ? "应用有多个服务空间,请通过uniCloud.init方法指定要使用的服务空间" : "应用未关联服务空间,请在uniCloud目录右键关联服务空间", t3.forEach((e3) => {
-      Gs[e3] = function() {
-        return console.error(n2), Promise.reject(new te({ code: "SYS_ERR", message: n2 }));
-      };
-    });
-  }
-  Object.assign(Gs, { get mixinDatacom() {
-    return Ms(Gs);
-  } }), xs(Gs), Gs.addInterceptor = N, Gs.removeInterceptor = D, Gs.interceptObject = F;
-})();
-var Ys = Gs;
-exports.Ys = Ys;
-exports._export_sfc = _export_sfc;
-exports.computed = computed;
-exports.createSSRApp = createSSRApp;
-exports.defineComponent = defineComponent;
-exports.e = e$1;
-exports.f = f$1;
-exports.getCurrentInstance = getCurrentInstance;
-exports.index = index;
-exports.initVueI18n = initVueI18n;
-exports.n = n$1;
-exports.o = o$1;
-exports.onLaunch = onLaunch;
-exports.onLoad = onLoad;
-exports.onMounted = onMounted;
-exports.onShow = onShow;
-exports.onUnmounted = onUnmounted;
-exports.p = p$1;
-exports.ref = ref;
-exports.resolveComponent = resolveComponent;
-exports.s = s$1;
-exports.sr = sr;
-exports.t = t$1;
-exports.unref = unref;
-exports.watch = watch;
-exports.wx$1 = wx$1;
diff --git a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.js b/unpackage/dist/dev/mp-weixin/components/navbar/navbar.js
deleted file mode 100644
index 4ccaa99..0000000
--- a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-const common_vendor = require("../../common/vendor.js");
-const common_assets = require("../../common/assets.js");
-const _sfc_main = {
-  __name: "navbar",
-  props: {
-    title: {
-      type: String,
-      default: ""
-    }
-  },
-  setup(__props) {
-    function navBackTo() {
-      common_vendor.index.navigateBack();
-    }
-    const props = __props;
-    const pageTitle = common_vendor.ref(props.title);
-    common_vendor.watch(
-      props.title,
-      (New, Old) => {
-        pageTitle.value = New;
-      },
-      { immediate: true }
-    );
-    return (_ctx, _cache) => {
-      return {
-        a: common_assets._imports_0,
-        b: common_vendor.o(($event) => navBackTo()),
-        c: common_vendor.t(__props.title)
-      };
-    };
-  }
-};
-wx.createComponent(_sfc_main);
diff --git a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.json b/unpackage/dist/dev/mp-weixin/components/navbar/navbar.json
deleted file mode 100644
index e8cfaaf..0000000
--- a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "component": true,
-  "usingComponents": {}
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.wxml b/unpackage/dist/dev/mp-weixin/components/navbar/navbar.wxml
deleted file mode 100644
index b49cde2..0000000
--- a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.wxml
+++ /dev/null
@@ -1 +0,0 @@
-<view class="navbar"><image src="{{a}}" alt="" bindtap="{{b}}"></image><text>{{c}}</text></view>
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.wxss b/unpackage/dist/dev/mp-weixin/components/navbar/navbar.wxss
deleted file mode 100644
index 2fc8dfb..0000000
--- a/unpackage/dist/dev/mp-weixin/components/navbar/navbar.wxss
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
-.navbar {
-  width: 100%;
-  height: 176rpx;
-  background: linear-gradient(to bottom, #5EA1FA, #8BC1FC);
-  display: flex;
-  align-items: flex-end;
-  box-sizing: border-box;
-  position: relative;
-  padding: 0 32rpx 24rpx;
-}
-.navbar image {
-  width: 40rpx;
-  height: 40rpx;
-  transform: rotate(180deg);
-}
-.navbar text {
-  font-weight: 400;
-  font-size: 36rpx;
-  color: #000000;
-  position: absolute;
-  width: 200rpx;
-  left: calc(50% - 100rpx);
-  text-align: center;
-  color: #e4ecf9;
-  letter-spacing: 1rpx;
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/config/baseUrl.js b/unpackage/dist/dev/mp-weixin/config/baseUrl.js
deleted file mode 100644
index f5ac894..0000000
--- a/unpackage/dist/dev/mp-weixin/config/baseUrl.js
+++ /dev/null
@@ -1,3 +0,0 @@
-"use strict";
-const BASE_URL = "https://www.huiwuyuntong.com/water-drinking-beta";
-exports.BASE_URL = BASE_URL;
diff --git a/unpackage/dist/dev/mp-weixin/pages/addCard/index.js b/unpackage/dist/dev/mp-weixin/pages/addCard/index.js
deleted file mode 100644
index afa7afe..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/addCard/index.js
+++ /dev/null
@@ -1,132 +0,0 @@
-"use strict";
-const common_vendor = require("../../common/vendor.js");
-const common_assets = require("../../common/assets.js");
-const api_index = require("../../api/index.js");
-if (!Array) {
-  const _easycom_navbar2 = common_vendor.resolveComponent("navbar");
-  const _easycom_uni_forms_item2 = common_vendor.resolveComponent("uni-forms-item");
-  const _easycom_uni_forms2 = common_vendor.resolveComponent("uni-forms");
-  (_easycom_navbar2 + _easycom_uni_forms_item2 + _easycom_uni_forms2)();
-}
-const _easycom_navbar = () => "../../components/navbar/navbar.js";
-const _easycom_uni_forms_item = () => "../../uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.js";
-const _easycom_uni_forms = () => "../../uni_modules/uni-forms/components/uni-forms/uni-forms.js";
-if (!Math) {
-  (_easycom_navbar + _easycom_uni_forms_item + _easycom_uni_forms)();
-}
-const _sfc_main = {
-  __name: "index",
-  setup(__props) {
-    const form = common_vendor.ref({
-      id: JSON.parse(common_vendor.index.getStorageSync("userInfo")).id,
-      waterCardNumber: "",
-      userName: "",
-      userPhone: "",
-      remark: ""
-    });
-    function toScan() {
-      common_vendor.index.scanCode({
-        scanType: ["qrCode"],
-        success: function(res) {
-          console.log("条码内容:" + res.result);
-          let data = res.result.split("&id=");
-          form.value.waterCardNumber = data[1];
-          console.log("form.value.waterCardNumber", form.value.waterCardNumber);
-        }
-      });
-    }
-    const formRef = common_vendor.ref();
-    const rules = common_vendor.ref({
-      waterCardNumber: {
-        rules: [
-          { required: true, errorMessage: "请输入卡号" }
-        ]
-      },
-      userName: {
-        rules: [
-          { required: true, errorMessage: "请输入姓名" },
-          { pattern: /^[\u4e00-\u9fa5\\.]+$/, errorMessage: '请输入中文或" . "符号' }
-        ]
-      },
-      userPhone: {
-        rules: [
-          { required: true, errorMessage: "请输入您的手机号" },
-          { pattern: /^1[3-9]\d{9}$/, errorMessage: "手机号格式不正确" }
-        ]
-      }
-    });
-    async function submit() {
-      formRef.value.validate().then(async () => {
-        await api_index.creatUserArchive(form.value).then((res) => {
-          if (res.code == 200) {
-            common_vendor.index.showToast({
-              title: "添加成功!",
-              image: "../../static/images/other/success.svg",
-              duration: 2e3
-            }).then(() => {
-              common_vendor.index.navigateBack();
-            });
-          } else if (res.code == 300) {
-            common_vendor.index.showToast({
-              title: res.msg,
-              duration: 2e3,
-              icon: "none"
-            });
-          } else {
-            common_vendor.index.showToast({
-              title: "绑卡失败",
-              duration: 2e3,
-              icon: "none"
-            });
-          }
-        });
-      });
-    }
-    common_vendor.onMounted(() => {
-    });
-    return (_ctx, _cache) => {
-      return {
-        a: common_vendor.p({
-          title: "绑定会员卡"
-        }),
-        b: form.value.waterCardNumber,
-        c: common_vendor.o(($event) => form.value.waterCardNumber = $event.detail.value),
-        d: common_vendor.o(($event) => toScan()),
-        e: common_assets._imports_0$5,
-        f: common_vendor.p({
-          label: "卡号:",
-          name: "waterCardNumber"
-        }),
-        g: form.value.userName,
-        h: common_vendor.o(($event) => form.value.userName = $event.detail.value),
-        i: common_vendor.p({
-          label: "姓名:",
-          name: "userName"
-        }),
-        j: form.value.userPhone,
-        k: common_vendor.o(($event) => form.value.userPhone = $event.detail.value),
-        l: common_vendor.p({
-          label: "联系方式:",
-          name: "userPhone"
-        }),
-        m: form.value.remark,
-        n: common_vendor.o(($event) => form.value.remark = $event.detail.value),
-        o: common_vendor.p({
-          label: "备注:",
-          name: "remark"
-        }),
-        p: common_vendor.sr(formRef, "4c5e7c86-1", {
-          "k": "formRef"
-        }),
-        q: common_vendor.p({
-          model: form.value,
-          rules: rules.value,
-          ["label-width"]: "100"
-        }),
-        r: common_vendor.o(($event) => submit())
-      };
-    };
-  }
-};
-const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-4c5e7c86"]]);
-wx.createPage(MiniProgramPage);
diff --git a/unpackage/dist/dev/mp-weixin/pages/addCard/index.json b/unpackage/dist/dev/mp-weixin/pages/addCard/index.json
deleted file mode 100644
index a7ecc1a..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/addCard/index.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "navigationStyle": "custom",
-  "usingComponents": {
-    "navbar": "../../components/navbar/navbar",
-    "uni-forms-item": "../../uni_modules/uni-forms/components/uni-forms-item/uni-forms-item",
-    "uni-forms": "../../uni_modules/uni-forms/components/uni-forms/uni-forms"
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/addCard/index.wxml b/unpackage/dist/dev/mp-weixin/pages/addCard/index.wxml
deleted file mode 100644
index 830e7fc..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/addCard/index.wxml
+++ /dev/null
@@ -1 +0,0 @@
-<view class="container data-v-4c5e7c86"><view class="content data-v-4c5e7c86"><navbar wx:if="{{a}}" class="data-v-4c5e7c86" u-i="4c5e7c86-0" bind:__l="__l" u-p="{{a}}"></navbar><view class="main data-v-4c5e7c86"><view class="title data-v-4c5e7c86">请填写卡及个人信息</view><view class="form data-v-4c5e7c86"><uni-forms wx:if="{{q}}" class="r data-v-4c5e7c86" u-s="{{['d']}}" u-r="formRef" u-i="4c5e7c86-1" bind:__l="__l" u-p="{{q}}"><uni-forms-item wx:if="{{f}}" u-s="{{['d']}}" class="form-item data-v-4c5e7c86" u-i="4c5e7c86-2,4c5e7c86-1" bind:__l="__l" u-p="{{f}}"><view class="card-item data-v-4c5e7c86"><input class="scan-input data-v-4c5e7c86" placeholder="请输入卡号或扫描二维码" value="{{b}}" bindinput="{{c}}"/><image class="scan-img data-v-4c5e7c86" bindtap="{{d}}" src="{{e}}" alt=""></image></view></uni-forms-item><uni-forms-item wx:if="{{i}}" class="data-v-4c5e7c86" u-s="{{['d']}}" u-i="4c5e7c86-3,4c5e7c86-1" bind:__l="__l" u-p="{{i}}"><input class="input-item data-v-4c5e7c86" placeholder="请输入姓名" value="{{g}}" bindinput="{{h}}"/></uni-forms-item><uni-forms-item wx:if="{{l}}" class="data-v-4c5e7c86" u-s="{{['d']}}" u-i="4c5e7c86-4,4c5e7c86-1" bind:__l="__l" u-p="{{l}}"><input class="input-item data-v-4c5e7c86" type="textarea" placeholder="请输入手机号" value="{{j}}" bindinput="{{k}}"/></uni-forms-item><uni-forms-item wx:if="{{o}}" class="data-v-4c5e7c86" u-s="{{['d']}}" u-i="4c5e7c86-5,4c5e7c86-1" bind:__l="__l" u-p="{{o}}"><input class="input-item data-v-4c5e7c86" type="textarea" placeholder="请输入内容" value="{{m}}" bindinput="{{n}}"/></uni-forms-item></uni-forms></view><view class="tips data-v-4c5e7c86"><text class="tips-text data-v-4c5e7c86">1、完成实名认证,方便遗失挂失及补卡等。</text><text class="data-v-4c5e7c86">2、绑卡后,运营商可以看到您实名时填写的姓名和电话。</text></view><view class="subBtn data-v-4c5e7c86" bindtap="{{r}}">提交信息</view></view></view></view>
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/addCard/index.wxss b/unpackage/dist/dev/mp-weixin/pages/addCard/index.wxss
deleted file mode 100644
index 31f0be0..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/addCard/index.wxss
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
-.container.data-v-4c5e7c86 {
-  width: 100%;
-  height: 100vh;
-}
-.container .content.data-v-4c5e7c86 {
-  width: 100%;
-  height: 100vh;
-}
-.container .content .main.data-v-4c5e7c86 {
-  width: 100%;
-  height: calc(100vh - 176rpx);
-  background: linear-gradient(to top, #FFFFFF, #E8EFFF);
-  padding: 0 50rpx 38rpx;
-  box-sizing: border-box;
-}
-.container .content .main .title.data-v-4c5e7c86 {
-  width: 100%;
-  height: 130rpx;
-  text-align: left;
-  line-height: 130rpx;
-}
-.container .content .main .form.data-v-4c5e7c86 {
-  height: 600rpx;
-  width: 100%;
-  background: #FFFFFF;
-  border-radius: 24rpx;
-  padding: 30rpx 50rpx 0;
-  box-sizing: border-box;
-}
-.container .content .main .form .input-item.data-v-4c5e7c86 {
-  line-height: 100%;
-  height: 100%;
-}
-.container .content .main .form .card-item.data-v-4c5e7c86 {
-  display: flex;
-  justify-content: space-around;
-  height: 100%;
-  align-items: center;
-}
-.container .content .main .form .card-item .scan-input.data-v-4c5e7c86 {
-  width: 375rpx;
-  margin-right: 20rpx;
-  line-height: 100%;
-  height: 100%;
-}
-.container .content .main .form .card-item .scan-img.data-v-4c5e7c86 {
-  width: 56rpx;
-  height: 56rpx;
-}
-.container .content .main .tips.data-v-4c5e7c86 {
-  width: 100%;
-  padding: 0 20rpx;
-  box-sizing: border-box;
-  display: flex;
-  justify-content: space-between;
-  align-items: flex-start;
-  flex-direction: column;
-  margin-top: 56rpx;
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #484848;
-}
-.container .content .main .tips .tips-text.data-v-4c5e7c86 {
-  margin-bottom: 28rpx;
-}
-.container .content .main .subBtn.data-v-4c5e7c86 {
-  width: 100%;
-  height: 98rpx;
-  background-color: #5EA1FA;
-  border-radius: 50rpx;
-  font-weight: 300;
-  font-size: 36rpx;
-  color: #FFFFFF;
-  text-align: center;
-  line-height: 98rpx;
-  margin-top: 236rpx;
-  letter-spacing: 2px;
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/address/index.js b/unpackage/dist/dev/mp-weixin/pages/address/index.js
deleted file mode 100644
index bcf1344..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/address/index.js
+++ /dev/null
@@ -1,98 +0,0 @@
-"use strict";
-const common_vendor = require("../../common/vendor.js");
-const common_assets = require("../../common/assets.js");
-const api_index = require("../../api/index.js");
-if (!Array) {
-  const _easycom_navbar2 = common_vendor.resolveComponent("navbar");
-  _easycom_navbar2();
-}
-const _easycom_navbar = () => "../../components/navbar/navbar.js";
-if (!Math) {
-  _easycom_navbar();
-}
-const _sfc_main = {
-  __name: "index",
-  setup(__props) {
-    const addressList = common_vendor.ref([]);
-    async function getAddressList() {
-      await api_index.searchAddress({ limit: 100, page: 1 }).then((res) => {
-        if (res.code == 200) {
-          res.data.list.forEach((item) => {
-            res.data.list.forEach((item2) => {
-              item2.isDefault = item2.isDefault == 1 ? true : false;
-              item2.addressWhole = item2.regionName.replace(/[,#]/g, " ") + item2.address;
-            });
-          });
-          addressList.value = res.data.list;
-        }
-      });
-    }
-    async function setDefault(isDefault, id, index1) {
-      if (isDefault == true) {
-        console.log("true");
-      } else {
-        console.log("false");
-        await api_index.setAddressDefaultApi(id).then((res) => {
-          if (res.code == 200) {
-            getAddressList();
-          } else {
-            common_vendor.index.showToast({
-              title: "设置失败",
-              image: "../../static/images/other/success.svg",
-              duration: 500
-            });
-          }
-        });
-      }
-    }
-    async function deleteAddress(id) {
-      await api_index.deleteAddressApi(id).then((res) => {
-        if (res.code == 200) {
-          common_vendor.index.showToast({
-            title: "删除成功",
-            image: "../../static/images/other/success.svg",
-            duration: 500
-          });
-          getAddressList();
-        }
-      });
-    }
-    function navToModify(id) {
-      common_vendor.index.navigateTo({
-        url: `/pages/addressAdd/index?id=${id}`
-      });
-    }
-    function navToAdd() {
-      let id = "";
-      common_vendor.index.navigateTo({
-        url: `/pages/addressAdd/index?id=${id}`
-      });
-    }
-    common_vendor.onShow(async () => {
-      getAddressList();
-    });
-    return (_ctx, _cache) => {
-      return {
-        a: common_vendor.p({
-          title: "地址管理"
-        }),
-        b: common_vendor.f(addressList.value, (item, index, i0) => {
-          return {
-            a: common_vendor.t(item.userName),
-            b: common_vendor.t(item.userPhone),
-            c: common_vendor.t(item.addressWhole),
-            d: item.id,
-            e: item.isDefault,
-            f: common_vendor.o(($event) => setDefault(item.isDefault, item.id)),
-            g: common_vendor.o(($event) => navToModify(item.id)),
-            h: common_vendor.o(($event) => deleteAddress(item.id))
-          };
-        }),
-        c: common_assets._imports_0$9,
-        d: common_assets._imports_1$4,
-        e: common_vendor.o(($event) => navToAdd())
-      };
-    };
-  }
-};
-wx.createPage(_sfc_main);
diff --git a/unpackage/dist/dev/mp-weixin/pages/address/index.json b/unpackage/dist/dev/mp-weixin/pages/address/index.json
deleted file mode 100644
index ff63ccc..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/address/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "navigationStyle": "custom",
-  "usingComponents": {
-    "navbar": "../../components/navbar/navbar"
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/address/index.wxml b/unpackage/dist/dev/mp-weixin/pages/address/index.wxml
deleted file mode 100644
index 5155251..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/address/index.wxml
+++ /dev/null
@@ -1 +0,0 @@
-<view class="container"><navbar wx:if="{{a}}" u-i="696da406-0" bind:__l="__l" u-p="{{a}}"></navbar><view class="content"><view class="main"><block wx:for="{{b}}" wx:for-item="item"><view class="address-item"><view class="user-info"><text>{{item.a}}</text><text>{{item.b}}</text></view><view class="address-info">{{item.c}}</view><view class="address-divide"></view><view class="handel"><view class="handel-left"><radio color="#4996E3" value="{{item.d}}" checked="{{item.e}}" bindtap="{{item.f}}"></radio><text>设为默认</text></view><view class="handel-right"><view bindtap="{{item.g}}"><image src="{{c}}" alt=""></image><text>编辑</text></view><view bindtap="{{item.h}}"><image src="{{d}}" alt=""></image><text>删除</text></view></view></view></view></block></view><view class="subBtn" bindtap="{{e}}">新增收货地址</view></view></view>
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/address/index.wxss b/unpackage/dist/dev/mp-weixin/pages/address/index.wxss
deleted file mode 100644
index 28d3283..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/address/index.wxss
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
-.container {
-  width: 100%;
-  height: 100vh;
-}
-.container .content {
-  width: 100%;
-  height: calc(100vh - 176rpx - 20rpx);
-  background: linear-gradient(to top, #FFFFFF, #E8EFFF);
-  padding-top: 20rpx;
-}
-.container .content .main {
-  width: 686rpx;
-  height: 1162rpx;
-  margin: 0 auto;
-  overflow-y: scroll;
-}
-.container .content .main .address-item {
-  width: 100%;
-  height: 254rpx;
-  padding: 20rpx 0 26rpx;
-  box-sizing: border-box;
-  margin-bottom: 20rpx;
-  background: #FFFFFF;
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-  align-items: flex-start;
-}
-.container .content .main .address-item .user-info {
-  width: 100%;
-  padding: 0 65rpx;
-  box-sizing: border-box;
-  display: flex;
-  justify-content: space-between;
-  font-weight: 300;
-  font-size: 32rpx;
-  color: #000000;
-}
-.container .content .main .address-item .address-info {
-  padding: 0 65rpx;
-  box-sizing: border-box;
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #646464;
-}
-.container .content .main .address-item .address-divide {
-  width: 100%;
-  height: 1rpx;
-  border-bottom: 2rpx dashed #D5DDE0;
-}
-.container .content .main .address-item .handel {
-  width: 100%;
-  padding: 0 65rpx;
-  box-sizing: border-box;
-  display: flex;
-  justify-content: space-between;
-  align-items: flex-start;
-}
-.container .content .main .address-item .handel .handel-left radio {
-  color: #000000;
-}
-.container .content .main .address-item .handel .handel-left text {
-  font-weight: 300;
-  font-size: 32rpx;
-  color: #0088FF;
-  line-height: 28rpx;
-}
-.container .content .main .address-item .handel .handel-right {
-  width: 35%;
-  height: 48rpx;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.container .content .main .address-item .handel .handel-right view {
-  display: flex;
-  align-items: center;
-}
-.container .content .main .address-item .handel .handel-right view image {
-  width: 28rpx;
-  height: 28rpx;
-  margin-right: 10rpx;
-}
-.container .content .main .address-item .handel .handel-right view text {
-  font-weight: 300;
-  font-size: 24rpx;
-  color: #373737;
-}
-.container .content .subBtn {
-  width: 686rpx;
-  height: 98rpx;
-  padding: 0 26rpx;
-  box-sizing: border-box;
-  background-color: #5EA1FA;
-  border-radius: 50rpx;
-  font-weight: 300;
-  font-size: 36rpx;
-  color: #FFFFFF;
-  line-height: 98rpx;
-  text-align: center;
-  letter-spacing: 2rpx;
-  margin: 100rpx auto 0;
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/index.js b/unpackage/dist/dev/mp-weixin/pages/index/index.js
deleted file mode 100644
index 2376f8f..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/index/index.js
+++ /dev/null
@@ -1,344 +0,0 @@
-"use strict";
-const common_vendor = require("../../common/vendor.js");
-const common_assets = require("../../common/assets.js");
-const config_baseUrl = require("../../config/baseUrl.js");
-const api_index = require("../../api/index.js");
-const _sfc_main = {
-  __name: "index",
-  setup(__props) {
-    const topHeight = common_vendor.ref(0);
-    function getTopHeight() {
-      if (common_vendor.index.getMenuButtonBoundingClientRect) {
-        topHeight.value = common_vendor.index.getMenuButtonBoundingClientRect().top * 2;
-      }
-    }
-    const cardInfo = common_vendor.ref({
-      //用户档案信息
-      id: "",
-      userName: "微信用户",
-      headImg: "",
-      userPhone: "",
-      integral: "",
-      waterCardNumber: "",
-      balance: "",
-      count: "",
-      state: "",
-      //state:true:挂失,false:正常
-      cardType: "",
-      //卡类型01卡消费 02计次消费 03游客消费 04电子卡
-      userCardType: ""
-      //userCardType:true:共享卡,false:正常卡
-    });
-    const isLoss = common_vendor.ref(false);
-    const isVip = common_vendor.ref(false);
-    const isShareCard = common_vendor.ref(false);
-    async function getVipInfo() {
-      await api_index.getVipInfoApi().then((res) => {
-        console.log("会员卡信息响应", res);
-        if (res.code == 200 && res.data.id) {
-          cardInfo.value.waterCardNumber = res.data.cardNumber;
-          cardInfo.value.cardType = res.data.cardType;
-          cardInfo.value.state = res.data.state == 2 ? true : false;
-          cardInfo.value.userCardType = res.data.userCardType == 2 ? true : false;
-          isLoss.value = cardInfo.value.state;
-          isShareCard.value = cardInfo.value.userCardType;
-          if (res.data.cardType == 1) {
-            cardInfo.value.balance = res.data.balance;
-          } else if (res.data.cardType == 2) {
-            cardInfo.value.count = res.data.count;
-          }
-          isVip.value = true;
-          console.log("会员卡及用户信息", cardInfo.value);
-        }
-      });
-    }
-    async function getInfo() {
-      await api_index.getUserInfo().then(async (res) => {
-        console.log("用户信息响应", res);
-        if (res.code == 200) {
-          cardInfo.value.userName = res.data.userInfo.userName ? res.data.userInfo.userName : cardInfo.value.userName;
-          cardInfo.value.headImg = res.data.userInfo.headImg;
-          cardInfo.value.integral = res.data.userInfo.integral;
-          cardInfo.value.userPhone = res.data.userInfo.userPhone;
-          cardInfo.value.id = res.data.userInfo.id;
-          await getVipInfo();
-          console.log("用户信息", cardInfo.value);
-          common_vendor.index.setStorageSync("userInfo", JSON.stringify(cardInfo.value));
-        }
-      });
-    }
-    function toScan() {
-      common_vendor.index.scanCode({
-        scanType: ["qrCode"],
-        success: async function(res) {
-          let code = res.result.split("=")[1];
-          console.log("条码内容:" + res.result, "code", code);
-          common_vendor.index.navigateTo({
-            url: `/pages/scanWater/index?facilityCode=${code}`
-          });
-        }
-      });
-    }
-    const functionList = common_vendor.ref([
-      //isUrl:1:页面跳转,2:弹窗功能,3:弹窗功能,4:未开发
-      { text: "余额记录", icon: "../../static/images/index/icon31.png", url: "/pages/functionList/balanceRecord/index", isUrl: 1 },
-      { text: "消费记录", icon: "../../static/images/index/icon32.png", url: "/pages/functionList/paymentRecord/index", isUrl: 1 },
-      { text: "充值记录", icon: "../../static/images/index/icon33.png", url: "/pages/functionList/rechargeRecord/index", isUrl: 1 },
-      { text: "水卡共享", icon: "../../static/images/index/icon34.png", url: "/pages/functionList/share/cardShare/index", isUrl: 1 },
-      { text: "故障上报", icon: "../../static/images/index/icon35.png", url: "/pages/infoBreakdown/index", isUrl: 1 },
-      { text: "优惠卷", icon: "../../static/images/index/icon36.png", url: "", isUrl: 4 },
-      { text: "卡挂失", icon: "../../static/images/index/icon37.png", url: "", isUrl: 2 },
-      { text: "卡解绑", icon: "../../static/images/index/icon38.png", url: "", isUrl: 3 }
-    ]);
-    function navTo(itemUrl) {
-      if (itemUrl) {
-        common_vendor.index.navigateTo({
-          url: itemUrl
-        });
-      }
-    }
-    async function setEvent(isUrl, url) {
-      if (isUrl == 1) {
-        navTo(url);
-      } else if (isUrl == 2) {
-        if (cardInfo.value.waterCardNumber) {
-          if (!isShareCard.value && !cardInfo.value.state) {
-            common_vendor.index.showModal({
-              title: "会员卡挂失",
-              content: "确认挂失会员卡?",
-              success: async function(res) {
-                if (res.confirm) {
-                  await api_index.reportLossApi(cardInfo.value.waterCardNumber).then(async (res2) => {
-                    if (res2.code == 200) {
-                      common_vendor.index.showToast({
-                        title: "已挂失",
-                        duration: 2e3
-                      });
-                      await api_index.getVipInfoApi().then((res3) => {
-                        if (res3.code == 200) {
-                          if (res3.data.state == 2) {
-                            isLoss.value = true;
-                          }
-                        }
-                      });
-                    }
-                  });
-                }
-              }
-            });
-          } else if (isShareCard.value) {
-            common_vendor.index.showToast({
-              title: "共享卡无权限",
-              icon: "none"
-            });
-          } else if (cardInfo.value.state) {
-            common_vendor.index.showToast({
-              title: "已挂失",
-              icon: "none"
-            });
-          }
-        } else {
-          common_vendor.index.showToast({
-            title: "未绑定会员卡!",
-            icon: "none"
-          });
-        }
-      } else if (isUrl == 3) {
-        if (cardInfo.value.waterCardNumber) {
-          if (!isShareCard.value) {
-            common_vendor.index.showModal({
-              title: "会员卡注销",
-              content: "确认注销会员卡?",
-              success: async function(res) {
-                if (res.confirm) {
-                  await api_index.removeBindingApi(cardInfo.value.waterCardNumber).then(async (res2) => {
-                    if (res2.code == 200) {
-                      common_vendor.index.showToast({
-                        title: "已注销",
-                        duration: 2e3,
-                        icon: "none"
-                      });
-                      await api_index.getVipInfoApi().then((res3) => {
-                        if (res3.code == 200) {
-                          if (!res3.data.id) {
-                            isVip.value = false;
-                            cardInfo.value.balance = "";
-                            cardInfo.value.count = "";
-                            cardInfo.value.waterCardNumber = "";
-                            common_vendor.index.setStorageSync("userInfo", JSON.stringify(cardInfo.value));
-                          }
-                        }
-                      });
-                    }
-                  });
-                }
-              }
-            });
-          } else {
-            common_vendor.index.showToast({
-              title: "共享卡无权限",
-              icon: "none"
-            });
-          }
-        } else {
-          common_vendor.index.showToast({
-            title: "未绑定会员卡!",
-            icon: "none"
-          });
-        }
-      } else {
-        upGrade();
-      }
-    }
-    function upGrade() {
-      common_vendor.index.showToast({
-        title: "该功能正在升级中!",
-        duration: 1e3,
-        icon: "none"
-      });
-    }
-    let userLocation = {
-      lat: "",
-      lon: ""
-    };
-    function getUserLocation() {
-      common_vendor.index.authorize({
-        scope: "scope.userLocation",
-        success() {
-          console.log("成功授权位置信息1");
-          storageLocation();
-        },
-        fail() {
-          console.log("用户拒绝授权位置信息,再次提示用户授权");
-          showToast();
-        }
-      });
-      function storageLocation() {
-        common_vendor.index.getLocation({
-          type: "gcj02",
-          isHighAccuracy: true,
-          success: (res) => {
-            userLocation.lat = res.latitude;
-            userLocation.lon = res.longitude;
-            common_vendor.index.setStorageSync("userLocation", JSON.stringify(userLocation));
-          },
-          fail: () => {
-            showToast();
-          }
-        });
-      }
-      function showToast() {
-        common_vendor.index.showModal({
-          title: "请求授权当前位置",
-          content: "请求获取您的位置,加载附近饮水设备信息!",
-          confirmText: "前往设置",
-          success: (res) => {
-            if (res.confirm) {
-              common_vendor.index.openSetting({
-                success: (res1) => {
-                  if (res1.authSetting["scope.userLocation"]) {
-                    console.log("用户二次授权成功");
-                    setTimeout(() => {
-                      storageLocation();
-                    }, 1e3);
-                  } else {
-                    showToast();
-                    console.log("用户拒绝授权");
-                  }
-                }
-              });
-            } else {
-              common_vendor.index.showToast({
-                title: "请先授权!",
-                duration: 2e3,
-                icon: "none"
-              });
-              showToast();
-            }
-          }
-        });
-      }
-    }
-    common_vendor.onMounted(async () => {
-      console.log("空用户信息", cardInfo.value);
-      common_vendor.index.setStorageSync("userInfo", JSON.stringify(cardInfo.value));
-      getTopHeight();
-      await getInfo();
-      await getUserLocation();
-      console.log("onMounted", "用户存储本地数据", JSON.parse(common_vendor.index.getStorageSync("userInfo")));
-    });
-    common_vendor.onShow(async () => {
-      getTopHeight();
-      await getInfo();
-      console.log("onShow", "用户存储本地数据", JSON.parse(common_vendor.index.getStorageSync("userInfo")));
-    });
-    common_vendor.index.showShareMenu({
-      withShareTicket: true,
-      menus: ["shareAppMessage", "shareTimeline"],
-      success: function() {
-      },
-      fail: function(err) {
-      }
-    });
-    return (_ctx, _cache) => {
-      return common_vendor.e({
-        a: cardInfo.value.headImg
-      }, cardInfo.value.headImg ? {
-        b: common_vendor.unref(config_baseUrl.BASE_URL) + "/upload" + cardInfo.value.headImg
-      } : {
-        c: common_assets._imports_0$4
-      }, {
-        d: common_vendor.t(cardInfo.value.userName),
-        e: common_vendor.o(($event) => navTo("/pages/userInfo/index")),
-        f: common_vendor.o(($event) => navTo("/pages/userInfo/index")),
-        g: common_assets._imports_1$2,
-        h: common_assets._imports_0$3,
-        i: isVip.value
-      }, isVip.value ? common_vendor.e({
-        j: isShareCard.value
-      }, isShareCard.value ? common_vendor.e({
-        k: isLoss.value
-      }, isLoss.value ? {} : {}) : {}, {
-        l: !isShareCard.value
-      }, !isShareCard.value ? common_vendor.e({
-        m: isLoss.value
-      }, isLoss.value ? {} : {}) : {}, {
-        n: common_vendor.t(cardInfo.value.waterCardNumber),
-        o: common_vendor.t(cardInfo.value.balance),
-        p: !isShareCard.value
-      }, !isShareCard.value ? {
-        q: common_vendor.o(($event) => navTo("/pages/recharge/index"))
-      } : {}) : {}, {
-        r: !isVip.value
-      }, !isVip.value ? {
-        s: common_vendor.o(($event) => navTo("/pages/addCard/index"))
-      } : {}, {
-        t: topHeight.value + "rpx",
-        v: common_assets._imports_3$1,
-        w: common_vendor.o(upGrade),
-        x: common_assets._imports_1$1,
-        y: common_vendor.o(($event) => navTo("/pages/facilityList/index")),
-        z: common_assets._imports_5,
-        A: common_vendor.o(($event) => toScan()),
-        B: common_vendor.f(functionList.value, (item, index, i0) => {
-          return {
-            a: item.icon,
-            b: common_vendor.t(item.text),
-            c: common_vendor.o(($event) => setEvent(item.isUrl, item.url), index),
-            d: index
-          };
-        }),
-        C: common_assets._imports_6,
-        D: common_vendor.o(($event) => navTo("/pagesPoints/pointsMall/index")),
-        E: common_assets._imports_7,
-        F: common_assets._imports_8,
-        G: common_vendor.o(($event) => navTo("/pages/station/index")),
-        H: common_assets._imports_9,
-        I: common_assets._imports_8,
-        J: common_vendor.o(upGrade)
-      });
-    };
-  }
-};
-const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-1cf27b2a"]]);
-wx.createPage(MiniProgramPage);
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/index.json b/unpackage/dist/dev/mp-weixin/pages/index/index.json
deleted file mode 100644
index ced5b27..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/index/index.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "navigationStyle": "custom",
-  "usingComponents": {}
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/index.wxml b/unpackage/dist/dev/mp-weixin/pages/index/index.wxml
deleted file mode 100644
index 4282251..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/index/index.wxml
+++ /dev/null
@@ -1 +0,0 @@
-<view class="container data-v-1cf27b2a"><view class="content data-v-1cf27b2a"><view class="card-box data-v-1cf27b2a" style="{{'padding-top:' + t}}"><view class="user-info data-v-1cf27b2a"><image wx:if="{{a}}" class="user-img data-v-1cf27b2a" src="{{b}}" alt=""></image><image wx:else class="user-img data-v-1cf27b2a" src="{{c}}" alt=""></image><text class="data-v-1cf27b2a" bindtap="{{e}}">{{d}}</text><image bindtap="{{f}}" class="user-more data-v-1cf27b2a" src="{{g}}"></image></view><view class="card data-v-1cf27b2a"><image class="card-bg data-v-1cf27b2a" src="{{h}}" alt=""></image><view wx:if="{{i}}" class="card-detail data-v-1cf27b2a"><view class="card-top data-v-1cf27b2a"><view class="vip data-v-1cf27b2a">VIP</view><view class="top-right data-v-1cf27b2a"><view wx:if="{{j}}" class="card-name data-v-1cf27b2a"><text class="data-v-1cf27b2a">共享卡</text><text wx:if="{{k}}" class="data-v-1cf27b2a">[已挂失]</text></view><view wx:if="{{l}}" class="card-name data-v-1cf27b2a"><text class="data-v-1cf27b2a">会员卡</text><text wx:if="{{m}}" class="card-loss data-v-1cf27b2a">[已挂失]</text></view><view class="card-num data-v-1cf27b2a"> 卡号:{{n}}</view></view></view><view class="card-bottom data-v-1cf27b2a"><view class="bottom-left data-v-1cf27b2a"><text class="bottom-left-text data-v-1cf27b2a">余额:</text><text class="bottom-left-money data-v-1cf27b2a">{{o}}</text></view><view wx:if="{{p}}" bindtap="{{q}}" class="card-btn data-v-1cf27b2a">充值</view></view></view><view wx:if="{{r}}" class="card-none data-v-1cf27b2a"><view class="card-none-top data-v-1cf27b2a"><text class="data-v-1cf27b2a">未绑定会员卡</text></view><view class="card-none-bottom data-v-1cf27b2a"><view bindtap="{{s}}" class="card-btn data-v-1cf27b2a">去绑定</view></view></view></view></view><view class="function-box1 data-v-1cf27b2a"><view class="box1-bg box1-one data-v-1cf27b2a" bindtap="{{w}}"><image class="box-one-image1 data-v-1cf27b2a" src="{{v}}" alt=""></image><view class="data-v-1cf27b2a">送水到家</view></view><view bindtap="{{y}}" class="box1-bg box1-two data-v-1cf27b2a"><image class="box-one-image2 data-v-1cf27b2a" src="{{x}}" alt=""></image><view class="data-v-1cf27b2a">附近设备</view></view></view><view class="scan-box data-v-1cf27b2a"><view class="scan data-v-1cf27b2a" bindtap="{{A}}"><image class="scan-img data-v-1cf27b2a" src="{{z}}"></image><view class="data-v-1cf27b2a">扫码取水</view></view></view><view class="function-box2 data-v-1cf27b2a"><view class="box2-title data-v-1cf27b2a"><text class="data-v-1cf27b2a">功能列表</text></view><view class="box2-content data-v-1cf27b2a"><block wx:for="{{B}}" wx:for-item="item" wx:key="d"><view class="box2-item data-v-1cf27b2a" bindtap="{{item.c}}"><view class="box2-item-img data-v-1cf27b2a"><image class="box2-image data-v-1cf27b2a" src="{{item.a}}" alt=""></image></view><view class="box2-item-text data-v-1cf27b2a">{{item.b}}</view></view></block></view></view><view class="advertisement-box data-v-1cf27b2a" bindtap="{{D}}"><image class="banner-img data-v-1cf27b2a" src="{{C}}"></image></view><view class="service-box data-v-1cf27b2a"><view class="service-title data-v-1cf27b2a"><text class="data-v-1cf27b2a">服务指南</text></view><view class="service-content data-v-1cf27b2a"><view class="service-bg data-v-1cf27b2a" bindtap="{{G}}"><view class="data-v-1cf27b2a"><image class="data-v-1cf27b2a" src="{{E}}" alt=""></image><text class="data-v-1cf27b2a">附近站点</text></view><view class="service-info data-v-1cf27b2a">服务中心正在营业中……</view><view class="data-v-1cf27b2a"><text class="data-v-1cf27b2a">查看更多</text><image class="data-v-1cf27b2a" src="{{F}}" alt=""></image></view></view><view class="service-bg data-v-1cf27b2a" bindtap="{{J}}"><view class="data-v-1cf27b2a"><image class="data-v-1cf27b2a" src="{{H}}" alt=""></image><text class="data-v-1cf27b2a">公示公告</text></view><view class="service-info data-v-1cf27b2a">停水公告的部分摘要的内容展示……</view><view class="data-v-1cf27b2a"><text class="data-v-1cf27b2a">查看更多</text><image class="data-v-1cf27b2a" src="{{I}}" alt=""></image></view></view></view></view></view></view>
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/index.wxss b/unpackage/dist/dev/mp-weixin/pages/index/index.wxss
deleted file mode 100644
index f993546..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/index/index.wxss
+++ /dev/null
@@ -1,467 +0,0 @@
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
-.container.data-v-1cf27b2a {
-  width: 100%;
-}
-.container .content.data-v-1cf27b2a {
-  width: 100%;
-  background: #F6F6F6;
-  overflow: scroll;
-}
-.container .content .card-box.data-v-1cf27b2a {
-  width: 100%;
-  height: auto;
-  box-sizing: border-box;
-  padding: 0 32rpx;
-  background: linear-gradient(to bottom, #5EA1FA, #D2F2FE);
-}
-.container .content .card-box .user-info.data-v-1cf27b2a {
-  width: 100%;
-  height: 100rpx;
-  align-items: center;
-  padding-left: 15rpx;
-  box-sizing: border-box;
-  margin-bottom: 14rpx;
-  display: flex;
-}
-.container .content .card-box .user-info .user-img.data-v-1cf27b2a {
-  width: 90rpx;
-  height: 90rpx;
-  border-radius: 50%;
-  margin-right: 20rpx;
-}
-.container .content .card-box .user-info text.data-v-1cf27b2a {
-  margin-right: 20rpx;
-  color: #fff;
-}
-.container .content .card-box .user-info .user-more.data-v-1cf27b2a {
-  width: 12rpx;
-  height: 28rpx;
-}
-.container .content .card-box .card.data-v-1cf27b2a {
-  width: 100%;
-  height: 256rpx;
-  position: relative;
-}
-.container .content .card-box .card .card-bg.data-v-1cf27b2a {
-  height: 256rpx;
-  width: 100%;
-  top: 0;
-  position: absolute;
-  z-index: 1;
-}
-.container .content .card-box .card .card-none.data-v-1cf27b2a {
-  width: 100%;
-  height: 100%;
-  padding: 38rpx;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-  justify-content: space-around;
-  color: #fff;
-  z-index: 2;
-}
-.container .content .card-box .card .card-none .card-none-top.data-v-1cf27b2a {
-  font-size: 40rpx;
-  font-weight: 600;
-  z-index: 2;
-  letter-spacing: 2rpx;
-}
-.container .content .card-box .card .card-none .card-none-bottom.data-v-1cf27b2a {
-  display: flex;
-  justify-content: flex-end;
-  z-index: 2;
-}
-.container .content .card-box .card .card-none .card-none-bottom .card-btn.data-v-1cf27b2a {
-  width: 196rpx;
-  height: 80rpx;
-  background: linear-gradient(to right, #338AFD 0%, #65A7FD 100%);
-  border-radius: 40rpx;
-  text-align: center;
-  line-height: 80rpx;
-  font-size: 44rpx;
-  letter-spacing: 3rpx;
-  font-weight: 500;
-}
-.container .content .card-box .card .card-detail.data-v-1cf27b2a {
-  width: 100%;
-  height: 100%;
-  padding: 38rpx;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  color: #fff;
-  z-index: 2;
-}
-.container .content .card-box .card .card-detail .card-top.data-v-1cf27b2a {
-  width: 100%;
-  display: flex;
-  align-items: center;
-  z-index: 2;
-}
-.container .content .card-box .card .card-detail .card-top .vip.data-v-1cf27b2a {
-  font-size: 114rpx;
-  font-weight: 600;
-}
-.container .content .card-box .card .card-detail .card-top .top-right.data-v-1cf27b2a {
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  margin-left: 20rpx;
-}
-.container .content .card-box .card .card-detail .card-top .top-right .card-name.data-v-1cf27b2a {
-  font-size: 40rpx;
-  font-weight: 400;
-}
-.container .content .card-box .card .card-detail .card-top .top-right .card-name .card-loss.data-v-1cf27b2a {
-  font-size: 34rpx;
-  font-weight: 600;
-  margin-left: 10rpx;
-  letter-spacing: 2rpx;
-  color: #333434;
-}
-.container .content .card-box .card .card-detail .card-top .top-right .card-num.data-v-1cf27b2a {
-  font-size: 34rpx;
-  font-weight: 400;
-}
-.container .content .card-box .card .card-detail .card-bottom.data-v-1cf27b2a {
-  width: 100%;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  z-index: 2;
-}
-.container .content .card-box .card .card-detail .card-bottom .bottom-left.data-v-1cf27b2a {
-  display: flex;
-  align-items: center;
-}
-.container .content .card-box .card .card-detail .card-bottom .bottom-left .bottom-left-text.data-v-1cf27b2a {
-  font-size: 40rpx;
-  font-weight: 400;
-  letter-spacing: 2rpx;
-}
-.container .content .card-box .card .card-detail .card-bottom .bottom-left .bottom-left-money.data-v-1cf27b2a {
-  font-size: 60rpx;
-  font-weight: 600;
-}
-.container .content .card-box .card .card-detail .card-bottom .card-btn.data-v-1cf27b2a {
-  width: 196rpx;
-  height: 80rpx;
-  background: linear-gradient(270deg, #65B5FD 0%, #338AFD 100%, #65A7FD 100%);
-  border-radius: 40rpx;
-  text-align: center;
-  line-height: 80rpx;
-  font-size: 48rpx;
-  letter-spacing: 6rpx;
-}
-.container .content .function-box1.data-v-1cf27b2a {
-  width: 100%;
-  box-sizing: border-box;
-  height: 172rpx;
-  padding: 20rpx 32rpx 22rpx;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  font-size: 36rpx;
-  font-weight: 500;
-  color: #4d4d4d;
-  letter-spacing: 2rpx;
-}
-.container .content .function-box1 .box1-bg.data-v-1cf27b2a {
-  width: 326rpx;
-  height: 130rpx;
-  border-radius: 24rpx;
-  background: #fff;
-  box-shadow: 0 0 12rpx 3rpx rgba(13, 118, 255, 0.16);
-}
-.container .content .function-box1 .box1-one.data-v-1cf27b2a {
-  text-align: center;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  justify-content: space-evenly;
-}
-.container .content .function-box1 .box1-one .box-one-image1.data-v-1cf27b2a {
-  width: 86rpx;
-  height: 86rpx;
-}
-.container .content .function-box1 .box1-two.data-v-1cf27b2a {
-  display: flex;
-  align-items: center;
-  justify-content: space-evenly;
-}
-.container .content .function-box1 .box1-two .box-one-image2.data-v-1cf27b2a {
-  width: 96rpx;
-  height: 96rpx;
-}
-.container .content .function-box1 .box1-three.data-v-1cf27b2a {
-  font-weight: 300;
-  font-size: 32rpx;
-  color: #000000;
-  text-align: center;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-}
-.container .content .function-box1 .box1-three image.data-v-1cf27b2a {
-  width: 83rpx;
-  height: 83rpx;
-  margin-bottom: 20rpx;
-}
-.container .content .scan-box.data-v-1cf27b2a {
-  width: 100%;
-  height: 116rpx;
-  padding: 0 42rpx 16rpx;
-  box-sizing: border-box;
-}
-.container .content .scan-box .scan.data-v-1cf27b2a {
-  width: 100%;
-  height: 100rpx;
-  background: #1678FF;
-  border-radius: 178rpx;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  color: #fff;
-  font-size: 44rpx;
-  font-weight: 500;
-  letter-spacing: 1rpx;
-}
-.container .content .scan-box .scan .scan-img.data-v-1cf27b2a {
-  width: 44rpx;
-  height: 44rpx;
-  margin-right: 20rpx;
-}
-.container .content .function-box2.data-v-1cf27b2a {
-  width: 100%;
-  box-sizing: border-box;
-  height: 420rpx;
-  padding: 0 32rpx 0;
-}
-.container .content .function-box2 .box2-title.data-v-1cf27b2a {
-  width: 100%;
-  font-weight: 300;
-  font-size: 32rpx;
-  color: #000000;
-  text-align: left;
-  margin-bottom: 10rpx;
-  margin-left: 30rpx;
-}
-.container .content .function-box2 .box2-content.data-v-1cf27b2a {
-  box-sizing: border-box;
-  padding: 22rpx 35rpx;
-  width: 686rpx;
-  height: 360rpx;
-  background: #fff;
-  border-radius: 24rpx;
-  box-shadow: 0 0 12rpx 2rpx rgba(0, 0, 0, 0.1);
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: space-between;
-  align-items: center;
-}
-.container .content .function-box2 .box2-content .box2-item.data-v-1cf27b2a {
-  width: 146rpx;
-  height: 143rpx;
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-  align-items: center;
-}
-.container .content .function-box2 .box2-content .box2-item .box2-item-img.data-v-1cf27b2a {
-  width: 100rpx;
-  height: 100rpx;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  background: #5EA1FA;
-  border-radius: 50%;
-}
-.container .content .function-box2 .box2-content .box2-item .box2-item-img .box2-image.data-v-1cf27b2a {
-  width: 48rpx;
-  height: 48rpx;
-}
-.container .content .function-box2 .box2-content .box2-item .box2-item-text.data-v-1cf27b2a {
-  width: 100%;
-  height: 40rpx;
-  font-weight: 300;
-  font-size: 30rpx;
-  color: #3e3e3e;
-  text-align: center;
-  font-weight: 600;
-}
-.container .content .advertisement-box.data-v-1cf27b2a {
-  width: 100%;
-  height: 188rpx;
-  padding: 0 32rpx 10rpx;
-  box-sizing: border-box;
-  display: flex;
-  justify-content: center;
-}
-.container .content .advertisement-box .banner-img.data-v-1cf27b2a {
-  width: 686rpx;
-  height: 178rpx;
-}
-.container .content .service-box.data-v-1cf27b2a {
-  width: 100%;
-  height: 255rpx;
-  padding: 0 32rpx;
-  box-sizing: border-box;
-}
-.container .content .service-box .service-title.data-v-1cf27b2a {
-  height: 44rpx;
-  font-weight: 300;
-  font-size: 32rpx;
-  color: #000000;
-  text-align: left;
-  margin-bottom: 5rpx;
-  margin-left: 30rpx;
-}
-.container .content .service-box .service-content.data-v-1cf27b2a {
-  width: 100%;
-  height: 206rpx;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.container .content .service-box .service-content .service-bg.data-v-1cf27b2a {
-  width: 330rpx;
-  height: 206rpx;
-  background: linear-gradient(to bottom, #AFD5FF, #FFFFFF);
-  border-radius: 24rpx;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  align-items: flex-start;
-}
-.container .content .service-box .service-content .service-bg view.data-v-1cf27b2a:first-child {
-  display: flex;
-  align-items: center;
-  margin-left: 40rpx;
-}
-.container .content .service-box .service-content .service-bg view:first-child image.data-v-1cf27b2a {
-  width: 48rpx;
-  height: 48rpx;
-  margin-right: 10rpx;
-}
-.container .content .service-box .service-content .service-bg view:first-child text.data-v-1cf27b2a {
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #000000;
-}
-.container .content .service-box .service-content .service-bg .service-info.data-v-1cf27b2a {
-  width: 214rpx;
-  font-weight: 300;
-  font-size: 24rpx;
-  color: #4D4B4B;
-  margin-left: 96rpx;
-}
-.container .content .service-box .service-content .service-bg view.data-v-1cf27b2a:last-child {
-  margin-left: 174rpx;
-  margin-top: 18rpx;
-  display: flex;
-  align-items: center;
-}
-.container .content .service-box .service-content .service-bg view:last-child image.data-v-1cf27b2a {
-  width: 32rpx;
-  height: 32rpx;
-}
-.container .content .service-box .service-content .service-bg view:last-child text.data-v-1cf27b2a {
-  font-weight: 300;
-  font-size: 24rpx;
-  color: #4D4B4B;
-  margin-right: 10rpx;
-}
-.container .popup-content.data-v-1cf27b2a {
-  height: 560rpx;
-  position: relative;
-  z-index: 1000;
-}
-.container .popup-content .popup-title.data-v-1cf27b2a {
-  width: 100%;
-  display: block;
-  text-align: center;
-  margin: 15rpx 0;
-  font-weight: 600;
-  font-size: 36rpx;
-}
-.container .popup-content .hr.data-v-1cf27b2a {
-  width: 100%;
-  height: 2rpx;
-  background: #e2e2e2;
-}
-.container .popup-content .img-box.data-v-1cf27b2a {
-  width: 65rpx;
-  height: 65rpx;
-  margin: 40rpx auto 30rpx;
-  border: 1rpx solid #e2e2e2;
-  border-radius: 50%;
-  padding: 15rpx;
-}
-.container .popup-content .img-box .img.data-v-1cf27b2a {
-  width: 100%;
-  height: 100%;
-}
-.container .popup-content .info-box.data-v-1cf27b2a {
-  width: 100%;
-  padding: 0 80rpx;
-  box-sizing: border-box;
-}
-.container .popup-content .info-box .hr2.data-v-1cf27b2a {
-  width: 100%;
-  height: 2rpx;
-  background: #e2e2e2;
-  margin: 20rpx 0;
-}
-.container .popup-content .info-box .info-text2.data-v-1cf27b2a {
-  font-size: 26rpx;
-  color: #767676;
-}
-.container .popup-content .button-box.data-v-1cf27b2a {
-  display: flex;
-  margin-top: 20rpx;
-}
-.container .popup-content .button-box button.data-v-1cf27b2a {
-  width: 230rpx;
-  height: 80rpx;
-  line-height: 80rpx;
-  border: none;
-  box-shadow: none;
-  margin-top: 30rpx;
-}
-.container .popup-content .button-box button.data-v-1cf27b2a::after {
-  border: none !important;
-}
-.container .popup-content .button-box .button1.data-v-1cf27b2a {
-  background-color: #F0F0F0;
-  color: #333333;
-}
-.container .popup-content .button-box .button2.data-v-1cf27b2a {
-  background-color: #06BF5E;
-  color: #ffffff;
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.js b/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.js
deleted file mode 100644
index 8681c24..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
-"use strict";
-const common_vendor = require("../../common/vendor.js");
-if (!Array) {
-  const _easycom_navbar2 = common_vendor.resolveComponent("navbar");
-  _easycom_navbar2();
-}
-const _easycom_navbar = () => "../../components/navbar/navbar.js";
-if (!Math) {
-  _easycom_navbar();
-}
-const _sfc_main = {
-  __name: "index",
-  setup(__props) {
-    function navTo() {
-      common_vendor.index.navigateTo({
-        url: "/pages/address/index"
-      });
-    }
-    return (_ctx, _cache) => {
-      return {
-        a: common_vendor.p({
-          title: "预约下单"
-        }),
-        b: common_vendor.o(($event) => navTo())
-      };
-    };
-  }
-};
-wx.createPage(_sfc_main);
diff --git a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.json b/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.json
deleted file mode 100644
index ff63ccc..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "navigationStyle": "custom",
-  "usingComponents": {
-    "navbar": "../../components/navbar/navbar"
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.wxml b/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.wxml
deleted file mode 100644
index be6bd2f..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.wxml
+++ /dev/null
@@ -1 +0,0 @@
-<view class="container"><navbar wx:if="{{a}}" u-i="0c68eff9-0" bind:__l="__l" u-p="{{a}}"></navbar><view class="content"><view class="add-address" bindtap="{{b}}">地址管理</view></view></view>
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.wxss b/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.wxss
deleted file mode 100644
index cd077c9..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/preSendWater/index.wxss
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
-.container {
-  width: 100%;
-  height: 100vh;
-}
-.container .content {
-  width: 100%;
-  height: calc(100vh - 176rpx);
-  background: linear-gradient(to top, #FFFFFF, #E8EFFF);
-}
-.container .content .add-address {
-  width: 100%;
-  padding-right: 32rpx;
-  box-sizing: border-box;
-  height: 94rpx;
-  line-height: 60rpx;
-  font-size: 26rpx;
-  font-weight: 600;
-  color: #5EA1FA;
-  display: flex;
-  justify-content: flex-end;
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/recharge/index.js b/unpackage/dist/dev/mp-weixin/pages/recharge/index.js
deleted file mode 100644
index 7b00dc2..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/recharge/index.js
+++ /dev/null
@@ -1,167 +0,0 @@
-"use strict";
-const common_vendor = require("../../common/vendor.js");
-const api_index = require("../../api/index.js");
-if (!Array) {
-  const _easycom_navbar2 = common_vendor.resolveComponent("navbar");
-  _easycom_navbar2();
-}
-const _easycom_navbar = () => "../../components/navbar/navbar.js";
-if (!Math) {
-  _easycom_navbar();
-}
-const _sfc_main = {
-  __name: "index",
-  setup(__props) {
-    const choosedMoney = common_vendor.ref(50);
-    const disabled = common_vendor.ref(true);
-    const userInfo = JSON.parse(common_vendor.index.getStorageSync("userInfo"));
-    const moneyList = common_vendor.ref([
-      { value: 50, active: true },
-      { value: 100, active: false },
-      { value: 200, active: false },
-      { value: 500, active: false },
-      { value: 1e3, active: false },
-      { value: "其他金额", active: false }
-    ]);
-    const activeStyle = common_vendor.ref({
-      backgroundColor: "#5EADFF",
-      color: "#fff"
-    });
-    function chooseMoney(index1) {
-      moneyList.value.forEach((item, index) => {
-        if (item.active == true) {
-          item.active = false;
-        }
-      });
-      moneyList.value[index1].active = true;
-      if (index1 == 5) {
-        disabled.value = false;
-        choosedMoney.value = "";
-      } else {
-        choosedMoney.value = moneyList.value[index1].value;
-        otherMoney.value = "";
-        disabled.value = true;
-      }
-    }
-    const otherMoney = common_vendor.ref();
-    common_vendor.ref();
-    const payList = common_vendor.ref([
-      // {text:"支付宝支付",value:1,checked:true,img:'../../static/images/recharge/pay.png'},
-      { text: "微信支付", value: 2, checked: true, img: "../../static/images/recharge/wx.png" }
-      // {text:"余额",value:3,checked:false,img:'../../static/images/recharge/balance.png'},
-    ]);
-    let timerId;
-    let payStatus = common_vendor.ref(true);
-    async function submit() {
-      if (payStatus.value) {
-        payStatus.value = false;
-        timerId = setTimeout(() => {
-          payStatus.value = true;
-        }, 2e4);
-        let money = "";
-        if (disabled.value) {
-          money = choosedMoney.value;
-        } else {
-          money = Number(otherMoney.value);
-        }
-        let data = {
-          cardNumber: userInfo.waterCardNumber,
-          paymentMethod: 1,
-          rechargeAmount: money
-        };
-        await api_index.rechargeApi(data).then(async (res) => {
-          if (res.code == 200) {
-            let data2 = {
-              businessType: 1,
-              businessNo: res.data
-            };
-            await wxPay(data2);
-            otherMoney.value = "";
-          }
-        });
-      } else {
-        common_vendor.index.showToast({
-          title: "充值间隔20秒,请稍后!",
-          icon: "none"
-        });
-      }
-    }
-    async function wxPay(data) {
-      await api_index.wxPayApi(data).then((res) => {
-        if (res.code == 200) {
-          common_vendor.wx$1.requestPayment({
-            //预支付订单信息
-            // appId: res.data.appId,
-            timeStamp: res.data.timeStamp,
-            //时间戳 
-            nonceStr: res.data.nonceStr,
-            //随机串     
-            package: res.data.package,
-            //prepay_id
-            signType: res.data.signType,
-            //签名算法MD5		
-            paySign: res.data.paySign,
-            //微信签名 
-            success(res2) {
-              if (res2.errMsg == "requestPayment:ok") {
-                console.log("支付成功", res2);
-                common_vendor.index.showToast({
-                  title: "支付成功",
-                  duration: 2e3
-                });
-                common_vendor.index.navigateBack();
-              } else {
-                common_vendor.index.showToast({
-                  title: "支付失败",
-                  duration: 2e3,
-                  icon: "none"
-                });
-              }
-            },
-            fail(res2) {
-              common_vendor.index.showToast({
-                title: "微信支付失败",
-                duration: 2e3,
-                icon: "none"
-              });
-            }
-          });
-        }
-      });
-    }
-    common_vendor.onUnmounted(() => {
-      clearTimeout(timerId);
-    });
-    return (_ctx, _cache) => {
-      return {
-        a: common_vendor.p({
-          title: "账户充值"
-        }),
-        b: common_vendor.f(moneyList.value, (item, index, i0) => {
-          return {
-            a: common_vendor.t(item.value),
-            b: common_vendor.s(item.active ? activeStyle.value : ""),
-            c: common_vendor.o(($event) => chooseMoney(index), index),
-            d: index
-          };
-        }),
-        c: disabled.value,
-        d: !disabled.value,
-        e: otherMoney.value,
-        f: common_vendor.o(($event) => otherMoney.value = $event.detail.value),
-        g: common_vendor.f(payList.value, (item, index, i0) => {
-          return {
-            a: item.img,
-            b: common_vendor.t(item.text),
-            c: item.value,
-            d: item.checked
-          };
-        }),
-        h: common_vendor.unref(payStatus) ? 1 : 0.7,
-        i: common_vendor.o(($event) => submit())
-      };
-    };
-  }
-};
-const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-f06186df"]]);
-wx.createPage(MiniProgramPage);
diff --git a/unpackage/dist/dev/mp-weixin/pages/recharge/index.json b/unpackage/dist/dev/mp-weixin/pages/recharge/index.json
deleted file mode 100644
index ff63ccc..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/recharge/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "navigationStyle": "custom",
-  "usingComponents": {
-    "navbar": "../../components/navbar/navbar"
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/recharge/index.wxml b/unpackage/dist/dev/mp-weixin/pages/recharge/index.wxml
deleted file mode 100644
index 9584a67..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/recharge/index.wxml
+++ /dev/null
@@ -1 +0,0 @@
-<view class="container data-v-f06186df"><navbar wx:if="{{a}}" class="data-v-f06186df" u-i="f06186df-0" bind:__l="__l" u-p="{{a}}"></navbar><view class="content data-v-f06186df"><view class="main data-v-f06186df"><view class="money data-v-f06186df"><view class="money-title data-v-f06186df"><view class="title-icon data-v-f06186df"></view><view class="title-text data-v-f06186df">充值金额</view></view><view class="money-list data-v-f06186df"><block wx:for="{{b}}" wx:for-item="item" wx:key="d"><view class="money-box data-v-f06186df" style="{{item.b}}" bindtap="{{item.c}}">¥{{item.a}}</view></block></view></view><view class="other-money data-v-f06186df"><view class="money-title data-v-f06186df"><view class="title-icon data-v-f06186df"></view><view class="title-text data-v-f06186df">其他金额</view></view><view class="money-input data-v-f06186df"><input class="data-v-f06186df" disabled="{{c}}" focus="{{d}}" placeholder="请输入其他金额" value="{{e}}" bindinput="{{f}}"/></view></view><view class="pay-methods data-v-f06186df"><view class="methods-list data-v-f06186df"><block wx:for="{{g}}" wx:for-item="item"><view class="pay-item data-v-f06186df"><view class="pay-item-right data-v-f06186df"><image class="data-v-f06186df" src="{{item.a}}" alt=""></image><view class="data-v-f06186df">{{item.b}}</view></view><radio class="data-v-f06186df" value="{{item.c}}" checked="{{item.d}}"/></view></block></view></view></view><view style="{{'opacity:' + h}}" class="submit-btn data-v-f06186df" bindtap="{{i}}">立即充值</view></view></view>
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/recharge/index.wxss b/unpackage/dist/dev/mp-weixin/pages/recharge/index.wxss
deleted file mode 100644
index b64853b..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/recharge/index.wxss
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
-.container.data-v-f06186df {
-  width: 100%;
-  height: 100vh;
-}
-.container .content.data-v-f06186df {
-  width: 100%;
-  height: calc(100vh - 176rpx);
-  background: linear-gradient(to top, #FFFFFF, #E8EFFF);
-  overflow-y: scroll;
-}
-.container .content .main.data-v-f06186df {
-  width: 686rpx;
-  height: 1262rpx;
-  background: #FFFFFF;
-  border-top-right-radius: 24rpx;
-  border-top-left-radius: 24rpx;
-  margin: 20rpx auto 0;
-  padding: 0 25rpx;
-  box-sizing: border-box;
-}
-.container .content .main .money.data-v-f06186df {
-  width: 100%;
-  height: 378rpx;
-  padding-top: 58rpx;
-  box-sizing: border-box;
-}
-.container .content .main .money .money-list.data-v-f06186df {
-  margin-top: 40rpx;
-  width: 100%;
-  height: 240rpx;
-  padding: 0 20rpx;
-  box-sizing: border-box;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  flex-wrap: wrap;
-}
-.container .content .main .money .money-list .money-box.data-v-f06186df {
-  width: 160rpx;
-  height: 100rpx;
-  border: 2rpx solid #75C8EB;
-  border-radius: 8rpx;
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #4EB6E3;
-  text-align: center;
-  line-height: 100rpx;
-}
-.container .content .main .other-money.data-v-f06186df {
-  width: 100%;
-  height: 164rpx;
-  margin-top: 58rpx;
-}
-.container .content .main .other-money .money-input.data-v-f06186df {
-  margin: 40rpx auto 0;
-  width: calc(100% - 40rpx);
-  height: 80rpx;
-  box-sizing: border-box;
-  border-radius: 8rpx;
-  border: 2rpx solid #75C8EB;
-}
-.container .content .main .other-money .money-input input.data-v-f06186df {
-  width: 94%;
-  height: 80rpx;
-  margin-left: 6%;
-}
-.container .content .main .pay-methods.data-v-f06186df {
-  width: 100%;
-  margin-top: 58rpx;
-}
-.container .content .main .pay-methods .methods-list.data-v-f06186df {
-  margin-top: 40rpx;
-  width: 100%;
-  padding: 0 20rpx;
-  box-sizing: border-box;
-  height: 130rpx;
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-  align-items: flex-start;
-}
-.container .content .main .pay-methods .methods-list .pay-item.data-v-f06186df {
-  width: 100%;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.container .content .main .pay-methods .methods-list .pay-item .pay-item-right.data-v-f06186df {
-  display: flex;
-}
-.container .content .main .pay-methods .methods-list .pay-item .pay-item-right image.data-v-f06186df {
-  width: 42rpx;
-  height: 42rpx;
-  margin-right: 34rpx;
-}
-.container .content .main .pay-methods .methods-list .pay-item .pay-item-right view.data-v-f06186df {
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #111111;
-}
-.container .submit-btn.data-v-f06186df {
-  width: 686rpx;
-  height: 98rpx;
-  background: #5EA1FA;
-  border-radius: 50rpx;
-  text-align: center;
-  line-height: 98rpx;
-  letter-spacing: 3rpx;
-  margin: 0 auto;
-  font-weight: 300;
-  font-size: 36rpx;
-  color: #FFFFFF;
-}
-.money-title.data-v-f06186df {
-  display: flex;
-  align-items: center;
-}
-.money-title .title-icon.data-v-f06186df {
-  width: 8rpx;
-  height: 36rpx;
-  background: #49B4E3;
-  margin-right: 12rpx;
-}
-.money-title .title-text.data-v-f06186df {
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #000000;
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.js b/unpackage/dist/dev/mp-weixin/pages/sendWater/index.js
deleted file mode 100644
index 9e57bd7..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.js
+++ /dev/null
@@ -1,68 +0,0 @@
-"use strict";
-const common_vendor = require("../../common/vendor.js");
-if (!Array) {
-  const _easycom_navbar2 = common_vendor.resolveComponent("navbar");
-  _easycom_navbar2();
-}
-const _easycom_navbar = () => "../../components/navbar/navbar.js";
-if (!Math) {
-  _easycom_navbar();
-}
-const _sfc_main = {
-  __name: "index",
-  setup(__props) {
-    function navTo() {
-      common_vendor.index.navigateTo({
-        url: "/pages/preSendWater/index"
-      });
-    }
-    const isComplete = common_vendor.ref(false);
-    const isActive = common_vendor.ref({ borderBottom: `3px solid #226AC9` });
-    function swatch(val) {
-      if (val == 1 && !isComplete.value || val == 2 && isComplete.value)
-        ;
-      else if (val == 1) {
-        isComplete.value = false;
-      } else if (val == 2) {
-        isComplete.value = true;
-      }
-    }
-    const deliverList = common_vendor.ref([
-      { count: "20", num: "132123123", addre1: "测试1", addre2: "测试2", time: "16:00-18:00" },
-      { count: "20", num: "132123123", addre1: "测试1", addre2: "测试2", time: "16:00-18:00" },
-      { count: "20", num: "132123123", addre1: "测试1", addre2: "测试2", time: "16:00-18:00" }
-    ]);
-    const completeList = common_vendor.ref([1, 2, 3]);
-    return (_ctx, _cache) => {
-      return common_vendor.e({
-        a: common_vendor.p({
-          title: "送水到家"
-        }),
-        b: common_vendor.o(($event) => navTo()),
-        c: common_vendor.o(($event) => swatch(1)),
-        d: common_vendor.s(!isComplete.value ? isActive.value : {}),
-        e: common_vendor.o(($event) => swatch(2)),
-        f: common_vendor.s(isComplete.value ? isActive.value : {}),
-        g: !isComplete.value
-      }, !isComplete.value ? {
-        h: common_vendor.f(deliverList.value, (item, index, i0) => {
-          return {
-            a: common_vendor.t(item.count),
-            b: common_vendor.t(item.num),
-            c: common_vendor.t(item.addre1),
-            d: common_vendor.t(item.addre2),
-            e: common_vendor.t(item.time),
-            f: index
-          };
-        })
-      } : {
-        i: common_vendor.f(completeList.value, (item, index, i0) => {
-          return {
-            a: index
-          };
-        })
-      });
-    };
-  }
-};
-wx.createPage(_sfc_main);
diff --git a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.json b/unpackage/dist/dev/mp-weixin/pages/sendWater/index.json
deleted file mode 100644
index ff63ccc..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "navigationStyle": "custom",
-  "usingComponents": {
-    "navbar": "../../components/navbar/navbar"
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.wxml b/unpackage/dist/dev/mp-weixin/pages/sendWater/index.wxml
deleted file mode 100644
index b477186..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.wxml
+++ /dev/null
@@ -1 +0,0 @@
-<view class="container"><navbar wx:if="{{a}}" u-i="5d3da990-0" bind:__l="__l" u-p="{{a}}"></navbar><view class="content"><view class="nav"><view class="nav-title"><view class="title-one" bindtap="{{b}}">立即预约</view><view class="title-text" bindtap="{{c}}" style="{{d}}">待配送</view><view class="title-text" bindtap="{{e}}" style="{{f}}">已完成</view></view></view><view wx:if="{{g}}" class="main-deliving"><block wx:for="{{h}}" wx:for-item="item" wx:key="f"><view class="item"><view class="item-top"><view class="top-left"><text>{{item.a}}</text><text>桶</text></view><text class="top-right">订单编号:{{item.b}}</text></view><view class="item-content"><view class="item-one"><view class="item-color1">取</view><text>{{item.c}}</text></view><view class="line"></view><view class="item-one"><view class="item-color2">送</view><text>{{item.d}}</text></view><view class="line"></view><view class="item-one"><view class="item-color3">达</view><text>预计今天{{item.e}}送达</text></view></view></view></block></view><view wx:else class="main-complete"><block wx:for="{{i}}" wx:for-item="item" wx:key="a"><view class="item"></view></block></view></view></view>
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.wxss b/unpackage/dist/dev/mp-weixin/pages/sendWater/index.wxss
deleted file mode 100644
index 8b3b710..0000000
--- a/unpackage/dist/dev/mp-weixin/pages/sendWater/index.wxss
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * 这里是uni-app内置的常用样式变量
- *
- * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
- * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
- *
- */
-/**
- * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
- *
- * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
- */
-/* 颜色变量 */
-/* 行为相关颜色 */
-/* 文字基本颜色 */
-/* 背景颜色 */
-/* 边框颜色 */
-/* 尺寸变量 */
-/* 文字尺寸 */
-/* 图片尺寸 */
-/* Border Radius */
-/* 水平间距 */
-/* 垂直间距 */
-/* 透明度 */
-/* 文章场景相关 */
-.container {
-  width: 100%;
-  height: 100vh;
-}
-.container .content {
-  width: 100%;
-  height: calc(100vh - 176rpx);
-  background: linear-gradient(to top, #FFFFFF, #E8EFFF);
-}
-.container .content .nav {
-  height: 160rpx;
-  width: 100%;
-  padding: 20rpx 0;
-  box-sizing: border-box;
-}
-.container .content .nav .nav-title {
-  width: 100%;
-  background: #FFF;
-  padding: 0 32rpx;
-  box-sizing: border-box;
-  height: 120rpx;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.container .content .nav .nav-title .title-one {
-  height: 60rpx;
-  width: 160rpx;
-  background: #DEEDFF;
-  border: 2rpx solid #4AA3FF;
-  text-align: center;
-  line-height: 60rpx;
-  border-radius: 24rpx;
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #007EFF;
-}
-.container .content .nav .nav-title .title-text {
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #000000;
-  width: 120rpx;
-  height: 88rpx;
-  text-align: center;
-  line-height: 88rpx;
-}
-.container .content .main-deliving {
-  height: calc(100% - 320rpx);
-  width: 100%;
-  padding: 32rpx;
-  overflow: scroll;
-  box-sizing: border-box;
-}
-.container .content .main-deliving .item {
-  width: 100%;
-  height: 420rpx;
-  background-color: #FFF;
-  margin-bottom: 20rpx;
-  border-radius: 24rpx;
-}
-.container .content .main-deliving .item .item-top {
-  width: 100%;
-  height: 88rpx;
-  border-bottom: 2rpx solid #DFDFDF;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-.container .content .main-deliving .item .item-top .top-left {
-  margin-left: 52rpx;
-  font-weight: 300;
-  font-size: 28rpx;
-  color: #000000;
-}
-.container .content .main-deliving .item .item-top .top-left text:first-child {
-  color: #FF3400;
-}
-.container .content .main-deliving .item .item-top .top-right {
-  margin-right: 22rpx;
-  font-weight: 300;
-  font-size: 24rpx;
-  color: #4D4D4D;
-}
-.container .content .main-deliving .item .item-content {
-  width: 100%;
-  height: 330rpx;
-  padding: 50rpx 46rpx;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.container .content .main-deliving .item .item-content .item-one {
-  display: flex;
-  align-items: center;
-}
-.container .content .main-deliving .item .item-content .item-one view {
-  width: 52rpx;
-  height: 52rpx;
-  text-align: center;
-  line-height: 52rpx;
-  border-radius: 50%;
-  color: #fff;
-  font-size: 24rpx;
-  margin-right: 32rpx;
-}
-.container .content .main-deliving .item .item-content .item-one text {
-  font-size: 28rpx;
-}
-.container .content .main-deliving .item .item-content .item-one .item-color1 {
-  background-color: #189Df5;
-}
-.container .content .main-deliving .item .item-content .item-one .item-color2 {
-  background-color: #32CB65;
-}
-.container .content .main-deliving .item .item-content .item-one .item-color3 {
-  background-color: #DCDCDC;
-}
-.container .content .main-deliving .item .item-content .line {
-  height: 40rpx;
-  width: 2rpx;
-  background-color: #707070;
-  margin-left: 25rpx;
-}
-.container .content .main-complete {
-  height: calc(100% - 320rpx);
-  width: 100%;
-  padding: 32rpx;
-  overflow: scroll;
-  box-sizing: border-box;
-}
-.container .content .main-complete .item {
-  width: 100%;
-  height: 420rpx;
-  background-color: #FFF;
-  margin-bottom: 20rpx;
-  border-radius: 24rpx;
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/project.config.json b/unpackage/dist/dev/mp-weixin/project.config.json
deleted file mode 100644
index e1facc3..0000000
--- a/unpackage/dist/dev/mp-weixin/project.config.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  "description": "项目配置文件。",
-  "packOptions": {
-    "ignore": [],
-    "include": []
-  },
-  "setting": {
-    "urlCheck": false,
-    "es6": true,
-    "postcss": false,
-    "minified": false,
-    "newFeature": true,
-    "bigPackageSizeSupport": true,
-    "babelSetting": {
-      "ignore": [],
-      "disablePlugins": [],
-      "outputPath": ""
-    }
-  },
-  "compileType": "miniprogram",
-  "libVersion": "",
-  "appid": "wxe86c40810c2c0e98",
-  "projectname": "water-drinking-uniapp",
-  "condition": {},
-  "editorSetting": {
-    "tabIndent": "insertSpaces",
-    "tabSize": 2
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/project.private.config.json b/unpackage/dist/dev/mp-weixin/project.private.config.json
deleted file mode 100644
index 1c71e23..0000000
--- a/unpackage/dist/dev/mp-weixin/project.private.config.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
-  "libVersion": "3.6.6",
-  "projectname": "water-drinking-uniapp",
-  "setting": {
-    "compileHotReLoad": true
-  }
-}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/static/images/addCard/back.png b/unpackage/dist/dev/mp-weixin/static/images/addCard/back.png
deleted file mode 100644
index dabb93b..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/addCard/back.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/back.png b/unpackage/dist/dev/mp-weixin/static/images/index/back.png
deleted file mode 100644
index 8a85bec..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/back.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/bottom-line.png b/unpackage/dist/dev/mp-weixin/static/images/index/bottom-line.png
deleted file mode 100644
index 4c60bfa..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/bottom-line.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/code1.png b/unpackage/dist/dev/mp-weixin/static/images/index/code1.png
deleted file mode 100644
index e917b08..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/code1.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon23.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon23.png
deleted file mode 100644
index 40dd4df..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon23.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon31.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon31.png
deleted file mode 100644
index 9413f85..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon31.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon32.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon32.png
deleted file mode 100644
index 2119427..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon32.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon33.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon33.png
deleted file mode 100644
index 767168c..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon33.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon34.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon34.png
deleted file mode 100644
index 97c9d23..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon34.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon35.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon35.png
deleted file mode 100644
index 0f3e8f8..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon35.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon36.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon36.png
deleted file mode 100644
index c7eed78..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon36.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon37.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon37.png
deleted file mode 100644
index 86f01b2..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon37.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/icon38.png b/unpackage/dist/dev/mp-weixin/static/images/index/icon38.png
deleted file mode 100644
index 78010d9..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/icon38.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/more-info5.png b/unpackage/dist/dev/mp-weixin/static/images/index/more-info5.png
deleted file mode 100644
index 3dc2aed..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/more-info5.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/vip-add.png b/unpackage/dist/dev/mp-weixin/static/images/index/vip-add.png
deleted file mode 100644
index 2e43e8b..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/vip-add.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/index/vip1.png b/unpackage/dist/dev/mp-weixin/static/images/index/vip1.png
deleted file mode 100644
index e66d06f..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/index/vip1.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/login/logo.png b/unpackage/dist/dev/mp-weixin/static/images/login/logo.png
deleted file mode 100644
index e5a3b4e..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/login/logo.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/login/wechat.png b/unpackage/dist/dev/mp-weixin/static/images/login/wechat.png
deleted file mode 100644
index 3d5d6c1..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/login/wechat.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/recharge/balance.png b/unpackage/dist/dev/mp-weixin/static/images/recharge/balance.png
deleted file mode 100644
index 79a7903..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/recharge/balance.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/recharge/pay.png b/unpackage/dist/dev/mp-weixin/static/images/recharge/pay.png
deleted file mode 100644
index 18c80b5..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/recharge/pay.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/images/recharge/wx.png b/unpackage/dist/dev/mp-weixin/static/images/recharge/wx.png
deleted file mode 100644
index 86c2530..0000000
--- a/unpackage/dist/dev/mp-weixin/static/images/recharge/wx.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/static/logo.png b/unpackage/dist/dev/mp-weixin/static/logo.png
deleted file mode 100644
index b5771e2..0000000
--- a/unpackage/dist/dev/mp-weixin/static/logo.png
+++ /dev/null
Binary files differ
diff --git a/unpackage/dist/dev/mp-weixin/util/request.js b/unpackage/dist/dev/mp-weixin/util/request.js
deleted file mode 100644
index 161dcb4..0000000
--- a/unpackage/dist/dev/mp-weixin/util/request.js
+++ /dev/null
@@ -1,28 +0,0 @@
-"use strict";
-const common_vendor = require("../common/vendor.js");
-const config_baseUrl = require("../config/baseUrl.js");
-const request = (url, data, method) => {
-  return new Promise((resolve, reject) => {
-    common_vendor.index.request({
-      url: config_baseUrl.BASE_URL + url,
-      method: method || "POST",
-      header: {
-        token: common_vendor.index.getStorageSync("token") || ""
-      },
-      data: data || {},
-      success: (res) => {
-        const data2 = res.data;
-        resolve(data2);
-      },
-      fail: (error) => {
-        common_vendor.index.showToast({
-          icon: "error",
-          title: "请求错误"
-        });
-        reject(error);
-      }
-    });
-  }).catch((e) => {
-  });
-};
-exports.request = request;

--
Gitblit v1.9.3