From 9c1d98f36f8b38d42db806a17ae07874773f227b Mon Sep 17 00:00:00 2001 From: YOGO <1587218160@qq.com> Date: Mon, 16 Mar 2026 11:10:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=87=91=E5=88=9A=E9=A1=BA?= =?UTF-8?q?=E4=B8=B0=E5=89=8D=E7=AB=AFH5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .hbuilderx/launch.json | 16 + Apis/book.js | 40 + Apis/clientCustomer.js | 55 + Apis/coupon.js | 37 + Apis/goodsList.js | 28 + Apis/home.js | 63 + Apis/invoice.js | 55 + Apis/lock.js | 139 ++ Apis/login.js | 159 ++ Apis/order.js | 172 ++ Apis/recommend.js | 21 + Apis/site.js | 70 + Apis/validInfo.js | 67 + App.vue | 241 +++ README.md | 21 +- components/AgreementCheck.vue | 246 +++ components/MediatorinviteDetail.vue | 158 ++ components/coupon.vue | 820 ++++++++ components/inviteDetail.vue | 163 ++ components/my-dropdown.vue | 124 ++ components/myCustomtTabBar.vue | 109 + components/myModal.vue | 210 ++ components/myPopup.vue | 172 ++ components/myUpload.vue | 142 ++ components/navBar.vue | 67 + components/noToken.vue | 29 + components/siteDetail.vue | 336 ++++ components/textEllipsis.vue | 110 + components/updatePopup.vue | 212 ++ components/uv-tabsSelf/props.js | 71 + components/uv-tabsSelf/uv-tabs.vue | 412 ++++ components/wxNavbar.vue | 51 + config/index.js | 61 + hooks/index.js | 43 + hooks/useCountDown.js | 68 + hooks/useLocation.js | 54 + index.html | 50 + locale/en.json | 502 +++++ locale/index.js | 38 + locale/ja.json | 23 + locale/messagesFunctions.js | 49 + locale/uni-app.ja.json | 36 + locale/zh-Hans.json | 502 +++++ locale/zh-Hant.json | 24 + main.js | 20 + manifest.json | 113 ++ package-lock.json | 1443 ++++++++++++++ package.json | 21 + pages.json | 281 +++ pages/book/book.vue | 53 + pages/book/index.vue | 456 +++++ pages/book/map.vue | 174 ++ pages/book/mapmode.vue | 364 ++++ pages/book/navigate.vue | 88 + pages/call/index.vue | 12 + pages/evaluate/index.vue | 396 ++++ pages/facecode/facecode.vue | 62 + pages/forgotPawd/index.vue | 300 +++ pages/goodsList/index.vue | 332 ++++ pages/index/index.vue | 1549 +++++++++++++++ pages/invite/index.vue | 157 ++ pages/login/index.vue | 642 ++++++ pages/orderdetail/door.vue | 224 +++ pages/orderdetail/index.vue | 1569 +++++++++++++++ pages/orderdetail/lock.vue | 259 +++ pages/personal/customerAi.vue | 44 + pages/personal/index.vue | 123 ++ pages/phone/index.vue | 10 + pages/register/index.vue | 305 +++ pages/renewOrder/index.vue | 1154 +++++++++++ pages/setOrder/index.vue | 1770 +++++++++++++++++ pages/site/index.vue | 350 ++++ pages/unlock/index.vue | 1472 ++++++++++++++ pages/webview/web.vue | 42 + pagesb/AControl/index.vue | 363 ++++ pagesb/Apis/flashSale.js | 17 + pagesb/activityDetail/index.vue | 173 ++ pagesb/changeUser/index.vue | 339 ++++ pagesb/components/my-uv-collapse/changelog.md | 5 + .../components/uv-collapse-item/props.js | 60 + .../uv-collapse-item/uv-collapse-item.vue | 232 +++ .../components/uv-collapse/props.js | 20 + .../components/uv-collapse/uv-collapse.vue | 86 + pagesb/components/my-uv-collapse/package.json | 89 + .../components/qf-image-cropper/changelog.md | 67 + .../qf-image-cropper.render.js | 738 +++++++ .../qf-image-cropper/qf-image-cropper.vue | 790 ++++++++ .../qf-image-cropper/qf-image-cropper.wxs | 604 ++++++ .../components/qf-image-cropper/package.json | 81 + pagesb/components/qf-image-cropper/readme.md | 95 + pagesb/flashSale/index.vue | 451 +++++ pagesb/houseKey/index.vue | 340 ++++ pagesb/initLock/index.vue | 728 +++++++ pagesb/initLock/lockInitApi.js | 158 ++ pagesb/invitation/index.vue | 394 ++++ pagesb/invoice/index.vue | 291 +++ pagesb/invoiceApply/index.vue | 582 ++++++ pagesb/invoiceApplyforRecord/index.vue | 271 +++ pagesb/latestEvents/index.vue | 189 ++ pagesb/maskUser/index.vue | 63 + pagesb/pointsMall/index.vue | 522 +++++ pagesb/referrerInfo/index.vue | 258 +++ pagesb/reserve/index.vue | 530 +++++ pagesb/unittypeDetail/index.vue | 280 +++ pagesb/userguide/index.vue | 356 ++++ pagesb/validationInfo/index.vue | 618 ++++++ pagesb/videoTutorial/index.vue | 249 +++ static/book/noSelectMapIcon.png | Bin 0 -> 566 bytes static/book/return.png | Bin 0 -> 425 bytes static/book/selectMapIcon.png | Bin 0 -> 472 bytes static/customicons.css | 20 + static/customicons.ttf | Bin 0 -> 2416 bytes static/evaluate/addPic.png | Bin 0 -> 2761 bytes static/evaluate/image.png | Bin 0 -> 582 bytes static/home/address.png | Bin 0 -> 271 bytes static/home/address.svg | 3 + static/home/appointment.png | Bin 0 -> 339 bytes static/home/area.png | Bin 0 -> 195 bytes static/home/bus.png | Bin 0 -> 240 bytes static/home/left.png | Bin 0 -> 343 bytes static/home/region.png | Bin 0 -> 186 bytes static/home/right.png | Bin 0 -> 341 bytes static/home/shichang_logo.png | Bin 0 -> 40224 bytes static/home/siteicon.svg | 4 + static/home/siteicon2.svg | 4 + static/iconfont/iconfont.css | 190 ++ static/orderdetail/refresh.png | Bin 0 -> 540 bytes static/personal/bottom-bg.png | Bin 0 -> 11536 bytes static/personal/head.png | Bin 0 -> 100200 bytes static/personal/id01.png | Bin 0 -> 2822 bytes static/personal/id02.png | Bin 0 -> 2070 bytes static/personal/id03.png | Bin 0 -> 1232 bytes static/personal/mes.png | Bin 0 -> 385 bytes static/personal/share.png | Bin 0 -> 391 bytes static/personal/userimg.png | Bin 0 -> 100218 bytes static/personal/warning.png | Bin 0 -> 283 bytes static/setOrder/fire.png | Bin 0 -> 335 bytes static/setOrder/selectArrow.png | Bin 0 -> 230 bytes static/site/hot.svg | 8 + static/site/map.svg | 1 + static/style/theme.scss | 156 ++ static/tabbar/book.png | Bin 0 -> 396 bytes static/tabbar/call.png | Bin 0 -> 808 bytes static/tabbar/home.svg | 1 + static/tabbar/index.png | Bin 0 -> 265 bytes static/tabbar/order.svg | 1 + static/tabbar/unlock.png | Bin 0 -> 230 bytes static/tabbar/user.svg | 1 + store/index.js | 80 + uni.scss | 116 ++ uni_modules/no-data/changelog.md | 0 .../no-data/components/no-data/i18n/en.json | 3 + .../no-data/components/no-data/i18n/index.js | 10 + .../no-data/components/no-data/i18n/ja.json | 3 + .../components/no-data/i18n/zh-Hans.json | 3 + .../components/no-data/i18n/zh-Hant.json | 3 + .../no-data/components/no-data/no-data.vue | 44 + uni_modules/no-data/package.json | 80 + uni_modules/no-data/readme.md | 1 + uni_modules/uni-badge/changelog.md | 33 + .../components/uni-badge/uni-badge.vue | 268 +++ uni_modules/uni-badge/package.json | 85 + uni_modules/uni-badge/readme.md | 10 + uni_modules/uni-breadcrumb/changelog.md | 6 + .../uni-breadcrumb-item.vue | 121 ++ .../uni-breadcrumb/uni-breadcrumb.vue | 41 + uni_modules/uni-breadcrumb/package.json | 88 + uni_modules/uni-breadcrumb/readme.md | 66 + uni_modules/uni-calendar/changelog.md | 26 + .../components/uni-calendar/calendar.js | 546 +++++ .../components/uni-calendar/i18n/en.json | 12 + .../components/uni-calendar/i18n/index.js | 8 + .../components/uni-calendar/i18n/zh-Hans.json | 12 + .../components/uni-calendar/i18n/zh-Hant.json | 12 + .../uni-calendar/uni-calendar-item.vue | 187 ++ .../components/uni-calendar/uni-calendar.vue | 566 ++++++ .../components/uni-calendar/util.js | 360 ++++ uni_modules/uni-calendar/package.json | 85 + uni_modules/uni-calendar/readme.md | 103 + uni_modules/uni-card/changelog.md | 26 + .../uni-card/components/uni-card/uni-card.vue | 272 +++ uni_modules/uni-card/package.json | 90 + uni_modules/uni-card/readme.md | 12 + uni_modules/uni-collapse/changelog.md | 36 + .../uni-collapse-item/uni-collapse-item.vue | 402 ++++ .../components/uni-collapse/uni-collapse.vue | 147 ++ uni_modules/uni-collapse/package.json | 89 + uni_modules/uni-collapse/readme.md | 12 + uni_modules/uni-combox/changelog.md | 15 + .../components/uni-combox/uni-combox.vue | 294 +++ uni_modules/uni-combox/package.json | 90 + uni_modules/uni-combox/readme.md | 11 + uni_modules/uni-countdown/changelog.md | 24 + .../components/uni-countdown/i18n/en.json | 6 + .../components/uni-countdown/i18n/index.js | 8 + .../uni-countdown/i18n/zh-Hans.json | 6 + .../uni-countdown/i18n/zh-Hant.json | 6 + .../uni-countdown/uni-countdown.vue | 267 +++ uni_modules/uni-countdown/package.json | 86 + uni_modules/uni-countdown/readme.md | 10 + uni_modules/uni-data-checkbox/changelog.md | 45 + .../uni-data-checkbox/uni-data-checkbox.vue | 821 ++++++++ uni_modules/uni-data-checkbox/package.json | 84 + uni_modules/uni-data-checkbox/readme.md | 18 + uni_modules/uni-data-picker/changelog.md | 75 + .../components/uni-data-picker/keypress.js | 45 + .../uni-data-picker/uni-data-picker.vue | 551 +++++ .../uni-data-pickerview/uni-data-picker.js | 622 ++++++ .../uni-data-pickerview.vue | 323 +++ uni_modules/uni-data-picker/package.json | 90 + uni_modules/uni-data-picker/readme.md | 22 + uni_modules/uni-data-select/changelog.md | 35 + .../uni-data-select/uni-data-select.vue | 517 +++++ uni_modules/uni-data-select/package.json | 85 + uni_modules/uni-data-select/readme.md | 8 + uni_modules/uni-dateformat/changelog.md | 10 + .../components/uni-dateformat/date-format.js | 200 ++ .../uni-dateformat/uni-dateformat.vue | 88 + uni_modules/uni-dateformat/package.json | 88 + uni_modules/uni-dateformat/readme.md | 11 + uni_modules/uni-datetime-picker/changelog.md | 133 ++ .../uni-datetime-picker/calendar-item.vue | 177 ++ .../uni-datetime-picker/calendar.vue | 928 +++++++++ .../uni-datetime-picker/i18n/en.json | 22 + .../uni-datetime-picker/i18n/index.js | 8 + .../uni-datetime-picker/i18n/zh-Hans.json | 22 + .../uni-datetime-picker/i18n/zh-Hant.json | 22 + .../uni-datetime-picker/time-picker.vue | 934 +++++++++ .../uni-datetime-picker.vue | 1026 ++++++++++ .../components/uni-datetime-picker/util.js | 403 ++++ uni_modules/uni-datetime-picker/package.json | 87 + uni_modules/uni-datetime-picker/readme.md | 21 + uni_modules/uni-drawer/changelog.md | 13 + .../components/uni-drawer/keypress.js | 45 + .../components/uni-drawer/uni-drawer.vue | 183 ++ uni_modules/uni-drawer/package.json | 87 + uni_modules/uni-drawer/readme.md | 10 + uni_modules/uni-easyinput/changelog.md | 97 + .../components/uni-easyinput/common.js | 54 + .../uni-easyinput/uni-easyinput.vue | 657 ++++++ uni_modules/uni-easyinput/package.json | 87 + uni_modules/uni-easyinput/readme.md | 11 + uni_modules/uni-fab/changelog.md | 23 + .../uni-fab/components/uni-fab/uni-fab.vue | 491 +++++ uni_modules/uni-fab/package.json | 84 + uni_modules/uni-fab/readme.md | 9 + uni_modules/uni-fav/changelog.md | 19 + .../uni-fav/components/uni-fav/i18n/en.json | 4 + .../uni-fav/components/uni-fav/i18n/index.js | 8 + .../components/uni-fav/i18n/zh-Hans.json | 4 + .../components/uni-fav/i18n/zh-Hant.json | 4 + .../uni-fav/components/uni-fav/uni-fav.vue | 161 ++ uni_modules/uni-fav/package.json | 89 + uni_modules/uni-fav/readme.md | 10 + uni_modules/uni-file-picker/changelog.md | 67 + .../uni-file-picker/choose-and-upload-file.js | 224 +++ .../uni-file-picker/uni-file-picker.vue | 667 +++++++ .../uni-file-picker/upload-file.vue | 325 +++ .../uni-file-picker/upload-image.vue | 292 +++ .../components/uni-file-picker/utils.js | 109 + uni_modules/uni-file-picker/package.json | 83 + uni_modules/uni-file-picker/readme.md | 11 + uni_modules/uni-forms/changelog.md | 92 + .../uni-forms-item/uni-forms-item.vue | 627 ++++++ .../components/uni-forms/uni-forms.vue | 397 ++++ .../uni-forms/components/uni-forms/utils.js | 293 +++ .../components/uni-forms/validate.js | 486 +++++ uni_modules/uni-forms/package.json | 88 + uni_modules/uni-forms/readme.md | 23 + uni_modules/uni-goods-nav/changelog.md | 18 + .../components/uni-goods-nav/i18n/en.json | 6 + .../components/uni-goods-nav/i18n/index.js | 8 + .../uni-goods-nav/i18n/zh-Hans.json | 6 + .../uni-goods-nav/i18n/zh-Hant.json | 6 + .../uni-goods-nav/uni-goods-nav.vue | 229 +++ uni_modules/uni-goods-nav/package.json | 88 + uni_modules/uni-goods-nav/readme.md | 10 + uni_modules/uni-grid/changelog.md | 13 + .../uni-grid-item/uni-grid-item.vue | 127 ++ .../uni-grid/components/uni-grid/uni-grid.vue | 142 ++ uni_modules/uni-grid/package.json | 86 + uni_modules/uni-grid/readme.md | 11 + uni_modules/uni-group/changelog.md | 16 + .../components/uni-group/uni-group.vue | 134 ++ uni_modules/uni-group/package.json | 87 + uni_modules/uni-group/readme.md | 9 + uni_modules/uni-icons/changelog.md | 22 + .../uni-icons/components/uni-icons/icons.js | 1169 +++++++++++ .../components/uni-icons/uni-icons.vue | 96 + .../components/uni-icons/uniicons.css | 663 ++++++ .../components/uni-icons/uniicons.ttf | Bin 0 -> 35760 bytes uni_modules/uni-icons/package.json | 86 + uni_modules/uni-icons/readme.md | 8 + uni_modules/uni-indexed-list/changelog.md | 17 + .../uni-indexed-list-item.vue | 144 ++ .../uni-indexed-list/uni-indexed-list.vue | 367 ++++ uni_modules/uni-indexed-list/package.json | 89 + uni_modules/uni-indexed-list/readme.md | 11 + uni_modules/uni-link/changelog.md | 17 + .../uni-link/components/uni-link/uni-link.vue | 128 ++ uni_modules/uni-link/package.json | 87 + uni_modules/uni-link/readme.md | 11 + uni_modules/uni-list/changelog.md | 46 + .../components/uni-list-ad/uni-list-ad.vue | 107 + .../uni-list-chat/uni-list-chat.scss | 58 + .../uni-list-chat/uni-list-chat.vue | 593 ++++++ .../uni-list-item/uni-list-item.vue | 534 +++++ .../uni-list/components/uni-list/uni-list.vue | 123 ++ .../components/uni-list/uni-refresh.vue | 65 + .../components/uni-list/uni-refresh.wxs | 87 + uni_modules/uni-list/package.json | 88 + uni_modules/uni-list/readme.md | 346 ++++ uni_modules/uni-load-more/changelog.md | 19 + .../components/uni-load-more/i18n/en.json | 5 + .../components/uni-load-more/i18n/index.js | 8 + .../uni-load-more/i18n/zh-Hans.json | 5 + .../uni-load-more/i18n/zh-Hant.json | 5 + .../uni-load-more/uni-load-more.vue | 399 ++++ uni_modules/uni-load-more/package.json | 86 + uni_modules/uni-load-more/readme.md | 14 + uni_modules/uni-nav-bar/changelog.md | 51 + .../components/uni-nav-bar/uni-nav-bar.vue | 357 ++++ .../components/uni-nav-bar/uni-status-bar.vue | 24 + uni_modules/uni-nav-bar/package.json | 86 + uni_modules/uni-nav-bar/readme.md | 15 + uni_modules/uni-notice-bar/changelog.md | 18 + .../uni-notice-bar/uni-notice-bar.vue | 426 ++++ uni_modules/uni-notice-bar/package.json | 87 + uni_modules/uni-notice-bar/readme.md | 13 + uni_modules/uni-number-box/changelog.md | 25 + .../uni-number-box/uni-number-box.vue | 221 ++ uni_modules/uni-number-box/package.json | 85 + uni_modules/uni-number-box/readme.md | 13 + uni_modules/uni-pagination/changelog.md | 27 + .../components/uni-pagination/i18n/en.json | 5 + .../components/uni-pagination/i18n/es.json | 5 + .../components/uni-pagination/i18n/fr.json | 5 + .../components/uni-pagination/i18n/index.js | 12 + .../uni-pagination/i18n/zh-Hans.json | 5 + .../uni-pagination/i18n/zh-Hant.json | 5 + .../uni-pagination/uni-pagination.vue | 465 +++++ uni_modules/uni-pagination/package.json | 83 + uni_modules/uni-pagination/readme.md | 11 + uni_modules/uni-popup/changelog.md | 68 + .../components/uni-popup-dialog/keypress.js | 45 + .../uni-popup-dialog/uni-popup-dialog.vue | 275 +++ .../uni-popup-message/uni-popup-message.vue | 143 ++ .../uni-popup-share/uni-popup-share.vue | 187 ++ .../components/uni-popup/i18n/en.json | 7 + .../components/uni-popup/i18n/index.js | 8 + .../components/uni-popup/i18n/zh-Hans.json | 7 + .../components/uni-popup/i18n/zh-Hant.json | 7 + .../components/uni-popup/keypress.js | 45 + .../uni-popup/components/uni-popup/popup.js | 26 + .../components/uni-popup/uni-popup.vue | 473 +++++ uni_modules/uni-popup/package.json | 87 + uni_modules/uni-popup/readme.md | 17 + uni_modules/uni-rate/changelog.md | 25 + .../uni-rate/components/uni-rate/uni-rate.vue | 365 ++++ uni_modules/uni-rate/package.json | 88 + uni_modules/uni-rate/readme.md | 12 + uni_modules/uni-row/changelog.md | 10 + .../uni-row/components/uni-col/uni-col.vue | 317 +++ .../uni-row/components/uni-row/uni-row.vue | 190 ++ uni_modules/uni-row/package.json | 87 + uni_modules/uni-row/readme.md | 10 + uni_modules/uni-scss/changelog.md | 8 + uni_modules/uni-scss/index.scss | 1 + uni_modules/uni-scss/package.json | 82 + uni_modules/uni-scss/readme.md | 4 + uni_modules/uni-scss/styles/index.scss | 7 + .../uni-scss/styles/setting/_border.scss | 3 + .../uni-scss/styles/setting/_color.scss | 66 + .../uni-scss/styles/setting/_radius.scss | 55 + .../uni-scss/styles/setting/_space.scss | 56 + .../uni-scss/styles/setting/_styles.scss | 167 ++ .../uni-scss/styles/setting/_text.scss | 24 + .../uni-scss/styles/setting/_variables.scss | 146 ++ .../uni-scss/styles/tools/functions.scss | 19 + uni_modules/uni-scss/theme.scss | 31 + uni_modules/uni-scss/variables.scss | 62 + uni_modules/uni-search-bar/changelog.md | 33 + .../components/uni-search-bar/i18n/en.json | 4 + .../components/uni-search-bar/i18n/index.js | 8 + .../uni-search-bar/i18n/zh-Hans.json | 4 + .../uni-search-bar/i18n/zh-Hant.json | 4 + .../uni-search-bar/uni-search-bar.vue | 298 +++ uni_modules/uni-search-bar/package.json | 89 + uni_modules/uni-search-bar/readme.md | 14 + uni_modules/uni-section/changelog.md | 2 + .../components/uni-section/uni-section.vue | 167 ++ uni_modules/uni-section/package.json | 87 + uni_modules/uni-section/readme.md | 8 + .../uni-segmented-control/changelog.md | 9 + .../uni-segmented-control.vue | 145 ++ .../uni-segmented-control/package.json | 87 + uni_modules/uni-segmented-control/readme.md | 13 + uni_modules/uni-steps/changelog.md | 16 + .../components/uni-steps/uni-steps.vue | 269 +++ uni_modules/uni-steps/package.json | 89 + uni_modules/uni-steps/readme.md | 13 + uni_modules/uni-swipe-action/changelog.md | 43 + .../uni-swipe-action-item/bindingx.js | 302 +++ .../components/uni-swipe-action-item/isPC.js | 12 + .../uni-swipe-action-item/mpalipay.js | 195 ++ .../uni-swipe-action-item/mpother.js | 260 +++ .../components/uni-swipe-action-item/mpwxs.js | 84 + .../uni-swipe-action-item/render.js | 270 +++ .../uni-swipe-action-item.vue | 347 ++++ .../components/uni-swipe-action-item/wx.wxs | 341 ++++ .../uni-swipe-action/uni-swipe-action.vue | 60 + uni_modules/uni-swipe-action/package.json | 87 + uni_modules/uni-swipe-action/readme.md | 11 + uni_modules/uni-swiper-dot/changelog.md | 12 + .../uni-swiper-dot/uni-swiper-dot.vue | 218 ++ uni_modules/uni-swiper-dot/package.json | 87 + uni_modules/uni-swiper-dot/readme.md | 11 + uni_modules/uni-table/changelog.md | 27 + .../components/uni-table/uni-table.vue | 455 +++++ .../components/uni-tbody/uni-tbody.vue | 29 + .../uni-table/components/uni-td/uni-td.vue | 90 + .../components/uni-th/filter-dropdown.vue | 511 +++++ .../uni-table/components/uni-th/uni-th.vue | 285 +++ .../components/uni-thead/uni-thead.vue | 129 ++ .../components/uni-tr/table-checkbox.vue | 179 ++ .../uni-table/components/uni-tr/uni-tr.vue | 171 ++ uni_modules/uni-table/i18n/en.json | 9 + uni_modules/uni-table/i18n/es.json | 9 + uni_modules/uni-table/i18n/fr.json | 9 + uni_modules/uni-table/i18n/index.js | 12 + uni_modules/uni-table/i18n/zh-Hans.json | 9 + uni_modules/uni-table/i18n/zh-Hant.json | 9 + uni_modules/uni-table/package.json | 83 + uni_modules/uni-table/readme.md | 13 + uni_modules/uni-tag/changelog.md | 21 + .../uni-tag/components/uni-tag/uni-tag.vue | 252 +++ uni_modules/uni-tag/package.json | 87 + uni_modules/uni-tag/readme.md | 13 + uni_modules/uni-test/changelog.md | 39 + .../uni-test/components/uni-test/uni-test.vue | 26 + uni_modules/uni-test/package.json | 83 + uni_modules/uni-test/readme.md | 10 + uni_modules/uni-title/changelog.md | 10 + .../components/uni-title/uni-title.vue | 171 ++ uni_modules/uni-title/package.json | 88 + uni_modules/uni-title/readme.md | 14 + uni_modules/uni-tooltip/changelog.md | 10 + .../components/uni-tooltip/uni-tooltip.vue | 68 + uni_modules/uni-tooltip/package.json | 88 + uni_modules/uni-tooltip/readme.md | 8 + uni_modules/uni-transition/changelog.md | 20 + .../uni-transition/createAnimation.js | 131 ++ .../uni-transition/uni-transition.vue | 281 +++ uni_modules/uni-transition/package.json | 87 + uni_modules/uni-transition/readme.md | 11 + uni_modules/uni-ui/changelog.md | 541 +++++ .../uni-ui/components/uni-badge/uni-badge.vue | 153 ++ .../components/uni-calendar/calendar.js | 546 +++++ .../uni-calendar/uni-calendar-item.vue | 170 ++ .../components/uni-calendar/uni-calendar.vue | 505 +++++ .../uni-ui/components/uni-calendar/util.js | 352 ++++ .../uni-ui/components/uni-card/uni-card.vue | 403 ++++ .../uni-collapse-item/uni-collapse-item.vue | 218 ++ .../components/uni-collapse/uni-collapse.vue | 59 + .../components/uni-combox/uni-combox.vue | 213 ++ .../uni-countdown/uni-countdown.vue | 211 ++ .../components/uni-data-checkbox/clientdb.js | 316 +++ .../uni-data-checkbox/uni-data-checkbox.vue | 826 ++++++++ .../components/uni-dateformat/date-format.js | 191 ++ .../uni-dateformat/uni-dateformat.vue | 90 + .../uni-datetime-picker.vue | 355 ++++ .../components/uni-drawer/uni-drawer.vue | 170 ++ .../uni-ui/components/uni-easyinput/common.js | 56 + .../uni-easyinput/uni-easyinput.vue | 401 ++++ .../uni-ui/components/uni-fab/uni-fab.vue | 433 ++++ .../uni-ui/components/uni-fav/uni-fav.vue | 140 ++ .../uni-ui/components/uni-field/uni-field.vue | 686 +++++++ .../uni-forms-item/uni-forms-item.vue | 436 ++++ .../uni-ui/components/uni-forms/uni-forms.vue | 420 ++++ .../uni-ui/components/uni-forms/validate.js | 442 ++++ .../uni-goods-nav/uni-goods-nav.vue | 225 +++ .../uni-grid-item/uni-grid-item.vue | 124 ++ .../uni-ui/components/uni-grid/uni-grid.vue | 141 ++ .../uni-ui/components/uni-group/uni-group.vue | 127 ++ .../uni-ui/components/uni-icons/icons.js | 132 ++ .../uni-ui/components/uni-icons/uni-icons.vue | 71 + .../uni-ui/components/uni-icons/uni.ttf | Bin 0 -> 26164 bytes .../uni-indexed-list-item.vue | 142 ++ .../uni-indexed-list/uni-indexed-list.vue | 318 +++ .../uni-ui/components/uni-link/uni-link.vue | 78 + .../components/uni-list-ad/uni-list-ad.vue | 107 + .../uni-list-chat/uni-list-chat.scss | 58 + .../uni-list-chat/uni-list-chat.vue | 533 +++++ .../uni-list-item/uni-list-item.vue | 440 ++++ .../uni-ui/components/uni-list/uni-list.vue | 106 + .../components/uni-list/uni-refresh.vue | 65 + .../components/uni-list/uni-refresh.wxs | 87 + .../uni-load-more/uni-load-more.vue | 359 ++++ .../components/uni-nav-bar/uni-nav-bar.vue | 242 +++ .../uni-notice-bar/uni-notice-bar.vue | 395 ++++ .../uni-number-box/uni-number-box.vue | 200 ++ .../uni-pagination/uni-pagination.vue | 204 ++ .../uni-popup-dialog/uni-popup-dialog.vue | 243 +++ .../uni-popup-message/uni-popup-message.vue | 116 ++ .../uni-popup-share/uni-popup-share.vue | 165 ++ .../uni-ui/components/uni-popup/message.js | 22 + .../uni-ui/components/uni-popup/popup.js | 25 + .../uni-ui/components/uni-popup/share.js | 16 + .../uni-ui/components/uni-popup/uni-popup.vue | 297 +++ .../uni-ui/components/uni-rate/uni-rate.vue | 296 +++ .../uni-search-bar/uni-search-bar.vue | 206 ++ .../components/uni-section/uni-section.vue | 136 ++ .../uni-segmented-control.vue | 138 ++ .../uni-status-bar/uni-status-bar.vue | 25 + .../uni-ui/components/uni-steps/uni-steps.vue | 256 +++ .../uni-swipe-action-item/bindingx.js | 292 +++ .../uni-swipe-action-item/index.wxs | 266 +++ .../uni-swipe-action-item/mpalipay.js | 207 ++ .../uni-swipe-action-item/mpother.js | 252 +++ .../components/uni-swipe-action-item/mpwxs.js | 116 ++ .../uni-swipe-action-item.vue | 365 ++++ .../uni-swipe-action/uni-swipe-action.vue | 42 + .../uni-swiper-dot/uni-swiper-dot.vue | 201 ++ .../uni-ui/components/uni-table/uni-table.vue | 263 +++ .../uni-ui/components/uni-tag/uni-tag.vue | 230 +++ .../uni-ui/components/uni-td/uni-td.vue | 74 + .../uni-ui/components/uni-test/uni-test.vue | 19 + .../uni-ui/components/uni-th/uni-th.vue | 78 + .../uni-ui/components/uni-title/uni-title.vue | 170 ++ .../uni-ui/components/uni-tr/uni-tr.vue | 117 ++ .../uni-transition/uni-transition.vue | 279 +++ .../uni-ui/components/uni-ui/uni-ui.vue | 7 + uni_modules/uni-ui/manifest.json | 95 + uni_modules/uni-ui/package.json | 129 ++ uni_modules/uni-ui/readme.md | 247 +++ uni_modules/uv-action-sheet/changelog.md | 7 + .../components/uv-action-sheet/props.js | 50 + .../uv-action-sheet/uv-action-sheet.vue | 280 +++ uni_modules/uv-action-sheet/package.json | 92 + uni_modules/uv-action-sheet/readme.md | 13 + uni_modules/uv-album/changelog.md | 10 + .../uv-album/components/uv-album/uv-album.vue | 312 +++ uni_modules/uv-album/package.json | 88 + uni_modules/uv-album/readme.md | 21 + uni_modules/uv-alert/changelog.md | 7 + .../uv-alert/components/uv-alert/props.js | 45 + .../uv-alert/components/uv-alert/uv-alert.vue | 246 +++ uni_modules/uv-alert/package.json | 88 + uni_modules/uv-alert/readme.md | 15 + uni_modules/uv-avatar/changelog.md | 13 + .../components/uv-avatar-group/props.js | 53 + .../uv-avatar-group/uv-avatar-group.vue | 106 + .../uv-avatar/components/uv-avatar/props.js | 80 + .../components/uv-avatar/uv-avatar.vue | 175 ++ uni_modules/uv-avatar/package.json | 89 + uni_modules/uv-avatar/readme.md | 11 + uni_modules/uv-back-top/changelog.md | 8 + .../components/uv-back-top/props.js | 58 + .../components/uv-back-top/uv-back-top.vue | 116 ++ uni_modules/uv-back-top/package.json | 89 + uni_modules/uv-back-top/readme.md | 11 + uni_modules/uv-badge/changelog.md | 7 + .../uv-badge/components/uv-badge/props.js | 73 + .../uv-badge/components/uv-badge/uv-badge.vue | 176 ++ uni_modules/uv-badge/package.json | 87 + uni_modules/uv-badge/readme.md | 11 + uni_modules/uv-button/changelog.md | 33 + .../uv-button/components/uv-button/nvue.scss | 46 + .../uv-button/components/uv-button/props.js | 163 ++ .../components/uv-button/uv-button.vue | 528 +++++ .../uv-button/components/uv-button/vue.scss | 93 + uni_modules/uv-button/package.json | 89 + uni_modules/uv-button/readme.md | 19 + uni_modules/uv-calendar/changelog.md | 16 + .../components/uv-calendar/calendar.js | 546 +++++ .../components/uv-calendar/header.vue | 104 + .../components/uv-calendar/month.vue | 616 ++++++ .../components/uv-calendar/props.js | 145 ++ .../components/uv-calendar/uv-calendar.vue | 390 ++++ uni_modules/uv-calendar/package.json | 89 + uni_modules/uv-calendar/readme.md | 21 + uni_modules/uv-calendars/changelog.md | 40 + .../components/uv-calendars/calendar-body.vue | 376 ++++ .../components/uv-calendars/calendar-item.vue | 248 +++ .../components/uv-calendars/calendar.js | 546 +++++ .../components/uv-calendars/i18n/en.json | 12 + .../components/uv-calendars/i18n/index.js | 8 + .../components/uv-calendars/i18n/zh-Hans.json | 12 + .../components/uv-calendars/i18n/zh-Hant.json | 12 + .../components/uv-calendars/util.js | 435 ++++ .../components/uv-calendars/uv-calendars.vue | 452 +++++ uni_modules/uv-calendars/package.json | 89 + uni_modules/uv-calendars/readme.md | 23 + uni_modules/uv-cell/changelog.md | 13 + .../uv-cell/components/uv-cell-group/props.js | 15 + .../uv-cell-group/uv-cell-group.vue | 63 + .../uv-cell/components/uv-cell/props.js | 116 ++ .../uv-cell/components/uv-cell/uv-cell.vue | 209 ++ uni_modules/uv-cell/package.json | 89 + uni_modules/uv-cell/readme.md | 11 + uni_modules/uv-checkbox/changelog.md | 34 + .../components/uv-checkbox-group/props.js | 84 + .../uv-checkbox-group/uv-checkbox-group.vue | 119 ++ .../components/uv-checkbox/props.js | 70 + .../components/uv-checkbox/uv-checkbox.vue | 370 ++++ uni_modules/uv-checkbox/package.json | 88 + uni_modules/uv-checkbox/readme.md | 19 + uni_modules/uv-code-input/changelog.md | 13 + .../components/uv-code-input/props.js | 83 + .../uv-code-input/uv-code-input.vue | 272 +++ uni_modules/uv-code-input/package.json | 87 + uni_modules/uv-code-input/readme.md | 19 + uni_modules/uv-code/changelog.md | 9 + .../uv-code/components/uv-code/props.js | 35 + .../uv-code/components/uv-code/uv-code.vue | 136 ++ uni_modules/uv-code/package.json | 87 + uni_modules/uv-code/readme.md | 11 + uni_modules/uv-collapse/changelog.md | 5 + .../components/uv-collapse-item/props.js | 60 + .../uv-collapse-item/uv-collapse-item.vue | 229 +++ .../components/uv-collapse/props.js | 20 + .../components/uv-collapse/uv-collapse.vue | 86 + uni_modules/uv-collapse/package.json | 89 + uni_modules/uv-collapse/readme.md | 11 + uni_modules/uv-count-down/changelog.md | 9 + .../components/uv-count-down/props.js | 25 + .../components/uv-count-down/utils.js | 62 + .../uv-count-down/uv-count-down.vue | 169 ++ uni_modules/uv-count-down/package.json | 87 + uni_modules/uv-count-down/readme.md | 11 + uni_modules/uv-count-to/changelog.md | 13 + .../components/uv-count-to/props.js | 60 + .../components/uv-count-to/uv-count-to.vue | 187 ++ uni_modules/uv-count-to/package.json | 87 + uni_modules/uv-count-to/readme.md | 11 + uni_modules/uv-datetime-picker/changelog.md | 34 + .../components/uv-datetime-picker/props.js | 130 ++ .../uv-datetime-picker/uv-datetime-picker.vue | 360 ++++ uni_modules/uv-datetime-picker/package.json | 89 + uni_modules/uv-datetime-picker/readme.md | 19 + uni_modules/uv-divider/changelog.md | 11 + .../uv-divider/components/uv-divider/props.js | 45 + .../components/uv-divider/uv-divider.vue | 113 ++ uni_modules/uv-divider/package.json | 88 + uni_modules/uv-divider/readme.md | 11 + uni_modules/uv-drop-down/changelog.md | 13 + .../uv-drop-down-item/uv-drop-down-item.vue | 169 ++ .../uv-drop-down-popup/uv-drop-down-popup.vue | 242 +++ .../components/uv-drop-down/uv-drop-down.vue | 135 ++ uni_modules/uv-drop-down/package.json | 91 + uni_modules/uv-drop-down/readme.md | 23 + uni_modules/uv-empty/changelog.md | 13 + .../uv-empty/components/uv-empty/props.js | 60 + .../uv-empty/components/uv-empty/uv-empty.vue | 126 ++ uni_modules/uv-empty/package.json | 88 + uni_modules/uv-empty/readme.md | 19 + uni_modules/uv-form/changelog.md | 23 + .../uv-form/components/uv-form-item/props.js | 49 + .../components/uv-form-item/uv-form-item.vue | 226 +++ .../uv-form/components/uv-form/props.js | 46 + .../uv-form/components/uv-form/uv-form.vue | 209 ++ .../uv-form/components/uv-form/valid.js | 1343 +++++++++++++ uni_modules/uv-form/package.json | 93 + uni_modules/uv-form/readme.md | 19 + uni_modules/uv-gap/changelog.md | 5 + uni_modules/uv-gap/components/uv-gap/props.js | 25 + .../uv-gap/components/uv-gap/uv-gap.vue | 36 + uni_modules/uv-gap/package.json | 87 + uni_modules/uv-gap/readme.md | 12 + uni_modules/uv-grid/changelog.md | 21 + .../uv-grid/components/uv-grid-item/props.js | 15 + .../components/uv-grid-item/uv-grid-item.vue | 226 +++ .../uv-grid/components/uv-grid/props.js | 20 + .../uv-grid/components/uv-grid/uv-grid.vue | 100 + uni_modules/uv-grid/package.json | 88 + uni_modules/uv-grid/readme.md | 17 + uni_modules/uv-icon/changelog.md | 31 + .../uv-icon/components/uv-icon/icons.js | 160 ++ .../uv-icon/components/uv-icon/props.js | 90 + .../uv-icon/components/uv-icon/uv-icon.vue | 226 +++ .../uv-icon/components/uv-icon/uvicons.ttf | Bin 0 -> 39632 bytes uni_modules/uv-icon/package.json | 83 + uni_modules/uv-icon/readme.md | 15 + uni_modules/uv-image/changelog.md | 36 + .../uv-image/components/uv-image/props.js | 95 + .../uv-image/components/uv-image/uv-image.vue | 287 +++ uni_modules/uv-image/package.json | 89 + uni_modules/uv-image/readme.md | 15 + uni_modules/uv-index-list/changelog.md | 18 + .../components/uv-index-anchor/props.js | 30 + .../uv-index-anchor/uv-index-anchor.vue | 98 + .../uv-index-item/uv-index-item.vue | 87 + .../components/uv-index-list/props.js | 30 + .../uv-index-list/uv-index-list.vue | 461 +++++ uni_modules/uv-index-list/package.json | 88 + uni_modules/uv-index-list/readme.md | 19 + uni_modules/uv-input/changelog.md | 29 + .../uv-input/components/uv-input/props.js | 175 ++ .../uv-input/components/uv-input/uv-input.vue | 348 ++++ uni_modules/uv-input/package.json | 88 + uni_modules/uv-input/readme.md | 19 + uni_modules/uv-keyboard/changelog.md | 17 + .../components/uv-keyboard-car/props.js | 24 + .../uv-keyboard-car/uv-keyboard-car.vue | 347 ++++ .../components/uv-keyboard-number/props.js | 19 + .../uv-keyboard-number/uv-keyboard-number.vue | 201 ++ .../components/uv-keyboard/props.js | 95 + .../components/uv-keyboard/uv-keyboard.vue | 180 ++ uni_modules/uv-keyboard/package.json | 89 + uni_modules/uv-keyboard/readme.md | 19 + uni_modules/uv-line-progress/changelog.md | 7 + .../components/uv-line-progress/props.js | 29 + .../uv-line-progress/uv-line-progress.vue | 146 ++ uni_modules/uv-line-progress/package.json | 87 + uni_modules/uv-line-progress/readme.md | 11 + uni_modules/uv-line/changelog.md | 5 + .../uv-line/components/uv-line/props.js | 34 + .../uv-line/components/uv-line/uv-line.vue | 60 + uni_modules/uv-line/package.json | 87 + uni_modules/uv-line/readme.md | 11 + uni_modules/uv-link/changelog.md | 7 + .../uv-link/components/uv-link/props.js | 40 + .../uv-link/components/uv-link/uv-link.vue | 83 + uni_modules/uv-link/package.json | 87 + uni_modules/uv-link/readme.md | 11 + uni_modules/uv-list/changelog.md | 25 + .../components/uv-list-item/uv-list-item.vue | 535 +++++ .../uv-list/components/uv-list/uv-list.vue | 147 ++ uni_modules/uv-list/package.json | 87 + uni_modules/uv-list/readme.md | 27 + uni_modules/uv-load-more/changelog.md | 7 + .../components/uv-load-more/props.js | 95 + .../components/uv-load-more/uv-load-more.vue | 152 ++ uni_modules/uv-load-more/package.json | 89 + uni_modules/uv-load-more/readme.md | 11 + uni_modules/uv-loading-icon/changelog.md | 9 + .../components/uv-loading-icon/props.js | 67 + .../uv-loading-icon/uv-loading-icon.vue | 347 ++++ uni_modules/uv-loading-icon/package.json | 87 + uni_modules/uv-loading-icon/readme.md | 19 + uni_modules/uv-loading-page/changelog.md | 11 + .../components/uv-loading-page/props.js | 55 + .../uv-loading-page/uv-loading-page.vue | 96 + uni_modules/uv-loading-page/package.json | 89 + uni_modules/uv-loading-page/readme.md | 11 + uni_modules/uv-modal/changelog.md | 28 + .../uv-modal/components/uv-modal/props.js | 90 + .../uv-modal/components/uv-modal/uv-modal.vue | 245 +++ uni_modules/uv-modal/package.json | 90 + uni_modules/uv-modal/readme.md | 23 + uni_modules/uv-navbar/changelog.md | 17 + .../uv-navbar/components/uv-navbar/props.js | 89 + .../components/uv-navbar/uv-navbar.vue | 245 +++ uni_modules/uv-navbar/package.json | 89 + uni_modules/uv-navbar/readme.md | 19 + uni_modules/uv-no-network/changelog.md | 5 + .../components/uv-no-network/props.js | 20 + .../uv-no-network/uv-no-network.vue | 222 +++ uni_modules/uv-no-network/package.json | 90 + uni_modules/uv-no-network/readme.md | 11 + uni_modules/uv-notice-bar/changelog.md | 19 + .../components/uv-column-notice/props.js | 61 + .../uv-column-notice/uv-column-notice.vue | 176 ++ .../components/uv-notice-bar/props.js | 76 + .../uv-notice-bar/uv-notice-bar.vue | 110 + .../components/uv-row-notice/props.js | 40 + .../uv-row-notice/uv-row-notice.vue | 341 ++++ uni_modules/uv-notice-bar/package.json | 88 + uni_modules/uv-notice-bar/readme.md | 19 + uni_modules/uv-notify/changelog.md | 9 + .../uv-notify/components/uv-notify/props.js | 45 + .../components/uv-notify/uv-notify.vue | 220 ++ uni_modules/uv-notify/package.json | 90 + uni_modules/uv-notify/readme.md | 11 + uni_modules/uv-number-box/changelog.md | 7 + .../components/uv-number-box/props.js | 113 ++ .../uv-number-box/uv-number-box.vue | 395 ++++ uni_modules/uv-number-box/package.json | 88 + uni_modules/uv-number-box/readme.md | 11 + uni_modules/uv-overlay/changelog.md | 9 + .../uv-overlay/components/uv-overlay/props.js | 25 + .../components/uv-overlay/uv-overlay.vue | 85 + uni_modules/uv-overlay/package.json | 88 + uni_modules/uv-overlay/readme.md | 11 + uni_modules/uv-parse/changelog.md | 13 + .../components/uv-parse/node/node.vue | 576 ++++++ .../uv-parse/components/uv-parse/parser.js | 1335 +++++++++++++ .../uv-parse/components/uv-parse/uv-parse.vue | 498 +++++ uni_modules/uv-parse/package.json | 87 + uni_modules/uv-parse/readme.md | 21 + .../static/app-plus/uv-parse/js/handler.js | 224 +++ .../app-plus/uv-parse/js/uni.webview.min.js | 19 + .../static/app-plus/uv-parse/local.html | 1 + uni_modules/uv-pick-color/changelog.md | 18 + .../components/uv-pick-color/colors.js | 217 ++ .../components/uv-pick-color/props.js | 47 + .../uv-pick-color/uv-pick-color.vue | 551 +++++ uni_modules/uv-pick-color/package.json | 89 + uni_modules/uv-pick-color/readme.md | 19 + uni_modules/uv-picker/changelog.md | 33 + .../uv-picker/components/uv-picker/props.js | 95 + .../components/uv-picker/uv-picker.vue | 330 +++ uni_modules/uv-picker/package.json | 90 + uni_modules/uv-picker/readme.md | 21 + uni_modules/uv-popup/changelog.md | 18 + .../uv-popup/components/uv-popup/keypress.js | 45 + .../uv-popup/components/uv-popup/uv-popup.vue | 539 +++++ uni_modules/uv-popup/package.json | 92 + uni_modules/uv-popup/readme.md | 21 + uni_modules/uv-qrcode/changelog.md | 13 + .../uv-qrcode/components/uv-qrcode/cache.js | 1 + .../uv-qrcode/gcanvas/bridge/bridge-weex.js | 241 +++ .../context-2d/FillStyleLinearGradient.js | 18 + .../gcanvas/context-2d/FillStylePattern.js | 8 + .../context-2d/FillStyleRadialGradient.js | 17 + .../gcanvas/context-2d/RenderingContext.js | 666 +++++++ .../gcanvas/context-webgl/ActiveInfo.js | 11 + .../uv-qrcode/gcanvas/context-webgl/Buffer.js | 21 + .../gcanvas/context-webgl/Framebuffer.js | 21 + .../uv-qrcode/gcanvas/context-webgl/GLenum.js | 298 +++ .../gcanvas/context-webgl/GLmethod.js | 142 ++ .../uv-qrcode/gcanvas/context-webgl/GLtype.js | 23 + .../gcanvas/context-webgl/Program.js | 21 + .../gcanvas/context-webgl/Renderbuffer.js | 21 + .../gcanvas/context-webgl/RenderingContext.js | 1191 +++++++++++ .../uv-qrcode/gcanvas/context-webgl/Shader.js | 22 + .../context-webgl/ShaderPrecisionFormat.js | 11 + .../gcanvas/context-webgl/Texture.js | 22 + .../gcanvas/context-webgl/UniformLocation.js | 22 + .../gcanvas/context-webgl/classUtils.js | 3 + .../uv-qrcode/gcanvas/env/canvas.js | 74 + .../components/uv-qrcode/gcanvas/env/image.js | 96 + .../components/uv-qrcode/gcanvas/env/tool.js | 24 + .../components/uv-qrcode/gcanvas/index.js | 39 + .../uv-qrcode/components/uv-qrcode/props.js | 85 + .../uv-qrcode/components/uv-qrcode/qrcode.js | 34 + .../uv-qrcode/components/uv-qrcode/queue.js | 41 + .../components/uv-qrcode/uv-qrcode.vue | 1038 ++++++++++ uni_modules/uv-qrcode/package.json | 87 + uni_modules/uv-qrcode/readme.md | 21 + uni_modules/uv-radio/changelog.md | 31 + .../components/uv-radio-group/props.js | 89 + .../uv-radio-group/uv-radio-group.vue | 115 ++ .../uv-radio/components/uv-radio/props.js | 65 + .../uv-radio/components/uv-radio/uv-radio.vue | 348 ++++ uni_modules/uv-radio/package.json | 88 + uni_modules/uv-radio/readme.md | 19 + uni_modules/uv-rate/changelog.md | 17 + .../uv-rate/components/uv-rate/props.js | 73 + .../uv-rate/components/uv-rate/uv-rate.vue | 274 +++ uni_modules/uv-rate/package.json | 88 + uni_modules/uv-rate/readme.md | 19 + uni_modules/uv-read-more/changelog.md | 7 + .../components/uv-read-more/props.js | 62 + .../components/uv-read-more/uv-read-more.vue | 162 ++ uni_modules/uv-read-more/package.json | 89 + uni_modules/uv-read-more/readme.md | 11 + uni_modules/uv-row/changelog.md | 5 + uni_modules/uv-row/components/uv-col/props.js | 30 + .../uv-row/components/uv-col/uv-col.vue | 165 ++ uni_modules/uv-row/components/uv-row/props.js | 20 + .../uv-row/components/uv-row/uv-row.vue | 95 + uni_modules/uv-row/package.json | 87 + uni_modules/uv-row/readme.md | 11 + uni_modules/uv-safe-bottom/changelog.md | 11 + .../uv-safe-bottom/uv-safe-bottom.vue | 67 + uni_modules/uv-safe-bottom/package.json | 87 + uni_modules/uv-safe-bottom/readme.md | 11 + uni_modules/uv-scroll-list/changelog.md | 12 + .../components/uv-scroll-list/nvue.js | 29 + .../components/uv-scroll-list/props.js | 35 + .../components/uv-scroll-list/scrollWxs.wxs | 51 + .../uv-scroll-list/uv-scroll-list.vue | 218 ++ uni_modules/uv-scroll-list/package.json | 87 + uni_modules/uv-scroll-list/readme.md | 19 + uni_modules/uv-search/changelog.md | 25 + .../uv-search/components/uv-search/props.js | 127 ++ .../components/uv-search/uv-search.vue | 311 +++ uni_modules/uv-search/package.json | 89 + uni_modules/uv-search/readme.md | 19 + uni_modules/uv-skeleton/changelog.md | 9 + .../components/uv-skeleton/props.js | 65 + .../components/uv-skeleton/uv-skeleton.vue | 250 +++ uni_modules/uv-skeleton/package.json | 87 + uni_modules/uv-skeleton/readme.md | 11 + uni_modules/uv-skeletons/changelog.md | 4 + .../components/uv-skeletons/uv-skeletons.vue | 247 +++ uni_modules/uv-skeletons/package.json | 88 + uni_modules/uv-skeletons/readme.md | 23 + uni_modules/uv-slider/changelog.md | 9 + .../uv-slider/components/uv-slider/props.js | 58 + .../components/uv-slider/uv-slider.vue | 58 + uni_modules/uv-slider/package.json | 87 + uni_modules/uv-slider/readme.md | 15 + uni_modules/uv-status-bar/changelog.md | 7 + .../components/uv-status-bar/props.js | 8 + .../uv-status-bar/uv-status-bar.vue | 54 + uni_modules/uv-status-bar/package.json | 87 + uni_modules/uv-status-bar/readme.md | 10 + uni_modules/uv-steps/changelog.md | 10 + .../components/uv-steps-item/props.js | 25 + .../uv-steps-item/uv-steps-item.vue | 347 ++++ .../uv-steps/components/uv-steps/props.js | 40 + .../uv-steps/components/uv-steps/uv-steps.vue | 83 + uni_modules/uv-steps/package.json | 89 + uni_modules/uv-steps/readme.md | 11 + uni_modules/uv-sticky/changelog.md | 11 + .../uv-sticky/components/uv-sticky/props.js | 41 + .../components/uv-sticky/uv-sticky.vue | 223 +++ uni_modules/uv-sticky/package.json | 87 + uni_modules/uv-sticky/readme.md | 11 + uni_modules/uv-subsection/changelog.md | 10 + .../components/uv-subsection/props.js | 54 + .../uv-subsection/uv-subsection.vue | 269 +++ uni_modules/uv-subsection/package.json | 87 + uni_modules/uv-subsection/readme.md | 11 + uni_modules/uv-swipe-action/changelog.md | 11 + .../uv-swipe-action-item/index - backup.wxs | 256 +++ .../components/uv-swipe-action-item/index.wxs | 225 +++ .../uv-swipe-action-item/nvue - backup.js | 264 +++ .../components/uv-swipe-action-item/nvue.js | 182 ++ .../components/uv-swipe-action-item/props.js | 40 + .../uv-swipe-action-item.vue | 200 ++ .../components/uv-swipe-action-item/wxs.js | 15 + .../components/uv-swipe-action/props.js | 10 + .../uv-swipe-action/uv-swipe-action.vue | 65 + uni_modules/uv-swipe-action/package.json | 88 + uni_modules/uv-swipe-action/readme.md | 11 + uni_modules/uv-swiper/changelog.md | 16 + .../components/uv-swiper-indicator/props.js | 30 + .../uv-swiper-indicator.vue | 112 ++ .../uv-swiper/components/uv-swiper/props.js | 136 ++ .../components/uv-swiper/uv-swiper.vue | 263 +++ uni_modules/uv-swiper/package.json | 88 + uni_modules/uv-swiper/readme.md | 19 + uni_modules/uv-switch/changelog.md | 14 + .../uv-switch/components/uv-switch/props.js | 58 + .../components/uv-switch/uv-switch.vue | 192 ++ uni_modules/uv-switch/package.json | 88 + uni_modules/uv-switch/readme.md | 19 + uni_modules/uv-tabbar/changelog.md | 14 + .../components/uv-tabbar-item/props.js | 40 + .../uv-tabbar-item/uv-tabbar-item.vue | 146 ++ .../uv-tabbar/components/uv-tabbar/props.js | 50 + .../components/uv-tabbar/uv-tabbar.vue | 146 ++ uni_modules/uv-tabbar/package.json | 90 + uni_modules/uv-tabbar/readme.md | 21 + uni_modules/uv-tabs/changelog.md | 22 + .../uv-tabs/components/uv-tabs/props.js | 71 + .../uv-tabs/components/uv-tabs/uv-tabs.vue | 390 ++++ uni_modules/uv-tabs/package.json | 90 + uni_modules/uv-tabs/readme.md | 19 + uni_modules/uv-tags/changelog.md | 10 + .../uv-tags/components/uv-tags/props.js | 95 + .../uv-tags/components/uv-tags/uv-tags.vue | 379 ++++ uni_modules/uv-tags/package.json | 89 + uni_modules/uv-tags/readme.md | 11 + uni_modules/uv-text/changelog.md | 11 + .../uv-text/components/uv-text/props.js | 113 ++ .../uv-text/components/uv-text/uv-text.vue | 218 ++ .../uv-text/components/uv-text/value.js | 87 + uni_modules/uv-text/package.json | 89 + uni_modules/uv-text/readme.md | 17 + uni_modules/uv-textarea/changelog.md | 28 + .../components/uv-textarea/props.js | 138 ++ .../components/uv-textarea/uv-textarea.vue | 238 +++ uni_modules/uv-textarea/package.json | 87 + uni_modules/uv-textarea/readme.md | 19 + uni_modules/uv-toast/changelog.md | 10 + .../uv-toast/components/uv-toast/uv-toast.vue | 333 ++++ uni_modules/uv-toast/package.json | 90 + uni_modules/uv-toast/readme.md | 11 + uni_modules/uv-toolbar/changelog.md | 2 + .../uv-toolbar/components/uv-toolbar/props.js | 40 + .../components/uv-toolbar/uv-toolbar.vue | 109 + uni_modules/uv-toolbar/package.json | 87 + uni_modules/uv-toolbar/readme.md | 31 + uni_modules/uv-tooltip/changelog.md | 13 + .../uv-tooltip/components/uv-tooltip/props.js | 60 + .../components/uv-tooltip/uv-tooltip.vue | 372 ++++ uni_modules/uv-tooltip/package.json | 90 + uni_modules/uv-tooltip/readme.md | 11 + uni_modules/uv-transition/changelog.md | 19 + .../uv-transition/createAnimation.js | 131 ++ .../components/uv-transition/props.js | 31 + .../uv-transition/uv-transition.vue | 320 +++ uni_modules/uv-transition/package.json | 87 + uni_modules/uv-transition/readme.md | 15 + uni_modules/uv-ui-tools/changelog.md | 76 + .../components/uv-ui-tools/uv-ui-tools.vue | 6 + uni_modules/uv-ui-tools/index.js | 79 + uni_modules/uv-ui-tools/index.scss | 7 + uni_modules/uv-ui-tools/libs/config/config.js | 34 + uni_modules/uv-ui-tools/libs/css/color.scss | 32 + uni_modules/uv-ui-tools/libs/css/common.scss | 100 + .../uv-ui-tools/libs/css/components.scss | 23 + .../uv-ui-tools/libs/css/variable.scss | 111 ++ uni_modules/uv-ui-tools/libs/css/vue.scss | 40 + .../libs/function/colorGradient.js | 134 ++ .../uv-ui-tools/libs/function/debounce.js | 29 + .../uv-ui-tools/libs/function/digit.js | 167 ++ .../uv-ui-tools/libs/function/index.js | 734 +++++++ .../uv-ui-tools/libs/function/platform.js | 75 + uni_modules/uv-ui-tools/libs/function/test.js | 287 +++ .../uv-ui-tools/libs/function/throttle.js | 30 + .../libs/luch-request/adapters/index.js | 132 ++ .../luch-request/core/InterceptorManager.js | 51 + .../libs/luch-request/core/Request.js | 201 ++ .../libs/luch-request/core/buildFullPath.js | 20 + .../libs/luch-request/core/defaults.js | 33 + .../libs/luch-request/core/dispatchRequest.js | 6 + .../libs/luch-request/core/mergeConfig.js | 126 ++ .../libs/luch-request/core/settle.js | 16 + .../libs/luch-request/helpers/buildURL.js | 64 + .../libs/luch-request/helpers/combineURLs.js | 14 + .../luch-request/helpers/isAbsoluteURL.js | 14 + .../uv-ui-tools/libs/luch-request/index.d.ts | 197 ++ .../uv-ui-tools/libs/luch-request/index.js | 2 + .../uv-ui-tools/libs/luch-request/utils.js | 135 ++ .../libs/luch-request/utils/clone.js | 264 +++ uni_modules/uv-ui-tools/libs/mixin/button.js | 13 + uni_modules/uv-ui-tools/libs/mixin/mixin.js | 172 ++ uni_modules/uv-ui-tools/libs/mixin/mpMixin.js | 8 + uni_modules/uv-ui-tools/libs/mixin/mpShare.js | 13 + .../uv-ui-tools/libs/mixin/openType.js | 47 + uni_modules/uv-ui-tools/libs/mixin/touch.js | 59 + uni_modules/uv-ui-tools/libs/util/dayjs.js | 216 ++ uni_modules/uv-ui-tools/libs/util/route.js | 126 ++ uni_modules/uv-ui-tools/package.json | 81 + uni_modules/uv-ui-tools/readme.md | 23 + uni_modules/uv-ui-tools/theme.scss | 43 + uni_modules/uv-ui/changelog.md | 353 ++++ uni_modules/uv-ui/components/uv-ui/uv-ui.vue | 7 + uni_modules/uv-ui/package.json | 162 ++ uni_modules/uv-ui/readme.md | 164 ++ uni_modules/uv-upload/changelog.md | 17 + .../uv-preview-video/uv-preview-video.vue | 52 + .../uv-upload/components/uv-upload/mixin.js | 22 + .../uv-upload/components/uv-upload/props.js | 130 ++ .../uv-upload/components/uv-upload/utils.js | 151 ++ .../components/uv-upload/uv-upload.vue | 492 +++++ uni_modules/uv-upload/package.json | 90 + uni_modules/uv-upload/readme.md | 11 + uni_modules/uv-vtabs/changelog.md | 20 + .../uv-vtabs-item/uv-vtabs-item.vue | 68 + .../uv-vtabs/components/uv-vtabs/props.js | 79 + .../uv-vtabs/components/uv-vtabs/uv-vtabs.vue | 438 ++++ uni_modules/uv-vtabs/package.json | 87 + uni_modules/uv-vtabs/readme.md | 19 + uni_modules/uv-waterfall/changelog.md | 24 + .../components/uv-waterfall/props.js | 69 + .../components/uv-waterfall/uv-waterfall.vue | 265 +++ uni_modules/uv-waterfall/package.json | 89 + uni_modules/uv-waterfall/readme.md | 19 + uni_modules/v-tabs/changelog.md | 143 ++ uni_modules/v-tabs/components/v-tabs/props.js | 104 + uni_modules/v-tabs/components/v-tabs/utils.js | 12 + .../v-tabs/components/v-tabs/v-tabs.vue | 296 +++ uni_modules/v-tabs/package.json | 84 + uni_modules/v-tabs/readme.md | 267 +++ utils/common.js | 278 +++ utils/map.js | 63 + utils/navigateTo.js | 17 + utils/request.js | 455 +++++ utils/storage.js | 46 + 1066 files changed, 141326 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 .hbuilderx/launch.json create mode 100644 Apis/book.js create mode 100644 Apis/clientCustomer.js create mode 100644 Apis/coupon.js create mode 100644 Apis/goodsList.js create mode 100644 Apis/home.js create mode 100644 Apis/invoice.js create mode 100644 Apis/lock.js create mode 100644 Apis/login.js create mode 100644 Apis/order.js create mode 100644 Apis/recommend.js create mode 100644 Apis/site.js create mode 100644 Apis/validInfo.js create mode 100644 App.vue create mode 100644 components/AgreementCheck.vue create mode 100644 components/MediatorinviteDetail.vue create mode 100644 components/coupon.vue create mode 100644 components/inviteDetail.vue create mode 100644 components/my-dropdown.vue create mode 100644 components/myCustomtTabBar.vue create mode 100644 components/myModal.vue create mode 100644 components/myPopup.vue create mode 100644 components/myUpload.vue create mode 100644 components/navBar.vue create mode 100644 components/noToken.vue create mode 100644 components/siteDetail.vue create mode 100644 components/textEllipsis.vue create mode 100644 components/updatePopup.vue create mode 100644 components/uv-tabsSelf/props.js create mode 100644 components/uv-tabsSelf/uv-tabs.vue create mode 100644 components/wxNavbar.vue create mode 100644 config/index.js create mode 100644 hooks/index.js create mode 100644 hooks/useCountDown.js create mode 100644 hooks/useLocation.js create mode 100644 index.html create mode 100644 locale/en.json create mode 100644 locale/index.js create mode 100644 locale/ja.json create mode 100644 locale/messagesFunctions.js create mode 100644 locale/uni-app.ja.json create mode 100644 locale/zh-Hans.json create mode 100644 locale/zh-Hant.json create mode 100644 main.js create mode 100644 manifest.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pages.json create mode 100644 pages/book/book.vue create mode 100644 pages/book/index.vue create mode 100644 pages/book/map.vue create mode 100644 pages/book/mapmode.vue create mode 100644 pages/book/navigate.vue create mode 100644 pages/call/index.vue create mode 100644 pages/evaluate/index.vue create mode 100644 pages/facecode/facecode.vue create mode 100644 pages/forgotPawd/index.vue create mode 100644 pages/goodsList/index.vue create mode 100644 pages/index/index.vue create mode 100644 pages/invite/index.vue create mode 100644 pages/login/index.vue create mode 100644 pages/orderdetail/door.vue create mode 100644 pages/orderdetail/index.vue create mode 100644 pages/orderdetail/lock.vue create mode 100644 pages/personal/customerAi.vue create mode 100644 pages/personal/index.vue create mode 100644 pages/phone/index.vue create mode 100644 pages/register/index.vue create mode 100644 pages/renewOrder/index.vue create mode 100644 pages/setOrder/index.vue create mode 100644 pages/site/index.vue create mode 100644 pages/unlock/index.vue create mode 100644 pages/webview/web.vue create mode 100644 pagesb/AControl/index.vue create mode 100644 pagesb/Apis/flashSale.js create mode 100644 pagesb/activityDetail/index.vue create mode 100644 pagesb/changeUser/index.vue create mode 100644 pagesb/components/my-uv-collapse/changelog.md create mode 100644 pagesb/components/my-uv-collapse/components/uv-collapse-item/props.js create mode 100644 pagesb/components/my-uv-collapse/components/uv-collapse-item/uv-collapse-item.vue create mode 100644 pagesb/components/my-uv-collapse/components/uv-collapse/props.js create mode 100644 pagesb/components/my-uv-collapse/components/uv-collapse/uv-collapse.vue create mode 100644 pagesb/components/my-uv-collapse/package.json create mode 100644 pagesb/components/qf-image-cropper/changelog.md create mode 100644 pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.render.js create mode 100644 pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.vue create mode 100644 pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.wxs create mode 100644 pagesb/components/qf-image-cropper/package.json create mode 100644 pagesb/components/qf-image-cropper/readme.md create mode 100644 pagesb/flashSale/index.vue create mode 100644 pagesb/houseKey/index.vue create mode 100644 pagesb/initLock/index.vue create mode 100644 pagesb/initLock/lockInitApi.js create mode 100644 pagesb/invitation/index.vue create mode 100644 pagesb/invoice/index.vue create mode 100644 pagesb/invoiceApply/index.vue create mode 100644 pagesb/invoiceApplyforRecord/index.vue create mode 100644 pagesb/latestEvents/index.vue create mode 100644 pagesb/maskUser/index.vue create mode 100644 pagesb/pointsMall/index.vue create mode 100644 pagesb/referrerInfo/index.vue create mode 100644 pagesb/reserve/index.vue create mode 100644 pagesb/unittypeDetail/index.vue create mode 100644 pagesb/userguide/index.vue create mode 100644 pagesb/validationInfo/index.vue create mode 100644 pagesb/videoTutorial/index.vue create mode 100644 static/book/noSelectMapIcon.png create mode 100644 static/book/return.png create mode 100644 static/book/selectMapIcon.png create mode 100644 static/customicons.css create mode 100644 static/customicons.ttf create mode 100644 static/evaluate/addPic.png create mode 100644 static/evaluate/image.png create mode 100644 static/home/address.png create mode 100644 static/home/address.svg create mode 100644 static/home/appointment.png create mode 100644 static/home/area.png create mode 100644 static/home/bus.png create mode 100644 static/home/left.png create mode 100644 static/home/region.png create mode 100644 static/home/right.png create mode 100644 static/home/shichang_logo.png create mode 100644 static/home/siteicon.svg create mode 100644 static/home/siteicon2.svg create mode 100644 static/iconfont/iconfont.css create mode 100644 static/orderdetail/refresh.png create mode 100644 static/personal/bottom-bg.png create mode 100644 static/personal/head.png create mode 100644 static/personal/id01.png create mode 100644 static/personal/id02.png create mode 100644 static/personal/id03.png create mode 100644 static/personal/mes.png create mode 100644 static/personal/share.png create mode 100644 static/personal/userimg.png create mode 100644 static/personal/warning.png create mode 100644 static/setOrder/fire.png create mode 100644 static/setOrder/selectArrow.png create mode 100644 static/site/hot.svg create mode 100644 static/site/map.svg create mode 100644 static/style/theme.scss create mode 100644 static/tabbar/book.png create mode 100644 static/tabbar/call.png create mode 100644 static/tabbar/home.svg create mode 100644 static/tabbar/index.png create mode 100644 static/tabbar/order.svg create mode 100644 static/tabbar/unlock.png create mode 100644 static/tabbar/user.svg create mode 100644 store/index.js create mode 100644 uni.scss create mode 100644 uni_modules/no-data/changelog.md create mode 100644 uni_modules/no-data/components/no-data/i18n/en.json create mode 100644 uni_modules/no-data/components/no-data/i18n/index.js create mode 100644 uni_modules/no-data/components/no-data/i18n/ja.json create mode 100644 uni_modules/no-data/components/no-data/i18n/zh-Hans.json create mode 100644 uni_modules/no-data/components/no-data/i18n/zh-Hant.json create mode 100644 uni_modules/no-data/components/no-data/no-data.vue create mode 100644 uni_modules/no-data/package.json create mode 100644 uni_modules/no-data/readme.md create mode 100644 uni_modules/uni-badge/changelog.md create mode 100644 uni_modules/uni-badge/components/uni-badge/uni-badge.vue create mode 100644 uni_modules/uni-badge/package.json create mode 100644 uni_modules/uni-badge/readme.md create mode 100644 uni_modules/uni-breadcrumb/changelog.md create mode 100644 uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue create mode 100644 uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue create mode 100644 uni_modules/uni-breadcrumb/package.json create mode 100644 uni_modules/uni-breadcrumb/readme.md create mode 100644 uni_modules/uni-calendar/changelog.md create mode 100644 uni_modules/uni-calendar/components/uni-calendar/calendar.js create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/en.json create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/index.js create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json create mode 100644 uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json create mode 100644 uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue create mode 100644 uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue create mode 100644 uni_modules/uni-calendar/components/uni-calendar/util.js create mode 100644 uni_modules/uni-calendar/package.json create mode 100644 uni_modules/uni-calendar/readme.md create mode 100644 uni_modules/uni-card/changelog.md create mode 100644 uni_modules/uni-card/components/uni-card/uni-card.vue create mode 100644 uni_modules/uni-card/package.json create mode 100644 uni_modules/uni-card/readme.md create mode 100644 uni_modules/uni-collapse/changelog.md create mode 100644 uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue create mode 100644 uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue create mode 100644 uni_modules/uni-collapse/package.json create mode 100644 uni_modules/uni-collapse/readme.md create mode 100644 uni_modules/uni-combox/changelog.md create mode 100644 uni_modules/uni-combox/components/uni-combox/uni-combox.vue create mode 100644 uni_modules/uni-combox/package.json create mode 100644 uni_modules/uni-combox/readme.md create mode 100644 uni_modules/uni-countdown/changelog.md create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/en.json create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/index.js create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json create mode 100644 uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json create mode 100644 uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue create mode 100644 uni_modules/uni-countdown/package.json create mode 100644 uni_modules/uni-countdown/readme.md create mode 100644 uni_modules/uni-data-checkbox/changelog.md create mode 100644 uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue create mode 100644 uni_modules/uni-data-checkbox/package.json create mode 100644 uni_modules/uni-data-checkbox/readme.md create mode 100644 uni_modules/uni-data-picker/changelog.md create mode 100644 uni_modules/uni-data-picker/components/uni-data-picker/keypress.js create mode 100644 uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue create mode 100644 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js create mode 100644 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue create mode 100644 uni_modules/uni-data-picker/package.json create mode 100644 uni_modules/uni-data-picker/readme.md create mode 100644 uni_modules/uni-data-select/changelog.md create mode 100644 uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue create mode 100644 uni_modules/uni-data-select/package.json create mode 100644 uni_modules/uni-data-select/readme.md create mode 100644 uni_modules/uni-dateformat/changelog.md create mode 100644 uni_modules/uni-dateformat/components/uni-dateformat/date-format.js create mode 100644 uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue create mode 100644 uni_modules/uni-dateformat/package.json create mode 100644 uni_modules/uni-dateformat/readme.md create mode 100644 uni_modules/uni-datetime-picker/changelog.md create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue create mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js create mode 100644 uni_modules/uni-datetime-picker/package.json create mode 100644 uni_modules/uni-datetime-picker/readme.md create mode 100644 uni_modules/uni-drawer/changelog.md create mode 100644 uni_modules/uni-drawer/components/uni-drawer/keypress.js create mode 100644 uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue create mode 100644 uni_modules/uni-drawer/package.json create mode 100644 uni_modules/uni-drawer/readme.md create mode 100644 uni_modules/uni-easyinput/changelog.md create mode 100644 uni_modules/uni-easyinput/components/uni-easyinput/common.js create mode 100644 uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue create mode 100644 uni_modules/uni-easyinput/package.json create mode 100644 uni_modules/uni-easyinput/readme.md create mode 100644 uni_modules/uni-fab/changelog.md create mode 100644 uni_modules/uni-fab/components/uni-fab/uni-fab.vue create mode 100644 uni_modules/uni-fab/package.json create mode 100644 uni_modules/uni-fab/readme.md create mode 100644 uni_modules/uni-fav/changelog.md create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/en.json create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/index.js create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json create mode 100644 uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json create mode 100644 uni_modules/uni-fav/components/uni-fav/uni-fav.vue create mode 100644 uni_modules/uni-fav/package.json create mode 100644 uni_modules/uni-fav/readme.md create mode 100644 uni_modules/uni-file-picker/changelog.md create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/utils.js create mode 100644 uni_modules/uni-file-picker/package.json create mode 100644 uni_modules/uni-file-picker/readme.md create mode 100644 uni_modules/uni-forms/changelog.md create mode 100644 uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue create mode 100644 uni_modules/uni-forms/components/uni-forms/uni-forms.vue create mode 100644 uni_modules/uni-forms/components/uni-forms/utils.js create mode 100644 uni_modules/uni-forms/components/uni-forms/validate.js create mode 100644 uni_modules/uni-forms/package.json create mode 100644 uni_modules/uni-forms/readme.md create mode 100644 uni_modules/uni-goods-nav/changelog.md create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/en.json create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/index.js create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hans.json create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/i18n/zh-Hant.json create mode 100644 uni_modules/uni-goods-nav/components/uni-goods-nav/uni-goods-nav.vue create mode 100644 uni_modules/uni-goods-nav/package.json create mode 100644 uni_modules/uni-goods-nav/readme.md create mode 100644 uni_modules/uni-grid/changelog.md create mode 100644 uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue create mode 100644 uni_modules/uni-grid/components/uni-grid/uni-grid.vue create mode 100644 uni_modules/uni-grid/package.json create mode 100644 uni_modules/uni-grid/readme.md create mode 100644 uni_modules/uni-group/changelog.md create mode 100644 uni_modules/uni-group/components/uni-group/uni-group.vue create mode 100644 uni_modules/uni-group/package.json create mode 100644 uni_modules/uni-group/readme.md create mode 100644 uni_modules/uni-icons/changelog.md create mode 100644 uni_modules/uni-icons/components/uni-icons/icons.js create mode 100644 uni_modules/uni-icons/components/uni-icons/uni-icons.vue create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.css create mode 100644 uni_modules/uni-icons/components/uni-icons/uniicons.ttf create mode 100644 uni_modules/uni-icons/package.json create mode 100644 uni_modules/uni-icons/readme.md create mode 100644 uni_modules/uni-indexed-list/changelog.md create mode 100644 uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue create mode 100644 uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue create mode 100644 uni_modules/uni-indexed-list/package.json create mode 100644 uni_modules/uni-indexed-list/readme.md create mode 100644 uni_modules/uni-link/changelog.md create mode 100644 uni_modules/uni-link/components/uni-link/uni-link.vue create mode 100644 uni_modules/uni-link/package.json create mode 100644 uni_modules/uni-link/readme.md create mode 100644 uni_modules/uni-list/changelog.md create mode 100644 uni_modules/uni-list/components/uni-list-ad/uni-list-ad.vue create mode 100644 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.scss create mode 100644 uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue create mode 100644 uni_modules/uni-list/components/uni-list-item/uni-list-item.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-list.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-refresh.vue create mode 100644 uni_modules/uni-list/components/uni-list/uni-refresh.wxs create mode 100644 uni_modules/uni-list/package.json create mode 100644 uni_modules/uni-list/readme.md create mode 100644 uni_modules/uni-load-more/changelog.md create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/en.json create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/index.js create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json create mode 100644 uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json create mode 100644 uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue create mode 100644 uni_modules/uni-load-more/package.json create mode 100644 uni_modules/uni-load-more/readme.md create mode 100644 uni_modules/uni-nav-bar/changelog.md create mode 100644 uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue create mode 100644 uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue create mode 100644 uni_modules/uni-nav-bar/package.json create mode 100644 uni_modules/uni-nav-bar/readme.md create mode 100644 uni_modules/uni-notice-bar/changelog.md create mode 100644 uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue create mode 100644 uni_modules/uni-notice-bar/package.json create mode 100644 uni_modules/uni-notice-bar/readme.md create mode 100644 uni_modules/uni-number-box/changelog.md create mode 100644 uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue create mode 100644 uni_modules/uni-number-box/package.json create mode 100644 uni_modules/uni-number-box/readme.md create mode 100644 uni_modules/uni-pagination/changelog.md create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/en.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/es.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/fr.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/index.js create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hans.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/i18n/zh-Hant.json create mode 100644 uni_modules/uni-pagination/components/uni-pagination/uni-pagination.vue create mode 100644 uni_modules/uni-pagination/package.json create mode 100644 uni_modules/uni-pagination/readme.md create mode 100644 uni_modules/uni-popup/changelog.md create mode 100644 uni_modules/uni-popup/components/uni-popup-dialog/keypress.js create mode 100644 uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue create mode 100644 uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue create mode 100644 uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/en.json create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/index.js create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json create mode 100644 uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json create mode 100644 uni_modules/uni-popup/components/uni-popup/keypress.js create mode 100644 uni_modules/uni-popup/components/uni-popup/popup.js create mode 100644 uni_modules/uni-popup/components/uni-popup/uni-popup.vue create mode 100644 uni_modules/uni-popup/package.json create mode 100644 uni_modules/uni-popup/readme.md create mode 100644 uni_modules/uni-rate/changelog.md create mode 100644 uni_modules/uni-rate/components/uni-rate/uni-rate.vue create mode 100644 uni_modules/uni-rate/package.json create mode 100644 uni_modules/uni-rate/readme.md create mode 100644 uni_modules/uni-row/changelog.md create mode 100644 uni_modules/uni-row/components/uni-col/uni-col.vue create mode 100644 uni_modules/uni-row/components/uni-row/uni-row.vue create mode 100644 uni_modules/uni-row/package.json create mode 100644 uni_modules/uni-row/readme.md create mode 100644 uni_modules/uni-scss/changelog.md create mode 100644 uni_modules/uni-scss/index.scss create mode 100644 uni_modules/uni-scss/package.json create mode 100644 uni_modules/uni-scss/readme.md create mode 100644 uni_modules/uni-scss/styles/index.scss create mode 100644 uni_modules/uni-scss/styles/setting/_border.scss create mode 100644 uni_modules/uni-scss/styles/setting/_color.scss create mode 100644 uni_modules/uni-scss/styles/setting/_radius.scss create mode 100644 uni_modules/uni-scss/styles/setting/_space.scss create mode 100644 uni_modules/uni-scss/styles/setting/_styles.scss create mode 100644 uni_modules/uni-scss/styles/setting/_text.scss create mode 100644 uni_modules/uni-scss/styles/setting/_variables.scss create mode 100644 uni_modules/uni-scss/styles/tools/functions.scss create mode 100644 uni_modules/uni-scss/theme.scss create mode 100644 uni_modules/uni-scss/variables.scss create mode 100644 uni_modules/uni-search-bar/changelog.md create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/en.json create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/index.js create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json create mode 100644 uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue create mode 100644 uni_modules/uni-search-bar/package.json create mode 100644 uni_modules/uni-search-bar/readme.md create mode 100644 uni_modules/uni-section/changelog.md create mode 100644 uni_modules/uni-section/components/uni-section/uni-section.vue create mode 100644 uni_modules/uni-section/package.json create mode 100644 uni_modules/uni-section/readme.md create mode 100644 uni_modules/uni-segmented-control/changelog.md create mode 100644 uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue create mode 100644 uni_modules/uni-segmented-control/package.json create mode 100644 uni_modules/uni-segmented-control/readme.md create mode 100644 uni_modules/uni-steps/changelog.md create mode 100644 uni_modules/uni-steps/components/uni-steps/uni-steps.vue create mode 100644 uni_modules/uni-steps/package.json create mode 100644 uni_modules/uni-steps/readme.md create mode 100644 uni_modules/uni-swipe-action/changelog.md create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue create mode 100644 uni_modules/uni-swipe-action/package.json create mode 100644 uni_modules/uni-swipe-action/readme.md create mode 100644 uni_modules/uni-swiper-dot/changelog.md create mode 100644 uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue create mode 100644 uni_modules/uni-swiper-dot/package.json create mode 100644 uni_modules/uni-swiper-dot/readme.md create mode 100644 uni_modules/uni-table/changelog.md create mode 100644 uni_modules/uni-table/components/uni-table/uni-table.vue create mode 100644 uni_modules/uni-table/components/uni-tbody/uni-tbody.vue create mode 100644 uni_modules/uni-table/components/uni-td/uni-td.vue create mode 100644 uni_modules/uni-table/components/uni-th/filter-dropdown.vue create mode 100644 uni_modules/uni-table/components/uni-th/uni-th.vue create mode 100644 uni_modules/uni-table/components/uni-thead/uni-thead.vue create mode 100644 uni_modules/uni-table/components/uni-tr/table-checkbox.vue create mode 100644 uni_modules/uni-table/components/uni-tr/uni-tr.vue create mode 100644 uni_modules/uni-table/i18n/en.json create mode 100644 uni_modules/uni-table/i18n/es.json create mode 100644 uni_modules/uni-table/i18n/fr.json create mode 100644 uni_modules/uni-table/i18n/index.js create mode 100644 uni_modules/uni-table/i18n/zh-Hans.json create mode 100644 uni_modules/uni-table/i18n/zh-Hant.json create mode 100644 uni_modules/uni-table/package.json create mode 100644 uni_modules/uni-table/readme.md create mode 100644 uni_modules/uni-tag/changelog.md create mode 100644 uni_modules/uni-tag/components/uni-tag/uni-tag.vue create mode 100644 uni_modules/uni-tag/package.json create mode 100644 uni_modules/uni-tag/readme.md create mode 100644 uni_modules/uni-test/changelog.md create mode 100644 uni_modules/uni-test/components/uni-test/uni-test.vue create mode 100644 uni_modules/uni-test/package.json create mode 100644 uni_modules/uni-test/readme.md create mode 100644 uni_modules/uni-title/changelog.md create mode 100644 uni_modules/uni-title/components/uni-title/uni-title.vue create mode 100644 uni_modules/uni-title/package.json create mode 100644 uni_modules/uni-title/readme.md create mode 100644 uni_modules/uni-tooltip/changelog.md create mode 100644 uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue create mode 100644 uni_modules/uni-tooltip/package.json create mode 100644 uni_modules/uni-tooltip/readme.md create mode 100644 uni_modules/uni-transition/changelog.md create mode 100644 uni_modules/uni-transition/components/uni-transition/createAnimation.js create mode 100644 uni_modules/uni-transition/components/uni-transition/uni-transition.vue create mode 100644 uni_modules/uni-transition/package.json create mode 100644 uni_modules/uni-transition/readme.md create mode 100644 uni_modules/uni-ui/changelog.md create mode 100644 uni_modules/uni-ui/components/uni-badge/uni-badge.vue create mode 100644 uni_modules/uni-ui/components/uni-calendar/calendar.js create mode 100644 uni_modules/uni-ui/components/uni-calendar/uni-calendar-item.vue create mode 100644 uni_modules/uni-ui/components/uni-calendar/uni-calendar.vue create mode 100644 uni_modules/uni-ui/components/uni-calendar/util.js create mode 100644 uni_modules/uni-ui/components/uni-card/uni-card.vue create mode 100644 uni_modules/uni-ui/components/uni-collapse-item/uni-collapse-item.vue create mode 100644 uni_modules/uni-ui/components/uni-collapse/uni-collapse.vue create mode 100644 uni_modules/uni-ui/components/uni-combox/uni-combox.vue create mode 100644 uni_modules/uni-ui/components/uni-countdown/uni-countdown.vue create mode 100644 uni_modules/uni-ui/components/uni-data-checkbox/clientdb.js create mode 100644 uni_modules/uni-ui/components/uni-data-checkbox/uni-data-checkbox.vue create mode 100644 uni_modules/uni-ui/components/uni-dateformat/date-format.js create mode 100644 uni_modules/uni-ui/components/uni-dateformat/uni-dateformat.vue create mode 100644 uni_modules/uni-ui/components/uni-datetime-picker/uni-datetime-picker.vue create mode 100644 uni_modules/uni-ui/components/uni-drawer/uni-drawer.vue create mode 100644 uni_modules/uni-ui/components/uni-easyinput/common.js create mode 100644 uni_modules/uni-ui/components/uni-easyinput/uni-easyinput.vue create mode 100644 uni_modules/uni-ui/components/uni-fab/uni-fab.vue create mode 100644 uni_modules/uni-ui/components/uni-fav/uni-fav.vue create mode 100644 uni_modules/uni-ui/components/uni-field/uni-field.vue create mode 100644 uni_modules/uni-ui/components/uni-forms-item/uni-forms-item.vue create mode 100644 uni_modules/uni-ui/components/uni-forms/uni-forms.vue create mode 100644 uni_modules/uni-ui/components/uni-forms/validate.js create mode 100644 uni_modules/uni-ui/components/uni-goods-nav/uni-goods-nav.vue create mode 100644 uni_modules/uni-ui/components/uni-grid-item/uni-grid-item.vue create mode 100644 uni_modules/uni-ui/components/uni-grid/uni-grid.vue create mode 100644 uni_modules/uni-ui/components/uni-group/uni-group.vue create mode 100644 uni_modules/uni-ui/components/uni-icons/icons.js create mode 100644 uni_modules/uni-ui/components/uni-icons/uni-icons.vue create mode 100644 uni_modules/uni-ui/components/uni-icons/uni.ttf create mode 100644 uni_modules/uni-ui/components/uni-indexed-list/uni-indexed-list-item.vue create mode 100644 uni_modules/uni-ui/components/uni-indexed-list/uni-indexed-list.vue create mode 100644 uni_modules/uni-ui/components/uni-link/uni-link.vue create mode 100644 uni_modules/uni-ui/components/uni-list-ad/uni-list-ad.vue create mode 100644 uni_modules/uni-ui/components/uni-list-chat/uni-list-chat.scss create mode 100644 uni_modules/uni-ui/components/uni-list-chat/uni-list-chat.vue create mode 100644 uni_modules/uni-ui/components/uni-list-item/uni-list-item.vue create mode 100644 uni_modules/uni-ui/components/uni-list/uni-list.vue create mode 100644 uni_modules/uni-ui/components/uni-list/uni-refresh.vue create mode 100644 uni_modules/uni-ui/components/uni-list/uni-refresh.wxs create mode 100644 uni_modules/uni-ui/components/uni-load-more/uni-load-more.vue create mode 100644 uni_modules/uni-ui/components/uni-nav-bar/uni-nav-bar.vue create mode 100644 uni_modules/uni-ui/components/uni-notice-bar/uni-notice-bar.vue create mode 100644 uni_modules/uni-ui/components/uni-number-box/uni-number-box.vue create mode 100644 uni_modules/uni-ui/components/uni-pagination/uni-pagination.vue create mode 100644 uni_modules/uni-ui/components/uni-popup-dialog/uni-popup-dialog.vue create mode 100644 uni_modules/uni-ui/components/uni-popup-message/uni-popup-message.vue create mode 100644 uni_modules/uni-ui/components/uni-popup-share/uni-popup-share.vue create mode 100644 uni_modules/uni-ui/components/uni-popup/message.js create mode 100644 uni_modules/uni-ui/components/uni-popup/popup.js create mode 100644 uni_modules/uni-ui/components/uni-popup/share.js create mode 100644 uni_modules/uni-ui/components/uni-popup/uni-popup.vue create mode 100644 uni_modules/uni-ui/components/uni-rate/uni-rate.vue create mode 100644 uni_modules/uni-ui/components/uni-search-bar/uni-search-bar.vue create mode 100644 uni_modules/uni-ui/components/uni-section/uni-section.vue create mode 100644 uni_modules/uni-ui/components/uni-segmented-control/uni-segmented-control.vue create mode 100644 uni_modules/uni-ui/components/uni-status-bar/uni-status-bar.vue create mode 100644 uni_modules/uni-ui/components/uni-steps/uni-steps.vue create mode 100644 uni_modules/uni-ui/components/uni-swipe-action-item/bindingx.js create mode 100644 uni_modules/uni-ui/components/uni-swipe-action-item/index.wxs create mode 100644 uni_modules/uni-ui/components/uni-swipe-action-item/mpalipay.js create mode 100644 uni_modules/uni-ui/components/uni-swipe-action-item/mpother.js create mode 100644 uni_modules/uni-ui/components/uni-swipe-action-item/mpwxs.js create mode 100644 uni_modules/uni-ui/components/uni-swipe-action-item/uni-swipe-action-item.vue create mode 100644 uni_modules/uni-ui/components/uni-swipe-action/uni-swipe-action.vue create mode 100644 uni_modules/uni-ui/components/uni-swiper-dot/uni-swiper-dot.vue create mode 100644 uni_modules/uni-ui/components/uni-table/uni-table.vue create mode 100644 uni_modules/uni-ui/components/uni-tag/uni-tag.vue create mode 100644 uni_modules/uni-ui/components/uni-td/uni-td.vue create mode 100644 uni_modules/uni-ui/components/uni-test/uni-test.vue create mode 100644 uni_modules/uni-ui/components/uni-th/uni-th.vue create mode 100644 uni_modules/uni-ui/components/uni-title/uni-title.vue create mode 100644 uni_modules/uni-ui/components/uni-tr/uni-tr.vue create mode 100644 uni_modules/uni-ui/components/uni-transition/uni-transition.vue create mode 100644 uni_modules/uni-ui/components/uni-ui/uni-ui.vue create mode 100644 uni_modules/uni-ui/manifest.json create mode 100644 uni_modules/uni-ui/package.json create mode 100644 uni_modules/uni-ui/readme.md create mode 100644 uni_modules/uv-action-sheet/changelog.md create mode 100644 uni_modules/uv-action-sheet/components/uv-action-sheet/props.js create mode 100644 uni_modules/uv-action-sheet/components/uv-action-sheet/uv-action-sheet.vue create mode 100644 uni_modules/uv-action-sheet/package.json create mode 100644 uni_modules/uv-action-sheet/readme.md create mode 100644 uni_modules/uv-album/changelog.md create mode 100644 uni_modules/uv-album/components/uv-album/uv-album.vue create mode 100644 uni_modules/uv-album/package.json create mode 100644 uni_modules/uv-album/readme.md create mode 100644 uni_modules/uv-alert/changelog.md create mode 100644 uni_modules/uv-alert/components/uv-alert/props.js create mode 100644 uni_modules/uv-alert/components/uv-alert/uv-alert.vue create mode 100644 uni_modules/uv-alert/package.json create mode 100644 uni_modules/uv-alert/readme.md create mode 100644 uni_modules/uv-avatar/changelog.md create mode 100644 uni_modules/uv-avatar/components/uv-avatar-group/props.js create mode 100644 uni_modules/uv-avatar/components/uv-avatar-group/uv-avatar-group.vue create mode 100644 uni_modules/uv-avatar/components/uv-avatar/props.js create mode 100644 uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue create mode 100644 uni_modules/uv-avatar/package.json create mode 100644 uni_modules/uv-avatar/readme.md create mode 100644 uni_modules/uv-back-top/changelog.md create mode 100644 uni_modules/uv-back-top/components/uv-back-top/props.js create mode 100644 uni_modules/uv-back-top/components/uv-back-top/uv-back-top.vue create mode 100644 uni_modules/uv-back-top/package.json create mode 100644 uni_modules/uv-back-top/readme.md create mode 100644 uni_modules/uv-badge/changelog.md create mode 100644 uni_modules/uv-badge/components/uv-badge/props.js create mode 100644 uni_modules/uv-badge/components/uv-badge/uv-badge.vue create mode 100644 uni_modules/uv-badge/package.json create mode 100644 uni_modules/uv-badge/readme.md create mode 100644 uni_modules/uv-button/changelog.md create mode 100644 uni_modules/uv-button/components/uv-button/nvue.scss create mode 100644 uni_modules/uv-button/components/uv-button/props.js create mode 100644 uni_modules/uv-button/components/uv-button/uv-button.vue create mode 100644 uni_modules/uv-button/components/uv-button/vue.scss create mode 100644 uni_modules/uv-button/package.json create mode 100644 uni_modules/uv-button/readme.md create mode 100644 uni_modules/uv-calendar/changelog.md create mode 100644 uni_modules/uv-calendar/components/uv-calendar/calendar.js create mode 100644 uni_modules/uv-calendar/components/uv-calendar/header.vue create mode 100644 uni_modules/uv-calendar/components/uv-calendar/month.vue create mode 100644 uni_modules/uv-calendar/components/uv-calendar/props.js create mode 100644 uni_modules/uv-calendar/components/uv-calendar/uv-calendar.vue create mode 100644 uni_modules/uv-calendar/package.json create mode 100644 uni_modules/uv-calendar/readme.md create mode 100644 uni_modules/uv-calendars/changelog.md create mode 100644 uni_modules/uv-calendars/components/uv-calendars/calendar-body.vue create mode 100644 uni_modules/uv-calendars/components/uv-calendars/calendar-item.vue create mode 100644 uni_modules/uv-calendars/components/uv-calendars/calendar.js create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/en.json create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/index.js create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hans.json create mode 100644 uni_modules/uv-calendars/components/uv-calendars/i18n/zh-Hant.json create mode 100644 uni_modules/uv-calendars/components/uv-calendars/util.js create mode 100644 uni_modules/uv-calendars/components/uv-calendars/uv-calendars.vue create mode 100644 uni_modules/uv-calendars/package.json create mode 100644 uni_modules/uv-calendars/readme.md create mode 100644 uni_modules/uv-cell/changelog.md create mode 100644 uni_modules/uv-cell/components/uv-cell-group/props.js create mode 100644 uni_modules/uv-cell/components/uv-cell-group/uv-cell-group.vue create mode 100644 uni_modules/uv-cell/components/uv-cell/props.js create mode 100644 uni_modules/uv-cell/components/uv-cell/uv-cell.vue create mode 100644 uni_modules/uv-cell/package.json create mode 100644 uni_modules/uv-cell/readme.md create mode 100644 uni_modules/uv-checkbox/changelog.md create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox-group/props.js create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox-group/uv-checkbox-group.vue create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox/props.js create mode 100644 uni_modules/uv-checkbox/components/uv-checkbox/uv-checkbox.vue create mode 100644 uni_modules/uv-checkbox/package.json create mode 100644 uni_modules/uv-checkbox/readme.md create mode 100644 uni_modules/uv-code-input/changelog.md create mode 100644 uni_modules/uv-code-input/components/uv-code-input/props.js create mode 100644 uni_modules/uv-code-input/components/uv-code-input/uv-code-input.vue create mode 100644 uni_modules/uv-code-input/package.json create mode 100644 uni_modules/uv-code-input/readme.md create mode 100644 uni_modules/uv-code/changelog.md create mode 100644 uni_modules/uv-code/components/uv-code/props.js create mode 100644 uni_modules/uv-code/components/uv-code/uv-code.vue create mode 100644 uni_modules/uv-code/package.json create mode 100644 uni_modules/uv-code/readme.md create mode 100644 uni_modules/uv-collapse/changelog.md create mode 100644 uni_modules/uv-collapse/components/uv-collapse-item/props.js create mode 100644 uni_modules/uv-collapse/components/uv-collapse-item/uv-collapse-item.vue create mode 100644 uni_modules/uv-collapse/components/uv-collapse/props.js create mode 100644 uni_modules/uv-collapse/components/uv-collapse/uv-collapse.vue create mode 100644 uni_modules/uv-collapse/package.json create mode 100644 uni_modules/uv-collapse/readme.md create mode 100644 uni_modules/uv-count-down/changelog.md create mode 100644 uni_modules/uv-count-down/components/uv-count-down/props.js create mode 100644 uni_modules/uv-count-down/components/uv-count-down/utils.js create mode 100644 uni_modules/uv-count-down/components/uv-count-down/uv-count-down.vue create mode 100644 uni_modules/uv-count-down/package.json create mode 100644 uni_modules/uv-count-down/readme.md create mode 100644 uni_modules/uv-count-to/changelog.md create mode 100644 uni_modules/uv-count-to/components/uv-count-to/props.js create mode 100644 uni_modules/uv-count-to/components/uv-count-to/uv-count-to.vue create mode 100644 uni_modules/uv-count-to/package.json create mode 100644 uni_modules/uv-count-to/readme.md create mode 100644 uni_modules/uv-datetime-picker/changelog.md create mode 100644 uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js create mode 100644 uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue create mode 100644 uni_modules/uv-datetime-picker/package.json create mode 100644 uni_modules/uv-datetime-picker/readme.md create mode 100644 uni_modules/uv-divider/changelog.md create mode 100644 uni_modules/uv-divider/components/uv-divider/props.js create mode 100644 uni_modules/uv-divider/components/uv-divider/uv-divider.vue create mode 100644 uni_modules/uv-divider/package.json create mode 100644 uni_modules/uv-divider/readme.md create mode 100644 uni_modules/uv-drop-down/changelog.md create mode 100644 uni_modules/uv-drop-down/components/uv-drop-down-item/uv-drop-down-item.vue create mode 100644 uni_modules/uv-drop-down/components/uv-drop-down-popup/uv-drop-down-popup.vue create mode 100644 uni_modules/uv-drop-down/components/uv-drop-down/uv-drop-down.vue create mode 100644 uni_modules/uv-drop-down/package.json create mode 100644 uni_modules/uv-drop-down/readme.md create mode 100644 uni_modules/uv-empty/changelog.md create mode 100644 uni_modules/uv-empty/components/uv-empty/props.js create mode 100644 uni_modules/uv-empty/components/uv-empty/uv-empty.vue create mode 100644 uni_modules/uv-empty/package.json create mode 100644 uni_modules/uv-empty/readme.md create mode 100644 uni_modules/uv-form/changelog.md create mode 100644 uni_modules/uv-form/components/uv-form-item/props.js create mode 100644 uni_modules/uv-form/components/uv-form-item/uv-form-item.vue create mode 100644 uni_modules/uv-form/components/uv-form/props.js create mode 100644 uni_modules/uv-form/components/uv-form/uv-form.vue create mode 100644 uni_modules/uv-form/components/uv-form/valid.js create mode 100644 uni_modules/uv-form/package.json create mode 100644 uni_modules/uv-form/readme.md create mode 100644 uni_modules/uv-gap/changelog.md create mode 100644 uni_modules/uv-gap/components/uv-gap/props.js create mode 100644 uni_modules/uv-gap/components/uv-gap/uv-gap.vue create mode 100644 uni_modules/uv-gap/package.json create mode 100644 uni_modules/uv-gap/readme.md create mode 100644 uni_modules/uv-grid/changelog.md create mode 100644 uni_modules/uv-grid/components/uv-grid-item/props.js create mode 100644 uni_modules/uv-grid/components/uv-grid-item/uv-grid-item.vue create mode 100644 uni_modules/uv-grid/components/uv-grid/props.js create mode 100644 uni_modules/uv-grid/components/uv-grid/uv-grid.vue create mode 100644 uni_modules/uv-grid/package.json create mode 100644 uni_modules/uv-grid/readme.md create mode 100644 uni_modules/uv-icon/changelog.md create mode 100644 uni_modules/uv-icon/components/uv-icon/icons.js create mode 100644 uni_modules/uv-icon/components/uv-icon/props.js create mode 100644 uni_modules/uv-icon/components/uv-icon/uv-icon.vue create mode 100644 uni_modules/uv-icon/components/uv-icon/uvicons.ttf create mode 100644 uni_modules/uv-icon/package.json create mode 100644 uni_modules/uv-icon/readme.md create mode 100644 uni_modules/uv-image/changelog.md create mode 100644 uni_modules/uv-image/components/uv-image/props.js create mode 100644 uni_modules/uv-image/components/uv-image/uv-image.vue create mode 100644 uni_modules/uv-image/package.json create mode 100644 uni_modules/uv-image/readme.md create mode 100644 uni_modules/uv-index-list/changelog.md create mode 100644 uni_modules/uv-index-list/components/uv-index-anchor/props.js create mode 100644 uni_modules/uv-index-list/components/uv-index-anchor/uv-index-anchor.vue create mode 100644 uni_modules/uv-index-list/components/uv-index-item/uv-index-item.vue create mode 100644 uni_modules/uv-index-list/components/uv-index-list/props.js create mode 100644 uni_modules/uv-index-list/components/uv-index-list/uv-index-list.vue create mode 100644 uni_modules/uv-index-list/package.json create mode 100644 uni_modules/uv-index-list/readme.md create mode 100644 uni_modules/uv-input/changelog.md create mode 100644 uni_modules/uv-input/components/uv-input/props.js create mode 100644 uni_modules/uv-input/components/uv-input/uv-input.vue create mode 100644 uni_modules/uv-input/package.json create mode 100644 uni_modules/uv-input/readme.md create mode 100644 uni_modules/uv-keyboard/changelog.md create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-car/props.js create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-car/uv-keyboard-car.vue create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-number/props.js create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard-number/uv-keyboard-number.vue create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard/props.js create mode 100644 uni_modules/uv-keyboard/components/uv-keyboard/uv-keyboard.vue create mode 100644 uni_modules/uv-keyboard/package.json create mode 100644 uni_modules/uv-keyboard/readme.md create mode 100644 uni_modules/uv-line-progress/changelog.md create mode 100644 uni_modules/uv-line-progress/components/uv-line-progress/props.js create mode 100644 uni_modules/uv-line-progress/components/uv-line-progress/uv-line-progress.vue create mode 100644 uni_modules/uv-line-progress/package.json create mode 100644 uni_modules/uv-line-progress/readme.md create mode 100644 uni_modules/uv-line/changelog.md create mode 100644 uni_modules/uv-line/components/uv-line/props.js create mode 100644 uni_modules/uv-line/components/uv-line/uv-line.vue create mode 100644 uni_modules/uv-line/package.json create mode 100644 uni_modules/uv-line/readme.md create mode 100644 uni_modules/uv-link/changelog.md create mode 100644 uni_modules/uv-link/components/uv-link/props.js create mode 100644 uni_modules/uv-link/components/uv-link/uv-link.vue create mode 100644 uni_modules/uv-link/package.json create mode 100644 uni_modules/uv-link/readme.md create mode 100644 uni_modules/uv-list/changelog.md create mode 100644 uni_modules/uv-list/components/uv-list-item/uv-list-item.vue create mode 100644 uni_modules/uv-list/components/uv-list/uv-list.vue create mode 100644 uni_modules/uv-list/package.json create mode 100644 uni_modules/uv-list/readme.md create mode 100644 uni_modules/uv-load-more/changelog.md create mode 100644 uni_modules/uv-load-more/components/uv-load-more/props.js create mode 100644 uni_modules/uv-load-more/components/uv-load-more/uv-load-more.vue create mode 100644 uni_modules/uv-load-more/package.json create mode 100644 uni_modules/uv-load-more/readme.md create mode 100644 uni_modules/uv-loading-icon/changelog.md create mode 100644 uni_modules/uv-loading-icon/components/uv-loading-icon/props.js create mode 100644 uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue create mode 100644 uni_modules/uv-loading-icon/package.json create mode 100644 uni_modules/uv-loading-icon/readme.md create mode 100644 uni_modules/uv-loading-page/changelog.md create mode 100644 uni_modules/uv-loading-page/components/uv-loading-page/props.js create mode 100644 uni_modules/uv-loading-page/components/uv-loading-page/uv-loading-page.vue create mode 100644 uni_modules/uv-loading-page/package.json create mode 100644 uni_modules/uv-loading-page/readme.md create mode 100644 uni_modules/uv-modal/changelog.md create mode 100644 uni_modules/uv-modal/components/uv-modal/props.js create mode 100644 uni_modules/uv-modal/components/uv-modal/uv-modal.vue create mode 100644 uni_modules/uv-modal/package.json create mode 100644 uni_modules/uv-modal/readme.md create mode 100644 uni_modules/uv-navbar/changelog.md create mode 100644 uni_modules/uv-navbar/components/uv-navbar/props.js create mode 100644 uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue create mode 100644 uni_modules/uv-navbar/package.json create mode 100644 uni_modules/uv-navbar/readme.md create mode 100644 uni_modules/uv-no-network/changelog.md create mode 100644 uni_modules/uv-no-network/components/uv-no-network/props.js create mode 100644 uni_modules/uv-no-network/components/uv-no-network/uv-no-network.vue create mode 100644 uni_modules/uv-no-network/package.json create mode 100644 uni_modules/uv-no-network/readme.md create mode 100644 uni_modules/uv-notice-bar/changelog.md create mode 100644 uni_modules/uv-notice-bar/components/uv-column-notice/props.js create mode 100644 uni_modules/uv-notice-bar/components/uv-column-notice/uv-column-notice.vue create mode 100644 uni_modules/uv-notice-bar/components/uv-notice-bar/props.js create mode 100644 uni_modules/uv-notice-bar/components/uv-notice-bar/uv-notice-bar.vue create mode 100644 uni_modules/uv-notice-bar/components/uv-row-notice/props.js create mode 100644 uni_modules/uv-notice-bar/components/uv-row-notice/uv-row-notice.vue create mode 100644 uni_modules/uv-notice-bar/package.json create mode 100644 uni_modules/uv-notice-bar/readme.md create mode 100644 uni_modules/uv-notify/changelog.md create mode 100644 uni_modules/uv-notify/components/uv-notify/props.js create mode 100644 uni_modules/uv-notify/components/uv-notify/uv-notify.vue create mode 100644 uni_modules/uv-notify/package.json create mode 100644 uni_modules/uv-notify/readme.md create mode 100644 uni_modules/uv-number-box/changelog.md create mode 100644 uni_modules/uv-number-box/components/uv-number-box/props.js create mode 100644 uni_modules/uv-number-box/components/uv-number-box/uv-number-box.vue create mode 100644 uni_modules/uv-number-box/package.json create mode 100644 uni_modules/uv-number-box/readme.md create mode 100644 uni_modules/uv-overlay/changelog.md create mode 100644 uni_modules/uv-overlay/components/uv-overlay/props.js create mode 100644 uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue create mode 100644 uni_modules/uv-overlay/package.json create mode 100644 uni_modules/uv-overlay/readme.md create mode 100644 uni_modules/uv-parse/changelog.md create mode 100644 uni_modules/uv-parse/components/uv-parse/node/node.vue create mode 100644 uni_modules/uv-parse/components/uv-parse/parser.js create mode 100644 uni_modules/uv-parse/components/uv-parse/uv-parse.vue create mode 100644 uni_modules/uv-parse/package.json create mode 100644 uni_modules/uv-parse/readme.md create mode 100644 uni_modules/uv-parse/static/app-plus/uv-parse/js/handler.js create mode 100644 uni_modules/uv-parse/static/app-plus/uv-parse/js/uni.webview.min.js create mode 100644 uni_modules/uv-parse/static/app-plus/uv-parse/local.html create mode 100644 uni_modules/uv-pick-color/changelog.md create mode 100644 uni_modules/uv-pick-color/components/uv-pick-color/colors.js create mode 100644 uni_modules/uv-pick-color/components/uv-pick-color/props.js create mode 100644 uni_modules/uv-pick-color/components/uv-pick-color/uv-pick-color.vue create mode 100644 uni_modules/uv-pick-color/package.json create mode 100644 uni_modules/uv-pick-color/readme.md create mode 100644 uni_modules/uv-picker/changelog.md create mode 100644 uni_modules/uv-picker/components/uv-picker/props.js create mode 100644 uni_modules/uv-picker/components/uv-picker/uv-picker.vue create mode 100644 uni_modules/uv-picker/package.json create mode 100644 uni_modules/uv-picker/readme.md create mode 100644 uni_modules/uv-popup/changelog.md create mode 100644 uni_modules/uv-popup/components/uv-popup/keypress.js create mode 100644 uni_modules/uv-popup/components/uv-popup/uv-popup.vue create mode 100644 uni_modules/uv-popup/package.json create mode 100644 uni_modules/uv-popup/readme.md create mode 100644 uni_modules/uv-qrcode/changelog.md create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/cache.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/bridge/bridge-weex.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleLinearGradient.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStylePattern.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/FillStyleRadialGradient.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-2d/RenderingContext.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ActiveInfo.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Buffer.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Framebuffer.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLenum.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLmethod.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/GLtype.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Program.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Renderbuffer.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/RenderingContext.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Shader.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/ShaderPrecisionFormat.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/Texture.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/UniformLocation.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/context-webgl/classUtils.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/canvas.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/image.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/env/tool.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/gcanvas/index.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/props.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/qrcode.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/queue.js create mode 100644 uni_modules/uv-qrcode/components/uv-qrcode/uv-qrcode.vue create mode 100644 uni_modules/uv-qrcode/package.json create mode 100644 uni_modules/uv-qrcode/readme.md create mode 100644 uni_modules/uv-radio/changelog.md create mode 100644 uni_modules/uv-radio/components/uv-radio-group/props.js create mode 100644 uni_modules/uv-radio/components/uv-radio-group/uv-radio-group.vue create mode 100644 uni_modules/uv-radio/components/uv-radio/props.js create mode 100644 uni_modules/uv-radio/components/uv-radio/uv-radio.vue create mode 100644 uni_modules/uv-radio/package.json create mode 100644 uni_modules/uv-radio/readme.md create mode 100644 uni_modules/uv-rate/changelog.md create mode 100644 uni_modules/uv-rate/components/uv-rate/props.js create mode 100644 uni_modules/uv-rate/components/uv-rate/uv-rate.vue create mode 100644 uni_modules/uv-rate/package.json create mode 100644 uni_modules/uv-rate/readme.md create mode 100644 uni_modules/uv-read-more/changelog.md create mode 100644 uni_modules/uv-read-more/components/uv-read-more/props.js create mode 100644 uni_modules/uv-read-more/components/uv-read-more/uv-read-more.vue create mode 100644 uni_modules/uv-read-more/package.json create mode 100644 uni_modules/uv-read-more/readme.md create mode 100644 uni_modules/uv-row/changelog.md create mode 100644 uni_modules/uv-row/components/uv-col/props.js create mode 100644 uni_modules/uv-row/components/uv-col/uv-col.vue create mode 100644 uni_modules/uv-row/components/uv-row/props.js create mode 100644 uni_modules/uv-row/components/uv-row/uv-row.vue create mode 100644 uni_modules/uv-row/package.json create mode 100644 uni_modules/uv-row/readme.md create mode 100644 uni_modules/uv-safe-bottom/changelog.md create mode 100644 uni_modules/uv-safe-bottom/components/uv-safe-bottom/uv-safe-bottom.vue create mode 100644 uni_modules/uv-safe-bottom/package.json create mode 100644 uni_modules/uv-safe-bottom/readme.md create mode 100644 uni_modules/uv-scroll-list/changelog.md create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/nvue.js create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/props.js create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/scrollWxs.wxs create mode 100644 uni_modules/uv-scroll-list/components/uv-scroll-list/uv-scroll-list.vue create mode 100644 uni_modules/uv-scroll-list/package.json create mode 100644 uni_modules/uv-scroll-list/readme.md create mode 100644 uni_modules/uv-search/changelog.md create mode 100644 uni_modules/uv-search/components/uv-search/props.js create mode 100644 uni_modules/uv-search/components/uv-search/uv-search.vue create mode 100644 uni_modules/uv-search/package.json create mode 100644 uni_modules/uv-search/readme.md create mode 100644 uni_modules/uv-skeleton/changelog.md create mode 100644 uni_modules/uv-skeleton/components/uv-skeleton/props.js create mode 100644 uni_modules/uv-skeleton/components/uv-skeleton/uv-skeleton.vue create mode 100644 uni_modules/uv-skeleton/package.json create mode 100644 uni_modules/uv-skeleton/readme.md create mode 100644 uni_modules/uv-skeletons/changelog.md create mode 100644 uni_modules/uv-skeletons/components/uv-skeletons/uv-skeletons.vue create mode 100644 uni_modules/uv-skeletons/package.json create mode 100644 uni_modules/uv-skeletons/readme.md create mode 100644 uni_modules/uv-slider/changelog.md create mode 100644 uni_modules/uv-slider/components/uv-slider/props.js create mode 100644 uni_modules/uv-slider/components/uv-slider/uv-slider.vue create mode 100644 uni_modules/uv-slider/package.json create mode 100644 uni_modules/uv-slider/readme.md create mode 100644 uni_modules/uv-status-bar/changelog.md create mode 100644 uni_modules/uv-status-bar/components/uv-status-bar/props.js create mode 100644 uni_modules/uv-status-bar/components/uv-status-bar/uv-status-bar.vue create mode 100644 uni_modules/uv-status-bar/package.json create mode 100644 uni_modules/uv-status-bar/readme.md create mode 100644 uni_modules/uv-steps/changelog.md create mode 100644 uni_modules/uv-steps/components/uv-steps-item/props.js create mode 100644 uni_modules/uv-steps/components/uv-steps-item/uv-steps-item.vue create mode 100644 uni_modules/uv-steps/components/uv-steps/props.js create mode 100644 uni_modules/uv-steps/components/uv-steps/uv-steps.vue create mode 100644 uni_modules/uv-steps/package.json create mode 100644 uni_modules/uv-steps/readme.md create mode 100644 uni_modules/uv-sticky/changelog.md create mode 100644 uni_modules/uv-sticky/components/uv-sticky/props.js create mode 100644 uni_modules/uv-sticky/components/uv-sticky/uv-sticky.vue create mode 100644 uni_modules/uv-sticky/package.json create mode 100644 uni_modules/uv-sticky/readme.md create mode 100644 uni_modules/uv-subsection/changelog.md create mode 100644 uni_modules/uv-subsection/components/uv-subsection/props.js create mode 100644 uni_modules/uv-subsection/components/uv-subsection/uv-subsection.vue create mode 100644 uni_modules/uv-subsection/package.json create mode 100644 uni_modules/uv-subsection/readme.md create mode 100644 uni_modules/uv-swipe-action/changelog.md create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action/props.js create mode 100644 uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue create mode 100644 uni_modules/uv-swipe-action/package.json create mode 100644 uni_modules/uv-swipe-action/readme.md create mode 100644 uni_modules/uv-swiper/changelog.md create mode 100644 uni_modules/uv-swiper/components/uv-swiper-indicator/props.js create mode 100644 uni_modules/uv-swiper/components/uv-swiper-indicator/uv-swiper-indicator.vue create mode 100644 uni_modules/uv-swiper/components/uv-swiper/props.js create mode 100644 uni_modules/uv-swiper/components/uv-swiper/uv-swiper.vue create mode 100644 uni_modules/uv-swiper/package.json create mode 100644 uni_modules/uv-swiper/readme.md create mode 100644 uni_modules/uv-switch/changelog.md create mode 100644 uni_modules/uv-switch/components/uv-switch/props.js create mode 100644 uni_modules/uv-switch/components/uv-switch/uv-switch.vue create mode 100644 uni_modules/uv-switch/package.json create mode 100644 uni_modules/uv-switch/readme.md create mode 100644 uni_modules/uv-tabbar/changelog.md create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar-item/props.js create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar-item/uv-tabbar-item.vue create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar/props.js create mode 100644 uni_modules/uv-tabbar/components/uv-tabbar/uv-tabbar.vue create mode 100644 uni_modules/uv-tabbar/package.json create mode 100644 uni_modules/uv-tabbar/readme.md create mode 100644 uni_modules/uv-tabs/changelog.md create mode 100644 uni_modules/uv-tabs/components/uv-tabs/props.js create mode 100644 uni_modules/uv-tabs/components/uv-tabs/uv-tabs.vue create mode 100644 uni_modules/uv-tabs/package.json create mode 100644 uni_modules/uv-tabs/readme.md create mode 100644 uni_modules/uv-tags/changelog.md create mode 100644 uni_modules/uv-tags/components/uv-tags/props.js create mode 100644 uni_modules/uv-tags/components/uv-tags/uv-tags.vue create mode 100644 uni_modules/uv-tags/package.json create mode 100644 uni_modules/uv-tags/readme.md create mode 100644 uni_modules/uv-text/changelog.md create mode 100644 uni_modules/uv-text/components/uv-text/props.js create mode 100644 uni_modules/uv-text/components/uv-text/uv-text.vue create mode 100644 uni_modules/uv-text/components/uv-text/value.js create mode 100644 uni_modules/uv-text/package.json create mode 100644 uni_modules/uv-text/readme.md create mode 100644 uni_modules/uv-textarea/changelog.md create mode 100644 uni_modules/uv-textarea/components/uv-textarea/props.js create mode 100644 uni_modules/uv-textarea/components/uv-textarea/uv-textarea.vue create mode 100644 uni_modules/uv-textarea/package.json create mode 100644 uni_modules/uv-textarea/readme.md create mode 100644 uni_modules/uv-toast/changelog.md create mode 100644 uni_modules/uv-toast/components/uv-toast/uv-toast.vue create mode 100644 uni_modules/uv-toast/package.json create mode 100644 uni_modules/uv-toast/readme.md create mode 100644 uni_modules/uv-toolbar/changelog.md create mode 100644 uni_modules/uv-toolbar/components/uv-toolbar/props.js create mode 100644 uni_modules/uv-toolbar/components/uv-toolbar/uv-toolbar.vue create mode 100644 uni_modules/uv-toolbar/package.json create mode 100644 uni_modules/uv-toolbar/readme.md create mode 100644 uni_modules/uv-tooltip/changelog.md create mode 100644 uni_modules/uv-tooltip/components/uv-tooltip/props.js create mode 100644 uni_modules/uv-tooltip/components/uv-tooltip/uv-tooltip.vue create mode 100644 uni_modules/uv-tooltip/package.json create mode 100644 uni_modules/uv-tooltip/readme.md create mode 100644 uni_modules/uv-transition/changelog.md create mode 100644 uni_modules/uv-transition/components/uv-transition/createAnimation.js create mode 100644 uni_modules/uv-transition/components/uv-transition/props.js create mode 100644 uni_modules/uv-transition/components/uv-transition/uv-transition.vue create mode 100644 uni_modules/uv-transition/package.json create mode 100644 uni_modules/uv-transition/readme.md create mode 100644 uni_modules/uv-ui-tools/changelog.md create mode 100644 uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue create mode 100644 uni_modules/uv-ui-tools/index.js create mode 100644 uni_modules/uv-ui-tools/index.scss create mode 100644 uni_modules/uv-ui-tools/libs/config/config.js create mode 100644 uni_modules/uv-ui-tools/libs/css/color.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/common.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/components.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/variable.scss create mode 100644 uni_modules/uv-ui-tools/libs/css/vue.scss create mode 100644 uni_modules/uv-ui-tools/libs/function/colorGradient.js create mode 100644 uni_modules/uv-ui-tools/libs/function/debounce.js create mode 100644 uni_modules/uv-ui-tools/libs/function/digit.js create mode 100644 uni_modules/uv-ui-tools/libs/function/index.js create mode 100644 uni_modules/uv-ui-tools/libs/function/platform.js create mode 100644 uni_modules/uv-ui-tools/libs/function/test.js create mode 100644 uni_modules/uv-ui-tools/libs/function/throttle.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/Request.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/core/settle.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/index.d.ts create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/index.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/utils.js create mode 100644 uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/button.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/mixin.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/mpMixin.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/mpShare.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/openType.js create mode 100644 uni_modules/uv-ui-tools/libs/mixin/touch.js create mode 100644 uni_modules/uv-ui-tools/libs/util/dayjs.js create mode 100644 uni_modules/uv-ui-tools/libs/util/route.js create mode 100644 uni_modules/uv-ui-tools/package.json create mode 100644 uni_modules/uv-ui-tools/readme.md create mode 100644 uni_modules/uv-ui-tools/theme.scss create mode 100644 uni_modules/uv-ui/changelog.md create mode 100644 uni_modules/uv-ui/components/uv-ui/uv-ui.vue create mode 100644 uni_modules/uv-ui/package.json create mode 100644 uni_modules/uv-ui/readme.md create mode 100644 uni_modules/uv-upload/changelog.md create mode 100644 uni_modules/uv-upload/components/uv-preview-video/uv-preview-video.vue create mode 100644 uni_modules/uv-upload/components/uv-upload/mixin.js create mode 100644 uni_modules/uv-upload/components/uv-upload/props.js create mode 100644 uni_modules/uv-upload/components/uv-upload/utils.js create mode 100644 uni_modules/uv-upload/components/uv-upload/uv-upload.vue create mode 100644 uni_modules/uv-upload/package.json create mode 100644 uni_modules/uv-upload/readme.md create mode 100644 uni_modules/uv-vtabs/changelog.md create mode 100644 uni_modules/uv-vtabs/components/uv-vtabs-item/uv-vtabs-item.vue create mode 100644 uni_modules/uv-vtabs/components/uv-vtabs/props.js create mode 100644 uni_modules/uv-vtabs/components/uv-vtabs/uv-vtabs.vue create mode 100644 uni_modules/uv-vtabs/package.json create mode 100644 uni_modules/uv-vtabs/readme.md create mode 100644 uni_modules/uv-waterfall/changelog.md create mode 100644 uni_modules/uv-waterfall/components/uv-waterfall/props.js create mode 100644 uni_modules/uv-waterfall/components/uv-waterfall/uv-waterfall.vue create mode 100644 uni_modules/uv-waterfall/package.json create mode 100644 uni_modules/uv-waterfall/readme.md create mode 100644 uni_modules/v-tabs/changelog.md create mode 100644 uni_modules/v-tabs/components/v-tabs/props.js create mode 100644 uni_modules/v-tabs/components/v-tabs/utils.js create mode 100644 uni_modules/v-tabs/components/v-tabs/v-tabs.vue create mode 100644 uni_modules/v-tabs/package.json create mode 100644 uni_modules/v-tabs/readme.md create mode 100644 utils/common.js create mode 100644 utils/map.js create mode 100644 utils/navigateTo.js create mode 100644 utils/request.js create mode 100644 utils/storage.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a70bc78 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/unpackage +/node_modules diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..81f13f4 --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,16 @@ +{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version": "0.0", + "configurations": [{ + "default" : + { + "launchtype" : "local" + }, + "mp-weixin" : + { + "launchtype" : "local" + }, + "type" : "uniCloud" + } + ] +} diff --git a/Apis/book.js b/Apis/book.js new file mode 100644 index 0000000..4f2f983 --- /dev/null +++ b/Apis/book.js @@ -0,0 +1,40 @@ +import request from "/utils/request.js"; +export function ClientSite() { + return { + // 查看所有门店 + getSiteDetailsAll: (data) => { + return request.request({ + url: `/ClientSite/GetSiteDetailsAll`, + data, + method: 'get', + }); + }, + // 根据门店ID查路线图 + GetSiteGuideById: (id) => { + return request.request({ + url:`/ClientSite/GetSiteGuideById?siteId=${id}`, + method: 'get', + }); + }, + // 获取门店所在的所有城市 + GetCityAll: () => { + return request.request({ + url: '/ClientSite/GetCityAll', + method: 'get', + }); + }, + // 根据门店所在的城市获取对应的区域 + GetDistrictByCity: (city) => { + return request.request({ + url: `/ClientSite/GetDistrictByCity?city=${city}`, + method: 'get', + }); + }, + GetSiteStopCarGuideById: (id) => { + return request.request({ + url:`/ClientSite/GetSiteStopCarGuideById?siteId=${id}`, + method: 'get', + }); + }, + } +} \ No newline at end of file diff --git a/Apis/clientCustomer.js b/Apis/clientCustomer.js new file mode 100644 index 0000000..26c60a1 --- /dev/null +++ b/Apis/clientCustomer.js @@ -0,0 +1,55 @@ +import request from '/utils/request.js'; + +export function getClientCustomerApi() { + return { + // 获取中介二维码 + GetMediatorQrCode: () => { + return request.request({ + url: '/ClientMediator/GetMediatorQrCode', + method: 'get' + }); + }, + // 获取中介信息 + GetMediatorInfoById: () => { + return request.request({ + url: '/ClientMediator/GetMediatorInfoById', + method: 'get' + }); + }, + // 修改中介信息 + UpdateMediatorInfo: (data) => { + return request.request({ + url: '/ClientMediator/UpdateMediatorInfo', + method: 'post', + data + }); + }, + // 获取中介的邀请记录 + GetMediatorUpUserList: () => { + return request.request({ + url: '/ClientMediator/GetMediatorUpUserList', + method: 'post' + }); + }, + // 获取当前用户绑定的中介信息 + GetMediatorByUser: () => { + return request.request({ + url: '/ClientMediator/GetMediatorByUser', + method: 'get' + }); + }, + GetMediatorCompanyAllList: () => { + return request.request({ + url: '/ClientMediator/GetMediatorCompanyAllList', + method: 'get' + }); + }, + ApplyMediator: (data) => { + return request.request({ + url: '/ClientMediator/ApplyMediator', + method: 'post', + data + }); + } + }; +} \ No newline at end of file diff --git a/Apis/coupon.js b/Apis/coupon.js new file mode 100644 index 0000000..8618376 --- /dev/null +++ b/Apis/coupon.js @@ -0,0 +1,37 @@ +import request from "/utils/request.js"; +export function couponApi() { + return { + // 获取优惠卷列表 + GetCouponList: (data) => { + return request.request({ + url: '/ClientCoupon/GetCouponList', + method: 'get', + data, + }); + }, + // 领取优惠卷 + DrawDownCoupon: (data) => { + return request.request({ + url: '/ClientCoupon/DrawDownCoupon?couponCode='+data.couponCode, + method: 'post', + data, + }); + }, + // 优惠卷弹窗 + GetNewUserCouponCode: (data) => { + return request.request({ + url: '/ClientCoupon/GetNewUserCouponCode', + method: 'get', + data, + }); + }, + // 美团优惠卷 + GetMeiTuanCodeByPhone: (data) => { + return request.request({ + url: '/MeiTuan/GetMeiTuanCodeByPhone', + method: 'get', + data, + }); + } + }; +} \ No newline at end of file diff --git a/Apis/goodsList.js b/Apis/goodsList.js new file mode 100644 index 0000000..f3db32f --- /dev/null +++ b/Apis/goodsList.js @@ -0,0 +1,28 @@ +import request from "/utils/request.js"; +export function useGoodsApi() { + return { + // 物品清单 + GetGoodsList: (data) => { + return request.request({ + url: `/ClientOrder/GetGoodsList`, + data, + method: 'get', + }); + }, + // 获取设置过的物品清单 + GetSubmitGoodsList: (id) => { + return request.request({ + url:`/ClientOrder/GetSubmitGoodsList?orderId=${id}`, + method: 'get', + }); + }, + // 提交物品清单 + SubmitGoodsList: (data) => { + return request.request({ + url: '/ClientOrder/SubmitGoodsList', + method: 'post', + data + }); + }, + } +} \ No newline at end of file diff --git a/Apis/home.js b/Apis/home.js new file mode 100644 index 0000000..3095b4c --- /dev/null +++ b/Apis/home.js @@ -0,0 +1,63 @@ +import request from "/utils/request.js"; +export function useLoginApi() { + return { + //获取code img + getCode: () => { + return request.request({ + url: '/Login/Captcha', + method: 'get', + }); + }, + //登录 + signIn: (data) => { + return request.request({ + url: '/Login/Login', + method: 'post', + data, + }); + }, + signOut: (data) => { + return request.request({ + url: '/user/signOut', + method: 'post', + data, + }); + }, + GetUnitTypeAll: () => { + return request.request({ + url: '/ClientSite/GetUnitTypeAll', + method: 'get', + }) + }, + GetHeatSites: () => { + return request.request({ + url: '/ClientSite/GetHeatSites', + method: 'get', + }) + }, + // 理解預約 + CreateReservation:(data)=>{ + return request.request({ + url: '/ClientReservation/CreateReservation', + method: 'post', + data + }) + }, + // 获取小程序内容 + GetPageContent:(data)=>{ + return request.request({ + url: '/ClientPageContent/GetPageContent', + method: 'get', + data + }) + }, + // 获取限时抢购入口 + GetFlashSaleEntrance:(data) => { + return request.request({ + url: '/ClientSite/GetFlashSaleEntrance', + method: 'get', + data, + }); + } + }; +} \ No newline at end of file diff --git a/Apis/invoice.js b/Apis/invoice.js new file mode 100644 index 0000000..3d229d0 --- /dev/null +++ b/Apis/invoice.js @@ -0,0 +1,55 @@ +import request from "/utils/request.js"; +export function useInvoiceApi() { + return { + // 发票申请 + InvoiceApplyFor: (data) => { + return request.request({ + url: '/ClientInvoice/InvoiceApplyFor', + method: 'post', + data, + }); + }, + // 获取可开票订单列表 + GetCanInvoiceList: (data) => { + return request.request({ + url: '/ClientOrder/GetCanInvoiceList', + method: 'get', + data, + } + ) + }, + // 获取申请开票列表 + GetInvoiceApplyFor: (data) => { + return request.request({ + url: '/ClientInvoice/GetInvoiceApplyFor', + method: 'get', + data, + } + ) + }, + // 取消开票 + CancelInvoiceApplyFor: (data) => { + return request.request({ + url: '/ClientInvoice/CancelInvoiceApplyFor', + method: 'get', + data, + }) + }, + // 获取申请开票详情 + GetInvoiceApplyForById: (data) => { + return request.request({ + url: '/ClientInvoice/GetInvoiceApplyForById', + method: 'get', + data, + }) + }, + // 修改发票 + UpdateInvoiceApplyFor: (data) => { + return request.request({ + url: '/ClientInvoice/UpdateInvoiceApplyFor', + method: 'post', + data, + }) + } + } +} \ No newline at end of file diff --git a/Apis/lock.js b/Apis/lock.js new file mode 100644 index 0000000..e4445e9 --- /dev/null +++ b/Apis/lock.js @@ -0,0 +1,139 @@ +import request from "/utils/request.js"; +export function useLockApi() { + return { + GetDyncPwdByMac: (data) => { + return request.request({ + url: '/LockOperation/GetDyncPwd', + method: 'get', + data, + }); + }, + GetAccesscontrolQRCodeBySite: (data) => { + return request.request({ + url: '/Accesscontrol/GetAccesscontrolQRCode', + method: 'get', + data, + }); + }, + // 门禁远程开门 + RemoteOpenDoor: (data) => { + return request.request({ + url: '/Accesscontrol/RemoteOpenDoor', + method: 'get', + data, + }); + }, + //通通锁远程开锁 + RemoteOpen: (data) => { + return request.request({ + url: '/LockOperation/RemoteOpen', + method: 'post', + data, + }); + }, + // 获取初始化的通通锁列表 + GetInitLockList: (data) => { + return request.request({ + url: '/Lock/GetLockInfoByOpenId', + method: 'get', + data, + }); + }, + // 获取初始化的通通锁信息 + SaveInitLock: (data) => { + return request.request({ + url: '/Lock/PushLockInfo', + method: 'post', + data, + }); + }, + //授权订单 + OrderAuthorizeCustomer: (data) => { + return request.request({ + url: '/ClientOrder/OrderAuthorizeCustomer', + method: 'post', + data, + }); + }, + // 更新授权订单 + UpdateOrderAuthorizeCustomer: (data) => { + return request.request({ + url: '/ClientOrder/UpdateOrderAuthorizeCustomer', + method: 'post', + data, + }); + }, + // 删除授权订单 + DeleteOrderAuthorize: (data) => { + return request.request({ + url: '/ClientOrder/DeleteOrderAuthorize?authorizeId=' + data.authorizeId, + method: 'delete', + data, + }); + }, + // 获取授权列表 + GetOrderAuthorizeList: (data) => { + return request.request({ + url: '/ClientOrder/GetOrderAuthorizeList', + method: 'get', + data, + }); + }, + // 获取授权的订单 + GetAuthorizeOrderList: (data) => { + return request.request({ + url: '/ClientOrder/GetAuthorizeOrderList', + method: 'post', + data, + }); + }, + // 设置用户固定密码 + SetUserFixedPassword: (data) => { + return request.request({ + url: '/LockOperation/SetUserFixedPassword', + method: 'post', + data, + }); + }, + // 门禁绑卡 + AddCardNumber: (data) => { + return request.request({ + url: '/Site/AddCardNumber', + method: 'get', + data, + }); + }, + //通通锁绑卡 + BindCardByWifiSmartLock: (data) => { + return request.request({ + url: '/LockOperation/BindCardByWifiSmartLock', + method: 'post', + data, + }); + }, + // zoned 锁绑卡 + SetRFIDCard: (data) => { + return request.request({ + url: '/LockOperation/SetRFIDCard', + method: 'post', + data, + }); + }, + // zoned 绑卡读取卡结果 + GetBindingCardResult: (data) => { + return request.request({ + url: '/LockOperation/GetBindingCardResult', + method: 'get', + data, + }); + }, + // 就门禁id 获取门禁信息 + GetNewLockerId: (data) => { + return request.request({ + url: '/Locker/GetNewLockerId', + method: 'get', + data, + }); + }, + }; +} \ No newline at end of file diff --git a/Apis/login.js b/Apis/login.js new file mode 100644 index 0000000..4dfb435 --- /dev/null +++ b/Apis/login.js @@ -0,0 +1,159 @@ +import request from "/utils/request.js"; +export function useLoginApi() { + return { + //获取code img + getCode: () => { + return request.request({ + url: '/Login/Captcha', + method: 'get', + }); + }, + //登录 + Login: (data) => { + return request.request({ + url: '/ClientCustomer/Login', + method: 'post', + data, + }); + }, + Register: (data) => { + return request.request({ + url: '/ClientCustomer/Register', + method: 'post', + data, + }); + }, + EmailVerify: (data) => { + return request.request({ + url: '/ClientCustomer/EmailVerify', + method: 'post', + data, + }); + }, + ForgotPassword: (data) => { + return request.request({ + url: '/ClientCustomer/ForgotPassword', + method: 'post', + data, + headers: { + "Content-Type": "application/json; charset=utf-8", + } + }); + }, + UpdateUserInfo: (data) => { + return request.request({ + url: '/ClientCustomer/UpdateUserInfo', + method: 'post', + data, + }); + }, + // 微信登录 + AuthorizedLogin: (data) => { + return request.request({ + url:'/ClientCustomer/AuthorizedLogin', + method:'post', + data, + }) + }, + // 通过用户授权的code去获取手机号码 + GetPhoneNumber: (data) => { + return request.request({ + url:`/ClientCustomer/GetPhoneNumber`, + method:'get', + params:{ + ...data, + isUpdate:true + }, + }) + }, + // 通过用户授权的code去获取手机号码 + GetPhoneNumberNoUpdate: (data) => { + return request.request({ + url:`/ClientCustomer/GetPhoneNumber?code=${data}`, + method:'get', + data, + }) + }, + // 获取用户信息 + GetUserInfo:() =>{ + return request.request({ + url:`/ClientCustomer/GetUserInfo`, + method:'get', + }) + }, + // 更新用户信息 + EditUserInfo: (data) => { + return request.request({ + url: '/ClientCustomer/EditUserInfo', + method: 'post', + data, + }); + }, + // 从主题二维码来的 + GetActivitiesCode: (data) => { + return request.request({ + url: '/ClientCustomer/GetActivitiesCode', + method: 'post', + data, + }); + }, + // 获取openId + GetOpenId: (data) => { + return request.request({ + url:'/ClientCustomer/GetOpenId', + method:'post', + data, + }) + }, + // 获取积分豆 + GetCustomerPoint: () => { + return request.request({ + url: '/ClientCustomer/GetCustomerPoint', + method: 'get', + }); + }, + // 兑换奖品 + CustomerExchangeGift: (data) => { + return request.request({ + url: '/ClientPoint/CustomerExchangeGift', + method: 'post', + data, + }); + }, + GetGiftInfo: (data) => { + return request.request({ + url: '/ClientPoint/GetGiftInfo', + method: 'post', + data, + }); + }, + GetGiftList: () => { + return request.request({ + url: '/ClientPoint/GetGiftList', + method: 'get', + }); + }, + GetCustomerExchangeGift: (data) => { + return request.request({ + url: '/ClientPoint/GetCustomerExchangeGift', + method: 'get', + data, + }); + }, + GetCustomerList: (data) => { + return request.request({ + url: '/Customer/GetCustomerList', + method: 'get', + data, + }); + }, + ShunFengLogin: (data) => { + return request.request({ + url: '/ShunFeng/ShunFengLogin', + method: 'post', + data, + }); + } + + }; +} \ No newline at end of file diff --git a/Apis/order.js b/Apis/order.js new file mode 100644 index 0000000..513c15c --- /dev/null +++ b/Apis/order.js @@ -0,0 +1,172 @@ +import request from "/utils/request.js"; +export function useOrderApi() { + return { + GetOrderById: (data) => { + return request.request({ + url: '/ClientOrder/GetOrderById', + method: 'get', + data, + }); + }, + GetOrderList: (data) => { + return request.request({ + url: '/ClientOrder/GetOrderList', + method: 'get', + data, + }); + }, + AddOrder: (data) => { + return request.request({ + url: '/ClientOrder/AddOrder', + method: 'post', + data, + }); + }, + AddOrder2: (data) => { + return request.request({ + url: '/ClientOrder/AddOrder2', + method: 'post', + data, + }); + }, + UploaderImage: (data) => { + return request.uploadFile({ + url: '/ClientImages/UploadFileByALiYun', + method: 'post', + data, + headers:{'Content-Type':'multipart/form-data'} + }); + }, + ApplyForRefundLocker: (data) => { + return request.request({ + url: '/ClientOrder/ApplyForRefundLocker', + method: 'post', + data, + }); + }, + CancelApplyForRefundLocker: (data) => { + return request.request({ + url: `/ClientOrder/CancelApplyForRefundLocker?orderId=${data}`, + method: 'post', + data, + }); + }, + SubmitOrderEvaluate: (data) => { + return request.request({ + url: '/ClientOrder/SubmitOrderEvaluate', + method: 'post', + data, + }); + }, + //续租订单价格 + ContinuationOrderPrice:(data)=>{ + return request.request({ + url: '/ClientOrder/ContinuationOrderPrice', + method: 'get', + data, + }) + }, + //续租订单价格 + ContinuationOrderPricePost:(data)=>{ + return request.request({ + url: '/ClientOrder/ContinuationOrderPrice', + method: 'post', + data, + }) + }, + //续租订单 + ContinuationOrder:(data)=>{ + return request.request({ + url: '/ClientOrder/ContinuationOrder', + method: 'post', + data, + }) + }, + //续租订单 + ContinuationOrderH5:(data)=>{ + return request.request({ + url: '/ClientOrder/ContinuationOrderH5', + method: 'post', + data, + }) + }, + // 关闭支付 + CloseWeChatPayment:(data)=>{ + return request.request({ + url: `/ClientOrder/CloseWeChatPayment?out_trade_no=${data.out_trade_no}`, + method: 'post', + data, + }) + }, + //授权 + OrderAuthorization:(data)=>{ + return request.request({ + url: '/ClientOrder/OrderAuthorization', + method: 'post', + data, + }) + }, + // 获取信息 + GetOrderAuthorizationFace:(data)=>{ + return request.request({ + url: '/ClientOrder/GetOrderAuthorizationFace', + method: 'get', + data, + }) + }, + // 申请退押金 + WeChatMerchantRefund:(data)=>{ + return request.request({ + url: '/ClientOrder/WeChatMerchantRefund', + method: 'get', + data, + }) + }, + // 获取起租天数 + GetStartDateRntalByKey: () => { + return request.request({ + url: '/sysconfig/GetStartDateRntalByKey', + method: 'get' + }); + }, + GenerateQuotation : (data) => { + return request.request({ + url: '/ClientSite/GenerateQuotation', + method: 'post', + data, + responseType: 'arraybuffer' + }); + }, + // 获取锁订单时间 + GetLockOrderTime: (data) => { + return request.request({ + url: '/ClientOrder/GetLockOrderTime', + method: 'post', + params: data, + }); + }, + // 取消支付 + OrderCountdownTime: (data) => { + return request.request({ + url: '/ClientOrder/OrderCountdownTime', + method: 'post', + params: data, + }); + }, + // 继续支付 + ContinueOrderPay: (data) => { + return request.request({ + url: '/ClientOrder/ContinueOrderPay', + method: 'post', + params: data, + }); + }, + GetAppText: (data) => { + return request.request({ + url: '/APP/GetAppText', + method: 'get', + data + }); + } + } +} \ No newline at end of file diff --git a/Apis/recommend.js b/Apis/recommend.js new file mode 100644 index 0000000..a0a580d --- /dev/null +++ b/Apis/recommend.js @@ -0,0 +1,21 @@ +import request from "/utils/request.js"; +export function useRecommend() { + return { + // 获取推荐列表 + GetRecommend: (data) => { + return request.request({ + url: '/ClientCustomer/GetRecommend', + data, + method: 'get', + }); + }, + // 获取推荐人数 + GetRecommendCount: (data) => { + return request.request({ + url: '/ClientCustomer/GetRecommendCount', + data, + method: 'get', + }); + } + } +} \ No newline at end of file diff --git a/Apis/site.js b/Apis/site.js new file mode 100644 index 0000000..e05d425 --- /dev/null +++ b/Apis/site.js @@ -0,0 +1,70 @@ +import request from "/utils/request.js"; +export function useSiteApi() { + return { + // 根據門店id 獲取門店 + GetUnitTypeBySiteId: (data) => { + return request.request({ + url: '/ClientSite/GetUnitTypeBySiteId', + method: 'get', + data, + }); + }, + GetLockerBySiteId: (data) => { + return request.request({ + url: '/ClientSite/GetLockerBySiteIdList', + method: 'get', + data, + }); + }, + GetLockerById: (data) => { + return request.request({ + url: '/ClientSite/GetLockerById', + method: 'get', + data, + }); + }, + GetLockerExpense: (data) => { + return request.request({ + url: '/ClientSite/GetLockerExpense', + method: 'post', + data, + }); + }, + AlternateReservation: (data) => { + return request.request({ + url:'/ClientUnitType/AlternateReservation', + method: 'post', + data, + }); + }, + GetReserveIsEnable: (data) => { + return request.request({ + url:'/ClientUnitType/GetReserveIsEnable', + method: 'get', + data, + }); + }, + // 取消預約 + CancelReservation: (data) => { + return request.request({ + url:'/ClientUnitType/CancelReservation', + method: 'post', + data, + }); + }, + // 获取五羊门店 + GetMultipleStoreInfo: () => { + return request.request({ + url: '/ClientSite/GetMultipleStoreInfo', + method: 'get', + }); + }, + GetLockerAgreementHTMLById: (data) => { + return request.request({ + url: '/ClientSite/GetLockerAgreementHTMLById', + method: 'get', + data, + }); + } + }; +} \ No newline at end of file diff --git a/Apis/validInfo.js b/Apis/validInfo.js new file mode 100644 index 0000000..dc0c2aa --- /dev/null +++ b/Apis/validInfo.js @@ -0,0 +1,67 @@ +import request from "/utils/request.js"; +export function authInfoApi() { + return { + // 获取认证列表 + GetCertificateList: (data) => { + return request.request({ + url: '/InfoCertification/GetCertificateList', + method: 'get', + data, + }); + }, + // 获取是否认证过 + GetIsCertification: () => { + return request.request({ + url: '/ClientInfoCertification/GetIsCertification', + method: 'get', + }); + }, + // 获取认证详情 + GetCertificationInfo: () => { + return request.request({ + url: '/ClientInfoCertification/GetCertificateByUserId', + method: 'get', + }); + }, + // 提交企业认证 + SubmitEnterpriseCertification: (data) => { + return request.request({ + url: '/ClientInfoCertification/SubmitEnterpriseCertification', + method: 'post', + data, + }); + }, + // 提交个人认证 + SubmitPersonCertification: (data) => { + return request.request({ + url: '/ClientInfoCertification/SubmitIndividualCertification', + method: 'post', + data, + }); + }, + // 修改验证信息 + UpdateCertification: (data) => { + return request.request({ + url: '/ClientInfoCertification/UpdateCertification', + method: 'post', + data, + }); + }, + // 领取优惠卷 + DrawDownCoupon: (data) => { + return request.request({ + url: '/ClientCoupon/DrawDownCoupon?couponCode='+data.couponCode, + method: 'post', + data, + }); + }, + // 优惠卷弹窗 + GetNewUserCouponCode: (data) => { + return request.request({ + url: '/ClientCoupon/GetNewUserCouponCode', + method: 'get', + data, + }); + } + }; +} \ No newline at end of file diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..24b165d --- /dev/null +++ b/App.vue @@ -0,0 +1,241 @@ + + + diff --git a/README.md b/README.md index a0b33ac..e37e4b1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,20 @@ -# SFH5 +# Introduction +TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project. -金刚顺丰H5 \ No newline at end of file +# Getting Started +TODO: Guide users through getting your code up and running on their own system. In this section you can talk about: +1. Installation process +2. Software dependencies +3. Latest releases +4. API references + +# Build and Test +TODO: Describe and show how to build your code and run the tests. + +# Contribute +TODO: Explain how other users and developers can contribute to make your code better. + +If you want to learn more about creating good readme files then refer the following [guidelines](https://docs.microsoft.com/en-us/azure/devops/repos/git/create-a-readme?view=azure-devops). You can also seek inspiration from the below readme files: +- [ASP.NET Core](https://github.com/aspnet/Home) +- [Visual Studio Code](https://github.com/Microsoft/vscode) +- [Chakra Core](https://github.com/Microsoft/ChakraCore) \ No newline at end of file diff --git a/components/AgreementCheck.vue b/components/AgreementCheck.vue new file mode 100644 index 0000000..74bd8c1 --- /dev/null +++ b/components/AgreementCheck.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/components/MediatorinviteDetail.vue b/components/MediatorinviteDetail.vue new file mode 100644 index 0000000..eb792f1 --- /dev/null +++ b/components/MediatorinviteDetail.vue @@ -0,0 +1,158 @@ + + + + + \ No newline at end of file diff --git a/components/coupon.vue b/components/coupon.vue new file mode 100644 index 0000000..978f47e --- /dev/null +++ b/components/coupon.vue @@ -0,0 +1,820 @@ + + + + + \ No newline at end of file diff --git a/components/inviteDetail.vue b/components/inviteDetail.vue new file mode 100644 index 0000000..084490e --- /dev/null +++ b/components/inviteDetail.vue @@ -0,0 +1,163 @@ + + + + + \ No newline at end of file diff --git a/components/my-dropdown.vue b/components/my-dropdown.vue new file mode 100644 index 0000000..bc01645 --- /dev/null +++ b/components/my-dropdown.vue @@ -0,0 +1,124 @@ + + + + + + \ No newline at end of file diff --git a/components/myCustomtTabBar.vue b/components/myCustomtTabBar.vue new file mode 100644 index 0000000..cd1652b --- /dev/null +++ b/components/myCustomtTabBar.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/components/myModal.vue b/components/myModal.vue new file mode 100644 index 0000000..ea2154a --- /dev/null +++ b/components/myModal.vue @@ -0,0 +1,210 @@ + + + + + \ No newline at end of file diff --git a/components/myPopup.vue b/components/myPopup.vue new file mode 100644 index 0000000..1d6097f --- /dev/null +++ b/components/myPopup.vue @@ -0,0 +1,172 @@ + + + + + \ No newline at end of file diff --git a/components/myUpload.vue b/components/myUpload.vue new file mode 100644 index 0000000..8c731a1 --- /dev/null +++ b/components/myUpload.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/components/navBar.vue b/components/navBar.vue new file mode 100644 index 0000000..df17d8e --- /dev/null +++ b/components/navBar.vue @@ -0,0 +1,67 @@ + + + + + \ No newline at end of file diff --git a/components/noToken.vue b/components/noToken.vue new file mode 100644 index 0000000..2dbda2c --- /dev/null +++ b/components/noToken.vue @@ -0,0 +1,29 @@ + + + + + \ No newline at end of file diff --git a/components/siteDetail.vue b/components/siteDetail.vue new file mode 100644 index 0000000..d7d6d12 --- /dev/null +++ b/components/siteDetail.vue @@ -0,0 +1,336 @@ + + + + + diff --git a/components/textEllipsis.vue b/components/textEllipsis.vue new file mode 100644 index 0000000..7f2545f --- /dev/null +++ b/components/textEllipsis.vue @@ -0,0 +1,110 @@ + + + + + \ No newline at end of file diff --git a/components/updatePopup.vue b/components/updatePopup.vue new file mode 100644 index 0000000..823882f --- /dev/null +++ b/components/updatePopup.vue @@ -0,0 +1,212 @@ + + + + + diff --git a/components/uv-tabsSelf/props.js b/components/uv-tabsSelf/props.js new file mode 100644 index 0000000..acab29e --- /dev/null +++ b/components/uv-tabsSelf/props.js @@ -0,0 +1,71 @@ +export default { + props: { + // 滑块的移动过渡时间,单位ms + duration: { + type: Number, + default: 300 + }, + // tabs标签数组 + list: { + type: Array, + default: () => [] + }, + // 滑块颜色 + lineColor: { + type: String, + default: '#3c9cff' + }, + // 菜单选择中时的样式 + activeStyle: { + type: [String, Object], + default: () => ({ + color: '#303133' + }) + }, + // 菜单非选中时的样式 + inactiveStyle: { + type: [String, Object], + default: () => ({ + color: '#606266' + }) + }, + // 滑块长度 + lineWidth: { + type: [String, Number], + default: 20 + }, + // 滑块高度 + lineHeight: { + type: [String, Number], + default: 3 + }, + // 滑块背景显示大小,当滑块背景设置为图片时使用 + lineBgSize: { + type: String, + default: 'cover' + }, + // 菜单item的样式 + itemStyle: { + type: [String, Object], + default: () => ({ + height: '44px' + }) + }, + // 菜单是否可滚动 + scrollable: { + type: Boolean, + default: true + }, + // 当前选中标签的索引 + current: { + type: [Number, String], + default: 0 + }, + // 默认读取的键名 + keyName: { + type: String, + default: 'name' + }, + ...uni.$uv?.props?.tabs + } +} \ No newline at end of file diff --git a/components/uv-tabsSelf/uv-tabs.vue b/components/uv-tabsSelf/uv-tabs.vue new file mode 100644 index 0000000..1cebe2e --- /dev/null +++ b/components/uv-tabsSelf/uv-tabs.vue @@ -0,0 +1,412 @@ + + + + diff --git a/components/wxNavbar.vue b/components/wxNavbar.vue new file mode 100644 index 0000000..0c06e90 --- /dev/null +++ b/components/wxNavbar.vue @@ -0,0 +1,51 @@ + + + + + \ No newline at end of file diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..b44bb01 --- /dev/null +++ b/config/index.js @@ -0,0 +1,61 @@ +export const isKingKong = true; +export const isShichang = !isKingKong; // 是否是时昌小程序环境 +const systemInfo = uni.getSystemInfoSync(); +export const isWeChatMiniProgram = systemInfo.hostName === 'WeChat'; // 是否是微信小程序环境 +export const isXiaohongshu = systemInfo.hostName === 'xhs'; // 是否是小红书环境 +const isDev = process.env.NODE_ENV === 'development' // 是否是开发环境 +export const OFFICIAL_URL = 'https://elitesys.kingkongcang.com/Mini' // 跳转小程序地址 +// 如果是小程序 就要写全域名, 如果是h5 自动获取域名 兼容测试环境(http://8.134.73.118:10000/api 不用进行跨域操作) 跟正式环境 自动获取域名补充 +export const devURL = "https://uat.kingkongcang.com/adminApi" // 开发环境地址 'http://118.145.200.78:10000/api http://localhost:5182/api' "https://dev.kingkongcang.com/adminApi" +export const testURL = isKingKong?"https://uat.kingkongcang.com/adminApi":"https://www.scstorage.net/adminApi" // 测试环境地址 +export const prodURL = isKingKong?"https://elitesys.kingkongcang.com/adminApi":"https://www.scstorage.net/adminApi" // 正式环境地址 +export let IsApp = false +// #ifdef APP-PLUS +IsApp = true +// #endif +export let isH5 = false// h5环境下 下单会跳转到小程序 +export let RElEASE_DATE = '2026/02/26' +let accountInfo = {} +// #ifdef MP-WEIXIN || MP-XHS +accountInfo = uni.getAccountInfoSync(); +isH5 = false + // #endif +export const AppId = accountInfo?.miniProgram?.appId +export const envVersion = accountInfo?.miniProgram?.envVersion +const returnBaseUrl = () => { + if (isWeChatMiniProgram || isXiaohongshu || IsApp) { + if (envVersion === 'develop') { + return devURL; + } else if (envVersion === 'trial') { + return testURL; + } else if (envVersion === 'release') { + return prodURL; + } else { + return prodURL; + } + // 预留 防止出错 + return isDev ? testURL: prodURL; // https://elitesys.kingkongcang.com/adminApi // 测试环境 https://uat.kingkongcang.com/adminApi 开发环境 https://dev.kingkongcang.com/adminApi http://localhost:5182/ + + } else { + return isDev + ? `${window.location.origin}/api` + : `${window.location.origin}/adminApi`; + } +}; +export const baseUrl = returnBaseUrl(); +export const baseImageUrl = isKingKong? 'https://elitesoss.oss-cn-guangzhou.aliyuncs.com/':'https://scstorage.oss-cn-guangzhou.aliyuncs.com/' + +export const currency = isKingKong ? '¥' : '¥'; +// 小程序默认金刚配色先 +export const theme = ((isWeChatMiniProgram || isXiaohongshu) && isKingKong) ? 'golden' : 'default'; // 默认主题 - "default" 金刚色主题 - "golden" +export const projectInfo = { + name: isKingKong ? '金刚迷你仓' : '时昌迷你仓', // 名字:金刚迷你仓、时昌迷你仓 + miniName: isKingKong ? '金刚迷你仓' : '时昌迷你仓', // 小程序名字:迷你仓订仓、时昌迷你仓 + phone: isKingKong ? '400-818-1813' : '15323894878', + callPhone: isKingKong ? '4008181813' : '15323894878' +}; +export const watermarkURL= '?x-oss-process=image/watermark,text_5Zu-54mH6K6k6K-B5LiT55So,t_80,g_center,rotate_45,color_FF0000,size_100' +// 时昌微信二维码 +export const scWechatImg = baseImageUrl + "d3572937-4a9c-410e-992b-c19ff03e9ada.jpg" + +export const setOrderDays = isKingKong ? 30 : 7; // 金刚小程序默认7天,其他默认30天 \ No newline at end of file diff --git a/hooks/index.js b/hooks/index.js new file mode 100644 index 0000000..243d91b --- /dev/null +++ b/hooks/index.js @@ -0,0 +1,43 @@ +import { ref,onBeforeMount} from "vue"; +/** + * 倒计时 + * @param {Number} second 倒计时秒数 + * @return {Number} count 倒计时秒数 + * @return {Function} countDown 倒计时函数 + * @example + * const { count, countDown } = useCountDown() + * countDown(60) + *
{{ count }}
+ */ + +export function useCountDown() { + const count = ref(0) + const timer = ref(null); + const countDown = (second = 60, ck = () => { }) => { + if (count.value === 0 && timer.value === null) { + ck(); + count.value = second; + timer.value = setInterval(() => { + count.value-- + if (count.value === 0) { + clearInterval(timer.value) + timer.value = null + } + }, 1000); + } + }; + const cancelCout=()=>{ + clearInterval(timer.value) + timer.value = null + count.value = 0 + } + onBeforeMount(() => { + timer.value && clearInterval(timer.value) + }); + + return { + count, + countDown, + cancelCout + }; +} diff --git a/hooks/useCountDown.js b/hooks/useCountDown.js new file mode 100644 index 0000000..0aa7fc5 --- /dev/null +++ b/hooks/useCountDown.js @@ -0,0 +1,68 @@ +import { ref, onUnmounted } from 'vue' +import dayjs from 'dayjs' + +export function useCountDown(startTime, endTime, onFinished) { + if (!startTime || !endTime) { + throw new Error('startTime and endTime are required') + } + const remaining = ref(0) + const formatted = ref('00:00:00') + let timer = null + + const toTimestamp = (t) => dayjs(t).valueOf() + + let startTs = toTimestamp(startTime) + let endTs = toTimestamp(endTime) + + const calc = () => { + const now = dayjs().valueOf() + if (now < startTs) { + remaining.value = startTs - now + } else if (now >= startTs && now < endTs) { + remaining.value = endTs - now + } else { + remaining.value = 0 + clearInterval(timer) + timer = null + onFinished && onFinished() + } + format() + } + + const format = () => { + let left = remaining.value + let totalSeconds = Math.floor(left / 1000) + const days = Math.floor(totalSeconds / 86400) + totalSeconds %= 86400 + const h = String(Math.floor(totalSeconds / 3600)).padStart(2, '0') + const m = String(Math.floor((totalSeconds % 3600) / 60)).padStart(2, '0') + const s = String(totalSeconds % 60).padStart(2, '0') + formatted.value = days > 0 ? `${days}天 ${h}:${m}:${s}` : `${h}:${m}:${s}` + } + + const start = () => { + // 如果已有计时器,先清掉 + if (timer) clearInterval(timer) + startTs = toTimestamp(startTime) + endTs = toTimestamp(endTime) + calc() + timer = setInterval(calc, 1000) + } + + const reset = (newStart, newEnd) => { + startTime = newStart + endTime = newEnd + start() + } + + onUnmounted(() => { + if (timer) clearInterval(timer) + }) + + return { + formatted, + remaining, + start, + reset + } +} diff --git a/hooks/useLocation.js b/hooks/useLocation.js new file mode 100644 index 0000000..5bd77c3 --- /dev/null +++ b/hooks/useLocation.js @@ -0,0 +1,54 @@ +import { reactive } from "vue"; +import { useMainStore } from "@/store/index"; + +export function useLocation() { + const { storeState, setLocation } = useMainStore(); + + const locationState = reactive({ + showGetLocation: false, + latitude: 0, + longitude: 0 + }); + + const getLocation = () => { + return new Promise((resolve) => { + // 1️⃣ 优先使用 store 里的定位 + if (storeState.location?.latitude && storeState.location?.longitude) { + locationState.latitude = storeState.location.latitude; + locationState.longitude = storeState.location.longitude; + resolve(true); + return; + } + + // 2️⃣ 本地已经有定位 + if (locationState.latitude && locationState.longitude) { + resolve(true); + return; + } + + // 3️⃣ 没有定位才请求 + SFUIP.getLocation().then(res => { + if (!res.success) { + resolve(false); + return; + } + + const { latitude, longitude } = res.data || {}; + + if (latitude && longitude) { + locationState.latitude = latitude; + locationState.longitude = longitude; + locationState.showGetLocation = false; + + setLocation({ latitude, longitude }); + resolve(true); + } else { + resolve(false); + } + }); + + }); + }; + + return { locationState, getLocation }; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..d028183 --- /dev/null +++ b/index.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + 金刚迷你仓 + + + + +
+ + + diff --git a/locale/en.json b/locale/en.json new file mode 100644 index 0000000..9403d1c --- /dev/null +++ b/locale/en.json @@ -0,0 +1,502 @@ +{ + "common.confirm": "Confirm", + "common.cancel": "Cancel", + "common.title": "Tips", + "common.noData": "No Data", + "common.delete": "Delete", + "common.update": "Update", + "common.password": "password", + "common.close": "Close", + "common.Skiptoday": "Skip today", + "common.payableTime": "Payable Time", + "common.AuthorizationOrder": "Authorization Order", + "common.cancelOrder": "Cancel Order", + "common.cancelOrderTips": "Are you sure you want to cancel the current order?", + "common.unpaidOrderTips": "There are unpaid orders, please pay first, or cancel the order before placing a new one!", + "common.cantUselocker": "This locker cannot be rented, please re-select!", + "common.userName": "User Name", + "common.logout": "Log Out", + "common.logoutTip": "Confirm logout?", + "common.FirstTimeLoginTips": "First-time login will automatically create an account.", + "common.more": "More", + "common.SpaceSpecsGuide": "Space Specs Guide", + "common.Seelegend": "See legend", + "common.Rent": "Rent", + "common.OriginalPrice": "Original Price", + "common.SalePrice": "Sale Price", + "common.SwitchStores": "Switch Stores", + "common.SwitchRegion": "Switch Region", + "common.Countdown": "Countdown", + "common.FlashSale": "Flash Sale", + "common.FlashSalePrice": "Flash Sale Price", + "common.ClickToCheck": "Click To Check", + "common.ClickToZoomIn": "Click To Zoom In", + "common.tryZooming": "If access recognition fails, try clicking to zoom in", + "common.OnSiteAssessment": "On-Site Assessment", + "common.ConsultationQuotation": "Consultation & quotation", + "common.Requirement": "Requirement", + "common.day": "day(s)", + "common.reset": "Reset", + "common.notRented": "Not rented", + "common.rented": "Rented", + "common.locked": "Locked", + "locale.auto": "System", + "locale.en": "English", + "locale.zh-hans": "简体中文", + "locale.zh-hant": "繁体中文", + "locale.ja": "日语", + "index.title": "Hello i18n", + "index.home": "Home", + "index.component": "Component", + "index.api": "API", + "index.schema": "Schema", + "index.demo": "uni-app globalization", + "index.demo-description": "Include uni-framework, manifest.json, pages.json, tabbar, Page, Component, API, Schema", + "index.detail": "Detail", + "index.language": "Language", + "index.language-info": "Settings", + "index.system-language": "System language", + "index.application-language": "Application language", + "index.language-change-confirm": "Applying this setting will restart the app", + "api.message": "Message", + "schema.name": "Name", + "schema.add": "Add", + "schema.add-success": "Add success", + "tabbar.home": "HOME", + "tabbar.book": "BOOK", + "tabbar.unlock": "UNLOCK", + "tabbar.personal": "PERSONAL", + "home.select": "SELECT A STORE", + "home.reserve": "RESERVE", + "home.book": "BOOK NOW", + "home.detail": "DETAILS", + "home.appointment": "APPOINTMENT", + "home.recommend": "RECOMMENDED", + "home.morestore": "MORE STORES", + "home.navigate": "NAVIGATE", + "home.wayfinding": "ROUTE GUIDANCE", + "home.travel": "Travel", + "home.collection": "Collection", + "home.clothes": "Clothes", + "home.appliances": "Appliances", + "home.goods": "Goods", + "home.relocate": "Relocation", + "home.wrapper": "Packing", + "home.material": "Materials", + "home.document": "Document", + "home.device": "Equipment", + "home.supplies": "Supplies", + "home.ecgoods": "E-Commerce", + "home.shops": "RETAIL SHOPS", + "home.individuals": "INDIVIDUALS", + "home.corporates": "CORPORATES", + "home.advantage1": "Guarantee", + "home.advantage1Info1": "Chain Management", + "home.advantage1Info2": "Extensive media coverage", + "home.advantage1Info3": "Best Choice", + "home.advantage2": "Convenience", + "home.advantage2Info1": "24hrs Self-Access", + "home.advantage2Info2": "Smart Lock", + "home.advantage2Info3": "Flexible Term", + "home.advantage3": "Safety", + "home.advantage3Info1": "24hrs CCTV", + "home.advantage3Info2": "One Door One Lock", + "home.advantage3Info3": "Free Insurance", + "home.advantage4": "Cleanliness", + "home.advantage4Info1": "Environment Control", + "home.advantage4Info2": "Fire Safety System", + "home.advantage4Info3": "Regular Sterilization", + "home.interior": "Interior", + "home.serviceHotline": "Customer Service Hotline", + "home.quote": "Quote Now", + "book.location": "LOCATION", + "book.map": "MAP MODE", + "book.list": "LIST MODE", + "book.city": "City", + "book.area": "Area", + "book.get": "Find your nearest store", + "book.getSite": "You need to turn on the location Settings to show the nearest store", + "book.getCode": "Get QR code", + "unlock.door": "DOOR", + "unlock.lock": "LOCK", + "unlock.renew": "RENEW", + "unlock.details": "DETAILS", + "unlock.moveout": "MOVE OUT", + "unlock.cancelPending": "Pending For Move-out Approval", + "unlock.outComplete": "Move-out Completed", + "unlock.cancel": "Cancel", + "unlock.cCancel": "CANCEL", + "unlock.cancelout": "Cancel Move-out Request", + "unlock.return": "RETURN", + "unlock.moveoutReminder": "MOVE OUT REMINDER", + "unlock.moveoutTip": "After you finished the termination procedures, your entrance access will be removed. Please make sure your belongings are taken away. Deposit will be returned in 14 working days.", + "unlock.uploadTip": "Please take a picture of an empty storage unit and upload it.", + "unlock.moveoutSuccess": "Warehouse return request is in process, please patiently wait for staff review!", + "unlock.confirmOut": "MOVE OUT", + "unlock.evaluate": "EVALUATE", + "unlock.disapproval": "DISAPPROVAL", + "unlock.disapprovalRemarks": "Disapproval Remarks", + "unlock.overdue": "OVERDUE", + "unlock.unPaid": "UNPAID", + "unlock.order": "MY ORDER", + "unlock.login": "Click To Login", + "unlock.nodata": "NO DATA", + "unlock.auth": "Auth", + "unlock.FixedPassword": "Fixed Password", + "unlock.AccessControlCardBinding": "Access Control Card Binding", + "unlock.LockCardUnbinding": "Lock Card Binding", + "unlock.getAuthOrder": "View authorized orders", + "unlock.ResetPassword": "Reset Password", + "unlock.remoteOpen": "Remote Access", + "unlock.remoteOpenLoading": "Door Opening...", + "unlock.remoteOpenSuccess": "Access Granted", + "unlock.remoteOpenFail": "Access Denied", + "unlock.fillInventory": "Please fill in the inventory list before using the warehouse", + "unlock.FaceEnrollment": "Enrollment", + "unlock.goToPay": "Go to Pay", + "unlock.cancelOrder": "Cancel Order", + "unlock.Deposit Refund": "Deposit Refund", + "unlock.agreement": "Agreement", + "bingCard.start": "Start pairing", + "bingCard.fail": "The operation failed", + "bingCard.Click": "Click [ Start Pairing ]", + "bingCard.Pairing": "Pairing", + "bingCard.panel": "Place the door card on the dashboard", + "bingCard.single": "You will hear a beep sound when card is paired successfully.", + "bingCard.close": "After success, you can close this pop-up window manually.", + "detail.store": "Store", + "detail.unit": "Unit type", + "detail.spec": "Ref Spec", + "detail.size": "Ref Size", + "detail.cSize": "Ref Volume", + "detail.cUnit": "UNIT TYPE", + "detail.startDate": "START DATE", + "detail.lease": "LEASE TERM", + "detail.rentalFee": "Rental fee", + "detail.cDeposit": "Deposit(1 month)", + "detail.cValueAdded": "VALUE-ADDED", + "detail.nodemand": "No Demand", + "detail.coupon": "COUPON", + "detail.valuation": "ITEM VALUATION", + "detail.currency": "(Currency: RMB)", + "detail.extraTip": "If your belongings exceed a valuation of $5000, please insure the premium yourself.", + "detail.feeDetail": "FEE DETAILS", + "detail.deposit": "Deposit", + "detail.valueAdded": "Value-added", + "detail.discount": "Discount", + "detail.total": "Total", + "detail.next": "NEXT", + "detail.read": "I have read and agreed on ", + "detail.agreement": "[User Service Agreement]", + "detail.agreeTip": "Please read and agree on [User Service Agreement].", + "detail.orderNum": "ORDER NUMBER", + "detail.type": "UNIT TYPE", + "detail.period": "LEASE PERIOD", + "detail.click": "Details: Click on", + "detail.sitemap": "SITEMAP", + "detail.selected": "SELECTED", + "detail.nodata": "No Data", + "detail.noselect": "No Select", + "detail.RENEWAL": "RENEWAL", + "detail.RefundableDeposit": "Refundable Deposit", + "detail.to": "TO", + "detail.quotation": "Quotation", + "detail.generateQuotation": "Generate Quotation", + "detail.regenerateQuotation": "Re-Generate Quotation", + "detail.viewQuotation": "View Quotation", + "detail.quotationFail": "Quotation generation failed", + "detail.quotationSuccess": "Please manually save or forward the quotation", + "detail.agreeTerm": "Agree to Terms", + "detail.scrollRead": "Please read all terms before agreeing", + "detail.points": "Points", + "detail.PointsRedemption": "Points Redemption", + "detail.AvailablePoints": "Available Points", + "detail.DeductionAmount": "Deduction Amount", + "door.refresh": "Refresh QR code", + "door.refreshPwd": "Refresh Password", + "door.tip": "Use facial recgonition device to scan QR code.", + "door.valid": "Valid for 1 minute.", + "door.pwd": "Enter the password to unlock.", + "door.Unlock": "Unlock", + "door.UnlockSuccessful": "Unlock Successful", + "person.order": "Order details", + "person.promotion": "Promotion", + "person.identify": "Identification", + "person.invoice": "Invoice", + "person.guide": "User guide", + "person.customer": "Customer service", + "person.invitation": "Invitation", + "person.evaluation": "Evaluation", + "person.latestEvents": "Latest Events", + "person.lock": "Locks", + "person.share": "SHARE AND GAIN RENT-GREE", + "person.join": "JOIN NOW", + "person.VideoTutorial": "Tutorial", + "person.referrerInfo": "Referrer Info", + "site.branch": "BRANCH", + "site.address": "Address", + "site.tip": "*illegal items are strictly prohibited", + "site.tip2": "*Charges are based on internal dimensions only", + "site.ReferenceVolume": "Ref Volume", + "site.WarehouseInternalDimensions": "Int. Dims", + "site.full": "SORRY,THIS TYPE IS FULL,PLEASE SELECT ANOTHER TYPE.", + "site.appointment": "Appointment", + "site.appointmentSuccess": "Appointment successful. Our staff will contact you shortly, please keep your phone accessible!", + "site.hadAppointment": "Already Appointment", + "site.cancelAppointment": "Whether to cancel the reservation", + "site.noAccessId": "The accesscontrol ID is not available", + "site.noPermission": "There is no permission for this store", + "login.account": "account", + "login.password": "password", + "login.confirm": "confirm password", + "login.code": "code", + "login.input": "Please input", + "login.login": "Log in", + "login.wxLogin": "WeChat Login", + "login.register": "Register an account", + "login.forget": "forget the password?", + "login.send": "SEND", + "login.change": "Change", + "login.toLogin": "LOGIN AN ACCOUNT", + "login.registered": "Registered", + "login.different": "The password is different.", + "login.phone": "Phone Number", + "login.inputPhone": "Please enter your phone number", + "login.phoneFormat": "Invalid phone format", + "login.inputCode": "Please enter the code", + "login.getCode": "Get Code", + "login.sending": "Sending...", + "login.sendSuccess": "Code sent", + "login.UserAgreement": "《User Agreement》", + "login.andAgreeTo": "and agree to", + "request.tip": "Tips", + "request.cancel": "Cancel", + "request.confirm": "Confirm", + "request.loginContent": "No login, whether to jump to the login page", + "request.captchaError": "CAPTCHA error or expired", + "request.userCancel": "Request canceled by user", + "request.timeout": "Network request timed out", + "request.noConnect": "Failed to connect to server", + "request.error": "Error", + "toast.copy": "Successful replication", + "invite.title1": "Invite friends and", + "invite.title2": "win the rewards.", + "invite.number": "Invitations", + "invite.activity": "Mechanism", + "invite.branch": "Branch", + "invite.details": "Details", + "invite.toInvite": "INVITE NOW", + "invite.record": "View records", + "invite.disclaimer": "* Disclaimer:", + "invite.disContent": " the sole decision of Storage Limited shall be final in case of any dispute.", + "common.edit": "Edit", + "common.paySuccess": "Payment Successful", + "common.payFail": "Payment Failed, Please Try Again!", + "common.$": "$", + "common.notStarted": "Not Started", + "common.status": "Status", + "common.verifyInfo": " Info Verify", + "common.infoUpdate": "Info Update", + "common.saveInfo": "Save Info", + "common.personalAuth": "Personal Auth", + "common.businessAuth": "Business Auth", + "common.IdCardFont": "Upload ID Front", + "common.IdCardBack": "Upload ID Back", + "common.UploadBusinessLicense": "Upload Business License", + "common.noOpen": "Not open, contact staff for details!", + "common.isGoAuth": "Upload personal information for verification.", + "common.Authentication": "Authentication", + "common.submit": "Submit", + "common.placeInputAll": "Please enter all the information", + "common.goodsList": "Goods List", + "common.OnlineConsultation": "Consultation", + "common.avatar": "Avatar", + "common.uploadAvatar": "Upload Avatar", + "common.nickname": "Nickname", + "common.phone": "Phone", + "common.bindPhone": "Bind Phone", + "common.bindPhoneAfter": "Bind the mobile phone number before performing this operation", + "common.bindPhoneUnlock": "Bind the phone number to get the order information", + "common.QuickBind": "Quick Bind", + "common.cancelBind": "Cancel Bind", + "common.facialData": "Facial Data", + "common.auth": "Authorization", + "common.requireAvatar": "Please upload the profile picture", + "common.requireName": "Please enter the nickname", + "common.requirePhone": "Please enter the phone number", + "common.note": "Notes", + "common.tip": "Tip", + "common.cancelApply": "Are you sure to cancel the application?", + "common.cancelSuccess": "Cancel successfully", + "common.cancelFail": "Cancel failed. Please try again later!", + "common.addOrder": "Confirm Order", + "common.AuthenticationFailedTips": "Your identity verification has not been approved.You may still place an order for same-day warehouse use (within the rental period).However, starting from the next day, you must submit valid identity information and pass verification to continue using the warehouse.", + "common.VacantDay": "Vacant Day", + "common.RemainingDay": "Remaining Day", + "common.OverdueDay": "Overdue Day", + "common.ORDER_AMOUNT_ERROR": "Invalid discount amount. Please select again.", + "common.tuangouCouponPrice": "tuangou coupon price", + "common.checkAgreementUrl": "Please read and agree to the terms first.", + "common.Expand": "Expand", + "common.Collapse": "Collapse", + "common.OtherStores": "Other Stores", + "coupon.coupon": "Coupon", + "coupon.meituanOrdazhongdianpingCoupon": "Meituan/Dazhongdianping Coupon", + "coupon.queryMeituanDazhongdianpingCoupon": "Click to check Meituan/Dianping coupons", + "coupon.useTips": "Instruction: Enter the coupon code to enjoy the discount.", + "coupon.enterCode": "Coupon code", + "coupon.limitedtimeoffer": "Limited-time offer", + "coupon.storewide": "Store-wide", + "coupon.redeemNow": "Redeem", + "coupon.instructions": "Instructions", + "coupon.validityPeriod": "Expiry", + "coupon.apply": "Apply", + "coupon.all": "All Unit Types", + "coupon.multiStoreUse": "Multi-store use", + "coupon.renewable": "Usable on reorders", + "coupon.noRenewable": "Not usable on reorders", + "coupon.redemptionuccessful": "Redemption successful", + "coupon.unusableCoupons": "Unusable Coupons", + "coupon.currentConditionsNotMet": "Current conditions not met", + "request.promoCodeError": "Promo code error", + "validation.getPhoneFail": "Failed to obtain the phone number, please enter it manually", + "validation.inputName1": "Please input the name", + "validation.selectCardType": "Please select the card type", + "validation.inputIdCard": "Please input the ID number", + "validation.uploadIdCard": "Please upload your ID photo", + "validation.inputPhone": "Please input the phone number", + "validation.inputInternationalPhone": "Please input the international phone number", + "validation.uploadImg": "The picture is uploading, please try again later", + "validation.inputName2": "Please input the company name", + "validation.inputLicense": "Please input the business license number", + "validation.uploadLicense": "Please upload your business ID card", + "validation.submitSuccess": "Submit successfully", + "validation.uploadSuccess": "Update successfully", + "validation.identifyCard": "China ID Card", + "validation.passport": "Passport", + "validation.permit": "Hong Kong and Macao Permit", + "validation.access": "One-click Access", + "validation.bind": "Binding", + "validation.vailSuccess": "Verification successful.", + "validation.agree": "Please read and agree to the User Service Agreement and Privacy Policy.", + "agreement.readAndAgree": "I have read and agree to the", + "agreement.service": "User Service Agreement", + "agreement.and": "and", + "agreement.privacy": "Privacy Policy", + "agreement.toast": "Please read and agree to the User Service Agreement and Privacy Policy.", + "verification.vailFail": "Authentication failed. Please verify that the document type and information are correct, and re-upload a clear image (front and back). Try authenticating again!", + "verification.vailSuccess": "Authentication successful.", + "invoiceApply.electronicInvoice": "Electronic Invoice", + "invoiceApply.paperInvoice": "Paper Invoice", + "invoiceApply.invoiceTips": "Your invoice application has been submitted successfully, please wait patiently for the staff to contact!", + "invoice.valid": "Invoices", + "invoice.pay": "Payment Time", + "invoice.site": "Store", + "invoice.type": "Unit Type", + "invoice.unit": "Unit", + "invoice.rent": "Lease Term", + "invoice.record": "Application Record", + "invoice.allSelect": "Select All", + "invoice.nextStep": "NEXT", + "invoice.tip": "- Invoices can be issued within one month after payment of the order", + "invoice.serial": "Number", + "invoice.time": "Application Time", + "invoice.status": "Audit Status", + "invoice.status0": "Pending approval", + "invoice.status1": "Approved, invoicing...", + "invoice.status2": "Failed approval", + "invoice.status3": "Cancelled", + "invoice.status4": "Invoiced", + "invoice.selectOrder": "Please select an order", + "invoice.validMoney": "The order amount must be greater than 0", + "evaluate.customerEvaluation": "CUSTOMER EVALUATION", + "evaluate.overallRating": "Overall rating", + "evaluate.userExperience": "User experience", + "evaluate.Hospitality": "Hospitality", + "evaluate.cleanliness": "Cleanliness", + "evaluate.convenience": "Convenience", + "evaluate.tips": "Please leave your invaluable comment or suggestion here.", + "evaluate.anonymous": "ANONYMOUS", + "goodsList.note": "Please note", + "goodsList.info": "Hello, according to the requirements of relevant departments, the items you store need to be declared independently for their category. This declaration form is for record keeping purposes, please fill it out carefully.", + "goodsList.multi": "Multiple choices", + "goodsList.tip1": "User Confirmation:", + "goodsList.tip2": "1. The stored items were obtained through legal channels;", + "goodsList.tip3": "2. Do not store prohibited items;", + "goodsList.tip4": "3. If property damage or personal injury is caused by changes in the user's stored items or other reasons, the user shall bear the responsibility.", + "goodsList.submit": "Confirm", + "houseKey.FriendsName": "Friend's name", + "houseKey.AuthorizationDate": "Authorization date", + "houseKey.ReceiveNotifications": "Receive notifications", + "houseKey.EnableNotifications": "Enable notifications", + "houseKey.PhoneNumber": "Phone number", + "houseKey.email": "Email", + "houseKey.EnterAuthorizedPhoneNumber": "Enter authorized person's phone number", + "houseKey.AddAuthorization": "Add authorization", + "houseKey.EnterFriendsName": "Enter friend's name", + "houseKey.EnterAuthorizationDate": "Enter authorization date", + "houseKey.EnterPhoneNumber": "Enter phone number", + "houseKey.EnterEmail": "Enter email", + "houseKey.CannotAuthorizeYourself": "Cannot authorize yourself", + "houseKey.UpdateSuccessful": "Update successful", + "houseKey.AddedSuccessfully": "Added successfully", + "houseKey.date": "Year-Month-Day", + "houseKey.overdue": "The authorization period has expired. Please re-select the authorization period and renew it.", + "houseKey.otherPhone": "The phone number of the authorized party", + "houseKey.otherEmail": "The email address of the authorized party", + "houseKey.getNote": "Open to receive notifications", + "unitTypeDetail.oneMonth": "Lease term: one month", + "unitTypeDetail.reference": "Reference", + "unitTypeDetail.discount": "Discount", + "reserve.FULLNAME": "Full Name", + "reserve.PHONE": "Phone", + "reserve.REGION": "Region", + "reserve.TYPE": "Type", + "reserve.PHONE NUMBER": "Phone Number", + "reserve.Individual & Family": "Individual & Family", + "reserve.Business & E-commerce": "Business & E-commerce", + "reserve.Retail & Store": "Retail & Store", + "reserve.contentTips": "Appointment successful! Please wait patiently for our staff to contact you. Keep your phone available. Thank you!", + "inviteDetail.title": "Invitation Records", + "inviteDetail.Username": "Username", + "inviteDetail.Registration Date": "Registration Date", + "inviteDetail.Status": "Status", + "inviteDetail.No invitation": "No invitation records found. Please share invitations.", + "inviteDetail.SORRY": "SORRY, THERE ARE NO RECORDS. PLEASE SHARE AND INVITE.", + "inviteDetail.Share Invitation": "Share Invitation", + "referrerInfo.company": "Referrer Company", + "referrerInfo.branch": "Referrer Branch", + "referrerInfo.commission": "Referral Commission Rate", + "referrerInfo.inviteRegister": "Invitation to Register", + "referrerInfo.inviteRecord": "Invitation Record", + "referrerInfo.inviteUserName": "User Name", + "referrerInfo.invitePhone": "Phone Number", + "referrerInfo.registrationTime": "Registration Time", + "referrerInfo.inviteEmpty": "No invitation record", + "referrerInfo.loadQrCode": "Download QR Code", + "referrerInfo.loadPoster": "Download Poster", + "referrerInfo.forwardInvitation": "Forward Invitation", + "pointsMall.title": "Points Mall", + "pointsMall.myPoints": "My Points", + "pointsMall.pointsUnit": "Points", + "pointsMall.exchange": "Redeem", + "pointsMall.exchangeFormTitle": "Shipping Information", + "pointsMall.submit": "Submit", + "pointsMall.receiverName": "Recipient Name", + "pointsMall.phone": "Phone Number", + "pointsMall.address": "Address", + "pointsMall.placeholderName": "Enter recipient name", + "pointsMall.placeholderPhone": "Enter phone number", + "pointsMall.placeholderAddress": "Enter detailed shipping address", + "pointsMall.exchangeConfirmTitle": "Exchange Confirmation", + "pointsMall.exchangeConfirmTip": "Are you sure you want to use {points} points to redeem?", + "pointsMall.stock": "Stock", + "pointsMall.successTitle": "Success", + "pointsMall.successTip": "Redemption successful. Please wait for our staff to contact you. Thank you!", + "pointsMall.toastOutOfStock": "Out of stock", + "pointsMall.toastNotEnoughPoints": "Not enough points", + "pointsMall.toastExchanging": "Redeeming...", + "pointsMall.toastExchangeFailed": "Redemption failed", + "pointsMall.exchangeRecordTitle": "Redemption Records", + "pointsMall.noExchangeRecord": "No redemption records" +} \ No newline at end of file diff --git a/locale/index.js b/locale/index.js new file mode 100644 index 0000000..7a96591 --- /dev/null +++ b/locale/index.js @@ -0,0 +1,38 @@ +import { createI18n } from 'vue-i18n'; + +// 导入静态翻译内容 +import en from './en.json'; +import zhHans from './zh-Hans.json'; +import zhHant from './zh-Hant.json'; +import ja from './ja.json'; +// 导入动态翻译函数 +import messagesFunctions from './messagesFunctions.js'; + +// 合并静态和动态的翻译内容 +const mergedMessages = { + en: { + ...en, + ...messagesFunctions.en, + }, + 'zh-Hans': { + ...zhHans, + ...messagesFunctions.zhHans, + }, + 'zh-Hant': { + ...zhHant, + ...messagesFunctions.zhHant, + }, + ja: { + ...ja, + ...messagesFunctions.ja, + }, +}; + +const language = "zh-Hans"; +const i18n = createI18n({ + locale: language, + messages: mergedMessages +}); +uni.setStorageSync("eliteSys-language-wx", language); + +export default i18n; \ No newline at end of file diff --git a/locale/ja.json b/locale/ja.json new file mode 100644 index 0000000..b2fa1b8 --- /dev/null +++ b/locale/ja.json @@ -0,0 +1,23 @@ +{ + "locale.auto": "システム", + "locale.en": "英語", + "locale.zh-hans": "简体中文", + "locale.zh-hant": "繁体中文", + "locale.ja": "日语", + "index.title": "Hello i18n", + "index.home": "ホーム", + "index.component": "コンポーネント", + "index.api": "API", + "index.schema": "Schema", + "index.demo": "uni-app globalization", + "index.demo-description": "ユニフレームワーク、manifest.json、pages.json、タブバー、ページ、コンポーネント、APIを含める、Schema", + "index.detail": "詳細", + "index.language": "言語", + "index.language-info": "設定", + "index.system-language": "システム言語", + "index.application-language": "アプリケーション言語", + "index.language-change-confirm": "この設定を適用すると、アプリが再起動します", + "api.message": "メッセージ", + "schema.add": "追加", + "schema.add-success": "成功を追加" +} diff --git a/locale/messagesFunctions.js b/locale/messagesFunctions.js new file mode 100644 index 0000000..d0e7fad --- /dev/null +++ b/locale/messagesFunctions.js @@ -0,0 +1,49 @@ +const numToChinese = (num) => { + if(num<1) num = 1 + const map = ['零','一','二','三','四','五','六','七','八','九'] + return map[num] || num.toString() +} +export default { + en: { + 'person.inviteData': ({ named }) => `Already invited ${named('friends')} friends, Opportunity to receive additional rewards`, + "detail.remain": ({ named }) => `Remaining ${named('days')} days`, + "detail.discountOff": ({ named }) => `${named('month')} MONTHS ${named('percent')}% OFF`, + "month": ({ named }) => `${named('count')} month(s)`, + "months": ({ named }) => `${named('count')} month(s)`, + "discountMomey": ({ named }) => `${named('discount')} Discount `, + "firstMonthRent": ({ named }) => `First Month Rent ${named('discount')}`, + "couponDiscount": ({ named }) => `${named('percent')} off `, + "freeMonth": ({ named }) => `Free ${named('discount')} months`, + "BonusMonth": ({ named }) => `Bonus ${named('discount')} months`, + "requiredMomey": ({ named }) => `${named('momey')} required`, + "fullMonths": ({ named }) => `available after ${named('count')} full months`, + "invoice.order": ({ named }) => `${named('number')} orders have been selected, totaling ${named('money')} yuan`, + "giftMonth": ({ named }) => `Gifted ${named('count')} months`, + "storeRenovationNotice": ({ named }) => `This store is under renovation. It will be available on ${named('limitDate')}. Orders can be placed in advance.`, + "storeCount": ({ named }) => `${named('count')} stores`, + "discount": ({ named }) => `${Math.floor(named('discount') * 100)}% off`, + "flashSaleDiscount": ({ named }) => `Extra ${Math.floor(named('discount') * 100)}% off`, + 'order.confirmReferrer': ({ named }) => `This order will be associated with the referrer ${named('referrer')}. Please confirm whether this transaction was completed through their referral.`, + }, + zhHans: { + 'person.inviteData': ({ named }) => `已邀请 ${named('friends')} 名好友, 有机会获得额外奖励`, //获得 ${named('days')} 天免费租期! + "detail.remain": ({ named }) => `租期:剩余${named('days')}天`, + "detail.discountOff": ({ named }) => `${named('month')}个月享${named('discount')}折`, + "month": ({ named }) => `${named('count')} 月`, + "months": ({ named }) => `${named('count')} 月`, + "discountMomey": ({ named }) => `优惠 ¥${named('discount')} `, + "firstMonthRent": ({ named }) => `首月 ${named('discount')} 元`, + "couponDiscount": ({ named }) => ` 打 ${named('discount')} 折 `, + "freeMonth": ({ named }) => `免租 ${named('discount')} 个月`, + "BonusMonth": ({ named }) => `赠送 ${named('discount')} 个月`, + "requiredMomey": ({ named }) => `满¥${named('momey')} 可用`, + "fullMonths": ({ named }) => `满 ${named('count')} 个月可用`, + "invoice.order": ({ named }) => `已选 ${named('number')} 个订单,共 ${named('money')} 元`, + "giftMonth": ({ named }) => `赠送 ${named('count')} 个月`, + "storeRenovationNotice": ({ named }) =>`该店铺装修中,将于 ${named('limitDate')} 开放使用,可提前下单`, + "storeCount": ({ named }) => `一共 ${named('count')} 店`, + "discount": ({ named }) => `${numToChinese(Math.floor(named('discount') * 10))||numToChinese[1]} 折`, + "flashSaleDiscount": ({ named }) => `额外${numToChinese(Math.floor(named('discount') * 10))}折`, + 'order.confirmReferrer': ({ named }) => `此订单将关联至转介人 ${named('referrer')}。请确认是否通过他的推荐完成本次交易?`, + }, +}; diff --git a/locale/uni-app.ja.json b/locale/uni-app.ja.json new file mode 100644 index 0000000..41cef76 --- /dev/null +++ b/locale/uni-app.ja.json @@ -0,0 +1,36 @@ +{ + "common": { + "uni.app.quit": "もう一度押すと、アプリケーションが終了します", + "uni.async.error": "サーバーへの接続がタイムアウトしました。画面をクリックして再試行してください", + "uni.showActionSheet.cancel": "キャンセル", + "uni.showToast.unpaired": "使用するには、showToastとhideToastをペアにする必要があることに注意してください", + "uni.showLoading.unpaired": "使用するには、showLoadingとhideLoadingをペアにする必要があることに注意してください", + "uni.showModal.cancel": "キャンセル", + "uni.showModal.confirm": "OK", + "uni.chooseImage.cancel": "キャンセル", + "uni.chooseImage.sourceType.album": "アルバムから選択", + "uni.chooseImage.sourceType.camera": "カメラ", + "uni.chooseVideo.cancel": "キャンセル", + "uni.chooseVideo.sourceType.album": "アルバムから選択", + "uni.chooseVideo.sourceType.camera": "カメラ", + "uni.previewImage.cancel": "キャンセル", + "uni.previewImage.button.save": "画像を保存", + "uni.previewImage.save.success": "画像をアルバムに正常に保存します", + "uni.previewImage.save.fail": "画像をアルバムに保存できませんでした", + "uni.setClipboardData.success": "コンテンツがコピーされました", + "uni.scanCode.title": "スキャンコード", + "uni.scanCode.album": "アルバム", + "uni.scanCode.fail": "認識に失敗しました", + "uni.scanCode.flash.on": "タッチして点灯", + "uni.scanCode.flash.off": "タップして閉じる", + "uni.startSoterAuthentication.authContent": "指紋認識...", + "uni.picker.done": "完了", + "uni.picker.cancel": "キャンセル", + "uni.video.danmu": "「弾幕」", + "uni.video.volume": "ボリューム", + "uni.button.feedback.title": "質問のフィードバック", + "uni.button.feedback.send": "送信" + }, + "ios": {}, + "android": {} +} diff --git a/locale/zh-Hans.json b/locale/zh-Hans.json new file mode 100644 index 0000000..597f8ec --- /dev/null +++ b/locale/zh-Hans.json @@ -0,0 +1,502 @@ +{ + "common.confirm": "确认", + "common.cancel": "取消", + "common.title": "提示", + "common.noData": "暂无数据", + "common.delete": "删除", + "common.update": "更新", + "common.password": "密码", + "common.close": "关闭", + "common.Skiptoday": "暂时跳过", + "common.payableTime": "剩余支付时间", + "common.AuthorizationOrder": "授权订单", + "common.cancelOrder": "取消订单", + "common.cancelOrderTips": "确认取消当前订单?", + "common.unpaidOrderTips": "存在未支付订单,请先支付,或者取消订单后再下单!", + "common.cantUselocker": "此体积仓位不可租用,请重新选择!", + "common.checkAgreementUrl": "请先阅读并同意协议", + "common.logout": "登出", + "common.logoutTip": "确认退出程序?", + "common.FirstTimeLoginTips": "「首次登录将自动注册」", + "common.SpaceSpecsGuide": "空间规格介绍参考", + "common.Seelegend": "查看图例", + "common.Rent": "租用", + "common.OriginalPrice": "原价格", + "common.SalePrice": "活动价", + "common.SwitchStores": "切换同地址分店", + "common.more": "更多", + "common.SwitchRegion": "切换区域", + "common.Countdown": "倒计时", + "common.FlashSale": "限时抢购", + "common.FlashSalePrice": "限时抢购价", + "common.ClickToCheck": "点击查看", + "common.ClickToZoomIn": "点击放大", + "common.tryZooming": "如果门禁识别不成功,可尝试点击放大", + "common.OnSiteAssessment": "上门评估", + "common.ConsultationQuotation": "咨询报价", + "common.Requirement": "需求", + "common.day": "天", + "common.reset": "重置", + "common.notRented": "未租", + "common.rented": "已租", + "common.locked": "鎖定", + "locale.auto": "系统", + "locale.en": "English", + "locale.zh-hans": "简体中文", + "locale.zh-hant": "繁体中文", + "locale.ja": "日语", + "index.title": "Hello i18n", + "index.home": "主页", + "index.component": "组件", + "index.api": "API", + "index.schema": "Schema", + "index.demo": "uni-app 国际化演示", + "index.demo-description": "包含 uni-framework、manifest.json、pages.json、tabbar、页面、组件、API、Schema", + "index.detail": "详情", + "index.language": "语言", + "index.language-info": "语言信息", + "index.system-language": "系统语言", + "index.application-language": "应用语言", + "index.language-change-confirm": "应用此设置将重启App", + "api.message": "提示", + "schema.name": "姓名", + "schema.add": "新增", + "schema.add-success": "新增成功", + "tabbar.home": "首页", + "tabbar.book": "订仓", + "tabbar.unlock": "用仓", + "tabbar.personal": "我的", + "home.select": "选择分店", + "home.reserve": "立即预约", + "home.book": "立即订仓", + "home.detail": "查看详情", + "home.appointment": "立即预约", + "home.recommend": "热推门店", + "home.morestore": "所有门店", + "home.navigate": "导航", + "home.wayfinding": "路径指引", + "home.travel": "出差寄存", + "home.collection": "玩具收藏", + "home.clothes": "衣物鞋帽", + "home.appliances": "家具家电", + "home.goods": "门店货物", + "home.relocate": "搬迁装修", + "home.wrapper": "包装材料", + "home.material": "物资储备", + "home.document": "文件档案", + "home.device": "办公设备", + "home.supplies": "活动物资", + "home.ecgoods": "电商货品", + "home.shops": "零售·门店", + "home.individuals": "个人·家庭", + "home.corporates": "企业·电商", + "home.advantage1": "连锁经营", + "home.advantage1Info1": "实力保证 覆盖广深", + "home.advantage1Info2": "南方卫视 多家采访", + "home.advantage1Info3": "千万用户 最优选择", + "home.advantage2": "使用方便", + "home.advantage2Info1": "全天开放 随时存取", + "home.advantage2Info2": "手机开仓 手机开锁", + "home.advantage2Info3": "一个月起 即租即用", + "home.advantage3": "安全保障", + "home.advantage3Info1": "实时监控 无死角位", + "home.advantage3Info2": "一人一仓 独立储物", + "home.advantage3Info3": "免费保险 保驾护航", + "home.advantage4": "环境整洁", + "home.advantage4Info1": "温度调节 防虫防鼠", + "home.advantage4Info2": "配备消防 光洁明亮", + "home.advantage4Info3": "定期保洁 专业消毒", + "home.interior": "参照", + "home.serviceHotline": "客服热线", + "home.quote": "立即查价", + "book.location": "地区筛选", + "book.map": "地图模式", + "book.list": "列表模式", + "book.city": "城市", + "book.area": "区域", + "book.get": "查找离你最近的店铺", + "book.getSite": "需要打开位置信息设置,来显示最近店铺", + "book.getCode": "获取二维码", + "unlock.door": "开门", + "unlock.lock": "开锁", + "unlock.renew": "续仓", + "unlock.details": "详情", + "unlock.moveout": "退仓", + "unlock.cancelPending": "退仓申请中", + "unlock.outComplete": "退仓完成", + "unlock.cancel": "取消", + "unlock.cCancel": "取消", + "unlock.cancelout": "取消退仓请求", + "unlock.return": "返回", + "unlock.moveoutReminder": "退仓提示", + "unlock.moveoutTip": "退仓后,您将失去开门权限!请确认已经清空仓内物品,14个工作日内,系统将会自动返还押金。", + "unlock.uploadTip": "请上传清空仓库后的照片。", + "unlock.moveoutSuccess": "退仓申请中,请等待耐心工作人员审核!", + "unlock.confirmOut": "确定退仓", + "unlock.evaluate": "评价", + "unlock.disapproval": "退仓驳回", + "unlock.disapprovalRemarks": "驳回理由", + "unlock.overdue": "已逾期", + "unlock.unPaid": "未支付", + "unlock.order": "我的订单", + "unlock.login": "点击登录,查看下单仓库", + "unlock.nodata": "暂无数据", + "unlock.auth": "授权", + "unlock.FixedPassword": "固定密码", + "unlock.AccessControlCardBinding": "门禁绑卡", + "unlock.LockCardUnbinding": "锁绑卡", + "unlock.getAuthOrder": "查看授权订单", + "unlock.ResetPassword": "重置密码", + "unlock.remoteOpen": "远程开门", + "unlock.remoteOpenLoading": "开门中...", + "unlock.remoteOpenSuccess": "开门成功", + "unlock.remoteOpenFail": "开门失败", + "unlock.fillInventory": "用仓前,请先填写物品清单", + "unlock.FaceEnrollment": "录入门禁", + "unlock.goToPay": "去支付", + "unlock.cancelOrder": "取消订单", + "unlock.Deposit Refund": "押金退款", + "unlock.agreement": "订仓协议", + "bingCard.start": "开始配对", + "bingCard.fail": "操作失败", + "bingCard.Click": "点击[ 开始配对 ]", + "bingCard.Pairing": "配对中", + "bingCard.panel": "请将ID卡开放在数位面板上", + "bingCard.single": "滴一声证明成功", + "bingCard.close": "成功后,可手工关闭此弹窗", + "detail.store": "门店", + "detail.unit": "仓型", + "detail.spec": "参考尺寸", + "detail.size": "参考体积", + "detail.cSize": "参考体积", + "detail.cUnit": "已选仓型", + "detail.startDate": "启用日期", + "detail.lease": "租赁期限", + "detail.rentalFee": "租仓费用", + "detail.cDeposit": "押金费用(一个月)", + "detail.cValueAdded": "额外服务", + "detail.nodemand": "无需求", + "detail.coupon": "使用优惠", + "detail.valuation": "费用详情", + "detail.currency": "(单位: 人民币)", + "detail.extraTip": "若您的物品估算金额超出¥5000,超出部分请您自行投保。", + "detail.feeDetail": "费用详情", + "detail.deposit": "押金费用", + "detail.valueAdded": "额外费用", + "detail.discount": "优惠抵扣", + "detail.total": "总共费用", + "detail.next": "下一步", + "detail.read": "我已经阅读并同意 ", + "detail.agreement": "《订仓协议》", + "detail.agreeTip": "请阅读并同意《订仓协议》", + "detail.orderNum": "订单序号", + "detail.type": "仓库", + "detail.period": "租赁时期", + "detail.click": "详情:点击查看订单", + "detail.sitemap": "平面图", + "detail.selected": "已选仓位", + "detail.nodata": "未选填需求", + "detail.noselect": "未选优惠", + "detail.RENEWAL": "续仓记录", + "detail.RefundableDeposit": "可退押金", + "detail.to": "续费至", + "detail.quotation": "报价单", + "detail.generateQuotation": "生成报价单", + "detail.regenerateQuotation": "重新生成报价单", + "detail.viewQuotation": "查看报价单", + "detail.quotationFail": "生成报价单失败", + "detail.quotationSuccess": "请手动保存或转发报价单", + "detail.scrollRead": "請在同意前閱讀所有條款", + "detail.agreeTerm": "同意條款", + "detail.points": "积分", + "detail.PointsRedemption": "积分抵扣", + "detail.AvailablePoints": "可用积分", + "detail.DeductionAmount": "抵扣金额", + "door.refresh": "刷新二维码", + "door.refreshPwd": "刷新密码", + "door.tip": "使用门禁设备扫描二维码", + "door.valid": "有效时限为1分钟", + "door.pwd": "输入密码即可开锁", + "door.Unlock": "开锁", + "door.UnlockSuccessful": "开锁成功", + "person.order": "订单详情", + "person.promotion": "优惠卡包", + "person.identify": "信息认证", + "person.invoice": "发票申请", + "person.guide": "用户指南", + "person.customer": "客服咨询", + "person.invitation": "邀请详情", + "person.evaluation": "用户评价", + "person.latestEvents": "最新活动", + "person.lock": "锁具管理", + "person.share": "分享即送免费租期", + "person.join": "立即参加", + "person.VideoTutorial": "视频教程", + "person.referrerInfo": "推荐人信息", + "site.branch": "分店", + "site.address": "地址", + "site.tip": "*非违规违禁物品均可存放", + "site.tip2": "*仅按仓内尺寸收费", + "site.ReferenceVolume": "参考体积", + "site.WarehouseInternalDimensions": "仓内尺寸", + "site.full": "抱歉,此仓型已租满,请选择其他仓型。", + "site.appointment": "候补预约", + "site.appointmentSuccess": "预约成功。随后工作人员会联系你,请保持手机顺畅!", + "site.hadAppointment": "已预约", + "site.cancelAppointment": "是否取消预约", + "site.noAccessId": "暂无门禁设备accesscontrol ID", + "site.noPermission": "暂无该门店的权限", + "login.account": "账号", + "login.password": "密码", + "login.confirm": "确认密码", + "login.code": "验证码", + "login.input": "请输入", + "login.login": "登录", + "login.wxLogin": "手机号快捷登录", + "login.register": "注册账号", + "login.forget": "忘记密码?", + "login.send": "发送", + "login.change": "更改", + "login.toLogin": "登录账号", + "login.registered": "注册", + "login.different": "密码不一致", + "login.phone": "手机号", + "login.inputPhone": "请输入手机号", + "login.phoneFormat": "手机号格式错误", + "login.inputCode": "请输入验证码", + "login.getCode": "获取验证码", + "login.sending": "发送中...", + "login.sendSuccess": "验证码已发送", + "login.UserAgreement": "《用户协议》", + "login.andAgreeTo": "同意并接受", + "request.tip": "提示", + "request.cancel": "取消", + "request.confirm": "确认", + "request.loginContent": "未登录,是否前往登录页面", + "request.captchaError": "验证码错误或已过期", + "request.userCancel": "用户取消请求", + "request.timeout": "网络请求超时", + "request.noConnect": "连接服务器失败", + "request.error": "错误", + "toast.copy": "复制成功", + "invite.title1": "邀好友", + "invite.title2": "赢优惠券", + "invite.number": "邀请人数", + "invite.activity": "活动内容", + "invite.branch": "适用门店", + "invite.details": "详情咨询", + "invite.toInvite": "去邀请", + "invite.record": "查看邀请记录", + "invite.disclaimer": "* 活动解释权归迷你仓所有", + "invite.disContent": "", + "common.edit": "编辑", + "common.paySuccess": "支付成功", + "common.payFail": "支付失败,请重新尝试!", + "common.$": "¥", + "common.notStarted": "未开始", + "common.status": "状态", + "common.verifyInfo": "信息认证", + "common.infoUpdate": "信息修改", + "common.saveInfo": "保存信息", + "common.personalAuth": "个人认证", + "common.businessAuth": "企业认证", + "common.IdCardFont": "上传证件照正面", + "common.IdCardBack": "上传证件照反面", + "common.UploadBusinessLicense": "上传营业执照", + "common.noOpen": "暂未开放,详细请联系工作人员!", + "common.isGoAuth": "所有用户必须进行身份验证。方可用仓。", + "common.Authentication": "身份验证", + "common.submit": "提交", + "common.placeInputAll": "请填写完信息后提交", + "common.goodsList": "物品清单", + "common.OnlineConsultation": "在线咨询", + "common.avatar": "头像", + "common.uploadAvatar": "上传头像", + "common.nickname": "昵称", + "common.phone": "手机号", + "common.facialData": "数据", + "common.bindPhone": "绑定手机号", + "common.bindPhoneAfter": "请先绑定手机号再进行此操作", + "common.bindPhoneUnlock": "请绑定手机号才能获取订单信息", + "common.QuickBind": "快速绑定", + "common.cancelBind": "暂不授权", + "common.auth": "授权", + "common.requireAvatar": "请上传头像", + "common.requireName": "请输入昵称", + "common.requirePhone": "请输入手机号", + "common.note": "备注", + "common.tip": "提示", + "common.cancelApply": "确定取消申请吗?", + "common.cancelSuccess": "取消成功", + "common.cancelFail": "取消失败,请稍后重试!", + "common.addOrder": "直接下单", + "common.AuthenticationFailedTips": "您当前身份信息认证未通过,下单当天可用仓(租赁期内),第二天起需要提交正确的身份信息且验证通过,方可继续用仓。", + "common.VacantDay": "空闲", + "common.RemainingDay": "剩余", + "common.OverdueDay": "逾期", + "common.ORDER_AMOUNT_ERROR": "订单金额必须大于0.01元,请重新选择!", + "common.userName": "姓名", + "common.tuangouCouponPrice": "团购优惠劵金额", + "common.Expand": "展开", + "common.Collapse": "收起", + "common.OtherStores": "其他门店", + "coupon.coupon": "优惠券", + "coupon.meituanOrdazhongdianpingCoupon": "美团/大众点评优惠劵", + "coupon.queryMeituanDazhongdianpingCoupon": "点击查询美团/大众点评优惠劵", + "coupon.useTips": "使用说明:填入优惠码兑换即可享受优惠。", + "coupon.enterCode": "填入优惠码", + "coupon.limitedtimeoffer": "限时优惠", + "coupon.storewide": "全店通用", + "coupon.redeemNow": "立即兑换", + "coupon.instructions": "使用说明", + "coupon.validityPeriod": "有效期", + "coupon.apply": "立即使用", + "coupon.all": "全部仓型", + "coupon.unusableCoupons": "当前门店不可用优惠券", + "coupon.multiStoreUse": "多店可用", + "coupon.renewable": "续单可用", + "coupon.noRenewable": "续单不可用", + "coupon.redemptionuccessful": "兑换成功", + "coupon.currentConditionsNotMet": "当前条件不满足", + "request.promoCodeError": "优惠码不正确", + "validation.getPhoneFail": "获取手机号失败,请手动输入", + "validation.inputName1": "请填写用户姓名", + "validation.selectCardType": "请选择证件类型", + "validation.inputIdCard": "请填写证件号码", + "validation.uploadIdCard": "请上传证件照", + "validation.inputPhone": "请填写手机号码", + "validation.inputInternationalPhone": "请填写境外号码", + "validation.inputInternationalPhoneHk": "请填写香港号码", + "validation.uploadImg": "图片正在上传中,请稍后重试", + "validation.inputName2": "请填写企业名称", + "validation.inputLicense": "请填写营业执照号码", + "validation.uploadLicense": "请上传企业证照", + "validation.submitSuccess": "提交成功", + "validation.uploadSuccess": "修改成功", + "validation.identifyCard": "内地身份证", + "validation.passport": "护照", + "validation.permit": "港澳通行证", + "validation.access": "一键获取", + "validation.bind": "一键绑定", + "validation.vailSuccess": "认证成功", + "agreement.readAndAgree": "我已阅读并同意", + "agreement.service": "《用户服务协议》", + "agreement.and": "及", + "agreement.privacy": "《隐私政策》", + "agreement.toast": "请先阅读并同意《用户服务协议》和《隐私政策》", + "verification.vailFail": "认证不通过,请检查证件类型与证件信息是否正确,请重新上传清晰图片(注意正反面)。", + "verification.vailSuccess": "认证成功", + "invoiceApply.electronicInvoice": "发票申请", + "invoiceApply.paperInvoice": "纸质发票", + "invoiceApply.invoiceTips": "您的发票申请已经提交成功,请耐心等候工作人员联系!", + "invoice.valid": "可开发票", + "invoice.pay": "支付时间", + "invoice.site": "门店", + "invoice.type": "仓型", + "invoice.unit": "仓位", + "invoice.rent": "租期", + "invoice.record": "申请记录", + "invoice.allSelect": "全选", + "invoice.nextStep": "下一步", + "invoice.tip": "- 订单付款后 一个月内可开发票", + "invoice.serial": "编号", + "invoice.time": "申请时间", + "invoice.status": "审核状态", + "invoice.status0": "待审核", + "invoice.status1": "审核通过,开票中", + "invoice.status2": "审核不通过", + "invoice.status3": "已取消", + "invoice.status4": "已开票", + "invoice.selectOrder": "请选择订单", + "invoice.validMoney": "订单金额必须大于0元", + "evaluate.customerEvaluation": "顾客评价", + "evaluate.overallRating": "综合评分", + "evaluate.userExperience": "用户体验", + "evaluate.Hospitality": "服务态度", + "evaluate.cleanliness": "整洁度", + "evaluate.convenience": "便利度", + "evaluate.tips": "请在这里留下你宝贵的意见或建议。", + "evaluate.anonymous": "匿名", + "goodsList.note": "请备注", + "goodsList.info": "您好,根据有关部门要求,您存放的物品需要进行物品品类自主申报。本申报单作留底备查之用,请认真填写。", + "goodsList.multi": "可多选", + "goodsList.tip1": "用户确认:", + "goodsList.tip2": "1、存放的物品均为合法渠道获取;", + "goodsList.tip3": "2、不存放违禁品;", + "goodsList.tip4": "3、由于用户存放物品异变等原因造成的财产毁损或人身伤亡的,由该用户承担责任。", + "goodsList.submit": "确认并提交", + "houseKey.FriendsName": "亲友姓名", + "houseKey.AuthorizationDate": "授权期限", + "houseKey.ReceiveNotifications": "接收通知", + "houseKey.EnableNotifications": "打开接受通知", + "houseKey.PhoneNumber": "电话号码", + "houseKey.email": "邮箱", + "houseKey.EnterAuthorizedPhoneNumber": "填写授权方的手机号", + "houseKey.AddAuthorization": "新增授权", + "houseKey.EnterFriendsName": "填写亲友姓名", + "houseKey.EnterAuthorizationDate": "填写授权期限", + "houseKey.EnterPhoneNumber": "填写电话号码", + "houseKey.EnterEmail": "填写邮箱", + "houseKey.CannotAuthorizeYourself": "不能授权给自己", + "houseKey.UpdateSuccessful": "更新成功", + "houseKey.AddedSuccessfully": "新增成功", + "houseKey.date": "年-月-日", + "houseKey.overdue": "授权期限已过期,请重新选择授权期限并更新", + "houseKey.otherPhone": "填写授权方的手机号", + "houseKey.otherEmail": "填写授权方的邮箱", + "houseKey.getNote": "打开接受通知", + "unitTypeDetail.oneMonth": "租期:一个月起租", + "unitTypeDetail.reference": "参考", + "unitTypeDetail.discount": "优惠", + "reserve.FULLNAME": "用户姓名", + "reserve.PHONE": "手機號碼", + "reserve.REGION": "城市地区", + "reserve.TYPE": "所属类型", + "reserve.PHONE NUMBER": "手机号码", + "reserve.Individual & Family": "个人&家庭", + "reserve.Business & E-commerce": "企业&电商", + "reserve.Retail & Store": "零售&门店", + "reserve.contentTips": "预约成功,请耐心等待工作人员联系,保持手机畅通,感谢!", + "inviteDetail.title": "邀请记录", + "inviteDetail.Username": "用户名称", + "inviteDetail.Registration Date": "注册日期", + "inviteDetail.Status": "状态", + "inviteDetail.No invitation": "抱歉,暂无邀请记录,请分享邀请。", + "inviteDetail.SORRY": "抱歉,没有记录。请分享并邀请。", + "inviteDetail.Share Invitation": "分享邀请", + "referrerInfo.company": "中介公司", + "referrerInfo.branch": "中介分行", + "referrerInfo.commission": "中介费百分比", + "referrerInfo.inviteRegister": "邀请注册", + "referrerInfo.inviteRecord": "邀请记录", + "referrerInfo.inviteUserName": "用户", + "referrerInfo.invitePhone": "手机号", + "referrerInfo.registrationTime": "注册时间", + "referrerInfo.inviteEmpty": "暂无邀请记录", + "referrerInfo.loadQrCode": "下载二维码", + "referrerInfo.loadPoster": "下载海报", + "referrerInfo.forwardInvitation": "转发邀请", + "pointsMall.title": "积分商城", + "pointsMall.myPoints": "我的积分", + "pointsMall.pointsUnit": "积分", + "pointsMall.exchange": "兑换", + "pointsMall.exchangeFormTitle": "填写收货信息", + "pointsMall.submit": "提交", + "pointsMall.receiverName": "姓名", + "pointsMall.phone": "手机号", + "pointsMall.address": "地址", + "pointsMall.placeholderName": "请输入收货人姓名", + "pointsMall.placeholderPhone": "请输入手机号码", + "pointsMall.placeholderAddress": "请输入详细收货地址", + "pointsMall.exchangeConfirmTitle": "兑换确认", + "pointsMall.exchangeConfirmTip": "是否确认使用 {points} 积分兑换?", + "pointsMall.stock": "库存", + "pointsMall.successTitle": "领取成功", + "pointsMall.successTip": "兑换成功,请耐心等候工作人员联系!感谢!", + "pointsMall.toastOutOfStock": "库存不足", + "pointsMall.toastNotEnoughPoints": "积分不足", + "pointsMall.toastExchanging": "兑换中...", + "pointsMall.toastExchangeFailed": "兑换失败", + "pointsMall.exchangeRecordTitle": "兑换记录", + "pointsMall.noExchangeRecord": "暂无兑换记录" +} \ No newline at end of file diff --git a/locale/zh-Hant.json b/locale/zh-Hant.json new file mode 100644 index 0000000..f287717 --- /dev/null +++ b/locale/zh-Hant.json @@ -0,0 +1,24 @@ +{ + "locale.auto": "系統", + "locale.en": "English", + "locale.zh-hans": "简体中文", + "locale.zh-hant": "繁體中文", + "locale.ja": "日语", + "index.title": "Hello i18n", + "index.home": "主頁", + "index.component": "組件", + "index.api": "API", + "index.schema": "Schema", + "index.demo": "uni-app 國際化演示", + "index.demo-description": "包含 uni-framework、manifest.json、pages.json、tabbar、頁面、組件、API、Schema", + "index.detail": "詳情", + "index.language": "語言", + "index.language-info": "語言信息", + "index.system-language": "系統語言", + "index.application-language": "應用語言", + "index.language-change-confirm": "應用此設置將重啟App", + "api.message": "提示", + "schema.name": "姓名", + "schema.add": "新增", + "schema.add-success": "新增成功" +} diff --git a/main.js b/main.js new file mode 100644 index 0000000..42c1938 --- /dev/null +++ b/main.js @@ -0,0 +1,20 @@ +import { createSSRApp } from "vue"; +import App from "./App"; +import i18n from "./locale/index"; +import * as Pinia from "pinia"; +// import VConsole from 'vconsole' +// new VConsole() +// import '@/uni.scss' +// 引入uvUI +import uvUI from "@/uni_modules/uv-ui-tools"; + +export function createApp() { + const app = createSSRApp(App); + app.use(uvUI); + app.use(Pinia.createPinia()); + app.use(i18n); + return { + app, + Pinia, + }; +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..19844c7 --- /dev/null +++ b/manifest.json @@ -0,0 +1,113 @@ +{ + "name" : "金刚迷你仓", + "appid" : "__UNI__FB6F2F3", + "description" : "", + "versionName" : "1.0.0", + "versionCode" : "100", + "transformPx" : false, + "app-plus" : { + "optimization" : { + "subPackages" : true + }, + "runmode" : "liberate", // 开启分包优化后,必须配置资源释放模式 + + /* 5+App特有相关 */ + "usingComponents" : true, + "nvueCompiler" : "EliteSys", + "nvueStyleCompiler" : "EliteSys", + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + "modules" : {}, + /* 模块配置 */ + "distribute" : { + /* 应用发布信息 */ + "android" : { + /* android打包配置 */ + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "ios" : {}, + /* ios打包配置 */ + "sdkConfigs" : {} + } + }, + /* SDK配置 */ + "quickapp" : {}, + /* 快应用特有相关 */ + "mp-weixin" : { + "appid" : "wx3c4ab696101d77d1", + "setting" : { + "urlCheck" : false + }, + "usingComponents" : true, + "permission" : { + "scope.userLocation" : { + "desc" : "将获取你的具体位置信息,用于辅助显示最近店铺" + } + }, + "plugins" : { + "player" : { + "version" : "2.0.0", + "provider" : "wxa75efa648b60994b" + } + }, + "requiredPrivateInfos" : [ "getLocation" ] + }, + "vueVersion" : "3", + "h5" : { + "router" : { + "base" : "./" + }, + "devServer" : { + "port" : 8999, + "proxy" : { + "/api" : { + "target" : "http://localhost:5182", + "ws" : true, + "changeOrigin" : true + } + } + }, + "optimization" : { + "treeShaking" : { + "enable" : true + } + }, + "sdkConfigs" : { + "maps" : { + "qqmap" : { + "key" : "B5ZBZ-S4SKW-YYQR5-3BVNP-NX4NQ-FYFYF" + } + } + } + }, + "locale" : "en", + "fallbackLocale" : "en", + "mp-xhs" : { + "appid" : "6786436ac669e40001348567", + "permission" : { + "scope.userLocation" : { + "desc" : "将获取你的具体位置信息,用于辅助显示最近店铺" + } + } + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..608b7b0 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1443 @@ +{ + "name": "elitesysclient", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "金刚迷你仓", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "crypto-js": "^4.2.0", + "dayjs": "^1.11.11", + "vconsole": "^3.15.1", + "vue3-google-map": "^0.20.0" + }, + "devDependencies": { + "sass-loader": "^10.5.2" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "peer": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@googlemaps/js-api-loader": { + "version": "1.16.6", + "resolved": "https://registry.npmmirror.com/@googlemaps/js-api-loader/-/js-api-loader-1.16.6.tgz", + "integrity": "sha512-V8p5W9DbPQx74jWUmyYJOerhiB4C+MHekaO0ZRmc6lrOYrvY7+syLhzOWpp55kqSPeNb+qbC2h8i69aLIX6krQ==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/@googlemaps/markerclusterer": { + "version": "2.5.3", + "resolved": "https://registry.npmmirror.com/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz", + "integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "supercluster": "^8.0.1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.30.tgz", + "integrity": "sha512-ZL8y4Xxdh8O6PSwfdZ1IpQ24PjTAieOz3jXb/MDTfDtANcKBMxg1KLm6OX2jofsaQGYfIVzd3BAG22i56/cF1w==", + "peer": true, + "dependencies": { + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.30", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.30.tgz", + "integrity": "sha512-+16Sd8lYr5j/owCbr9dowcNfrHd+pz+w2/b5Lt26Oz/kB90C9yNbxQ3bYOvt7rI2bxk0nqda39hVcwDFw85c2Q==", + "peer": true, + "dependencies": { + "@vue/compiler-core": "3.4.30", + "@vue/shared": "3.4.30" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.30.tgz", + "integrity": "sha512-8vElKklHn/UY8+FgUFlQrYAPbtiSB2zcgeRKW7HkpSRn/JjMRmZvuOtwDx036D1aqKNSTtXkWRfqx53Qb+HmMg==", + "peer": true, + "dependencies": { + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.30", + "@vue/compiler-dom": "3.4.30", + "@vue/compiler-ssr": "3.4.30", + "@vue/shared": "3.4.30", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.10", + "postcss": "^8.4.38", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.30.tgz", + "integrity": "sha512-ZJ56YZGXJDd6jky4mmM0rNaNP6kIbQu9LTKZDhcpddGe/3QIalB1WHHmZ6iZfFNyj5mSypTa4+qDJa5VIuxMSg==", + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.4.30", + "@vue/shared": "3.4.30" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.30.tgz", + "integrity": "sha512-bVJurnCe3LS0JII8PPoAA63Zd2MBzcKrEzwdQl92eHCcxtIbxD2fhNwJpa+KkM3Y/A4T5FUnmdhgKwOf6BfbcA==", + "peer": true, + "dependencies": { + "@vue/shared": "3.4.30" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.30.tgz", + "integrity": "sha512-qaFEbnNpGz+tlnkaualomogzN8vBLkgzK55uuWjYXbYn039eOBZrWxyXWq/7qh9Bz2FPifZqGjVDl/FXiq9L2g==", + "peer": true, + "dependencies": { + "@vue/reactivity": "3.4.30", + "@vue/shared": "3.4.30" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.30.tgz", + "integrity": "sha512-tV6B4YiZRj5QsaJgw2THCy5C1H+2UeywO9tqgWEc21tn85qHEERndHN/CxlyXvSBFrpmlexCIdnqPuR9RM9thw==", + "peer": true, + "dependencies": { + "@vue/reactivity": "3.4.30", + "@vue/runtime-core": "3.4.30", + "@vue/shared": "3.4.30", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.30.tgz", + "integrity": "sha512-TBD3eqR1DeDc0cMrXS/vEs/PWzq1uXxnvjoqQuDGFIEHFIwuDTX/KWAQKIBjyMWLFHEeTDGYVsYci85z2UbTDg==", + "peer": true, + "dependencies": { + "@vue/compiler-ssr": "3.4.30", + "@vue/shared": "3.4.30" + }, + "peerDependencies": { + "vue": "3.4.30" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.30.tgz", + "integrity": "sha512-CLg+f8RQCHQnKvuHY9adMsMaQOcqclh6Z5V9TaoMgy0ut0tz848joZ7/CYFFyF/yZ5i2yaw7Fn498C+CNZVHIg==", + "peer": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001640", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", + "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0", + "peer": true + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.2.tgz", + "integrity": "sha512-T6SqyLd1iLuqPA90J5N4cTalrtovCySh58iiZDGJ6FGznbclKh4UI+FGacQSgFzwKG77W7XT5gwbVEbd9cIH1A==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.48.0", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.48.0.tgz", + "integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "peer": true + }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.819", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.819.tgz", + "integrity": "sha512-8RwI6gKUokbHWcN3iRij/qpvf/wCbIVY5slODi85werwqUQwpFXM+dvUBND93Qh7SB0pW3Hlq3/wZsqQ3M9Jaw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "peer": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "peer": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mutation-observer": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/mutation-observer/-/mutation-observer-1.0.3.tgz", + "integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "peer": true + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, + "node_modules/sass-loader": { + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.5.2.tgz", + "integrity": "sha512-vMUoSNOUKJILHpcNCCyD23X34gve1TS7Rjd9uXHeKqhvBG39x6XbswFDtpbTElj6XdMFezoWhkh5vtKudf2cgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "webpack": "^4.36.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "dependencies": { + "kdbush": "^4.0.2" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.31.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", + "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vconsole": { + "version": "3.15.1", + "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz", + "integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "copy-text-to-clipboard": "^3.0.1", + "core-js": "^3.11.0", + "mutation-observer": "^1.0.3" + } + }, + "node_modules/vue": { + "version": "3.4.30", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.30.tgz", + "integrity": "sha512-NcxtKCwkdf1zPsr7Y8+QlDBCGqxvjLXF2EX+yi76rV5rrz90Y6gK1cq0olIhdWGgrlhs9ElHuhi9t3+W5sG5Xw==", + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.4.30", + "@vue/compiler-sfc": "3.4.30", + "@vue/runtime-dom": "3.4.30", + "@vue/server-renderer": "3.4.30", + "@vue/shared": "3.4.30" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue3-google-map": { + "version": "0.20.0", + "resolved": "https://registry.npmmirror.com/vue3-google-map/-/vue3-google-map-0.20.0.tgz", + "integrity": "sha512-GUih2O3lhKKBjl9jODZgva5OtwX2DXQJEL+6EO7sEk9mD8AJbSjxbT8KjfKUP90fYIwUmZpwvcEU0cqiCLCeaA==", + "dependencies": { + "@googlemaps/js-api-loader": "^1.16.2", + "@googlemaps/markerclusterer": "^2.4.0", + "fast-deep-equal": "^3.1.3" + }, + "engines": { + "node": ">=16.11.0" + }, + "peerDependencies": { + "vue": "^3" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8557776 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "金刚迷你仓", + "version": "1.0.0", + "description": "金刚迷你仓", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "YOGO", + "license": "ISC", + "dependencies": { + "crypto-js": "^4.2.0", + "dayjs": "^1.11.11", + "vconsole": "^3.15.1", + "vue3-google-map": "^0.20.0" + }, + "devDependencies": { + "sass-loader": "^10.5.2" + } +} diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..c82a454 --- /dev/null +++ b/pages.json @@ -0,0 +1,281 @@ +{ + "subPackages": [ + { + "name": "pagesb", + "root": "pagesb", + "pages": [ + { + "path": "changeUser/index" + }, + { + "path": "referrerInfo/index" + }, + { + "path": "pointsMall/index" + }, + { + "path": "invitation/index" + }, + { + "path": "houseKey/index" + }, + { + "path": "flashSale/index" + }, + { + "path": "latestEvents/index" + }, + { + "path": "activityDetail/index", + "style": { + "navigationBarTitleText": " " + } + }, + { + "path": "invoice/index" + }, + { + "path": "invoiceApplyforRecord/index" + }, + { + "path": "invoiceApply/index" + }, + { + "path": "videoTutorial/index" + }, + { + "path": "reserve/index" + }, + { + "path": "validationInfo/index", + "style": { + "navigationBarTitleText": "实名验证" + } + }, + { + "path": "userguide/index" + }, + { + "path": "unittypeDetail/index" + }, + { + "path": "initLock/index" + }, + { + "path": "maskUser/index" + }, + { + "path": "AControl/index" + } + ], + "plugins": { + "ttPlugin": { + "version": "3.0.6", + "provider": "wx43d5971c94455481" + } + } + } + ], + "pages": [ + { + "path": "pages/index/index", + "style": { + "navigationBarTitleText": "首页", + "mp-weixin": { + "usingComponents": { + "player-component": "plugin://player/video" + } + } + } + }, + { + "path": "pages/goodsList/index", + "style": { + "navigationBarTitleText": " " + } + }, + { + "path": "pages/renewOrder/index", + "style": { + "navigationBarTitleText": " " + } + }, + { + "path": "pages/webview/web", + "style": { + "navigationBarTitleText": " ", + "navigationStyle": "default" + } + }, + { + "path": "pages/book/book", + "style": { + "navigationBarTitleText": "Book" + } + }, + { + "path": "pages/facecode/facecode", + "style": { + "navigationBarTitleText": "facecode" + } + }, + { + "path": "pages/book/index", + "style": { + "navigationBarTitleText": "Book" + } + }, + { + "path": "pages/unlock/index", + "style": { + "navigationBarTitleText": "订单" + } + }, + { + "path": "pages/personal/index", + "style": { + "navigationBarTitleText": "我的" + } + }, + { + "path": "pages/book/mapmode", + "style": { + "navigationBarTitleText": "Map" + } + }, + { + "path": "pages/site/index", + "style": { + "navigationBarTitleText": "门店" + } + }, + { + "path": "pages/setOrder/index", + "style": { + "navigationBarTitleText": "Order" + } + }, + { + "path": "pages/login/index", + "style": { + "navigationBarTitleText": "Login" + } + }, + { + "path": "pages/register/index", + "style": { + "navigationBarTitleText": "Register" + } + }, + { + "path": "pages/forgotPawd/index", + "style": { + "navigationBarTitleText": "ForgotPAWd" + } + }, + { + "path": "pages/book/navigate", + "style": { + "navigationBarTitleText": " ", + "navigationStyle": "default" + } + }, + { + "path": "pages/orderdetail/index", + "style": { + "navigationBarTitleText": "Orderdetail" + } + }, + { + "path": "pages/orderdetail/lock", + "style": { + "navigationBarTitleText": "Lock" + } + }, + { + "path": "pages/orderdetail/door", + "style": { + "navigationBarTitleText": "Door" + } + }, + { + "path": "pages/personal/customerAi", + "style": { + "navigationBarTitleText": " ", + "navigationStyle": "default" + } + }, + { + "path": "pages/evaluate/index", + "style": { + "navigationBarTitleText": "Evaluate" + } + }, + { + "path": "pages/call/index", + "style": { + "navigationBarTitleText": "Call" + } + }, + { + "path": "pages/invite/index", + "style": { + "navigationBarTitleText": "Home" + } + } + ], + "tabBar": { + "list": [ + { + "pagePath": "pages/index/index", + "text": " ", + "iconPath": "static/tabbar/index.png", + "selectedIconPath": "static/tabbar/index.png" + }, + { + "pagePath": "pages/book/index", + "text": " ", + "iconPath": "static/tabbar/book.png", + "selectedIconPath": "static/tabbar/book.png" + }, + { + "pagePath": "pages/call/index", + "iconPath": "static/tabbar/call.png", + "selectedIconPath": "static/tabbar/call.png" + }, + { + "pagePath": "pages/unlock/index", + "text": " ", + "iconPath": "static/tabbar/unlock.png", + "selectedIconPath": "static/tabbar/unlock.png" + }, + { + "pagePath": "pages/personal/index", + "text": " ", + "iconPath": "static/tabbar/personal.png", + "selectedIconPath": "static/tabbar/personal.png" + } + ] + }, + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "Elitesys", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8", + "navigationStyle": "custom", + "app-plus": { + "background": "#efeff4" + } + }, + "condition": { + //模式配置,仅开发期间生效 + "current": 0, //当前激活的模式(list 的索引项) + "list": [ + { + "name": "", //模式名称 + "path": "", //启动页面,必选 + "query": "" //启动参数,在页面的onLoad函数里面得到 + } + ] + } +} \ No newline at end of file diff --git a/pages/book/book.vue b/pages/book/book.vue new file mode 100644 index 0000000..f0811a4 --- /dev/null +++ b/pages/book/book.vue @@ -0,0 +1,53 @@ + + + + + \ No newline at end of file diff --git a/pages/book/index.vue b/pages/book/index.vue new file mode 100644 index 0000000..6789832 --- /dev/null +++ b/pages/book/index.vue @@ -0,0 +1,456 @@ + + + + + diff --git a/pages/book/map.vue b/pages/book/map.vue new file mode 100644 index 0000000..4a818da --- /dev/null +++ b/pages/book/map.vue @@ -0,0 +1,174 @@ + + + + + \ No newline at end of file diff --git a/pages/book/mapmode.vue b/pages/book/mapmode.vue new file mode 100644 index 0000000..38aa165 --- /dev/null +++ b/pages/book/mapmode.vue @@ -0,0 +1,364 @@ + + + + + diff --git a/pages/book/navigate.vue b/pages/book/navigate.vue new file mode 100644 index 0000000..8015dfd --- /dev/null +++ b/pages/book/navigate.vue @@ -0,0 +1,88 @@ + + + + + \ No newline at end of file diff --git a/pages/call/index.vue b/pages/call/index.vue new file mode 100644 index 0000000..9be7893 --- /dev/null +++ b/pages/call/index.vue @@ -0,0 +1,12 @@ + + + + + diff --git a/pages/evaluate/index.vue b/pages/evaluate/index.vue new file mode 100644 index 0000000..8d19be7 --- /dev/null +++ b/pages/evaluate/index.vue @@ -0,0 +1,396 @@ + + + + \ No newline at end of file diff --git a/pages/facecode/facecode.vue b/pages/facecode/facecode.vue new file mode 100644 index 0000000..1beb33a --- /dev/null +++ b/pages/facecode/facecode.vue @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/pages/forgotPawd/index.vue b/pages/forgotPawd/index.vue new file mode 100644 index 0000000..05d72b9 --- /dev/null +++ b/pages/forgotPawd/index.vue @@ -0,0 +1,300 @@ + + + + + \ No newline at end of file diff --git a/pages/goodsList/index.vue b/pages/goodsList/index.vue new file mode 100644 index 0000000..967ea8f --- /dev/null +++ b/pages/goodsList/index.vue @@ -0,0 +1,332 @@ + + + + + diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..9b1b2aa --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,1549 @@ + + + + + diff --git a/pages/invite/index.vue b/pages/invite/index.vue new file mode 100644 index 0000000..3066f81 --- /dev/null +++ b/pages/invite/index.vue @@ -0,0 +1,157 @@ + + + + + \ No newline at end of file diff --git a/pages/login/index.vue b/pages/login/index.vue new file mode 100644 index 0000000..ed60edd --- /dev/null +++ b/pages/login/index.vue @@ -0,0 +1,642 @@ + + + + + diff --git a/pages/orderdetail/door.vue b/pages/orderdetail/door.vue new file mode 100644 index 0000000..994cd6d --- /dev/null +++ b/pages/orderdetail/door.vue @@ -0,0 +1,224 @@ + + + + + \ No newline at end of file diff --git a/pages/orderdetail/index.vue b/pages/orderdetail/index.vue new file mode 100644 index 0000000..ac8cc99 --- /dev/null +++ b/pages/orderdetail/index.vue @@ -0,0 +1,1569 @@ + + + + + \ No newline at end of file diff --git a/pages/orderdetail/lock.vue b/pages/orderdetail/lock.vue new file mode 100644 index 0000000..92189b4 --- /dev/null +++ b/pages/orderdetail/lock.vue @@ -0,0 +1,259 @@ + + + + + \ No newline at end of file diff --git a/pages/personal/customerAi.vue b/pages/personal/customerAi.vue new file mode 100644 index 0000000..3247855 --- /dev/null +++ b/pages/personal/customerAi.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/pages/personal/index.vue b/pages/personal/index.vue new file mode 100644 index 0000000..b2d010d --- /dev/null +++ b/pages/personal/index.vue @@ -0,0 +1,123 @@ + + + + diff --git a/pages/phone/index.vue b/pages/phone/index.vue new file mode 100644 index 0000000..d77dee1 --- /dev/null +++ b/pages/phone/index.vue @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/pages/register/index.vue b/pages/register/index.vue new file mode 100644 index 0000000..8a88040 --- /dev/null +++ b/pages/register/index.vue @@ -0,0 +1,305 @@ + + + + + \ No newline at end of file diff --git a/pages/renewOrder/index.vue b/pages/renewOrder/index.vue new file mode 100644 index 0000000..74ef12e --- /dev/null +++ b/pages/renewOrder/index.vue @@ -0,0 +1,1154 @@ + + + + + diff --git a/pages/setOrder/index.vue b/pages/setOrder/index.vue new file mode 100644 index 0000000..8e0248e --- /dev/null +++ b/pages/setOrder/index.vue @@ -0,0 +1,1770 @@ + + + + + diff --git a/pages/site/index.vue b/pages/site/index.vue new file mode 100644 index 0000000..c02f19f --- /dev/null +++ b/pages/site/index.vue @@ -0,0 +1,350 @@ + + + + + diff --git a/pages/unlock/index.vue b/pages/unlock/index.vue new file mode 100644 index 0000000..c65fa0f --- /dev/null +++ b/pages/unlock/index.vue @@ -0,0 +1,1472 @@ + + + + + diff --git a/pages/webview/web.vue b/pages/webview/web.vue new file mode 100644 index 0000000..e34a66e --- /dev/null +++ b/pages/webview/web.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/pagesb/AControl/index.vue b/pagesb/AControl/index.vue new file mode 100644 index 0000000..1174e55 --- /dev/null +++ b/pagesb/AControl/index.vue @@ -0,0 +1,363 @@ + + + + diff --git a/pagesb/Apis/flashSale.js b/pagesb/Apis/flashSale.js new file mode 100644 index 0000000..06c0899 --- /dev/null +++ b/pagesb/Apis/flashSale.js @@ -0,0 +1,17 @@ +import request from "/utils/request.js"; +export default { + GetFlashSaleDistrict:(data) => { + return request.request({ + url: '/ClientSite/GetFlashSaleDistrict', + method: 'get', + data, + }); + }, + GetFlashSaleInfo:(data) => { + return request.request({ + url: '/ClientSite/GetFlashSaleInfo', + method: 'get', + data, + }); + }, + } \ No newline at end of file diff --git a/pagesb/activityDetail/index.vue b/pagesb/activityDetail/index.vue new file mode 100644 index 0000000..36dd485 --- /dev/null +++ b/pagesb/activityDetail/index.vue @@ -0,0 +1,173 @@ + + + + diff --git a/pagesb/changeUser/index.vue b/pagesb/changeUser/index.vue new file mode 100644 index 0000000..252a514 --- /dev/null +++ b/pagesb/changeUser/index.vue @@ -0,0 +1,339 @@ + + + + + diff --git a/pagesb/components/my-uv-collapse/changelog.md b/pagesb/components/my-uv-collapse/changelog.md new file mode 100644 index 0000000..0219560 --- /dev/null +++ b/pagesb/components/my-uv-collapse/changelog.md @@ -0,0 +1,5 @@ +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-collapse 折叠面板 diff --git a/pagesb/components/my-uv-collapse/components/uv-collapse-item/props.js b/pagesb/components/my-uv-collapse/components/uv-collapse-item/props.js new file mode 100644 index 0000000..18983c1 --- /dev/null +++ b/pagesb/components/my-uv-collapse/components/uv-collapse-item/props.js @@ -0,0 +1,60 @@ +export default { + props: { + // 标题 + title: { + type: String, + default: '' + }, + // 标题右侧内容 + value: { + type: String, + default: '' + }, + // 标题下方的描述信息 + label: { + type: String, + default: '' + }, + // 是否禁用折叠面板 + disabled: { + type: Boolean, + default: false + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: true + }, + // 是否开启点击反馈 + clickable: { + type: Boolean, + default: true + }, + // 是否显示内边框 + border: { + type: Boolean, + default: true + }, + // 标题的对齐方式 + align: { + type: String, + default: 'left' + }, + // 唯一标识符 + name: { + type: [String, Number], + default: '' + }, + // 标题左侧图片,可为绝对路径的图片或内置图标 + icon: { + type: String, + default: '' + }, + // 面板展开收起的过渡时间,单位ms + duration: { + type: Number, + default: 300 + }, + ...uni.$uv?.props?.collapseItem + } +} \ No newline at end of file diff --git a/pagesb/components/my-uv-collapse/components/uv-collapse-item/uv-collapse-item.vue b/pagesb/components/my-uv-collapse/components/uv-collapse-item/uv-collapse-item.vue new file mode 100644 index 0000000..777bc1a --- /dev/null +++ b/pagesb/components/my-uv-collapse/components/uv-collapse-item/uv-collapse-item.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/pagesb/components/my-uv-collapse/components/uv-collapse/props.js b/pagesb/components/my-uv-collapse/components/uv-collapse/props.js new file mode 100644 index 0000000..70fa04c --- /dev/null +++ b/pagesb/components/my-uv-collapse/components/uv-collapse/props.js @@ -0,0 +1,20 @@ +export default { + props: { + // 当前展开面板的name,非手风琴模式:[],手风琴模式:string | number + value: { + type: [String, Number, Array, null], + default: null + }, + // 是否手风琴模式 + accordion: { + type: Boolean, + default: false + }, + // 是否显示外边框 + border: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.collapse + } +} \ No newline at end of file diff --git a/pagesb/components/my-uv-collapse/components/uv-collapse/uv-collapse.vue b/pagesb/components/my-uv-collapse/components/uv-collapse/uv-collapse.vue new file mode 100644 index 0000000..5e5c96d --- /dev/null +++ b/pagesb/components/my-uv-collapse/components/uv-collapse/uv-collapse.vue @@ -0,0 +1,86 @@ + + + diff --git a/pagesb/components/my-uv-collapse/package.json b/pagesb/components/my-uv-collapse/package.json new file mode 100644 index 0000000..cf9565f --- /dev/null +++ b/pagesb/components/my-uv-collapse/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-collapse", + "displayName": "uv-collapse 折叠面板 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.1", + "description": "折叠面板组件,通过折叠面板收纳内容区域,点击可展开收起,多功能参数可配置。", + "keywords": [ + "uv-collapse", + "uvui", + "uv-ui", + "collapse", + "折叠面板" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-line", + "uv-cell" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/pagesb/components/qf-image-cropper/changelog.md b/pagesb/components/qf-image-cropper/changelog.md new file mode 100644 index 0000000..531a5e4 --- /dev/null +++ b/pagesb/components/qf-image-cropper/changelog.md @@ -0,0 +1,67 @@ +## 2.2.4(2024-06-21) +* 新增 reverseRotatable 属性,是否支持逆向翻转 +* 修复 `2.1.7` 版本导致旋转后图片没有自动适配裁剪框的问题 +## 2.2.3(2024-06-21) +* 新增 gpu 属性,是否开启硬件加速,图片缩放过程中如果出现元素的“留影”或“重影”效果,可通过该方式解决或减轻这一问题 +* 修复 组件使用 `v-if` 并设置 `src` 属性时可能会出现图片渲染位置存在偏差的问题 + +## 2.2.2(2024-06-21) +* 优化 组件实例 chooseImage 方法支持传参 +* 修复 组件使用 `v-if` 时组件无非正常渲染的问题 + +## 2.2.1(2024-06-15) +* 修复 H5平台不支持手势拖动图片的问题 + +## 2.2.0(2024-05-31) +* 修复 APP平台 `vue2` 项目因 `2.1.9` 版本修复 `vue3` 项目bug而引发的问题 + +## 2.1.9(2024-05-29) +* 修复 APP平台 `vue3` 项目因 uniapp `renderjs` 中未支持条件编译,导致运行了H5平台代码报错的问题 + +## 2.1.8(2024-05-29) +* 新增 zIndex 属性,调整组件层级 +* 新增 组件内容插槽 +* 优化 微信小程序平台动态修改元素style时的多余内容 + +## 2.1.7(2024-05-28) +* 新增 checkRange 属性,当 checkRange=false 时允许图片位置超出裁剪边界 +* 新增 minScale 属性,图片最小缩放倍数,当 minScale<0 时可使图片宽高不再受裁剪区域宽高限制 +* 新增 backgroundColor 属性,生成图片背景色,如果裁剪区域没有完全包含在图片中时,不设置该属性生成图片存在一定的透明块 +* 优化 动态修改图片宽高但没有传入src时,尺寸适应问题 +* 修复 APP平台通过 `this.$ownerInstance` 获取组件实例时机过早,其值为 `undefined` 导致报错界面没有正常渲染的问题 + +## 2.1.6(2023-04-16) +* 修复 组件使用 v-show 指令会导致选择图片后初始位置严重偏位的问题 + +## 2.1.5(2023-04-15) +* 新增 兼容APP平台 + +## 2.1.4(2023-03-13) +* 新增 fileType 属性,用于指定生成文件的类型,只支持 'jpg' 或 'png',默认为 'png' +* 新增 delay 属性,微信小程序平台使用 `Canvas 2D` 绘制时控制图片从绘制到生成所需时间 +* 优化 当生成图片的尺寸宽/高超过 Canvas 2D 最大限制(1365*1365)则将画布尺寸缩放在限制范围内绘制完成后输出目标尺寸 +* 优化 旋转图标指示方向与实际旋转方向不符 + +## 2.1.3(2023-02-06) +* 优化 vue3支持 + +## 2.1.2(2023-02-03) +* 新增 navigation 属性,H5平台当 showAngle 为 true 时,使用插件的页面在 `page.json` 中配置了 "navigationStyle": "custom" 时,必须将此值设为 false ,否则四个可拉伸角的触发位置会有偏差 +* 修复 H5平台部分设备(已知iPhone11以下机型)拍照的图片缩放时会闪动的问题 + +## 2.1.1(2022-12-06) +* 修复 横屏适配问题 + +## 2.1.0(2022-12-06) +* 新增 兼容H5平台,使用 renderjs 响应手势事件 + +## 2.0.0(2022-12-05) +* 重构 插件,使用 WXS 响应手势事件 +* 新增 图片翻转 +* 新增 拉伸裁剪框放大图片 +* 新增 监听PC鼠标滚轮触发缩放 +* 新增 圆形、圆角矩形的图片裁剪 +* 优化 图片缩放,移动端以双指触摸中心点为缩放中心点,PC端以鼠标所在点为缩放中心点 +* 优化 裁剪框样式 +* 优化 图片位置拖动 支持边界回弹效果(滑动时可滑出边界,释放时回弹到边界) +* 优化 生成图片使用新版 Canvas 2D 接口 diff --git a/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.render.js b/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.render.js new file mode 100644 index 0000000..d4e2339 --- /dev/null +++ b/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.render.js @@ -0,0 +1,738 @@ +/** + * 图片编辑器-手势监听 + * 1. 支持编译到app-vue(uni-app 2.5.5及以上版本)、H5上 + */ +/** 图片偏移量 */ +var offset = { x: 0, y: 0 }; +/** 图片缩放比例 */ +var scale = 1; +/** 图片最小缩放比例 */ +var minScale = 1; +/** 图片旋转角度 */ +var rotate = 0; +/** 触摸点 */ +var touches = []; +/** 图片布局信息 */ +var img = {}; +/** 系统信息 */ +var sys = {}; +/** 裁剪区域布局信息 */ +var area = {}; +/** 触摸行为类型 */ +var touchType = ''; +/** 操作角的位置 */ +var activeAngle = 0; +/** 裁剪区域布局信息偏移量 */ +var areaOffset = { left: 0, right: 0, top: 0, bottom: 0 }; +/** 元素ID */ +var elIds = { + 'imageStyles': 'crop-image', + 'maskStylesList': 'crop-mask-block', + 'borderStyles': 'crop-border', + 'circleBoxStyles': 'crop-circle-box', + 'circleStyles': 'crop-circle', + 'gridStylesList': 'crop-grid', + 'angleStylesList': 'crop-angle', +} +/** 记录上次初始化时间戳,排除APP重复更新 */ +var timestamp = 0; +/** vue3 renderjs 条件编译无效,以此方式区别 APP 和 H5 */ +// #ifdef H5 +var platform = 'H5'; +// #endif +// #ifdef APP +var platform = 'APP'; +// #endif +/** + * 样式对象转字符串 + * @param {Object} style 样式对象 + */ +function styleToString(style) { + if(typeof style === 'string') return style; + var str = ''; + for (let k in style) { + str += k + ':' + style[k] + ';'; + } + return str; +} +/** + * + * @param {Object} instance 页面实例对象 + * @param {Object} key 要修改样式的key + * @param {Object|Array} style 样式 + */ +function setStyle(instance, key, style) { + // console.log('setStyle', instance, key, JSON.stringify(style)) + // #ifdef APP-PLUS + if(platform === 'APP') { + if(Object.prototype.toString.call(style) === '[object Array]') { + for (var i = 0, len = style.length; i < len; i++) { + var el = window.document.getElementById(elIds[key] + '-' + (i + 1)); + el && (el.style = styleToString(style[i])); + } + } else { + var el = window.document.getElementById(elIds[key]); + el && (el.style = styleToString(style)); + } + } + // #endif + // #ifdef H5 + if(platform === 'H5') instance[key] = style; + // #endif +} +/** + * 触发页面实例指定方法 + * @param {Object} instance 页面实例对象 + * @param {Object} name 方法名称 + * @param {Object} obj 传递参数 + */ +function callMethod(instance, name, obj) { + // #ifdef APP-PLUS + if(platform === 'APP') instance.callMethod(name, obj); + // #endif + // #ifdef H5 + if(platform === 'H5') instance[name](obj); + // #endif +} +/** + * 计算两点间距 + * @param {Object} touches 触摸点信息 + */ +function getDistanceByTouches(touches) { + // 根据勾股定理求两点间距离 + var a = touches[1].pageX - touches[0].pageX; + var b = touches[1].pageY - touches[0].pageY; + var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); + // 求两点间的中点坐标 + // 1. a、b可能为负值 + // 2. 在求a、b时,如用touches[1]减touches[0],则求中点坐标也得用touches[1]减a/2、b/2 + // 3. 同理,在求a、b时,也可用touches[0]减touches[1],则求中点坐标也得用touches[0]减a/2、b/2 + var x = touches[1].pageX - a / 2; + var y = touches[1].pageY - b / 2; + return { c, x, y }; +}; + +/** + * 修正取值 + * @param {Object} a + * @param {Object} b + * @param {Object} c + * @param {Object} reverse 是否反向 + */ +function correctValue(a, b, c, reverse) { + return reverse ? Math.max(Math.min(a, b), c) : Math.min(Math.max(a, b), c); +} + +/** + * 检查边界:限制 x、y 拖动范围,禁止滑出边界 + * @param {Object} e 点坐标 + */ +function checkRange(e) { + var r = rotate / 90 % 2; + if(r === 1) { // 因图片宽高可能不等,翻转 90° 或 270° 后图片宽高需反着计算,且左右和上下边界要根据差值做偏移 + var o = (img.height - img.width) / 2; // 宽高差值一半 + return { + x: correctValue(e.x, -img.height + o + area.width + area.left, area.left + o, img.height < area.height), + y: correctValue(e.y, -img.width - o + area.height + area.top, area.top - o, img.width < area.width) + } + } + return { + x: correctValue(e.x, -img.width + area.width + area.left, area.left, img.width < area.width), + y: correctValue(e.y, -img.height + area.height + area.top, area.top, img.height < area.height) + } +}; +/** + * 变更图片布局信息 + * @param {Object} e 布局信息 + */ +function changeImageRect(e) { + // console.log('changeImageRect', e) + offset.x += e.x || 0; + offset.y += e.y || 0; + if(e.check && area.checkRange) { // 检查边界 + var point = checkRange(offset); + if(offset.x !== point.x || offset.y !== point.y) { + offset = point; + } + } + + // 因频繁修改 width/height 会造成大量的内存消耗,改为scale + // e.instance.imageStyles = { + // width: img.width + 'px', + // height: img.height + 'px', + // transform: 'translate(' + (offset.x + ox) + 'px, ' + (offset.y + ox) + 'px) rotate(' + rotate +'deg)' + // }; + var ox = (img.width - img.oldWidth) / 2; + var oy = (img.height - img.oldHeight) / 2; + // e.instance.imageStyles = { + // width: img.oldWidth + 'px', + // height: img.oldHeight + 'px', + // transform: 'translate(' + (offset.x + ox) + 'px, ' + (offset.y + oy) + 'px) rotate(' + rotate +'deg) scale(' + scale + ')' + // }; + setStyle(e.instance, 'imageStyles', { + width: img.oldWidth + 'px', + height: img.oldHeight + 'px', + transform: (img.gpu ? 'translateZ(0) ' : '') + 'translate(' + (offset.x + ox) + 'px, ' + (offset.y + oy) + 'px' + ') rotate(' + rotate +'deg) scale(' + scale + ')' + }); + callMethod(e.instance, 'dataChange', { + width: img.width, + height: img.height, + x: offset.x, + y: offset.y, + rotate: rotate + }); +}; +/** + * 变更裁剪区域布局信息 + * @param {Object} e 布局信息 + */ +function changeAreaRect(e) { + // console.log('changeAreaRect', e) + // 变更蒙版样式 + setStyle(e.instance, 'maskStylesList', [ + { + left: 0, + width: (area.left + areaOffset.left) + 'px', + top: 0, + bottom: 0, + 'z-index': area.zIndex + 2 + }, + { + left: (area.right + areaOffset.right) + 'px', + right: 0, + top: 0, + bottom: 0, + 'z-index': area.zIndex + 2 + }, + { + left: (area.left + areaOffset.left) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + top: 0, + height: (area.top + areaOffset.top) + 'px', + 'z-index': area.zIndex + 2 + }, + { + left: (area.left + areaOffset.left) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + top: (area.bottom + areaOffset.bottom) + 'px', + // height: (area.top - areaOffset.bottom + sys.offsetBottom) + 'px', + bottom: 0, + 'z-index': area.zIndex + 2 + } + ]); + // 变更边框样式 + if(area.showBorder) { + setStyle(e.instance, 'borderStyles', { + left: (area.left + areaOffset.left) + 'px', + top: (area.top + areaOffset.top) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 3 + }); + } + + // 变更参考线样式 + if(area.showGrid) { + setStyle(e.instance, 'gridStylesList', [ + { + 'border-width': '1px 0 0 0', + left: (area.left + areaOffset.left) + 'px', + right: (area.right + areaOffset.right) + 'px', + top: (area.top + areaOffset.top + (area.height + areaOffset.bottom - areaOffset.top) / 3 - 0.5) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '1px 0 0 0', + left: (area.left + areaOffset.left) + 'px', + right: (area.right + areaOffset.right) + 'px', + top: (area.top + areaOffset.top + (area.height + areaOffset.bottom - areaOffset.top) * 2 / 3 - 0.5) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 1px 0 0', + top: (area.top + areaOffset.top) + 'px', + bottom: (area.bottom + areaOffset.bottom) + 'px', + left: (area.left + areaOffset.left + (area.width + areaOffset.right - areaOffset.left) / 3 - 0.5) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 1px 0 0', + top: (area.top + areaOffset.top) + 'px', + bottom: (area.bottom + areaOffset.bottom) + 'px', + left: (area.left + areaOffset.left + (area.width + areaOffset.right - areaOffset.left) * 2 / 3 - 0.5) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 3 + } + ]); + } + + // 变更四个伸缩角样式 + if(area.showAngle) { + setStyle(e.instance, 'angleStylesList', [ + { + 'border-width': area.angleBorderWidth + 'px 0 0 ' + area.angleBorderWidth + 'px', + left: (area.left + areaOffset.left - area.angleBorderWidth) + 'px', + top: (area.top + areaOffset.top - area.angleBorderWidth) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px 0 0', + left: (area.right + areaOffset.right - area.angleSize) + 'px', + top: (area.top + areaOffset.top - area.angleBorderWidth) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 0 ' + area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px', + left: (area.left + areaOffset.left - area.angleBorderWidth) + 'px', + top: (area.bottom + areaOffset.bottom - area.angleSize) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 ' + area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px 0', + left: (area.right + areaOffset.right - area.angleSize) + 'px', + top: (area.bottom + areaOffset.bottom - area.angleSize) + 'px', + 'z-index': area.zIndex + 3 + } + ]); + } + + // 变更圆角样式 + if(area.radius > 0) { + var radius = area.radius; + if(area.width === area.height && area.radius >= area.width / 2) { // 圆形 + radius = (area.width / 2); + } else { // 圆角矩形 + if(area.width !== area.height) { // 限制圆角半径不能超过短边的一半 + radius = Math.min(area.width / 2, area.height / 2, radius); + } + } + setStyle(e.instance, 'circleBoxStyles', { + left: (area.left + areaOffset.left) + 'px', + top: (area.top + areaOffset.top) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 2 + }); + setStyle(e.instance, 'circleStyles', { + 'box-shadow': '0 0 0 ' + Math.max(area.width, area.height) + 'px rgba(51, 51, 51, 0.8)', + 'border-radius': radius + 'px' + }); + } +}; +/** + * 缩放图片 + * @param {Object} e 布局信息 + */ +function scaleImage(e) { + // console.log('scaleImage', e) + var last = scale; + scale = Math.min(Math.max(e.scale + scale, minScale), img.maxScale); + if(last !== scale) { + img.width = img.oldWidth * scale; + img.height = img.oldHeight * scale; + // 参考问题:有一个长4000px、宽4000px的四方形ABCD,A点的坐标固定在(-2000,-2000), + // 该四边形上有一个点E,坐标为(-100,-300),将该四方形复制一份并缩小到90%后, + // 新四边形的A点坐标为多少时可使新四边形的E点与原四边形的E点重合? + // 预期效果:从图中选取某点(参照物)为中心点进行缩放,缩放时无论图像怎么变化,该点位置始终固定不变 + // 计算方法:以相同起点先计算缩放前后两点间的距离,再加上原图像偏移量即可 + e.x = (e.x - offset.x) * (1 - scale / last); + e.y = (e.y - offset.y) * (1 - scale / last); + changeImageRect(e); + return true; + } + return false; +}; +/** + * 获取触摸点在哪个角 + * @param {number} x 触摸点x轴坐标 + * @param {number} y 触摸点y轴坐标 + * @return {number} 角的位置:0=无;1=左上;2=右上;3=左下;4=右下; + */ +function getToucheAngle(x, y) { + // console.log('getToucheAngle', x, y, JSON.stringify(area)) + var o = area.angleBorderWidth; // 需扩大触发范围则把 o 值加大即可 + var oy = sys.navigation ? 0 : sys.windowTop; + if(y >= area.top - o + oy && y <= area.top + area.angleSize + o + oy) { + if(x >= area.left - o && x <= area.left + area.angleSize + o) { + return 1; // 左上角 + } else if(x >= area.right - area.angleSize - o && x <= area.right + o) { + return 2; // 右上角 + } + } else if(y >= area.bottom - area.angleSize - o + oy && y <= area.bottom + o + oy) { + if(x >= area.left - o && x <= area.left + area.angleSize + o) { + return 3; // 左下角 + } else if(x >= area.right - area.angleSize - o && x <= area.right + o) { + return 4; // 右下角 + } + } + return 0; // 无触摸到角 +}; +/** + * 重置数据 + */ +function resetData() { + offset = { x: 0, y: 0 }; + scale = 1; + minScale = img.minScale; + rotate = 0; +}; +function getTouchs(touches) { + var result = []; + var len = touches ? touches.length : 0 + for (var i = 0; i < len; i++) { + result[i] = { + pageX: touches[i].pageX, + // h5无标题栏时,窗口顶部距离仍为标题栏高度,且触摸点y轴坐标还是有标题栏的值,即减去标题栏高度的值 + pageY: touches[i].pageY + sys.windowTop + }; + } + return result; +}; +var mouseEvent = false; +export default { + data() { + return { + imageStyles: {}, + maskStylesList: [{}, {}, {}, {}], + borderStyles: {}, + gridStylesList: [{}, {}, {}, {}], + angleStylesList: [{}, {}, {}, {}], + circleBoxStyles: {}, + circleStyles: {} + } + }, + created() { + // 监听 PC 端鼠标滚轮 + // #ifdef H5 + platform === 'H5' && window.addEventListener('mousewheel', async (e) => { + var touchs = getTouchs([e]) + img.src && scaleImage({ + instance: await this.getInstance(), + check: true, + // 鼠标向上滚动时,deltaY 固定 -100,鼠标向下滚动时,deltaY 固定 100 + scale: e.deltaY > 0 ? -0.05 : 0.05, + x: touchs[0].pageX, + y: touchs[0].pageY + }); + }); + // #endif + }, + // #ifdef H5 + mounted() { + platform === 'H5' && this.initH5Events(); + }, + // #endif + setPlatform(p) { + platform = p; + }, + methods: { + // #ifdef H5 + getTouchEvent(e) { + e.touches = [ + { pageX: e.pageX, pageY: e.pageY } + ]; + return e; + }, + initH5Events() { + const preview = document.getElementById('pic-preview'); + preview?.addEventListener('mousedown', (e, ev) => { + mouseEvent = true; + this.touchstart(this.getTouchEvent(e)); + }); + preview?.addEventListener('mousemove', (e) => { + if (!mouseEvent) return; + this.touchmove(this.getTouchEvent(e)); + }); + preview?.addEventListener('mouseup', (e) => { + mouseEvent = false; + this.touchend(this.getTouchEvent(e)) + }); + preview?.addEventListener('mouseleave', (e) => { + mouseEvent = false; + this.touchend(this.getTouchEvent(e)) + }); + }, + // #endif + async getInstance() { + // #ifdef APP-PLUS + if(platform === 'APP') + return this.$ownerInstance + ? Promise.resolve(this.$ownerInstance) + : new Promise((resolve) => { + setTimeout(async () => { + resolve(await this.getInstance()); + }); + }); + // #endif + // #ifdef H5 + if(platform === 'H5') + return Promise.resolve(this); + // #endif + }, + /** + * 初始化:观察数据变更 + * @param {Object} newVal 新数据 + * @param {Object} oldVal 旧数据 + * @param {Object} o 组件实例对象 + */ + initObserver: async function(newVal, oldVal, o, i) { + // console.log('initObserver', newVal, oldVal, o, i) + if(newVal && (!img.src || timestamp !== newVal.timestamp)) { + timestamp = newVal.timestamp; + img = newVal.img; + sys = newVal.sys; + area = newVal.area; + minScale = img.minScale; + resetData(); + const instance = await this.getInstance() + img.src && changeImageRect({ + instance, + x: (sys.windowWidth - img.width) / 2, + y: (sys.windowHeight + sys.windowTop - sys.offsetBottom - img.height) / 2 + }); + changeAreaRect({ + instance + }); + } + }, + /** + * 鼠标滚轮滚动 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + mousewheel: function(e, o) { + // h5平台 wheel 事件无法判断滚轮滑动方向,需使用 mousewheel + }, + /** + * 触摸开始 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + touchstart: function(e, o) { + if(!img.src) return; + touches = getTouchs(e.touches); + activeAngle = area.showAngle ? getToucheAngle(touches[0].pageX, touches[0].pageY) : 0; + if(touches.length === 1 && activeAngle !== 0) { + touchType = 'stretch'; // 伸缩裁剪区域 + } else { + touchType = ''; + } + // console.log('touchstart', e, activeAngle) + }, + /** + * 触摸移动 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + touchmove: async function(e, o) { + if(!img.src) return; + // console.log('touchmove', e, o) + e.touches = getTouchs(e.touches); + if(touchType === 'stretch') { // 触摸四个角进行拉伸 + var point = e.touches[0]; + var start = touches[0]; + var x = point.pageX - start.pageX; + var y = point.pageY - start.pageY; + if(x !== 0 || y !== 0) { + var maxX = area.width * (1 - area.minScale); + var maxY = area.height * (1 - area.minScale); + // console.log(x, y, maxX, maxY, offset, area) + touches[0] = point; + switch(activeAngle) { + case 1: // 左上角 + x += areaOffset.left; + y += areaOffset.top; + // console.log(x, y, offset.left > area.left) + // console.log(maxX, maxY) + if(x >= 0 && y >= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x >= area.left) || (offset.y > 0 && offset.y >= area.top)) + ? Math.min(offset.y - area.top, offset.x - area.left) + : false; + if(x > y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(x > maxX) x = maxX; + y = x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(y > maxY) y = maxY; + x = y * area.width / area.height; + } + areaOffset.left = x; + areaOffset.top = y; + } + break; + case 2: // 右上角 + x += areaOffset.right; + y += areaOffset.top; + if(x <= 0 && y >= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x + img.width <= area.right) || (offset.y > 0 && offset.y >= area.top)) + ? Math.min(offset.y - area.top, area.right - offset.x - img.width) + : false; + if(-x > y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(-x > maxX) x = -maxX; + y = -x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(y > maxY) y = maxY; + x = -y * area.width / area.height; + } + areaOffset.right = x; + areaOffset.top = y; + } + break; + case 3: // 左下角 + x += areaOffset.left; + y += areaOffset.bottom; + if(x >= 0 && y <= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x >= area.left) || (offset.y > 0 && offset.y + img.height <= area.bottom)) + ? Math.min(area.bottom - offset.y - img.height, offset.x - area.left) + : false; + if(x > -y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(x > maxX) x = maxX; + y = -x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(-y > maxY) y = -maxY; + x = -y * area.width / area.height; + } + areaOffset.left = x; + areaOffset.bottom = y; + } + break; + case 4: // 右下角 + x += areaOffset.right; + y += areaOffset.bottom; + if(x <= 0 && y <= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x + img.width <= area.right) || (offset.y > 0 && offset.y + img.height <= area.bottom)) + ? Math.min(area.bottom - offset.y - img.height, area.right - offset.x - img.width) + : false; + if(-x > -y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(-x > maxX) x = -maxX; + y = x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(-y > maxY) y = -maxY; + x = y * area.width / area.height; + } + areaOffset.right = x; + areaOffset.bottom = y; + } + break; + } + // console.log(x, y, JSON.stringify(areaOffset)) + changeAreaRect({ + instance: await this.getInstance(), + }); + // this.draw(); + } + } else if (e.touches.length == 2) { // 双点触摸缩放 + var start = getDistanceByTouches(touches); + var end = getDistanceByTouches(e.touches); + scaleImage({ + instance: await this.getInstance(), + check: !area.bounce, + scale: (end.c - start.c) / 100, + x: end.x, + y: end.y + }); + touchType = 'scale'; + } else if(touchType === 'scale') {// 从双点触摸变成单点触摸 / 从缩放变成拖动 + touchType = 'move'; + } else { + changeImageRect({ + instance: await this.getInstance(), + check: !area.bounce, + x: e.touches[0].pageX - touches[0].pageX, + y: e.touches[0].pageY - touches[0].pageY + }); + touchType = 'move'; + } + touches = e.touches; + }, + /** + * 触摸结束 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + touchend: async function(e, o) { + if(!img.src) return; + if(touchType === 'stretch') { // 拉伸裁剪区域的四个角缩放 + // 裁剪区域宽度被缩放到多少 + var left = areaOffset.left; + var right = areaOffset.right; + var top = areaOffset.top; + var bottom = areaOffset.bottom; + var w = area.width + right - left; + var h = area.height + bottom - top; + // 图像放大倍数 + var p = scale * (area.width / w) - scale; + // 复原裁剪区域 + areaOffset = { left: 0, right: 0, top: 0, bottom: 0 }; + changeAreaRect({ + instance: await this.getInstance(), + }); + scaleImage({ + instance: await this.getInstance(), + scale: p, + x: area.left + left + (1 === activeAngle || 3 === activeAngle ? w : 0), + y: area.top + top + (1 === activeAngle || 2 === activeAngle ? h : 0) + }); + } else if (area.bounce) { // 检查边界并矫正,实现拖动到边界时有回弹效果 + changeImageRect({ + instance: await this.getInstance(), + check: true + }); + } + }, + /** + * 顺时针翻转图片90° + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + rotateImage: async function(r) { + rotate = (rotate + (r || 90)) % 360; + + if(img.minScale >= 1) { + // 因图片宽高可能不等,翻转后图片宽高需足够填满裁剪区域 + minScale = 1; + if(img.width < area.height) { + minScale = area.height / img.oldWidth; + } else if(img.height < area.width) { + minScale = (area.width / img.oldHeight) + } + if(minScale !== 1) { + scaleImage({ + instance: await this.getInstance(), + scale: minScale - scale, + x: sys.windowWidth / 2, + y: (sys.windowHeight - sys.offsetBottom) / 2 + }); + } + } + + // 由于拖动画布后会导致图片位置偏移,翻转时的旋转中心点需是图片区域+偏移区域的中心点 + // 翻转x轴中心点 = (超出裁剪区域右侧的图片宽度 - 超出裁剪区域左侧的图片宽度) / 2 + // 翻转y轴中心点 = (超出裁剪区域下方的图片宽度 - 超出裁剪区域上方的图片宽度) / 2 + var ox = ((offset.x + img.width - area.right) - (area.left - offset.x)) / 2; + var oy = ((offset.y + img.height - area.bottom) - (area.top - offset.y)) / 2; + changeImageRect({ + instance: await this.getInstance(), + check: true, + x: -ox - oy, + y: -oy + ox + }); + }, + rotateImage90: function() { + this.rotateImage(90) + }, + rotateImage270: function() { + this.rotateImage(270) + }, + } +} \ No newline at end of file diff --git a/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.vue b/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.vue new file mode 100644 index 0000000..807731c --- /dev/null +++ b/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.vue @@ -0,0 +1,790 @@ + + + + + + + + + + + + + + diff --git a/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.wxs b/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.wxs new file mode 100644 index 0000000..27fbd51 --- /dev/null +++ b/pagesb/components/qf-image-cropper/components/qf-image-cropper/qf-image-cropper.wxs @@ -0,0 +1,604 @@ +/** + * 图片编辑器-手势监听 + * 1. wxs 暂不支持 es6 语法 + * 2. 支持编译到微信小程序、QQ小程序、app-vue、H5上(uni-app 2.2.5及以上版本) + */ +/** 图片偏移量 */ +var offset = { x: 0, y: 0 }; +/** 图片缩放比例 */ +var scale = 1; +/** 图片最小缩放比例 */ +var minScale = 1; +/** 图片旋转角度 */ +var rotate = 0; +/** 触摸点 */ +var touches = []; +/** 图片布局信息 */ +var img = {}; +/** 系统信息 */ +var sys = {}; +/** 裁剪区域布局信息 */ +var area = {}; +/** 触摸行为类型 */ +var touchType = ''; +/** 操作角的位置 */ +var activeAngle = 0; +/** 裁剪区域布局信息偏移量 */ +var areaOffset = { left: 0, right: 0, top: 0, bottom: 0 }; +/** + * 计算两点间距 + * @param {Object} touches 触摸点信息 + */ +function getDistanceByTouches(touches) { + // 根据勾股定理求两点间距离 + var a = touches[1].pageX - touches[0].pageX; + var b = touches[1].pageY - touches[0].pageY; + var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); + // 求两点间的中点坐标 + // 1. a、b可能为负值 + // 2. 在求a、b时,如用touches[1]减touches[0],则求中点坐标也得用touches[1]减a/2、b/2 + // 3. 同理,在求a、b时,也可用touches[0]减touches[1],则求中点坐标也得用touches[0]减a/2、b/2 + var x = touches[1].pageX - a / 2; + var y = touches[1].pageY - b / 2; + return { c, x, y }; +}; +/** + * 修正取值 + * @param {Object} a + * @param {Object} b + * @param {Object} c + * @param {Object} reverse 是否反向 + */ +function correctValue(a, b, c, reverse) { + return reverse ? Math.max(Math.min(a, b), c) : Math.min(Math.max(a, b), c); +} + +/** + * 检查边界:限制 x、y 拖动范围,禁止滑出边界 + * @param {Object} e 点坐标 + */ +function checkRange(e) { + var r = rotate / 90 % 2; + if(r === 1) { // 因图片宽高可能不等,翻转 90° 或 270° 后图片宽高需反着计算,且左右和上下边界要根据差值做偏移 + var o = (img.height - img.width) / 2; // 宽高差值一半 + return { + x: correctValue(e.x, -img.height + o + area.width + area.left, area.left + o, img.height < area.height), + y: correctValue(e.y, -img.width - o + area.height + area.top, area.top - o, img.width < area.width) + } + } + return { + x: correctValue(e.x, -img.width + area.width + area.left, area.left, img.width < area.width), + y: correctValue(e.y, -img.height + area.height + area.top, area.top, img.height < area.height) + } +}; +/** + * 变更图片布局信息 + * @param {Object} e 布局信息 + */ +function changeImageRect(e) { + offset.x += e.x || 0; + offset.y += e.y || 0; + var image = e.instance.selectComponent('.crop-image'); + if(e.check && area.checkRange) { // 检查边界 + var point = checkRange(offset); + if(offset.x !== point.x || offset.y !== point.y) { + offset = point; + } + } + // image.setStyle({ + // width: img.width + 'px', + // height: img.height + 'px', + // transform: 'translate(' + offset.x + 'px, ' + offset.y + 'px) rotate(' + rotate +'deg)' + // }); + var ox = (img.width - img.oldWidth) / 2; + var oy = (img.height - img.oldHeight) / 2; + image.setStyle({ + width: img.oldWidth + 'px', + height: img.oldHeight + 'px', + transform: (img.gpu ? 'translateZ(0) ' : '') + 'translate(' + (offset.x + ox) + 'px, ' + (offset.y + oy) + 'px) rotate(' + rotate +'deg) scale(' + scale + ')' + }); + + e.instance.callMethod('dataChange', { + width: img.width, + height: img.height, + x: offset.x, + y: offset.y, + rotate: rotate + }); +}; +/** + * 变更裁剪区域布局信息 + * @param {Object} e 布局信息 + */ +function changeAreaRect(e) { + // 变更蒙版样式 + var masks = e.instance.selectAllComponents('.crop-mask-block'); + var maskStyles = [ + { + left: 0, + width: (area.left + areaOffset.left) + 'px', + top: 0, + bottom: 0, + 'z-index': area.zIndex + 2 + }, + { + left: (area.right + areaOffset.right) + 'px', + right: 0, + top: 0, + bottom: 0, + 'z-index': area.zIndex + 2 + }, + { + left: (area.left + areaOffset.left) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + top: 0, + height: (area.top + areaOffset.top) + 'px', + 'z-index': area.zIndex + 2 + }, + { + left: (area.left + areaOffset.left) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + top: (area.bottom + areaOffset.bottom) + 'px', + // height: (area.top - areaOffset.bottom + sys.offsetBottom) + 'px', + bottom: 0, + 'z-index': area.zIndex + 2 + } + ]; + var len = masks.length; + for (var i = 0; i < len; i++) { + masks[i].setStyle(maskStyles[i]); + } + + // 变更边框样式 + if(area.showBorder) { + var border = e.instance.selectComponent('.crop-border'); + border.setStyle({ + left: (area.left + areaOffset.left) + 'px', + top: (area.top + areaOffset.top) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 3 + }); + } + + // 变更参考线样式 + if(area.showGrid) { + var grids = e.instance.selectAllComponents('.crop-grid'); + var gridStyles = [ + { + 'border-width': '1px 0 0 0', + left: (area.left + areaOffset.left) + 'px', + right: (area.right + areaOffset.right) + 'px', + top: (area.top + areaOffset.top + (area.height + areaOffset.bottom - areaOffset.top) / 3 - 0.5) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '1px 0 0 0', + left: (area.left + areaOffset.left) + 'px', + right: (area.right + areaOffset.right) + 'px', + top: (area.top + areaOffset.top + (area.height + areaOffset.bottom - areaOffset.top) * 2 / 3 - 0.5) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 1px 0 0', + top: (area.top + areaOffset.top) + 'px', + bottom: (area.bottom + areaOffset.bottom) + 'px', + left: (area.left + areaOffset.left + (area.width + areaOffset.right - areaOffset.left) / 3 - 0.5) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 1px 0 0', + top: (area.top + areaOffset.top) + 'px', + bottom: (area.bottom + areaOffset.bottom) + 'px', + left: (area.left + areaOffset.left + (area.width + areaOffset.right - areaOffset.left) * 2 / 3 - 0.5) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 3 + } + ]; + var len = grids.length; + for (var i = 0; i < len; i++) { + grids[i].setStyle(gridStyles[i]); + } + } + + // 变更四个伸缩角样式 + if(area.showAngle) { + var angles = e.instance.selectAllComponents('.crop-angle'); + var angleStyles = [ + { + 'border-width': area.angleBorderWidth + 'px 0 0 ' + area.angleBorderWidth + 'px', + left: (area.left + areaOffset.left - area.angleBorderWidth) + 'px', + top: (area.top + areaOffset.top - area.angleBorderWidth) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px 0 0', + left: (area.right + areaOffset.right - area.angleSize) + 'px', + top: (area.top + areaOffset.top - area.angleBorderWidth) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 0 ' + area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px', + left: (area.left + areaOffset.left - area.angleBorderWidth) + 'px', + top: (area.bottom + areaOffset.bottom - area.angleSize) + 'px', + 'z-index': area.zIndex + 3 + }, + { + 'border-width': '0 ' + area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px 0', + left: (area.right + areaOffset.right - area.angleSize) + 'px', + top: (area.bottom + areaOffset.bottom - area.angleSize) + 'px', + 'z-index': area.zIndex + 3 + } + ]; + var len = angles.length; + for (var i = 0; i < len; i++) { + angles[i].setStyle(angleStyles[i]); + } + } + + // 变更圆角样式 + if(area.radius > 0) { + var circleBox = e.instance.selectComponent('.crop-circle-box'); + var circle = e.instance.selectComponent('.crop-circle'); + var radius = area.radius; + if(area.width === area.height && area.radius >= area.width / 2) { // 圆形 + radius = (area.width / 2); + } else { // 圆角矩形 + if(area.width !== area.height) { // 限制圆角半径不能超过短边的一半 + radius = Math.min(area.width / 2, area.height / 2, radius); + } + } + circleBox.setStyle({ + left: (area.left + areaOffset.left) + 'px', + top: (area.top + areaOffset.top) + 'px', + width: (area.width + areaOffset.right - areaOffset.left) + 'px', + height: (area.height + areaOffset.bottom - areaOffset.top) + 'px', + 'z-index': area.zIndex + 2 + }); + circle.setStyle({ + 'box-shadow': '0 0 0 ' + Math.max(area.width, area.height) + 'px rgba(51, 51, 51, 0.8)', + 'border-radius': radius + 'px' + }); + } +}; +/** + * 缩放图片 + * @param {Object} e 布局信息 + */ +function scaleImage(e) { + var last = scale; + scale = Math.min(Math.max(e.scale + scale, minScale), img.maxScale); + if(last !== scale) { + img.width = img.oldWidth * scale; + img.height = img.oldHeight * scale; + // 参考问题:有一个长4000px、宽4000px的四方形ABCD,A点的坐标固定在(-2000,-2000), + // 该四边形上有一个点E,坐标为(-100,-300),将该四方形复制一份并缩小到90%后, + // 新四边形的A点坐标为多少时可使新四边形的E点与原四边形的E点重合? + // 预期效果:从图中选取某点(参照物)为中心点进行缩放,缩放时无论图像怎么变化,该点位置始终固定不变 + // 计算方法:以相同起点先计算缩放前后两点间的距离,再加上原图像偏移量即可 + e.x = (e.x - offset.x) * (1 - scale / last); + e.y = (e.y - offset.y) * (1 - scale / last); + changeImageRect(e); + return true; + } + return false; +}; +/** + * 获取触摸点在哪个角 + * @param {number} x 触摸点x轴坐标 + * @param {number} y 触摸点y轴坐标 + * @return {number} 角的位置:0=无;1=左上;2=右上;3=左下;4=右下; + */ +function getToucheAngle(x, y) { + // console.log('getToucheAngle', x, y, JSON.stringify(area)) + var o = area.angleBorderWidth; // 需扩大触发范围则把 o 值加大即可 + if(y >= area.top - o && y <= area.top + area.angleSize + o) { + if(x >= area.left - o && x <= area.left + area.angleSize + o) { + return 1; // 左上角 + } else if(x >= area.right - area.angleSize - o && x <= area.right + o) { + return 2; // 右上角 + } + } else if(y >= area.bottom - area.angleSize - o && y <= area.bottom + o) { + if(x >= area.left - o && x <= area.left + area.angleSize + o) { + return 3; // 左下角 + } else if(x >= area.right - area.angleSize - o && x <= area.right + o) { + return 4; // 右下角 + } + } + return 0; // 无触摸到角 +}; +/** + * 重置数据 + */ +function resetData() { + offset = { x: 0, y: 0 }; + scale = 1; + minScale = img.minScale; + rotate = 0; +}; +/** +* 顺时针翻转图片90° +* @param {Object} e 事件对象 +* @param {Object} o 组件实例对象 +*/ +function rotateImage(e, o, r) { + rotate = (rotate + r) % 360; + + if(img.minScale >= 1) { + // 因图片宽高可能不等,翻转后图片宽高需足够填满裁剪区域 + minScale = 1; + if(img.width < area.height) { + minScale = area.height / img.oldWidth; + } else if(img.height < area.width) { + minScale = (area.width / img.oldHeight) + } + if(minScale !== 1) { + scaleImage({ + instance: o, + scale: minScale - scale, + x: sys.windowWidth / 2, + y: (sys.windowHeight - sys.offsetBottom) / 2 + }); + } + } + + // 由于拖动画布后会导致图片位置偏移,翻转时的旋转中心点需是图片区域+偏移区域的中心点 + // 翻转x轴中心点 = (超出裁剪区域右侧的图片宽度 - 超出裁剪区域左侧的图片宽度) / 2 + // 翻转y轴中心点 = (超出裁剪区域下方的图片宽度 - 超出裁剪区域上方的图片宽度) / 2 + var ox = ((offset.x + img.width - area.right) - (area.left - offset.x)) / 2; + var oy = ((offset.y + img.height - area.bottom) - (area.top - offset.y)) / 2; + changeImageRect({ + instance: o, + check: true, + x: -ox - oy, + y: -oy + ox + }); +}; +module.exports = { + /** + * 初始化:观察数据变更 + * @param {Object} newVal 新数据 + * @param {Object} oldVal 旧数据 + * @param {Object} o 组件实例对象 + */ + initObserver: function(newVal, oldVal, o, i) { + if(newVal) { + img = newVal.img; + sys = newVal.sys; + area = newVal.area; + minScale = img.minScale; + resetData(); + img.src && changeImageRect({ + instance: o, + x: (sys.windowWidth - img.width) / 2, + y: (sys.windowHeight - sys.offsetBottom - img.height) / 2 + }); + changeAreaRect({ + instance: o + }); + // console.log('initRect', JSON.stringify(newVal)) + } + }, + /** + * 鼠标滚轮滚动 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + mousewheel: function(e, o) { + if(!img.src) return; + scaleImage({ + instance: o, + check: true, + // 鼠标向上滚动时,deltaY 固定 -100,鼠标向下滚动时,deltaY 固定 100 + scale: e.detail.deltaY > 0 ? -0.05 : 0.05, + x: e.touches[0].pageX, + y: e.touches[0].pageY + }); + }, + /** + * 触摸开始 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + touchstart: function(e, o) { + if(!img.src) return; + touches = e.touches; + activeAngle = area.showAngle ? getToucheAngle(touches[0].pageX, touches[0].pageY) : 0; + if(touches.length === 1 && activeAngle !== 0) { + touchType = 'stretch'; // 伸缩裁剪区域 + } else { + touchType = ''; + } + // console.log('touchstart', JSON.stringify(e), activeAngle) + }, + /** + * 触摸移动 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + touchmove: function(e, o) { + if(!img.src) return; + // console.log('touchmove', JSON.stringify(e), JSON.stringify(o)) + if(touchType === 'stretch') { // 触摸四个角进行拉伸 + var point = e.touches[0]; + var start = touches[0]; + var x = point.pageX - start.pageX; + var y = point.pageY - start.pageY; + if(x !== 0 || y !== 0) { + var maxX = area.width * (1 - area.minScale); + var maxY = area.height * (1 - area.minScale); + // console.log(x, y, maxX, maxY, offset, area) + touches[0] = point; + switch(activeAngle) { + case 1: // 左上角 + x += areaOffset.left; + y += areaOffset.top; + if(x >= 0 && y >= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x >= area.left) || (offset.y > 0 && offset.y >= area.top)) + ? Math.min(offset.y - area.top, offset.x - area.left) + : false; + if(x > y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(x > maxX) x = maxX; + y = x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(y > maxY) y = maxY; + x = y * area.width / area.height; + } + areaOffset.left = x; + areaOffset.top = y; + } + break; + case 2: // 右上角 + x += areaOffset.right; + y += areaOffset.top; + if(x <= 0 && y >= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x + img.width <= area.right) || (offset.y > 0 && offset.y >= area.top)) + ? Math.min(offset.y - area.top, area.right - offset.x - img.width) + : false; + if(-x > y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(-x > maxX) x = -maxX; + y = -x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(y > maxY) y = maxY; + x = -y * area.width / area.height; + } + areaOffset.right = x; + areaOffset.top = y; + } + break; + case 3: // 左下角 + x += areaOffset.left; + y += areaOffset.bottom; + if(x >= 0 && y <= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x >= area.left) || (offset.y > 0 && offset.y + img.height <= area.bottom)) + ? Math.min(area.bottom - offset.y - img.height, offset.x - area.left) + : false; + if(x > -y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(x > maxX) x = maxX; + y = -x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(-y > maxY) y = -maxY; + x = -y * area.width / area.height; + } + areaOffset.left = x; + areaOffset.bottom = y; + } + break; + case 4: // 右下角 + x += areaOffset.right; + y += areaOffset.bottom; + if(x <= 0 && y <= 0) { // 有效滑动 + var max = minScale < 1 && area.checkRange && ((offset.x > 0 && offset.x + img.width <= area.right) || (offset.y > 0 && offset.y + img.height <= area.bottom)) + ? Math.min(area.bottom - offset.y - img.height, area.right - offset.x - img.width) + : false; + if(-x > -y) { // 以x轴滑动距离为缩放基准 + if(typeof max === 'number') maxX = max; + if(-x > maxX) x = -maxX; + y = x * area.height / area.width; + } else { // 以y轴滑动距离为缩放基准 + if(typeof max === 'number') maxY = max; + if(-y > maxY) y = -maxY; + x = y * area.width / area.height; + } + areaOffset.right = x; + areaOffset.bottom = y; + } + break; + } + // console.log(x, y, JSON.stringify(areaOffset)) + changeAreaRect({ + instance: o, + }); + // this.draw(); + } + } else if (e.touches.length == 2) { // 双点触摸缩放 + var start = getDistanceByTouches(touches); + var end = getDistanceByTouches(e.touches); + scaleImage({ + instance: o, + check: !area.bounce, + scale: (end.c - start.c) / 100, + x: end.x, + y: end.y + }); + touchType = 'scale'; + } else if(touchType === 'scale') {// 从双点触摸变成单点触摸 / 从缩放变成拖动 + touchType = 'move'; + } else { + changeImageRect({ + instance: o, + check: !area.bounce, + x: e.touches[0].pageX - touches[0].pageX, + y: e.touches[0].pageY - touches[0].pageY + }); + touchType = 'move'; + } + touches = e.touches; + }, + /** + * 触摸结束 + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + touchend: function(e, o) { + if(!img.src) return; + if(touchType === 'stretch') { // 拉伸裁剪区域的四个角缩放 + // 裁剪区域宽度被缩放到多少 + var left = areaOffset.left; + var right = areaOffset.right; + var top = areaOffset.top; + var bottom = areaOffset.bottom; + var w = area.width + right - left; + var h = area.height + bottom - top; + // 图像放大倍数 + var p = scale * (area.width / w) - scale; + // 复原裁剪区域 + areaOffset = { left: 0, right: 0, top: 0, bottom: 0 }; + changeAreaRect({ + instance: o, + }); + scaleImage({ + instance: o, + scale: p, + x: area.left + left + (1 === activeAngle || 3 === activeAngle ? w : 0), + y: area.top + top + (1 === activeAngle || 2 === activeAngle ? h : 0) + }); + } else if (area.bounce) { // 检查边界并矫正,实现拖动到边界时有回弹效果 + changeImageRect({ + instance: o, + check: true + }); + } + }, + /** + * 顺时针翻转图片90° + * @param {Object} e 事件对象 + * @param {Object} o 组件实例对象 + */ + rotateImage: function(e, o) { + rotateImage(e, o, 90); + }, + rotateImage90: function(e, o) { + rotateImage(e, o, 90) + }, + rotateImage270: function(e, o) { + rotateImage(e, o, 270) + }, + // 此处只用于对齐其他平台端的样式参数,防止异常,无作用 + imageStyles: '', + maskStylesList: ['', '', '', ''], + borderStyles: '', + gridStylesList: ['', '', '', ''], + angleStylesList: ['', '', '', ''], + circleBoxStyles: '', + circleStyles: '', +} \ No newline at end of file diff --git a/pagesb/components/qf-image-cropper/package.json b/pagesb/components/qf-image-cropper/package.json new file mode 100644 index 0000000..e945454 --- /dev/null +++ b/pagesb/components/qf-image-cropper/package.json @@ -0,0 +1,81 @@ +{ + "id": "qf-image-cropper", + "displayName": "图片裁剪插件", + "version": "2.2.4", + "description": "图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式,功能多性能高体验好注释全。", + "keywords": [ + "qf-image-cropper", + "图片裁剪", + "图片编辑", + "头像裁剪", + "小程序" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, +"dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "y", + "阿里": "n", + "百度": "n", + "字节跳动": "n", + "QQ": "u", + "钉钉": "n", + "快手": "n", + "飞书": "n", + "京东": "n" + }, + "快应用": { + "华为": "n", + "联盟": "n" + } + } + } + } +} \ No newline at end of file diff --git a/pagesb/components/qf-image-cropper/readme.md b/pagesb/components/qf-image-cropper/readme.md new file mode 100644 index 0000000..0c62aac --- /dev/null +++ b/pagesb/components/qf-image-cropper/readme.md @@ -0,0 +1,95 @@ +# qf-image-cropper +## 图片裁剪插件 +uniapp微信小程序图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式,功能多性能高体验好注释全。 + +### 平台支持: +1. 支持微信小程序:移动端、PC端、开发者工具 +2. 支持H5平台(2.1.0版本起) +3. 支持APP平台(2.1.5版本起):Android、IOS +4. 其他平台暂未测试兼容性未知 + +### 支持功能: +1. 自定义裁剪尺寸 +2. 定点等比例缩放:移动端以双指触摸中心点为缩放中心点,PC端以鼠标所在点为缩放中心点 +3. 自由拖动:支持限制滑出边界,也支持回弹效果(滑动时可滑出边界,释放时回弹到边界) +4. 图片翻转:在裁剪尺寸非 1:1 的情况下,翻转时宽高无法铺满裁剪区域时,图片会自动放大到合适尺寸 +5. 裁剪生成新图片 +6. 本地选择图片 +7. 可定制样式:可自由选择是否渲染裁剪边框、可伸缩裁剪顶角、参考线 +8. 裁剪圆角图片:圆形、圆角矩形 + +### 属性说明 +| 属性名 | 类型 | 默认值 | 说明 | +|:---|:---|:---|:---| +| src | String | | 图片资源地址 | +| width | Number | 300 | 裁剪宽度 | +| height | Number | 300 | 裁剪高度 | +| showBorder | Boolean | true | 是否绘制裁剪区域边框 | +| showGrid | Boolean | true | 是否绘制裁剪区域网格参考线 | +| showAngle | Boolean | true | 是否展示四个支持伸缩的角 | +| areaScale | Number | 0.3 | 裁剪区域最小缩放倍数 | +| minScale | Number | 1 | 图片最小缩放倍数 | +| maxScale | Number | 5 | 图片最大缩放倍数 | +| checkRange | Boolean | true | 检查图片位置是否超出裁剪边界,如果超出则会矫正位置 | +| backgroundColor | String | | 生成图片背景色:如果裁剪区域没有完全包含在图片中时,不设置该属性则生成图片存在一定的透明块 | +| bounce | Boolean | true | 是否有回弹效果:当 checkRange 为 true 时有效,拖动时可以拖出边界,释放时会弹回边界 | +| rotatable | Boolean | true | 是否支持翻转 | +| reverseRotatable | Boolean | false | 是否支持逆向翻转 | +| choosable | Boolean | true | 是否支持从本地选择素材 | +| gpu | Boolean | false | 是否开启硬件加速,图片缩放过程中如果出现元素的“留影”或“重影”效果,可通过该方式解决或减轻这一问题 | +| angleSize | Number | 20 | 四个角尺寸,单位px | +| angleBorderWidth | Number | 2 | 四个角边框宽度,单位px | +| zIndex | Number/String | | 调整组件层级 | +| radius | Number | | 裁剪图片圆角半径,单位px | +| fileType | String | png | 生成文件的类型,只支持 'jpg' 或 'png'。默认为 'png' | +| delay | Number | 1000 | 图片从绘制到生成所需时间,单位ms
微信小程序平台使用 `Canvas 2D` 绘制时有效
如绘制大图或出现裁剪图片空白等情况应适当调大该值,因 `Canvas 2d` 采用同步绘制,需自己把控绘制完成时间 | +| navigation | Boolean | true | 页面是否是原生标题栏:
H5平台当 showAngle 为 true 时,使用插件的页面在 `page.json` 中配置了 `"navigationStyle": "custom"` 时,必须将此值设为 false ,否则四个可拉伸角的触发位置会有偏差。
注:因H5平台的窗口高度是包含标题栏的,而屏幕触摸点的坐标是不包含的 | +| @crop | EventHandle | | 剪裁完成后触发,event = { tempFilePath }。在H5平台下,tempFilePath 为 base64 | + +### 基本用法 +``` + + + +``` +通过ref组件实例可在进入页面后直接打开相册选择图片 +``` +mounted() { + this.$refs.qfImageCropper.chooseImage({ sourceType: ['album'] }); +} +``` +### 使用说明 +1.建议在`pages.json`中将引用插件的页面添加一下配置禁止下拉刷新和禁止页面滑动,防止出现性能或页面抖动等问题。 +``` +{ + "enablePullDownRefresh": false, + "disableScroll": true +} +``` +2.建议使用本插件不要设置过大宽高的目标图片尺寸,建议1365x1365以内,否则可能会导致如下问题: +``` +1.界面卡顿,内存占用过高 +2.生成图片失真(模糊) +3.确定裁剪后一直显示 `裁剪中...`,该问题是由 `uni.canvasToTempFilePath` 无法回调导致,不同平台不同设备限制可能有所不同。 +``` +3.如裁剪后的图片存在偏移的问题,请检查是否受自己项目中父组件或全局样式影响。 +4.src属性设置网络图片时,图片资源必须是能触发 `getImageInfo` API 的 success 回调才可用于插件裁剪。因此小程序平台获取网络图片信息需先配置download域名白名单才能生效。 \ No newline at end of file diff --git a/pagesb/flashSale/index.vue b/pagesb/flashSale/index.vue new file mode 100644 index 0000000..fee5f8d --- /dev/null +++ b/pagesb/flashSale/index.vue @@ -0,0 +1,451 @@ + + + + + diff --git a/pagesb/houseKey/index.vue b/pagesb/houseKey/index.vue new file mode 100644 index 0000000..af4b327 --- /dev/null +++ b/pagesb/houseKey/index.vue @@ -0,0 +1,340 @@ + + + + diff --git a/pagesb/initLock/index.vue b/pagesb/initLock/index.vue new file mode 100644 index 0000000..1a5d18b --- /dev/null +++ b/pagesb/initLock/index.vue @@ -0,0 +1,728 @@ + + + + + diff --git a/pagesb/initLock/lockInitApi.js b/pagesb/initLock/lockInitApi.js new file mode 100644 index 0000000..87233a4 --- /dev/null +++ b/pagesb/initLock/lockInitApi.js @@ -0,0 +1,158 @@ +const getResponseData = (response) => { + switch (response.type) { + case 0: + return response["data"]; // 操作成功 + default: { + uni.showToast({ + icon: "none", + title: response.errorMsg, + }); + return null; + } + } +}; + +export const ttLockRequest = (url, method, params) => { + return new Promise(resolve => { + uni.request({ + url: `https://cnapi.ttlock.com${url}`, + header: { + "content-type": "application/x-www-form-urlencoded", + }, + data: params, + method: method, + success: (response) => { + let result = null; + switch (response.statusCode) { + case 200: + if (!!response.data && typeof response.data["errcode"] === "undefined") { + result = getResponseData({ + data: response.data, + errorCode: -2, + errorMsg: "操作成功", + type: 0, + }); + } else { + let errMsg = response.data["errcode"] === 0 ? "操作成功" : response.data["errmsg"]; + result = getResponseData({ + data: response.data, + errorCode: -2, + errorMsg: errMsg, + type: 0, + }); + } + break; + default: + result = getResponseData({ + errorCode: -2, + errorMsg: `服务器请求失败,状态码:${response.statusCode}`, + type: 2, + }); + break; + } + resolve(result); + }, + fail: (err) => { + let result = getResponseData({ + errorCode: -1, + errorMsg: "服务器请求失败,请检查服务器域名是否已被列入白名单", + type: 3, + }); + resolve(result); + }, + }); + }); +}; + +export const ttLockRequest2 = (url, method, params) => { + return new Promise(resolve => { + uni.request({ + url: `https://api.ttlock.com${url}`, + header: { + "content-type": "application/x-www-form-urlencoded", + }, + data: _makeParams(params), + method: method, + dataType: "json", + success: (response) => { + let result = null; + switch (response.statusCode) { + case 200: + if (!!response.data && typeof response.data["errcode"] === "undefined") { + result = getResponseData({ + data: response.data, + errorCode: -2, + errorMsg: "操作成功", + type: 0, + }); + } else { + let errMsg = response.data["errcode"] === 0 ? "操作成功" : response.data["errmsg"]; + result = getResponseData({ + data: response.data, + errorCode: -2, + errorMsg: errMsg, + type: 0, + }); + } + break; + default: + result = getResponseData({ + errorCode: -2, + errorMsg: `服务器请求失败,状态码:${response.statusCode}`, + type: 2, + }); + break; + } + resolve(result); + }, + fail: (err) => { + let result = getResponseData({ + errorCode: -1, + errorMsg: "服务器请求失败,请检查服务器域名是否已被列入白名单", + type: 3, + }); + resolve(result); + }, + }); + }); +}; + +function _generateParams(params) { + if (!params) return {}; + for (let key of Object.keys(params)) { + if (params[key] === null) { + params[key] = undefined; + continue; + } + const type = typeof params[key]; + switch (type) { + case "function": + { + params[key] = undefined; + } + break; + case "object": + { + params[key] = JSON.stringify(params[key]); + } + break; + case "number": + case "string": + case "boolean": + default: + break; + } + } + return JSON.parse(JSON.stringify(params)); +} + +function _makeParams(params) { + return JSON.parse( + JSON.stringify({ + ..._generateParams(params), + clientId: "7946f0d923934a61baefb3303de4d132", + accessToken: uni.getStorageSync("tt_access_token"), + date: Date.now(), + }) + ); +} \ No newline at end of file diff --git a/pagesb/invitation/index.vue b/pagesb/invitation/index.vue new file mode 100644 index 0000000..9d24eeb --- /dev/null +++ b/pagesb/invitation/index.vue @@ -0,0 +1,394 @@ + + + + + diff --git a/pagesb/invoice/index.vue b/pagesb/invoice/index.vue new file mode 100644 index 0000000..3cdb0f8 --- /dev/null +++ b/pagesb/invoice/index.vue @@ -0,0 +1,291 @@ + + + + + diff --git a/pagesb/invoiceApply/index.vue b/pagesb/invoiceApply/index.vue new file mode 100644 index 0000000..d0bc9bb --- /dev/null +++ b/pagesb/invoiceApply/index.vue @@ -0,0 +1,582 @@ + + + + + \ No newline at end of file diff --git a/pagesb/invoiceApplyforRecord/index.vue b/pagesb/invoiceApplyforRecord/index.vue new file mode 100644 index 0000000..000b487 --- /dev/null +++ b/pagesb/invoiceApplyforRecord/index.vue @@ -0,0 +1,271 @@ + + + + + diff --git a/pagesb/latestEvents/index.vue b/pagesb/latestEvents/index.vue new file mode 100644 index 0000000..33142b4 --- /dev/null +++ b/pagesb/latestEvents/index.vue @@ -0,0 +1,189 @@ + + + + diff --git a/pagesb/maskUser/index.vue b/pagesb/maskUser/index.vue new file mode 100644 index 0000000..14857b8 --- /dev/null +++ b/pagesb/maskUser/index.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/pagesb/pointsMall/index.vue b/pagesb/pointsMall/index.vue new file mode 100644 index 0000000..16bc81d --- /dev/null +++ b/pagesb/pointsMall/index.vue @@ -0,0 +1,522 @@ + + + + + diff --git a/pagesb/referrerInfo/index.vue b/pagesb/referrerInfo/index.vue new file mode 100644 index 0000000..f504cf7 --- /dev/null +++ b/pagesb/referrerInfo/index.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/pagesb/reserve/index.vue b/pagesb/reserve/index.vue new file mode 100644 index 0000000..baee6bf --- /dev/null +++ b/pagesb/reserve/index.vue @@ -0,0 +1,530 @@ + + + + diff --git a/pagesb/unittypeDetail/index.vue b/pagesb/unittypeDetail/index.vue new file mode 100644 index 0000000..da9fbe8 --- /dev/null +++ b/pagesb/unittypeDetail/index.vue @@ -0,0 +1,280 @@ + + + + diff --git a/pagesb/userguide/index.vue b/pagesb/userguide/index.vue new file mode 100644 index 0000000..513f932 --- /dev/null +++ b/pagesb/userguide/index.vue @@ -0,0 +1,356 @@ + + + + diff --git a/pagesb/validationInfo/index.vue b/pagesb/validationInfo/index.vue new file mode 100644 index 0000000..5ff74d9 --- /dev/null +++ b/pagesb/validationInfo/index.vue @@ -0,0 +1,618 @@ + + + + diff --git a/pagesb/videoTutorial/index.vue b/pagesb/videoTutorial/index.vue new file mode 100644 index 0000000..78a8050 --- /dev/null +++ b/pagesb/videoTutorial/index.vue @@ -0,0 +1,249 @@ + + + + diff --git a/static/book/noSelectMapIcon.png b/static/book/noSelectMapIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..b87cda897f4bc1c51d59931de16ac0a0b6a0102a GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQaHv)V@T!Hle%Lf1VnEXF)`2T_- zh_M@nt{D8kWcdH2(f@Ns|Bo5{KWhB{h|&Ke#{c)4{NH8v|CA9(>V)zCV_VeoW?4UR zO&?WbFApzwM_2cwGpzpK(4Sake`l%1aq z(EE1}E^gnra^YN#Z=c@3ym6+ZJu%+T&8Nsn6sYu_r;B5V#O2%x*NYAr2)JJ7z0B0| zMaz3yj`uOy*+N;b{{IgYu})yK$gfT-dv~{$tGM8PUO7AOip+aUk6L(!$-SLn{ry0< z4woU{VxK=NrdBVRJ+nXdc;UwWqNrQp`xJ#wy9wP+syI43=w8>&BToM#csjEsC++K9 za{G4RG&|@09UEf3XCJx8T5^10H{Xm&`n*$EtY1uc;A}ZHXJJF#mUk1Dvemx#nNS&% z>Brk3ow#{d&4ax4Z4CN0{5Rg6X;_>2(|+o+KL2I)lKXZqn;x*J$grO?S*7lN(Mv5U u*;l&a^Y6=DgC#L_l(<~e&J56*HNuZdNvX0a|TaWKbLh*2~7a783~O5 literal 0 HcmV?d00001 diff --git a/static/book/return.png b/static/book/return.png new file mode 100644 index 0000000000000000000000000000000000000000..1f3ee10b858cb94d1313c6e84820d9f97655999e GIT binary patch literal 425 zcmV;a0apHrP)Px$V@X6oRCodH+CdV+APj|Jj^@$4nMaF*L&m^h4X&KLzZ*a>FkUiJAm1=XR&Ej~NelyHY9Us?v1XIezgIpT zV1!Ey1{gsgOb?P#e|ZIiWCVdQB^fhD{Kq=qX3b|3Jp&96$Fi3(XJI}g8N)+kZzGuu zFhZ4pA%!tEgTrtBIIW)yFnmpIt%30yhQuyce}I%Z>SOefB=0k1Ff!@Tz!>QOB=pkP zl#*FQ4whR=XS4KxvO%eT%kEWlP(GkYC#5GQx%%iN1r%>2%Scid5R$S1IY8;XxBg=Y zH%gWdD4Qi&4&~E}xT}p+`GDfR#7AC>aEUO25-@yvfFiYhknJg;tV>T%l&7owNcn6o z@c|0=DQo#`JnMdxOo~oQ`lbGcQa274zw816@1sNS4o^KfZtW;MTeI^EU=S7pvKafGW>=x;TbNTu!}ky|3AU$03m2sp0OI9AC-ms)bAc{NKN{sbfce@sf$U zhc~}XGo8O)Es`&`a8ZiJX@#pw*>Af~-!kp!U9Bp=wd@KTYcdn>=T{4@>s*r7ci8mj z|4=r4DQ0SDc~&uOYvSHBo=XiT^8M~O_s{W>^hNi^qY`%BDfxk43*8M5sPOFPXODfO zpYmQivp7ufK**+lpAOZ@GbFw1v|4;1c!%kud0W{99djAxY5DVYekj`ZM?P*TcWU=4 qEggCH3sc=+Kh4<|Qdhh9GwO97=x#)pUXO@geCyFlH|4k literal 0 HcmV?d00001 diff --git a/static/customicons.css b/static/customicons.css new file mode 100644 index 0000000..14ed5fa --- /dev/null +++ b/static/customicons.css @@ -0,0 +1,20 @@ +@font-face { + font-family: "customicons"; /* Project id 2878519 */ + src:url('/static/customicons.ttf') format('truetype'); +} + +.customicons { + font-family: "customicons" !important; +} + +.youxi:before { + content: "\e60e"; +} + +.wenjian:before { + content: "\e60f"; +} + +.zhuanfa:before { + content: "\e610"; +} diff --git a/static/customicons.ttf b/static/customicons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a3c8ab9f22d18d5d605503eda314e5d2a31fdfc0 GIT binary patch literal 2416 zcmd^A%WoS+82@H>?IgD2#K~q|hdkDH>bQB>&f0O>=25F@5|GlQX`8fENObGiPEx<* zIHl>yDoB8U!lAtvAt9k$df{KC1gT1(TA*@aKU;Z8A_c6Yj%<0Ab$%Pq=pKvad z-A@0oKRQn&-bGc{Qu=Do+{0<;!iM5&AR2xX-va&;wQns~zS&B(8f^c>xHVfy>O!2V zuzd$(TTZ`OWbJet@*^0lc|DhE{bb?+k@a&TAyX`DmiI>vrzUh9wW#VtLONPQPcgH{GfcG%HCo!>rVIv8K7)wAe(G9W~W6s*} z5MlL3;c^>AXo`e0v-20pnbpgA>V(Zx`M)vCu4i=kuX|?D<5C8Ok=0}+EcYWmqwucq z9k>tcJ$p@N7UdY3K%*@M)z9zF77#b3%z!fxHdq^cAvWrY zjm5{}(W73UQ-HKbh-#b|iyQiGC8|vcP=ZB(`A1^`pS7F$eO6f+XC1Pl#U~jwSS-Z6 zoYdm6fFb2Ts4UG+2aoy3eJ4h)WHMJqPWZ+ggv;Y`8Ne>v?K0a?dV7a@d%xnHstS*S!80>UHNq5P zcT^Cf-6E!7v@~-j7+e|8elTC7!G#HLb7P0n=yWzJ9gWT2iG@K%Yp-64j#evA{TmZG zWJPwUm;la=mS?v1K>SNwq9YWdlSr<&p0z19Zlu(!^)Mr=JSzZ7)T_mjuz=s|>kl!c zB@l~)Q)H`{IH*LH!r`TeI(%*{!Lr8Sps0GoVXsi(ZM7mhk8cX!KdH!FU9!mAbI=zO zP#q6W0#>gAiixoIV3!-P``)ng_~q*Du3#5l{`J@HiH~s`$rPj0xaF>5@3G|gDTd`t z2}&`saAq1brJKoCUtp5O z;^K01ht1M-_H0vw)#X+iuR9#q9aYKR<`5;DCw%I1?(O?_+2N4wrR4G}CnNsOmL?^| z?r41nJAO^`vqW__v>3uGEQc3DyKNq9yhk|YJmP6uSZGw-E=vQP_BpOMS9fi$j;5~R zmD%KpS-b3(?Z^BHZ8{R|>1<(-tEK86+@Y}Cr!9vT!UsEbw=A*jY1`o&ywm0}zN$9* z)x4>Q+QHOsI)0nBn^>R*ddb8hc%O+S-~kg`@aNM^Yz04QVjB(OyQ}-O!($Prh)GSD zCqQqSm{BWzW@3Sy^o5B<@ZXwP0{+Rw7E);6#8&VJCbrQEYc{c+0xUUQO6ld)s(Ni( zT~8MB=|aAI*q={jwz7KZaCq3Sq)MCXg}gcviX2jNseGz*=w|aqMk|-oYPwX&sk88x z%4Q2{u~gVdCCj0;a=Cai9OmS z&fu!b!m{+7^jYf_XqRXcdfcZoHN+IGM+T-)9_ZH9MG(} zz7$rH1y-?vT($u}Noa>?&9ExsItb%AjOS24WW<@{KiqoZ|NR#gi3v<(60?v^AJ&GW i+l8&0>&^ObYFtuIC+Gpxs*A((`E@KK=o#Msw}} literal 0 HcmV?d00001 diff --git a/static/evaluate/addPic.png b/static/evaluate/addPic.png new file mode 100644 index 0000000000000000000000000000000000000000..4c9180b2d3c6c34250b730102ec399006f6cdd54 GIT binary patch literal 2761 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 literal 0 HcmV?d00001 diff --git a/static/home/address.png b/static/home/address.png new file mode 100644 index 0000000000000000000000000000000000000000..ec3c3d103dc522e515b42acb646961ace914336f GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1Iglb$Y)Ar^v5 zCtc({tia>)S=2On%Ky67RHFd#Q!N)mV^Ze&HVAPtZmhf`sqg(b`trYgTe~DWM4fvFdAj literal 0 HcmV?d00001 diff --git a/static/home/address.svg b/static/home/address.svg new file mode 100644 index 0000000..2642e65 --- /dev/null +++ b/static/home/address.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/home/appointment.png b/static/home/appointment.png new file mode 100644 index 0000000000000000000000000000000000000000..92934c531b758d9b7df7e0c1282b69bf5fb2db3d GIT binary patch literal 339 zcmV-Z0j&OsP)Px$4M{{nR7ef&S4$3qAP{B2!8`;DN}FVa60cO;lv2WX);5(R762yFUN`;&UncuqrPifBAta|Na*Wk6yc)Qo z!JfUiUKP6obB^(_aCN-j7P$1vV(z{cMbyR4Kcj#GA0hIxJI lbKoIb&UogDO|_x}zz^Wp-5rgsf%pIb002ovPDHLkV1hv@ly(3B literal 0 HcmV?d00001 diff --git a/static/home/area.png b/static/home/area.png new file mode 100644 index 0000000000000000000000000000000000000000..46981af1aa4702c2db847dd38c33287530705119 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa#^NA%Cx&(BWL^R}wVp1HAr^wk z2@OnqqQdNau8;r9cpdw1ImJiHK|+mv@x-eJ4kC>rj}Hkr3$!_1F-*t^FuBLSi806O zM%o*;M^`wCrS8BSWZJx}l@QMawv| p;fLT7#w;tZu12-84QwW+4Bh&>8+*1-djxa{gQu&X%Q~loCID1UJemLi literal 0 HcmV?d00001 diff --git a/static/home/bus.png b/static/home/bus.png new file mode 100644 index 0000000000000000000000000000000000000000..9b5876cf3d2e22ed1aae00147ec3aaa60b6360fc GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+k!3HE-=Cy!0jKx9jP7LeL$-D$|R(ZNOhFAz* z4L-=*puqEnNhPx$5lKWrR7efAmH`gLAP59~nosM``ZO-`-Efu29nGphF-~h}D;=wh2_TioRI@-f96*`Arf)(hrQa;tE>Q0T%0KFNV zQQV=M(V+(^D^YGnS5!L$=M?O>o}QH8gS7`Yqe(s1U;(kO2RNJ_0T_ZRKqfjH6%KN5 zRvLrN|4|^T_E<_;pr+*;t*$d;d53i48jr6YRn9&xZGj?)SWB^^i2h%W2+cgBe?837 zblS3lN{ys->UFU=eitu8dvyBpF)q~YZjI3?)LC(?h&k*MbPfAJy$6DgxE&7alNxJ^ pz2F$kDym@ZH!A>hT-c-1_X8fkjs6<8JMaJi002ovPDHLkV1jbRk;MQ2 literal 0 HcmV?d00001 diff --git a/static/home/region.png b/static/home/region.png new file mode 100644 index 0000000000000000000000000000000000000000..ef716584df222992cc6bf7bd3048cbf7b97632c1 GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa#^NA%Cx&(BWL^R}C7v#hAr^wk z2@OnUs>!i@u9L(3R44n+@lu}e$q9G_C+8?mLVY0*|Mh#7FEjdm<1_fS&%M*in gbT&4NEMCpXP!Tajw<5ZJ4bXlDPgg&ebxsLQ0LYXzwg3PC literal 0 HcmV?d00001 diff --git a/static/home/right.png b/static/home/right.png new file mode 100644 index 0000000000000000000000000000000000000000..28d8bd327e86ceecef91cb5e0e7f0873a0404594 GIT binary patch literal 341 zcmV-b0jmCqP)Px$4@pEpR7efAl?xJuAP7ZWnoDbEEsZyqz(-jIn9Ml-IY3~gIE08Q5p6`YOCu4T zW3M_?jgJTjN+Yt3wchL|LDncgRABb<%y=B;k6~))GgMD3=zFMS;Q|(`+)t^p7^Y7A zz0{SL9_4|0%gW(pAW`^2;QXCowM4A8-yw3(kT(F+FG&KrXMixcy(AK1uh9%N9*2g2 zw9NB*3lFoB271F`4VwyS6c`Spv6R1Iq?j!%YACo|7WkWc#1?)A2F78qvlan~M5A+} zJsgwIRj2r2p(PrFonAiZdR;!lKwRl%3*~jN2--6H%H#RR&@s$fFqx6aXg^HB31|+a nKWs6i-1Q_(s0Tps-ZkOPf=3@7^t00000NkvXXu0mjf!ZM1M literal 0 HcmV?d00001 diff --git a/static/home/shichang_logo.png b/static/home/shichang_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d8122f93145f273ca07d880975e1e784bc3e622e GIT binary patch literal 40224 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 + + + diff --git a/static/home/siteicon2.svg b/static/home/siteicon2.svg new file mode 100644 index 0000000..cbf925a --- /dev/null +++ b/static/home/siteicon2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/iconfont/iconfont.css b/static/iconfont/iconfont.css new file mode 100644 index 0000000..df47b7f --- /dev/null +++ b/static/iconfont/iconfont.css @@ -0,0 +1,190 @@ +@font-face { + font-family: "custom-icon"; /* Project id 4659338 */ + src: + url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'); +} + +.custom-icon { + font-family: "custom-icon" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.custom-icon-next-btn:before { + content: "\e62a"; +} + +.custom-icon-pre-btn:before { + content: "\e62b"; +} + +.custom-icon-wrapper:before { + content: "\e622"; +} + +.custom-icon-material:before { + content: "\e623"; +} + +.custom-icon-ecGoods:before { + content: "\e624"; +} + +.custom-icon-officeComputer:before { + content: "\e625"; +} + +.custom-icon-brush:before { + content: "\e626"; +} + +.custom-icon-documentFile:before { + content: "\e627"; +} + +.custom-icon-flag:before { + content: "\e628"; +} + +.custom-icon-box:before { + content: "\e629"; +} + +.custom-icon-info:before { + content: "\e620"; +} + +.custom-icon-share1:before { + content: "\e621"; +} + +.custom-icon-bottle:before { + content: "\e61b"; +} + +.custom-icon-uploadImage1:before { + content: "\e61c"; +} + +.custom-icon-uploadImage:before { + content: "\e61d"; +} + +.custom-icon-bus:before { + content: "\e61e"; +} + +.custom-icon-map1:before { + content: "\e61f"; +} + +.custom-icon-landmark:before { + content: "\e61a"; +} + +.custom-icon-halfArrow:before { + content: "\e619"; +} + +.custom-icon-identify:before { + content: "\e618"; +} + +.custom-icon-invoice:before { + content: "\e615"; +} + +.custom-icon-present:before { + content: "\e617"; +} + +.custom-icon-customer:before { + content: "\e614"; +} + +.custom-icon-guide:before { + content: "\e612"; +} + +.custom-icon-coupon1:before { + content: "\e613"; +} + +.custom-icon-order1:before { + content: "\e611"; +} + +.custom-icon-invite:before { + content: "\e616"; +} + +.custom-icon-setting1:before { + content: "\e60a"; +} + +.custom-icon-home1:before { + content: "\e60b"; +} + +.custom-icon-unlock:before { + content: "\e60e"; +} + +.custom-icon-personal:before { + content: "\e610"; +} + +.custom-icon-washer:before { + content: "\e601"; +} + +.custom-icon-book:before { + content: "\e608"; +} + +.custom-icon-safety:before { + content: "\e606"; +} + +.custom-icon-truck:before { + content: "\e602"; +} + +.custom-icon-robot:before { + content: "\e60f"; +} + +.custom-icon-telephone:before { + content: "\e600"; +} + +.custom-icon-clothes:before { + content: "\e603"; +} + +.custom-icon-airplane:before { + content: "\e604"; +} + +.custom-icon-file:before { + content: "\e605"; +} + +.custom-icon-arm:before { + content: "\e607"; +} + +.custom-icon-flower:before { + content: "\e609"; +} + +.custom-icon-dropdown:before { + content: "\e60d"; +} + +.custom-icon-user1:before { + content: "\e60c"; +} + diff --git a/static/orderdetail/refresh.png b/static/orderdetail/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..d9d370ee81d2d2ad78ff6e21f801656e7c905be5 GIT binary patch literal 540 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

E-9sm$@F_A+NvbTZOaX&3HeyQ`F71#9sL24xoEv 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 P0}yz+`njxgN@xNAOYid4 literal 0 HcmV?d00001 diff --git a/static/personal/warning.png b/static/personal/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..afca7306beaa775e62e19693d605672686769354 GIT binary patch literal 283 zcmV+$0p$LPP)Px#)k#D_R5%f>RLc#+APhyqOwPx$2}wjjR7efAmRSzNAPhu(v>uH+Rq1b!mS_-zY+}}sN~sk*JTEMY$i(j}@;OAp z#FV}iz(eHxiTwNOK?R{(!5X>^Ttat(Pr&r^xW{P+7$^gHO9MR~&u7NGHq^kVBKi7T zQHgI^>&$clLv3Pqo+Us-q2stIJ@qt~;sH5EKnaH5Kq=q^I09+{C h>ODTMc(I3(3@`EksbA;82+9Be002ovPDHLkV1huKk+lE- literal 0 HcmV?d00001 diff --git a/static/setOrder/selectArrow.png b/static/setOrder/selectArrow.png new file mode 100644 index 0000000000000000000000000000000000000000..8364e92c4ac20af3a569abd67a7306bec1332e70 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^azHG^!3HFKKIPp6QjEnx?oJHr&dIz4au#^HIEHxe z9-ZdRbwGi~rC7qet9tX7jC*GmZ;j}fy6s=Ds7hoyNH}dmYF* dzr*kaXMp9iz0ItT=L6l!;OXk;vd$@?2>^1;RvrKV literal 0 HcmV?d00001 diff --git a/static/site/hot.svg b/static/site/hot.svg new file mode 100644 index 0000000..c14c265 --- /dev/null +++ b/static/site/hot.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/static/site/map.svg b/static/site/map.svg new file mode 100644 index 0000000..45243b0 --- /dev/null +++ b/static/site/map.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/style/theme.scss b/static/style/theme.scss new file mode 100644 index 0000000..c9ddc44 --- /dev/null +++ b/static/style/theme.scss @@ -0,0 +1,156 @@ +@import "@/uni.scss"; + +// 旧版 +:root, +.default-theme { + --main-color: #00C8D5; + --bg-color: #00CCD8; + --bg-color2: #0B7FB4; + --bg-color3: #049EBB; + --bg-popup: #049EBB; + --left-linear: #00B0BC; + --left-linear2: #00B0BC; + --right-linear: #0A7EB7; + --btn-color1: #0A85B7; + --btn-color2: #47A4B6; + --btn-color3: #0A84B8; + --btn-color4: #049CBB; + --btn-color5: #0790B9; + --stress-color: #FFFFFF; + --stress-color2: #049EBB; + --active-color: #00A7BE; + --text-color: #FFFFFF; + --stress-text: #045459; + --rgb-color: 0, 84, 118; + --blackOrWhite:#000000; //默认是黑 金刚是白 + --whiteOrBlack:#FFFFFF; //默认是白 金刚是黑 +} + +// 英文语言类 +// .en_lang { +// @for $i from 10 through 36 { +// --f#{$i}: #{$i}rpx; +// } +// } +// // 中文比英文大两号 +// // 中文语言类,使用前缀并调整值 +// .zh_lang { +// @for $i from 10 through 36 { +// --f#{$i}: #{($i + 2)}rpx; // 添加了前缀并增加了2rpx +// } +// } + + +.golden-theme { + --main-color: #FEBD00; + --bg-color: #0F2232; + --bg-color2: #0F2232; + --bg-color3: #0F2232; + --bg-popup: #FFCC37; + --left-linear: #FEBD00; + --left-linear2: #FFA600; + --right-linear: #FEBD00; + --btn-color1: #FEBD00; + --btn-color2: #DEB150; + --btn-color3: #FEBD00; + --btn-color4: #FFBE00; + --btn-color5: #FFBE00; + --stress-color: #FEBD00; + --stress-color2: #FEB200; + --active-color: #FEBD00; + --text-color: #0F2232; + --stress-text: #0F2232; + --rgb-color: 246, 189, 66; + --blackOrWhite:#FFFFFF; + --whiteOrBlack:#000000; +} + +* { + font-family: + "PingFang SC", + "Microsoft YaHei", + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Helvetica, + Arial, + sans-serif; +} + +.location-popup { + display: flex; + align-items: start; + justify-content: center; + height: 100%; + + & > .select-area-wrap { + display: flex; + position: fixed; + width: 750rpx; + margin-top: 128rpx; + padding: 40rpx 0; + background-color: var(--bg-popup); + + .inner-wrap { + width: 50%; + display: flex; + flex-direction: column; + justify-content: flex-start; + overflow: hidden; + overflow-y: scroll; + padding-left: 40px; + } + + .top-wrap { + display: flex; + margin-bottom: 20rpx; + + .text { + font-weight: bold; + margin-left: 16rpx; + } + } + + .select-wrap { + max-height: calc(100vh - 400rpx); + overflow: auto; + + .select-item { + display: flex; + align-items: center; + margin-bottom: 20rpx; + + .circle { + min-width: 40rpx; + min-height: 40rpx; + width: 40rpx; + height: 40rpx; + margin-right: 30rpx; + background: #FFFFFF; + border-radius: 50%; + border: 2px solid #000000; + } + + .name { + font-weight: bold; + } + + &.select { + .circle { + background: var(--main-color); + } + } + } + } + + .border { + position: absolute; + top: 40rpx; + left: 50%; + width: 2px; + height: calc(100% - 80rpx); + background: #000000; + } + } +} \ No newline at end of file diff --git a/static/tabbar/book.png b/static/tabbar/book.png new file mode 100644 index 0000000000000000000000000000000000000000..2e7b235f26ded658b3b4ba4ea07f7fa241de0b49 GIT binary patch literal 396 zcmV;70dxL|P)Px$MoC0LR7eeDV88+X|Nrms|NsB}|EU8Sa9G2@KppcDrr@)v;s5{tlw!C|I4z=v z1l$&&i^1kW?X5+GmVuR5Q7=aeeyZ7vW-q~ANapvip|F3`i ziXKW>`FMkF`NNn08J6$Ei-p!6!fG(OAYO~MKYNSU5|ATgHXcPc6DuFDMIasfUcUc7 z@#bTk_{;A$D*`TH~#ajIrLv|`zgGbclE*lDJQSv^e|o@_1}0z zFfpK~%AV_wuv&)KB2XSdH;54b%7-tcTLjYa?a$x;7vFy-3V;3c7po;8LA*Y~sf!E= zEEY9Ty~@VoBS?FJ3DuP{m5pcu&LNc q#BB-4MhaV`pq4BMJD|883kLv<6tOVNQ94@y0000400001b5ch_0Itp) z=>Px%;z>k7RA>d|nG3RmAPhxaT9?+Hb!of_5*q^K2ij-LOvfLRdvYUwx@`+uO6ieO zdXnEOr9^*8X|yk{!+0=m{w|bG-c{&WE0PFf*qttbv(9CpHhuD*ay`yM>%a>jpE8R5=mO}zmQqGhC;NjIt|A)C7BY@M z*eA}algWQosht>X2pAZ1SaOr@?i$M=5huHl1rVHyHVHU1Zgw>YDnUj8`FUO7K&8OA z&n<9mHju$&aj?;LbIS<8z5vwIqLAPYPDaOLUD*f6wAPF3Dq|05J%eotjULddgd)NSS9i4}PI9<{H6;2l0YIgJv7;wI<9wG&*r{mZS}Y};uTixl z*Q5xkoag6Sx1|_-40J*}t{DqguJs)V4}nWdtO!;bP& z^&4HQRVS&OAPF;2qjN{?9}^^&{{Hds}tN!NirCzea@sZlqH?lJ77n-~Kok15y%kf5axI$0_R zNtbTe6Ew82i?T>TVcqQRqH5yt>xt=vO!9yLoS{oB_gfF$P}`UKPKNHbD}(;RHM&2g z-OZkW-UIZTC#3fSL-0*Lkl2r$Qome$>4U@jITt@$6jxzlf`{*KXnjZqeCKOc2c)pf mVSLT{k4}TO{L07m)9pWd0xf*4SBpLX0000 \ No newline at end of file diff --git a/static/tabbar/index.png b/static/tabbar/index.png new file mode 100644 index 0000000000000000000000000000000000000000..5102e44b11870ff8552e1c175f48b3377d2072f2 GIT binary patch literal 265 zcmV+k0rvihP)Px#!%0LzR7ef&mRk;mAPhuV8cTC$ENu*GiS@Q+uA*O%7?4L#I}l1rWC4%?6zH;$ z%eiR)7Hwbsje!|aD9Z6uIG2rCj#L)p+?Negepg4Tvtg^vN%;^W;21{khZyVCzx#G` zKYAb;-=jMq()m`M(_pzgM@t2LQYPrO%u~84T~pwn!%)+B&9v9A8H*Y$$i4R2yOIL= zDRLi)B9XCALDwggIMM0>5pB13^px6Q13)eLg;6~O>69KkO577C4lrw1CGCAY1)S`B P00000NkvXXu0mjfGVEv5 literal 0 HcmV?d00001 diff --git a/static/tabbar/order.svg b/static/tabbar/order.svg new file mode 100644 index 0000000..a1c9e0e --- /dev/null +++ b/static/tabbar/order.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/tabbar/unlock.png b/static/tabbar/unlock.png new file mode 100644 index 0000000000000000000000000000000000000000..5fc0f313cd3927c9da820a8a86fc40427d63b6cd GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^Vn8gz!3HE#_5EXk6k~CayA#8@b22Z1oCTgPjv*er zZ^In94k++^&a^u_|L2yTzNnF%Rj#pVoo|Ac?UkF|$6=Xl8)i?A8YW)`u5ksE(au59i;{z-U~ dQA@@yhGVmN<$aS6UI)6B!PC{xWt~$(697bAR;&O3 literal 0 HcmV?d00001 diff --git a/static/tabbar/user.svg b/static/tabbar/user.svg new file mode 100644 index 0000000..8feebc2 --- /dev/null +++ b/static/tabbar/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/store/index.js b/store/index.js new file mode 100644 index 0000000..6b4932d --- /dev/null +++ b/store/index.js @@ -0,0 +1,80 @@ +import { defineStore } from "pinia"; +import { ref } from "vue"; +import { theme } from "@/config/index"; +import { useLoginApi } from "@/Apis/login"; +import { authInfoApi } from "@/Apis/validInfo.js"; +const getApi = useLoginApi(); +const getAuthApi = authInfoApi(); +export const useMainStore = defineStore('main', () => { + const storeState = ref({ + token:'', + userInfo:{}, //userType应该是管理员。2是管理员,3是开门管理员 + location: {}, + hasVerify:false, // 是否已经验证过 + hasTrytoLogin:false, // 是否尝试过登录 + }) + function setToken(token) { + storeState.value.token = token + } + const setHasVerify = (hasVerify) => { + storeState.value.hasVerify = hasVerify; + } + const getHasVerify = async () => { + if (!storeState.value.hasVerify) { + // 判断是否认证 + let { code, data } = + await getAuthApi.GetIsCertification(); + if (code == 200 && data?.isPass) { + setHasVerify(data?.isPass); + return data; + } + } + return storeState.value.hasVerify; + } + const themeInfo = ref({}); + function setTheme() { + const language = uni.getStorageSync("eliteSys-language-wx") || "zh-Hans"; + const themeList = [ + { theme: "default", iconColor: "#FFFFFF", activeColor: "#00A7BE" }, + { theme: "golden", iconColor: "#0F2232", activeColor: "#F6BD42" }, + ]; + let item = themeList.find(item => item.theme == theme); + item.language = language === "en" ? "en_lang" : "zh_lang"; + themeInfo.value = item; + } + // 获取用户信息 + const getUserInfo = ()=>{ + return getApi.GetUserInfo().then(res=>{ + if(res.code == 200){ + storeState.value.userInfo = res.data ?? {} + uni.setStorage({ + key:'userInfo', + data:res.data + }) + + }else{ + storeState.value.userInfo = {} + logOut() + } + return res + }).catch((err=>{ + storeState.value.userInfo = {} + logOut() + return err + })) + } + // 退出登陆 + const logOut = ()=>{ + storeState.value.token = '' + storeState.value.userInfo = {} + uni.removeStorage({ + key:'token' + }); // 清除缓存 + } + + const setLocation = (location) => { + storeState.value.location = location; + } + + return { storeState, setToken, themeInfo, setTheme, getUserInfo, logOut, setLocation,getHasVerify }; +}); \ No newline at end of file diff --git a/uni.scss b/uni.scss new file mode 100644 index 0000000..aa2e7f3 --- /dev/null +++ b/uni.scss @@ -0,0 +1,116 @@ +@import '@/uni_modules/uni-scss/variables.scss'; + +$sfRedColor: #FB322E; +$sfblackColor: #0D1118; +$sfgrayBgColor: #F1F2F7; +$padding20: 20rpx; +$padding32: 32rpx; + + +$backgroundColor: + radial-gradient(circle at 120% -5%, + #EFE4ED 0%, + transparent 60% + ), + radial-gradient(circle at -20% 40%, + #EFE4ED 0%, + transparent 60% + ), + linear-gradient(180deg, #E0EAF6 0%, #F0F5FB 100%); + +.p20 { padding: $padding20; } +.p20-r { padding-right: $padding20; } +.p20-l { padding-left: $padding20; } +.p20-t { padding-top: $padding20; } +.p20-b { padding-bottom: $padding20; } + +.p32 { padding: $padding32; } +.p32-r { padding-right: $padding32; } +.p32-l { padding-left: $padding32; } +.p32-t { padding-top: $padding32; } +.p32-b { padding-bottom: $padding32; } + +.m20 { margin: $padding20; } +.m20-r { margin-right: $padding20; } +.m20-l { margin-left: $padding20; } +.m20-t { margin-top: $padding20; } +.m20-b { margin-bottom: $padding20; } + +.m32 { margin: $padding32; } +.m32-r { margin-right: $padding32; } +.m32-l { margin-left: $padding32; } +.m32-t { margin-top: $padding32; } +.m32-b { margin-bottom: $padding32; } +.border-radius-20 { border-radius: 20rpx; } +.card { + background-color: #fff; + border-radius: 16rpx; + padding: 36rpx; + line-height: normal; + margin-bottom: $padding20; + width: 100%; +} +.container{ + padding: $padding20; + width: 100%; + padding-bottom: 200rpx; +} +:deep(.uv-icon__icon){ + line-height: normal!important; +} +:deep(.uv-button--info){ + border-color: #A8AAAC; +} + +.font36{ + font-size: 36rpx; +} +.font32{ + font-size: 32rpx; +} +.font28{ + font-size: 26rpx +} +.font26{ + font-size: 26rpx +} +.font16{ + font-size: 16rpx +} +.fontb{ + font-weight: 600; +} + +.textGary{ + color: #A8AAAC; +} +.textRed{ + color: $sfRedColor; +} +.mgb20{ + margin-bottom: 20rpx; +} +.mgb10{ + margin-bottom: 10rpx; +} + +/* 行为相关颜色 */ +$uni-color-primary: #007aff; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; +/* 背景颜色 */ +$uni-bg-color:#ffffff; +$uni-bg-color-grey:#f8f8f8; +$uni-bg-color-hover:#f1f1f1;//点击状态颜色 +$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 + +/* 水平间距 */ +$uni-spacing-row-sm: 5px; +$uni-spacing-row-base: 10px; +$uni-spacing-row-lg: 15px; + +/* 垂直间距 */ +$uni-spacing-col-sm: 4px; +$uni-spacing-col-base: 8px; +$uni-spacing-col-lg: 12px; diff --git a/uni_modules/no-data/changelog.md b/uni_modules/no-data/changelog.md new file mode 100644 index 0000000..e69de29 diff --git a/uni_modules/no-data/components/no-data/i18n/en.json b/uni_modules/no-data/components/no-data/i18n/en.json new file mode 100644 index 0000000..249bc85 --- /dev/null +++ b/uni_modules/no-data/components/no-data/i18n/en.json @@ -0,0 +1,3 @@ +{ + "no-data.title": "No Data" +} diff --git a/uni_modules/no-data/components/no-data/i18n/index.js b/uni_modules/no-data/components/no-data/i18n/index.js new file mode 100644 index 0000000..f5000b1 --- /dev/null +++ b/uni_modules/no-data/components/no-data/i18n/index.js @@ -0,0 +1,10 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +import ja from './ja.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant, + ja +} diff --git a/uni_modules/no-data/components/no-data/i18n/ja.json b/uni_modules/no-data/components/no-data/i18n/ja.json new file mode 100644 index 0000000..fca47b6 --- /dev/null +++ b/uni_modules/no-data/components/no-data/i18n/ja.json @@ -0,0 +1,3 @@ +{ + "no-data.title": "データなし" +} diff --git a/uni_modules/no-data/components/no-data/i18n/zh-Hans.json b/uni_modules/no-data/components/no-data/i18n/zh-Hans.json new file mode 100644 index 0000000..dd3b343 --- /dev/null +++ b/uni_modules/no-data/components/no-data/i18n/zh-Hans.json @@ -0,0 +1,3 @@ +{ + "no-data.title": "无数据" +} diff --git a/uni_modules/no-data/components/no-data/i18n/zh-Hant.json b/uni_modules/no-data/components/no-data/i18n/zh-Hant.json new file mode 100644 index 0000000..eb758cd --- /dev/null +++ b/uni_modules/no-data/components/no-data/i18n/zh-Hant.json @@ -0,0 +1,3 @@ +{ + "no-data.title": "無數據" +} diff --git a/uni_modules/no-data/components/no-data/no-data.vue b/uni_modules/no-data/components/no-data/no-data.vue new file mode 100644 index 0000000..8e16bfe --- /dev/null +++ b/uni_modules/no-data/components/no-data/no-data.vue @@ -0,0 +1,44 @@ + + + + diff --git a/uni_modules/no-data/package.json b/uni_modules/no-data/package.json new file mode 100644 index 0000000..284d2ef --- /dev/null +++ b/uni_modules/no-data/package.json @@ -0,0 +1,80 @@ +{ + "id": "no-data", + "displayName": "no-data", + "version": "1.0.0", + "description": "no-data", + "keywords": [ + "no-data" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "", + "data": "", + "permissions": "" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "u", + "aliyun": "u" + }, + "client": { + "Vue": { + "vue2": "u", + "vue3": "u" + }, + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/no-data/readme.md b/uni_modules/no-data/readme.md new file mode 100644 index 0000000..f6364f2 --- /dev/null +++ b/uni_modules/no-data/readme.md @@ -0,0 +1 @@ +# no-data \ No newline at end of file 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 @@ + + + + + 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-breadcrumb/changelog.md b/uni_modules/uni-breadcrumb/changelog.md new file mode 100644 index 0000000..209e5c5 --- /dev/null +++ b/uni_modules/uni-breadcrumb/changelog.md @@ -0,0 +1,6 @@ +## 0.1.2(2022-06-08) +- 修复 微信小程序 separator 不显示的Bug +## 0.1.1(2022-06-02) +- 新增 支持 uni.scss 修改颜色 +## 0.1.0(2022-04-21) +- 初始化 diff --git a/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue b/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue new file mode 100644 index 0000000..b9edbd6 --- /dev/null +++ b/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue @@ -0,0 +1,121 @@ + + + diff --git a/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue b/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue new file mode 100644 index 0000000..94493a2 --- /dev/null +++ b/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue @@ -0,0 +1,41 @@ + + + diff --git a/uni_modules/uni-breadcrumb/package.json b/uni_modules/uni-breadcrumb/package.json new file mode 100644 index 0000000..0a04e50 --- /dev/null +++ b/uni_modules/uni-breadcrumb/package.json @@ -0,0 +1,88 @@ +{ + "id": "uni-breadcrumb", + "displayName": "uni-breadcrumb 面包屑", + "version": "0.1.2", + "description": "Breadcrumb 面包屑", + "keywords": [ + "uni-breadcrumb", + "breadcrumb", + "uni-ui", + "面包屑导航", + "面包屑" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "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" + } + } + } + } +} diff --git a/uni_modules/uni-breadcrumb/readme.md b/uni_modules/uni-breadcrumb/readme.md new file mode 100644 index 0000000..6976b8d --- /dev/null +++ b/uni_modules/uni-breadcrumb/readme.md @@ -0,0 +1,66 @@ + +## breadcrumb 面包屑导航 +> **组件名:uni-breadcrumb** +> 代码块: `ubreadcrumb` + +显示当前页面的路径,快速返回之前的任意页面。 + +### 安装方式 + +本组件符合[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 + + {{route.name}} + +``` + +```js +export default { + name: "uni-stat-breadcrumb", + data() { + return { + routes: [{ + to: '/A', + name: 'A页面' + }, { + to: '/B', + name: 'B页面' + }, { + to: '/C', + name: 'C页面' + }] + }; + } + } +``` + + +## API + +### Breadcrumb Props + +|属性名 |类型 |默认值 |说明 | +|:-: |:-: |:-: |:-: | +|separator |String |斜杠'/' |分隔符 | +|separatorClass |String | |图标分隔符 class | + +### Breadcrumb Item Props + +|属性名 |类型 |默认值 |说明 | +|:-: |:-: |:-: |:-: | +|to |String | |路由跳转页面路径 | +|replace|Boolean | |在使用 to 进行路由跳转时,启用 replace 将不会向 history 添加新记录(仅 h5 支持) | + + + + +## 组件示例 + +点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/breadcrumb/breadcrumb](https://hellouniapp.dcloud.net.cn/pages/extUI/breadcrumb/breadcrumb) \ No newline at end of file diff --git a/uni_modules/uni-calendar/changelog.md b/uni_modules/uni-calendar/changelog.md new file mode 100644 index 0000000..f291eec --- /dev/null +++ b/uni_modules/uni-calendar/changelog.md @@ -0,0 +1,26 @@ +## 1.4.10(2023-04-10) +- 修复 某些情况 monthSwitch 未触发的Bug +## 1.4.9(2023-02-02) +- 修复 某些情况切换月份错误的Bug +## 1.4.8(2023-01-30) +- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/161964) +## 1.4.7(2022-09-16) +- 优化 支持使用 uni-scss 控制主题色 +## 1.4.6(2022-09-08) +- 修复 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件的Bug +## 1.4.5(2022-02-25) +- 修复 条件编译 nvue 不支持的 css 样式的Bug +## 1.4.4(2022-02-25) +- 修复 条件编译 nvue 不支持的 css 样式的Bug +## 1.4.3(2021-09-22) +- 修复 startDate、 endDate 属性失效的Bug +## 1.4.2(2021-08-24) +- 新增 支持国际化 +## 1.4.1(2021-08-05) +- 修复 弹出层被 tabbar 遮盖的Bug +## 1.4.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.3.16(2021-05-12) +- 新增 组件示例地址 +## 1.3.15(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-calendar/components/uni-calendar/calendar.js b/uni_modules/uni-calendar/components/uni-calendar/calendar.js new file mode 100644 index 0000000..b8d7d6f --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/calendar.js @@ -0,0 +1,546 @@ +/** +* @1900-2100区间内的公历、农历互转 +* @charset UTF-8 +* @github https://github.com/jjonline/calendar.js +* @Author Jea杨(JJonline@JJonline.Cn) +* @Time 2014-7-21 +* @Time 2016-8-13 Fixed 2033hex、Attribution Annals +* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug +* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year +* @Version 1.0.3 +* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] +* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] +*/ +/* eslint-disable */ +var calendar = { + + /** + * 农历1900-2100的润大小信息表 + * @Array Of Property + * @return Hex + */ + lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909 + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919 + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929 + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939 + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949 + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959 + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969 + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979 + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989 + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999 + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009 + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019 + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049 + /** Add By JJonline@JJonline.Cn**/ + 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059 + 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069 + 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079 + 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089 + 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099 + 0x0d520], // 2100 + + /** + * 公历每个月份的天数普通表 + * @Array Of Property + * @return Number + */ + solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + + /** + * 天干地支之天干速查表 + * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] + * @return Cn string + */ + Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], + + /** + * 天干地支之地支速查表 + * @Array Of Property + * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] + * @return Cn string + */ + Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], + + /** + * 天干地支之地支速查表<=>生肖 + * @Array Of Property + * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] + * @return Cn string + */ + Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], + + /** + * 24节气速查表 + * @Array Of Property + * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] + * @return Cn string + */ + solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], + + /** + * 1900-2100各年的24节气日期速查表 + * @Array Of Property + * @return 0x string For splice + */ + sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', + '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', + 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', + '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', + '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', + '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', + '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', + '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', + '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', + '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', + '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', + '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], + + /** + * 数字转中文速查表 + * @Array Of Property + * @trans ['日','一','二','三','四','五','六','七','八','九','十'] + * @return Cn string + */ + nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], + + /** + * 日期转农历称呼速查表 + * @Array Of Property + * @trans ['初','十','廿','卅'] + * @return Cn string + */ + nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], + + /** + * 月份转农历称呼速查表 + * @Array Of Property + * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] + * @return Cn string + */ + nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], + + /** + * 返回农历y年一整年的总天数 + * @param lunar Year + * @return Number + * @eg:var count = calendar.lYearDays(1987) ;//count=387 + */ + lYearDays: function (y) { + var i; var sum = 348 + for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } + return (sum + this.leapDays(y)) + }, + + /** + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 + * @param lunar Year + * @return Number (0-12) + * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 + */ + leapMonth: function (y) { // 闰字编码 \u95f0 + return (this.lunarInfo[y - 1900] & 0xf) + }, + + /** + * 返回农历y年闰月的天数 若该年没有闰月则返回0 + * @param lunar Year + * @return Number (0、29、30) + * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 + */ + leapDays: function (y) { + if (this.leapMonth(y)) { + return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) + } + return (0) + }, + + /** + * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 + * @param lunar Year + * @return Number (-1、29、30) + * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 + */ + monthDays: function (y, m) { + if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1 + return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) + }, + + /** + * 返回公历(!)y年m月的天数 + * @param solar Year + * @return Number (-1、28、29、30、31) + * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 + */ + solarDays: function (y, m) { + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var ms = m - 1 + if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29 + return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) + } else { + return (this.solarMonth[ms]) + } + }, + + /** + * 农历年份转换为干支纪年 + * @param lYear 农历年的年份数 + * @return Cn string + */ + toGanZhiYear: function (lYear) { + var ganKey = (lYear - 3) % 10 + var zhiKey = (lYear - 3) % 12 + if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干 + if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支 + return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] + }, + + /** + * 公历月、日判断所属星座 + * @param cMonth [description] + * @param cDay [description] + * @return Cn string + */ + toAstro: function (cMonth, cDay) { + var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' + var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] + return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座 + }, + + /** + * 传入offset偏移量返回干支 + * @param offset 相对甲子的偏移量 + * @return Cn string + */ + toGanZhi: function (offset) { + return this.Gan[offset % 10] + this.Zhi[offset % 12] + }, + + /** + * 传入公历(!)y年获得该年第n个节气的公历日期 + * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 + * @return day Number + * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 + */ + getTerm: function (y, n) { + if (y < 1900 || y > 2100) { return -1 } + if (n < 1 || n > 24) { return -1 } + var _table = this.sTermInfo[y - 1900] + var _info = [ + parseInt('0x' + _table.substr(0, 5)).toString(), + parseInt('0x' + _table.substr(5, 5)).toString(), + parseInt('0x' + _table.substr(10, 5)).toString(), + parseInt('0x' + _table.substr(15, 5)).toString(), + parseInt('0x' + _table.substr(20, 5)).toString(), + parseInt('0x' + _table.substr(25, 5)).toString() + ] + var _calday = [ + _info[0].substr(0, 1), + _info[0].substr(1, 2), + _info[0].substr(3, 1), + _info[0].substr(4, 2), + + _info[1].substr(0, 1), + _info[1].substr(1, 2), + _info[1].substr(3, 1), + _info[1].substr(4, 2), + + _info[2].substr(0, 1), + _info[2].substr(1, 2), + _info[2].substr(3, 1), + _info[2].substr(4, 2), + + _info[3].substr(0, 1), + _info[3].substr(1, 2), + _info[3].substr(3, 1), + _info[3].substr(4, 2), + + _info[4].substr(0, 1), + _info[4].substr(1, 2), + _info[4].substr(3, 1), + _info[4].substr(4, 2), + + _info[5].substr(0, 1), + _info[5].substr(1, 2), + _info[5].substr(3, 1), + _info[5].substr(4, 2) + ] + return parseInt(_calday[n - 1]) + }, + + /** + * 传入农历数字月份返回汉语通俗表示法 + * @param lunar month + * @return Cn string + * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' + */ + toChinaMonth: function (m) { // 月 => \u6708 + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var s = this.nStr3[m - 1] + s += '\u6708'// 加上月字 + return s + }, + + /** + * 传入农历日期数字返回汉字表示法 + * @param lunar day + * @return Cn string + * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' + */ + toChinaDay: function (d) { // 日 => \u65e5 + var s + switch (d) { + case 10: + s = '\u521d\u5341'; break + case 20: + s = '\u4e8c\u5341'; break + break + case 30: + s = '\u4e09\u5341'; break + break + default : + s = this.nStr2[Math.floor(d / 10)] + s += this.nStr1[d % 10] + } + return (s) + }, + + /** + * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” + * @param y year + * @return Cn string + * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' + */ + getAnimal: function (y) { + return this.Animals[(y - 4) % 12] + }, + + /** + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON + * @param y solar year + * @param m solar month + * @param d solar day + * @return JSON object + * @eg:console.log(calendar.solar2lunar(1987,11,01)); + */ + solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31 + // 年份限定、上限 + if (y < 1900 || y > 2100) { + return -1// undefined转换为数字变为NaN + } + // 公历传参最下限 + if (y == 1900 && m == 1 && d < 31) { + return -1 + } + // 未传参 获得当天 + if (!y) { + var objDate = new Date() + } else { + var objDate = new Date(y, parseInt(m) - 1, d) + } + var i; var leap = 0; var temp = 0 + // 修正ymd参数 + var y = objDate.getFullYear() + var m = objDate.getMonth() + 1 + var d = objDate.getDate() + var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 + for (i = 1900; i < 2101 && offset > 0; i++) { + temp = this.lYearDays(i) + offset -= temp + } + if (offset < 0) { + offset += temp; i-- + } + + // 是否今天 + var isTodayObj = new Date() + var isToday = false + if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { + isToday = true + } + // 星期几 + var nWeek = objDate.getDay() + var cWeek = this.nStr1[nWeek] + // 数字表示周几顺应天朝周一开始的惯例 + if (nWeek == 0) { + nWeek = 7 + } + // 农历年 + var year = i + var leap = this.leapMonth(i) // 闰哪个月 + var isLeap = false + + // 效验闰月 + for (i = 1; i < 13 && offset > 0; i++) { + // 闰月 + if (leap > 0 && i == (leap + 1) && isLeap == false) { + --i + isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数 + } else { + temp = this.monthDays(year, i)// 计算农历普通月天数 + } + // 解除闰月 + if (isLeap == true && i == (leap + 1)) { isLeap = false } + offset -= temp + } + // 闰月导致数组下标重叠取反 + if (offset == 0 && leap > 0 && i == leap + 1) { + if (isLeap) { + isLeap = false + } else { + isLeap = true; --i + } + } + if (offset < 0) { + offset += temp; --i + } + // 农历月 + var month = i + // 农历日 + var day = offset + 1 + // 天干地支处理 + var sm = m - 1 + var gzY = this.toGanZhiYear(year) + + // 当月的两个节气 + // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` + var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始 + var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始 + + // 依据12节气修正干支月 + var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) + if (d >= firstNode) { + gzM = this.toGanZhi((y - 1900) * 12 + m + 12) + } + + // 传入的日期的节气与否 + var isTerm = false + var Term = null + if (firstNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 2] + } + if (secondNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 1] + } + // 日柱 当月一日与 1900/1/1 相差天数 + var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 + var gzD = this.toGanZhi(dayCyclical + d - 1) + // 该日期所属的星座 + var astro = this.toAstro(m, d) + + return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } + }, + + /** + * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON + * @param y lunar year + * @param m lunar month + * @param d lunar day + * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] + * @return JSON object + * @eg:console.log(calendar.lunar2solar(1987,9,10)); + */ + lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1 + var isLeapMonth = !!isLeapMonth + var leapOffset = 0 + var leapMonth = this.leapMonth(y) + var leapDay = this.leapDays(y) + if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 + if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值 + var day = this.monthDays(y, m) + var _day = day + // bugFix 2016-9-25 + // if month is leap, _day use leapDays method + if (isLeapMonth) { + _day = this.leapDays(y, m) + } + if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验 + + // 计算农历的时间差 + var offset = 0 + for (var i = 1900; i < y; i++) { + offset += this.lYearDays(i) + } + var leap = 0; var isAdd = false + for (var i = 1; i < m; i++) { + leap = this.leapMonth(y) + if (!isAdd) { // 处理闰月 + if (leap <= i && leap > 0) { + offset += this.leapDays(y); isAdd = true + } + } + offset += this.monthDays(y, i) + } + // 转换闰月农历 需补充该年闰月的前一个月的时差 + if (isLeapMonth) { offset += day } + // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) + var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) + var calObj = new Date((offset + d - 31) * 86400000 + stmap) + var cY = calObj.getUTCFullYear() + var cM = calObj.getUTCMonth() + 1 + var cD = calObj.getUTCDate() + + return this.solar2lunar(cY, cM, cD) + } +} + +export default calendar diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json new file mode 100644 index 0000000..fcbd13c --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json @@ -0,0 +1,12 @@ +{ + "uni-calender.ok": "ok", + "uni-calender.cancel": "cancel", + "uni-calender.today": "today", + "uni-calender.MON": "MON", + "uni-calender.TUE": "TUE", + "uni-calender.WED": "WED", + "uni-calender.THU": "THU", + "uni-calender.FRI": "FRI", + "uni-calender.SAT": "SAT", + "uni-calender.SUN": "SUN" +} diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js b/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js new file mode 100644 index 0000000..de7509c --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js @@ -0,0 +1,8 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json new file mode 100644 index 0000000..1ca43de --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json @@ -0,0 +1,12 @@ +{ + "uni-calender.ok": "确定", + "uni-calender.cancel": "取消", + "uni-calender.today": "今日", + "uni-calender.SUN": "日", + "uni-calender.MON": "一", + "uni-calender.TUE": "二", + "uni-calender.WED": "三", + "uni-calender.THU": "四", + "uni-calender.FRI": "五", + "uni-calender.SAT": "六" +} diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json new file mode 100644 index 0000000..e0fe33b --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json @@ -0,0 +1,12 @@ +{ + "uni-calender.ok": "確定", + "uni-calender.cancel": "取消", + "uni-calender.today": "今日", + "uni-calender.SUN": "日", + "uni-calender.MON": "一", + "uni-calender.TUE": "二", + "uni-calender.WED": "三", + "uni-calender.THU": "四", + "uni-calender.FRI": "五", + "uni-calender.SAT": "六" +} diff --git a/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue new file mode 100644 index 0000000..a54135e --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue @@ -0,0 +1,187 @@ + + + + + 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..17c958d --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue @@ -0,0 +1,566 @@ + + + + + diff --git a/uni_modules/uni-calendar/components/uni-calendar/util.js b/uni_modules/uni-calendar/components/uni-calendar/util.js new file mode 100644 index 0000000..5ec8a92 --- /dev/null +++ b/uni_modules/uni-calendar/components/uni-calendar/util.js @@ -0,0 +1,360 @@ +import CALENDAR from './calendar.js' + +class Calendar { + constructor({ + date, + selected, + startDate, + endDate, + range + } = {}) { + // 当前日期 + this.date = this.getDate(new Date()) // 当前初入日期 + // 打点信息 + this.selected = selected || []; + // 范围开始 + this.startDate = startDate + // 范围结束 + this.endDate = endDate + this.range = range + // 多选状态 + this.cleanMultipleStatus() + // 每周日期 + this.weeks = {} + // this._getWeek(this.date.fullDate) + } + /** + * 设置日期 + * @param {Object} date + */ + setDate(date) { + this.selectDate = this.getDate(date) + this._getWeek(this.selectDate.fullDate) + } + + /** + * 清理多选状态 + */ + cleanMultipleStatus() { + this.multipleStatus = { + before: '', + after: '', + data: [] + } + } + + /** + * 重置开始日期 + */ + resetSatrtDate(startDate) { + // 范围开始 + this.startDate = startDate + + } + + /** + * 重置结束日期 + */ + resetEndDate(endDate) { + // 范围结束 + this.endDate = endDate + } + + /** + * 获取任意时间 + */ + getDate(date, AddDayCount = 0, str = 'day') { + if (!date) { + date = new Date() + } + if (typeof date !== 'object') { + date = date.replace(/-/g, '/') + } + const dd = new Date(date) + switch (str) { + case 'day': + dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期 + break + case 'month': + if (dd.getDate() === 31 && AddDayCount>0) { + dd.setDate(dd.getDate() + AddDayCount) + } else { + const preMonth = dd.getMonth() + dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期 + const nextMonth = dd.getMonth() + // 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题 + if(AddDayCount<0 && preMonth!==0 && nextMonth-preMonth>AddDayCount){ + dd.setMonth(nextMonth+(nextMonth-preMonth+AddDayCount)) + } + // 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题 + if(AddDayCount>0 && nextMonth-preMonth>AddDayCount){ + dd.setMonth(nextMonth-(nextMonth-preMonth-AddDayCount)) + } + } + break + case 'year': + dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期 + break + } + const y = dd.getFullYear() + const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0 + const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0 + return { + fullDate: y + '-' + m + '-' + d, + year: y, + month: m, + date: d, + day: dd.getDay() + } + } + + + /** + * 获取上月剩余天数 + */ + _getLastMonthDays(firstDay, full) { + let dateArr = [] + for (let i = firstDay; i > 0; i--) { + const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate() + dateArr.push({ + date: beforeDate, + month: full.month - 1, + lunar: this.getlunar(full.year, full.month - 1, beforeDate), + disable: true + }) + } + return dateArr + } + /** + * 获取本月天数 + */ + _currentMonthDys(dateData, full) { + let dateArr = [] + let fullDate = this.date.fullDate + for (let i = 1; i <= dateData; i++) { + let nowDate = full.year + '-' + (full.month < 10 ? + full.month : full.month) + '-' + (i < 10 ? + '0' + i : i) + // 是否今天 + let isDay = fullDate === nowDate + // 获取打点信息 + let info = this.selected && this.selected.find((item) => { + if (this.dateEqual(nowDate, item.date)) { + return item + } + }) + + // 日期禁用 + let disableBefore = true + let disableAfter = true + if (this.startDate) { + // let dateCompBefore = this.dateCompare(this.startDate, fullDate) + // disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate) + disableBefore = this.dateCompare(this.startDate, nowDate) + } + + if (this.endDate) { + // let dateCompAfter = this.dateCompare(fullDate, this.endDate) + // disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate) + disableAfter = this.dateCompare(nowDate, this.endDate) + } + let multiples = this.multipleStatus.data + let checked = false + let multiplesStatus = -1 + if (this.range) { + if (multiples) { + multiplesStatus = multiples.findIndex((item) => { + return this.dateEqual(item, nowDate) + }) + } + if (multiplesStatus !== -1) { + checked = true + } + } + let data = { + fullDate: nowDate, + year: full.year, + date: i, + multiple: this.range ? checked : false, + beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate), + afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate), + month: full.month, + lunar: this.getlunar(full.year, full.month, i), + disable: !(disableBefore && disableAfter), + isDay + } + if (info) { + data.extraInfo = info + } + + dateArr.push(data) + } + return dateArr + } + /** + * 获取下月天数 + */ + _getNextMonthDays(surplus, full) { + let dateArr = [] + for (let i = 1; i < surplus + 1; i++) { + dateArr.push({ + date: i, + month: Number(full.month) + 1, + lunar: this.getlunar(full.year, Number(full.month) + 1, i), + disable: true + }) + } + return dateArr + } + + /** + * 获取当前日期详情 + * @param {Object} date + */ + getInfo(date) { + if (!date) { + date = new Date() + } + const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate) + return dateInfo + } + + /** + * 比较时间大小 + */ + dateCompare(startDate, endDate) { + // 计算截止时间 + startDate = new Date(startDate.replace('-', '/').replace('-', '/')) + // 计算详细项的截止时间 + endDate = new Date(endDate.replace('-', '/').replace('-', '/')) + if (startDate <= endDate) { + return true + } else { + return false + } + } + + /** + * 比较时间是否相等 + */ + dateEqual(before, after) { + // 计算截止时间 + before = new Date(before.replace('-', '/').replace('-', '/')) + // 计算详细项的截止时间 + after = new Date(after.replace('-', '/').replace('-', '/')) + if (before.getTime() - after.getTime() === 0) { + return true + } else { + return false + } + } + + + /** + * 获取日期范围内所有日期 + * @param {Object} begin + * @param {Object} end + */ + geDateAll(begin, end) { + var arr = [] + var ab = begin.split('-') + var ae = end.split('-') + var db = new Date() + db.setFullYear(ab[0], ab[1] - 1, ab[2]) + var de = new Date() + de.setFullYear(ae[0], ae[1] - 1, ae[2]) + var unixDb = db.getTime() - 24 * 60 * 60 * 1000 + var unixDe = de.getTime() - 24 * 60 * 60 * 1000 + for (var k = unixDb; k <= unixDe;) { + k = k + 24 * 60 * 60 * 1000 + arr.push(this.getDate(new Date(parseInt(k))).fullDate) + } + return arr + } + /** + * 计算阴历日期显示 + */ + getlunar(year, month, date) { + return CALENDAR.solar2lunar(year, month, date) + } + /** + * 设置打点 + */ + setSelectInfo(data, value) { + this.selected = value + this._getWeek(data) + } + + /** + * 获取多选状态 + */ + setMultiple(fullDate) { + let { + before, + after + } = this.multipleStatus + + if (!this.range) return + if (before && after) { + this.multipleStatus.before = '' + this.multipleStatus.after = '' + this.multipleStatus.data = [] + } else { + if (!before) { + this.multipleStatus.before = fullDate + } else { + this.multipleStatus.after = fullDate + if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after); + } else { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before); + } + } + } + this._getWeek(fullDate) + } + + /** + * 获取每周数据 + * @param {Object} dateData + */ + _getWeek(dateData) { + const { + year, + month + } = this.getDate(dateData) + let firstDay = new Date(year, month - 1, 1).getDay() + let currentDay = new Date(year, month, 0).getDate() + let dates = { + lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天 + currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数 + nextMonthDays: [], // 下个月开始几天 + weeks: [] + } + let canlender = [] + const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length) + dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData)) + canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays) + let weeks = {} + // 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天 + for (let i = 0; i < canlender.length; i++) { + if (i % 7 === 0) { + weeks[parseInt(i / 7)] = new Array(7) + } + weeks[parseInt(i / 7)][i % 7] = canlender[i] + } + this.canlender = canlender + this.weeks = weeks + } + + //静态方法 + // static init(date) { + // if (!this.instance) { + // this.instance = new Calendar(date); + // } + // return this.instance; + // } +} + + +export default Calendar diff --git a/uni_modules/uni-calendar/package.json b/uni_modules/uni-calendar/package.json new file mode 100644 index 0000000..fad841f --- /dev/null +++ b/uni_modules/uni-calendar/package.json @@ -0,0 +1,85 @@ +{ + "id": "uni-calendar", + "displayName": "uni-calendar 日历", + "version": "1.4.10", + "description": "日历组件", + "keywords": [ + "uni-ui", + "uniui", + "日历", + "", + "打卡", + "日历选择" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-calendar/readme.md b/uni_modules/uni-calendar/readme.md new file mode 100644 index 0000000..4e1748c --- /dev/null +++ b/uni_modules/uni-calendar/readme.md @@ -0,0 +1,103 @@ + + +## Calendar 日历 +> **组件名:uni-calendar** +> 代码块: `uCalendar` + + +日历组件 + +> **注意事项** +> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。 +> - 本组件农历转换使用的js是 [@1900-2100区间内的公历、农历互转](https://github.com/jjonline/calendar.js) +> - 仅支持自定义组件模式 +> - `date`属性传入的应该是一个 String ,如: 2019-06-27 ,而不是 new Date() +> - 通过 `insert` 属性来确定当前的事件是 @change 还是 @confirm 。理应合并为一个事件,但是为了区分模式,现使用两个事件,这里需要注意 +> - 弹窗模式下无法阻止后面的元素滚动,如有需要阻止,请在弹窗弹出后,手动设置滚动元素为不可滚动 + + +### 安装方式 + +本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 + +如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) + +### 基本用法 + +在 ``template`` 中使用组件 + +```html + + + +``` + +### 通过方法打开日历 + +需要设置 `insert` 为 `false` + +```html + + + + +``` + +```javascript + +export default { + data() { + return {}; + }, + methods: { + open(){ + this.$refs.calendar.open(); + }, + confirm(e) { + console.log(e); + } + } +}; + +``` + + +## API + +### Calendar Props + +| 属性名 | 类型 | 默认值| 说明 | +| - | - | - | - | +| date | String |- | 自定义当前时间,默认为今天 | +| lunar | Boolean | false | 显示农历 | +| startDate | String |- | 日期选择范围-开始日期 | +| endDate | String |- | 日期选择范围-结束日期 | +| range | Boolean | false | 范围选择 | +| insert | Boolean | false | 插入模式,可选值,ture:插入模式;false:弹窗模式;默认为插入模式 | +|clearDate |Boolean |true |弹窗模式是否清空上次选择内容 | +| selected | Array |- | 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}] | +|showMonth | Boolean | true | 是否显示月份为背景 | + +### Calendar Events + +| 事件名 | 说明 |返回值| +| - | - | - | +| open | 弹出日历组件,`insert :false` 时生效|- | + + + + + +## 组件示例 + +点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar](https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar) diff --git a/uni_modules/uni-card/changelog.md b/uni_modules/uni-card/changelog.md new file mode 100644 index 0000000..c3cd8c4 --- /dev/null +++ b/uni_modules/uni-card/changelog.md @@ -0,0 +1,26 @@ +## 1.3.1(2021-12-20) +- 修复 在vue页面下略缩图显示不正常的bug +## 1.3.0(2021-11-19) +- 重构插槽的用法 ,header 替换为 title +- 新增 actions 插槽 +- 新增 cover 封面图属性和插槽 +- 新增 padding 内容默认内边距离 +- 新增 margin 卡片默认外边距离 +- 新增 spacing 卡片默认内边距 +- 新增 shadow 卡片阴影属性 +- 取消 mode 属性,可使用组合插槽代替 +- 取消 note 属性 ,使用actions插槽代替 +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-card](https://uniapp.dcloud.io/component/uniui/uni-card) +## 1.2.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.2.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.8(2021-07-01) +- 优化 图文卡片无图片加载时,提供占位图标 +- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持) +- 修复 thumbnail 不存在仍然占位的 bug +## 1.1.7(2021-05-12) +- 新增 组件示例地址 +## 1.1.6(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-card/components/uni-card/uni-card.vue b/uni_modules/uni-card/components/uni-card/uni-card.vue new file mode 100644 index 0000000..88d8342 --- /dev/null +++ b/uni_modules/uni-card/components/uni-card/uni-card.vue @@ -0,0 +1,272 @@ + + + + + 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..292e4c7 --- /dev/null +++ b/uni_modules/uni-collapse/changelog.md @@ -0,0 +1,36 @@ +## 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..d62a6a7 --- /dev/null +++ b/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue @@ -0,0 +1,402 @@ + + + + + diff --git a/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue b/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue new file mode 100644 index 0000000..384c39a --- /dev/null +++ b/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue @@ -0,0 +1,147 @@ + + + diff --git a/uni_modules/uni-collapse/package.json b/uni_modules/uni-collapse/package.json new file mode 100644 index 0000000..65349cf --- /dev/null +++ b/uni_modules/uni-collapse/package.json @@ -0,0 +1,89 @@ +{ + "id": "uni-collapse", + "displayName": "uni-collapse 折叠面板", + "version": "1.4.3", + "description": "Collapse 组件,可以折叠 / 展开的内容区域。", + "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-collapse/readme.md b/uni_modules/uni-collapse/readme.md new file mode 100644 index 0000000..bc758eb --- /dev/null +++ b/uni_modules/uni-collapse/readme.md @@ -0,0 +1,12 @@ + + +## Collapse 折叠面板 +> **组件名:uni-collapse** +> 代码块: `uCollapse` +> 关联组件:`uni-collapse-item`、`uni-icons`。 + + +折叠面板用来折叠/显示过长的内容或者是列表。通常是在多内容分类项使用,折叠不重要的内容,显示重要内容。点击可以展开折叠部分。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-collapse) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-combox/changelog.md b/uni_modules/uni-combox/changelog.md new file mode 100644 index 0000000..23c2748 --- /dev/null +++ b/uni_modules/uni-combox/changelog.md @@ -0,0 +1,15 @@ +## 1.0.1(2021-11-23) +- 优化 label、label-width 属性 +## 1.0.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-combox](https://uniapp.dcloud.io/component/uniui/uni-combox) +## 0.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 0.0.6(2021-05-12) +- 新增 组件示例地址 +## 0.0.5(2021-04-21) +- 优化 添加依赖 uni-icons, 导入后自动下载依赖 +## 0.0.4(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 +## 0.0.3(2021-02-04) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-combox/components/uni-combox/uni-combox.vue b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue new file mode 100644 index 0000000..83454e5 --- /dev/null +++ b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue @@ -0,0 +1,294 @@ + + + + + diff --git a/uni_modules/uni-combox/package.json b/uni_modules/uni-combox/package.json new file mode 100644 index 0000000..4a05c3f --- /dev/null +++ b/uni_modules/uni-combox/package.json @@ -0,0 +1,90 @@ +{ + "id": "uni-combox", + "displayName": "uni-combox 组合框", + "version": "1.0.1", + "description": "可以选择也可以输入的表单项 ", + "keywords": [ + "uni-ui", + "uniui", + "combox", + "组合框", + "select" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-combox/readme.md b/uni_modules/uni-combox/readme.md new file mode 100644 index 0000000..ffa2cc8 --- /dev/null +++ b/uni_modules/uni-combox/readme.md @@ -0,0 +1,11 @@ + + +## Combox 组合框 +> **组件名:uni-combox** +> 代码块: `uCombox` + + +组合框组件。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-combox) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-countdown/changelog.md b/uni_modules/uni-countdown/changelog.md new file mode 100644 index 0000000..f25beef --- /dev/null +++ b/uni_modules/uni-countdown/changelog.md @@ -0,0 +1,24 @@ +## 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..65a1216 --- /dev/null +++ b/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue @@ -0,0 +1,267 @@ + + + diff --git a/uni_modules/uni-countdown/package.json b/uni_modules/uni-countdown/package.json new file mode 100644 index 0000000..70e99ee --- /dev/null +++ b/uni_modules/uni-countdown/package.json @@ -0,0 +1,86 @@ +{ + "id": "uni-countdown", + "displayName": "uni-countdown 倒计时", + "version": "1.2.2", + "description": "CountDown 倒计时组件", + "keywords": [ + "uni-ui", + "uniui", + "countdown", + "倒计时" +], + "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-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..c7a468a --- /dev/null +++ b/uni_modules/uni-data-checkbox/changelog.md @@ -0,0 +1,45 @@ +## 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..3c75d9f --- /dev/null +++ b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue @@ -0,0 +1,821 @@ + + + + + diff --git a/uni_modules/uni-data-checkbox/package.json b/uni_modules/uni-data-checkbox/package.json new file mode 100644 index 0000000..113c350 --- /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.3", + "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..1dd79f7 --- /dev/null +++ b/uni_modules/uni-data-picker/changelog.md @@ -0,0 +1,75 @@ +## 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.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 @@ + + + + + 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-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 @@ + + + + + diff --git a/uni_modules/uni-data-picker/package.json b/uni_modules/uni-data-picker/package.json new file mode 100644 index 0000000..038f9ce --- /dev/null +++ b/uni_modules/uni-data-picker/package.json @@ -0,0 +1,90 @@ +{ + "id": "uni-data-picker", + "displayName": "uni-data-picker 数据驱动的picker选择器", + "version": "1.1.2", + "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景", + "keywords": [ + "uni-ui", + "uniui", + "picker", + "级联", + "省市区", + "" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-load-more", + "uni-icons", + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "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", + "京东": "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..6cda224 --- /dev/null +++ b/uni_modules/uni-data-picker/readme.md @@ -0,0 +1,22 @@ +## DataPicker 级联选择 +> **组件名:uni-data-picker** +> 代码块: `uDataPicker` +> 关联组件:`uni-data-pickerview`、`uni-load-more`。 + + +`` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。 + +支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。 + +候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。 + +`` 组件尤其适用于地址选择、分类选择等选择类。 + +`` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。 + +`` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。 + +在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-data-select/changelog.md b/uni_modules/uni-data-select/changelog.md new file mode 100644 index 0000000..eb3d1ce --- /dev/null +++ b/uni_modules/uni-data-select/changelog.md @@ -0,0 +1,35 @@ +## 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..9b32348 --- /dev/null +++ b/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue @@ -0,0 +1,517 @@ + + + + + diff --git a/uni_modules/uni-data-select/package.json b/uni_modules/uni-data-select/package.json new file mode 100644 index 0000000..0187429 --- /dev/null +++ b/uni_modules/uni-data-select/package.json @@ -0,0 +1,85 @@ +{ + "id": "uni-data-select", + "displayName": "uni-data-select 下拉框选择器", + "version": "1.0.6", + "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" + }, + "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 @@ + + + + + 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..1f1a554 --- /dev/null +++ b/uni_modules/uni-datetime-picker/changelog.md @@ -0,0 +1,133 @@ +## 2.2.22(2023-03-30) +- 修复 日历 picker 修改年月后,自动选中当月1日 [详情](https://ask.dcloud.net.cn/question/165937) +- 修复 小程序端 低版本 ios NaN [详情](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 属性支持配置选择器打开时默认显示的时间 +- 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间 +- 优化 字节小程序日期时间范围选择,底部日期换行问题 +## 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 @@ + + + + + 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..3418f49 --- /dev/null +++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue @@ -0,0 +1,928 @@ + + + + + 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..81a042a --- /dev/null +++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue @@ -0,0 +1,934 @@ + + + + + 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..bd96488 --- /dev/null +++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue @@ -0,0 +1,1026 @@ + + + + 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..7dc34c4 --- /dev/null +++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js @@ -0,0 +1,403 @@ +class Calendar { + constructor({ + selected, + startDate, + endDate, + range, + } = {}) { + // 当前日期 + this.date = this.getDateObj(new Date()) // 当前初入日期 + // 打点信息 + this.selected = selected || []; + // 起始时间 + this.startDate = startDate + // 终止时间 + this.endDate = endDate + // 是否范围选择 + this.range = range + // 多选状态 + this.cleanMultipleStatus() + // 每周日期 + this.weeks = {} + this.lastHover = false + } + /** + * 设置日期 + * @param {Object} date + */ + setDate(date) { + const selectDate = this.getDateObj(date) + this.getWeeks(selectDate.fullDate) + } + + /** + * 清理多选状态 + */ + cleanMultipleStatus() { + this.multipleStatus = { + before: '', + after: '', + data: [] + } + } + + setStartDate(startDate) { + this.startDate = startDate + } + + setEndDate(endDate) { + this.endDate = endDate + } + + getPreMonthObj(date){ + date = fixIosDateFormat(date) + date = new Date(date) + + const oldMonth = date.getMonth() + date.setMonth(oldMonth - 1) + const newMonth = date.getMonth() + if(oldMonth !== 0 && newMonth - oldMonth === 0){ + date.setMonth(newMonth - 1) + } + return this.getDateObj(date) + } + getNextMonthObj(date){ + date = fixIosDateFormat(date) + date = new Date(date) + + const oldMonth = date.getMonth() + date.setMonth(oldMonth + 1) + const newMonth = date.getMonth() + if(newMonth - oldMonth > 1){ + date.setMonth(newMonth - 1) + } + return this.getDateObj(date) + } + + /** + * 获取指定格式Date对象 + */ + getDateObj(date) { + date = fixIosDateFormat(date) + date = new Date(date) + + return { + fullDate: getDate(date), + year: date.getFullYear(), + month: addZero(date.getMonth() + 1), + date: addZero(date.getDate()), + day: date.getDay() + } + } + + /** + * 获取上一个月日期集合 + */ + getPreMonthDays(amount, dateObj) { + const result = [] + for (let i = amount - 1; i >= 0; i--) { + const month = dateObj.month - 1 + result.push({ + date: new Date(dateObj.year, month, -i).getDate(), + month, + disable: true + }) + } + return result + } + /** + * 获取本月日期集合 + */ + getCurrentMonthDays(amount, dateObj) { + const result = [] + const fullDate = this.date.fullDate + for (let i = 1; i <= amount; i++) { + const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}` + const isToday = fullDate === currentDate + // 获取打点信息 + const info = this.selected && this.selected.find((item) => { + if (this.dateEqual(currentDate, item.date)) { + return item + } + }) + + // 日期禁用 + let disableBefore = true + let disableAfter = true + if (this.startDate) { + disableBefore = dateCompare(this.startDate, currentDate) + } + + if (this.endDate) { + disableAfter = dateCompare(currentDate, this.endDate) + } + + let multiples = this.multipleStatus.data + let multiplesStatus = -1 + if (this.range && multiples) { + multiplesStatus = multiples.findIndex((item) => { + return this.dateEqual(item, currentDate) + }) + } + const checked = multiplesStatus !== -1 + + result.push({ + fullDate: currentDate, + year: dateObj.year, + date: i, + multiple: this.range ? checked : false, + beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this.multipleStatus.after), + afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this.multipleStatus.after), + month: dateObj.month, + disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(currentDate,this.endDate)), + isToday, + userChecked: false, + extraInfo: info + }) + } + return result + } + /** + * 获取下一个月日期集合 + */ + _getNextMonthDays(amount, dateObj) { + const result = [] + const month = dateObj.month + 1 + for (let i = 1; i <= amount; i++) { + result.push({ + date: i, + month, + disable: true + }) + } + return result + } + + /** + * 获取当前日期详情 + * @param {Object} date + */ + getInfo(date) { + if (!date) { + date = new Date() + } + + return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate) + } + + /** + * 比较时间是否相等 + */ + dateEqual(before, after) { + before = new Date(fixIosDateFormat(before)) + after = new Date(fixIosDateFormat(after)) + return before.valueOf() === after.valueOf() + } + + /** + * 比较真实起始日期 + */ + + isLogicBefore(currentDate, before, after) { + let logicBefore = before + if (before && after) { + logicBefore = dateCompare(before, after) ? before : after + } + return this.dateEqual(logicBefore, currentDate) + } + + isLogicAfter(currentDate, before, after) { + let logicAfter = after + if (before && after) { + logicAfter = dateCompare(before, after) ? after : before + } + return this.dateEqual(logicAfter, currentDate) + } + + /** + * 获取日期范围内所有日期 + * @param {Object} begin + * @param {Object} end + */ + geDateAll(begin, end) { + var arr = [] + var ab = begin.split('-') + var ae = end.split('-') + var db = new Date() + db.setFullYear(ab[0], ab[1] - 1, ab[2]) + var de = new Date() + de.setFullYear(ae[0], ae[1] - 1, ae[2]) + var unixDb = db.getTime() - 24 * 60 * 60 * 1000 + var unixDe = de.getTime() - 24 * 60 * 60 * 1000 + for (var k = unixDb; k <= unixDe;) { + k = k + 24 * 60 * 60 * 1000 + arr.push(this.getDateObj(new Date(parseInt(k))).fullDate) + } + return arr + } + + /** + * 获取多选状态 + */ + setMultiple(fullDate) { + if (!this.range) return + + let { + before, + after + } = this.multipleStatus + if (before && after) { + if (!this.lastHover) { + this.lastHover = true + return + } + this.multipleStatus.before = fullDate + this.multipleStatus.after = '' + this.multipleStatus.data = [] + this.multipleStatus.fulldate = '' + this.lastHover = false + } else { + if (!before) { + this.multipleStatus.before = fullDate + this.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) { + 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) + } + + /** + * 更新默认值多选状态 + */ + 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) +} + +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} \ No newline at end of file diff --git a/uni_modules/uni-datetime-picker/package.json b/uni_modules/uni-datetime-picker/package.json new file mode 100644 index 0000000..8abed63 --- /dev/null +++ b/uni_modules/uni-datetime-picker/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-datetime-picker", + "displayName": "uni-datetime-picker 日期选择器", + "version": "2.2.22", + "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" + }, + "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..82331a8 --- /dev/null +++ b/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/uni_modules/uni-drawer/package.json b/uni_modules/uni-drawer/package.json new file mode 100644 index 0000000..dd056e4 --- /dev/null +++ b/uni_modules/uni-drawer/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-drawer", + "displayName": "uni-drawer 抽屉", + "version": "1.2.1", + "description": "抽屉式导航,用于展示侧滑菜单,侧滑导航。", + "keywords": [ + "uni-ui", + "uniui", + "drawer", + "抽屉", + "侧滑导航" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-drawer/readme.md b/uni_modules/uni-drawer/readme.md new file mode 100644 index 0000000..dcf6e6b --- /dev/null +++ b/uni_modules/uni-drawer/readme.md @@ -0,0 +1,10 @@ + + +## Drawer 抽屉 +> **组件名:uni-drawer** +> 代码块: `uDrawer` + +抽屉侧滑菜单。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-drawer) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-easyinput/changelog.md b/uni_modules/uni-easyinput/changelog.md new file mode 100644 index 0000000..765401a --- /dev/null +++ b/uni_modules/uni-easyinput/changelog.md @@ -0,0 +1,97 @@ +## 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..2c7993a --- /dev/null +++ b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue @@ -0,0 +1,657 @@ + + + + + diff --git a/uni_modules/uni-easyinput/package.json b/uni_modules/uni-easyinput/package.json new file mode 100644 index 0000000..bd128e1 --- /dev/null +++ b/uni_modules/uni-easyinput/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-easyinput", + "displayName": "uni-easyinput 增强输入框", + "version": "1.1.9", + "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" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-easyinput/readme.md b/uni_modules/uni-easyinput/readme.md new file mode 100644 index 0000000..f1faf8f --- /dev/null +++ b/uni_modules/uni-easyinput/readme.md @@ -0,0 +1,11 @@ + + +### Easyinput 增强输入框 +> **组件名:uni-easyinput** +> 代码块: `uEasyinput` + + +easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-fab/changelog.md b/uni_modules/uni-fab/changelog.md new file mode 100644 index 0000000..9bd4729 --- /dev/null +++ b/uni_modules/uni-fab/changelog.md @@ -0,0 +1,23 @@ +## 1.2.5(2023-03-29) +- 新增 pattern.icon 属性,可自定义图标 +## 1.2.4(2022-09-07) +小程序端由于 style 使用了对象导致报错,[详情](https://ask.dcloud.net.cn/question/152790?item_id=211778&rf=false) +## 1.2.3(2022-09-05) +- 修复 nvue 环境下,具有 tabBar 时,fab 组件下部位置无法正常获取 --window-bottom 的bug,详见:[https://ask.dcloud.net.cn/question/110638?notification_id=826310](https://ask.dcloud.net.cn/question/110638?notification_id=826310) +## 1.2.2(2021-12-29) +- 更新 组件依赖 +## 1.2.1(2021-11-19) +- 修复 阴影颜色不正确的bug +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-fab](https://uniapp.dcloud.io/component/uniui/uni-fab) +## 1.1.1(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-05-12) +- 新增 组件示例地址 +## 1.0.6(2021-02-05) +- 调整为uni_modules目录规范 +- 优化 按钮背景色调整 +- 优化 兼容pc端 diff --git a/uni_modules/uni-fab/components/uni-fab/uni-fab.vue b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue new file mode 100644 index 0000000..dfa65c1 --- /dev/null +++ b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue @@ -0,0 +1,491 @@ + + + + + diff --git a/uni_modules/uni-fab/package.json b/uni_modules/uni-fab/package.json new file mode 100644 index 0000000..18c0810 --- /dev/null +++ b/uni_modules/uni-fab/package.json @@ -0,0 +1,84 @@ +{ + "id": "uni-fab", + "displayName": "uni-fab 悬浮按钮", + "version": "1.2.5", + "description": "悬浮按钮 fab button ,点击可展开一个图标按钮菜单。", + "keywords": [ + "uni-ui", + "uniui", + "按钮", + "悬浮按钮", + "fab" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-scss","uni-icons"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/uni_modules/uni-fab/readme.md b/uni_modules/uni-fab/readme.md new file mode 100644 index 0000000..9a444e8 --- /dev/null +++ b/uni_modules/uni-fab/readme.md @@ -0,0 +1,9 @@ +## Fab 悬浮按钮 +> **组件名:uni-fab** +> 代码块: `uFab` + + +点击可展开一个图形按钮菜单 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-fab) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-fav/changelog.md b/uni_modules/uni-fav/changelog.md new file mode 100644 index 0000000..d8a08d4 --- /dev/null +++ b/uni_modules/uni-fav/changelog.md @@ -0,0 +1,19 @@ +## 1.2.1(2022-05-30) +- 新增 stat 属性 ,是否开启uni统计功能 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-fav](https://uniapp.dcloud.io/component/uniui/uni-fav) +## 1.1.1(2021-08-24) +- 新增 支持国际化 +## 1.1.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.6(2021-05-12) +- 新增 组件示例地址 +## 1.0.5(2021-04-21) +- 优化 添加依赖 uni-icons, 导入后自动下载依赖 +## 1.0.4(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 +## 1.0.3(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 +## 1.0.2(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/en.json b/uni_modules/uni-fav/components/uni-fav/i18n/en.json new file mode 100644 index 0000000..9a0759e --- /dev/null +++ b/uni_modules/uni-fav/components/uni-fav/i18n/en.json @@ -0,0 +1,4 @@ +{ + "uni-fav.collect": "collect", + "uni-fav.collected": "collected" +} diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/index.js b/uni_modules/uni-fav/components/uni-fav/i18n/index.js new file mode 100644 index 0000000..de7509c --- /dev/null +++ b/uni_modules/uni-fav/components/uni-fav/i18n/index.js @@ -0,0 +1,8 @@ +import en from './en.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json new file mode 100644 index 0000000..67c89bf --- /dev/null +++ b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json @@ -0,0 +1,4 @@ +{ + "uni-fav.collect": "收藏", + "uni-fav.collected": "已收藏" +} diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json new file mode 100644 index 0000000..67c89bf --- /dev/null +++ b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json @@ -0,0 +1,4 @@ +{ + "uni-fav.collect": "收藏", + "uni-fav.collected": "已收藏" +} diff --git a/uni_modules/uni-fav/components/uni-fav/uni-fav.vue b/uni_modules/uni-fav/components/uni-fav/uni-fav.vue new file mode 100644 index 0000000..d2c58df --- /dev/null +++ b/uni_modules/uni-fav/components/uni-fav/uni-fav.vue @@ -0,0 +1,161 @@ + + + + + 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..b8230e9 --- /dev/null +++ b/uni_modules/uni-file-picker/changelog.md @@ -0,0 +1,67 @@ +## 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..aff0864 --- /dev/null +++ b/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js @@ -0,0 +1,224 @@ +'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) => { + uni.chooseImage({ + count, + sizeType, + sourceType, + extension, + success(res) { + resolve(normalizeChooseAndUploadFileRes(res, 'image')); + }, + fail(res) { + reject({ + errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL), + }); + }, + }); + }); +} + +function chooseVideo(opts) { + const { + camera, + compressed, + maxDuration, + sourceType, + extension + } = opts; + return new Promise((resolve, reject) => { + 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), + }); + }, + }); + }); +} + +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..370441d --- /dev/null +++ b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue @@ -0,0 +1,667 @@ + + + + + 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 @@ + + + + + diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue new file mode 100644 index 0000000..2a29bc2 --- /dev/null +++ b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/utils.js b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js new file mode 100644 index 0000000..60aaa3e --- /dev/null +++ b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js @@ -0,0 +1,109 @@ +/** + * 获取文件名和后缀 + * @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, + 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..35c926c --- /dev/null +++ b/uni_modules/uni-file-picker/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-file-picker", + "displayName": "uni-file-picker 文件选择上传", + "version": "1.0.4", + "description": "文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间", + "keywords": [ + "uni-ui", + "uniui", + "图片上传", + "文件上传" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/uni_modules/uni-file-picker/readme.md b/uni_modules/uni-file-picker/readme.md new file mode 100644 index 0000000..c8399a5 --- /dev/null +++ b/uni_modules/uni-file-picker/readme.md @@ -0,0 +1,11 @@ + +## FilePicker 文件选择上传 + +> **组件名:uni-file-picker** +> 代码块: `uFilePicker` + + +文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-file-picker) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/uni_modules/uni-forms/changelog.md b/uni_modules/uni-forms/changelog.md new file mode 100644 index 0000000..8218df5 --- /dev/null +++ b/uni_modules/uni-forms/changelog.md @@ -0,0 +1,92 @@ +## 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..91fe351 --- /dev/null +++ b/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue @@ -0,0 +1,627 @@ + + + + + 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..ed2f6d9 --- /dev/null +++ b/uni_modules/uni-forms/components/uni-forms/uni-forms.vue @@ -0,0 +1,397 @@ + + + + + diff --git a/uni_modules/uni-forms/components/uni-forms/utils.js b/uni_modules/uni-forms/components/uni-forms/utils.js new file mode 100644 index 0000000..6da2421 --- /dev/null +++ b/uni_modules/uni-forms/components/uni-forms/utils.js @@ -0,0 +1,293 @@ +/** + * 简单处理对象拷贝 + * @param {Obejct} 被拷贝对象 + * @@return {Object} 拷贝对象 + */ +export const deepCopy = (val) => { + return JSON.parse(JSON.stringify(val)) +} +/** + * 过滤数字类型 + * @param {String} format 数字类型 + * @@return {Boolean} 返回是否为数字类型 + */ +export const typeFilter = (format) => { + return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp'; +} + +/** + * 把 value 转换成指定的类型,用于处理初始值,原因是初始值需要入库不能为 undefined + * @param {String} key 字段名 + * @param {any} value 字段值 + * @param {Object} rules 表单校验规则 + */ +export const getValue = (key, value, rules) => { + const isRuleNumType = rules.find(val => val.format && typeFilter(val.format)); + const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool'); + // 输入类型为 number + if (!!isRuleNumType) { + if (!value && value !== 0) { + value = null + } else { + value = isNumber(Number(value)) ? Number(value) : value + } + } + + // 输入类型为 boolean + if (!!isRuleBoolType) { + value = isBoolean(value) ? value : false + } + + return value; +} + +/** + * 获取表单数据 + * @param {String|Array} name 真实名称,需要使用 realName 获取 + * @param {Object} data 原始数据 + * @param {any} value 需要设置的值 + */ +export const setDataValue = (field, formdata, value) => { + formdata[field] = value + return value || '' +} + +/** + * 获取表单数据 + * @param {String|Array} field 真实名称,需要使用 realName 获取 + * @param {Object} data 原始数据 + */ +export const getDataValue = (field, data) => { + return objGet(data, field) +} + +/** + * 获取表单类型 + * @param {String|Array} field 真实名称,需要使用 realName 获取 + */ +export const getDataValueType = (field, data) => { + const value = getDataValue(field, data) + return { + type: type(value), + value + } +} + +/** + * 获取表单可用的真实name + * @param {String|Array} name 表单name + * @@return {String} 表单可用的真实name + */ +export const realName = (name, data = {}) => { + const base_name = _basePath(name) + if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) { + const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_') + return realname + } + return base_name[0] || name +} + +/** + * 判断是否表单可用的真实name + * @param {String|Array} name 表单name + * @@return {String} 表单可用的真实name + */ +export const isRealName = (name) => { + const reg = /^_formdata_#*/ + return reg.test(name) +} + +/** + * 获取表单数据的原始格式 + * @@return {Object|Array} object 需要解析的数据 + */ +export const rawData = (object = {}, name) => { + let newData = JSON.parse(JSON.stringify(object)) + let formData = {} + for(let i in newData){ + let path = name2arr(i) + objSet(formData,path,newData[i]) + } + return formData +} + +/** + * 真实name还原为 array + * @param {*} name + */ +export const name2arr = (name) => { + let field = name.replace('_formdata_#', '') + field = field.split('#').map(v => (isNumber(v) ? Number(v) : v)) + return field +} + +/** + * 对象中设置值 + * @param {Object|Array} object 源数据 + * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c'] + * @param {String} value 需要设置的值 + */ +export const objSet = (object, path, value) => { + if (typeof object !== 'object') return object; + _basePath(path).reduce((o, k, i, _) => { + if (i === _.length - 1) { + // 若遍历结束直接赋值 + o[k] = value + return null + } else if (k in o) { + // 若存在对应路径,则返回找到的对象,进行下一次遍历 + return o[k] + } else { + // 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象 + o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {} + return o[k] + } + }, object) + // 返回object + return object; +} + +// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用 +function _basePath(path) { + // 若是数组,则直接返回 + if (Array.isArray(path)) return path + // 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']' + return path.replace(/\[/g, '.').replace(/\]/g, '').split('.') +} + +/** + * 从对象中获取值 + * @param {Object|Array} object 源数据 + * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c'] + * @param {String} defaultVal 如果无法从调用链中获取值的默认值 + */ +export const objGet = (object, path, defaultVal = 'undefined') => { + // 先将path处理成统一格式 + let newPath = _basePath(path) + // 递归处理,返回最后结果 + let val = newPath.reduce((o, k) => { + return (o || {})[k] + }, object); + return !val || val !== undefined ? val : defaultVal +} + + +/** + * 是否为 number 类型 + * @param {any} num 需要判断的值 + * @return {Boolean} 是否为 number + */ +export const isNumber = (num) => { + return !isNaN(Number(num)) +} + +/** + * 是否为 boolean 类型 + * @param {any} bool 需要判断的值 + * @return {Boolean} 是否为 boolean + */ +export const isBoolean = (bool) => { + return (typeof bool === 'boolean') +} +/** + * 是否有必填字段 + * @param {Object} rules 规则 + * @return {Boolean} 是否有必填字段 + */ +export const isRequiredField = (rules) => { + let isNoField = false; + for (let i = 0; i < rules.length; i++) { + const ruleData = rules[i]; + if (ruleData.required) { + isNoField = true; + break; + } + } + return isNoField; +} + + +/** + * 获取数据类型 + * @param {Any} obj 需要获取数据类型的值 + */ +export const type = (obj) => { + var class2type = {}; + + // 生成class2type映射 + "Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) { + class2type["[object " + item + "]"] = item.toLowerCase(); + }) + if (obj == null) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[Object.prototype.toString.call(obj)] || "object" : + typeof obj; +} + +/** + * 判断两个值是否相等 + * @param {any} a 值 + * @param {any} b 值 + * @return {Boolean} 是否相等 + */ +export const isEqual = (a, b) => { + //如果a和b本来就全等 + if (a === b) { + //判断是否为0和-0 + return a !== 0 || 1 / a === 1 / b; + } + //判断是否为null和undefined + if (a == null || b == null) { + return a === b; + } + //接下来判断a和b的数据类型 + var classNameA = toString.call(a), + classNameB = toString.call(b); + //如果数据类型不相等,则返回false + if (classNameA !== classNameB) { + return false; + } + //如果数据类型相等,再根据不同数据类型分别判断 + switch (classNameA) { + case '[object RegExp]': + case '[object String]': + //进行字符串转换比较 + return '' + a === '' + b; + case '[object Number]': + //进行数字转换比较,判断是否为NaN + if (+a !== +a) { + return +b !== +b; + } + //判断是否为0或-0 + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + return +a === +b; + } + //如果是对象类型 + if (classNameA == '[object Object]') { + //获取a和b的属性长度 + var propsA = Object.getOwnPropertyNames(a), + propsB = Object.getOwnPropertyNames(b); + if (propsA.length != propsB.length) { + return false; + } + for (var i = 0; i < propsA.length; i++) { + var propName = propsA[i]; + //如果对应属性对应值不相等,则返回false + if (a[propName] !== b[propName]) { + return false; + } + } + return true; + } + //如果是数组类型 + if (classNameA == '[object Array]') { + if (a.toString() == b.toString()) { + return true; + } + return false; + } +} diff --git a/uni_modules/uni-forms/components/uni-forms/validate.js b/uni_modules/uni-forms/components/uni-forms/validate.js new file mode 100644 index 0000000..1834c6c --- /dev/null +++ b/uni_modules/uni-forms/components/uni-forms/validate.js @@ -0,0 +1,486 @@ +var pattern = { + email: /^\S+?@\S+?\.\S+?$/, + idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/, + url: new RegExp( + "^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$", + 'i') +}; + +const FORMAT_MAPPING = { + "int": 'integer', + "bool": 'boolean', + "double": 'number', + "long": 'number', + "password": 'string' + // "fileurls": 'array' +} + +function formatMessage(args, resources = '') { + var defaultMessage = ['label'] + defaultMessage.forEach((item) => { + if (args[item] === undefined) { + args[item] = '' + } + }) + + let str = resources + for (let key in args) { + let reg = new RegExp('{' + key + '}') + str = str.replace(reg, args[key]) + } + return str +} + +function isEmptyValue(value, type) { + if (value === undefined || value === null) { + return true; + } + + if (typeof value === 'string' && !value) { + return true; + } + + if (Array.isArray(value) && !value.length) { + return true; + } + + if (type === 'object' && !Object.keys(value).length) { + return true; + } + + return false; +} + +const types = { + integer(value) { + return types.number(value) && parseInt(value, 10) === value; + }, + string(value) { + return typeof value === 'string'; + }, + number(value) { + if (isNaN(value)) { + return false; + } + return typeof value === 'number'; + }, + "boolean": function(value) { + return typeof value === 'boolean'; + }, + "float": function(value) { + return types.number(value) && !types.integer(value); + }, + array(value) { + return Array.isArray(value); + }, + object(value) { + return typeof value === 'object' && !types.array(value); + }, + date(value) { + return value instanceof Date; + }, + timestamp(value) { + if (!this.integer(value) || Math.abs(value).toString().length > 16) { + return false + } + return true; + }, + file(value) { + return typeof value.url === 'string'; + }, + email(value) { + return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255; + }, + url(value) { + return typeof value === 'string' && !!value.match(pattern.url); + }, + pattern(reg, value) { + try { + return new RegExp(reg).test(value); + } catch (e) { + return false; + } + }, + method(value) { + return typeof value === 'function'; + }, + idcard(value) { + return typeof value === 'string' && !!value.match(pattern.idcard); + }, + 'url-https'(value) { + return this.url(value) && value.startsWith('https://'); + }, + 'url-scheme'(value) { + return value.startsWith('://'); + }, + 'url-web'(value) { + return false; + } +} + +class RuleValidator { + + constructor(message) { + this._message = message + } + + async validateRule(fieldKey, fieldValue, value, data, allData) { + var result = null + + let rules = fieldValue.rules + + let hasRequired = rules.findIndex((item) => { + return item.required + }) + if (hasRequired < 0) { + if (value === null || value === undefined) { + return result + } + if (typeof value === 'string' && !value.length) { + return result + } + } + + var message = this._message + + if (rules === undefined) { + return message['default'] + } + + for (var i = 0; i < rules.length; i++) { + let rule = rules[i] + let vt = this._getValidateType(rule) + + Object.assign(rule, { + label: fieldValue.label || `["${fieldKey}"]` + }) + + if (RuleValidatorHelper[vt]) { + result = RuleValidatorHelper[vt](rule, value, message) + if (result != null) { + break + } + } + + if (rule.validateExpr) { + let now = Date.now() + let resultExpr = rule.validateExpr(value, allData, now) + if (resultExpr === false) { + result = this._getMessage(rule, rule.errorMessage || this._message['default']) + break + } + } + + if (rule.validateFunction) { + result = await this.validateFunction(rule, value, data, allData, vt) + if (result !== null) { + break + } + } + } + + if (result !== null) { + result = message.TAG + result + } + + return result + } + + async validateFunction(rule, value, data, allData, vt) { + let result = null + try { + let callbackMessage = null + const res = await rule.validateFunction(rule, value, allData || data, (message) => { + callbackMessage = message + }) + if (callbackMessage || (typeof res === 'string' && res) || res === false) { + result = this._getMessage(rule, callbackMessage || res, vt) + } + } catch (e) { + result = this._getMessage(rule, e.message, vt) + } + return result + } + + _getMessage(rule, message, vt) { + return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default']) + } + + _getValidateType(rule) { + var result = '' + if (rule.required) { + result = 'required' + } else if (rule.format) { + result = 'format' + } else if (rule.arrayType) { + result = 'arrayTypeFormat' + } else if (rule.range) { + result = 'range' + } else if (rule.maximum !== undefined || rule.minimum !== undefined) { + result = 'rangeNumber' + } else if (rule.maxLength !== undefined || rule.minLength !== undefined) { + result = 'rangeLength' + } else if (rule.pattern) { + result = 'pattern' + } else if (rule.validateFunction) { + result = 'validateFunction' + } + return result + } +} + +const RuleValidatorHelper = { + required(rule, value, message) { + if (rule.required && isEmptyValue(value, rule.format || typeof value)) { + return formatMessage(rule, rule.errorMessage || message.required); + } + + return null + }, + + range(rule, value, message) { + const { + range, + errorMessage + } = rule; + + let list = new Array(range.length); + for (let i = 0; i < range.length; i++) { + const item = range[i]; + if (types.object(item) && item.value !== undefined) { + list[i] = item.value; + } else { + list[i] = item; + } + } + + let result = false + if (Array.isArray(value)) { + result = (new Set(value.concat(list)).size === list.length); + } else { + if (list.indexOf(value) > -1) { + result = true; + } + } + + if (!result) { + return formatMessage(rule, errorMessage || message['enum']); + } + + return null + }, + + rangeNumber(rule, value, message) { + if (!types.number(value)) { + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); + } + + let { + minimum, + maximum, + exclusiveMinimum, + exclusiveMaximum + } = rule; + let min = exclusiveMinimum ? value <= minimum : value < minimum; + let max = exclusiveMaximum ? value >= maximum : value > maximum; + + if (minimum !== undefined && min) { + return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ? + 'exclusiveMinimum' : 'minimum' + ]) + } else if (maximum !== undefined && max) { + return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ? + 'exclusiveMaximum' : 'maximum' + ]) + } else if (minimum !== undefined && maximum !== undefined && (min || max)) { + return formatMessage(rule, rule.errorMessage || message['number'].range) + } + + return null + }, + + rangeLength(rule, value, message) { + if (!types.string(value) && !types.array(value)) { + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); + } + + let min = rule.minLength; + let max = rule.maxLength; + let val = value.length; + + if (min !== undefined && val < min) { + return formatMessage(rule, rule.errorMessage || message['length'].minLength) + } else if (max !== undefined && val > max) { + return formatMessage(rule, rule.errorMessage || message['length'].maxLength) + } else if (min !== undefined && max !== undefined && (val < min || val > max)) { + return formatMessage(rule, rule.errorMessage || message['length'].range) + } + + return null + }, + + pattern(rule, value, message) { + if (!types['pattern'](rule.pattern, value)) { + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); + } + + return null + }, + + format(rule, value, message) { + var customTypes = Object.keys(types); + var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType); + + if (customTypes.indexOf(format) > -1) { + if (!types[format](value)) { + return formatMessage(rule, rule.errorMessage || message.typeError); + } + } + + return null + }, + + arrayTypeFormat(rule, value, message) { + if (!Array.isArray(value)) { + return formatMessage(rule, rule.errorMessage || message.typeError); + } + + for (let i = 0; i < value.length; i++) { + const element = value[i]; + let formatResult = this.format(rule, element, message) + if (formatResult !== null) { + return formatResult + } + } + + return null + } +} + +class SchemaValidator extends RuleValidator { + + constructor(schema, options) { + super(SchemaValidator.message); + + this._schema = schema + this._options = options || null + } + + updateSchema(schema) { + this._schema = schema + } + + async validate(data, allData) { + let result = this._checkFieldInSchema(data) + if (!result) { + result = await this.invokeValidate(data, false, allData) + } + return result.length ? result[0] : null + } + + async validateAll(data, allData) { + let result = this._checkFieldInSchema(data) + if (!result) { + result = await this.invokeValidate(data, true, allData) + } + return result + } + + async validateUpdate(data, allData) { + let result = this._checkFieldInSchema(data) + if (!result) { + result = await this.invokeValidateUpdate(data, false, allData) + } + return result.length ? result[0] : null + } + + async invokeValidate(data, all, allData) { + let result = [] + let schema = this._schema + for (let key in schema) { + let value = schema[key] + let errorMessage = await this.validateRule(key, value, data[key], data, allData) + if (errorMessage != null) { + result.push({ + key, + errorMessage + }) + if (!all) break + } + } + return result + } + + async invokeValidateUpdate(data, all, allData) { + let result = [] + for (let key in data) { + let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData) + if (errorMessage != null) { + result.push({ + key, + errorMessage + }) + if (!all) break + } + } + return result + } + + _checkFieldInSchema(data) { + var keys = Object.keys(data) + var keys2 = Object.keys(this._schema) + if (new Set(keys.concat(keys2)).size === keys2.length) { + return '' + } + + var noExistFields = keys.filter((key) => { + return keys2.indexOf(key) < 0; + }) + var errorMessage = formatMessage({ + field: JSON.stringify(noExistFields) + }, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid']) + return [{ + key: 'invalid', + errorMessage + }] + } +} + +function Message() { + return { + TAG: "", + default: '验证错误', + defaultInvalid: '提交的字段{field}在数据库中并不存在', + validateFunction: '验证无效', + required: '{label}必填', + 'enum': '{label}超出范围', + timestamp: '{label}格式无效', + whitespace: '{label}不能为空', + typeError: '{label}类型无效', + date: { + format: '{label}日期{value}格式无效', + parse: '{label}日期无法解析,{value}无效', + invalid: '{label}日期{value}无效' + }, + length: { + minLength: '{label}长度不能少于{minLength}', + maxLength: '{label}长度不能超过{maxLength}', + range: '{label}必须介于{minLength}和{maxLength}之间' + }, + number: { + minimum: '{label}不能小于{minimum}', + maximum: '{label}不能大于{maximum}', + exclusiveMinimum: '{label}不能小于等于{minimum}', + exclusiveMaximum: '{label}不能大于等于{maximum}', + range: '{label}必须介于{minimum}and{maximum}之间' + }, + pattern: { + mismatch: '{label}格式不匹配' + } + }; +} + + +SchemaValidator.message = new Message(); + +export default SchemaValidator diff --git a/uni_modules/uni-forms/package.json b/uni_modules/uni-forms/package.json new file mode 100644 index 0000000..1925611 --- /dev/null +++ b/uni_modules/uni-forms/package.json @@ -0,0 +1,88 @@ +{ + "id": "uni-forms", + "displayName": "uni-forms 表单", + "version": "1.4.9", + "description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据", + "keywords": [ + "uni-ui", + "表单", + "校验", + "表单校验", + "表单验证" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/uni_modules/uni-forms/readme.md b/uni_modules/uni-forms/readme.md new file mode 100644 index 0000000..63d5a04 --- /dev/null +++ b/uni_modules/uni-forms/readme.md @@ -0,0 +1,23 @@ + + +## Forms 表单 + +> **组件名:uni-forms** +> 代码块: `uForms`、`uni-forms-item` +> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。 + + +uni-app的内置组件已经有了 `

`组件,用于提交表单内容。 + +然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 ``组件封装了 ``组件,内置了表单验证功能。 + +`` 提供了 `rules`属性来描述校验规则、``子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。 + +每个要校验的表单项,不管input还是checkbox,都必须放在``组件中,且一个``组件只能放置一个表单项。 + +``组件内部预留了显示error message的区域,默认是在表单项的底部。 + +另外,``组件下面的各个表单项,可以通过``包裹为不同的分组。同一``下的不同表单项目将聚拢在一起,同其他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 @@ + + + + + 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..20fd54e --- /dev/null +++ b/uni_modules/uni-grid/components/uni-grid-item/uni-grid-item.vue @@ -0,0 +1,127 @@ + + + + + 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..96a412f --- /dev/null +++ b/uni_modules/uni-grid/components/uni-grid/uni-grid.vue @@ -0,0 +1,142 @@ + + + + + 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 @@ + + + + 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..6449885 --- /dev/null +++ b/uni_modules/uni-icons/changelog.md @@ -0,0 +1,22 @@ +## 1.3.5(2022-01-24) +- 优化 size 属性可以传入不带单位的字符串数值 +## 1.3.4(2022-01-24) +- 优化 size 支持其他单位 +## 1.3.3(2022-01-17) +- 修复 nvue 有些图标不显示的bug,兼容老版本图标 +## 1.3.2(2021-12-01) +- 优化 示例可复制图标名称 +## 1.3.1(2021-11-23) +- 优化 兼容旧组件 type 值 +## 1.3.0(2021-11-19) +- 新增 更多图标 +- 优化 自定义图标使用方式 +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons) +## 1.1.7(2021-11-08) +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.5(2021-05-12) +- 新增 组件示例地址 +## 1.1.4(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-icons/components/uni-icons/icons.js b/uni_modules/uni-icons/components/uni-icons/icons.js new file mode 100644 index 0000000..7889936 --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/icons.js @@ -0,0 +1,1169 @@ +export default { + "id": "2852637", + "name": "uniui图标库", + "font_family": "uniicons", + "css_prefix_text": "uniui-", + "description": "", + "glyphs": [ + { + "icon_id": "25027049", + "name": "yanse", + "font_class": "color", + "unicode": "e6cf", + "unicode_decimal": 59087 + }, + { + "icon_id": "25027048", + "name": "wallet", + "font_class": "wallet", + "unicode": "e6b1", + "unicode_decimal": 59057 + }, + { + "icon_id": "25015720", + "name": "settings-filled", + "font_class": "settings-filled", + "unicode": "e6ce", + "unicode_decimal": 59086 + }, + { + "icon_id": "25015434", + "name": "shimingrenzheng-filled", + "font_class": "auth-filled", + "unicode": "e6cc", + "unicode_decimal": 59084 + }, + { + "icon_id": "24934246", + "name": "shop-filled", + "font_class": "shop-filled", + "unicode": "e6cd", + "unicode_decimal": 59085 + }, + { + "icon_id": "24934159", + "name": "staff-filled-01", + "font_class": "staff-filled", + "unicode": "e6cb", + "unicode_decimal": 59083 + }, + { + "icon_id": "24932461", + "name": "VIP-filled", + "font_class": "vip-filled", + "unicode": "e6c6", + "unicode_decimal": 59078 + }, + { + "icon_id": "24932462", + "name": "plus_circle_fill", + "font_class": "plus-filled", + "unicode": "e6c7", + "unicode_decimal": 59079 + }, + { + "icon_id": "24932463", + "name": "folder_add-filled", + "font_class": "folder-add-filled", + "unicode": "e6c8", + "unicode_decimal": 59080 + }, + { + "icon_id": "24932464", + "name": "yanse-filled", + "font_class": "color-filled", + "unicode": "e6c9", + "unicode_decimal": 59081 + }, + { + "icon_id": "24932465", + "name": "tune-filled", + "font_class": "tune-filled", + "unicode": "e6ca", + "unicode_decimal": 59082 + }, + { + "icon_id": "24932455", + "name": "a-rilidaka-filled", + "font_class": "calendar-filled", + "unicode": "e6c0", + "unicode_decimal": 59072 + }, + { + "icon_id": "24932456", + "name": "notification-filled", + "font_class": "notification-filled", + "unicode": "e6c1", + "unicode_decimal": 59073 + }, + { + "icon_id": "24932457", + "name": "wallet-filled", + "font_class": "wallet-filled", + "unicode": "e6c2", + "unicode_decimal": 59074 + }, + { + "icon_id": "24932458", + "name": "paihangbang-filled", + "font_class": "medal-filled", + "unicode": "e6c3", + "unicode_decimal": 59075 + }, + { + "icon_id": "24932459", + "name": "gift-filled", + "font_class": "gift-filled", + "unicode": "e6c4", + "unicode_decimal": 59076 + }, + { + "icon_id": "24932460", + "name": "fire-filled", + "font_class": "fire-filled", + "unicode": "e6c5", + "unicode_decimal": 59077 + }, + { + "icon_id": "24928001", + "name": "refreshempty", + "font_class": "refreshempty", + "unicode": "e6bf", + "unicode_decimal": 59071 + }, + { + "icon_id": "24926853", + "name": "location-ellipse", + "font_class": "location-filled", + "unicode": "e6af", + "unicode_decimal": 59055 + }, + { + "icon_id": "24926735", + "name": "person-filled", + "font_class": "person-filled", + "unicode": "e69d", + "unicode_decimal": 59037 + }, + { + "icon_id": "24926703", + "name": "personadd-filled", + "font_class": "personadd-filled", + "unicode": "e698", + "unicode_decimal": 59032 + }, + { + "icon_id": "24923351", + "name": "back", + "font_class": "back", + "unicode": "e6b9", + "unicode_decimal": 59065 + }, + { + "icon_id": "24923352", + "name": "forward", + "font_class": "forward", + "unicode": "e6ba", + "unicode_decimal": 59066 + }, + { + "icon_id": "24923353", + "name": "arrowthinright", + "font_class": "arrow-right", + "unicode": "e6bb", + "unicode_decimal": 59067 + }, + { + "icon_id": "24923353", + "name": "arrowthinright", + "font_class": "arrowthinright", + "unicode": "e6bb", + "unicode_decimal": 59067 + }, + { + "icon_id": "24923354", + "name": "arrowthinleft", + "font_class": "arrow-left", + "unicode": "e6bc", + "unicode_decimal": 59068 + }, + { + "icon_id": "24923354", + "name": "arrowthinleft", + "font_class": "arrowthinleft", + "unicode": "e6bc", + "unicode_decimal": 59068 + }, + { + "icon_id": "24923355", + "name": "arrowthinup", + "font_class": "arrow-up", + "unicode": "e6bd", + "unicode_decimal": 59069 + }, + { + "icon_id": "24923355", + "name": "arrowthinup", + "font_class": "arrowthinup", + "unicode": "e6bd", + "unicode_decimal": 59069 + }, + { + "icon_id": "24923356", + "name": "arrowthindown", + "font_class": "arrow-down", + "unicode": "e6be", + "unicode_decimal": 59070 + },{ + "icon_id": "24923356", + "name": "arrowthindown", + "font_class": "arrowthindown", + "unicode": "e6be", + "unicode_decimal": 59070 + }, + { + "icon_id": "24923349", + "name": "arrowdown", + "font_class": "bottom", + "unicode": "e6b8", + "unicode_decimal": 59064 + },{ + "icon_id": "24923349", + "name": "arrowdown", + "font_class": "arrowdown", + "unicode": "e6b8", + "unicode_decimal": 59064 + }, + { + "icon_id": "24923346", + "name": "arrowright", + "font_class": "right", + "unicode": "e6b5", + "unicode_decimal": 59061 + }, + { + "icon_id": "24923346", + "name": "arrowright", + "font_class": "arrowright", + "unicode": "e6b5", + "unicode_decimal": 59061 + }, + { + "icon_id": "24923347", + "name": "arrowup", + "font_class": "top", + "unicode": "e6b6", + "unicode_decimal": 59062 + }, + { + "icon_id": "24923347", + "name": "arrowup", + "font_class": "arrowup", + "unicode": "e6b6", + "unicode_decimal": 59062 + }, + { + "icon_id": "24923348", + "name": "arrowleft", + "font_class": "left", + "unicode": "e6b7", + "unicode_decimal": 59063 + }, + { + "icon_id": "24923348", + "name": "arrowleft", + "font_class": "arrowleft", + "unicode": "e6b7", + "unicode_decimal": 59063 + }, + { + "icon_id": "24923334", + "name": "eye", + "font_class": "eye", + "unicode": "e651", + "unicode_decimal": 58961 + }, + { + "icon_id": "24923335", + "name": "eye-filled", + "font_class": "eye-filled", + "unicode": "e66a", + "unicode_decimal": 58986 + }, + { + "icon_id": "24923336", + "name": "eye-slash", + "font_class": "eye-slash", + "unicode": "e6b3", + "unicode_decimal": 59059 + }, + { + "icon_id": "24923337", + "name": "eye-slash-filled", + "font_class": "eye-slash-filled", + "unicode": "e6b4", + "unicode_decimal": 59060 + }, + { + "icon_id": "24923305", + "name": "info-filled", + "font_class": "info-filled", + "unicode": "e649", + "unicode_decimal": 58953 + }, + { + "icon_id": "24923299", + "name": "reload-01", + "font_class": "reload", + "unicode": "e6b2", + "unicode_decimal": 59058 + }, + { + "icon_id": "24923195", + "name": "mic_slash_fill", + "font_class": "micoff-filled", + "unicode": "e6b0", + "unicode_decimal": 59056 + }, + { + "icon_id": "24923165", + "name": "map-pin-ellipse", + "font_class": "map-pin-ellipse", + "unicode": "e6ac", + "unicode_decimal": 59052 + }, + { + "icon_id": "24923166", + "name": "map-pin", + "font_class": "map-pin", + "unicode": "e6ad", + "unicode_decimal": 59053 + }, + { + "icon_id": "24923167", + "name": "location", + "font_class": "location", + "unicode": "e6ae", + "unicode_decimal": 59054 + }, + { + "icon_id": "24923064", + "name": "starhalf", + "font_class": "starhalf", + "unicode": "e683", + "unicode_decimal": 59011 + }, + { + "icon_id": "24923065", + "name": "star", + "font_class": "star", + "unicode": "e688", + "unicode_decimal": 59016 + }, + { + "icon_id": "24923066", + "name": "star-filled", + "font_class": "star-filled", + "unicode": "e68f", + "unicode_decimal": 59023 + }, + { + "icon_id": "24899646", + "name": "a-rilidaka", + "font_class": "calendar", + "unicode": "e6a0", + "unicode_decimal": 59040 + }, + { + "icon_id": "24899647", + "name": "fire", + "font_class": "fire", + "unicode": "e6a1", + "unicode_decimal": 59041 + }, + { + "icon_id": "24899648", + "name": "paihangbang", + "font_class": "medal", + "unicode": "e6a2", + "unicode_decimal": 59042 + }, + { + "icon_id": "24899649", + "name": "font", + "font_class": "font", + "unicode": "e6a3", + "unicode_decimal": 59043 + }, + { + "icon_id": "24899650", + "name": "gift", + "font_class": "gift", + "unicode": "e6a4", + "unicode_decimal": 59044 + }, + { + "icon_id": "24899651", + "name": "link", + "font_class": "link", + "unicode": "e6a5", + "unicode_decimal": 59045 + }, + { + "icon_id": "24899652", + "name": "notification", + "font_class": "notification", + "unicode": "e6a6", + "unicode_decimal": 59046 + }, + { + "icon_id": "24899653", + "name": "staff", + "font_class": "staff", + "unicode": "e6a7", + "unicode_decimal": 59047 + }, + { + "icon_id": "24899654", + "name": "VIP", + "font_class": "vip", + "unicode": "e6a8", + "unicode_decimal": 59048 + }, + { + "icon_id": "24899655", + "name": "folder_add", + "font_class": "folder-add", + "unicode": "e6a9", + "unicode_decimal": 59049 + }, + { + "icon_id": "24899656", + "name": "tune", + "font_class": "tune", + "unicode": "e6aa", + "unicode_decimal": 59050 + }, + { + "icon_id": "24899657", + "name": "shimingrenzheng", + "font_class": "auth", + "unicode": "e6ab", + "unicode_decimal": 59051 + }, + { + "icon_id": "24899565", + "name": "person", + "font_class": "person", + "unicode": "e699", + "unicode_decimal": 59033 + }, + { + "icon_id": "24899566", + "name": "email-filled", + "font_class": "email-filled", + "unicode": "e69a", + "unicode_decimal": 59034 + }, + { + "icon_id": "24899567", + "name": "phone-filled", + "font_class": "phone-filled", + "unicode": "e69b", + "unicode_decimal": 59035 + }, + { + "icon_id": "24899568", + "name": "phone", + "font_class": "phone", + "unicode": "e69c", + "unicode_decimal": 59036 + }, + { + "icon_id": "24899570", + "name": "email", + "font_class": "email", + "unicode": "e69e", + "unicode_decimal": 59038 + }, + { + "icon_id": "24899571", + "name": "personadd", + "font_class": "personadd", + "unicode": "e69f", + "unicode_decimal": 59039 + }, + { + "icon_id": "24899558", + "name": "chatboxes-filled", + "font_class": "chatboxes-filled", + "unicode": "e692", + "unicode_decimal": 59026 + }, + { + "icon_id": "24899559", + "name": "contact", + "font_class": "contact", + "unicode": "e693", + "unicode_decimal": 59027 + }, + { + "icon_id": "24899560", + "name": "chatbubble-filled", + "font_class": "chatbubble-filled", + "unicode": "e694", + "unicode_decimal": 59028 + }, + { + "icon_id": "24899561", + "name": "contact-filled", + "font_class": "contact-filled", + "unicode": "e695", + "unicode_decimal": 59029 + }, + { + "icon_id": "24899562", + "name": "chatboxes", + "font_class": "chatboxes", + "unicode": "e696", + "unicode_decimal": 59030 + }, + { + "icon_id": "24899563", + "name": "chatbubble", + "font_class": "chatbubble", + "unicode": "e697", + "unicode_decimal": 59031 + }, + { + "icon_id": "24881290", + "name": "upload-filled", + "font_class": "upload-filled", + "unicode": "e68e", + "unicode_decimal": 59022 + }, + { + "icon_id": "24881292", + "name": "upload", + "font_class": "upload", + "unicode": "e690", + "unicode_decimal": 59024 + }, + { + "icon_id": "24881293", + "name": "weixin", + "font_class": "weixin", + "unicode": "e691", + "unicode_decimal": 59025 + }, + { + "icon_id": "24881274", + "name": "compose", + "font_class": "compose", + "unicode": "e67f", + "unicode_decimal": 59007 + }, + { + "icon_id": "24881275", + "name": "qq", + "font_class": "qq", + "unicode": "e680", + "unicode_decimal": 59008 + }, + { + "icon_id": "24881276", + "name": "download-filled", + "font_class": "download-filled", + "unicode": "e681", + "unicode_decimal": 59009 + }, + { + "icon_id": "24881277", + "name": "pengyouquan", + "font_class": "pyq", + "unicode": "e682", + "unicode_decimal": 59010 + }, + { + "icon_id": "24881279", + "name": "sound", + "font_class": "sound", + "unicode": "e684", + "unicode_decimal": 59012 + }, + { + "icon_id": "24881280", + "name": "trash-filled", + "font_class": "trash-filled", + "unicode": "e685", + "unicode_decimal": 59013 + }, + { + "icon_id": "24881281", + "name": "sound-filled", + "font_class": "sound-filled", + "unicode": "e686", + "unicode_decimal": 59014 + }, + { + "icon_id": "24881282", + "name": "trash", + "font_class": "trash", + "unicode": "e687", + "unicode_decimal": 59015 + }, + { + "icon_id": "24881284", + "name": "videocam-filled", + "font_class": "videocam-filled", + "unicode": "e689", + "unicode_decimal": 59017 + }, + { + "icon_id": "24881285", + "name": "spinner-cycle", + "font_class": "spinner-cycle", + "unicode": "e68a", + "unicode_decimal": 59018 + }, + { + "icon_id": "24881286", + "name": "weibo", + "font_class": "weibo", + "unicode": "e68b", + "unicode_decimal": 59019 + }, + { + "icon_id": "24881288", + "name": "videocam", + "font_class": "videocam", + "unicode": "e68c", + "unicode_decimal": 59020 + }, + { + "icon_id": "24881289", + "name": "download", + "font_class": "download", + "unicode": "e68d", + "unicode_decimal": 59021 + }, + { + "icon_id": "24879601", + "name": "help", + "font_class": "help", + "unicode": "e679", + "unicode_decimal": 59001 + }, + { + "icon_id": "24879602", + "name": "navigate-filled", + "font_class": "navigate-filled", + "unicode": "e67a", + "unicode_decimal": 59002 + }, + { + "icon_id": "24879603", + "name": "plusempty", + "font_class": "plusempty", + "unicode": "e67b", + "unicode_decimal": 59003 + }, + { + "icon_id": "24879604", + "name": "smallcircle", + "font_class": "smallcircle", + "unicode": "e67c", + "unicode_decimal": 59004 + }, + { + "icon_id": "24879605", + "name": "minus-filled", + "font_class": "minus-filled", + "unicode": "e67d", + "unicode_decimal": 59005 + }, + { + "icon_id": "24879606", + "name": "micoff", + "font_class": "micoff", + "unicode": "e67e", + "unicode_decimal": 59006 + }, + { + "icon_id": "24879588", + "name": "closeempty", + "font_class": "closeempty", + "unicode": "e66c", + "unicode_decimal": 58988 + }, + { + "icon_id": "24879589", + "name": "clear", + "font_class": "clear", + "unicode": "e66d", + "unicode_decimal": 58989 + }, + { + "icon_id": "24879590", + "name": "navigate", + "font_class": "navigate", + "unicode": "e66e", + "unicode_decimal": 58990 + }, + { + "icon_id": "24879591", + "name": "minus", + "font_class": "minus", + "unicode": "e66f", + "unicode_decimal": 58991 + }, + { + "icon_id": "24879592", + "name": "image", + "font_class": "image", + "unicode": "e670", + "unicode_decimal": 58992 + }, + { + "icon_id": "24879593", + "name": "mic", + "font_class": "mic", + "unicode": "e671", + "unicode_decimal": 58993 + }, + { + "icon_id": "24879594", + "name": "paperplane", + "font_class": "paperplane", + "unicode": "e672", + "unicode_decimal": 58994 + }, + { + "icon_id": "24879595", + "name": "close", + "font_class": "close", + "unicode": "e673", + "unicode_decimal": 58995 + }, + { + "icon_id": "24879596", + "name": "help-filled", + "font_class": "help-filled", + "unicode": "e674", + "unicode_decimal": 58996 + }, + { + "icon_id": "24879597", + "name": "plus-filled", + "font_class": "paperplane-filled", + "unicode": "e675", + "unicode_decimal": 58997 + }, + { + "icon_id": "24879598", + "name": "plus", + "font_class": "plus", + "unicode": "e676", + "unicode_decimal": 58998 + }, + { + "icon_id": "24879599", + "name": "mic-filled", + "font_class": "mic-filled", + "unicode": "e677", + "unicode_decimal": 58999 + }, + { + "icon_id": "24879600", + "name": "image-filled", + "font_class": "image-filled", + "unicode": "e678", + "unicode_decimal": 59000 + }, + { + "icon_id": "24855900", + "name": "locked-filled", + "font_class": "locked-filled", + "unicode": "e668", + "unicode_decimal": 58984 + }, + { + "icon_id": "24855901", + "name": "info", + "font_class": "info", + "unicode": "e669", + "unicode_decimal": 58985 + }, + { + "icon_id": "24855903", + "name": "locked", + "font_class": "locked", + "unicode": "e66b", + "unicode_decimal": 58987 + }, + { + "icon_id": "24855884", + "name": "camera-filled", + "font_class": "camera-filled", + "unicode": "e658", + "unicode_decimal": 58968 + }, + { + "icon_id": "24855885", + "name": "chat-filled", + "font_class": "chat-filled", + "unicode": "e659", + "unicode_decimal": 58969 + }, + { + "icon_id": "24855886", + "name": "camera", + "font_class": "camera", + "unicode": "e65a", + "unicode_decimal": 58970 + }, + { + "icon_id": "24855887", + "name": "circle", + "font_class": "circle", + "unicode": "e65b", + "unicode_decimal": 58971 + }, + { + "icon_id": "24855888", + "name": "checkmarkempty", + "font_class": "checkmarkempty", + "unicode": "e65c", + "unicode_decimal": 58972 + }, + { + "icon_id": "24855889", + "name": "chat", + "font_class": "chat", + "unicode": "e65d", + "unicode_decimal": 58973 + }, + { + "icon_id": "24855890", + "name": "circle-filled", + "font_class": "circle-filled", + "unicode": "e65e", + "unicode_decimal": 58974 + }, + { + "icon_id": "24855891", + "name": "flag", + "font_class": "flag", + "unicode": "e65f", + "unicode_decimal": 58975 + }, + { + "icon_id": "24855892", + "name": "flag-filled", + "font_class": "flag-filled", + "unicode": "e660", + "unicode_decimal": 58976 + }, + { + "icon_id": "24855893", + "name": "gear-filled", + "font_class": "gear-filled", + "unicode": "e661", + "unicode_decimal": 58977 + }, + { + "icon_id": "24855894", + "name": "home", + "font_class": "home", + "unicode": "e662", + "unicode_decimal": 58978 + }, + { + "icon_id": "24855895", + "name": "home-filled", + "font_class": "home-filled", + "unicode": "e663", + "unicode_decimal": 58979 + }, + { + "icon_id": "24855896", + "name": "gear", + "font_class": "gear", + "unicode": "e664", + "unicode_decimal": 58980 + }, + { + "icon_id": "24855897", + "name": "smallcircle-filled", + "font_class": "smallcircle-filled", + "unicode": "e665", + "unicode_decimal": 58981 + }, + { + "icon_id": "24855898", + "name": "map-filled", + "font_class": "map-filled", + "unicode": "e666", + "unicode_decimal": 58982 + }, + { + "icon_id": "24855899", + "name": "map", + "font_class": "map", + "unicode": "e667", + "unicode_decimal": 58983 + }, + { + "icon_id": "24855825", + "name": "refresh-filled", + "font_class": "refresh-filled", + "unicode": "e656", + "unicode_decimal": 58966 + }, + { + "icon_id": "24855826", + "name": "refresh", + "font_class": "refresh", + "unicode": "e657", + "unicode_decimal": 58967 + }, + { + "icon_id": "24855808", + "name": "cloud-upload", + "font_class": "cloud-upload", + "unicode": "e645", + "unicode_decimal": 58949 + }, + { + "icon_id": "24855809", + "name": "cloud-download-filled", + "font_class": "cloud-download-filled", + "unicode": "e646", + "unicode_decimal": 58950 + }, + { + "icon_id": "24855810", + "name": "cloud-download", + "font_class": "cloud-download", + "unicode": "e647", + "unicode_decimal": 58951 + }, + { + "icon_id": "24855811", + "name": "cloud-upload-filled", + "font_class": "cloud-upload-filled", + "unicode": "e648", + "unicode_decimal": 58952 + }, + { + "icon_id": "24855813", + "name": "redo", + "font_class": "redo", + "unicode": "e64a", + "unicode_decimal": 58954 + }, + { + "icon_id": "24855814", + "name": "images-filled", + "font_class": "images-filled", + "unicode": "e64b", + "unicode_decimal": 58955 + }, + { + "icon_id": "24855815", + "name": "undo-filled", + "font_class": "undo-filled", + "unicode": "e64c", + "unicode_decimal": 58956 + }, + { + "icon_id": "24855816", + "name": "more", + "font_class": "more", + "unicode": "e64d", + "unicode_decimal": 58957 + }, + { + "icon_id": "24855817", + "name": "more-filled", + "font_class": "more-filled", + "unicode": "e64e", + "unicode_decimal": 58958 + }, + { + "icon_id": "24855818", + "name": "undo", + "font_class": "undo", + "unicode": "e64f", + "unicode_decimal": 58959 + }, + { + "icon_id": "24855819", + "name": "images", + "font_class": "images", + "unicode": "e650", + "unicode_decimal": 58960 + }, + { + "icon_id": "24855821", + "name": "paperclip", + "font_class": "paperclip", + "unicode": "e652", + "unicode_decimal": 58962 + }, + { + "icon_id": "24855822", + "name": "settings", + "font_class": "settings", + "unicode": "e653", + "unicode_decimal": 58963 + }, + { + "icon_id": "24855823", + "name": "search", + "font_class": "search", + "unicode": "e654", + "unicode_decimal": 58964 + }, + { + "icon_id": "24855824", + "name": "redo-filled", + "font_class": "redo-filled", + "unicode": "e655", + "unicode_decimal": 58965 + }, + { + "icon_id": "24841702", + "name": "list", + "font_class": "list", + "unicode": "e644", + "unicode_decimal": 58948 + }, + { + "icon_id": "24841489", + "name": "mail-open-filled", + "font_class": "mail-open-filled", + "unicode": "e63a", + "unicode_decimal": 58938 + }, + { + "icon_id": "24841491", + "name": "hand-thumbsdown-filled", + "font_class": "hand-down-filled", + "unicode": "e63c", + "unicode_decimal": 58940 + }, + { + "icon_id": "24841492", + "name": "hand-thumbsdown", + "font_class": "hand-down", + "unicode": "e63d", + "unicode_decimal": 58941 + }, + { + "icon_id": "24841493", + "name": "hand-thumbsup-filled", + "font_class": "hand-up-filled", + "unicode": "e63e", + "unicode_decimal": 58942 + }, + { + "icon_id": "24841494", + "name": "hand-thumbsup", + "font_class": "hand-up", + "unicode": "e63f", + "unicode_decimal": 58943 + }, + { + "icon_id": "24841496", + "name": "heart-filled", + "font_class": "heart-filled", + "unicode": "e641", + "unicode_decimal": 58945 + }, + { + "icon_id": "24841498", + "name": "mail-open", + "font_class": "mail-open", + "unicode": "e643", + "unicode_decimal": 58947 + }, + { + "icon_id": "24841488", + "name": "heart", + "font_class": "heart", + "unicode": "e639", + "unicode_decimal": 58937 + }, + { + "icon_id": "24839963", + "name": "loop", + "font_class": "loop", + "unicode": "e633", + "unicode_decimal": 58931 + }, + { + "icon_id": "24839866", + "name": "pulldown", + "font_class": "pulldown", + "unicode": "e632", + "unicode_decimal": 58930 + }, + { + "icon_id": "24813798", + "name": "scan", + "font_class": "scan", + "unicode": "e62a", + "unicode_decimal": 58922 + }, + { + "icon_id": "24813786", + "name": "bars", + "font_class": "bars", + "unicode": "e627", + "unicode_decimal": 58919 + }, + { + "icon_id": "24813788", + "name": "cart-filled", + "font_class": "cart-filled", + "unicode": "e629", + "unicode_decimal": 58921 + }, + { + "icon_id": "24813790", + "name": "checkbox", + "font_class": "checkbox", + "unicode": "e62b", + "unicode_decimal": 58923 + }, + { + "icon_id": "24813791", + "name": "checkbox-filled", + "font_class": "checkbox-filled", + "unicode": "e62c", + "unicode_decimal": 58924 + }, + { + "icon_id": "24813794", + "name": "shop", + "font_class": "shop", + "unicode": "e62f", + "unicode_decimal": 58927 + }, + { + "icon_id": "24813795", + "name": "headphones", + "font_class": "headphones", + "unicode": "e630", + "unicode_decimal": 58928 + }, + { + "icon_id": "24813796", + "name": "cart", + "font_class": "cart", + "unicode": "e631", + "unicode_decimal": 58929 + } + ] +} 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..86e7444 --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue @@ -0,0 +1,96 @@ + + + + + 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..2f56eab --- /dev/null +++ b/uni_modules/uni-icons/components/uni-icons/uniicons.css @@ -0,0 +1,663 @@ +.uniui-color:before { + content: "\e6cf"; +} + +.uniui-wallet:before { + content: "\e6b1"; +} + +.uniui-settings-filled:before { + content: "\e6ce"; +} + +.uniui-auth-filled:before { + content: "\e6cc"; +} + +.uniui-shop-filled:before { + content: "\e6cd"; +} + +.uniui-staff-filled:before { + content: "\e6cb"; +} + +.uniui-vip-filled:before { + content: "\e6c6"; +} + +.uniui-plus-filled:before { + content: "\e6c7"; +} + +.uniui-folder-add-filled:before { + content: "\e6c8"; +} + +.uniui-color-filled:before { + content: "\e6c9"; +} + +.uniui-tune-filled:before { + content: "\e6ca"; +} + +.uniui-calendar-filled:before { + content: "\e6c0"; +} + +.uniui-notification-filled:before { + content: "\e6c1"; +} + +.uniui-wallet-filled:before { + content: "\e6c2"; +} + +.uniui-medal-filled:before { + content: "\e6c3"; +} + +.uniui-gift-filled:before { + content: "\e6c4"; +} + +.uniui-fire-filled:before { + content: "\e6c5"; +} + +.uniui-refreshempty:before { + content: "\e6bf"; +} + +.uniui-location-filled:before { + content: "\e6af"; +} + +.uniui-person-filled:before { + content: "\e69d"; +} + +.uniui-personadd-filled:before { + content: "\e698"; +} + +.uniui-back:before { + content: "\e6b9"; +} + +.uniui-forward:before { + content: "\e6ba"; +} + +.uniui-arrow-right:before { + content: "\e6bb"; +} + +.uniui-arrowthinright:before { + content: "\e6bb"; +} + +.uniui-arrow-left:before { + content: "\e6bc"; +} + +.uniui-arrowthinleft:before { + content: "\e6bc"; +} + +.uniui-arrow-up:before { + content: "\e6bd"; +} + +.uniui-arrowthinup:before { + content: "\e6bd"; +} + +.uniui-arrow-down:before { + content: "\e6be"; +} + +.uniui-arrowthindown:before { + content: "\e6be"; +} + +.uniui-bottom:before { + content: "\e6b8"; +} + +.uniui-arrowdown:before { + content: "\e6b8"; +} + +.uniui-right:before { + content: "\e6b5"; +} + +.uniui-arrowright:before { + content: "\e6b5"; +} + +.uniui-top:before { + content: "\e6b6"; +} + +.uniui-arrowup:before { + content: "\e6b6"; +} + +.uniui-left:before { + content: "\e6b7"; +} + +.uniui-arrowleft:before { + content: "\e6b7"; +} + +.uniui-eye:before { + content: "\e651"; +} + +.uniui-eye-filled:before { + content: "\e66a"; +} + +.uniui-eye-slash:before { + content: "\e6b3"; +} + +.uniui-eye-slash-filled:before { + content: "\e6b4"; +} + +.uniui-info-filled:before { + content: "\e649"; +} + +.uniui-reload:before { + content: "\e6b2"; +} + +.uniui-micoff-filled:before { + content: "\e6b0"; +} + +.uniui-map-pin-ellipse:before { + content: "\e6ac"; +} + +.uniui-map-pin:before { + content: "\e6ad"; +} + +.uniui-location:before { + content: "\e6ae"; +} + +.uniui-starhalf:before { + content: "\e683"; +} + +.uniui-star:before { + content: "\e688"; +} + +.uniui-star-filled:before { + content: "\e68f"; +} + +.uniui-calendar:before { + content: "\e6a0"; +} + +.uniui-fire:before { + content: "\e6a1"; +} + +.uniui-medal:before { + content: "\e6a2"; +} + +.uniui-font:before { + content: "\e6a3"; +} + +.uniui-gift:before { + content: "\e6a4"; +} + +.uniui-link:before { + content: "\e6a5"; +} + +.uniui-notification:before { + content: "\e6a6"; +} + +.uniui-staff:before { + content: "\e6a7"; +} + +.uniui-vip:before { + content: "\e6a8"; +} + +.uniui-folder-add:before { + content: "\e6a9"; +} + +.uniui-tune:before { + content: "\e6aa"; +} + +.uniui-auth:before { + content: "\e6ab"; +} + +.uniui-person:before { + content: "\e699"; +} + +.uniui-email-filled:before { + content: "\e69a"; +} + +.uniui-phone-filled:before { + content: "\e69b"; +} + +.uniui-phone:before { + content: "\e69c"; +} + +.uniui-email:before { + content: "\e69e"; +} + +.uniui-personadd:before { + content: "\e69f"; +} + +.uniui-chatboxes-filled:before { + content: "\e692"; +} + +.uniui-contact:before { + content: "\e693"; +} + +.uniui-chatbubble-filled:before { + content: "\e694"; +} + +.uniui-contact-filled:before { + content: "\e695"; +} + +.uniui-chatboxes:before { + content: "\e696"; +} + +.uniui-chatbubble:before { + content: "\e697"; +} + +.uniui-upload-filled:before { + content: "\e68e"; +} + +.uniui-upload:before { + content: "\e690"; +} + +.uniui-weixin:before { + content: "\e691"; +} + +.uniui-compose:before { + content: "\e67f"; +} + +.uniui-qq:before { + content: "\e680"; +} + +.uniui-download-filled:before { + content: "\e681"; +} + +.uniui-pyq:before { + content: "\e682"; +} + +.uniui-sound:before { + content: "\e684"; +} + +.uniui-trash-filled:before { + content: "\e685"; +} + +.uniui-sound-filled:before { + content: "\e686"; +} + +.uniui-trash:before { + content: "\e687"; +} + +.uniui-videocam-filled:before { + content: "\e689"; +} + +.uniui-spinner-cycle:before { + content: "\e68a"; +} + +.uniui-weibo:before { + content: "\e68b"; +} + +.uniui-videocam:before { + content: "\e68c"; +} + +.uniui-download:before { + content: "\e68d"; +} + +.uniui-help:before { + content: "\e679"; +} + +.uniui-navigate-filled:before { + content: "\e67a"; +} + +.uniui-plusempty:before { + content: "\e67b"; +} + +.uniui-smallcircle:before { + content: "\e67c"; +} + +.uniui-minus-filled:before { + content: "\e67d"; +} + +.uniui-micoff:before { + content: "\e67e"; +} + +.uniui-closeempty:before { + content: "\e66c"; +} + +.uniui-clear:before { + content: "\e66d"; +} + +.uniui-navigate:before { + content: "\e66e"; +} + +.uniui-minus:before { + content: "\e66f"; +} + +.uniui-image:before { + content: "\e670"; +} + +.uniui-mic:before { + content: "\e671"; +} + +.uniui-paperplane:before { + content: "\e672"; +} + +.uniui-close:before { + content: "\e673"; +} + +.uniui-help-filled:before { + content: "\e674"; +} + +.uniui-paperplane-filled:before { + content: "\e675"; +} + +.uniui-plus:before { + content: "\e676"; +} + +.uniui-mic-filled:before { + content: "\e677"; +} + +.uniui-image-filled:before { + content: "\e678"; +} + +.uniui-locked-filled:before { + content: "\e668"; +} + +.uniui-info:before { + content: "\e669"; +} + +.uniui-locked:before { + content: "\e66b"; +} + +.uniui-camera-filled:before { + content: "\e658"; +} + +.uniui-chat-filled:before { + content: "\e659"; +} + +.uniui-camera:before { + content: "\e65a"; +} + +.uniui-circle:before { + content: "\e65b"; +} + +.uniui-checkmarkempty:before { + content: "\e65c"; +} + +.uniui-chat:before { + content: "\e65d"; +} + +.uniui-circle-filled:before { + content: "\e65e"; +} + +.uniui-flag:before { + content: "\e65f"; +} + +.uniui-flag-filled:before { + content: "\e660"; +} + +.uniui-gear-filled:before { + content: "\e661"; +} + +.uniui-home:before { + content: "\e662"; +} + +.uniui-home-filled:before { + content: "\e663"; +} + +.uniui-gear:before { + content: "\e664"; +} + +.uniui-smallcircle-filled:before { + content: "\e665"; +} + +.uniui-map-filled:before { + content: "\e666"; +} + +.uniui-map:before { + content: "\e667"; +} + +.uniui-refresh-filled:before { + content: "\e656"; +} + +.uniui-refresh:before { + content: "\e657"; +} + +.uniui-cloud-upload:before { + content: "\e645"; +} + +.uniui-cloud-download-filled:before { + content: "\e646"; +} + +.uniui-cloud-download:before { + content: "\e647"; +} + +.uniui-cloud-upload-filled:before { + content: "\e648"; +} + +.uniui-redo:before { + content: "\e64a"; +} + +.uniui-images-filled:before { + content: "\e64b"; +} + +.uniui-undo-filled:before { + content: "\e64c"; +} + +.uniui-more:before { + content: "\e64d"; +} + +.uniui-more-filled:before { + content: "\e64e"; +} + +.uniui-undo:before { + content: "\e64f"; +} + +.uniui-images:before { + content: "\e650"; +} + +.uniui-paperclip:before { + content: "\e652"; +} + +.uniui-settings:before { + content: "\e653"; +} + +.uniui-search:before { + content: "\e654"; +} + +.uniui-redo-filled:before { + content: "\e655"; +} + +.uniui-list:before { + content: "\e644"; +} + +.uniui-mail-open-filled:before { + content: "\e63a"; +} + +.uniui-hand-down-filled:before { + content: "\e63c"; +} + +.uniui-hand-down:before { + content: "\e63d"; +} + +.uniui-hand-up-filled:before { + content: "\e63e"; +} + +.uniui-hand-up:before { + content: "\e63f"; +} + +.uniui-heart-filled:before { + content: "\e641"; +} + +.uniui-mail-open:before { + content: "\e643"; +} + +.uniui-heart:before { + content: "\e639"; +} + +.uniui-loop:before { + content: "\e633"; +} + +.uniui-pulldown:before { + content: "\e632"; +} + +.uniui-scan:before { + content: "\e62a"; +} + +.uniui-bars:before { + content: "\e627"; +} + +.uniui-cart-filled:before { + content: "\e629"; +} + +.uniui-checkbox:before { + content: "\e62b"; +} + +.uniui-checkbox-filled:before { + content: "\e62c"; +} + +.uniui-shop:before { + content: "\e62f"; +} + +.uniui-headphones:before { + content: "\e630"; +} + +.uniui-cart:before { + content: "\e631"; +} 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 0000000000000000000000000000000000000000..835f33bc9411461b8b9046b3fec742e921d6ce3a GIT binary patch literal 35760 zcmeFacbp?vl{Q?rN>WLsSXIigCAC7gI!S6tox^m`be^1}CwPJ>yxZ{uSzi{WC_=LI+*Wx!<-H!v})21fuKMZQ#fB2Fs zuEGwU_ZyDmuR3&e_s&PS@Be}0T=(JF$l;w=9Als0-iQ4lE^0cm^YDeWhnK#G<4!$@ z>-QZydhsP6Kl0Pv9Cw|EbP-?YO$@C;`+ zuKnR1zxV)MXnddfv56Dn_-W<%#_jZ^d%1f!hyI(6O8C!lXY}93nl=3f9^gzbYS03Jm0vJ;T)Z1IKntfUtypB#zx`e6wG3 zC5AhB&Me^QdH${3yL1otSUp#NN^cKN_yKnkm%XqxczWUgrT^Oo|6lL`SPy&+DZ_DX z1{?B^82rf|!cpSXHhg1*;kZecHy+MI*MqCu>g9T0eYieaf9edzAC9!tJL|pm0UQ~l zBQN;JaG!_sb8)VT%i=%By_I_#_ZIFh?(N(=xVtf?-^|^~y@`7RcMEqbcN=#*_eSmx z?)BVjxU0EqFm9T;Q`~9pTJAdTdhWH{>+qBtxEr~fxSP3Gb60T(xkKDx?g)33JH{R7 zPH-1465x0fg%5CGeb33>TxSiZCZa24wyO7(&Q z>$wfwMs5?gnVaOMxM^;NYvpFSIc_<(f-7(s&u0CxL#u8VbF$klItIryQ@x|5W z48lm`>dOtnnB(dz48rK+>MISxIOOW948n-y>Z=XH*yQSK48kbo>T3axcUVKK~8Y>od!W-aP?gVL3VKU-3CF5aP>U~L7s5+3k`x~;p%%0f{fwn z`wW7#;p+Phg52Ti2MmG);_4R}1X;w@scs-hC9Y0&13^AJNK#+l4o$3aH zH00`3HxT3^SEssxAR)Or)eQt$$+z7tkWDxWPSHIIBXb!IaW`m$ZxcXZRf;QpmZ#4*d zg{!~KAZQq_ewRVeHC+Ae20`m^^>-Kq{lnGoHVB%CtKVY~bP`v;*C1#ou700E&{JIf zeuJQ~xcWN{g6`t#?=lEljH|!fAm}r${tpI0vvKtY41$j1>hCcK+K#I~Xb|)sSAVZT z(12Y1eFi}na`pEc1g*%`|Ir}mN3Q+>gPp}tAE%avLosrF^GJG z`bQ0dZsqD9GYDFitAE@e=v%J-34@?{x%wv!f)3{DpE3yAn5#cz5cD!v|Fl8S&|Lj9 z20>SI_0JjvtVjlpxwFpV+N5QQ~$g{(D+>a3kE^= zbM-G81S^26f5{-&16=*f2Ej7m>R&MkHUd}wszKz<)E_qpb^}-cnn7g6)t@j3wggxI zxp1QBm2=klxXa|a&TVx+;Qp=WwVt{>D}O~9QXW)O>O0h5db_-@^8Ud$^pPT-1=NS-v_4k2r|_kM*0!vaW9xyNll~`AaKH zuPQxR4wv6t{%QC2?wh**v$DGKU?rS_5?F|crGafkiL7dNk-%Y_E4VmkSn6>Hb;SUukEx3l0# zej=BS$yT%Av8Uc*J`xpdRw>aQ5n{34Scli{%@0hjo|#!%t;CXMOO1~vM@By$$wu(0 z7+*JsbCF0c%-{dHFL+pQI~s3&zjaOf89{d%!`6o3fsCO(`6

+     logo +

+

uv-ui

+

兼容vue3+2多平台快速开发的UI框架

+ +[![star](https://gitee.com/climblee/uv-ui/badge/star.svg?theme=gvp)](https://gitee.com/climblee/uv-ui) +[![star](https://gitee.com/climblee/uv-ui/badge/fork.svg?theme=gvp)](https://gitee.com/climblee/uv-ui) +[![star](https://img.shields.io/github/stars/climblee/uv-ui?style=flat-square&logo=GitHub)](https://github.com/climblee/uv-ui) +[![issues](https://img.shields.io/github/issues/climblee/uv-ui?style=flat-square&logo=GitHub)](https://github.com/climblee/uv-ui/issues) +[![Website](https://img.shields.io/badge/uvui-up-blue?style=flat-square)](https://www.uvui.cn) +[![version](https://img.shields.io/badge/version-1.1.16-brightgreen.svg)](https://www.uvui.cn/components/changelog.html) +[![license](https://img.shields.io/github/license/climblee/uv-ui?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License) + +## 温馨提示:如需下载uv-ui示例项目,请不要使用【下载插件ZIP】按钮。 + +### uvui官方群1:549833913 +### uvui官方群2:206060892 + +## uvui特点 + +1. **uv-ui的前世今生**,`uv-ui` 是基于 `uview2.x` 版本改造而来。重命名也是为了避开发布冲突和很多组件 `u-`在 `nvue` 中不能使用的情况,所以这才诞生了`uv-ui`。感谢 `uview-ui` 作者的开源奉献,再次为开源点赞。 同时 `uv-ui` 也是无条件开源。 + +2. **全端兼容**,`uv-ui`支持vue3、vue2、app-vue、app-nvue、h5、小程序等。`uv-ui`的组件都是多端自适应的,底层会抹平很多小程序平台的差异或bug。 + +3. **扩展配置**,`uv-ui`内置的方法默认不再挂载到`uni`对象之上,也就意味着默认情况下不能在项目中直接使用`uni.$uv.xxx`使用内置方法。但是可以通过扩展可以解决,通过如下方式进行配置即可,使用方式请参考[扩展配置](https://www.uvui.cn/components/setting.html)。其中包括[ JS工具库](https://www.uvui.cn/components/setting.html#%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE-js%E5%B7%A5%E5%85%B7%E5%BA%93)、[ 自定义主题](https://www.uvui.cn/components/setting.html#%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE-%E8%87%AA%E5%AE%9A%E4%B9%89%E4%B8%BB%E9%A2%98)、[ 基础样式](https://www.uvui.cn/components/setting.html#%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE-%E5%9F%BA%E7%A1%80%E6%A0%B7%E5%BC%8F)、[ setconfig](https://www.uvui.cn/components/setting.html#%E6%89%A9%E5%B1%95%E9%85%8D%E7%BD%AE-setconfig)等。 + +## 预览 + +通过微信(APP下载不支持微信扫码)或浏览器扫码查看演示效果。 + +         + +## 链接 + +- [官方文档](https://www.uvui.cn) +- [演示地址](https://h5.uvui.cn) +- [更新日志](https://www.uvui.cn/components/changelog.html) +- [关于我们](https://www.uvui.cn/cooperation/about.html) +- 组件列表 + +## 交流反馈 + +欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uvui.cn/components/addQQGroup.html) + +## 快速开始 + +方式一:`uv-ui` 强烈建议通过 `下载插件并导入HbuilderX` 导入组件。 + +方式二:下载完整 [uv-ui项目](https://ext.dcloud.net.cn/plugin?id=12287) 将 `uni_modules` 复制到自己的项目。 + +方式三:通过 `npm i @climblee/uv-ui` 下载,此方法需要配置 easycom,配置详情可查看[安装](https://www.uvui.cn/components/install.html)。 + +请通过[快速上手](https://www.uvui.cn/components/quickstart.html)了解更详细的内容。 + +**注意:导入插件后,建议`HBuilderX`重新运行项目,可能新导入的插件不能实时更新而导致不能运行。** + +## 使用方法 + +组件导入 `uni_modules` 后,直接在项目中使用,无需通过import引入组件。 + +```html + +``` + +## 扩展功能 + +`uv-ui` 内置了强大的工具函数、请求封装等,可以根据自身需求进行扩展配置,详情请查看[扩展配置](https://www.uvui.cn/components/setting.html)。 + +**注意:只有[扩展配置](https://www.uvui.cn/components/setting.html)后才能在自己的项目页面中使用组件库内置方法和变量等**。 + +
+ +## 组件列表 + +下表为 `uv-ui` 的扩展组件清单,点击每个组件**点击下载&安装**即可在详情页面导入组件到项目下,导入后建议重新运行即可直接使用,组件无需import和注册。 + +| 组件名 | 组件说明 | +| --- | --- | +| uv-skeletons | [新版骨架屏(推荐)](https://www.uvui.cn/components/skeletons.html) | +| uv-calendars | [新版日历(推荐)](https://www.uvui.cn/components/calendars.html) | +| uv-drop-down | [下拉筛选](https://www.uvui.cn/components/dropDown.html) | +| uv-scroll-list | [横向滚动列表](https://www.uvui.cn/components/scrollList.html) | +| uv-vtabs | [垂直选项卡](https://www.uvui.cn/components/vtabs.html) | +| uv-pick-color | [颜色选择器](https://www.uvui.cn/components/pickColor.html) | +| uv-qrcode | [二维码](https://www.uvui.cn/components/qrcode.html) | +| uv-waterfall | [瀑布流](https://www.uvui.cn/components/waterfall.html) | +| uv-row | [Layout 布局](https://www.uvui.cn/components/layout.html) | +| uv-icon | [图标](https://www.uvui.cn/components/icon.html) | +| uv-button | [按钮](https://www.uvui.cn/components/button.html) | +| uv-text | [文本](https://www.uvui.cn/components/text.html) | +| uv-link | [超链接](https://www.uvui.cn/components/link.html) | +| uv-image | [图片](https://www.uvui.cn/components/image.html) | +| uv-transition | [动画](https://www.uvui.cn/components/transition.html) | +| uv-form | [表单](https://www.uvui.cn/components/form.html) | +| uv-input | [增强输入框](https://www.uvui.cn/components/input.html) | +| uv-textarea | [增强文本域](https://www.uvui.cn/components/textarea.html) | +| uv-checkbox | [复选框](https://www.uvui.cn/components/checkbox.html) | +| uv-radio | [单选框](https://www.uvui.cn/components/radio.html) | +| uv-switch | [开关选择器](https://www.uvui.cn/components/switch.html) | +| uv-calendar | [日历](https://www.uvui.cn/components/calendar.html) | +| uv-picker | [选择器](https://www.uvui.cn/components/picker.html) | +| uv-datetime-picker | [时间选择器](https://www.uvui.cn/components/datetimePicker.html) | +| uv-code | [验证码倒计时](https://www.uvui.cn/components/code.html) | +| uv-keyboard | [键盘](https://www.uvui.cn/components/keyboard.html) | +| uv-rate | [评分](https://www.uvui.cn/components/rate.html) | +| uv-search | [多功能搜索框](https://www.uvui.cn/components/search.html) | +| uv-number-box | [步进器](https://www.uvui.cn/components/numberBox.html) | +| uv-upload | [上传](https://www.uvui.cn/components/upload.html) | +| uv-slider | [滑动选择器](https://www.uvui.cn/components/slider.html) | +| uv-list | [列表](https://www.uvui.cn/components/list.html) | +| uv-index-list | [索引列表](https://www.uvui.cn/components/indexList.html) | +| uv-tags | [标签](https://www.uvui.cn/components/tag.html) | +| uv-line-progress | [线形进度条](https://www.uvui.cn/components/lineProgress.html) | +| uv-badge | [徽标数](https://www.uvui.cn/components/badge.html) | +| uv-count-down | [倒计时](https://www.uvui.cn/components/countDown.html) | +| uv-count-to | [数字滚动](https://www.uvui.cn/components/countTo.html) | +| uv-avatar | [头像](https://www.uvui.cn/components/avatar.html) | +| uv-skeleton | [骨架屏](https://www.uvui.cn/components/skeleton.html) | +| uv-loading-icon | [加载动画](https://www.uvui.cn/components/loadingIcon.html) | +| uv-loading-page | [加载页](https://www.uvui.cn/components/loadingPage.html) | +| uv-load-more | [加载更多](https://www.uvui.cn/components/loadMore.html) | +| uv-empty | [内容为空](https://www.uvui.cn/components/empty.html) | +| uv-tooltip | [长按提示](https://www.uvui.cn/components/tooltip.html) | +| uv-alert | [警告提示](https://www.uvui.cn/components/alert.html) | +| uv-toast | [消息提示](https://www.uvui.cn/components/toast.html) | +| uv-notice-bar | [滚动通知](https://www.uvui.cn/components/noticeBar.html) | +| uv-notify | [消息提示](https://www.uvui.cn/components/notify.html) | +| uv-no-network | [无网络提示](https://www.uvui.cn/components/noNetwork.html) | +| uv-popup | [弹出层](https://www.uvui.cn/components/popup.html) | +| uv-modal | [模态框](https://www.uvui.cn/components/modal.html) | +| uv-cell | [单元格](https://www.uvui.cn/components/cell.html) | +| uv-swipe-action | [滑动单元格](https://www.uvui.cn/components/swipeAction.html) | +| uv-swiper | [轮播图](https://www.uvui.cn/components/swiper.html) | +| uv-collapse | [折叠面板](https://www.uvui.cn/components/collapse.html) | +| uv-grid | [宫格布局](https://www.uvui.cn/components/grid.html) | +| uv-album | [相册](https://www.uvui.cn/components/album.html) | +| uv-tabbar | [底部导航栏](https://www.uvui.cn/components/tabbar.html) | +| uv-back-top | [返回顶部](https://www.uvui.cn/components/backTop.html) | +| uv-navbar | [自定义导航栏](https://www.uvui.cn/components/navbar.html) | +| uv-action-sheet | [底部操作菜单](https://www.uvui.cn/components/actionSheet.html) | +| uv-tabs | [标签选项卡](https://www.uvui.cn/components/tabs.html) | +| uv-steps | [步骤条](https://www.uvui.cn/components/steps.html) | +| uv-subsection | [分段器](https://www.uvui.cn/components/subsection.html) | +| uv-sticky | [吸顶](https://www.uvui.cn/components/sticky.html) | +| uv-parse | [富文本解析器](https://www.uvui.cn/components/parse.html) | +| uv-overlay | [遮罩层](https://www.uvui.cn/components/overlay.html) | +| uv-code-input | [验证码输入](https://www.uvui.cn/components/codeInput.html) | +| uv-read-more | [展开阅读更多](https://www.uvui.cn/components/readMore.html) | +| uv-line | [线条](https://www.uvui.cn/components/line.html) | +| uv-gap | [间隔槽](https://www.uvui.cn/components/gap.html) | +| uv-divider | [分割线](https://www.uvui.cn/components/divider.html) | + +## 版权信息 +uv-ui遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uv-ui应用到您的产品中。 + +## 作者想说 +- 开源真的不易,不图大家的钱财,所以希望大家多多鼓励支持,希望不要恶意评论,有问题加群快速解决。 +- 遇到BUG,是一件很正常的事情,是程序肯定就有BUG,所以希望大家能以理解的心态去提出BUG,然后作者才有动力去努力修复。 +- 最后觉得好用的小伙伴,不要吝啬你的双手,给个好评就是给我们最大的鼓励。 + +# 恶评者手下留情,有事加QQ群解决:549833913 \ No newline at end of file diff --git a/uni_modules/uv-upload/changelog.md b/uni_modules/uv-upload/changelog.md new file mode 100644 index 0000000..dfcefe7 --- /dev/null +++ b/uni_modules/uv-upload/changelog.md @@ -0,0 +1,17 @@ +## 1.0.6(2023-12-20) +1. 修复动态设置deletable为false不生效的BUG +## 1.0.5(2023-08-31) +1. 添加uv-popup依赖 +## 1.0.4(2023-08-18) +1. 修复图片预览位置错误的BUG +2. 修复视频预览不生效的BUG +3. 修复改变上传视频宽高不生效的BUG +## 1.0.3(2023-07-03) +去除插槽判断,避免某些平台不显示的BUG +## 1.0.2(2023-05-24) +1. 优化fileList,watch中增加deep属性 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-upload 上传 diff --git a/uni_modules/uv-upload/components/uv-preview-video/uv-preview-video.vue b/uni_modules/uv-upload/components/uv-preview-video/uv-preview-video.vue new file mode 100644 index 0000000..327c680 --- /dev/null +++ b/uni_modules/uv-upload/components/uv-preview-video/uv-preview-video.vue @@ -0,0 +1,52 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-upload/components/uv-upload/mixin.js b/uni_modules/uv-upload/components/uv-upload/mixin.js new file mode 100644 index 0000000..13ab0d2 --- /dev/null +++ b/uni_modules/uv-upload/components/uv-upload/mixin.js @@ -0,0 +1,22 @@ +import { error } from '@/uni_modules/uv-ui-tools/libs/function/index.js' +export default { + watch: { + // 监听accept的变化,判断是否符合个平台要求 + // 只有微信小程序才支持选择媒体,文件类型,所以这里做一个判断提示 + accept: { + immediate: true, + handler(val) { + // #ifndef MP-WEIXIN + if (val === 'all' || val === 'media') { + error('只有微信小程序才支持把accept配置为all、media之一') + } + // #endif + // #ifndef H5 || MP-WEIXIN + if (val === 'file') { + error('只有微信小程序和H5(HX2.9.9)才支持把accept配置为file') + } + // #endif + } + } + } +} diff --git a/uni_modules/uv-upload/components/uv-upload/props.js b/uni_modules/uv-upload/components/uv-upload/props.js new file mode 100644 index 0000000..2aad7b6 --- /dev/null +++ b/uni_modules/uv-upload/components/uv-upload/props.js @@ -0,0 +1,130 @@ +export default { + props: { + // 接受的文件类型, 可选值为all media image file video + accept: { + type: String, + default: 'image' + }, + // 图片或视频拾取模式,当accept为image类型时设置capture可选额外camera可以直接调起摄像头 + capture: { + type: [String, Array], + default: () => ['album', 'camera'] + }, + // 当accept为video时生效,是否压缩视频,默认为true + compressed: { + type: Boolean, + default: true + }, + // 当accept为video时生效,可选值为back或front + camera: { + type: String, + default: 'back' + }, + // 当accept为video时生效,拍摄视频最长拍摄时间,单位秒 + maxDuration: { + type: Number, + default: 60 + }, + // 上传区域的图标,只能内置图标 + uploadIcon: { + type: String, + default: 'camera-fill' + }, + // 上传区域的图标的颜色,默认 + uploadIconColor: { + type: String, + default: '#D3D4D6' + }, + // 是否开启文件读取前事件 + useBeforeRead: { + type: Boolean, + default: false + }, + // 读取后的处理函数 + afterRead: { + type: Function, + default: null + }, + // 读取前的处理函数 + beforeRead: { + type: Function, + default: null + }, + // 是否开启图片预览功能 + previewFullImage: { + type: Boolean, + default: true + }, + // 是否开启视频预览功能 + previewFullVideo: { + type: Boolean, + default: true + }, + // 最大上传数量 + maxCount: { + type: [String, Number], + default: 52 + }, + // 是否禁用 + disabled: { + type: Boolean, + default: false + }, + // 预览上传的图片时的裁剪模式,和image组件mode属性一致 + imageMode: { + type: String, + default: 'aspectFill' + }, + // 标识符,可以在回调函数的第二项参数中获取 + name: { + type: String, + default: '' + }, + // 所选的图片的尺寸, 可选值为original compressed + sizeType: { + type: Array, + default: () => ['original', 'compressed'] + }, + // 是否开启图片多选,部分安卓机型不支持 + multiple: { + type: Boolean, + default: false + }, + // 是否展示删除按钮 + deletable: { + type: Boolean, + default: true + }, + // 文件大小限制,单位为byte + maxSize: { + type: [String, Number], + default: Number.MAX_VALUE + }, + // 显示已上传的文件列表 + fileList: { + type: Array, + default: () => [] + }, + // 上传区域的提示文字 + uploadText: { + type: String, + default: '' + }, + // 内部预览图片区域和选择图片按钮的区域宽度 + width: { + type: [String, Number], + default: 80 + }, + // 内部预览图片区域和选择图片按钮的区域高度 + height: { + type: [String, Number], + default: 80 + }, + // 是否在上传完成后展示预览图 + previewImage: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.upload + } +} \ No newline at end of file diff --git a/uni_modules/uv-upload/components/uv-upload/utils.js b/uni_modules/uv-upload/components/uv-upload/utils.js new file mode 100644 index 0000000..88cb602 --- /dev/null +++ b/uni_modules/uv-upload/components/uv-upload/utils.js @@ -0,0 +1,151 @@ +function pickExclude(obj, keys) { + // 某些情况下,type可能会为 + if (!['[object Object]', '[object File]'].includes(Object.prototype.toString.call(obj))) { + return {} + } + return Object.keys(obj).reduce((prev, key) => { + if (!keys.includes(key)) { + prev[key] = obj[key] + } + return prev + }, {}) +} + +function formatImage(res) { + return res.tempFiles.map((item) => ({ + ...pickExclude(item, ['path']), + type: 'image', + url: item.path, + thumb: item.path, + size: item.size, + // #ifdef H5 + name: item.name + // #endif + })) +} + +function formatVideo(res) { + return [ + { + ...pickExclude(res, ['tempFilePath', 'thumbTempFilePath', 'errMsg']), + type: 'video', + url: res.tempFilePath, + thumb: res.thumbTempFilePath, + size: res.size, + // #ifdef H5 + name: res.name + // #endif + } + ] +} + +function formatMedia(res) { + return res.tempFiles.map((item) => ({ + ...pickExclude(item, ['fileType', 'thumbTempFilePath', 'tempFilePath']), + type: res.type, + url: item.tempFilePath, + thumb: res.type === 'video' ? item.thumbTempFilePath : item.tempFilePath, + size: item.size + })) +} + +function formatFile(res) { + return res.tempFiles.map((item) => ({ + ...pickExclude(item, ['path']), + url: item.path, + size:item.size, + // #ifdef H5 + name: item.name, + type: item.type + // #endif + })) +} +export function chooseFile({ + accept, + multiple, + capture, + compressed, + maxDuration, + sizeType, + camera, + maxCount +}) { + return new Promise((resolve, reject) => { + switch (accept) { + case 'image': + uni.chooseImage({ + count: multiple ? Math.min(maxCount, 9) : 1, + sourceType: capture, + sizeType, + success: (res) => resolve(formatImage(res)), + fail: reject + }) + break + // #ifdef MP-WEIXIN + // 只有微信小程序才支持chooseMedia接口 + case 'media': + wx.chooseMedia({ + count: multiple ? Math.min(maxCount, 9) : 1, + sourceType: capture, + maxDuration, + sizeType, + camera, + success: (res) => resolve(formatMedia(res)), + fail: reject + }) + break + // #endif + case 'video': + uni.chooseVideo({ + sourceType: capture, + compressed, + maxDuration, + camera, + success: (res) => resolve(formatVideo(res)), + fail: reject + }) + break + // #ifdef MP-WEIXIN || H5 + // 只有微信小程序才支持chooseMessageFile接口 + case 'file': + // #ifdef MP-WEIXIN + wx.chooseMessageFile({ + count: multiple ? maxCount : 1, + type: accept, + success: (res) => resolve(formatFile(res)), + fail: reject + }) + // #endif + // #ifdef H5 + // 需要hx2.9.9以上才支持uni.chooseFile + uni.chooseFile({ + count: multiple ? maxCount : 1, + type: accept, + success: (res) => resolve(formatFile(res)), + fail: reject + }) + // #endif + break + // #endif + default: + // 此为保底选项,在accept不为上面任意一项的时候选取全部文件 + // #ifdef MP-WEIXIN + wx.chooseMessageFile({ + count: multiple ? maxCount : 1, + type: 'all', + success: (res) => resolve(formatFile(res)), + fail: reject + }) + // #endif + // #ifdef H5 + // 需要hx2.9.9以上才支持uni.chooseFile + uni.chooseFile({ + count: multiple ? maxCount : 1, + type: 'all', + success: (res) => resolve(formatFile(res)), + fail: reject + }) + // #endif + } + }) +} diff --git a/uni_modules/uv-upload/components/uv-upload/uv-upload.vue b/uni_modules/uv-upload/components/uv-upload/uv-upload.vue new file mode 100644 index 0000000..55f579e --- /dev/null +++ b/uni_modules/uv-upload/components/uv-upload/uv-upload.vue @@ -0,0 +1,492 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-upload/package.json b/uni_modules/uv-upload/package.json new file mode 100644 index 0000000..b29dbb0 --- /dev/null +++ b/uni_modules/uv-upload/package.json @@ -0,0 +1,90 @@ +{ + "id": "uv-upload", + "displayName": "uv-upload 上传 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.6", + "description": "该组件用于上传图片等文件场景。", + "keywords": [ + "uv-upload", + "uvui", + "uv-ui", + "upload", + "上传" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon", + "uv-loading-icon", + "uv-popup" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-upload/readme.md b/uni_modules/uv-upload/readme.md new file mode 100644 index 0000000..de4aedf --- /dev/null +++ b/uni_modules/uv-upload/readme.md @@ -0,0 +1,11 @@ +## Upload 上传 + +> **组件名:uv-upload** + +该组件用于上传图片等文件场景。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/uni_modules/uv-vtabs/changelog.md b/uni_modules/uv-vtabs/changelog.md new file mode 100644 index 0000000..4d73568 --- /dev/null +++ b/uni_modules/uv-vtabs/changelog.md @@ -0,0 +1,20 @@ +## 1.0.8(2023-12-20) +1. 优化 +## 1.0.7(2023-12-20) +1. 优化 +## 1.0.6(2023-12-12) +1. 修复设置current,快速点击菜单,导致死循环的BUG +## 1.0.5(2023-06-27) +修复:非联动,内容过多的情况,滚动一段距离,再切换未滚动到顶部的BUG +## 1.0.4(2023-06-13) +1. 增加scrolltolower回调函数 +2. 优化 +## 1.0.3(2023-06-13) +1. 优化 +## 1.0.2(2023-06-13) +1. 增加hdHeight参数,避免顶部有内容计算联动不准确的BUG +2. 优化滑动触发频率,避免跳动 +## 1.0.1(2023-06-04) +1. 文档说明 +## 1.0.0(2023-06-04) +1. 新增垂直选项卡组件 diff --git a/uni_modules/uv-vtabs/components/uv-vtabs-item/uv-vtabs-item.vue b/uni_modules/uv-vtabs/components/uv-vtabs-item/uv-vtabs-item.vue new file mode 100644 index 0000000..286dc8c --- /dev/null +++ b/uni_modules/uv-vtabs/components/uv-vtabs-item/uv-vtabs-item.vue @@ -0,0 +1,68 @@ + + diff --git a/uni_modules/uv-vtabs/components/uv-vtabs/props.js b/uni_modules/uv-vtabs/components/uv-vtabs/props.js new file mode 100644 index 0000000..a64dce8 --- /dev/null +++ b/uni_modules/uv-vtabs/components/uv-vtabs/props.js @@ -0,0 +1,79 @@ +export default { + props: { + // 列表数据 + list: { + type: Array, + default: ()=>[] + }, + // 从list元素对象中读取的键名,默认name + keyName: { + type: String, + default: 'name' + }, + // 当前选中项 + current: { + type: [Number, String], + default: 0 + }, + // 头部内容的高度 + hdHeight: { + type: [Number, String], + default: 0 + }, + // 是否联动,默认开启联动 + chain: { + type: Boolean, + default: true + }, + // 整个列表的高度,默认auto屏幕高度 + height: { + type: [Number, String], + default: 'auto' + }, + // 左边列表的宽度,默认200rpx + barWidth: { + type: [Number, String], + default: '180rpx' + }, + // 左边列表是否允许滚动 + barScrollable: { + type: Boolean, + default: true + }, + // 背景颜色 默认主题颜色 $bg-color + barBgColor: { + type: String, + default: '' + }, + // 左边列表的自定义样式 + barStyle: { + type: [Object, String], + default: '' + }, + // 左边列表项的自定义样式 + barItemStyle: { + type: [Object, String], + default: '' + }, + // 左边选择项激活时的自定义样式 + barItemActiveStyle: { + type: [Object, String], + default: '' + }, + // 左边选择项激活时的左边线条自定义样式 + barItemActiveLineStyle: { + type: [Object, String], + default: '' + }, + // 菜单项中的徽标自定义样式,比如定位位置 + barItemBadgeStyle: { + type: [Object, String], + default: '' + }, + // 右边区域自定义样式 + contentStyle: { + type: [Object, String], + default: '' + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-vtabs/components/uv-vtabs/uv-vtabs.vue b/uni_modules/uv-vtabs/components/uv-vtabs/uv-vtabs.vue new file mode 100644 index 0000000..cd23320 --- /dev/null +++ b/uni_modules/uv-vtabs/components/uv-vtabs/uv-vtabs.vue @@ -0,0 +1,438 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-vtabs/package.json b/uni_modules/uv-vtabs/package.json new file mode 100644 index 0000000..9848beb --- /dev/null +++ b/uni_modules/uv-vtabs/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-vtabs", + "displayName": "uv-vtabs 垂直选项卡 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.8", + "description": "uv-vtabs 垂直分类组件主要用于分类选择,简单配置即可使用,左右自动进行联动,不用自己再去做复杂的计算,组件内部已经完成相关计算。支持联动和不联动,商品分类,灵活配置,多端兼容开箱即用。", + "keywords": [ + "uv-vtabs", + "uvui", + "uv-ui", + "垂直分类", + "垂直选项卡" +], + "repository": "", +"engines": { + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-badge" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-vtabs/readme.md b/uni_modules/uv-vtabs/readme.md new file mode 100644 index 0000000..812b10c --- /dev/null +++ b/uni_modules/uv-vtabs/readme.md @@ -0,0 +1,19 @@ +## Vtabs 垂直选项卡 + +> **组件名:uv-vtabs** + +该组件主要用于分类选择,开箱即用,简单配置参数即可使用,左右自动进行联动,不用自己再去做复杂的计算,组件内部已经完成相关计算。联动和不联动两种可选方式,联动-左右均可滚动,不联动-右边区域只会在选中时显示。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-waterfall/changelog.md b/uni_modules/uv-waterfall/changelog.md new file mode 100644 index 0000000..18f9162 --- /dev/null +++ b/uni_modules/uv-waterfall/changelog.md @@ -0,0 +1,24 @@ +## 1.0.8(2023-08-17) +1. 修复只有一条数据切换时可能存在位置错误的BUG +## 1.0.7(2023-07-22) +1. 避免快速切换报错的BUG +## 1.0.6(2023-07-17) +1. 优化文档 +2. 优化其他 +## 1.0.5(2023-07-14) +1. 优化changeList未处理数据时,正确返回对应列的数据,避免误导 +## 1.0.4(2023-05-27) +1. 修复在百度小程序中可能存在的BUG +2. 去掉原有的slot方式 +## 1.0.3(2023-05-23) +1. 修复在百度/头条小程序显示异常等BUG +2. 增加changeList回调函数处理数据 +3. 更新示例 +## 1.0.2(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.1(2023-05-12) +1. 增加clear回调函数 +2. 增加remove回调函数 +## 1.0.0(2023-05-10) +uv-waterfall 瀑布流 diff --git a/uni_modules/uv-waterfall/components/uv-waterfall/props.js b/uni_modules/uv-waterfall/components/uv-waterfall/props.js new file mode 100644 index 0000000..de8cb8f --- /dev/null +++ b/uni_modules/uv-waterfall/components/uv-waterfall/props.js @@ -0,0 +1,69 @@ +export default { + props: { + // 瀑布流数据 + // #ifdef VUE2 + value: { + type: Array, + default: () => [] + }, + // #endif + // #ifdef VUE3 + modelValue: { + type: Array, + default: () => [] + }, + // #endif + // 数据的id值,根据id值对数据执行删除操作 + // 如数据为:{id: 1, name: 'uv-ui'},那么该值设置为id + idKey: { + type: String, + default: 'id' + }, + // 每次插入数据的事件间隔,间隔越长能保证两列高度相近,但是用户体验不好,单位ms + addTime: { + type: Number, + default: 200 + }, + // 瀑布流的列数,默认2,最高为5 + columnCount: { + type: [Number, String], + default: 2 + }, + // 列与列的间隙,默认20 + columnGap: { + type: [Number, String], + default: 20 + }, + // 左边和列表的间隙 + leftGap: { + type: [Number, String], + default: 0 + }, + // 右边和列表的间隙 + rightGap: { + type: [Number, String], + default: 0 + }, + // 是否显示滚动条,仅nvue生效 + showScrollbar: { + type: [Boolean], + default: false + }, + // 列宽,nvue生效 + columnWidth: { + type: [Number, String], + default: 'auto' + }, + // 瀑布流的宽度,nvue生效 + width: { + type: [Number, String], + default: '' + }, + // 瀑布流的高度,nvue生效 + height: { + type: [Number, String], + default: '' + }, + ...uni.$uv?.props?.waterfall + } +} \ No newline at end of file diff --git a/uni_modules/uv-waterfall/components/uv-waterfall/uv-waterfall.vue b/uni_modules/uv-waterfall/components/uv-waterfall/uv-waterfall.vue new file mode 100644 index 0000000..cfb3ebc --- /dev/null +++ b/uni_modules/uv-waterfall/components/uv-waterfall/uv-waterfall.vue @@ -0,0 +1,265 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-waterfall/package.json b/uni_modules/uv-waterfall/package.json new file mode 100644 index 0000000..9a2bbfc --- /dev/null +++ b/uni_modules/uv-waterfall/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-waterfall", + "displayName": "uv-waterfall 瀑布流 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.8", + "description": "该组件主要用于瀑布流式布局显示,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部,同时集成nvue的原生瀑布流。", + "keywords": [ + "uv-waterfall", + "uvui", + "uv-ui", + "waterfall", + "瀑布流" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-image", + "uv-loading-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-waterfall/readme.md b/uni_modules/uv-waterfall/readme.md new file mode 100644 index 0000000..b043b85 --- /dev/null +++ b/uni_modules/uv-waterfall/readme.md @@ -0,0 +1,19 @@ +## Waterfall 瀑布流 + +> **组件名:uv-waterfall** + +该组件主要用于瀑布流式布局显示,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部,同时集成`nvue`的原生瀑布流用于`app-nvue`。常用于一些电商商品展示等,如某宝首页、x红书等。 + +研究uniapp瀑布流多年,**该方式是目前小程序端最佳方案**,灵活配置,简单易用,开箱即用。 + +该插件请根据文档耐心查看,`vue`的写法稍微麻烦点,但是效果是很好的,比之前上线的两个版本的瀑布流适用,更有扩展性,我自己的上线项目也是用的此插件。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 diff --git a/uni_modules/v-tabs/changelog.md b/uni_modules/v-tabs/changelog.md new file mode 100644 index 0000000..7a4039c --- /dev/null +++ b/uni_modules/v-tabs/changelog.md @@ -0,0 +1,143 @@ +## 2.1.9(2024-06-14) +1. [修改]当`current`初始值大于`tabs.length`或者小于`0`,自动设置`current`的值为`0` +2. [抛弃]压缩包方式的源码不提供维护了,只维护`uni_modules`中的源码 +## 2.1.8(2024-06-07) +1. [新增]支持`vue3`了 +## 2.1.6(2024-06-06) +1. [修复]当有`fixed`属性之后,在支付宝小程序无法滚动的bug +## 2.1.5(2023-11-02) +1. [修复]修复`change`和`v-model`绑定的值不同步 +2. [修复]暂时停用`activeFontSize`选项 +3. [修改]修改默认激活的文字不加粗 +## 2.1.4(2023-10-12) +1. [修改]修改计算方式 +2. [新增]外部可以通过`this.$refs.tabs.update()`方法主动更新 +## 2.1.3(2023-09-11) +1. [新增]支持自定义插槽模式,具体可以查看示例代码使用方式。[gitee demo](https://github.com/xfjpeter/uni-plugins/blob/3e2bd062163f664889122fd74b8bd6ccad6a97f1/pages/tabs/tabs.vue#L47C10-L50C16) 或 [github demo](https://github.com/xfjpeter/uni-plugins/blob/3e2bd062163f664889122fd74b8bd6ccad6a97f1/pages/tabs/tabs.vue#L47C10-L50C16) +## 2.1.2(2023-06-12) +1. [新增]添加`z-index`参数控制层级大小,默认1993 +2. [说明]以后该插件只更新`uni_modules`方式的,`zip`方式的不提供更新了 +## 2.1.1(2022-09-16) +1. 将插件更新为`uni_modules`方式 +## 2.1.0(2022-08-12) +1. 增加`disable`参数,控制是否可以点击,只能应用在数组对象中,见[disabled 的用法](#112-当tabs使用的数组对象的方式特定参数需要注意一下) + +```js +export default { + data() { + return { + tabs: [{ id: 1, name: '' }] + } + } +} +``` + +## 2.0.10(2022-01-27) + +1. 更新属性line-animation设置为false可以不要动画,这是好多朋友问到,特此加上 + +## 2.0.9(2020-10-12) + +1. 修复 v-tabs 第一次可能出现第一个标签显示不完整的情况 +2. 修改了 pages/tabs/order 示例文件 + +## 2.0.8(2020-09-21) + +1. 修复添加 fixed 属性后,滚动条无效 +2. 修复选项很少的情况下,下划线计算计算错误 +3. 新增 paddingItem 属性,设置选项左右边距(上下边距需要设置 height 属性,或者设置 padding 属性) + +## 2.0.7(2020-09-17) + +1. 紧急修复 bug,横向滑动不了的情况 + +## 2.0.6(2020-09-16) + +1. 新增 fixed 属性,是否固定在顶部,示例地址:pages/tabs/tabs-static +2. 优化之前的页面结构 + +## 2.0.5(2020-09-09) + +1. 修复 width 错误,dom 加载的时候没有及时获取到 data 属性导致的 。 + +## 2.0.4(2020-08-29) + +1. 优化异步改变 tabs 后,下划线不初始化问题 +2. github 地址上有图 2 的源码,需要的自行下载,页面路径:pages/tabs/order.vue + +## 2.0.3(2020-08-20) + +1. 优化 节点查询 和 选中渲染 +2. 优化支付宝中 createSelectorQuery() 的影响 + +**特别说明:** + +> 支付宝中平铺方法和其他方法不能在一个页面中出现,不然有一个显示错误(具体什么原因没查到,有好心的人发现了,望告知一下,感谢 + +## 2.0.2(2020-08-19) + +1. 优化 change 事件触发机制 + +## 2.0.1(2020-08-16) + +1. 修改默认高度为 70rpx +2. 新增属性 bgColor,可设置背景颜色,默认 #fff +3. 新增整个 tab 的 padding 属性,默认 0 + +## 2.0.0(2020-08-13) + +1. 全新的 v-tabs 2.0 +2. 支持 H5 小程序 APP +3. 属性高度可配置 + +## 1.3.2(2020-07-21) + +1. 新增 auto 的配置,是否平铺 tab +2. 修复文档上的错误示例(感谢 lushgwe@163.com 的反馈) + +## 1.3.0(2020-07-05) + +1. 新增 padding 的可配置 +2. 修复 v-model 双向绑定问题 +3. 修复初始化下划线没定位的为题 + +## 1.2.0(2020-06-19) + +1. 添加注释 +2. 修复 bug + +## 1.1.8(2020-06-11) + +1. 添加 change 事件 +2. 修复插件内容问题 +3. 修复下划线不居中问题 + +## 1.1.6(2020-06-11) + +1. 添加 change 事件 +2. 修复插件内容问题 + +## 1.1.4(2020-06-11) + +1. 添加 change 事件 +2. 修复插件内容问题 + +## 1.1.2(2020-06-11) + +1. 添加 change 事件 + +## 1.1.1(2020-06-09) + +1. 修复小程序端选中的下划线不显示问题 +2. 新增 tab 高度设置 +3. lineHeight 修改为只支持 String 方式 + +## 1.1.0(2020-06-09) + +1. 修复小程序端选中的下划线不显示问题 +2. 新增 tab 高度设置 +3. lineHeight 修改为只支持 String 方式 + +## 1.0.0(2020-06-04) + +1. 更新插件1.0.0 \ No newline at end of file diff --git a/uni_modules/v-tabs/components/v-tabs/props.js b/uni_modules/v-tabs/components/v-tabs/props.js new file mode 100644 index 0000000..22f871a --- /dev/null +++ b/uni_modules/v-tabs/components/v-tabs/props.js @@ -0,0 +1,104 @@ +export default { + value: { + type: Number, + default: 0 + }, + modelValue: { + type: Number, + default: 0 + }, + tabs: { + type: Array, + default() { + return [] + } + }, + bgColor: { + type: String, + default: '#fff' + }, + padding: { + type: String, + default: '0' + }, + color: { + type: String, + default: '#333' + }, + activeColor: { + type: String, + default: '#2979ff' + }, + fontSize: { + type: String, + default: '28rpx' + }, + activeFontSize: { + type: String, + default: '32rpx' + }, + bold: { + type: Boolean, + default: false + }, + scroll: { + type: Boolean, + default: true + }, + height: { + type: String, + default: '70rpx' + }, + lineColor: { + type: String, + default: '#2979ff' + }, + lineHeight: { + type: [String, Number], + default: '10rpx' + }, + lineScale: { + type: Number, + default: 0.5 + }, + lineRadius: { + type: String, + default: '10rpx' + }, + pills: { + type: Boolean, + default: false + }, + pillsColor: { + type: String, + default: '#2979ff' + }, + pillsBorderRadius: { + type: String, + default: '10rpx' + }, + pillsBorder: { + type: String, + default: '1rpx solid' + }, + field: { + type: String, + default: '' + }, + fixed: { + type: Boolean, + default: false + }, + paddingItem: { + type: String, + default: '0 22rpx' + }, + lineAnimation: { + type: Boolean, + default: true + }, + zIndex: { + type: Number, + default: 1993 + } +} diff --git a/uni_modules/v-tabs/components/v-tabs/utils.js b/uni_modules/v-tabs/components/v-tabs/utils.js new file mode 100644 index 0000000..71f1d7f --- /dev/null +++ b/uni_modules/v-tabs/components/v-tabs/utils.js @@ -0,0 +1,12 @@ +export function startMicroTask(callback) { + if (typeof queueMicrotask === 'function') { + queueMicrotask(callback) + } else if (typeof MutationObserver === 'function') { + const node = document.createElement('div') + const observer = new MutationObserver(callback) + observer.observe(node, { childList: true }) + node.textContent = 'xfjpeter' + } else { + setTimeout(callback, 0) + } +} diff --git a/uni_modules/v-tabs/components/v-tabs/v-tabs.vue b/uni_modules/v-tabs/components/v-tabs/v-tabs.vue new file mode 100644 index 0000000..ef2762d --- /dev/null +++ b/uni_modules/v-tabs/components/v-tabs/v-tabs.vue @@ -0,0 +1,296 @@ + + + + + diff --git a/uni_modules/v-tabs/package.json b/uni_modules/v-tabs/package.json new file mode 100644 index 0000000..3fc359b --- /dev/null +++ b/uni_modules/v-tabs/package.json @@ -0,0 +1,84 @@ +{ + "id": "v-tabs", + "displayName": "自定义 tab 选项卡 2", + "version": "2.1.9", + "description": "自定义 tab ,支持多种样式,支持 h5 小程序 app", + "keywords": [ + "v-tabs", + "tab", + "选项卡" +], + "repository": "https://github.com/xfjpeter/uni-plugins", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "1207791534" + }, + "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-nvue": "n" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "n", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "y", + "快手": "y", + "飞书": "y", + "京东": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/v-tabs/readme.md b/uni_modules/v-tabs/readme.md new file mode 100644 index 0000000..fb05bce --- /dev/null +++ b/uni_modules/v-tabs/readme.md @@ -0,0 +1,267 @@ +## 插件说明 + +> 这是 `v-tabs` 插件的升级版本,参数上有很大变动,支持 `H5` `小程序` `手机端`,如果是在之前的插件上升级的话,请注意参数的变更,触发的事件没有变更。 + +## 使用说明 + +### 1、最基本用法 + +- 视图文件 + +```html + +``` + +- 脚本文件 + +```js +export default { + data() { + return { + current: 0, + tabs: ['军事', '国内', '新闻新闻', '军事', '国内', '新闻', '军事', '国内', '新闻'] + } + }, + methods: { + changeTab(index) { + console.log('当前选中的项:' + index) + } + } +} +``` + +### 2、平铺整个屏幕 + +- 视图文件 + +```html + +``` + +- 脚本文件 + +```js +export default { + data() { + return { + activeTab: 0 + } + } +} +``` + +### 3、胶囊用法 + +- 视图文件 + +```html + +``` + +- 脚本文件 + +```js +data() { + return { + current: 2, + tabs: [ + '军事', + '国内', + '新闻新闻', + '军事', + '国内', + '新闻', + '军事', + '国内', + '新闻', + ], + }, + methods: { + changeTab(index) { + console.log('当前选中索引:' + index) + } + } +} +``` + +## 文档说明 + +### 1、属性说明 + +| 参数 | 类型 | 默认值 | 说明 | +| :---------------: | :-----: | :-------: | :-----------------------------------------------------------------------: | +| tabs | Array | [] | 控制 tab 的列表 | +| value | Number | 0 | 必传(双向绑定的值) | +| color | String | '#333' | 默认文字颜色 | +| activeColor | String | '#2979ff' | 选中文字的颜色 | +| fontSize | String | '28rpx' | 默认文字大小(rpx 或 px)(弃用) | +| bold | Boolean | true | 是否加粗选中项 | +| scroll | Boolean | true | 是否显示滚动条,平铺设置 false | +| height | String | '70rpx' | tab 高度(rpx 或 px) | +| lineHeight | String | '10rpx' | 滑块高度(rpx 或 px) | +| lineColor | String | '#2979ff' | 滑块的颜色 | +| lineScale | Number | 0.5 | 滑块宽度缩放值 | +| lineRadius | String | '10rpx' | 滑块圆角宽度(rpx 或 px) | +| pills | Boolean | false | 是否开启胶囊 | +| pillsColor | String | '#2979ff' | 胶囊背景颜色(rpx 或 px) | +| pillsBorderRadius | String | '10rpx' | 胶囊圆角宽度(rpx 或 px) | +| field | String | '' | 如果 tabs 子项是对象,输入需要展示的键名 | +| bgColor | String | '#fff' | 背景色,支持 linear-gradient 渐变 | +| padding | String | '0' | 整个 tab padding 属性 | +| fixed | Boolean | false | 是否固定在顶部 | +| paddingItem | String | '0 22rpx' | 选项的边距(设置上下不生效,需要设置高度) | +| lineAnimation | Boolean | true | 是否需要 line 和 pills 的动画,在隐藏页面后默认移动到第一个的时候比较实用 | +| zIndex | Number | 1993 | 控制 tab 的层级,默认1993 | + +### 1.1 `tabs`参数展开说明 + +#### 1.1.1 当`tabs`仅仅是单纯的数组时候,没有什么特别的地方 + +```js +export default { + data() { + return { + tabs: ['全部', '待付款', '待消费', '已完成', '已评价', '已过期', '已退款'] + } + } +} +``` + +#### 1.1.2 当`tabs`使用的数组对象的方式,特定参数需要注意一下 + +- `disabled` 参数,可以控制按钮是否可以点击 + +```js +export default { + data() { + return { + tabs: [ + { id: 1, name: '待付款', disabled: false }, + { id: 2, name: '待收货', disabled: false }, + { id: 3, name: '待评价', disabled: false }, + { id: 4, name: '退款/售后', disabled: true }, + { id: 5, name: '我的订单', disabled: false } + ] + } + } +} +``` + +### 2、事件说明 + +| 名称 | 参数 | 说明 | +| :----: | :---: | :--------------------------------: | +| change | index | 改变选中项触发, index 选中项的下标 | + +## 更新日志 + +### 2.1.9(2024-06-14) +1. [修改]当`current`初始值大于`tabs.length`或者小于`0`,自动设置`current`的值为`0` +2. [抛弃]压缩包方式的源码不提供维护了,只维护`uni_modules`中的源码 + +### 2.1.8(2024-06-06) +1. [新增]支持`vue3`了 + +### 2.1.6(2024-06-06) +1. [修复]使用`fixed`属性之后,在支付宝小程序无法滚动的bug + +### 2.1.5(2023-11-02) +1. [修复]修复`change`和`v-model`绑定的值不同步 +2. [修复]暂时停用`activeFontSize`选项 +3. [修改]修改默认激活的文字不加粗 + +### 2.1.4(2023-10-12) +1. [修改]修改计算方式 +2. [新增]外部可以通过`this.$refs.tabs.update()`方法主动更新 + +### 2.1.3(2023-09-11) +1. [新增]支持自定义插槽模式,具体可以查看示例代码使用方式。[gitee demo](https://github.com/xfjpeter/uni-plugins/blob/master/pages/tabs/tabs.vue#L47-L50) 或 [github demo](https://github.com/xfjpeter/uni-plugins/blob/master/pages/tabs/tabs.vue#L47-L50) + +### 2.1.2(2023-06-12) +1. [新增]添加`z-index`参数控制层级大小,默认1993 +2. [说明]以后该插件只更新`uni_modules`方式的,`zip`方式的不提供更新了,如果需要的请到 [gitee uni-plugins](https://gitee.com/xfjpeter/uni-plugins) 或 [github uni-plugins](https://github.com/xfjpeter/uni-plugins)下载源码,自行使用 + +### 2.1.1(2022-09-16) + +1. 将插件更新为`uni_modules`方式 + +### 2022-08-12 + +1. 增加`disable`参数,控制是否可以点击,只能应用在数组对象中,见[disabled 的用法](#112-当tabs使用的数组对象的方式特定参数需要注意一下) + +```js +export default { + data() { + return { + tabs: [{ id: 1, name: '' }] + } + } +} +``` + +### 2022-01-27 + +1. 更新属性`line-animation`设置为`false`可以不要动画,这是好多朋友问到,特此加上 + +### 2020-09-24 + +1. 修复 `v-tabs` 第一次可能出现第一个标签显示不完整的情况 +2. 修改了 `pages/tabs/order` 示例文件 + +### 2020-09-21 + +1. 修复添加 `fixed` 属性后,滚动条无效 +2. 修复选项很少的情况下,下划线计算计算错误 +3. 新增 `paddingItem` 属性,设置选项左右边距(上下边距需要设置 `height` 属性,或者设置 `padding` 属性) + +**写在最后:** +欢迎各位老铁反馈 bug ,本人后端 PHP 一枚,只是应为感兴趣前端,自己琢磨,自己搞。如果你在使用的过程中有什么不合理,需要优化的,都可以在下面评论(或加我 QQ: 1207791534),本人看见后回复、修正,感谢。 + +### 2020-09-17 + +1. 紧急修复 bug,横向滑动不了的情况 + +### 2020-09-16 + +1. 新增 `fixed` 属性,是否固定在顶部,示例地址:`pages/tabs/tabs-static` +2. 优化之前的页面结构 + +**注意:** + +1. 使用 `padding` 属性的时候,尽量不要左右边距,会导致下划线位置不对 +2. 如果不绑定 `v-model` 会导致 `change` 事件改变的时候,下划线不跟随问题 + +### 2020-09-09 + +1. 修复 `width` 错误,dom 加载的时候没有及时获取到 `data` 属性导致的。 + +### 2020-08-29 + +1. 优化异步改变 `tabs` 后,下划线不初始化问题 +2. `github` 地址上有图 2 的源码,需要的自行下载,页面路径:`pages/tabs/order` + +### 2020-08-20 + +1. 优化 `节点查询` 和 `选中渲染` +2. 优化支付宝中 `createSelectorQuery()` 的影响 + +### 2020-08-19 + +1. 优化 `change` 事件触发机制 + +### 2020-08-16 + +1. 修改默认高度为 `70rpx` +2. 新增属性 `bgColor`,可设置背景颜色,默认 `#fff` +3. 新增整个 `tab` 的 `padding` 属性,默认 `0` + +### 2020-08-13 + +1. 全新的 `v-tabs 2.0` +2. 支持 `H5` `小程序` `APP` +3. 属性高度可配置 + +## 预览 + +![v-tabs 2.0.1.gif](https://tva1.sinaimg.cn/large/007S8ZIlgy1ghsv40mj76g30ai0i2tsd.gif) +![v-tabs 2.0.2.gif](https://img-cdn-aliyun.dcloud.net.cn/stream/plugin_screens/42f3a920-a674-11ea-8a24-ffee00625e2e_1.png?v=1597912963) diff --git a/utils/common.js b/utils/common.js new file mode 100644 index 0000000..4103054 --- /dev/null +++ b/utils/common.js @@ -0,0 +1,278 @@ +import { projectInfo,OFFICIAL_URL} from "@/config/index.js"; +import i18n from '../locale/index'; +const { t } = i18n.global; + +export const onTabItemTap = (event)=>{ + if(event.index === 2) { + makePhoneCall() + return + } + uni.switchTab({ + url: `/${event.pagePath}` + }); +} +export const makePhoneCall = (phoneNumber = projectInfo.callPhone)=>{ + if(!(typeof phoneNumber == 'string' || typeof phoneNumber == 'number')){ + phoneNumber = '4008181813' + } + uni.makePhoneCall({ + phoneNumber, + }); +} +// tab列 +const pagePathList = [ + '/pages/index/index', + '/pages/unlock/index', + '/pages/personal/index', +] +export const navigateBack = (url)=>{ + const app = getApp(); + + const pages = getCurrentPages() + // 有可返回的页面则直接返回,uni.navigateBack 默认返回失败之后会自动刷新页面 ,无法继续返回 + if (pages.length > 1) { + uni.navigateBack(1) + return; + } + if(url){ + if(pagePathList.includes(url)) + { + uni.switchTab({ + url, + }) + }else{ + uni.navigateTo({ + url, + }) + } + + return + } + uni.reLaunch({ + url: "/pages/index/index" + }) + return; +} +// onshow 判断有没token 没有就不去请求 有的话就去请求 +export const onShowRerequestByIsLogin = (callBack,errCallBack)=>{ + // 检查是否存在token 没有直接跳转 + const token = uni.getStorageSync('token') + if(token){ + callBack() + }else{ + errCallBack&&errCallBack() + } + +} +// 登陆完 是否可以返回到登录前的页面 +export const isToHome = () => { + let routes = getCurrentPages(); + let isNeeToHome = false; + // 登录后返回原来页面的路由 + let refreshPage = ["pages/unlock/index", "pages/setOrder/index", "pages/site/index", "pages/orderdetail/index", "pages/orderdetail/door", "pages/orderdetail/lock","pagesb/reserve/index"]; + let preRoute = routes[routes.length - 2]?.route; + if (preRoute && refreshPage.includes(preRoute)) { + isNeeToHome = false + }else{ + isNeeToHome = true + } + if (isNeeToHome) { + uni.reLaunch({ + url:'/pages/index/index' + }); + } else { + navigateBack(); + } +} + +// 将角度转换为弧度常量 +const RADIANS_PER_DEGREE = Math.PI / 180.0; +// 通过经纬度计算两点之间距离 +export const getDistance = (lat1, lng1, lat2, lng2) => { + const radLat1 = lat1 * RADIANS_PER_DEGREE; + const radLat2 = lat2 * RADIANS_PER_DEGREE; + const deltaLat = radLat1 - radLat2; + const deltaLng = lng1 * RADIANS_PER_DEGREE - lng2 * RADIANS_PER_DEGREE; + let distance = 2 * Math.asin(Math.sqrt(Math.sin(deltaLat / 2) ** 2 + Math.cos(radLat1) * Math.cos(radLat2) * Math.sin(deltaLng / 2) ** 2)); + distance = distance * 6378.137; // 地球半径 + distance = Math.round(distance * 10) / 10; + if (distance > 99) { + return { distance: ">99", number: distance }; + } + return { distance, number: distance }; +} +// 导出导航栏高度 +export const navbarHeightAndStatusBarHeight = () => { + let systemInfo = {}; + // #ifdef MP-WEIXIN + systemInfo = uni.getDeviceInfo(); + // #endif + let navbarHeight = 0; + let statusBarHeight = 0; + let iStatusBarHeight = 0; + + + navbarHeight = getApp().globalData.navbarHeight; + statusBarHeight = getApp().globalData.statusBarHeight; + iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight + // 不知道什么原因 navbarHeight 会出现0的情况 如果为0 再重新获取一下 + if (navbarHeight === 0 || statusBarHeight === 0) { + // #ifdef MP-WEIXIN || MP-XHS + // 状态栏高度 + const wxStatusBarHeight = uni.getSystemInfoSync().statusBarHeight; + const wxMenuBtn = uni.getMenuButtonBoundingClientRect(); + // 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2 + const barHeight = wxMenuBtn.height + (wxMenuBtn.top - wxStatusBarHeight) * 2; + // 总体高度 = 状态栏高度 + 导航栏高度 + navbarHeight = (barHeight || 40) + wxStatusBarHeight+iStatusBarHeight; + statusBarHeight = wxStatusBarHeight || 20; + // #endif + }else{ + // #ifdef APP-PLUS + navbarHeight = navbarHeight+iStatusBarHeight + // #endif + } + + // 判断是否为PC(Windows、Mac) + if (systemInfo.platform === 'windows' || systemInfo.platform === 'mac') { + // 在这里处理PC端的逻辑 + let tempHeight = { + navbarHeight, + statusBarHeight + } + return { + navbarHeight: 0, + statusBarHeight: 0, + tempHeight + } + } + + return { + navbarHeight, + statusBarHeight + } +} +// h5 跳转小程序 +export const h5GoWx =(successCallback, failCallback,completeCallback)=>{ + uni.showModal({ + cancelText:t("request.cancel"), + confirmText:t("request.confirm"), + title:t("request.tip"), + content:"前往微信小程序下单", + success:(e)=>{ + if(e.confirm){ + window.location.href = OFFICIAL_URL + } + successCallback && successCallback(e) + } , + fail: failCallback, + complete: completeCallback + }) +} +// 去掉小数点后两位 +export const removeTrailingZeros = (num) => { + // Check if input is a valid number + if (isNaN(num) || num === null || num === undefined) { + return num; + } + // Convert to float and then to string to remove trailing zeros + return parseFloat(num).toString(); + } + +// 分享页的参数 +export const shareParam = { + title: `${projectInfo.miniName}`, + path: '/pages/index/index' +} + +// 根据门店id 跳转到时昌的小程序 +export const jumpToSc = [ + { id: '1906958815820124160', targetId: '1881917629627764736' }, +] + +// 五羊门店的id +export const wuyangSiteIds = [ + '1854360658481647616', + '1854360658913660928', + '1854360659777687552', + '1854360654157320192', + ] +// ['10078', '10079', '10082', '10084'] +// [ +// '1854360658481647616', +// '1854360658913660928', +// '1854360659777687552', +// '1854360654157320192', +// ]; + + +/** + * 合并五羊门店,把同组 id push 到 siteList + * @param {Array} stores 门店列表 + * @returns {Array} + */ +export const mergeFiveGoatStores = (stores) => { + // 找到所有存在的五羊门店(按原顺序) + const existing = wuyangSiteIds + .map(id => stores.find(s => s.id === id)) + .filter(Boolean); + + if (existing.length === 0) return stores; // 没有任何五羊门店,不处理 + + // 选出主门店(按 ids 顺序第一个存在的) + const mainStore = existing[0]; + + // 其余门店作为子站点 + const siteList = existing.slice(1); + + return stores + .filter(store => !wuyangSiteIds.includes(store.id) || store.id === mainStore.id) // 非主门店不再出现在列表 + .map(store => { + if (store.id === mainStore.id) { + return { + ...store, + siteList, + isFiveGoatStores: siteList.length > 0, + }; + } + return store; + }); +}; + +// 把 url 的参数转换成对象 +export const parseUrlParams = (url) => { + const params = {}; + const queryString = url.split('?')[1]; + if (!queryString) return params; + + const pairs = queryString.split('&'); + for (const pair of pairs) { + const [key, value] = pair.split('='); + if (key) { + params[key] = value || ''; + } + } + return params; +} +// 顺丰参数 +export const shunfenLogin = (code) => { + // 授权参数(请根据实际情况修改) +const authOptions = { + appId: "202603041358374970", // 第三方接入ID + scope: ["sf_userinfo", "sf_mobile", "sf_base", "sf_emp", "sf_channelId"], + successUrl: "https://uat.kingkongcang.com/client/", // 当前页面地址 +}; + window.sf.getAuthCode({ + ...authOptions, + }) + .then((res) => { + console.log('getAuthCode success',res); + }) + .catch((err) => console.log('getAuthCode err',err)); + +} +// 获取url 参数 +export const getQueryParam = (name, url = window.location.href) => { + const params = new URL(url).searchParams; + return params.get(name); +} \ No newline at end of file diff --git a/utils/map.js b/utils/map.js new file mode 100644 index 0000000..0501573 --- /dev/null +++ b/utils/map.js @@ -0,0 +1,63 @@ +// 定义 PI 常量 +const PI = 3.14159265358979324; +const x_PI = (PI * 3000.0) / 180.0; + +/**** 腾讯地图和谷歌地图使用的坐标系不同,因此在两者之间进行坐标转换时需要进行相应的处理。 +******腾讯地图使用的是GCJ-02坐标系(也称为国测局坐标系),而谷歌地图在中国境内使用的也是GCJ-02坐标系,但在中国境外使用的是WGS-84坐标系。 +以下是一个示例,展示如何在 Vue 3 中实现腾讯地图坐标和谷歌地图坐标之间的相互转换: +*****/ +export function gcj02ToWgs84(lng, lat) { + if (outOfChina(lng, lat)) { + return [lng, lat]; + } else { + let dlat = transformLat(lng - 105.0, lat - 35.0); + let dlng = transformLng(lng - 105.0, lat - 35.0); + const radlat = (lat / 180.0) * PI; + let magic = Math.sin(radlat); + magic = 1 - 0.00669342162296594323 * magic * magic; + const sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / (((6335552.717000426 * (1 - 0.00669342162296594323)) / (magic * sqrtmagic)) * PI); + dlng = (dlng * 180.0) / ((6378245.0 / sqrtmagic) * Math.cos(radlat) * PI); + const mglat = lat + dlat; + const mglng = lng + dlng; + return [lng * 2 - mglng, lat * 2 - mglat]; + } +} + +export function wgs84ToGcj02(lng, lat) { + if (outOfChina(lng, lat)) { + return [lng, lat]; + } else { + let dlat = transformLat(lng - 105.0, lat - 35.0); + let dlng = transformLng(lng - 105.0, lat - 35.0); + const radlat = (lat / 180.0) * PI; + let magic = Math.sin(radlat); + magic = 1 - 0.00669342162296594323 * magic * magic; + const sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / (((6335552.717000426 * (1 - 0.00669342162296594323)) / (magic * sqrtmagic)) * PI); + dlng = (dlng * 180.0) / ((6378245.0 / sqrtmagic) * Math.cos(radlat) * PI); + const mglat = lat + dlat; + const mglng = lng + dlng; + return [mglng, mglat]; + } +} + +function transformLat(lng, lat) { + let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; + ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; + return ret; +} + +function transformLng(lng, lat) { + let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; + ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; + return ret; +} + +function outOfChina(lng, lat) { + return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55); +} diff --git a/utils/navigateTo.js b/utils/navigateTo.js new file mode 100644 index 0000000..cb039ef --- /dev/null +++ b/utils/navigateTo.js @@ -0,0 +1,17 @@ +export const navigateTo = (url) => { + // H5 不让去登录先 跳转小程序 + const pagePathList = [ + '/pages/index/index', + '/pages/unlock/index', + '/pages/personal/index', + ] + if (pagePathList.includes(url)) { + uni.switchTab({ + url, + }) + } else { + uni.navigateTo({ + url, + }) + } +} \ No newline at end of file diff --git a/utils/request.js b/utils/request.js new file mode 100644 index 0000000..d4d6f50 --- /dev/null +++ b/utils/request.js @@ -0,0 +1,455 @@ +import { baseUrl,devURL,isWeChatMiniProgram,OFFICIAL_URL,AppId} from '@/config/index.js' +import { useMainStore } from "@/store/index.js" +import { h5GoWx,shunfenLogin } from "@/utils/common"; +import i18n from '../locale/index'; +import { isH5 } from '../config'; +const { t } = i18n.global; + +const messageToIn18n = { + 'Promo code is incorrect or has expired':t("request.promoCodeError") +} + +const LOGIN_ERROR_CODE = [ + { + code : 401, + msg : '' + }, +] //错误码 +const WHITE_CODE_LIST = [ + { + code : 200, + msg : '' + }, + { + code : 210, // 无数据 + msg : '' + }, + { + code : 204, + msg : '' + }, + { + code : 1001, + msg : '' + }, + { + code : 5006, + msg : t("request.captchaError") + }, + { + code : 1002, + } +] +const failCode = [ + { + code:600001, + msg:'网络异常,请检查网络是否联网' + } +] +//白名单 +// 需要token的 接口 +const NEED_TOKEN_URL = [ + '/ClientOrder/AddOrder', + '/ClientOrder/GetOrderById', + '/ClientOrder/GetOrderList', + '/ClientUnitType/AlternateReservation' +] +// 需要token的接口,但是不跳转登录页 +const NEED_TOKEN_URL_NoGoLogin = [ + '/ClientUnitType/GetReserveIsEnable', // 门店预约接口 + '/ClientCustomer/GetUserInfo', // 获取用户信息 + '/ClientCoupon/GetNewUserCouponCode' // 获取新用户优惠券 +] +// 报错不弹窗 +const NOWARRING_URL = [ + '/ClientCustomer/GetActivitiesCode', + '/ClientCustomer/GetOpenId', + '/ClientSite/GetFlashSaleEntrance', + '/ClientSite/GetMultipleStoreInfo', + '/APP/GetAppText' +] +// 官网跳转微信小程序 链接 https://elitesys.kingkongcang.com/Mini + + +function urlStringify(obj) { + if (typeof obj !== 'object' || obj === null) { + return '' + } + + const params = Object.keys(obj).map(key => { + const value = encodeURIComponent(obj[key]); + return `${encodeURIComponent(key)}=${value}`; + }); + + return params.length ? '?' + params.join('&') : ''; +} + +class HttpRequest { + + constructor() { + this.baseUrl = baseUrl + this.timeout = 60000; + this.showModal = false; // 记录当前弹窗状态 避免多次弹窗 定时三秒重置弹窗状态 避免非正常关闭弹窗 导致app无法操作 + this.isShowUpDate = false; // 是否显示更新 + } + // 设置弹窗 + setShowModal(showModal) { + this.showModal = showModal; + if(showModal){ + setTimeout(() => { + this.showModal = false; + }, 3000) + } + } + + // 是否去登录窗口 + showLoginModal(){ + // 如果已经打开 就不重复打开 + if(this.showModal) return + // 设置弹窗状态 + this.setShowModal(true) + // 如果是小程序就询问是否登陆 不是的话直接小程序链接 + if(!isH5){ + uni.showModal({ + cancelText:t("request.cancel"), + confirmText:t("request.confirm"), + title:t("request.tip"), + content:t("request.loginContent"), + success: (e) => { + if(e.confirm){ + shunfenLogin() + uni.hideLoading() + }else{ + uni.hideLoading() + } + }, + fail: () => { + + }, + complete: () => { + this.setShowModal(false) + } + }) + }else{ + h5GoWx((e) => { + if(e.confirm){ + uni.hideLoading() + }else{ + uni.hideLoading() + } + },()=>{ + + },()=>{ + this.setShowModal(false) + }) + // uni.showModal({ + // cancelText:t("request.cancel"), + // confirmText:t("request.confirm"), + // title:t("request.tip"), + // content:"前往小程序下单", + // success: (e) => { + // if(e.confirm){ + // window.location.href = OFFICIAL_URL + // uni.hideLoading() + // }else{ + // uni.hideLoading() + // } + // }, + // fail: () => { + + // }, + // complete: () => { + // this.setShowModal(false) + // } + // }) + } + + uni.hideLoading() + } + logOut (){ + const { logOut:logOutFunc } = useMainStore() + logOutFunc() + } + getConfig(headerData) { + const baseHeader = { + Authorization: "Bearer " + uni.getStorageSync('token'), + lang: uni.getStorageSync("eliteSys-language-wx") =='en'? 'en' : 'zh', + AppId, + } + return { + url: this.baseUrl, + timeout: this.timeout, + header: headerData ? {...baseHeader,...headerData} : {...baseHeader} + }; + } + + getParams(payload) { + const { method, data,url,params } = payload; + payload.url = this.baseUrl + url + if (['post', 'put', 'patch', 'delete'].indexOf(method) >= 0) { + payload.data = data; + } else { + payload.url = payload.url + urlStringify(data); + delete payload.data; + } + if(params){ + payload.url = payload.url + urlStringify(params); + } + + return payload; + } + + checkStatus(status) { + let errMessage = ''; + switch (status) { + case 400: + errMessage = 'error'; + break; + case 401: + errMessage = 'Unauthorized, please log in again'; + break; + case 403: + errMessage = 'Access denied'; + break; + case 404: + errMessage = 'Request error, the resource was not found'; + break; + case 405: + errMessage = 'Request method not allowed'; + break; + case 408: + errMessage = 'Request timeout'; + break; + case 500: + errMessage = 'Server side error'; + break; + case 501: + errMessage = 'The network is not implemented'; + break; + case 502: + errMessage = 'Network error'; + break; + case 503: + errMessage = 'Service is not available'; + break; + case 504: + errMessage = 'Network timeout'; + break; + case 505: + errMessage = 'The request is not supported by the http version'; + break; + default: + errMessage = 'Connection error'; + } + return errMessage; + } + + // 拦截处理 + setInterceptors(config,setOptions) { + const token = uni.getStorageSync('token') + const that = this; + const isNeeTokenNoGoLogin = NEED_TOKEN_URL_NoGoLogin.every(item=>setOptions.url.indexOf(item)===-1) + if(!isNeeTokenNoGoLogin){ + // 检查是否存在token 没有就return + if(!token){ + uni.hideLoading() + Promise.reject('Need login') + } + } + const isNeeToken = NEED_TOKEN_URL.every(item=>setOptions.url.indexOf(item)===-1) + if(!isNeeToken){ + // 检查是否存在token 没有直接跳转 + if(!token){ + this.showLoginModal() + return Promise.reject('Need login'); + } + } + // 请求拦截 + // config.requestInterceptor = options => { + // if (!navigator.onLine) { + // uni.showToast({ + // title: 'Please check that your network is normal.', + // icon: 'none', + // duration: 3000 + // }); + // return Promise.reject(new Error('Please check that your network is normal.')); + // } + // const token = "Bearer " + uni.getStorageSync('token'); + // if (token) { + // options.header.Authorization = token; + // } + // return options; + // }; + + // 响应拦截 + config.responseInterceptor = (response,setOptions) => { + const result = response.data; + const type = Object.prototype.toString.call(result); + if (type === '[object Blob]' || type === '[object ArrayBuffer]') { + return result; + } else { + let { code, msg } = result; + const isErrorToken = LOGIN_ERROR_CODE.some(item => item.code == code); + const isWhiteCode = WHITE_CODE_LIST.some(item => item.code == code); + + if (code == 105) { + uni.navigateTo({ + url:'/pagesb/maskUser/index' + }); + return result; + } + + if (isErrorToken) { + // if(code === 401) { + // uni.removeStorageSync({ + // key: 'token', + // success: function (res) { + // uni.navigateTo({ + // url: '/pages/login/index' + // }); + // } + // }) + // } + // 判断链接 需不需要跳转登录页 + const isNeeTokenNoGoLogin = NEED_TOKEN_URL_NoGoLogin.some(item=>setOptions.url.indexOf(item)!==-1) + if(!isNeeTokenNoGoLogin){ + this.logOut() + this.showLoginModal() + } + uni.hideLoading() + return response; + } else if (!isWhiteCode) { + if (msg === 'Request canceled by user') return result; + if (messageToIn18n[msg]){ + msg = t(messageToIn18n[msg]) + } + setTimeout(()=>{ + const isNOWARRING_URL = NOWARRING_URL.some(item=>setOptions.url.indexOf(item)!==-1) + if(!isNOWARRING_URL){ + uni.showToast({ + title: msg || t("request.error"), + icon: 'none', + duration: 3000 + }); + } + + },500) + return response.data; + } else { + return result; + } + } + }; + + config.responseInterceptorError = error => { + if((error.errMsg == 'request:fail ' && !this.isShowUpDate)||(error.statusCode == 502 && !this.isShowUpDate)) { + this.isShowUpDate = true + uni.request({ + url: devURL + '/app/GetIsProductionServerUpdating', + success: response => { + if(response?.data.data) { + uni.showModal({ + title: '系统更新时提示', + content: '系统更新中,预计耗时10分钟,请稍后再试!', + showCancel:false, + success: (res)=> { + this.isShowUpDate = false + } + }); + } else { + this.isShowUpDate = false + } + }, + fail: error => { + this.isShowUpDate = false + } + }); + } + + if (error && error.response) { + error.message = that.checkStatus(error.response.status); + } + const isTimeout = error.errMsg.includes('timeout'); + if (error.errMsg === 'Request canceled by user') return error.errMsg; + const msg = failCode.find(item => item.code == error.errno)?.msg||error.errMsg; + uni.showToast({ + title: isTimeout ? t("request.timeout") : msg || t("request.noConnect"), + icon: 'none', + duration: 2000 + }); + return error; + }; + } + + request(options) { + const config = this.getConfig(options.header); + const setOptions = this.getParams(options) + this.setInterceptors(config,setOptions); + return new Promise((resolve, reject) => { + uni.request({ + ...config, + ...setOptions, + success: response => { + if(response.statusCode === 502){ + try { + const err = config.responseInterceptorError(response); + reject(err); + } catch (error) { + console.log('Error in response interceptor:', response); + reject(error); + } + } + const result = config.responseInterceptor(response,setOptions); + resolve(result); + }, + fail: error => { + try { + const err = config.responseInterceptorError(error); + reject(err); + } catch (catchErr) { + console.log('Error in response interceptor:', catchErr); + reject(catchErr); + } + // const err = config.responseInterceptorError(error); + reject(error); + } + }); + }); + } + async uploadFile(options) { + const config = this.getConfig(options.header); + const setOptions = this.getParams(options) + this.setInterceptors(options,setOptions); + // 上传前 预请求 + // const data = await this.request({ + // url: '/ClientSite/GetSiteDetailsAll', + // method: 'get'}) + + return new Promise((resolve, reject) => { + uni.uploadFile({ + ...config, + ...setOptions, + filePath:options.data.filePath, + name: 'file', + success: response => { + response.data = JSON.parse(response.data) + const result = options.responseInterceptor(response); + resolve(result); + }, + fail: error => { + if(setOptions.url.indexOf('/GetUserInfo')!==-1){ + } + const err = options.responseInterceptorError(error); + if(setOptions.url.indexOf('/GetUserInfo')!==-1){ + } + console.log(err) + reject(err); + } + }); + }); + } + +} + +const request = new HttpRequest(); +export default request; diff --git a/utils/storage.js b/utils/storage.js new file mode 100644 index 0000000..3480dbd --- /dev/null +++ b/utils/storage.js @@ -0,0 +1,46 @@ +const __NEXT_NAME__ = 'EliteSysClient'; + +export const Local = { + // 设置键名 + setKey(key) { + return `${__NEXT_NAME__}:${key}`; + }, + + // 设置永久缓存 + set(key, val) { + try { + uni.setStorageSync(Local.setKey(key), JSON.stringify(val)); + } catch (e) { + console.error('Set storage failed:', e); + } + }, + + // 获取永久缓存 + get(key) { + try { + const json = uni.getStorageSync(Local.setKey(key)); + return json ? JSON.parse(json) : null; + } catch (e) { + console.error('Get storage failed:', e); + return null; + } + }, + + // 移除永久缓存 + remove(key) { + try { + uni.removeStorageSync(Local.setKey(key)); + } catch (e) { + console.error('Remove storage failed:', e); + } + }, + + // 移除全部永久缓存 + clear() { + try { + uni.clearStorageSync(); + } catch (e) { + console.error('Clear storage failed:', e); + } + }, +};

PqiNa$~E4XJ#a8s%?nsx`&SiQ7Wz{CE9c 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 literal 0 HcmV?d00001 diff --git a/uni_modules/uni-icons/package.json b/uni_modules/uni-icons/package.json new file mode 100644 index 0000000..d1c4e77 --- /dev/null +++ b/uni_modules/uni-icons/package.json @@ -0,0 +1,86 @@ +{ + "id": "uni-icons", + "displayName": "uni-icons 图标", + "version": "1.3.5", + "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。", + "keywords": [ + "uni-ui", + "uniui", + "icon", + "图标" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.2.14" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file 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..2f13bae --- /dev/null +++ b/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list-item.vue @@ -0,0 +1,144 @@ + + + + + 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..35e168c --- /dev/null +++ b/uni_modules/uni-indexed-list/components/uni-indexed-list/uni-indexed-list.vue @@ -0,0 +1,367 @@ + + + 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 @@ + + + + + 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 @@ + + + + + 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 @@ + + + + + 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 @@ + + + + + \ 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 @@ + + + + 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 @@ + + + + + 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 + + + + + +``` + +### 多行内容显示 + +- 设置 `note` 属性 ,可以在第二行显示描述文本信息 + +```html + + + + + +``` + +### 右侧显示角标、switch + +- 设置 `show-badge` 属性 ,可以显示角标内容 +- 设置 `show-switch` 属性,可以显示 switch 开关 + +```html + + + + + +``` + +### 左侧显示略缩图、图标 + +- 设置 `thumb` 属性 ,可以在列表左侧显示略缩图 +- 设置 `show-extra-icon` 属性,并指定 `extra-icon` 可以在左侧显示图标 + +```html + + + + +``` + +### 开启点击反馈和右侧箭头 +- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件 +- 设置 `link` 属性,会自动开启点击反馈,并给列表右侧添加一个箭头 +- 设置 `to` 属性,可以跳转页面,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo` + +```html + + + + + + + +``` + + +### 聊天列表示例 +- 设置 `clickable` 为 `true` ,则表示这是一个可点击的列表,会默认给一个点击效果,并可以监听 `click` 事件 +- 设置 `link` 属性,会自动开启点击反馈,`link` 的值表示跳转方式,如果不指定,默认为 `navigateTo` +- 设置 `to` 属性,可以跳转页面 +- `time` 属性,通常会设置成时间显示,但是这个属性不仅仅可以设置时间,你可以传入任何文本,注意文本长度可能会影响显示 +- `avatar` 和 `avatarList` 属性同时只会有一个生效,同时设置的话,`avatarList` 属性的长度大于1 ,`avatar` 属性将失效 +- 可以通过默认插槽自定义列表右侧内容 + +```html + + + + + + + + + + + + + + + + + 刚刚 + + + + + + + +``` + +```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 + + + + + + + + + 自定义插槽 + + + + +``` + + + + + +### 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..8f03f1d --- /dev/null +++ b/uni_modules/uni-load-more/changelog.md @@ -0,0 +1,19 @@ +## 1.3.3(2022-01-20) +- 新增 showText属性 ,是否显示文本 +## 1.3.2(2022-01-19) +- 修复 nvue 平台下不显示文本的bug +## 1.3.1(2022-01-19) +- 修复 微信小程序平台样式选择器报警告的问题 +## 1.3.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more) +## 1.2.1(2021-08-24) +- 新增 支持国际化 +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.8(2021-05-12) +- 新增 组件示例地址 +## 1.1.7(2021-03-30) +- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug +## 1.1.6(2021-02-05) +- 调整为uni_modules目录规范 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..e5eff4d --- /dev/null +++ b/uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue @@ -0,0 +1,399 @@ + + + + + diff --git a/uni_modules/uni-load-more/package.json b/uni_modules/uni-load-more/package.json new file mode 100644 index 0000000..2fa6f04 --- /dev/null +++ b/uni_modules/uni-load-more/package.json @@ -0,0 +1,86 @@ +{ + "id": "uni-load-more", + "displayName": "uni-load-more 加载更多", + "version": "1.3.3", + "description": "LoadMore 组件,常用在列表里面,做滚动加载使用。", + "keywords": [ + "uni-ui", + "uniui", + "加载更多", + "load-more" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file 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..0f9a2f1 --- /dev/null +++ b/uni_modules/uni-nav-bar/changelog.md @@ -0,0 +1,51 @@ +## 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..c890860 --- /dev/null +++ b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue @@ -0,0 +1,357 @@ + + + + + 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..4ac73ae --- /dev/null +++ b/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/uni_modules/uni-nav-bar/package.json b/uni_modules/uni-nav-bar/package.json new file mode 100644 index 0000000..240ae95 --- /dev/null +++ b/uni_modules/uni-nav-bar/package.json @@ -0,0 +1,86 @@ +{ + "id": "uni-nav-bar", + "displayName": "uni-nav-bar 自定义导航栏", + "version": "1.3.11", + "description": "自定义导航栏组件,主要用于头部导航。", + "keywords": [ + "uni-ui", + "导航", + "导航栏", + "自定义导航栏" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ No newline at end of file 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..d526811 --- /dev/null +++ b/uni_modules/uni-notice-bar/changelog.md @@ -0,0 +1,18 @@ +## 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..98d4720 --- /dev/null +++ b/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue @@ -0,0 +1,426 @@ + + + + + diff --git a/uni_modules/uni-notice-bar/package.json b/uni_modules/uni-notice-bar/package.json new file mode 100644 index 0000000..8d9b13c --- /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.1", + "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..5925c32 --- /dev/null +++ b/uni_modules/uni-number-box/changelog.md @@ -0,0 +1,25 @@ +## 1.2.1(2021-11-22) +- 修复 vue3中某些scss变量无法找到的问题 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box) +## 1.1.2(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +## 1.1.1(2021-07-30) +- 优化 vue3下事件警告的问题 +## 1.1.0(2021-07-13) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.7(2021-05-12) +- 新增 组件示例地址 +## 1.0.6(2021-04-20) +- 修复 uni-number-box 浮点数运算不精确的 bug +- 修复 uni-number-box change 事件触发不正确的 bug +- 新增 uni-number-box v-model 双向绑定 +## 1.0.5(2021-02-05) +- 调整为uni_modules目录规范 + +## 1.0.7(2021-02-05) +- 调整为uni_modules目录规范 +- 新增 支持 v-model +- 新增 支持 focus、blur 事件 +- 新增 支持 PC 端 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..e91c032 --- /dev/null +++ b/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue @@ -0,0 +1,221 @@ + + + diff --git a/uni_modules/uni-number-box/package.json b/uni_modules/uni-number-box/package.json new file mode 100644 index 0000000..ad82336 --- /dev/null +++ b/uni_modules/uni-number-box/package.json @@ -0,0 +1,85 @@ +{ + "id": "uni-number-box", + "displayName": "uni-number-box 数字输入框", + "version": "1.2.1", + "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。", + "keywords": [ + "uni-ui", + "uniui", + "数字输入框" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ 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": "Artculo/Pgina" +} 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 @@ + + + + + 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..bc59f07 --- /dev/null +++ b/uni_modules/uni-popup/changelog.md @@ -0,0 +1,68 @@ +## 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..b5eee79 --- /dev/null +++ b/uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue @@ -0,0 +1,275 @@ + + + + + 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 @@ + + + + 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..5be7624 --- /dev/null +++ b/uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue @@ -0,0 +1,187 @@ + + + + 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.vue b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue new file mode 100644 index 0000000..54afee2 --- /dev/null +++ b/uni_modules/uni-popup/components/uni-popup/uni-popup.vue @@ -0,0 +1,473 @@ + + + + diff --git a/uni_modules/uni-popup/package.json b/uni_modules/uni-popup/package.json new file mode 100644 index 0000000..f40556b --- /dev/null +++ b/uni_modules/uni-popup/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-popup", + "displayName": "uni-popup 弹出层", + "version": "1.8.3", + "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" + }, + "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..9802dfc --- /dev/null +++ b/uni_modules/uni-rate/components/uni-rate/uni-rate.vue @@ -0,0 +1,365 @@ + + + + + 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..d5f3728 --- /dev/null +++ b/uni_modules/uni-row/components/uni-col/uni-col.vue @@ -0,0 +1,317 @@ + + + + + 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..c7d9370 --- /dev/null +++ b/uni_modules/uni-row/components/uni-row/uni-row.vue @@ -0,0 +1,190 @@ + + + + + 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..b41fdd3 --- /dev/null +++ b/uni_modules/uni-search-bar/changelog.md @@ -0,0 +1,33 @@ +## 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..d4e5c12 --- /dev/null +++ b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hans.json @@ -0,0 +1,4 @@ +{ + "uni-search-bar.cancel": "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..318b6ef --- /dev/null +++ b/uni_modules/uni-search-bar/components/uni-search-bar/i18n/zh-Hant.json @@ -0,0 +1,4 @@ +{ + "uni-search-bar.cancel": "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..5a518a8 --- /dev/null +++ b/uni_modules/uni-search-bar/components/uni-search-bar/uni-search-bar.vue @@ -0,0 +1,298 @@ + + + + + diff --git a/uni_modules/uni-search-bar/package.json b/uni_modules/uni-search-bar/package.json new file mode 100644 index 0000000..9352c57 --- /dev/null +++ b/uni_modules/uni-search-bar/package.json @@ -0,0 +1,89 @@ +{ + "id": "uni-search-bar", + "displayName": "uni-search-bar 搜索栏", + "version": "1.2.3", + "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" + } + } + } + } +} \ 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 @@ + + + + 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..a44385d --- /dev/null +++ b/uni_modules/uni-segmented-control/changelog.md @@ -0,0 +1,9 @@ +## 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..e8bb3e5 --- /dev/null +++ b/uni_modules/uni-segmented-control/components/uni-segmented-control/uni-segmented-control.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/uni_modules/uni-segmented-control/package.json b/uni_modules/uni-segmented-control/package.json new file mode 100644 index 0000000..6cae41d --- /dev/null +++ b/uni_modules/uni-segmented-control/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-segmented-control", + "displayName": "uni-segmented-control 分段器", + "version": "1.2.0", + "description": "分段器由至少 2 个分段控件组成,用作不同视图的显示", + "keywords": [ + "uni-ui", + "uniui", + "分段器", + "segement", + "顶部选择" +], + "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-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..cb9d367 --- /dev/null +++ b/uni_modules/uni-steps/changelog.md @@ -0,0 +1,16 @@ +## 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..a6c8f28 --- /dev/null +++ b/uni_modules/uni-steps/components/uni-steps/uni-steps.vue @@ -0,0 +1,269 @@ + + + + + diff --git a/uni_modules/uni-steps/package.json b/uni_modules/uni-steps/package.json new file mode 100644 index 0000000..c687b40 --- /dev/null +++ b/uni_modules/uni-steps/package.json @@ -0,0 +1,89 @@ +{ + "id": "uni-steps", + "displayName": "uni-steps 步骤条", + "version": "1.1.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" + } + } + } + } +} \ 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..c916427 --- /dev/null +++ b/uni_modules/uni-swipe-action/changelog.md @@ -0,0 +1,43 @@ +## 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..d79c297 --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue @@ -0,0 +1,347 @@ + + + + + + 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 @@ + + + + + diff --git a/uni_modules/uni-swipe-action/package.json b/uni_modules/uni-swipe-action/package.json new file mode 100644 index 0000000..47651a6 --- /dev/null +++ b/uni_modules/uni-swipe-action/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-swipe-action", + "displayName": "uni-swipe-action 滑动操作", + "version": "1.3.8", + "description": "SwipeAction 滑动操作操作组件", + "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", + "联盟": "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..46eb8c1 --- /dev/null +++ b/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue @@ -0,0 +1,218 @@ + + + + + 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..9f87c67 --- /dev/null +++ b/uni_modules/uni-table/changelog.md @@ -0,0 +1,27 @@ +## 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..21d9527 --- /dev/null +++ b/uni_modules/uni-table/components/uni-table/uni-table.vue @@ -0,0 +1,455 @@ + + + + + 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..fbe1bdc --- /dev/null +++ b/uni_modules/uni-table/components/uni-tbody/uni-tbody.vue @@ -0,0 +1,29 @@ + + + + + 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..9ce93e9 --- /dev/null +++ b/uni_modules/uni-table/components/uni-td/uni-td.vue @@ -0,0 +1,90 @@ + + + + + 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 @@ + + + + + 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..14889dd --- /dev/null +++ b/uni_modules/uni-table/components/uni-th/uni-th.vue @@ -0,0 +1,285 @@ + + + + + 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..0dd18cd --- /dev/null +++ b/uni_modules/uni-table/components/uni-thead/uni-thead.vue @@ -0,0 +1,129 @@ + + + + + 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 @@ + + + + + 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..f9b9671 --- /dev/null +++ b/uni_modules/uni-table/components/uni-tr/uni-tr.vue @@ -0,0 +1,171 @@ + + + + + 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..7c2f91c --- /dev/null +++ b/uni_modules/uni-table/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-table", + "displayName": "uni-table 表格", + "version": "1.2.3", + "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" + }, + "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" + } + } + } + } +} \ No newline at end of file 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..c0c5839 --- /dev/null +++ b/uni_modules/uni-tag/changelog.md @@ -0,0 +1,21 @@ +## 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..6378a0b --- /dev/null +++ b/uni_modules/uni-tag/components/uni-tag/uni-tag.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/uni_modules/uni-tag/package.json b/uni_modules/uni-tag/package.json new file mode 100644 index 0000000..1878088 --- /dev/null +++ b/uni_modules/uni-tag/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-tag", + "displayName": "uni-tag 标签", + "version": "2.1.0", + "description": "Tag 组件,用于展示1个或多个文字标签,可点击切换选中、不选中的状态。", + "keywords": [ + "uni-ui", + "uniui", + "", + "tag", + "标签" +], + "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-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-test/changelog.md b/uni_modules/uni-test/changelog.md new file mode 100644 index 0000000..2f3b102 --- /dev/null +++ b/uni_modules/uni-test/changelog.md @@ -0,0 +1,39 @@ +## 2.0.13(2021-11-18) +邱 +## 2.0.12(2021-11-18) +123123 +## 2.0.11(2021-11-18) +0000 +## 2.0.10(2021-11-18) +111234 +## 2.0.9(2021-11-18) +3333 +## 2.0.8(2021-11-18) +=== +## 2.0.7(2021-11-18) +111 +## 2.0.6(2021-05-26) +- test +## 0.0.37(2021-03-23) +- uni-forms 更新 校验器 +- uni-forms 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug + + +## 0.0.36(2021-03-23) +- uni-forms 更新 校验器 +- uni-forms 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug + + +## 0.0.35(2021-03-23) +- uni-forms 更新 校验器 +- uni-forms 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug + + +## 0.0.34(2021-03-23) +- 测试新同步插件 +## 0.0.33(2021-03-09) +- test +## 0.0.32(2021-02-24) +- 更新 read 2 +## 0.0.31(2021-02-24) +- 同步 readme.md diff --git a/uni_modules/uni-test/components/uni-test/uni-test.vue b/uni_modules/uni-test/components/uni-test/uni-test.vue new file mode 100644 index 0000000..9ea8aaf --- /dev/null +++ b/uni_modules/uni-test/components/uni-test/uni-test.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/uni_modules/uni-test/package.json b/uni_modules/uni-test/package.json new file mode 100644 index 0000000..9a3c4c4 --- /dev/null +++ b/uni_modules/uni-test/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-test", + "displayName": "Test 测试插件", + "version": "2.0.13", + "description": "测试插件 ", + "keywords": [ + "test" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "^3.1.3" + }, + "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" + } + } + } + } +} diff --git a/uni_modules/uni-test/readme.md b/uni_modules/uni-test/readme.md new file mode 100644 index 0000000..ddb24c6 --- /dev/null +++ b/uni_modules/uni-test/readme.md @@ -0,0 +1,10 @@ + + +## DataCheckbox 数据驱动的单选复选框 +> **组件名:uni-data-checkbox** +> 代码块: `uDataCheckbox` + + +本组件是基于uni-app基础组件checkbox的封装。本组件要解决问题包括: + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-card) \ No newline at end of file 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 @@ + + + + + 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..00f1572 --- /dev/null +++ b/uni_modules/uni-tooltip/changelog.md @@ -0,0 +1,10 @@ +## 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..ffbb6fa --- /dev/null +++ b/uni_modules/uni-tooltip/components/uni-tooltip/uni-tooltip.vue @@ -0,0 +1,68 @@ + + + + + + diff --git a/uni_modules/uni-tooltip/package.json b/uni_modules/uni-tooltip/package.json new file mode 100644 index 0000000..e88ecf8 --- /dev/null +++ b/uni_modules/uni-tooltip/package.json @@ -0,0 +1,88 @@ +{ + "id": "uni-tooltip", + "displayName": "uni-tooltip 提示文字", + "version": "0.2.1", + "description": "Tooltip 提示文字", + "keywords": [ + "uni-tooltip", + "uni-ui", + "tooltip", + "tip", + "文字提示" + ], + "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": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "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..b1a824b --- /dev/null +++ b/uni_modules/uni-transition/changelog.md @@ -0,0 +1,20 @@ +## 1.3.1(2021-11-23) +- 修复 init 方法初始化问题 +## 1.3.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition) +## 1.2.1(2021-09-27) +- 修复 init 方法不生效的 Bug +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.1(2021-05-12) +- 新增 示例地址 +- 修复 示例项目缺少组件的 Bug +## 1.1.0(2021-04-22) +- 新增 通过方法自定义动画 +- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式 +- 优化 动画触发逻辑,使动画更流畅 +- 优化 支持单独的动画类型 +- 优化 文档示例 +## 1.0.2(2021-02-05) +- 调整为 uni_modules 目录规范 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..a2bf104 --- /dev/null +++ b/uni_modules/uni-transition/components/uni-transition/uni-transition.vue @@ -0,0 +1,281 @@ + + + + + diff --git a/uni_modules/uni-transition/package.json b/uni_modules/uni-transition/package.json new file mode 100644 index 0000000..d15fdf0 --- /dev/null +++ b/uni_modules/uni-transition/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-transition", + "displayName": "uni-transition 过渡动画", + "version": "1.3.1", + "description": "元素的简单过渡动画", + "keywords": [ + "uni-ui", + "uniui", + "动画", + "过渡", + "过渡动画" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": ["uni-scss"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} \ 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..61b26d0 --- /dev/null +++ b/uni_modules/uni-ui/changelog.md @@ -0,0 +1,541 @@ +## 1.4.27(2023-04-23) +- 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-badge/uni-badge.vue b/uni_modules/uni-ui/components/uni-badge/uni-badge.vue new file mode 100644 index 0000000..4291fbc --- /dev/null +++ b/uni_modules/uni-ui/components/uni-badge/uni-badge.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-calendar/calendar.js b/uni_modules/uni-ui/components/uni-calendar/calendar.js new file mode 100644 index 0000000..b8d7d6f --- /dev/null +++ b/uni_modules/uni-ui/components/uni-calendar/calendar.js @@ -0,0 +1,546 @@ +/** +* @1900-2100区间内的公历、农历互转 +* @charset UTF-8 +* @github https://github.com/jjonline/calendar.js +* @Author Jea杨(JJonline@JJonline.Cn) +* @Time 2014-7-21 +* @Time 2016-8-13 Fixed 2033hex、Attribution Annals +* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug +* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year +* @Version 1.0.3 +* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] +* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] +*/ +/* eslint-disable */ +var calendar = { + + /** + * 农历1900-2100的润大小信息表 + * @Array Of Property + * @return Hex + */ + lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909 + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919 + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929 + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939 + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949 + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959 + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969 + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979 + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989 + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999 + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009 + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019 + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049 + /** Add By JJonline@JJonline.Cn**/ + 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059 + 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069 + 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079 + 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089 + 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099 + 0x0d520], // 2100 + + /** + * 公历每个月份的天数普通表 + * @Array Of Property + * @return Number + */ + solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + + /** + * 天干地支之天干速查表 + * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] + * @return Cn string + */ + Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], + + /** + * 天干地支之地支速查表 + * @Array Of Property + * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] + * @return Cn string + */ + Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], + + /** + * 天干地支之地支速查表<=>生肖 + * @Array Of Property + * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] + * @return Cn string + */ + Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], + + /** + * 24节气速查表 + * @Array Of Property + * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] + * @return Cn string + */ + solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], + + /** + * 1900-2100各年的24节气日期速查表 + * @Array Of Property + * @return 0x string For splice + */ + sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', + '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', + 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', + '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', + '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', + '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', + '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', + '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', + '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', + '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', + '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', + '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], + + /** + * 数字转中文速查表 + * @Array Of Property + * @trans ['日','一','二','三','四','五','六','七','八','九','十'] + * @return Cn string + */ + nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], + + /** + * 日期转农历称呼速查表 + * @Array Of Property + * @trans ['初','十','廿','卅'] + * @return Cn string + */ + nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], + + /** + * 月份转农历称呼速查表 + * @Array Of Property + * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] + * @return Cn string + */ + nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], + + /** + * 返回农历y年一整年的总天数 + * @param lunar Year + * @return Number + * @eg:var count = calendar.lYearDays(1987) ;//count=387 + */ + lYearDays: function (y) { + var i; var sum = 348 + for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } + return (sum + this.leapDays(y)) + }, + + /** + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 + * @param lunar Year + * @return Number (0-12) + * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 + */ + leapMonth: function (y) { // 闰字编码 \u95f0 + return (this.lunarInfo[y - 1900] & 0xf) + }, + + /** + * 返回农历y年闰月的天数 若该年没有闰月则返回0 + * @param lunar Year + * @return Number (0、29、30) + * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 + */ + leapDays: function (y) { + if (this.leapMonth(y)) { + return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) + } + return (0) + }, + + /** + * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 + * @param lunar Year + * @return Number (-1、29、30) + * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 + */ + monthDays: function (y, m) { + if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1 + return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) + }, + + /** + * 返回公历(!)y年m月的天数 + * @param solar Year + * @return Number (-1、28、29、30、31) + * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 + */ + solarDays: function (y, m) { + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var ms = m - 1 + if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29 + return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) + } else { + return (this.solarMonth[ms]) + } + }, + + /** + * 农历年份转换为干支纪年 + * @param lYear 农历年的年份数 + * @return Cn string + */ + toGanZhiYear: function (lYear) { + var ganKey = (lYear - 3) % 10 + var zhiKey = (lYear - 3) % 12 + if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干 + if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支 + return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] + }, + + /** + * 公历月、日判断所属星座 + * @param cMonth [description] + * @param cDay [description] + * @return Cn string + */ + toAstro: function (cMonth, cDay) { + var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' + var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] + return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座 + }, + + /** + * 传入offset偏移量返回干支 + * @param offset 相对甲子的偏移量 + * @return Cn string + */ + toGanZhi: function (offset) { + return this.Gan[offset % 10] + this.Zhi[offset % 12] + }, + + /** + * 传入公历(!)y年获得该年第n个节气的公历日期 + * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 + * @return day Number + * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 + */ + getTerm: function (y, n) { + if (y < 1900 || y > 2100) { return -1 } + if (n < 1 || n > 24) { return -1 } + var _table = this.sTermInfo[y - 1900] + var _info = [ + parseInt('0x' + _table.substr(0, 5)).toString(), + parseInt('0x' + _table.substr(5, 5)).toString(), + parseInt('0x' + _table.substr(10, 5)).toString(), + parseInt('0x' + _table.substr(15, 5)).toString(), + parseInt('0x' + _table.substr(20, 5)).toString(), + parseInt('0x' + _table.substr(25, 5)).toString() + ] + var _calday = [ + _info[0].substr(0, 1), + _info[0].substr(1, 2), + _info[0].substr(3, 1), + _info[0].substr(4, 2), + + _info[1].substr(0, 1), + _info[1].substr(1, 2), + _info[1].substr(3, 1), + _info[1].substr(4, 2), + + _info[2].substr(0, 1), + _info[2].substr(1, 2), + _info[2].substr(3, 1), + _info[2].substr(4, 2), + + _info[3].substr(0, 1), + _info[3].substr(1, 2), + _info[3].substr(3, 1), + _info[3].substr(4, 2), + + _info[4].substr(0, 1), + _info[4].substr(1, 2), + _info[4].substr(3, 1), + _info[4].substr(4, 2), + + _info[5].substr(0, 1), + _info[5].substr(1, 2), + _info[5].substr(3, 1), + _info[5].substr(4, 2) + ] + return parseInt(_calday[n - 1]) + }, + + /** + * 传入农历数字月份返回汉语通俗表示法 + * @param lunar month + * @return Cn string + * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' + */ + toChinaMonth: function (m) { // 月 => \u6708 + if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1 + var s = this.nStr3[m - 1] + s += '\u6708'// 加上月字 + return s + }, + + /** + * 传入农历日期数字返回汉字表示法 + * @param lunar day + * @return Cn string + * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' + */ + toChinaDay: function (d) { // 日 => \u65e5 + var s + switch (d) { + case 10: + s = '\u521d\u5341'; break + case 20: + s = '\u4e8c\u5341'; break + break + case 30: + s = '\u4e09\u5341'; break + break + default : + s = this.nStr2[Math.floor(d / 10)] + s += this.nStr1[d % 10] + } + return (s) + }, + + /** + * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” + * @param y year + * @return Cn string + * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' + */ + getAnimal: function (y) { + return this.Animals[(y - 4) % 12] + }, + + /** + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON + * @param y solar year + * @param m solar month + * @param d solar day + * @return JSON object + * @eg:console.log(calendar.solar2lunar(1987,11,01)); + */ + solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31 + // 年份限定、上限 + if (y < 1900 || y > 2100) { + return -1// undefined转换为数字变为NaN + } + // 公历传参最下限 + if (y == 1900 && m == 1 && d < 31) { + return -1 + } + // 未传参 获得当天 + if (!y) { + var objDate = new Date() + } else { + var objDate = new Date(y, parseInt(m) - 1, d) + } + var i; var leap = 0; var temp = 0 + // 修正ymd参数 + var y = objDate.getFullYear() + var m = objDate.getMonth() + 1 + var d = objDate.getDate() + var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 + for (i = 1900; i < 2101 && offset > 0; i++) { + temp = this.lYearDays(i) + offset -= temp + } + if (offset < 0) { + offset += temp; i-- + } + + // 是否今天 + var isTodayObj = new Date() + var isToday = false + if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { + isToday = true + } + // 星期几 + var nWeek = objDate.getDay() + var cWeek = this.nStr1[nWeek] + // 数字表示周几顺应天朝周一开始的惯例 + if (nWeek == 0) { + nWeek = 7 + } + // 农历年 + var year = i + var leap = this.leapMonth(i) // 闰哪个月 + var isLeap = false + + // 效验闰月 + for (i = 1; i < 13 && offset > 0; i++) { + // 闰月 + if (leap > 0 && i == (leap + 1) && isLeap == false) { + --i + isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数 + } else { + temp = this.monthDays(year, i)// 计算农历普通月天数 + } + // 解除闰月 + if (isLeap == true && i == (leap + 1)) { isLeap = false } + offset -= temp + } + // 闰月导致数组下标重叠取反 + if (offset == 0 && leap > 0 && i == leap + 1) { + if (isLeap) { + isLeap = false + } else { + isLeap = true; --i + } + } + if (offset < 0) { + offset += temp; --i + } + // 农历月 + var month = i + // 农历日 + var day = offset + 1 + // 天干地支处理 + var sm = m - 1 + var gzY = this.toGanZhiYear(year) + + // 当月的两个节气 + // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` + var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始 + var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始 + + // 依据12节气修正干支月 + var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) + if (d >= firstNode) { + gzM = this.toGanZhi((y - 1900) * 12 + m + 12) + } + + // 传入的日期的节气与否 + var isTerm = false + var Term = null + if (firstNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 2] + } + if (secondNode == d) { + isTerm = true + Term = this.solarTerm[m * 2 - 1] + } + // 日柱 当月一日与 1900/1/1 相差天数 + var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 + var gzD = this.toGanZhi(dayCyclical + d - 1) + // 该日期所属的星座 + var astro = this.toAstro(m, d) + + return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } + }, + + /** + * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON + * @param y lunar year + * @param m lunar month + * @param d lunar day + * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] + * @return JSON object + * @eg:console.log(calendar.lunar2solar(1987,9,10)); + */ + lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1 + var isLeapMonth = !!isLeapMonth + var leapOffset = 0 + var leapMonth = this.leapMonth(y) + var leapDay = this.leapDays(y) + if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 + if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值 + var day = this.monthDays(y, m) + var _day = day + // bugFix 2016-9-25 + // if month is leap, _day use leapDays method + if (isLeapMonth) { + _day = this.leapDays(y, m) + } + if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验 + + // 计算农历的时间差 + var offset = 0 + for (var i = 1900; i < y; i++) { + offset += this.lYearDays(i) + } + var leap = 0; var isAdd = false + for (var i = 1; i < m; i++) { + leap = this.leapMonth(y) + if (!isAdd) { // 处理闰月 + if (leap <= i && leap > 0) { + offset += this.leapDays(y); isAdd = true + } + } + offset += this.monthDays(y, i) + } + // 转换闰月农历 需补充该年闰月的前一个月的时差 + if (isLeapMonth) { offset += day } + // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) + var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) + var calObj = new Date((offset + d - 31) * 86400000 + stmap) + var cY = calObj.getUTCFullYear() + var cM = calObj.getUTCMonth() + 1 + var cD = calObj.getUTCDate() + + return this.solar2lunar(cY, cM, cD) + } +} + +export default calendar diff --git a/uni_modules/uni-ui/components/uni-calendar/uni-calendar-item.vue b/uni_modules/uni-ui/components/uni-calendar/uni-calendar-item.vue new file mode 100644 index 0000000..c66a58d --- /dev/null +++ b/uni_modules/uni-ui/components/uni-calendar/uni-calendar-item.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-calendar/uni-calendar.vue b/uni_modules/uni-ui/components/uni-calendar/uni-calendar.vue new file mode 100644 index 0000000..9c856cc --- /dev/null +++ b/uni_modules/uni-ui/components/uni-calendar/uni-calendar.vue @@ -0,0 +1,505 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-calendar/util.js b/uni_modules/uni-ui/components/uni-calendar/util.js new file mode 100644 index 0000000..37f4432 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-calendar/util.js @@ -0,0 +1,352 @@ +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) { + dd.setDate(dd.getDate() + AddDayCount) + } else { + dd.setMonth(dd.getMonth() + AddDayCount) // 获取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 isinfo = false + 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) + } + + if (this.endDate) { + let dateCompAfter = this.dateCompare(fullDate, this.endDate) + disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate) + } + let multiples = this.multipleStatus.data + let checked = false + let multiplesStatus = -1 + if (this.range) { + if (multiples) { + multiplesStatus = multiples.findIndex((item) => { + return this.dateEqual(item, nowDate) + }) + } + if (multiplesStatus !== -1) { + checked = true + } + } + let data = { + fullDate: nowDate, + year: full.year, + date: i, + multiple: this.range ? checked : false, + beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate), + afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate), + month: full.month, + lunar: this.getlunar(full.year, full.month, i), + disable: !disableBefore || !disableAfter, + isDay + } + if (info) { + data.extraInfo = info + } + + dateArr.push(data) + } + return dateArr + } + /** + * 获取下月天数 + */ + _getNextMonthDays(surplus, full) { + let dateArr = [] + for (let i = 1; i < surplus + 1; i++) { + dateArr.push({ + date: i, + month: Number(full.month) + 1, + lunar: this.getlunar(full.year, Number(full.month) + 1, i), + disable: true + }) + } + return dateArr + } + + /** + * 获取当前日期详情 + * @param {Object} date + */ + getInfo(date) { + if (!date) { + date = new Date() + } + const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate) + return dateInfo + } + + /** + * 比较时间大小 + */ + dateCompare(startDate, endDate) { + // 计算截止时间 + startDate = new Date(startDate.replace('-', '/').replace('-', '/')) + // 计算详细项的截止时间 + endDate = new Date(endDate.replace('-', '/').replace('-', '/')) + if (startDate <= endDate) { + return true + } else { + return false + } + } + + /** + * 比较时间是否相等 + */ + dateEqual(before, after) { + // 计算截止时间 + before = new Date(before.replace('-', '/').replace('-', '/')) + // 计算详细项的截止时间 + after = new Date(after.replace('-', '/').replace('-', '/')) + if (before.getTime() - after.getTime() === 0) { + return true + } else { + return false + } + } + + + /** + * 获取日期范围内所有日期 + * @param {Object} begin + * @param {Object} end + */ + geDateAll(begin, end) { + var arr = [] + var ab = begin.split('-') + var ae = end.split('-') + var db = new Date() + db.setFullYear(ab[0], ab[1] - 1, ab[2]) + var de = new Date() + de.setFullYear(ae[0], ae[1] - 1, ae[2]) + var unixDb = db.getTime() - 24 * 60 * 60 * 1000 + var unixDe = de.getTime() - 24 * 60 * 60 * 1000 + for (var k = unixDb; k <= unixDe;) { + k = k + 24 * 60 * 60 * 1000 + arr.push(this.getDate(new Date(parseInt(k))).fullDate) + } + return arr + } + /** + * 计算阴历日期显示 + */ + getlunar(year, month, date) { + return CALENDAR.solar2lunar(year, month, date) + } + /** + * 设置打点 + */ + setSelectInfo(data, value) { + this.selected = value + this._getWeek(data) + } + + /** + * 获取多选状态 + */ + setMultiple(fullDate) { + let { + before, + after + } = this.multipleStatus + + if (!this.range) return + if (before && after) { + this.multipleStatus.before = '' + this.multipleStatus.after = '' + this.multipleStatus.data = [] + } else { + if (!before) { + this.multipleStatus.before = fullDate + } else { + this.multipleStatus.after = fullDate + if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after); + } else { + this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before); + } + } + } + this._getWeek(fullDate) + } + + /** + * 获取每周数据 + * @param {Object} dateData + */ + _getWeek(dateData) { + const { + fullDate, + year, + month, + date, + day + } = 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-ui/components/uni-card/uni-card.vue b/uni_modules/uni-ui/components/uni-card/uni-card.vue new file mode 100644 index 0000000..fdebf7e --- /dev/null +++ b/uni_modules/uni-ui/components/uni-card/uni-card.vue @@ -0,0 +1,403 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-collapse-item/uni-collapse-item.vue b/uni_modules/uni-ui/components/uni-collapse-item/uni-collapse-item.vue new file mode 100644 index 0000000..de0cdc5 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-collapse-item/uni-collapse-item.vue @@ -0,0 +1,218 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-collapse/uni-collapse.vue b/uni_modules/uni-ui/components/uni-collapse/uni-collapse.vue new file mode 100644 index 0000000..bb3745f --- /dev/null +++ b/uni_modules/uni-ui/components/uni-collapse/uni-collapse.vue @@ -0,0 +1,59 @@ + + + diff --git a/uni_modules/uni-ui/components/uni-combox/uni-combox.vue b/uni_modules/uni-ui/components/uni-combox/uni-combox.vue new file mode 100644 index 0000000..5f5786d --- /dev/null +++ b/uni_modules/uni-ui/components/uni-combox/uni-combox.vue @@ -0,0 +1,213 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-countdown/uni-countdown.vue b/uni_modules/uni-ui/components/uni-countdown/uni-countdown.vue new file mode 100644 index 0000000..7e9c508 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-countdown/uni-countdown.vue @@ -0,0 +1,211 @@ + + + diff --git a/uni_modules/uni-ui/components/uni-data-checkbox/clientdb.js b/uni_modules/uni-ui/components/uni-data-checkbox/clientdb.js new file mode 100644 index 0000000..ff7501b --- /dev/null +++ b/uni_modules/uni-ui/components/uni-data-checkbox/clientdb.js @@ -0,0 +1,316 @@ + +const events = { + load: 'load', + error: 'error' +} +const pageMode = { + add: 'add', + replace: 'replace' +} + +const attrs = [ + 'pageCurrent', + 'pageSize', + 'collection', + 'action', + 'field', + 'getcount', + 'orderby', + 'where' +] + +export default { + data() { + return { + loading: false, + listData: this.getone ? {} : [], + paginationInternal: { + current: this.pageCurrent, + size: this.pageSize, + count: 0 + }, + errorMessage: '' + } + }, + created() { + let db = null; + let dbCmd = null; + + if(this.collection){ + this.db = uniCloud.database(); + this.dbCmd = this.db.command; + } + + this._isEnded = false + + this.$watch(() => { + var al = [] + attrs.forEach(key => { + al.push(this[key]) + }) + return al + }, (newValue, oldValue) => { + this.paginationInternal.pageSize = this.pageSize + + let needReset = false + for (let i = 2; i < newValue.length; i++) { + if (newValue[i] != oldValue[i]) { + needReset = true + break + } + } + if (needReset) { + this.clear() + this.reset() + } + if (newValue[0] != oldValue[0]) { + this.paginationInternal.current = this.pageCurrent + } + + this._execLoadData() + }) + + // #ifdef H5 + if (process.env.NODE_ENV === 'development') { + this._debugDataList = [] + if (!window.unidev) { + window.unidev = { + clientDB: { + data: [] + } + } + } + unidev.clientDB.data.push(this._debugDataList) + } + // #endif + + // #ifdef MP-TOUTIAO + let changeName + let events = this.$scope.dataset.eventOpts + for (var i = 0; i < events.length; i++) { + let event = events[i] + if (event[0].includes('^load')) { + changeName = event[1][0][0] + } + } + if (changeName) { + let parent = this.$parent + let maxDepth = 16 + this._changeDataFunction = null + while (parent && maxDepth > 0) { + let fun = parent[changeName] + if (fun && typeof fun === 'function') { + this._changeDataFunction = fun + maxDepth = 0 + break + } + parent = parent.$parent + maxDepth--; + } + } + // #endif + + // if (!this.manual) { + // this.loadData() + // } + }, + // #ifdef H5 + beforeDestroy() { + if (process.env.NODE_ENV === 'development' && window.unidev) { + var cd = this._debugDataList + var dl = unidev.clientDB.data + for (var i = dl.length - 1; i >= 0; i--) { + if (dl[i] === cd) { + dl.splice(i, 1) + break + } + } + } + }, + // #endif + methods: { + loadData(args1, args2) { + let callback = null + if (typeof args1 === 'object') { + if (args1.clear) { + this.clear() + this.reset() + } + if (args1.current !== undefined) { + this.paginationInternal.current = args1.current + } + if (typeof args2 === 'function') { + callback = args2 + } + } else if (typeof args1 === 'function') { + callback = args1 + } + + this._execLoadData(callback) + }, + loadMore() { + if (this._isEnded) { + return + } + this._execLoadData() + }, + refresh() { + this.clear() + this._execLoadData() + }, + clear() { + this._isEnded = false + this.listData = [] + }, + reset() { + this.paginationInternal.current = 1 + }, + remove(id, { + action, + callback, + confirmTitle, + confirmContent + } = {}) { + if (!id || !id.length) { + return + } + uni.showModal({ + title: confirmTitle || '提示', + content: confirmContent || '是否删除该数据', + showCancel: true, + success: (res) => { + if (!res.confirm) { + return + } + this._execRemove(id, action, callback) + } + }) + }, + _execLoadData(callback) { + if (this.loading) { + return + } + this.loading = true + this.errorMessage = '' + + this._getExec().then((res) => { + this.loading = false + const { + data, + count + } = res.result + this._isEnded = data.length < this.pageSize + + callback && callback(data, this._isEnded) + this._dispatchEvent(events.load, data) + + if (this.getone) { + this.listData = data.length ? data[0] : undefined + } else if (this.pageData === pageMode.add) { + this.listData.push(...data) + if (this.listData.length) { + this.paginationInternal.current++ + } + } else if (this.pageData === pageMode.replace) { + this.listData = data + this.paginationInternal.count = count + } + + // #ifdef H5 + if (process.env.NODE_ENV === 'development') { + this._debugDataList.length = 0 + this._debugDataList.push(...JSON.parse(JSON.stringify(this.listData))) + } + // #endif + }).catch((err) => { + this.loading = false + this.errorMessage = err + callback && callback() + this.$emit(events.error, err) + }) + }, + _getExec() { + let exec = this.db + if (this.action) { + exec = exec.action(this.action) + } + + exec = exec.collection(this.collection) + + if (!(!this.where || !Object.keys(this.where).length)) { + exec = exec.where(this.where) + } + if (this.field) { + exec = exec.field(this.field) + } + if (this.orderby) { + exec = exec.orderBy(this.orderby) + } + + const { + current, + size + } = this.paginationInternal + exec = exec.skip(size * (current - 1)).limit(size).get({ + getCount: this.getcount + }) + + return exec + }, + _execRemove(id, action, callback) { + if (!this.collection || !id) { + return + } + + const ids = Array.isArray(id) ? id : [id] + if (!ids.length) { + return + } + + uni.showLoading({ + mask: true + }) + + let exec = this.db + if (action) { + exec = exec.action(action) + } + + exec.collection(this.collection).where({ + _id: dbCmd.in(ids) + }).remove().then((res) => { + callback && callback(res.result) + if (this.pageData === pageMode.replace) { + this.refresh() + } else { + this.removeData(ids) + } + }).catch((err) => { + uni.showModal({ + content: err.message, + showCancel: false + }) + }).finally(() => { + uni.hideLoading() + }) + }, + removeData(ids) { + let il = ids.slice(0) + let dl = this.listData + for (let i = dl.length - 1; i >= 0; i--) { + let index = il.indexOf(dl[i]._id) + if (index >= 0) { + dl.splice(i, 1) + il.splice(index, 1) + } + } + }, + _dispatchEvent(type, data) { + if (this._changeDataFunction) { + this._changeDataFunction(data, this._isEnded) + } else { + this.$emit(type, data, this._isEnded) + } + } + } +} diff --git a/uni_modules/uni-ui/components/uni-data-checkbox/uni-data-checkbox.vue b/uni_modules/uni-ui/components/uni-data-checkbox/uni-data-checkbox.vue new file mode 100644 index 0000000..40d1412 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-data-checkbox/uni-data-checkbox.vue @@ -0,0 +1,826 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-dateformat/date-format.js b/uni_modules/uni-ui/components/uni-dateformat/date-format.js new file mode 100644 index 0000000..1939135 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-dateformat/date-format.js @@ -0,0 +1,191 @@ +// 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': + 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 && 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-ui/components/uni-dateformat/uni-dateformat.vue b/uni_modules/uni-ui/components/uni-dateformat/uni-dateformat.vue new file mode 100644 index 0000000..487908c --- /dev/null +++ b/uni_modules/uni-ui/components/uni-dateformat/uni-dateformat.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-datetime-picker/uni-datetime-picker.vue b/uni_modules/uni-ui/components/uni-datetime-picker/uni-datetime-picker.vue new file mode 100644 index 0000000..fd735e2 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-datetime-picker/uni-datetime-picker.vue @@ -0,0 +1,355 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-drawer/uni-drawer.vue b/uni_modules/uni-ui/components/uni-drawer/uni-drawer.vue new file mode 100644 index 0000000..ecf6b2f --- /dev/null +++ b/uni_modules/uni-ui/components/uni-drawer/uni-drawer.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-easyinput/common.js b/uni_modules/uni-ui/components/uni-easyinput/common.js new file mode 100644 index 0000000..df9abe1 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-easyinput/common.js @@ -0,0 +1,56 @@ +/** + * @desc 函数防抖 + * @param func 目标函数 + * @param wait 延迟执行毫秒数 + * @param immediate true - 立即执行, false - 延迟执行 + */ +export const debounce = function(func, wait = 1000, immediate = true) { + let timer; + console.log(1); + return function() { + console.log(123); + 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-ui/components/uni-easyinput/uni-easyinput.vue b/uni_modules/uni-ui/components/uni-easyinput/uni-easyinput.vue new file mode 100644 index 0000000..e791d84 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-easyinput/uni-easyinput.vue @@ -0,0 +1,401 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-fab/uni-fab.vue b/uni_modules/uni-ui/components/uni-fab/uni-fab.vue new file mode 100644 index 0000000..c702895 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-fab/uni-fab.vue @@ -0,0 +1,433 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-fav/uni-fav.vue b/uni_modules/uni-ui/components/uni-fav/uni-fav.vue new file mode 100644 index 0000000..46a5ab8 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-fav/uni-fav.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/uni_modules/uni-ui/components/uni-field/uni-field.vue b/uni_modules/uni-ui/components/uni-field/uni-field.vue new file mode 100644 index 0000000..3884356 --- /dev/null +++ b/uni_modules/uni-ui/components/uni-field/uni-field.vue @@ -0,0 +1,686 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-textarea/package.json b/uni_modules/uv-textarea/package.json new file mode 100644 index 0000000..7df2034 --- /dev/null +++ b/uni_modules/uv-textarea/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-textarea", + "displayName": "uv-textarea 文本域 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.11", + "description": "文本域此组件满足了可能出现的表单信息补充,编辑等实际逻辑的功能,内置了字数校验等。", + "keywords": [ + "uv-textarea", + "uvui", + "uv-ui", + "textarea", + "文本域" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-textarea/readme.md b/uni_modules/uv-textarea/readme.md new file mode 100644 index 0000000..6a64819 --- /dev/null +++ b/uni_modules/uv-textarea/readme.md @@ -0,0 +1,19 @@ +## Textarea 文本域 + +> **组件名:uv-textarea** + +文本域此组件满足了可能出现的表单信息补充,编辑等实际逻辑的功能,内置了字数校验等。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-toast/changelog.md b/uni_modules/uv-toast/changelog.md new file mode 100644 index 0000000..7858c41 --- /dev/null +++ b/uni_modules/uv-toast/changelog.md @@ -0,0 +1,10 @@ +## 1.0.3(2023-12-06) +1. 增加z-index参数 +2. 增加overlay参数 +## 1.0.2(2023-10-13) +1. unmounted兼容vue3 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-toast 消息提示 diff --git a/uni_modules/uv-toast/components/uv-toast/uv-toast.vue b/uni_modules/uv-toast/components/uv-toast/uv-toast.vue new file mode 100644 index 0000000..5458a5e --- /dev/null +++ b/uni_modules/uv-toast/components/uv-toast/uv-toast.vue @@ -0,0 +1,333 @@ + + + \ No newline at end of file diff --git a/uni_modules/uv-toast/package.json b/uni_modules/uv-toast/package.json new file mode 100644 index 0000000..c77987b --- /dev/null +++ b/uni_modules/uv-toast/package.json @@ -0,0 +1,90 @@ +{ + "id": "uv-toast", + "displayName": "uv-toast 消息提示 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.3", + "description": "Toast 组件主要用于消息通知、加载提示、操作结果提示等醒目提示效果,我们为其提供了多种丰富的API。", + "keywords": [ + "uv-toast", + "uvui", + "uv-ui", + "toast", + "消息提示" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-overlay", + "uv-loading-icon", + "uv-gap" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-toast/readme.md b/uni_modules/uv-toast/readme.md new file mode 100644 index 0000000..a95a5ae --- /dev/null +++ b/uni_modules/uv-toast/readme.md @@ -0,0 +1,11 @@ +## Toast 消息提示 + +> **组件名:uv-toast** + +Toast 组件主要用于消息通知、加载提示、操作结果提示等醒目提示效果,我们为其提供了多种丰富的API。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/uni_modules/uv-toolbar/changelog.md b/uni_modules/uv-toolbar/changelog.md new file mode 100644 index 0000000..3acfcd6 --- /dev/null +++ b/uni_modules/uv-toolbar/changelog.md @@ -0,0 +1,2 @@ +## 1.0.0(2023-08-02) +1. 新增工具条组件 diff --git a/uni_modules/uv-toolbar/components/uv-toolbar/props.js b/uni_modules/uv-toolbar/components/uv-toolbar/props.js new file mode 100644 index 0000000..e332412 --- /dev/null +++ b/uni_modules/uv-toolbar/components/uv-toolbar/props.js @@ -0,0 +1,40 @@ +export default { + props: { + // 是否展示工具条 + show: { + type: Boolean, + default: true + }, + // 是否显示下边框 + showBorder: { + type: Boolean, + default: false + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: '取消' + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: '确认' + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: '#909193' + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: '#3c9cff' + }, + // 标题文字 + title: { + type: String, + default: '' + }, + ...uni.$uv?.props?.toolbar + } +} \ No newline at end of file diff --git a/uni_modules/uv-toolbar/components/uv-toolbar/uv-toolbar.vue b/uni_modules/uv-toolbar/components/uv-toolbar/uv-toolbar.vue new file mode 100644 index 0000000..0b3fc9e --- /dev/null +++ b/uni_modules/uv-toolbar/components/uv-toolbar/uv-toolbar.vue @@ -0,0 +1,109 @@ + + + + \ No newline at end of file diff --git a/uni_modules/uv-toolbar/package.json b/uni_modules/uv-toolbar/package.json new file mode 100644 index 0000000..d519665 --- /dev/null +++ b/uni_modules/uv-toolbar/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-toolbar", + "displayName": "uv-toolbar 工具条", + "version": "1.0.0", + "description": "该组价是仅用于uv-ui中一个公共小工具,提供一个取消和确定的样式,可以设置标题,主要用于弹窗顶部的选择确定工具条", + "keywords": [ + "uv-toolbar", + "uvui", + "uv-ui", + "工具条", + "工具" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-toolbar/readme.md b/uni_modules/uv-toolbar/readme.md new file mode 100644 index 0000000..b33643f --- /dev/null +++ b/uni_modules/uv-toolbar/readme.md @@ -0,0 +1,31 @@ +## Toolbar 工具条 + +> **组件名:uv-toolbar** + +该组价是仅用于uv-ui中一个公共小工具,提供一个取消和确定的样式,可以设置标题,主要用于弹窗顶部的选择确定工具条。 + +### 基本使用 + +```vue + +``` + +### Toolbar Props + +| 属性名 | 类型 | 默认值 | 说明 | +|:-|:-|:-|:-| +| show | Boolean | true | 是否展示工具条 | +| showBorder | Boolean | false | 是否显示下边框 | +| cancelText | String | '取消' | 取消按钮的文字 | +| confirmText | String | '确定' | 确定按钮的文字 | +| cancelColor | String | '#909193' | 取消按钮的颜色 | +| confirmColor | String | '#3c9cff' | 确认按钮的颜色 | +| title | String | - | 标题文字 | + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-tooltip/changelog.md b/uni_modules/uv-tooltip/changelog.md new file mode 100644 index 0000000..5009f54 --- /dev/null +++ b/uni_modules/uv-tooltip/changelog.md @@ -0,0 +1,13 @@ +## 1.0.5(2023-07-02) +修改VUE3模式不显示的BUG +## 1.0.4(2023-07-02) +uv-tooltip 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +## 1.0.3(2023-05-17) +1. 修复报错的BUG +## 1.0.2(2023-05-17) +1. vue2模式下报错的BUG修复 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-tooltip 长按提示 diff --git a/uni_modules/uv-tooltip/components/uv-tooltip/props.js b/uni_modules/uv-tooltip/components/uv-tooltip/props.js new file mode 100644 index 0000000..4130df5 --- /dev/null +++ b/uni_modules/uv-tooltip/components/uv-tooltip/props.js @@ -0,0 +1,60 @@ +export default { + props: { + // 需要显示的提示文字 + text: { + type: [String, Number], + default: '' + }, + // 点击复制按钮时,复制的文本,为空则使用text值 + copyText: { + type: [String, Number], + default: '' + }, + // 文本大小 + size: { + type: [String, Number], + default: 14 + }, + // 字体颜色 + color: { + type: String, + default: '#606266' + }, + // 弹出提示框时,文本的背景色 + bgColor: { + type: String, + default: 'transparent' + }, + // 弹出提示的方向,top-上方,bottom-下方 + direction: { + type: String, + default: 'top' + }, + // 弹出提示的z-index,nvue无效 + zIndex: { + type: [String, Number], + default: 10071 + }, + // 是否显示复制按钮 + showCopy: { + type: Boolean, + default: true + }, + // 扩展的按钮组 + buttons: { + type: Array, + default: () => [] + }, + // 是否显示透明遮罩以防止触摸穿透 + overlay: { + type: Boolean, + default: true + }, + // 是否显示复制成功或者失败的toast + showToast: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.tooltip + } +} \ No newline at end of file diff --git a/uni_modules/uv-tooltip/components/uv-tooltip/uv-tooltip.vue b/uni_modules/uv-tooltip/components/uv-tooltip/uv-tooltip.vue new file mode 100644 index 0000000..6e762d7 --- /dev/null +++ b/uni_modules/uv-tooltip/components/uv-tooltip/uv-tooltip.vue @@ -0,0 +1,372 @@ + + + + + diff --git a/uni_modules/uv-tooltip/package.json b/uni_modules/uv-tooltip/package.json new file mode 100644 index 0000000..092dd03 --- /dev/null +++ b/uni_modules/uv-tooltip/package.json @@ -0,0 +1,90 @@ +{ + "id": "uv-tooltip", + "displayName": "uv-tooltip 长按提示", + "version": "1.0.5", + "description": "Tooltip组件主要用于长按操作,类似微信的长按气泡。", + "keywords": [ + "uv-tooltip", + "uvui", + "uv-ui", + "tooltip", + "长按提示" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-overlay", + "uv-transition", + "uv-line" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-tooltip/readme.md b/uni_modules/uv-tooltip/readme.md new file mode 100644 index 0000000..9a97fcb --- /dev/null +++ b/uni_modules/uv-tooltip/readme.md @@ -0,0 +1,11 @@ +## Tooltip 长按提示 + +> **组件名:uv-tooltip** + +Tooltip组件主要用于长按操作,类似微信的长按气泡。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/uni_modules/uv-transition/changelog.md b/uni_modules/uv-transition/changelog.md new file mode 100644 index 0000000..59e4968 --- /dev/null +++ b/uni_modules/uv-transition/changelog.md @@ -0,0 +1,19 @@ +## 1.0.8(2023-10-18) +1. 修复在APP上不能正常显示的BUG +## 1.0.7(2023-10-12) +1. 修复部分情况,修改某属性自动关闭的BUG +## 1.0.6(2023-07-24) +1. 优化 nvue模式下增加cellChild参数,是否在list中cell节点下,nvue中cell下建议设置成true +## 1.0.5(2023-07-02) +修改VUE3模式下可能存在的BUG +## 1.0.4(2023-07-02) +uv-transition 动画组件,代码重构优化,性能更加友好,增加自定义动画功能。详情参考文档:https://www.uvui.cn/components/transition.html +## 1.0.3(2023-06-12) +1. 恢复this.$nextTick的使用,经过测试百度等平台无问题 +## 1.0.2(2023-05-23) +1. 百度小程序等平台不支持this.$nextick,修改成延时 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增动画组件 diff --git a/uni_modules/uv-transition/components/uv-transition/createAnimation.js b/uni_modules/uv-transition/components/uv-transition/createAnimation.js new file mode 100644 index 0000000..8f89b18 --- /dev/null +++ b/uni_modules/uv-transition/components/uv-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/uv-transition/components/uv-transition/props.js b/uni_modules/uv-transition/components/uv-transition/props.js new file mode 100644 index 0000000..e8b4e6b --- /dev/null +++ b/uni_modules/uv-transition/components/uv-transition/props.js @@ -0,0 +1,31 @@ +export default { + props: { + // 是否展示组件 + show: { + type: Boolean, + default: false + }, + // 使用的动画模式 + mode: { + type: [Array, String, null], + default() { + return 'fade' + } + }, + // 动画的执行时间,单位ms + duration: { + type: [String, Number], + default: 300 + }, + // 使用的动画过渡函数 + timingFunction: { + type: String, + default: 'ease-out' + }, + customClass: { + type: String, + default: '' + }, + ...uni.$uv?.props?.transition + } +} \ No newline at end of file diff --git a/uni_modules/uv-transition/components/uv-transition/uv-transition.vue b/uni_modules/uv-transition/components/uv-transition/uv-transition.vue new file mode 100644 index 0000000..cf9790d --- /dev/null +++ b/uni_modules/uv-transition/components/uv-transition/uv-transition.vue @@ -0,0 +1,320 @@ + + diff --git a/uni_modules/uv-transition/package.json b/uni_modules/uv-transition/package.json new file mode 100644 index 0000000..c05eadb --- /dev/null +++ b/uni_modules/uv-transition/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-transition", + "displayName": "uv-transition 动画 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.8", + "description": "transition 该组件用于组件的动画过渡效果。", + "keywords": [ + "uv-transition", + "uvui", + "uv-ui", + "transition", + "动画" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-transition/readme.md b/uni_modules/uv-transition/readme.md new file mode 100644 index 0000000..fbf8f59 --- /dev/null +++ b/uni_modules/uv-transition/readme.md @@ -0,0 +1,15 @@ +## Transition 动画 + +> **组件名:uv-transition** + +该组件用于组件的动画过渡效果,支持自定义动画,开箱即用。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 diff --git a/uni_modules/uv-ui-tools/changelog.md b/uni_modules/uv-ui-tools/changelog.md new file mode 100644 index 0000000..998373e --- /dev/null +++ b/uni_modules/uv-ui-tools/changelog.md @@ -0,0 +1,76 @@ +## 1.1.25(2024-01-20) +1.1.20版本更新 +## 1.1.24(2023-12-21) +1. luch-request更新 +## 1.1.23(2023-12-12) +1. 1.1.19版本 +## 1.1.22(2023-11-28) +1. 优化 +## 1.1.21(2023-11-10) +1. 1.1.17版本 +## 1.1.20(2023-10-30) +1. 1.1.16版本 +## 1.1.19(2023-10-13) +1. 兼容vue3 +## 1.1.18(2023-10-12) +1. 1.1.15版本 +## 1.1.17(2023-09-27) +1. 1.1.14版本发布 +## 1.1.16(2023-09-15) +1. 1.1.13版本发布 +## 1.1.15(2023-09-15) +1. 更新button.js相关按钮支持open-type="agreePrivacyAuthorization" +## 1.1.14(2023-09-14) +1. 优化dayjs +## 1.1.13(2023-09-13) +1. 优化,$uv中增加unit参数,方便组件中使用 +## 1.1.12(2023-09-10) +1. 升级版本 +## 1.1.11(2023-09-04) +1. 1.1.11版本 +## 1.1.10(2023-08-31) +1. 修复customStyle和customClass存在冲突的问题 +## 1.1.9(2023-08-27) +1. 版本升级 +2. 优化 +## 1.1.8(2023-08-24) +1. 版本升级 +## 1.1.7(2023-08-22) +1. 版本升级 +## 1.1.6(2023-08-18) +uvui版本:1.1.6 +## 1.0.15(2023-08-14) +1. 更新uvui版本号 +## 1.0.13(2023-08-06) +1. 优化 +## 1.0.12(2023-08-06) +1. 修改版本号 +## 1.0.11(2023-08-06) +1. 路由增加events参数 +2. 路由拦截修复 +## 1.0.10(2023-08-01) +1. 优化 +## 1.0.9(2023-06-28) +优化openType.js +## 1.0.8(2023-06-15) +1. 修改支付宝报错的BUG +## 1.0.7(2023-06-07) +1. 解决微信小程序使用uvui提示 Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors +2. 解决上述提示,需要在uni.scss配置$uvui-nvue-style: false; 然后在APP.vue下面引入uvui内置的基础样式:@import '@/uni_modules/uv-ui-tools/index.scss'; +## 1.0.6(2023-06-04) +1. uv-ui-tools 优化工具组件,兼容更多功能 +2. 小程序分享功能优化等 +## 1.0.5(2023-06-02) +1. 修改扩展使用mixin中方法的问题 +## 1.0.4(2023-05-23) +1. 兼容百度小程序修改bem函数 +## 1.0.3(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.2(2023-05-10) +1. 增加Http请求封装 +2. 优化 +## 1.0.1(2023-05-04) +1. 修改名称及备注 +## 1.0.0(2023-05-04) +1. uv-ui工具集首次发布 diff --git a/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue b/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue new file mode 100644 index 0000000..baf45e9 --- /dev/null +++ b/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue @@ -0,0 +1,6 @@ + + + diff --git a/uni_modules/uv-ui-tools/index.js b/uni_modules/uv-ui-tools/index.js new file mode 100644 index 0000000..71a8b66 --- /dev/null +++ b/uni_modules/uv-ui-tools/index.js @@ -0,0 +1,79 @@ +// 全局挂载引入http相关请求拦截插件 +import Request from './libs/luch-request' + +// 引入全局mixin +import mixin from './libs/mixin/mixin.js' +// 小程序特有的mixin +import mpMixin from './libs/mixin/mpMixin.js' +// #ifdef MP +import mpShare from './libs/mixin/mpShare.js' +// #endif + +// 路由封装 +import route from './libs/util/route.js' +// 公共工具函数 +import * as index from './libs/function/index.js' +// 防抖方法 +import debounce from './libs/function/debounce.js' +// 节流方法 +import throttle from './libs/function/throttle.js' +// 规则检验 +import * as test from './libs/function/test.js' + +// 颜色渐变相关,colorGradient-颜色渐变,hexToRgb-十六进制颜色转rgb颜色,rgbToHex-rgb转十六进制 +import * as colorGradient from './libs/function/colorGradient.js' + +// 配置信息 +import config from './libs/config/config.js' +// 平台 +import platform from './libs/function/platform' + +const $uv = { + route, + config, + test, + date: index.timeFormat, // 另名date + ...index, + colorGradient: colorGradient.colorGradient, + hexToRgb: colorGradient.hexToRgb, + rgbToHex: colorGradient.rgbToHex, + colorToRgba: colorGradient.colorToRgba, + http: new Request(), + debounce, + throttle, + platform, + mixin, + mpMixin +} +uni.$uv = $uv; +const install = (Vue,options={}) => { + // #ifndef APP-NVUE + const cloneMixin = index.deepClone(mixin); + delete cloneMixin?.props?.customClass; + delete cloneMixin?.props?.customStyle; + Vue.mixin(cloneMixin); + // #ifdef MP + if(options.mpShare){ + Vue.mixin(mpShare); + } + // #endif + // #endif + // #ifdef VUE2 + // 时间格式化,同时两个名称,date和timeFormat + Vue.filter('timeFormat', (timestamp, format) => uni.$uv.timeFormat(timestamp, format)); + Vue.filter('date', (timestamp, format) => uni.$uv.timeFormat(timestamp, format)); + // 将多久以前的方法,注入到全局过滤器 + Vue.filter('timeFrom', (timestamp, format) => uni.$uv.timeFrom(timestamp, format)); + // 同时挂载到uni和Vue.prototype中 + // #ifndef APP-NVUE + // 只有vue,挂载到Vue.prototype才有意义,因为nvue中全局Vue.prototype和Vue.mixin是无效的 + Vue.prototype.$uv = $uv; + // #endif + // #endif + // #ifdef VUE3 + Vue.config.globalProperties.$uv = $uv; + // #endif +} +export default { + install +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/index.scss b/uni_modules/uv-ui-tools/index.scss new file mode 100644 index 0000000..8d05b8d --- /dev/null +++ b/uni_modules/uv-ui-tools/index.scss @@ -0,0 +1,7 @@ +// 引入公共基础类 +@import "./libs/css/common.scss"; + +// 非nvue的样式 +/* #ifndef APP-NVUE */ +@import "./libs/css/vue.scss"; +/* #endif */ \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/config/config.js b/uni_modules/uv-ui-tools/libs/config/config.js new file mode 100644 index 0000000..f18ae74 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/config/config.js @@ -0,0 +1,34 @@ +// 此版本发布于2024-01-20 +const version = '1.1.20' + +// 开发环境才提示,生产环境不会提示 +if (process.env.NODE_ENV === 'development') { + console.log(`\n %c uvui V${version} https://www.uvui.cn/ \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0; border-radius: 5px;'); +} + +export default { + v: version, + version, + // 主题名称 + type: [ + 'primary', + 'success', + 'info', + 'error', + 'warning' + ], + // 颜色部分,本来可以通过scss的:export导出供js使用,但是奈何nvue不支持 + color: { + 'uv-primary': '#2979ff', + 'uv-warning': '#ff9900', + 'uv-success': '#19be6b', + 'uv-error': '#fa3534', + 'uv-info': '#909399', + 'uv-main-color': '#303133', + 'uv-content-color': '#606266', + 'uv-tips-color': '#909399', + 'uv-light-color': '#c0c4cc' + }, + // 默认单位,可以通过配置为rpx,那么在用于传入组件大小参数为数值时,就默认为rpx + unit: 'px' +} diff --git a/uni_modules/uv-ui-tools/libs/css/color.scss b/uni_modules/uv-ui-tools/libs/css/color.scss new file mode 100644 index 0000000..ce65743 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/color.scss @@ -0,0 +1,32 @@ +$uv-main-color: #303133 !default; +$uv-content-color: #606266 !default; +$uv-tips-color: #909193 !default; +$uv-light-color: #c0c4cc !default; +$uv-border-color: #dadbde !default; +$uv-bg-color: #f3f4f6 !default; +$uv-disabled-color: #c8c9cc !default; + +$uv-primary: #3c9cff !default; +$uv-primary-dark: #398ade !default; +$uv-primary-disabled: #9acafc !default; +$uv-primary-light: #ecf5ff !default; + +$uv-warning: #f9ae3d !default; +$uv-warning-dark: #f1a532 !default; +$uv-warning-disabled: #f9d39b !default; +$uv-warning-light: #fdf6ec !default; + +$uv-success: #5ac725 !default; +$uv-success-dark: #53c21d !default; +$uv-success-disabled: #a9e08f !default; +$uv-success-light: #f5fff0; + +$uv-error: #f56c6c !default; +$uv-error-dark: #e45656 !default; +$uv-error-disabled: #f7b2b2 !default; +$uv-error-light: #fef0f0 !default; + +$uv-info: #909399 !default; +$uv-info-dark: #767a82 !default; +$uv-info-disabled: #c4c6c9 !default; +$uv-info-light: #f4f4f5 !default; diff --git a/uni_modules/uv-ui-tools/libs/css/common.scss b/uni_modules/uv-ui-tools/libs/css/common.scss new file mode 100644 index 0000000..7ab99f8 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/common.scss @@ -0,0 +1,100 @@ +// 超出行数,自动显示行尾省略号,最多5行 +// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】 +@for $i from 1 through 5 { + .uv-line-#{$i} { + /* #ifdef APP-NVUE */ + // nvue下,可以直接使用lines属性,这是weex特有样式 + lines: $i; + text-overflow: ellipsis; + overflow: hidden; + flex: 1; + /* #endif */ + + /* #ifndef APP-NVUE */ + // vue下,单行和多行显示省略号需要单独处理 + @if $i == '1' { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } @else { + display: -webkit-box!important; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + -webkit-line-clamp: $i; + -webkit-box-orient: vertical!important; + } + /* #endif */ + } +} +$uv-bordercolor: #dadbde; +@if variable-exists(uv-border-color) { + $uv-bordercolor: $uv-border-color; +} + +// 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时, +// App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效 +// 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important +// 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现 +.uv-border { + border-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-style: solid; +} + +.uv-border-top { + border-top-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; +} + +.uv-border-left { + border-left-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-left-style: solid; +} + +.uv-border-right { + border-right-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-right-style: solid; +} + +.uv-border-bottom { + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-bottom-style: solid; +} + +.uv-border-top-bottom { + border-top-width: 0.5px!important; + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + border-bottom-style: solid; +} + +// 去除button的所有默认样式,让其表现跟普通的view、text元素一样 +.uv-reset-button { + padding: 0; + background-color: transparent; + /* #ifndef APP-PLUS */ + font-size: inherit; + line-height: inherit; + color: inherit; + /* #endif */ + /* #ifdef APP-NVUE */ + border-width: 0; + /* #endif */ +} + +/* #ifndef APP-NVUE */ +.uv-reset-button::after { + border: none; +} +/* #endif */ + +.uv-hover-class { + opacity: 0.7; +} + diff --git a/uni_modules/uv-ui-tools/libs/css/components.scss b/uni_modules/uv-ui-tools/libs/css/components.scss new file mode 100644 index 0000000..81ce15d --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/components.scss @@ -0,0 +1,23 @@ +@mixin flex($direction: row) { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: $direction; +} + +/* #ifndef APP-NVUE */ +// 由于uvui是基于nvue环境进行开发的,此环境中普通元素默认为flex-direction: column; +// 所以在非nvue中,需要对元素进行重置为flex-direction: column; 否则可能会表现异常 +$uvui-nvue-style: true !default; +@if $uvui-nvue-style == true { + view, scroll-view, swiper-item { + display: flex; + flex-direction: column; + flex-shrink: 0; + flex-grow: 0; + flex-basis: auto; + align-items: stretch; + align-content: flex-start; + } +} +/* #endif */ diff --git a/uni_modules/uv-ui-tools/libs/css/variable.scss b/uni_modules/uv-ui-tools/libs/css/variable.scss new file mode 100644 index 0000000..63903c9 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/variable.scss @@ -0,0 +1,111 @@ +// 超出行数,自动显示行尾省略号,最多5行 +// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】 +@if variable-exists(show-lines) { + @for $i from 1 through 5 { + .uv-line-#{$i} { + /* #ifdef APP-NVUE */ + // nvue下,可以直接使用lines属性,这是weex特有样式 + lines: $i; + text-overflow: ellipsis; + overflow: hidden; + flex: 1; + /* #endif */ + + /* #ifndef APP-NVUE */ + // vue下,单行和多行显示省略号需要单独处理 + @if $i == '1' { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } @else { + display: -webkit-box!important; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + -webkit-line-clamp: $i; + -webkit-box-orient: vertical!important; + } + /* #endif */ + } + } +} +@if variable-exists(show-border) { + $uv-bordercolor: #dadbde; + @if variable-exists(uv-border-color) { + $uv-bordercolor: $uv-border-color; + } + // 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时, + // App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效 + // 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important + // 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现 + @if variable-exists(show-border-surround) { + .uv-border { + border-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-style: solid; + } + } + @if variable-exists(show-border-top) { + .uv-border-top { + border-top-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + } + } + @if variable-exists(show-border-left) { + .uv-border-left { + border-left-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-left-style: solid; + } + } + @if variable-exists(show-border-right) { + .uv-border-right { + border-right-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-right-style: solid; + } + } + @if variable-exists(show-border-bottom) { + .uv-border-bottom { + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-bottom-style: solid; + } + } + @if variable-exists(show-border-top-bottom) { + .uv-border-top-bottom { + border-top-width: 0.5px!important; + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + border-bottom-style: solid; + } + } +} +@if variable-exists(show-reset-button) { + // 去除button的所有默认样式,让其表现跟普通的view、text元素一样 + .uv-reset-button { + padding: 0; + background-color: transparent; + /* #ifndef APP-PLUS */ + font-size: inherit; + line-height: inherit; + color: inherit; + /* #endif */ + /* #ifdef APP-NVUE */ + border-width: 0; + /* #endif */ + } + + /* #ifndef APP-NVUE */ + .uv-reset-button::after { + border: none; + } + /* #endif */ +} +@if variable-exists(show-hover) { + .uv-hover-class { + opacity: 0.7; + } +} diff --git a/uni_modules/uv-ui-tools/libs/css/vue.scss b/uni_modules/uv-ui-tools/libs/css/vue.scss new file mode 100644 index 0000000..bdbefdd --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/vue.scss @@ -0,0 +1,40 @@ +// 历遍生成4个方向的底部安全区 +@each $d in top, right, bottom, left { + .uv-safe-area-inset-#{$d} { + padding-#{$d}: 0; + padding-#{$d}: constant(safe-area-inset-#{$d}); + padding-#{$d}: env(safe-area-inset-#{$d}); + } +} + +//提升H5端uni.toast()的层级,避免被uvui的modal等遮盖 +/* #ifdef H5 */ +uni-toast { + z-index: 10090; +} +uni-toast .uni-toast { + z-index: 10090; +} +/* #endif */ + +// 隐藏scroll-view的滚动条 +::-webkit-scrollbar { + display: none; + width: 0 !important; + height: 0 !important; + -webkit-appearance: none; + background: transparent; +} + +$uvui-nvue-style: true !default; +@if $uvui-nvue-style == false { + view, scroll-view, swiper-item { + display: flex; + flex-direction: column; + flex-shrink: 0; + flex-grow: 0; + flex-basis: auto; + align-items: stretch; + align-content: flex-start; + } +} diff --git a/uni_modules/uv-ui-tools/libs/function/colorGradient.js b/uni_modules/uv-ui-tools/libs/function/colorGradient.js new file mode 100644 index 0000000..55c188f --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/colorGradient.js @@ -0,0 +1,134 @@ +/** + * 求两个颜色之间的渐变值 + * @param {string} startColor 开始的颜色 + * @param {string} endColor 结束的颜色 + * @param {number} step 颜色等分的份额 + * */ +function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) { + const startRGB = hexToRgb(startColor, false) // 转换为rgb数组模式 + const startR = startRGB[0] + const startG = startRGB[1] + const startB = startRGB[2] + + const endRGB = hexToRgb(endColor, false) + const endR = endRGB[0] + const endG = endRGB[1] + const endB = endRGB[2] + + const sR = (endR - startR) / step // 总差值 + const sG = (endG - startG) / step + const sB = (endB - startB) / step + const colorArr = [] + for (let i = 0; i < step; i++) { + // 计算每一步的hex值 + let hex = rgbToHex(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB + * i + startB))})`) + // 确保第一个颜色值为startColor的值 + if (i === 0) hex = rgbToHex(startColor) + // 确保最后一个颜色值为endColor的值 + if (i === step - 1) hex = rgbToHex(endColor) + colorArr.push(hex) + } + return colorArr +} + +// 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式) +function hexToRgb(sColor, str = true) { + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + sColor = String(sColor).toLowerCase() + if (sColor && reg.test(sColor)) { + if (sColor.length === 4) { + let sColorNew = '#' + for (let i = 1; i < 4; i += 1) { + sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)) + } + sColor = sColorNew + } + // 处理六位的颜色值 + const sColorChange = [] + for (let i = 1; i < 7; i += 2) { + sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`)) + } + if (!str) { + return sColorChange + } + return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})` + } if (/^(rgb|RGB)/.test(sColor)) { + const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',') + return arr.map((val) => Number(val)) + } + return sColor +} + +// 将rgb表示方式转换为hex表示方式 +function rgbToHex(rgb) { + const _this = rgb + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + if (/^(rgb|RGB)/.test(_this)) { + const aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',') + let strHex = '#' + for (let i = 0; i < aColor.length; i++) { + let hex = Number(aColor[i]).toString(16) + hex = String(hex).length == 1 ? `${0}${hex}` : hex // 保证每个rgb的值为2位 + if (hex === '0') { + hex += hex + } + strHex += hex + } + if (strHex.length !== 7) { + strHex = _this + } + return strHex + } if (reg.test(_this)) { + const aNum = _this.replace(/#/, '').split('') + if (aNum.length === 6) { + return _this + } if (aNum.length === 3) { + let numHex = '#' + for (let i = 0; i < aNum.length; i += 1) { + numHex += (aNum[i] + aNum[i]) + } + return numHex + } + } else { + return _this + } +} + +/** +* JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba(255,255,255,0.5)字符串 +* sHex为传入的十六进制的色值 +* alpha为rgba的透明度 +*/ +function colorToRgba(color, alpha) { + color = rgbToHex(color) + // 十六进制颜色值的正则表达式 + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + /* 16进制颜色转为RGB格式 */ + let sColor = String(color).toLowerCase() + if (sColor && reg.test(sColor)) { + if (sColor.length === 4) { + let sColorNew = '#' + for (let i = 1; i < 4; i += 1) { + sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)) + } + sColor = sColorNew + } + // 处理六位的颜色值 + const sColorChange = [] + for (let i = 1; i < 7; i += 2) { + sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`)) + } + // return sColorChange.join(',') + return `rgba(${sColorChange.join(',')},${alpha})` + } + + return sColor +} + +export { + colorGradient, + hexToRgb, + rgbToHex, + colorToRgba +} diff --git a/uni_modules/uv-ui-tools/libs/function/debounce.js b/uni_modules/uv-ui-tools/libs/function/debounce.js new file mode 100644 index 0000000..ad3996b --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/debounce.js @@ -0,0 +1,29 @@ +let timeout = null + +/** + * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数 + * + * @param {Function} func 要执行的回调函数 + * @param {Number} wait 延时的时间 + * @param {Boolean} immediate 是否立即执行 + * @return null + */ +function debounce(func, wait = 500, immediate = false) { + // 清除定时器 + if (timeout !== null) clearTimeout(timeout) + // 立即执行,此类情况一般用不到 + if (immediate) { + const callNow = !timeout + timeout = setTimeout(() => { + timeout = null + }, wait) + if (callNow) typeof func === 'function' && func() + } else { + // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法 + timeout = setTimeout(() => { + typeof func === 'function' && func() + }, wait) + } +} + +export default debounce diff --git a/uni_modules/uv-ui-tools/libs/function/digit.js b/uni_modules/uv-ui-tools/libs/function/digit.js new file mode 100644 index 0000000..c8260a0 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/digit.js @@ -0,0 +1,167 @@ +let _boundaryCheckingState = true; // 是否进行越界检查的全局开关 + +/** + * 把错误的数据转正 + * @private + * @example strip(0.09999999999999998)=0.1 + */ +function strip(num, precision = 15) { + return +parseFloat(Number(num).toPrecision(precision)); +} + +/** + * Return digits length of a number + * @private + * @param {*number} num Input number + */ +function digitLength(num) { + // Get digit length of e + const eSplit = num.toString().split(/[eE]/); + const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0); + return len > 0 ? len : 0; +} + +/** + * 把小数转成整数,如果是小数则放大成整数 + * @private + * @param {*number} num 输入数 + */ +function float2Fixed(num) { + if (num.toString().indexOf('e') === -1) { + return Number(num.toString().replace('.', '')); + } + const dLen = digitLength(num); + return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num); +} + +/** + * 检测数字是否越界,如果越界给出提示 + * @private + * @param {*number} num 输入数 + */ +function checkBoundary(num) { + if (_boundaryCheckingState) { + if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { + console.warn(`${num} 超出了精度限制,结果可能不正确`); + } + } +} + +/** + * 把递归操作扁平迭代化 + * @param {number[]} arr 要操作的数字数组 + * @param {function} operation 迭代操作 + * @private + */ +function iteratorOperation(arr, operation) { + const [num1, num2, ...others] = arr; + let res = operation(num1, num2); + + others.forEach((num) => { + res = operation(res, num); + }); + + return res; +} + +/** + * 高精度乘法 + * @export + */ +export function times(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, times); + } + + const [num1, num2] = nums; + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + const baseNum = digitLength(num1) + digitLength(num2); + const leftValue = num1Changed * num2Changed; + + checkBoundary(leftValue); + + return leftValue / Math.pow(10, baseNum); +} + +/** + * 高精度加法 + * @export + */ +export function plus(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, plus); + } + + const [num1, num2] = nums; + // 取最大的小数位 + const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + // 把小数都转为整数然后再计算 + return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; +} + +/** + * 高精度减法 + * @export + */ +export function minus(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, minus); + } + + const [num1, num2] = nums; + const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; +} + +/** + * 高精度除法 + * @export + */ +export function divide(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, divide); + } + + const [num1, num2] = nums; + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + checkBoundary(num1Changed); + checkBoundary(num2Changed); + // 重要,这里必须用strip进行修正 + return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1)))); +} + +/** + * 四舍五入 + * @export + */ +export function round(num, ratio) { + const base = Math.pow(10, ratio); + let result = divide(Math.round(Math.abs(times(num, base))), base); + if (num < 0 && result !== 0) { + result = times(result, -1); + } + // 位数不足则补0 + return result; +} + +/** + * 是否进行边界检查,默认开启 + * @param flag 标记开关,true 为开启,false 为关闭,默认为 true + * @export + */ +export function enableBoundaryChecking(flag = true) { + _boundaryCheckingState = flag; +} + + +export default { + times, + plus, + minus, + divide, + round, + enableBoundaryChecking, +}; + diff --git a/uni_modules/uv-ui-tools/libs/function/index.js b/uni_modules/uv-ui-tools/libs/function/index.js new file mode 100644 index 0000000..dc72e45 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/index.js @@ -0,0 +1,734 @@ +import { number, empty } from './test.js' +import { round } from './digit.js' +/** + * @description 如果value小于min,取min;如果value大于max,取max + * @param {number} min + * @param {number} max + * @param {number} value + */ +function range(min = 0, max = 0, value = 0) { + return Math.max(min, Math.min(max, Number(value))) +} + +/** + * @description 用于获取用户传递值的px值 如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.rpx2px进行转换 + * @param {number|string} value 用户传递值的px值 + * @param {boolean} unit + * @returns {number|string} + */ +function getPx(value, unit = false) { + if (number(value)) { + return unit ? `${value}px` : Number(value) + } + // 如果带有rpx,先取出其数值部分,再转为px值 + if (/(rpx|rpx)$/.test(value)) { + return unit ? `${uni.rpx2px(parseInt(value))}px` : Number(uni.rpx2px(parseInt(value))) + } + return unit ? `${parseInt(value)}px` : parseInt(value) +} + +/** + * @description 进行延时,以达到可以简写代码的目的 比如: await uni.$uv.sleep(20)将会阻塞20ms + * @param {number} value 堵塞时间 单位ms 毫秒 + * @returns {Promise} 返回promise + */ +function sleep(value = 30) { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, value) + }) +} +/** + * @description 运行期判断平台 + * @returns {string} 返回所在平台(小写) + * @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台 + */ +function os() { + return uni.getSystemInfoSync().platform.toLowerCase() +} +/** + * @description 获取系统信息同步接口 + * @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync + */ +function sys() { + return uni.getSystemInfoSync() +} + +/** + * @description 取一个区间数 + * @param {Number} min 最小值 + * @param {Number} max 最大值 + */ +function random(min, max) { + if (min >= 0 && max > 0 && max >= min) { + const gab = max - min + 1 + return Math.floor(Math.random() * gab + min) + } + return 0 +} + +/** + * @param {Number} len uuid的长度 + * @param {Boolean} firstU 将返回的首字母置为"u" + * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制 + */ +function guid(len = 32, firstU = true, radix = null) { + const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('') + const uuid = [] + radix = radix || chars.length + + if (len) { + // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 + for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] + } else { + let r + // rfc4122标准要求返回的uuid中,某些位为固定的字符 + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-' + uuid[14] = '4' + + for (let i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | Math.random() * 16 + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r] + } + } + } + // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class + if (firstU) { + uuid.shift() + return `u${uuid.join('')}` + } + return uuid.join('') +} + +/** +* @description 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法 + this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx + 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name + 值(默认为undefined),就是查找最顶层的$parent +* @param {string|undefined} name 父组件的参数名 +*/ +function $parent(name = undefined) { + let parent = this.$parent + // 通过while历遍,这里主要是为了H5需要多层解析的问题 + while (parent) { + // 父组件 + if (parent.$options && parent.$options.name !== name) { + // 如果组件的name不相等,继续上一级寻找 + parent = parent.$parent + } else { + return parent + } + } + return false +} + +/** + * @description 样式转换 + * 对象转字符串,或者字符串转对象 + * @param {object | string} customStyle 需要转换的目标 + * @param {String} target 转换的目的,object-转为对象,string-转为字符串 + * @returns {object|string} + */ +function addStyle(customStyle, target = 'object') { + // 字符串转字符串,对象转对象情形,直接返回 + if (empty(customStyle) || typeof(customStyle) === 'object' && target === 'object' || target === 'string' && + typeof(customStyle) === 'string') { + return customStyle + } + // 字符串转对象 + if (target === 'object') { + // 去除字符串样式中的两端空格(中间的空格不能去掉,比如padding: 20px 0如果去掉了就错了),空格是无用的 + customStyle = trim(customStyle) + // 根据";"将字符串转为数组形式 + const styleArray = customStyle.split(';') + const style = {} + // 历遍数组,拼接成对象 + for (let i = 0; i < styleArray.length; i++) { + // 'font-size:20px;color:red;',如此最后字符串有";"的话,会导致styleArray最后一个元素为空字符串,这里需要过滤 + if (styleArray[i]) { + const item = styleArray[i].split(':') + style[trim(item[0])] = trim(item[1]) + } + } + return style + } + // 这里为对象转字符串形式 + let string = '' + for (const i in customStyle) { + // 驼峰转为中划线的形式,否则css内联样式,无法识别驼峰样式属性名 + const key = i.replace(/([A-Z])/g, '-$1').toLowerCase() + string += `${key}:${customStyle[i]};` + } + // 去除两端空格 + return trim(string) +} + +/** + * @description 添加单位,如果有rpx,rpx,%,px等单位结尾或者值为auto,直接返回,否则加上px单位结尾 + * @param {string|number} value 需要添加单位的值 + * @param {string} unit 添加的单位名 比如px + */ +function addUnit(value = 'auto', unit = uni?.$uv?.config?.unit ? uni?.$uv?.config?.unit : 'px') { + value = String(value) + // 用uvui内置验证规则中的number判断是否为数值 + return number(value) ? `${value}${unit}` : value +} + +/** + * @description 深度克隆 + * @param {object} obj 需要深度克隆的对象 + * @param cache 缓存 + * @returns {*} 克隆后的对象或者原值(不是对象) + */ +function deepClone(obj, cache = new WeakMap()) { + if (obj === null || typeof obj !== 'object') return obj; + if (cache.has(obj)) return cache.get(obj); + let clone; + if (obj instanceof Date) { + clone = new Date(obj.getTime()); + } else if (obj instanceof RegExp) { + clone = new RegExp(obj); + } else if (obj instanceof Map) { + clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)])); + } else if (obj instanceof Set) { + clone = new Set(Array.from(obj, value => deepClone(value, cache))); + } else if (Array.isArray(obj)) { + clone = obj.map(value => deepClone(value, cache)); + } else if (Object.prototype.toString.call(obj) === '[object Object]') { + clone = Object.create(Object.getPrototypeOf(obj)); + cache.set(obj, clone); + for (const [key, value] of Object.entries(obj)) { + clone[key] = deepClone(value, cache); + } + } else { + clone = Object.assign({}, obj); + } + cache.set(obj, clone); + return clone; +} + +/** + * @description JS对象深度合并 + * @param {object} target 需要拷贝的对象 + * @param {object} source 拷贝的来源对象 + * @returns {object|boolean} 深度合并后的对象或者false(入参有不是对象) + */ +function deepMerge(target = {}, source = {}) { + target = deepClone(target) + if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target; + const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target); + for (const prop in source) { + if (!source.hasOwnProperty(prop)) continue; + const sourceValue = source[prop]; + const targetValue = merged[prop]; + if (sourceValue instanceof Date) { + merged[prop] = new Date(sourceValue); + } else if (sourceValue instanceof RegExp) { + merged[prop] = new RegExp(sourceValue); + } else if (sourceValue instanceof Map) { + merged[prop] = new Map(sourceValue); + } else if (sourceValue instanceof Set) { + merged[prop] = new Set(sourceValue); + } else if (typeof sourceValue === 'object' && sourceValue !== null) { + merged[prop] = deepMerge(targetValue, sourceValue); + } else { + merged[prop] = sourceValue; + } + } + return merged; +} + +/** + * @description error提示 + * @param {*} err 错误内容 + */ +function error(err) { + // 开发环境才提示,生产环境不会提示 + if (process.env.NODE_ENV === 'development') { + console.error(`uvui提示:${err}`) + } +} + +/** + * @description 打乱数组 + * @param {array} array 需要打乱的数组 + * @returns {array} 打乱后的数组 + */ +function randomArray(array = []) { + // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0 + return array.sort(() => Math.random() - 0.5) +} + +// padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序 +// 所以这里做一个兼容polyfill的兼容处理 +if (!String.prototype.padStart) { + // 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解 + String.prototype.padStart = function(maxLength, fillString = ' ') { + if (Object.prototype.toString.call(fillString) !== '[object String]') { + throw new TypeError( + 'fillString must be String' + ) + } + const str = this + // 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉 + if (str.length >= maxLength) return String(str) + + const fillLength = maxLength - str.length + let times = Math.ceil(fillLength / fillString.length) + while (times >>= 1) { + fillString += fillString + if (times === 1) { + fillString += fillString + } + } + return fillString.slice(0, fillLength) + str + } +} + +/** + * @description 格式化时间 + * @param {String|Number} dateTime 需要格式化的时间戳 + * @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd + * @returns {string} 返回格式化后的字符串 + */ +function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') { + let date + // 若传入时间为假值,则取当前时间 + if (!dateTime) { + date = new Date() + } + // 若为unix秒时间戳,则转为毫秒时间戳(逻辑有点奇怪,但不敢改,以保证历史兼容) + else if (/^\d{10}$/.test(dateTime?.toString().trim())) { + date = new Date(dateTime * 1000) + } + // 若用户传入字符串格式时间戳,new Date无法解析,需做兼容 + else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) { + date = new Date(Number(dateTime)) + } + // 处理平台性差异,在Safari/Webkit中,new Date仅支持/作为分割符的字符串时间 + // 处理 '2022-07-10 01:02:03',跳过 '2022-07-10T01:02:03' + else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) { + date = new Date(dateTime.replace(/-/g, '/')) + } + // 其他都认为符合 RFC 2822 规范 + else { + date = new Date(dateTime) + } + + const timeSource = { + 'y': date.getFullYear().toString(), // 年 + 'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月 + 'd': date.getDate().toString().padStart(2, '0'), // 日 + 'h': date.getHours().toString().padStart(2, '0'), // 时 + 'M': date.getMinutes().toString().padStart(2, '0'), // 分 + 's': date.getSeconds().toString().padStart(2, '0') // 秒 + // 有其他格式化字符需求可以继续添加,必须转化成字符串 + } + + for (const key in timeSource) { + const [ret] = new RegExp(`${key}+`).exec(formatStr) || [] + if (ret) { + // 年可能只需展示两位 + const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0 + formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex)) + } + } + + return formatStr +} + +/** + * @description 时间戳转为多久之前 + * @param {String|Number} timestamp 时间戳 + * @param {String|Boolean} format + * 格式化规则如果为时间格式字符串,超出一定时间范围,返回固定的时间格式; + * 如果为布尔值false,无论什么时间,都返回多久以前的格式 + * @returns {string} 转化后的内容 + */ +function timeFrom(timestamp = null, format = 'yyyy-mm-dd') { + if (timestamp == null) timestamp = Number(new Date()) + timestamp = parseInt(timestamp) + // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位) + if (timestamp.toString().length == 10) timestamp *= 1000 + let timer = (new Date()).getTime() - timestamp + timer = parseInt(timer / 1000) + // 如果小于5分钟,则返回"刚刚",其他以此类推 + let tips = '' + switch (true) { + case timer < 300: + tips = '刚刚' + break + case timer >= 300 && timer < 3600: + tips = `${parseInt(timer / 60)}分钟前` + break + case timer >= 3600 && timer < 86400: + tips = `${parseInt(timer / 3600)}小时前` + break + case timer >= 86400 && timer < 2592000: + tips = `${parseInt(timer / 86400)}天前` + break + default: + // 如果format为false,则无论什么时间戳,都显示xx之前 + if (format === false) { + if (timer >= 2592000 && timer < 365 * 86400) { + tips = `${parseInt(timer / (86400 * 30))}个月前` + } else { + tips = `${parseInt(timer / (86400 * 365))}年前` + } + } else { + tips = timeFormat(timestamp, format) + } + } + return tips +} + +/** + * @description 去除空格 + * @param String str 需要去除空格的字符串 + * @param String pos both(左右)|left|right|all 默认both + */ +function trim(str, pos = 'both') { + str = String(str) + if (pos == 'both') { + return str.replace(/^\s+|\s+$/g, '') + } + if (pos == 'left') { + return str.replace(/^\s*/, '') + } + if (pos == 'right') { + return str.replace(/(\s*$)/g, '') + } + if (pos == 'all') { + return str.replace(/\s+/g, '') + } + return str +} + +/** + * @description 对象转url参数 + * @param {object} data,对象 + * @param {Boolean} isPrefix,是否自动加上"?" + * @param {string} arrayFormat 规则 indices|brackets|repeat|comma + */ +function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') { + const prefix = isPrefix ? '?' : '' + const _result = [] + if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets' + for (const key in data) { + const value = data[key] + // 去掉为空的参数 + if (['', undefined, null].indexOf(value) >= 0) { + continue + } + // 如果值为数组,另行处理 + if (value.constructor === Array) { + // e.g. {ids: [1, 2, 3]} + switch (arrayFormat) { + case 'indices': + // 结果: ids[0]=1&ids[1]=2&ids[2]=3 + for (let i = 0; i < value.length; i++) { + _result.push(`${key}[${i}]=${value[i]}`) + } + break + case 'brackets': + // 结果: ids[]=1&ids[]=2&ids[]=3 + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + break + case 'repeat': + // 结果: ids=1&ids=2&ids=3 + value.forEach((_value) => { + _result.push(`${key}=${_value}`) + }) + break + case 'comma': + // 结果: ids=1,2,3 + let commaStr = '' + value.forEach((_value) => { + commaStr += (commaStr ? ',' : '') + _value + }) + _result.push(`${key}=${commaStr}`) + break + default: + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + } + } else { + _result.push(`${key}=${value}`) + } + } + return _result.length ? prefix + _result.join('&') : '' +} + +/** + * 显示消息提示框 + * @param {String} title 提示的内容,长度与 icon 取值有关。 + * @param {Number} duration 提示的延迟时间,单位毫秒,默认:2000 + */ +function toast(title, duration = 2000) { + uni.showToast({ + title: String(title), + icon: 'none', + duration + }) +} + +/** + * @description 根据主题type值,获取对应的图标 + * @param {String} type 主题名称,primary|info|error|warning|success + * @param {boolean} fill 是否使用fill填充实体的图标 + */ +function type2icon(type = 'success', fill = false) { + // 如果非预置值,默认为success + if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success' + let iconName = '' + // 目前(2019-12-12),info和primary使用同一个图标 + switch (type) { + case 'primary': + iconName = 'info-circle' + break + case 'info': + iconName = 'info-circle' + break + case 'error': + iconName = 'close-circle' + break + case 'warning': + iconName = 'error-circle' + break + case 'success': + iconName = 'checkmark-circle' + break + default: + iconName = 'checkmark-circle' + } + // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的 + if (fill) iconName += '-fill' + return iconName +} + +/** + * @description 数字格式化 + * @param {number|string} number 要格式化的数字 + * @param {number} decimals 保留几位小数 + * @param {string} decimalPoint 小数点符号 + * @param {string} thousandsSeparator 千分位符号 + * @returns {string} 格式化后的数字 + */ +function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') { + number = (`${number}`).replace(/[^0-9+-Ee.]/g, '') + const n = !isFinite(+number) ? 0 : +number + const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) + const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator + const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint + let s = '' + + s = (prec ? round(n, prec) + '' : `${Math.round(n)}`).split('.') + const re = /(-?\d+)(\d{3})/ + while (re.test(s[0])) { + s[0] = s[0].replace(re, `$1${sep}$2`) + } + + if ((s[1] || '').length < prec) { + s[1] = s[1] || '' + s[1] += new Array(prec - s[1].length + 1).join('0') + } + return s.join(dec) +} + +/** + * @description 获取duration值 + * 如果带有ms或者s直接返回,如果大于一定值,认为是ms单位,小于一定值,认为是s单位 + * 比如以30位阈值,那么300大于30,可以理解为用户想要的是300ms,而不是想花300s去执行一个动画 + * @param {String|number} value 比如: "1s"|"100ms"|1|100 + * @param {boolean} unit 提示: 如果是false 默认返回number + * @return {string|number} + */ +function getDuration(value, unit = true) { + const valueNum = parseInt(value) + if (unit) { + if (/s$/.test(value)) return value + return value > 30 ? `${value}ms` : `${value}s` + } + if (/ms$/.test(value)) return valueNum + if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000 + return valueNum +} + +/** + * @description 日期的月或日补零操作 + * @param {String} value 需要补零的值 + */ +function padZero(value) { + return `00${value}`.slice(-2) +} + +/** + * @description 在uv-form的子组件内容发生变化,或者失去焦点时,尝试通知uv-form执行校验方法 + * @param {*} instance + * @param {*} event + */ +function formValidate(instance, event) { + const formItem = $parent.call(instance, 'uv-form-item') + const form = $parent.call(instance, 'uv-form') + // 如果发生变化的input或者textarea等,其父组件中有uv-form-item或者uv-form等,就执行form的validate方法 + // 同时将form-item的pros传递给form,让其进行精确对象验证 + if (formItem && form) { + form.validateField(formItem.prop, () => {}, event) + } +} + +/** + * @description 获取某个对象下的属性,用于通过类似'a.b.c'的形式去获取一个对象的的属性的形式 + * @param {object} obj 对象 + * @param {string} key 需要获取的属性字段 + * @returns {*} + */ +function getProperty(obj, key) { + if (!obj) { + return + } + if (typeof key !== 'string' || key === '') { + return '' + } + if (key.indexOf('.') !== -1) { + const keys = key.split('.') + let firstObj = obj[keys[0]] || {} + + for (let i = 1; i < keys.length; i++) { + if (firstObj) { + firstObj = firstObj[keys[i]] + } + } + return firstObj + } + return obj[key] +} + +/** + * @description 设置对象的属性值,如果'a.b.c'的形式进行设置 + * @param {object} obj 对象 + * @param {string} key 需要设置的属性 + * @param {string} value 设置的值 + */ +function setProperty(obj, key, value) { + if (!obj) { + return + } + // 递归赋值 + const inFn = function(_obj, keys, v) { + // 最后一个属性key + if (keys.length === 1) { + _obj[keys[0]] = v + return + } + // 0~length-1个key + while (keys.length > 1) { + const k = keys[0] + if (!_obj[k] || (typeof _obj[k] !== 'object')) { + _obj[k] = {} + } + const key = keys.shift() + // 自调用判断是否存在属性,不存在则自动创建对象 + inFn(_obj[k], keys, v) + } + } + + if (typeof key !== 'string' || key === '') { + + } else if (key.indexOf('.') !== -1) { // 支持多层级赋值操作 + const keys = key.split('.') + inFn(obj, keys, value) + } else { + obj[key] = value + } +} + +/** + * @description 获取当前页面路径 + */ +function page() { + const pages = getCurrentPages(); + const route = pages[pages.length - 1]?.route; + // 某些特殊情况下(比如页面进行redirectTo时的一些时机),pages可能为空数组 + return `/${route ? route : ''}` +} + +/** + * @description 获取当前路由栈实例数组 + */ +function pages() { + const pages = getCurrentPages() + return pages +} + +/** + * 获取页面历史栈指定层实例 + * @param back {number} [0] - 0或者负数,表示获取历史栈的哪一层,0表示获取当前页面实例,-1 表示获取上一个页面实例。默认0。 + */ +function getHistoryPage(back = 0) { + const pages = getCurrentPages() + const len = pages.length + return pages[len - 1 + back] +} + + + +/** + * @description 修改uvui内置属性值 + * @param {object} props 修改内置props属性 + * @param {object} config 修改内置config属性 + * @param {object} color 修改内置color属性 + * @param {object} zIndex 修改内置zIndex属性 + */ +function setConfig({ + props = {}, + config = {}, + color = {}, + zIndex = {} +}) { + const { + deepMerge, + } = uni.$uv + uni.$uv.config = deepMerge(uni.$uv.config, config) + uni.$uv.props = deepMerge(uni.$uv.props, props) + uni.$uv.color = deepMerge(uni.$uv.color, color) + uni.$uv.zIndex = deepMerge(uni.$uv.zIndex, zIndex) +} + +export { + range, + getPx, + sleep, + os, + sys, + random, + guid, + $parent, + addStyle, + addUnit, + deepClone, + deepMerge, + error, + randomArray, + timeFormat, + timeFrom, + trim, + queryParams, + toast, + type2icon, + priceFormat, + getDuration, + padZero, + formValidate, + getProperty, + setProperty, + page, + pages, + getHistoryPage, + setConfig +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/function/platform.js b/uni_modules/uv-ui-tools/libs/function/platform.js new file mode 100644 index 0000000..d6b926e --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/platform.js @@ -0,0 +1,75 @@ +/** + * 注意: + * 此部分内容,在vue-cli模式下,需要在vue.config.js加入如下内容才有效: + * module.exports = { + * transpileDependencies: ['uview-v2'] + * } + */ + +let platform = 'none' + +// #ifdef VUE3 +platform = 'vue3' +// #endif + +// #ifdef VUE2 +platform = 'vue2' +// #endif + +// #ifdef APP-PLUS +platform = 'plus' +// #endif + +// #ifdef APP-NVUE +platform = 'nvue' +// #endif + +// #ifdef H5 +platform = 'h5' +// #endif + +// #ifdef MP-WEIXIN +platform = 'weixin' +// #endif + +// #ifdef MP-ALIPAY +platform = 'alipay' +// #endif + +// #ifdef MP-BAIDU +platform = 'baidu' +// #endif + +// #ifdef MP-TOUTIAO +platform = 'toutiao' +// #endif + +// #ifdef MP-QQ +platform = 'qq' +// #endif + +// #ifdef MP-KUAISHOU +platform = 'kuaishou' +// #endif + +// #ifdef MP-360 +platform = '360' +// #endif + +// #ifdef MP +platform = 'mp' +// #endif + +// #ifdef QUICKAPP-WEBVIEW +platform = 'quickapp-webview' +// #endif + +// #ifdef QUICKAPP-WEBVIEW-HUAWEI +platform = 'quickapp-webview-huawei' +// #endif + +// #ifdef QUICKAPP-WEBVIEW-UNION +platform = 'quckapp-webview-union' +// #endif + +export default platform diff --git a/uni_modules/uv-ui-tools/libs/function/test.js b/uni_modules/uv-ui-tools/libs/function/test.js new file mode 100644 index 0000000..7c8b747 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/test.js @@ -0,0 +1,287 @@ +/** + * 验证电子邮箱格式 + */ +function email(value) { + return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value) +} + +/** + * 验证手机格式 + */ +function mobile(value) { + return /^1([3589]\d|4[5-9]|6[1-2,4-7]|7[0-8])\d{8}$/.test(value) +} + +/** + * 验证URL格式 + */ +function url(value) { + return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/ + .test(value) +} + +/** + * 验证日期格式 + */ +function date(value) { + if (!value) return false + // 判断是否数值或者字符串数值(意味着为时间戳),转为数值,否则new Date无法识别字符串时间戳 + if (number(value)) value = +value + return !/Invalid|NaN/.test(new Date(value).toString()) +} + +/** + * 验证ISO类型的日期格式 + */ +function dateISO(value) { + return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value) +} + +/** + * 验证十进制数字 + */ +function number(value) { + return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value) +} + +/** + * 验证字符串 + */ +function string(value) { + return typeof value === 'string' +} + +/** + * 验证整数 + */ +function digits(value) { + return /^\d+$/.test(value) +} + +/** + * 验证身份证号码 + */ +function idCard(value) { + return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test( + value + ) +} + +/** + * 是否车牌号 + */ +function carNo(value) { + // 新能源车牌 + const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/ + // 旧车牌 + const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/ + if (value.length === 7) { + return creg.test(value) + } if (value.length === 8) { + return xreg.test(value) + } + return false +} + +/** + * 金额,只允许2位小数 + */ +function amount(value) { + // 金额,只允许保留两位小数 + return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value) +} + +/** + * 中文 + */ +function chinese(value) { + const reg = /^[\u4e00-\u9fa5]+$/gi + return reg.test(value) +} + +/** + * 只能输入字母 + */ +function letter(value) { + return /^[a-zA-Z]*$/.test(value) +} + +/** + * 只能是字母或者数字 + */ +function enOrNum(value) { + // 英文或者数字 + const reg = /^[0-9a-zA-Z]*$/g + return reg.test(value) +} + +/** + * 验证是否包含某个值 + */ +function contains(value, param) { + return value.indexOf(param) >= 0 +} + +/** + * 验证一个值范围[min, max] + */ +function range(value, param) { + return value >= param[0] && value <= param[1] +} + +/** + * 验证一个长度范围[min, max] + */ +function rangeLength(value, param) { + return value.length >= param[0] && value.length <= param[1] +} + +/** + * 是否固定电话 + */ +function landline(value) { + const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/ + return reg.test(value) +} + +/** + * 判断是否为空 + */ +function empty(value) { + switch (typeof value) { + case 'undefined': + return true + case 'string': + if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true + break + case 'boolean': + if (!value) return true + break + case 'number': + if (value === 0 || isNaN(value)) return true + break + case 'object': + if (value === null || value.length === 0) return true + for (const i in value) { + return false + } + return true + } + return false +} + +/** + * 是否json字符串 + */ +function jsonString(value) { + if (typeof value === 'string') { + try { + const obj = JSON.parse(value) + if (typeof obj === 'object' && obj) { + return true + } + return false + } catch (e) { + return false + } + } + return false +} + +/** + * 是否数组 + */ +function array(value) { + if (typeof Array.isArray === 'function') { + return Array.isArray(value) + } + return Object.prototype.toString.call(value) === '[object Array]' +} + +/** + * 是否对象 + */ +function object(value) { + return Object.prototype.toString.call(value) === '[object Object]' +} + +/** + * 是否短信验证码 + */ +function code(value, len = 6) { + return new RegExp(`^\\d{${len}}$`).test(value) +} + +/** + * 是否函数方法 + * @param {Object} value + */ +function func(value) { + return typeof value === 'function' +} + +/** + * 是否promise对象 + * @param {Object} value + */ +function promise(value) { + return object(value) && func(value.then) && func(value.catch) +} + +/** 是否图片格式 + * @param {Object} value + */ +function image(value) { + const newValue = value.split('?')[0] + const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i + return IMAGE_REGEXP.test(newValue) +} + +/** + * 是否视频格式 + * @param {Object} value + */ +function video(value) { + const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i + return VIDEO_REGEXP.test(value) +} + +/** + * 是否为正则对象 + * @param {Object} + * @return {Boolean} + */ +function regExp(o) { + return o && Object.prototype.toString.call(o) === '[object RegExp]' +} + +export { + email, + mobile, + url, + date, + dateISO, + number, + digits, + idCard, + carNo, + amount, + chinese, + letter, + enOrNum, + contains, + range, + rangeLength, + empty, + jsonString, + landline, + object, + array, + code, + func, + promise, + video, + image, + regExp, + string +} diff --git a/uni_modules/uv-ui-tools/libs/function/throttle.js b/uni_modules/uv-ui-tools/libs/function/throttle.js new file mode 100644 index 0000000..2f33611 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/throttle.js @@ -0,0 +1,30 @@ +let timer; let + flag +/** + * 节流原理:在一定时间内,只能触发一次 + * + * @param {Function} func 要执行的回调函数 + * @param {Number} wait 延时的时间 + * @param {Boolean} immediate 是否立即执行 + * @return null + */ +function throttle(func, wait = 500, immediate = true) { + if (immediate) { + if (!flag) { + flag = true + // 如果是立即执行,则在wait毫秒内开始时执行 + typeof func === 'function' && func() + timer = setTimeout(() => { + flag = false + }, wait) + } + } else if (!flag) { + flag = true + // 如果是非立即执行,则在wait毫秒内的结束处执行 + timer = setTimeout(() => { + flag = false + typeof func === 'function' && func() + }, wait) + } +} +export default throttle diff --git a/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js b/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js new file mode 100644 index 0000000..31a5cfc --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js @@ -0,0 +1,132 @@ +import buildURL from '../helpers/buildURL' +import buildFullPath from '../core/buildFullPath' +import settle from '../core/settle' +import {isUndefined} from "../utils" + +/** + * 返回可选值存在的配置 + * @param {Array} keys - 可选值数组 + * @param {Object} config2 - 配置 + * @return {{}} - 存在的配置项 + */ +const mergeKeys = (keys, config2) => { + let config = {} + keys.forEach(prop => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } + }) + return config +} +export default (config) => { + return new Promise((resolve, reject) => { + let fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer) + const _config = { + url: fullPath, + header: config.header, + complete: (response) => { + config.fullPath = fullPath + response.config = config + response.rawData = response.data + try { + let jsonParseHandle = false + const forcedJSONParsingType = typeof config.forcedJSONParsing + if (forcedJSONParsingType === 'boolean') { + jsonParseHandle = config.forcedJSONParsing + } else if (forcedJSONParsingType === 'object') { + const includesMethod = config.forcedJSONParsing.include || [] + jsonParseHandle = includesMethod.includes(config.method) + } + + // 对可能字符串不是json 的情况容错 + if (jsonParseHandle && typeof response.data === 'string') { + response.data = JSON.parse(response.data) + } + // eslint-disable-next-line no-empty + } catch (e) { + } + settle(resolve, reject, response) + } + } + let requestTask + if (config.method === 'UPLOAD') { + delete _config.header['content-type'] + delete _config.header['Content-Type'] + let otherConfig = { + // #ifdef MP-ALIPAY + fileType: config.fileType, + // #endif + filePath: config.filePath, + name: config.name + } + const optionalKeys = [ + // #ifdef APP-PLUS || H5 + 'files', + // #endif + // #ifdef H5 + 'file', + // #endif + // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU + 'timeout', + // #endif + 'formData' + ] + requestTask = uni.uploadFile({..._config, ...otherConfig, ...mergeKeys(optionalKeys, config)}) + } else if (config.method === 'DOWNLOAD') { + const optionalKeys = [ + // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU + 'timeout', + // #endif + // #ifdef MP + 'filePath', + // #endif + ] + requestTask = uni.downloadFile({..._config, ...mergeKeys(optionalKeys, config)}) + } else { + const optionalKeys = [ + 'data', + 'method', + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + 'timeout', + // #endif + 'dataType', + // #ifndef MP-ALIPAY + 'responseType', + // #endif + // #ifdef APP-PLUS + 'sslVerify', + // #endif + // #ifdef H5 + 'withCredentials', + // #endif + // #ifdef APP-PLUS + 'firstIpv4', + // #endif + // #ifdef MP-WEIXIN + 'enableHttp2', + 'enableQuic', + // #endif + // #ifdef MP-TOUTIAO || MP-WEIXIN + 'enableCache', + // #endif + // #ifdef MP-WEIXIN + 'enableHttpDNS', + 'httpDNSServiceId', + 'enableChunked', + 'forceCellularNetwork', + // #endif + // #ifdef MP-ALIPAY + 'enableCookie', + // #endif + // #ifdef MP-BAIDU + 'cloudCache', + 'defer' + // #endif + ] + requestTask = uni.request({..._config, ...mergeKeys(optionalKeys, config)}) + } + if (config.getTask) { + config.getTask(requestTask, config) + } + }) +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js b/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js new file mode 100644 index 0000000..3ea0d5e --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js @@ -0,0 +1,51 @@ +'use strict' + + +function InterceptorManager() { + this.handlers = [] +} + +/** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ +InterceptorManager.prototype.use = function use(fulfilled, rejected) { + this.handlers.push({ + fulfilled: fulfilled, + rejected: rejected + }) + return this.handlers.length - 1 +} + +/** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + */ +InterceptorManager.prototype.eject = function eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null + } +} + +/** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + */ +InterceptorManager.prototype.forEach = function forEach(fn) { + this.handlers.forEach(h => { + if (h !== null) { + fn(h) + } + }) +} + +export default InterceptorManager diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js b/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js new file mode 100644 index 0000000..96c89a8 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js @@ -0,0 +1,201 @@ +/** + * @Class Request + * @description luch-request http请求插件 + * @Author lu-ch + * @Email webwork.s@qq.com + * 文档: https://www.quanzhan.co/luch-request/ + * github: https://github.com/lei-mu/luch-request + * DCloud: http://ext.dcloud.net.cn/plugin?id=392 + */ + + +import dispatchRequest from './dispatchRequest' +import InterceptorManager from './InterceptorManager' +import mergeConfig from './mergeConfig' +import defaults from './defaults' +import { isPlainObject } from '../utils' +import clone from '../utils/clone' + +export default class Request { + /** + * @param {Object} arg - 全局配置 + * @param {String} arg.baseURL - 全局根路径 + * @param {Object} arg.header - 全局header + * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式 + * @param {String} arg.dataType = [json] - 全局默认的dataType + * @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持 + * @param {Object} arg.custom - 全局默认的自定义参数 + * @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序 + * @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+) + * @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+) + * @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+) + * @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300 + */ + constructor(arg = {}) { + if (!isPlainObject(arg)) { + arg = {} + console.warn('设置全局参数必须接收一个Object') + } + this.config = clone({...defaults, ...arg}) + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + } + } + + /** + * @Function + * @param {Request~setConfigCallback} f - 设置全局默认配置 + */ + setConfig(f) { + this.config = f(this.config) + } + + middleware(config) { + config = mergeConfig(this.config, config) + let chain = [dispatchRequest, undefined] + let promise = Promise.resolve(config) + + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + chain.unshift(interceptor.fulfilled, interceptor.rejected) + }) + + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + chain.push(interceptor.fulfilled, interceptor.rejected) + }) + + while (chain.length) { + promise = promise.then(chain.shift(), chain.shift()) + } + + return promise + } + + /** + * @Function + * @param {Object} config - 请求配置项 + * @prop {String} options.url - 请求路径 + * @prop {Object} options.data - 请求参数 + * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型 + * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse + * @prop {Object} [options.header = config.header] - 请求header + * @prop {Object} [options.method = config.method] - 请求方法 + * @returns {Promise} + */ + request(config = {}) { + return this.middleware(config) + } + + get(url, options = {}) { + return this.middleware({ + url, + method: 'GET', + ...options + }) + } + + post(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'POST', + ...options + }) + } + + // #ifndef MP-ALIPAY || MP-KUAISHOU || MP-JD + put(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'PUT', + ...options + }) + } + + // #endif + + // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU + delete(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'DELETE', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN + connect(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'CONNECT', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN || MP-BAIDU + head(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'HEAD', + ...options + }) + } + + // #endif + + // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU + options(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'OPTIONS', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN + trace(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'TRACE', + ...options + }) + } + + // #endif + + upload(url, config = {}) { + config.url = url + config.method = 'UPLOAD' + return this.middleware(config) + } + + download(url, config = {}) { + config.url = url + config.method = 'DOWNLOAD' + return this.middleware(config) + } + + get version () { + return '3.1.0' + } +} + + +/** + * setConfig回调 + * @return {Object} - 返回操作后的config + * @callback Request~setConfigCallback + * @param {Object} config - 全局默认config + */ diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js b/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js new file mode 100644 index 0000000..f2852f4 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js @@ -0,0 +1,20 @@ +'use strict' + +import isAbsoluteURL from '../helpers/isAbsoluteURL' +import combineURLs from '../helpers/combineURLs' + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * @returns {string} The combined full path + */ +export default function buildFullPath(baseURL, requestedURL) { + if (baseURL && !isAbsoluteURL(requestedURL)) { + return combineURLs(baseURL, requestedURL) + } + return requestedURL +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js b/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js new file mode 100644 index 0000000..db74609 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js @@ -0,0 +1,33 @@ +/** + * 默认的全局配置 + */ + + +export default { + baseURL: '', + header: {}, + method: 'GET', + dataType: 'json', + paramsSerializer: null, + // #ifndef MP-ALIPAY + responseType: 'text', + // #endif + custom: {}, + // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU + timeout: 60000, + // #endif + // #ifdef APP-PLUS + sslVerify: true, + // #endif + // #ifdef H5 + withCredentials: false, + // #endif + // #ifdef APP-PLUS + firstIpv4: false, + // #endif + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300 + }, + // 是否尝试将响应数据json化 + forcedJSONParsing: true +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js b/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js new file mode 100644 index 0000000..c5f2c85 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js @@ -0,0 +1,6 @@ +import adapter from '../adapters/index' + + +export default (config) => { + return adapter(config) +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js b/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js new file mode 100644 index 0000000..99c8ecd --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js @@ -0,0 +1,126 @@ +import {deepMerge, isUndefined} from '../utils' + +/** + * 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局 + * @param {Array} keys - 配置项 + * @param {Object} globalsConfig - 当前的全局配置 + * @param {Object} config2 - 局部配置 + * @return {{}} + */ +const mergeKeys = (keys, globalsConfig, config2) => { + let config = {} + keys.forEach(prop => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } else if (!isUndefined(globalsConfig[prop])) { + config[prop] = globalsConfig[prop] + } + }) + return config +} +/** + * + * @param globalsConfig - 当前实例的全局配置 + * @param config2 - 当前的局部配置 + * @return - 合并后的配置 + */ +export default (globalsConfig, config2 = {}) => { + const method = config2.method || globalsConfig.method || 'GET' + let config = { + baseURL: config2.baseURL || globalsConfig.baseURL || '', + method: method, + url: config2.url || '', + params: config2.params || {}, + custom: {...(globalsConfig.custom || {}), ...(config2.custom || {})}, + header: deepMerge(globalsConfig.header || {}, config2.header || {}) + } + const defaultToConfig2Keys = ['getTask', 'validateStatus', 'paramsSerializer', 'forcedJSONParsing'] + config = {...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2)} + + // eslint-disable-next-line no-empty + if (method === 'DOWNLOAD') { + const downloadKeys = [ + // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU + 'timeout', + // #endif + // #ifdef MP + 'filePath', + // #endif + ] + config = {...config, ...mergeKeys(downloadKeys, globalsConfig, config2)} + } else if (method === 'UPLOAD') { + delete config.header['content-type'] + delete config.header['Content-Type'] + const uploadKeys = [ + // #ifdef APP-PLUS || H5 + 'files', + // #endif + // #ifdef MP-ALIPAY + 'fileType', + // #endif + // #ifdef H5 + 'file', + // #endif + 'filePath', + 'name', + // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU + 'timeout', + // #endif + 'formData', + ] + uploadKeys.forEach(prop => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } + }) + // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU + if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) { + config['timeout'] = globalsConfig['timeout'] + } + // #endif + } else { + const defaultsKeys = [ + 'data', + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + 'timeout', + // #endif + 'dataType', + // #ifndef MP-ALIPAY + 'responseType', + // #endif + // #ifdef APP-PLUS + 'sslVerify', + // #endif + // #ifdef H5 + 'withCredentials', + // #endif + // #ifdef APP-PLUS + 'firstIpv4', + // #endif + // #ifdef MP-WEIXIN + 'enableHttp2', + 'enableQuic', + // #endif + // #ifdef MP-TOUTIAO || MP-WEIXIN + 'enableCache', + // #endif + // #ifdef MP-WEIXIN + 'enableHttpDNS', + 'httpDNSServiceId', + 'enableChunked', + 'forceCellularNetwork', + // #endif + // #ifdef MP-ALIPAY + 'enableCookie', + // #endif + // #ifdef MP-BAIDU + 'cloudCache', + 'defer' + // #endif + + ] + config = {...config, ...mergeKeys(defaultsKeys, globalsConfig, config2)} + } + + return config +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js b/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js new file mode 100644 index 0000000..b2f1659 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js @@ -0,0 +1,16 @@ +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + */ +export default function settle(resolve, reject, response) { + const validateStatus = response.config.validateStatus + const status = response.statusCode + if (status && (!validateStatus || validateStatus(status))) { + resolve(response) + } else { + reject(response) + } +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js new file mode 100644 index 0000000..e90b908 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js @@ -0,0 +1,64 @@ +'use strict' + +import * as utils from './../utils' + +function encode(val) { + return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']') +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @returns {string} The formatted url + */ +export default function buildURL(url, params, paramsSerializer) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url + } + + var serializedParams + if (paramsSerializer) { + serializedParams = paramsSerializer(params) + } else if (utils.isURLSearchParams(params)) { + serializedParams = params.toString() + } else { + var parts = [] + + utils.forEach(params, function serialize(val, key) { + if (val === null || typeof val === 'undefined') { + return + } + + if (utils.isArray(val)) { + key = key + '[]' + } else { + val = [val] + } + + utils.forEach(val, function parseValue(v) { + if (utils.isDate(v)) { + v = v.toISOString() + } else if (utils.isObject(v)) { + v = JSON.stringify(v) + } + parts.push(encode(key) + '=' + encode(v)) + }) + }) + + serializedParams = parts.join('&') + } + + if (serializedParams) { + var hashmarkIndex = url.indexOf('#') + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex) + } + + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams + } + + return url +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js new file mode 100644 index 0000000..7b9d1ef --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js @@ -0,0 +1,14 @@ +'use strict' + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * @returns {string} The combined URL + */ +export default function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js new file mode 100644 index 0000000..2a82517 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js @@ -0,0 +1,14 @@ +'use strict' + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +export default function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url) +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts b/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts new file mode 100644 index 0000000..62d3fb9 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts @@ -0,0 +1,197 @@ +export type HttpTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask; + +export type HttpRequestTask = UniApp.RequestTask; + +export type HttpUploadTask = UniApp.UploadTask; + +export type HttpDownloadTask = UniApp.DownloadTask; + +export type HttpMethod = + "GET" + | "POST" + | "PUT" + | "DELETE" + | "CONNECT" + | "HEAD" + | "OPTIONS" + | "TRACE" + | "UPLOAD" + | "DOWNLOAD"; + +export type HttpRequestHeader = Record; + +export type HttpParams = Record; + +export type HttpData = Record; + +export type HttpResponseType = 'arraybuffer' | 'text'; + +export type HttpCustom = Record; + +export type HttpFileType = 'image' | 'video' | 'audio'; + +export type HttpFormData = Record; + +export type HttpResponseHeader = Record & { + "set-cookie"?: string[] +}; + +export interface HttpRequestConfig { + /** @desc 请求服务器接口地址 */ + url?: string; + /** @desc 请求方式,默认为 GET */ + method?: HttpMethod; + /** @desc 请求基地址 */ + baseURL?: string; + /** @desc 请求头信息,不能设置 Referer,App、H5 端会自动带上 cookie,且 H5 端不可手动修改 */ + header?: HttpRequestHeader; + /** @desc 请求查询参数,自动拼接为查询字符串 */ + params?: HttpParams; + /** @desc 请求体参数 */ + data?: HttpData; + /** @desc 超时时间,单位 ms,默认为 60000,仅 H5 (HBuilderX 2.9.9+)、APP (HBuilderX 2.9.9+)、微信小程序 (2.10.0)、支付宝小程序支持 */ + timeout?: number; + /** @desc 跨域请求时是否携带凭证 (cookies),默认为 false,仅 H5 (HBuilderX 2.6.15+) 支持 */ + withCredentials?: boolean; + /** @desc 设置响应的数据类型,支付宝小程序不支持 */ + responseType?: HttpResponseType; + /** @desc 全局自定义验证器 */ + validateStatus?: ((statusCode: number) => boolean) | null; + + + /** params 参数自定义处理 */ + paramsSerializer?: (params: AnyObject) => string | void; + + /** @desc 默认为 json,如果设为 json,会尝试对返回的数据做一次 JSON.parse */ + dataType?: string; + /** @desc DNS 解析时是否优先使用 ipv4,默认为 false,仅 App-Android (HBuilderX 2.8.0+) 支持 */ + firstIpv4?: boolean; + /** @desc 是否验证 SSL 证书,默认为 true,仅 App-Android (HBuilderX 2.3.3+) 支持 */ + sslVerify?: boolean; + + /** @desc 开启 http2;微信小程序 */ + enableHttp2?: boolean; + + /** @desc 开启 quic;微信小程序 */ + enableQuic?: boolean; + /** @desc 开启 cache;微信小程序、字节跳动小程序 2.31.0+ */ + enableCache?: boolean; + /** @desc 开启 httpDNS;微信小程序 */ + enableHttpDNS?: boolean; + /** @desc httpDNS 服务商;微信小程序 */ + httpDNSServiceId?: string; + /** @desc 开启 transfer-encoding chunked;微信小程序 */ + enableChunked?: boolean; + /** @desc wifi下使用移动网络发送请求;微信小程序 */ + forceCellularNetwork?: boolean; + /** @desc 开启后可在headers中编辑cookie;支付宝小程序 10.2.33+ */ + enableCookie?: boolean; + /** @desc 是否开启云加速;百度小程序 3.310.11+ */ + cloudCache?: boolean | object; + /** @desc 控制当前请求是否延时至首屏内容渲染后发送;百度小程序 3.310.11+ */ + defer?: boolean; + + /** @desc 自定义参数 */ + custom?: HttpCustom; + + /** @desc 返回当前请求的 task 和 options,不要在这里修改 options */ + getTask?: (task: T, options: HttpRequestConfig) => void; + + /** @desc 需要上传的文件列表,使用 files 时,filePath 和 name 不生效,仅支持 App、H5 (2.6.15+) */ + files?: { name?: string; file?: File; uri: string; }[]; + /** @desc 文件类型,仅支付宝小程序支持且为必填项 */ + fileType?: HttpFileType; + /** @desc 要上传的文件对象,仅 H5 (2.6.15+) 支持 */ + file?: File; + /** @desc 要上传文件资源的路径,使用 files 时,filePath 和 name 不生效 */ + filePath?: string; + /** @desc 文件对应的 key,开发者在服务器端通过这个 key 可以获取到文件二进制内容,使用 files 时,filePath 和 name 不生效 */ + name?: string; + /** @desc 请求中其他额外的 form data */ + formData?: HttpFormData; +} + +export interface HttpResponse { + data: T; + statusCode: number; + header: HttpResponseHeader; + config: HttpRequestConfig; + cookies: string[]; + errMsg: string; + rawData: any; +} + +export interface HttpUploadResponse { + data: T; + statusCode: number; + config: HttpRequestConfig; + errMsg: string; + rawData: any; +} + +export interface HttpDownloadResponse extends HttpResponse { + tempFilePath: string; + apFilePath?: string; + filePath?: string; + fileContent?: string; +} + +export interface HttpError { + data?: T; + statusCode?: number; + header?: HttpResponseHeader; + config: HttpRequestConfig; + cookies?: string[]; + errMsg: string; +} + +export interface HttpPromise extends Promise> { +} + +export interface HttpInterceptorManager { + use(onFulfilled?: (value: V) => V | Promise, onRejected?: (error: E) => T | Promise): void; + + eject(id: number): void; +} + +export abstract class HttpRequestAbstract { + constructor(config?: HttpRequestConfig); + + interceptors: { + request: HttpInterceptorManager; + response: HttpInterceptorManager; + } + + request, D = HttpRequestTask>(config: HttpRequestConfig): Promise; + + get, D = HttpRequestTask>(url: string, config?: HttpRequestConfig): Promise; + + delete, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig): Promise; + + head, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig): Promise; + + options, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig): Promise; + + post, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig): Promise; + + put, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig): Promise; + + config: HttpRequestConfig; + + setConfig(onSend: (config: HttpRequestConfig) => HttpRequestConfig): void; + + connect, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig): Promise; + + trace, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig): Promise; + + upload, D = HttpUploadTask>(url: string, config?: HttpRequestConfig): Promise; + + download, D = HttpDownloadTask>(url: string, config?: HttpRequestConfig): Promise; + + middleware, D = HttpTask>(config: HttpRequestConfig): Promise; +} + +declare class HttpRequest extends HttpRequestAbstract { +} + +export default HttpRequest; diff --git a/uni_modules/uv-ui-tools/libs/luch-request/index.js b/uni_modules/uv-ui-tools/libs/luch-request/index.js new file mode 100644 index 0000000..d8fe348 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/index.js @@ -0,0 +1,2 @@ +import Request from './core/Request' +export default Request diff --git a/uni_modules/uv-ui-tools/libs/luch-request/utils.js b/uni_modules/uv-ui-tools/libs/luch-request/utils.js new file mode 100644 index 0000000..0b5bf21 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/utils.js @@ -0,0 +1,135 @@ +'use strict' + +// utils is a library of generic helper functions non-specific to axios + +var toString = Object.prototype.toString + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Array, otherwise false + */ +export function isArray (val) { + return toString.call(val) === '[object Array]' +} + + +/** + * Determine if a value is an Object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Object, otherwise false + */ +export function isObject (val) { + return val !== null && typeof val === 'object' +} + +/** + * Determine if a value is a Date + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Date, otherwise false + */ +export function isDate (val) { + return toString.call(val) === '[object Date]' +} + +/** + * Determine if a value is a URLSearchParams object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +export function isURLSearchParams (val) { + return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams +} + + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + */ +export function forEach (obj, fn) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return + } + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj] + } + + if (isArray(obj)) { + // Iterate over array values + for (var i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj) + } + } else { + // Iterate over object keys + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + fn.call(null, obj[key], key, obj) + } + } + } +} + +/** + * 是否为boolean 值 + * @param val + * @returns {boolean} + */ +export function isBoolean(val) { + return typeof val === 'boolean' +} + +/** + * 是否为真正的对象{} new Object + * @param {any} obj - 检测的对象 + * @returns {boolean} + */ +export function isPlainObject(obj) { + return Object.prototype.toString.call(obj) === '[object Object]' +} + + + +/** + * Function equal to merge with the difference being that no reference + * to original objects is kept. + * + * @see merge + * @param {Object} obj1 Object to merge + * @returns {Object} Result of all merge properties + */ +export function deepMerge(/* obj1, obj2, obj3, ... */) { + let result = {} + function assignValue(val, key) { + if (typeof result[key] === 'object' && typeof val === 'object') { + result[key] = deepMerge(result[key], val) + } else if (typeof val === 'object') { + result[key] = deepMerge({}, val) + } else { + result[key] = val + } + } + for (let i = 0, l = arguments.length; i < l; i++) { + forEach(arguments[i], assignValue) + } + return result +} + +export function isUndefined (val) { + return typeof val === 'undefined' +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js b/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js new file mode 100644 index 0000000..2fee704 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js @@ -0,0 +1,264 @@ +/* eslint-disable */ +var clone = (function() { + 'use strict'; + + function _instanceof(obj, type) { + return type != null && obj instanceof type; + } + + var nativeMap; + try { + nativeMap = Map; + } catch(_) { + // maybe a reference error because no `Map`. Give it a dummy value that no + // value will ever be an instanceof. + nativeMap = function() {}; + } + + var nativeSet; + try { + nativeSet = Set; + } catch(_) { + nativeSet = function() {}; + } + + var nativePromise; + try { + nativePromise = Promise; + } catch(_) { + nativePromise = function() {}; + } + + /** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). + * @param `includeNonEnumerable` - set to true if the non-enumerable properties + * should be cloned as well. Non-enumerable properties on the prototype + * chain will be ignored. (optional - false by default) + */ + function clone(parent, circular, depth, prototype, includeNonEnumerable) { + if (typeof circular === 'object') { + depth = circular.depth; + prototype = circular.prototype; + includeNonEnumerable = circular.includeNonEnumerable; + circular = circular.circular; + } + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular == 'undefined') + circular = true; + + if (typeof depth == 'undefined') + depth = Infinity; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + + if (depth === 0) + return parent; + + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + + if (_instanceof(parent, nativeMap)) { + child = new nativeMap(); + } else if (_instanceof(parent, nativeSet)) { + child = new nativeSet(); + } else if (_instanceof(parent, nativePromise)) { + child = new nativePromise(function (resolve, reject) { + parent.then(function(value) { + resolve(_clone(value, depth - 1)); + }, function(err) { + reject(_clone(err, depth - 1)); + }); + }); + } else if (clone.__isArray(parent)) { + child = []; + } else if (clone.__isRegExp(parent)) { + child = new RegExp(parent.source, __getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (clone.__isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + if (Buffer.from) { + // Node.js >= 5.10.0 + child = Buffer.from(parent); + } else { + // Older Node.js versions + child = new Buffer(parent.length); + parent.copy(child); + } + return child; + } else if (_instanceof(parent, Error)) { + child = Object.create(parent); + } else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + if (_instanceof(parent, nativeMap)) { + parent.forEach(function(value, key) { + var keyChild = _clone(key, depth - 1); + var valueChild = _clone(value, depth - 1); + child.set(keyChild, valueChild); + }); + } + if (_instanceof(parent, nativeSet)) { + parent.forEach(function(value) { + var entryChild = _clone(value, depth - 1); + child.add(entryChild); + }); + } + + for (var i in parent) { + var attrs = Object.getOwnPropertyDescriptor(parent, i); + if (attrs) { + child[i] = _clone(parent[i], depth - 1); + } + + try { + var objProperty = Object.getOwnPropertyDescriptor(parent, i); + if (objProperty.set === 'undefined') { + // no setter defined. Skip cloning this property + continue; + } + child[i] = _clone(parent[i], depth - 1); + } catch(e){ + if (e instanceof TypeError) { + // when in strict mode, TypeError will be thrown if child[i] property only has a getter + // we can't do anything about this, other than inform the user that this property cannot be set. + continue + } else if (e instanceof ReferenceError) { + //this may happen in non strict mode + continue + } + } + + } + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(parent); + for (var i = 0; i < symbols.length; i++) { + // Don't need to worry about cloning a symbol because it is a primitive, + // like a number or string. + var symbol = symbols[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); + if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { + continue; + } + child[symbol] = _clone(parent[symbol], depth - 1); + Object.defineProperty(child, symbol, descriptor); + } + } + + if (includeNonEnumerable) { + var allPropertyNames = Object.getOwnPropertyNames(parent); + for (var i = 0; i < allPropertyNames.length; i++) { + var propertyName = allPropertyNames[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); + if (descriptor && descriptor.enumerable) { + continue; + } + child[propertyName] = _clone(parent[propertyName], depth - 1); + Object.defineProperty(child, propertyName, descriptor); + } + } + + return child; + } + + return _clone(parent, depth); + } + + /** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ + clone.clonePrototype = function clonePrototype(parent) { + if (parent === null) + return null; + + var c = function () {}; + c.prototype = parent; + return new c(); + }; + +// private utility functions + + function __objToStr(o) { + return Object.prototype.toString.call(o); + } + clone.__objToStr = __objToStr; + + function __isDate(o) { + return typeof o === 'object' && __objToStr(o) === '[object Date]'; + } + clone.__isDate = __isDate; + + function __isArray(o) { + return typeof o === 'object' && __objToStr(o) === '[object Array]'; + } + clone.__isArray = __isArray; + + function __isRegExp(o) { + return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; + } + clone.__isRegExp = __isRegExp; + + function __getRegExpFlags(re) { + var flags = ''; + if (re.global) flags += 'g'; + if (re.ignoreCase) flags += 'i'; + if (re.multiline) flags += 'm'; + return flags; + } + clone.__getRegExpFlags = __getRegExpFlags; + + return clone; +})(); + +export default clone diff --git a/uni_modules/uv-ui-tools/libs/mixin/button.js b/uni_modules/uv-ui-tools/libs/mixin/button.js new file mode 100644 index 0000000..0c019c2 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/button.js @@ -0,0 +1,13 @@ +export default { + props: { + lang: String, + sessionFrom: String, + sendMessageTitle: String, + sendMessagePath: String, + sendMessageImg: String, + showMessageCard: Boolean, + appParameter: String, + formType: String, + openType: String + } +} diff --git a/uni_modules/uv-ui-tools/libs/mixin/mixin.js b/uni_modules/uv-ui-tools/libs/mixin/mixin.js new file mode 100644 index 0000000..0dd3b03 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/mixin.js @@ -0,0 +1,172 @@ +import * as index from '../function/index.js'; +import * as test from '../function/test.js'; +import route from '../util/route.js'; +import debounce from '../function/debounce.js'; +import throttle from '../function/throttle.js'; +export default { + // 定义每个组件都可能需要用到的外部样式以及类名 + props: { + // 每个组件都有的父组件传递的样式,可以为字符串或者对象形式 + customStyle: { + type: [Object, String], + default: () => ({}) + }, + customClass: { + type: String, + default: '' + }, + // 跳转的页面路径 + url: { + type: String, + default: '' + }, + // 页面跳转的类型 + linkType: { + type: String, + default: 'navigateTo' + } + }, + data() { + return {} + }, + onLoad() { + // getRect挂载到$uv上,因为这方法需要使用in(this),所以无法把它独立成一个单独的文件导出 + this.$uv.getRect = this.$uvGetRect + }, + created() { + // 组件当中,只有created声明周期,为了能在组件使用,故也在created中将方法挂载到$uv + this.$uv.getRect = this.$uvGetRect + }, + computed: { + $uv() { + return { + ...index, + test, + route, + debounce, + throttle, + unit: uni?.$uv?.config?.unit + } + }, + /** + * 生成bem规则类名 + * 由于微信小程序,H5,nvue之间绑定class的差异,无法通过:class="[bem()]"的形式进行同用 + * 故采用如下折中做法,最后返回的是数组(一般平台)或字符串(支付宝和字节跳动平台),类似['a', 'b', 'c']或'a b c'的形式 + * @param {String} name 组件名称 + * @param {Array} fixed 一直会存在的类名 + * @param {Array} change 会根据变量值为true或者false而出现或者隐藏的类名 + * @returns {Array|string} + */ + bem() { + return function(name, fixed, change) { + // 类名前缀 + const prefix = `uv-${name}--` + const classes = {} + if (fixed) { + fixed.map((item) => { + // 这里的类名,会一直存在 + classes[prefix + this[item]] = true + }) + } + if (change) { + change.map((item) => { + // 这里的类名,会根据this[item]的值为true或者false,而进行添加或者移除某一个类 + this[item] ? (classes[prefix + item] = this[item]) : (delete classes[prefix + item]) + }) + } + return Object.keys(classes) + // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效 + // #ifdef MP-ALIPAY || MP-TOUTIAO || MP-LARK || MP-BAIDU + .join(' ') + // #endif + } + } + }, + methods: { + // 跳转某一个页面 + openPage(urlKey = 'url') { + const url = this[urlKey] + if (url) { + // 执行类似uni.navigateTo的方法 + uni[this.linkType]({ + url + }) + } + }, + // 查询节点信息 + // 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21) + // 解决办法为在组件根部再套一个没有任何作用的view元素 + $uvGetRect(selector, all) { + return new Promise((resolve) => { + uni.createSelectorQuery() + .in(this)[all ? 'selectAll' : 'select'](selector) + .boundingClientRect((rect) => { + if (all && Array.isArray(rect) && rect.length) { + resolve(rect) + } + if (!all && rect) { + resolve(rect) + } + }) + .exec() + }) + }, + getParentData(parentName = '') { + // 避免在created中去定义parent变量 + if (!this.parent) this.parent = {} + // 这里的本质原理是,通过获取父组件实例(也即类似uv-radio的父组件uv-radio-group的this) + // 将父组件this中对应的参数,赋值给本组件(uv-radio的this)的parentData对象中对应的属性 + // 之所以需要这么做,是因为所有端中,头条小程序不支持通过this.parent.xxx去监听父组件参数的变化 + // 此处并不会自动更新子组件的数据,而是依赖父组件uv-radio-group去监听data的变化,手动调用更新子组件的方法去重新获取 + this.parent = this.$uv.$parent.call(this, parentName) + if (this.parent.children) { + // 如果父组件的children不存在本组件的实例,才将本实例添加到父组件的children中 + this.parent.children.indexOf(this) === -1 && this.parent.children.push(this) + } + if (this.parent && this.parentData) { + // 历遍parentData中的属性,将parent中的同名属性赋值给parentData + Object.keys(this.parentData).map((key) => { + this.parentData[key] = this.parent[key] + }) + } + }, + // 阻止事件冒泡 + preventEvent(e) { + e && typeof(e.stopPropagation) === 'function' && e.stopPropagation() + }, + // 空操作 + noop(e) { + this.preventEvent(e) + } + }, + onReachBottom() { + uni.$emit('uvOnReachBottom') + }, + beforeDestroy() { + // 判断当前页面是否存在parent和chldren,一般在checkbox和checkbox-group父子联动的场景会有此情况 + // 组件销毁时,移除子组件在父组件children数组中的实例,释放资源,避免数据混乱 + if (this.parent && test.array(this.parent.children)) { + // 组件销毁时,移除父组件中的children数组中对应的实例 + const childrenList = this.parent.children + childrenList.map((child, index) => { + // 如果相等,则移除 + if (child === this) { + childrenList.splice(index, 1) + } + }) + } + }, + // 兼容vue3 + unmounted() { + if (this.parent && test.array(this.parent.children)) { + // 组件销毁时,移除父组件中的children数组中对应的实例 + const childrenList = this.parent.children + childrenList.map((child, index) => { + // 如果相等,则移除 + if (child === this) { + childrenList.splice(index, 1) + } + }) + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js b/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js new file mode 100644 index 0000000..90b6903 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js @@ -0,0 +1,8 @@ +export default { + // #ifdef MP-WEIXIN + // 将自定义节点设置成虚拟的(去掉自定义组件包裹层),更加接近Vue组件的表现,能更好的使用flex属性 + options: { + virtualHost: true + } + // #endif +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/mixin/mpShare.js b/uni_modules/uv-ui-tools/libs/mixin/mpShare.js new file mode 100644 index 0000000..c9695a0 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/mpShare.js @@ -0,0 +1,13 @@ +export default { + onLoad() { + // 设置默认的转发参数 + uni.$uv.mpShare = { + title: '', // 默认为小程序名称 + path: '', // 默认为当前页面路径 + imageUrl: '' // 默认为当前页面的截图 + } + }, + onShareAppMessage() { + return uni.$uv.mpShare + } +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/mixin/openType.js b/uni_modules/uv-ui-tools/libs/mixin/openType.js new file mode 100644 index 0000000..1b94b7e --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/openType.js @@ -0,0 +1,47 @@ +export default { + props: { + openType: String + }, + emits: ['getphonenumber','getuserinfo','error','opensetting','launchapp','contact','chooseavatar','addgroupapp','chooseaddress','subscribe','login','im'], + methods: { + onGetPhoneNumber(event) { + this.$emit('getphonenumber', event.detail) + }, + onGetUserInfo(event) { + this.$emit('getuserinfo', event.detail) + }, + onError(event) { + this.$emit('error', event.detail) + }, + onOpenSetting(event) { + this.$emit('opensetting', event.detail) + }, + onLaunchApp(event) { + this.$emit('launchapp', event.detail) + }, + onContact(event) { + this.$emit('contact', event.detail) + }, + onChooseavatar(event) { + this.$emit('chooseavatar', event.detail) + }, + onAgreeprivacyauthorization(event) { + this.$emit('agreeprivacyauthorization', event.detail) + }, + onAddgroupapp(event) { + this.$emit('addgroupapp', event.detail) + }, + onChooseaddress(event) { + this.$emit('chooseaddress', event.detail) + }, + onSubscribe(event) { + this.$emit('subscribe', event.detail) + }, + onLogin(event) { + this.$emit('login', event.detail) + }, + onIm(event) { + this.$emit('im', event.detail) + } + } +} diff --git a/uni_modules/uv-ui-tools/libs/mixin/touch.js b/uni_modules/uv-ui-tools/libs/mixin/touch.js new file mode 100644 index 0000000..0ecbd88 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/touch.js @@ -0,0 +1,59 @@ +const MIN_DISTANCE = 10 + +function getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal' + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical' + } + return '' +} + +export default { + methods: { + getTouchPoint(e) { + if (!e) { + return { + x: 0, + y: 0 + } + } if (e.touches && e.touches[0]) { + return { + x: e.touches[0].pageX, + y: e.touches[0].pageY + } + } if (e.changedTouches && e.changedTouches[0]) { + return { + x: e.changedTouches[0].pageX, + y: e.changedTouches[0].pageY + } + } + return { + x: e.clientX || 0, + y: e.clientY || 0 + } + }, + resetTouchStatus() { + this.direction = '' + this.deltaX = 0 + this.deltaY = 0 + this.offsetX = 0 + this.offsetY = 0 + }, + touchStart(event) { + this.resetTouchStatus() + const touch = this.getTouchPoint(event) + this.startX = touch.x + this.startY = touch.y + }, + touchMove(event) { + const touch = this.getTouchPoint(event) + this.deltaX = touch.x - this.startX + this.deltaY = touch.y - this.startY + this.offsetX = Math.abs(this.deltaX) + this.offsetY = Math.abs(this.deltaY) + this.direction = this.direction || getDirection(this.offsetX, this.offsetY) + } + } +} diff --git a/uni_modules/uv-ui-tools/libs/util/dayjs.js b/uni_modules/uv-ui-tools/libs/util/dayjs.js new file mode 100644 index 0000000..c84ab68 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/util/dayjs.js @@ -0,0 +1,216 @@ +var __getOwnPropNames = Object.getOwnPropertyNames; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; + +var require_dayjs_min = __commonJS({ + "uvuidayjs"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", f = "month", h = "quarter", c = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, f), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), f); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: f, y: c, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: h }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = function(t2) { + return t2 instanceof _; + }, S = function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, w = function(t2, e2) { + if (p(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, O = v; + O.l = S, O.i = p, O.w = function(t2, e2) { + return w(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = S(t2.locale, null, true), this.parse(t2); + } + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return new Date(NaN); + if (O.u(e2)) + return new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.$x = t2.x || {}, this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return O; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = w(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return w(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < w(t2); + }, m2.$g = function(t2, e2, n2) { + return O.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!O.u(e2) || e2, h2 = O.p(t2), l2 = function(t3, e3) { + var i2 = O.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, $2 = function(t3, e3) { + return O.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (h2) { + case c: + return r2 ? l2(1, 0) : l2(31, 11); + case f: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = O.p(t2), h2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = h2 + "Date", n2[d] = h2 + "Date", n2[f] = h2 + "Month", n2[c] = h2 + "FullYear", n2[u] = h2 + "Hours", n2[s] = h2 + "Minutes", n2[i] = h2 + "Seconds", n2[r] = h2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === f || o2 === c) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[O.p(t2)](); + }, m2.add = function(r2, h2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = O.p(h2), y2 = function(t2) { + var e2 = w(l2); + return O.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }; + if ($2 === f) + return this.set(f, this.$M + r2); + if ($2 === c) + return this.set(c, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return O.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = O.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, f2 = n2.months, h2 = function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, c2 = function(t3) { + return O.s(s2 % 12 || 12, t3, "0"); + }, d2 = n2.meridiem || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }, $2 = { YY: String(this.$y).slice(-2), YYYY: this.$y, M: a2 + 1, MM: O.s(a2 + 1, 2, "0"), MMM: h2(n2.monthsShort, a2, f2, 3), MMMM: h2(f2, a2), D: this.$D, DD: O.s(this.$D, 2, "0"), d: String(this.$W), dd: h2(n2.weekdaysMin, this.$W, o2, 2), ddd: h2(n2.weekdaysShort, this.$W, o2, 3), dddd: o2[this.$W], H: String(s2), HH: O.s(s2, 2, "0"), h: c2(1), hh: c2(2), a: d2(s2, u2, true), A: d2(s2, u2, false), m: String(u2), mm: O.s(u2, 2, "0"), s: String(this.$s), ss: O.s(this.$s, 2, "0"), SSS: O.s(this.$ms, 3, "0"), Z: i2 }; + return r2.replace(y, function(t3, e3) { + return e3 || $2[t3] || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = O.p(d2), M3 = w(r2), m3 = (M3.utcOffset() - this.utcOffset()) * e, v2 = this - M3, g2 = O.m(this, M3); + return g2 = ($2 = {}, $2[c] = g2 / 12, $2[f] = g2, $2[h] = g2 / 3, $2[o] = (v2 - m3) / 6048e5, $2[a] = (v2 - m3) / 864e5, $2[u] = v2 / n, $2[s] = v2 / e, $2[i] = v2 / t, $2)[y2] || v2, l2 ? g2 : O.a(g2); + }, m2.daysInMonth = function() { + return this.endOf(f).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = S(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return O.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), T = _.prototype; + return w.prototype = T, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", f], ["$y", c], ["$D", d]].forEach(function(t2) { + T[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), w.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, w), t2.$i = true), w; + }, w.locale = S, w.isDayjs = p, w.unix = function(t2) { + return w(1e3 * t2); + }, w.en = D[g], w.Ls = D, w.p = {}, w; + }); + } +}); +export default require_dayjs_min(); diff --git a/uni_modules/uv-ui-tools/libs/util/route.js b/uni_modules/uv-ui-tools/libs/util/route.js new file mode 100644 index 0000000..80c0afd --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/util/route.js @@ -0,0 +1,126 @@ +/** + * 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷 + * 并且带有路由拦截功能 + */ +import { queryParams, deepMerge, page } from '@/uni_modules/uv-ui-tools/libs/function/index.js' +class Router { + constructor() { + // 原始属性定义 + this.config = { + type: 'navigateTo', + url: '', + delta: 1, // navigateBack页面后退时,回退的层数 + params: {}, // 传递的参数 + animationType: 'pop-in', // 窗口动画,只在APP有效 + animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效 + intercept: false ,// 是否需要拦截 + events: {} // 页面间通信接口,用于监听被打开页面发送到当前页面的数据。hbuilderx 2.8.9+ 开始支持。 + } + // 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文 + // 这里在构造函数中进行this绑定 + this.route = this.route.bind(this) + } + + // 判断url前面是否有"/",如果没有则加上,否则无法跳转 + addRootPath(url) { + return url[0] === '/' ? url : `/${url}` + } + + // 整合路由参数 + mixinParam(url, params) { + url = url && this.addRootPath(url) + + // 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary" + // 如果有url中有get参数,转换后无需带上"?" + let query = '' + if (/.*\/.*\?.*=.*/.test(url)) { + // object对象转为get类型的参数 + query = queryParams(params, false) + // 因为已有get参数,所以后面拼接的参数需要带上"&"隔开 + return url += `&${query}` + } + // 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号 + query = queryParams(params) + return url += query + } + + // 对外的方法名称 + async route(options = {}, params = {}) { + // 合并用户的配置和内部的默认配置 + let mergeConfig = {} + + if (typeof options === 'string') { + // 如果options为字符串,则为route(url, params)的形式 + mergeConfig.url = this.mixinParam(options, params) + mergeConfig.type = 'navigateTo' + } else { + mergeConfig = deepMerge(this.config, options) + // 否则正常使用mergeConfig中的url和params进行拼接 + mergeConfig.url = this.mixinParam(options.url, options.params) + } + // 如果本次跳转的路径和本页面路径一致,不执行跳转,防止用户快速点击跳转按钮,造成多次跳转同一个页面的问题 + if (mergeConfig.url === page()) return + + if (params.intercept) { + mergeConfig.intercept = params.intercept + } + // params参数也带给拦截器 + mergeConfig.params = params + // 合并内外部参数 + mergeConfig = deepMerge(this.config, mergeConfig) + // 判断用户是否定义了拦截器 + if (typeof mergeConfig.intercept === 'function') { + // 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转 + const isNext = await new Promise((resolve, reject) => { + mergeConfig.intercept(mergeConfig, resolve) + }) + // 如果isNext为true,则执行路由跳转 + isNext && this.openPage(mergeConfig) + } else { + this.openPage(mergeConfig) + } + } + + // 执行路由跳转 + openPage(config) { + // 解构参数 + const { + url, + type, + delta, + animationType, + animationDuration, + events + } = config + if (config.type == 'navigateTo' || config.type == 'to') { + uni.navigateTo({ + url, + animationType, + animationDuration, + events + }) + } + if (config.type == 'redirectTo' || config.type == 'redirect') { + uni.redirectTo({ + url + }) + } + if (config.type == 'switchTab' || config.type == 'tab') { + uni.switchTab({ + url + }) + } + if (config.type == 'reLaunch' || config.type == 'launch') { + uni.reLaunch({ + url + }) + } + if (config.type == 'navigateBack' || config.type == 'back') { + uni.navigateBack({ + delta + }) + } + } +} + +export default (new Router()).route \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/package.json b/uni_modules/uv-ui-tools/package.json new file mode 100644 index 0000000..2d940f6 --- /dev/null +++ b/uni_modules/uv-ui-tools/package.json @@ -0,0 +1,81 @@ +{ + "id": "uv-ui-tools", + "displayName": "uv-ui-tools 工具集 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.1.25", + "description": "uv-ui-tools,集成工具库,强大的Http请求封装,清晰的文档说明,开箱即用。方便使用,可以全局使用", + "keywords": [ + "uv-ui-tools,uv-ui组件库,工具集,uvui,uView2.x" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "y", + "快手": "y", + "飞书": "y", + "京东": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/readme.md b/uni_modules/uv-ui-tools/readme.md new file mode 100644 index 0000000..79a7df5 --- /dev/null +++ b/uni_modules/uv-ui-tools/readme.md @@ -0,0 +1,23 @@ +## uv-ui-tools 工具集 + +> **组件名:uv-ui-tools** + +uv-ui工具集成,包括网络Http请求、便捷工具、节流防抖、对象操作、时间格式化、路由跳转、全局唯一标识符、规则校验等等。 + +该组件推荐配合[uv-ui组件库](https://www.uvui.cn/components/intro.html)使用,单独下载也可以在自己项目中使用,需要做相应的配置,可查看文档。强烈推荐使用[uv-ui组件库](https://www.uvui.cn/components/intro.html),导入组件都会自动导入`uv-ui-tools`。需要在自己的项目中使用请参考[扩展配置](https://www.uvui.cn/components/setting.html)。 + +uv-ui破釜沉舟之兼容vue3+2、app、h5、多端小程序的uni-app生态框架,大部分组件基于uView2.x,在经过改进后全面支持vue3,部分组件做了进一步的优化,修复大量BUG,支持单独导入,方便开发者选择导入需要的组件。开箱即用,灵活配置。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/theme.scss b/uni_modules/uv-ui-tools/theme.scss new file mode 100644 index 0000000..cfaae92 --- /dev/null +++ b/uni_modules/uv-ui-tools/theme.scss @@ -0,0 +1,43 @@ +// 此文件为uvUI的主题变量,这些变量目前只能通过uni.scss引入才有效,另外由于 +// uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中,造成微信程序包太大, +// 故uni.scss只建议放scss变量名相关样式,其他的样式可以通过main.js或者App.vue引入 + +$uv-main-color: #303133; +$uv-content-color: #606266; +$uv-tips-color: #909193; +$uv-light-color: #c0c4cc; +$uv-border-color: #dadbde; +$uv-bg-color: #f3f4f6; +$uv-disabled-color: #c8c9cc; + +$uv-primary: #3c9cff; +$uv-primary-dark: #398ade; +$uv-primary-disabled: #9acafc; +$uv-primary-light: #ecf5ff; + +$uv-warning: #f9ae3d; +$uv-warning-dark: #f1a532; +$uv-warning-disabled: #f9d39b; +$uv-warning-light: #fdf6ec; + +$uv-success: #5ac725; +$uv-success-dark: #53c21d; +$uv-success-disabled: #a9e08f; +$uv-success-light: #f5fff0; + +$uv-error: #f56c6c; +$uv-error-dark: #e45656; +$uv-error-disabled: #f7b2b2; +$uv-error-light: #fef0f0; + +$uv-info: #909399; +$uv-info-dark: #767a82; +$uv-info-disabled: #c4c6c9; +$uv-info-light: #f4f4f5; + +@mixin flex($direction: row) { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: $direction; +} \ No newline at end of file diff --git a/uni_modules/uv-ui/changelog.md b/uni_modules/uv-ui/changelog.md new file mode 100644 index 0000000..fce7860 --- /dev/null +++ b/uni_modules/uv-ui/changelog.md @@ -0,0 +1,353 @@ +## 1.1.20(2024-01-20) +1. 优化 uv-loading-page重构,避免初始加载的时候先显示页面的问题,小程序平台由于性能问题,可能还是会短暂出现,请注意优化处理 +2. 优化 uv-textarea confirmType默认值改成return,支持换行 +3. 优化 uv-ui-tools luch-request更新 +4. 修复 uv-drop-down parentData不变的BUG +5. 修复 uv-picker 上个版本引出的BUG +6. 修复 uv-image 设置show-menu-by-longpress不生效的BUG +7. 修复 uv-upload 动态设置deletable为false不生效的BUG +## 1.1.19(2023-12-12) +1. 优化 uv-toast部分重构,支持取消遮罩不影响点击其他元素 a. 增加z-index参数;b. 增加overlay参数 +2. 优化 关于组件如何阻止事件冒泡,增加相关说明:[组件怎么阻止事件冒泡](https://www.uvui.cn/components/feature.html#组件怎么阻止事件冒泡) +3. 优化 持续优化文档 +4. 修复 uv-tabs current为字符串activeStyle不生效的BUG +5. 修复 uv-vtabs 在change回调中设置current,快速点击菜单,导致死循环的BUG +6. 修复 uv-cell right-icon插槽编译到APP端不显示的BUG,问题来源:[https://gitee.com/climblee/uv-ui/issues/I8LXZI](https://gitee.com/climblee/uv-ui/issues/I8LXZI) +## 1.1.18(2023-11-28) +0. 优化 uv-datetime-picker 增加round属性,设置弹窗圆角 +1. 优化 uv-subsection 增加customItemStyle属性,方便修改bar样式,比如设置圆角 +2. 修复 uv-picker issues反馈的问题uv-picker在组合式API的自定义组件中,columns动态赋值无法显示选项:[https://gitee.com/climblee/uv-ui/issues/I8H0GQ](https://gitee.com/climblee/uv-ui/issues/I8H0GQ) +3. 修复 uv-popup issues问题:[https://gitee.com/climblee/uv-ui/issues/I8HDLO](https://gitee.com/climblee/uv-ui/issues/I8HDLO) +4. 修复 uv-skeletons 支付宝小程序报错的BUG +5. 修复 uv-image webp之前未使用的BUG & 微信报错的BUG +6. 修复 uv-modal 上版本引出的确认和取消按钮均不显示,还有高度的BUG +## 1.1.17(2023-11-10) +0. 交流反馈 欢迎加入uv-ui官方群1交流反馈: 549833913(1000+) +1. 交流反馈 欢迎加入uv-ui官方群2交流反馈: 206060892 +2. 新增 新增其他小组件下载入口:其他小组件 +3. 优化 uv-calendars 增加readonly属性,是否为只读状态,只读状态下禁止选择日期 +4. 修复 uv-search 禁用时,不能触发click的BUG +5. 修复 uv-checkbox and uv-radio label文字过长,不换行的相关说明及处理 +6. 修复 uv-input and uv-search 点击clear按钮在微信小程序不好触发的BUG +7. 修复 uv-list 修复设置ellipsis不生效的BUG +8. 修复 uv-index-list 修复sticky属性不生效的BUG +## 1.1.16(2023-10-30) +1. 交流反馈 欢迎加入uv-ui官方群1交流反馈: 549833913(940+/1000) +2. 交流反馈 欢迎加入uv-ui官方群2交流反馈: 206060892 +3. 新增 uv-skeletons 骨架屏,全新升级骨架屏,更加灵活,体验更加,强烈推荐使用新版骨架屏。一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。 +4. 优化 uv-button 增加后置插槽suffix,方便在按钮文字后面增加图标等 +5. 优化 uv-popup vue模式内容有背景色,设置圆角被遮挡的情况 +6. 优化 uv-tabs 点击一个选项,change事件重复派发的问题 +7. 优化 持续优化文档及其他 +8. 修复 uv-album 设置singleSize、multipleSize、space等值带单位,存在不显示的BUG +9. 修复 uv-picker 省市级示例设置defaultValue,再次选择第二列错乱的BUG +10. 修复 uv-icon imgMode默认值改成aspectFit,否则会导致支付宝平台name设置为本地图片显示不全的BUG +11. 修复 uv-transition 在APP-IOS上不能正常显示的BUG +12. 修复 uv-toast、uv-swipe-action、uv-sticky、uv-notify、uv-notice-bar、uv-grid、uv-count-down、uv-code等组件,unmounted兼容vue3 +## 1.1.15(2023-10-12) +1. 优化 uv-keyboard a. 增加disKeys参数,mode = "car"下,被禁用的键,如:['I','O']; b. 增加customabc参数,mode = "car"下,是否启用自定义中英文切换内容模式,为了兼容支付宝等小程序不兼容嵌套插槽,导致同时显示自定义内容和原始内容; c. 增加ref方法changeCarMode,mode = "car"下, 调用此方法可以切换中英文模式; d. 增加@changeCarInputMode,mode = "car"下,调用此方法可以进行切换中英文; e. 增加插槽abc,mode = "car"下,自定义中英文切换内容 +2. 优化 uv-checkbox uv-radio 优化:https://gitee.com/climblee/uv-ui/issues/I872VD +3. 优化 uv-picker 将immediate-change默认值改为true,该值在于change回调的及时性,微信小程序生效 +4. 优化 uv-tags 兼容customStyle参数等优化 +5. 修复 uv-transition 部分情况,修改某属性自动关闭的BUG +6. 修复 uv-calendars 懒加载报错:https://gitee.com/climblee/uv-ui/issues/I869JS +7. 修复 uv-datetime-picker 设置minDate出现选择错乱的BUG +8. 修复 uv-input 搜狗输入法下存在不可清空的情况 +9. 修复 uv-calendars selected没有设置了info或者info设置为空字符串后,文本则无法恢复BUG +## 1.1.14(2023-09-27) +1. 优化 uv-list-item 可使用customStyle变量进行样式控制 +2. 优化 uv-cell 增加cellStyle参数,方便自定义单元格的样式 +3. 优化 uv-switch 优化细节 +4. 优化 不断优化[文档](https://www.uvui.cn/) +5. 修复 uv-button 通过customStyle修改按钮宽度,组件中最外层节点不改变的问题 +6. 修复 uv-calendars a. 修复range模式下,selected设置了info后选中后,导致文本不恢复的问题;b. 修复multiple模式下,selected自定义信息的颜色没变,依然是白色 +7. 修复 uv-checkbox uv-checkbox-group之change回调中v-model值不更新的BUG +## 1.1.13(2023-09-15) +1. 优化 uv-button a. 增加参数iconSize,用于控制图标的大小;b. 增加open-type="agreePrivacyAuthorization"类型,用户同意隐私协议事件回调 +2. 优化 uv-picker 三级联动的案例:[https://www.uvui.cn/components/picker.html#省市区三级联动](https://www.uvui.cn/components/picker.html#省市区三级联动) +3. 修复 uv-read-more 全局设置rpx时,导致展开高度不对的BUG +4. 修复 uv-tabs a. 设置lineWidth未带单位产生的误差BUG;b. 首次加载时,处理下划线会有左到右的过渡效果 +5. 修复 uv-textaera 设置autoHeight后出现高度异常的BUG +6. 修复 uv-input H5等情况设置禁用或可读情况下,点击事件无效的问题,nvue需要特殊处理 +7. 修复 uv-calendars a. 在vue2+小程序渲染时闪烁的问题;b. 增加allowSameDay参数,是否允许日期范围的起止时间为同一天,mode=range时有效 +8. 修复 uv-safe-bottom 兼容飞书小程序 +9. 修复 uv-album 添加依赖,避免导入运行有误 +10. 修复 uv-ui-tools 优化组件用到的相关 +## 1.1.12(2023-09-10) +1. 修复 uv-popup a. h5初始zIndex错误的问题;b. 修复全局设置prop无效的问题 +2. 修复 uv-button 修复多个按钮由view包裹,显示在一行宽度不正常的BUG +3. 修复 uv-modal a. 修复两个按钮之间竖线不显示的问题;b. uv-ui项目自定义按钮示例修复 +4. 修复 uv-calendars 修复国际化失效的BUG +5. 修复 uv-keyboard 修复键盘change回调事件产生冲突的BUG +## 1.1.11(2023-09-02) +1. 优化 uv-calendars a. 去除range参数,由mode="range"替换;b. 新增mode参数,不传 / multiple / range,分别为单日期, 多个日期,选择日期范围;c. 与uv-calendar选择日期的功能保持一致 +2. 优化 uv-modal a. 增加align参数,设置文本对齐方式;b. 增加textStyle参数,扩展文本样式 +3. 优化 uv-datetime-picker a. 增加mode="year"模式,方便只选择年;b. 增加clearDate参数,是否清除上次选择 +4. 修复 uv-ui-tools 设置customstyle同名计算属性报错:The computed property "customStyle" is already defined as a prop +5. 修复 uv-image a. 设置widthFix时出现显示不全的BUG;b. 修复抖音等平台在width和height属性改变时出现不显示的BUG +6. 修复 uv-checkbox 点击空隙处或label插槽内容不会选中的问题 +7. 修复 uv-radio 点击空隙处或label插槽内容不会选中的问题 +8. 修复 uv-calendars 在pages.json中设置easycom会报错的BUG +9. 修复 uv-index-list 设置customNavHeight导致定位不准确的BUG +## 1.1.10(2023-08-30) +1. 交流反馈 欢迎加入uv-ui官方群1交流反馈: 549833913 +2. 交流反馈 欢迎加入uv-ui官方群2交流反馈: 206060892 +3. 优化 uv-calendars 1. 去除range参数,由mode="range"替换;2. 新增mode参数,不传 / multiple / range,分别为单日期, 多个日期,选择日期范围;3. 与uv-calendar选择日期的功能保持一致 +4. 新增 uv-album 新增相册组件及相关文档 +5. 优化 其他优化 +6. 修复 uv-text app-nvue设置align不生效的BUG +7. 修复 uv-drop-down 自定义内容,点击自定义内容时会自动关闭弹窗的问题 +8. 修复 uv-image 异步修改宽高不生效的问题,问题来源:https://gitee.com/climblee/uv-ui/issues/I7WUQ3 +9. 修复 uv-calendars 通过setConfig修改属性不生效的问题,出自评论区:https://ext.dcloud.net.cn/plugin?id=12287 +10. 修复 uv-list 设置边框不生效的BUG +## 1.1.9(2023-08-27) +1. 优化 uv-calendars 1. 去除range参数,由mode="range"替换;2. 新增mode参数,不传 / multiple / range,分别为单日期, 多个日期,选择日期范围;3. 与uv-calendar选择日期的功能保持一致 +2. 优化 uv-picker 增加round属性,设置圆角 +3. 修复 uv-calendars 点击返回今天按钮时,monthSwitch方法回调参数返回月份不是当天对应月份 +4. 修复 uv-radio 1. 设置 labelSize 属性设置无效的问题:https://gitee.com/climblee/uv-ui/issues/I7W6UN;2. v-model 绑定布尔值控制台报警:https://gitee.com/climblee/uv-ui/issues/I7W714 +5. 修复 uv-checkbox 1. 设置 label 属性为布尔值不生效的BUG +## 1.1.8(2023-08-24) +1. 优化 uv-popup 弹出不丝滑优化思路:https://www.uvui.cn/components/popup.html#yh +2. 修复 uv-switch 取消value传值,只能使用v-model传值,避免异步操作不生效的BUG +3. 修复 uv-index-list ios端滚动过程中+快速点击右侧导航页面出现空白的BUG +4. 修复 uv-rate 1. 支付宝报错的BUG; 2. 不能选半星的BUG +5. 修复 uv-model 异步loading时,确认回调还会一直触发的BUG +6. 修复 uv-swiper 标题文字过多未隐藏掉的BUG +7. 修复 uv-text app-nvue编译不能自动换行的BUG +## 1.1.7(2023-08-22) +1. 优化 uv-drop-down a. 增加@change回调,返回弹窗关闭状态; b. 增加init方法,方便位置改变进行调整 +2. 优化 部分文档优化 +3. 修复 uv-input a. app-nvue-ios端不能输入的BUG;b. 键盘高度等值不返回BUG +4. 修复 uv-scroll-list 报错导致不能移动指示器的BUG +5. 修复 uv-search 边距值在上次更新中误改导致不对的BUG +6. 修复 uv-image 设置width和height为100%不生效的BUG +## 1.1.6(2023-08-18) +1. 优化 优化文档 +2. 修复 uv-list 使用列表右侧显示 switch,switchChange回调中返回数据为undefined的BUG +3. 修复 uv-checkbox 数据多不换行的BUG +4. 修复 uv-upload 1. 图片预览位置错误的BUG;2. 视频预览不生效的BUG;3. 改变上传视频宽高不生效的BUG +5. 修复 uv-navbar 在部分ios高版本机型,返回按钮不好操作的问题 +6. 修复 uv-waterfall 只有一条数据的时候,切换的时候数据会左右显示错误的BUG +## 1.1.5(2023-08-14) +1. 优化 uv-pick-color 删除scrollTop参数,内部修改后就不需要了 +2. 优化 uv-loading-icon 增加textStyle参数,可自定义文本样式,比如给上边距 +3. 修复 uv-safe-bottom 百度小程序报错的BUG +4. 修复 uv-form 设置labelWidth属性时,节点渲染有闪动的BUG +5. 修复 uv-grid 设置col属性时,节点渲染有闪动的BUG +6. 修复 uv-parse 阻止a标签跳转文档说明 +## 1.1.4(2023-08-13) +1. 优化 nvue自定义图标 [详细文档-nvue中自定义图标库](https://www.uvui.cn/guide/customIcon.html#nvue%E4%B8%AD%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9B%BE%E6%A0%87%E5%BA%93) +2. 优化 uv.$uv.http 在APP.vue页面使用报错的BUG: [Api集中管理](https://www.uvui.cn/js/http.html#_3-api%E9%9B%86%E4%B8%AD%E7%AE%A1%E7%90%86) +3. 修复 uv-navbar app-nvue运行ios存在背景图片错乱的问题 +4. 修复 uv-list app-nvue运行ios存在,分包页面不滚动 +5. 修复 uv-textarea 值为null或undefined时显示错误的bug +6. 修复 uv-search 值为null或undefined时显示错误的bug +7. 修复 uv-scroll-list vue2编译报错的BUG +8. 修复 uv-calendars 选择月份弹窗层级的问题 +9. 修复 uv-form 动画在vue3 setup语法糖中错乱,以及表单其他相关问题解决: [Issues](https://gitee.com/my_dear_li_pan/uv-ui/issues/I7SNTT) +10. 修复 uv-picker-color 滚动页面无法点击的BUG:增加scrollTop参数,设置滚动条的位置。不设置如果页面出现滚动就需要传该值,会出现颜色面板无法进行选颜色的情况。 +11. 交流反馈 欢迎加入uv-ui官方群1交流反馈: [549833913](https://www.uvui.cn/components/addQQGroup.html) +12. 交流反馈 欢迎加入uv-ui官方群2交流反馈: [206060892](https://www.uvui.cn/components/addQQGroup.html) +## 1.1.3(2023-08-06) +1. 优化 uv-calendars 1. 增加startText参数; 2. 增加endText参数; 3. 增加selected中的参数; 4. 优化日历范围选择 +2. 优化 uv-empty icon属性支持base64图片 +3. 优化 uv-navbar 增加背景图片的裁剪模式参数imgMode +4. 优化 uv-picker-color 颜色值不对的BUG +5. 优化 [API文档优化](https://www.uvui.cn/components/changelog.html) +6. 优化 常见问题增加:[怎么隐藏uv-tabs等组件的滚动条](https://www.uvui.cn/components/problem.html#%E4%B9%9D%E3%80%81%E6%80%8E%E4%B9%88%E9%9A%90%E8%97%8Fuv-tabs%E7%AD%89%E7%BB%84%E4%BB%B6%E7%9A%84%E6%BB%9A%E5%8A%A8%E6%9D%A1) +7. 修复 uv-radio name为数字0时不能选中的BUG +8. 修复 uv-textarea 1. v-model设置为数据时的BUG;2. 复制过多内容,计数显示错误的BUG;3. maxlength为-1改成不显示计数 +9. 修复 uv-code-input 在vue2模式下,v-model设置为0时不生效的BUG +10. 修复 uv-input 在vue2模式下,v-model设置为0时不生效的BUG +11. 修复 uv-search 在vue2模式下,v-model设置为0时不生效的BUG +12. 修复 uv-ui-tools 1. 路由拦截修复;2. 增加events参数 +## 1.1.2(2023-08-03) +1. 新增 uv-calendars 新版日历发布 +2. 新增 uv-toolbar 组件独立发布,老用户更新uv-picker,需要手动删除uv-picker目录下的uv-toolbar目录,否则会有冲突提示 +3. 优化 uv-tags 增加cellChild参数 +4. 优化 uv-navbar 兼容背景图片 +5. 优化 uv-notice-bar 竖向滚动时候增加change回调 +## 1.1.1(2023-07-30) +1. 新增 uv-drop-down 下拉筛选组件,兼容app-nvue及多端 +2. 优化 uv-textarea 增加confirm-hold参数,方便设置进行换行处理 +3. 优化 其他关于文档的优化等 +## 1.1.0(2023-07-26) +1. 重构 uv-list 全面重构,提高性能,放弃使用scroll-view,具体文档参考:uv-list列表 +2. 优化 uv-search 1. 增加prefix和suffix 前置和后置插槽;2. 增加boxStyle参数,方便控制输入框部分的样式 +3. 优化 文档优化:获取节点布局信息,文档新增nvue获取方式的说明 +## 1.0.22(2023-07-26) +1. 优化 uv-textarea 组件 增加textStyle和countStyle属性,方便控制文本样式 +2. 优化 uv-swiper 增加竖向播放属性:vertical +3. 优化 uv-icon 支持base64图片格式 +4. 优化 uv-transition 和 uv-image 增加参数cellChild属性,避免nvue中出现回收后不显示的BUG +5. 优化 uv-button 增加customTextStyle属性,方便自定义按钮文字样式 +6. 优化 优化部分文档说明 +7. 修复 uv-slider 修改背景颜色属性为backgroundColor,避免设置不生效 +8. 修复 uv-index-list 1. 修复全局设置成rpx存在的高度BUG;2. 修复其他BUG +## 1.0.21(2023-07-22) +1. 新增 uv-scroll-list 横向滚动列表组件 +2. 优化 增加测试占位图,方便开发者使用线上图片进行测试:[https://www.uvui.cn/components/testPic.html](https://www.uvui.cn/components/testPic.html) +3. 优化 uv-calendar 组件文档示例等优化,增加setFormatter说明 +4. 优化 uv-notice-bar 优化文档,说明不显示左边图标的使用方法 +5. 修复 uv-input 在微信小程序端清除内容存在不能清除的BUG +6. 修复 uv-button 1. 解决微信小程序动态设置hover-class点击态不消失的BUG; 2. 文档优化 +7. 修复 uv-waterfall 在tab切换等场景快速切换时,会出现报错的BUG +8. 优化 优化其他 +## 1.0.20(2023-07-18) +1. 修复 uv-textarea 设置-1不生效 +2. 修复 uv-icon 恢复uv-empty相关的图标 +3. 修复 uv-empty 恢复设置mode属性的内置图标 +4. 优化 [优化文档](https://www.uvui.cn) +## 1.0.19(2023-07-14) +1. 优化 uv-waterfall 当changeList未处理数据时,正确返回对应列的数据,避免误导 +2. 修复 uv-rate VUE3模式下设置value属性不生效的BUG +3. 修复 uv-input VUE3模式下设置value属性不生效的BUG +4. 修复 uv-search VUE3模式下设置value属性不生效的BUG +5. 修复 uv-code-input VUE3模式下设置value属性不生效的BUG +6. 修复 uv-number-box VUE3模式下设置value属性不生效的BUG +7. 修复 uv-radio VUE3模式下设置value属性不生效的BUG +8. 修复 uv-checkbox VUE3模式下设置value属性不生效的BUG +9. 修复 uv-textarea VUE3模式下设置value属性不生效的BUG +10. 修复 uv-switch VUE3模式下设置value属性不生效的BUG +11. 修复 uv-slider VUE3模式下设置value属性不生效的BUG +12. 修复 uv-datetime-picker VUE3模式下设置value属性不生效的BUG +13. 修复 uv-icon 部分图标错误的BUG +## 1.0.18(2023-07-06) +1. 优化 uv-icon 1. 更新图标,删除一些不常用的图标;2. 删除base64,修改成ttf文件引入读取图标。uv-icon 图标 +2. 优化 uv-icon nvue自定义图标用法,文档说明:[点击跳转](https://www.uvui.cn/guide/customIcon.html) +3. 优化 uv-upload 文档示例代码,增加fileList参数说明:[点击跳转](https://www.uvui.cn/components/upload.html#filelist-options) +4. 修复 uv-checkbox vue3模式下,动态修改v-model绑定的值无效的BUG +5. 修复 uv-radio vue3模式下,动态修改v-model绑定的值无效的BUG +6. 修复 uv-datetime-picker vue3模式下,动态修改v-model绑定的值无效的BUG +## 1.0.17(2023-07-04) +1. 优化 uv-icon 修复,NVUE平台主题颜色在APP不生效的BUG +2. 优化 uv-notice-bar 优化,增加disableScroll属性 +3. 优化 uv-input uv-back-top uv-cell uv-form uv-search uv-modal uv-navbar uv-index-list uv-empty uv-upload 去除插槽判断,避免某些平台不显示的BUG +4. 优化 uv-form 优化文档 +5. 优化 优化其他相关文档 +## 1.0.16(2023-07-03) +1. 优化 uv-transition 动画组件,代码重构优化,性能更加友好,增加自定义动画功能。详情[参考文档](https://www.uvui.cn/components/transition.html) +2. 优化 uv-popup 弹出层,代码重构优化,性能翻倍,小程序体验性能更加,避免卡顿。打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/popup.html) +3. 优化 uv-calendar 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/actionSheet.html) +4. 优化 uv-action-sheet 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/calendar.html) +5. 优化 uv-datetime-picker 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/datetimePicker.html) +6. 优化 uv-form 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +7. 优化 uv-keyboard 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/keyboard.html) +8. 优化 uv-modal 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/modal.html) +9. 优化 uv-notify 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/notify.html) +10. 优化 uv-overlay 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +11. 优化 uv-pick-color 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/pickColor.html) +12. 优化 uv-picker 由于弹出层uv-popup的修改,打开和关闭方法更改,详情[参考文档](https://www.uvui.cn/components/picker.html) +13. 优化 uv-tooltip 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +14. 优化 uv-loading-page 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +15. 优化 相关文档的优化更改。 +16. 修复 uv-safe-bottom 修复,在百度程序,抖音小程序不生效的BUG +## 1.0.15(2023-06-29) +1. 欢迎加QQ群交流:[549833913](https://www.uvui.cn/components/addQQGroup.html) +2. 优化 uv-swiper 优化:1. 增加titleStyle属性,方便修改标题样式;2. 标题上去掉是否是图片的判断,避免无后缀的图片不显示 +3. 优化 uv-steps 优化:1. 增加插槽title; 3. 文档关于插槽相关的参数说明完善;增加customStyle属性 +4. 优化 uv-checkbox 优化:增加label文字插槽,与radio保持一致,优化文档相关说明 +5. 优化 uv-modal 优化:增加closeLoading方法,方便异步加载手动取消加载状态,更新文档 +6. 优化 uv-image 增加文档说明:uv-list、 uv-waterfall等组件在 Android平台使用了list封装,所以在该组件中仍然不能使用uv-image等组件 +7. 优化 优化更多文档 +8. 修复 uv-vtabs 修复非联动情况下,内容过多的情况,滚动一段距离,再切换未滚动到顶部的BUG +9. 修复 uv-image 修复:duration属性不生效的BUG +10. 修复 uv-code-input 修复:使用:disabledKeyboard="true"属性,事件全部失效的BUG +11. 修复 uv-button 修复:设置open-type="chooseAvatar"等值不生效的BUG +## 1.0.14(2023-06-25) +1. 欢迎加QQ群交流:[549833913](https://www.uvui.cn/components/addQQGroup.html) +2. 优化 uv-count-down 增加外部样式customStyle参数 +3. 优化 文档的全面优化 +4. 修复 uv-count-to 1. 修复继续滚动的函数 2. 修改文档错误 4. 适配px和rpx的单位 4. 适配customStyle参数 +5. 修复 uv-load-more 修复customStyle参数设置背景等不生效的BUG +6. 修复 uv-code-input 优化下边框 +7. 修复 uv-tabs 添加uv-icon依赖 +8. 修复 uv-grid 优化修改 +9. 修复 uv-cell 优化修改 +## 1.0.13(2023-06-20) +1. 优化 uv-calendar formatter格式化中增加topInfo参数 +2. 优化 uv-tabs 增加customStyle参数 +3. 优化 文档优化,便于开发者直接开干 +4. 优化 uv-switch 优化size属性,适配单位传递 +5. 修复 uv-ui-tools、uv-form、uv-picker 修复vue3编译支付宝异常 +6. 修复 uv-ui-tools、uv-form、uv-picker 修复vue3编译支付宝异常 +7. 修复 uv-parse 修复在nvue不显示的BUG +8. 修复 uv-form 修复某些条件下报错的BUG +## 1.0.12(2023-06-14) +1. 优化部分组件,优化文档部分细节 +2. uv-popup、uv-modal 修复遮罩层zIndex问题 +3. uv-form 在vue3的setup语法中ref使用uvForm会导致报错 +4. uv-tabs activeStyle设置字体大小,可能会导致下划线位置不对BUG +5. uv-pick-color 百度小程序点击报错 +6. uv-transition 恢复this.$nextTick +7. uv-picker 抖音小程序选择的时候报错,导致不能关闭的BUG +8. uv-checkbox 多余的属性labelDisabled,导致APP中报错提示 +9. uv-tabbar 底部安全距离组件无效的BUG +10. uv-vtabs 头部存在的时候,联动不准确的BUG +## 1.0.11(2023-06-12) +1. uv-radio-group、uv-checkbox-group 兼容自定义样式customStyle,方便通过样式调整整体位置等,数据较多时允许换行 +2. uv-ui-tools 优化内置样式等,解决微信小程序使用uvui提示 Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors,[详情](https://www.uvui.cn/components/problem.html) +3. uv-datetime-picker 取消defaultIndex参数,目前传该值也没实际意义 +4. uv-tabbar 增加iconSize参数 +5. uv-calendar 增加change回调 +6. uv-calendar 修复BUG +7. uv-rate 修复只读或禁止状态下设置value无效的问题 +8. uv-popup 修复zIndex问题 +9. uv-modal 修复zIndex问题 +10. 文档-扩展配置更新:[扩展配置](https://www.uvui.cn/components/setting.html) +11. 文档-优化更新:[uv-ui文档](https://www.uvui.cn/components/changelog.html) +12. 文档-新增常见问题:[常见问题](https://www.uvui.cn/components/problem.html) +13. 优化其他 +## 1.0.10(2023-06-05) +1. uv-navbar 渐变背景色兼容 +2. uv-calendar 日历选择BUG修复 +## 1.0.9(2023-06-05) +1. 新增uv-vtabs垂直选项卡组件,主要用于分类展示,分类切换功能,支持联动和不联动两种模式 +2. uv-qrcode,uv-datetime-picker,uv-subsection等文档说明优化,避免开发困难;优化API相关说明 +3. uv-notice-bar 1. 修复在触发error函数报错的BUG;2. 修复在text值为undefined的时候,解决报错BUG +4. uv-button 等组件修复触发两次事件的BUG +5. uv-datetime-picker 1. 修复重置值存在不更新的BUG;2. 优化文档,增加filter使用方法说明 +6. uv-badge 修复type等属性为null或undefined的时候不显示徽标的BUG +7. uv-ui-tools 优化工具组件,兼容更多功能,小程序分享功能优化等 +... +## 1.0.8(2023-05-27) +1. uv-waterfall修复在百度小程序中可能存在的BUG;去掉原有的slot方式 +2. uv-image修复可能报错的问题 +3. uv-pick-color 在文档预览模式中无法点击的问题 +4. uv-index-list 修复select事件不触发的问题 +5. 优化其他组件及示例项目等 +## 1.0.7(2023-05-25) +1. uv-icon 将线上ttf字体包替换成base64,避免加载时或者网络差时候显示白色方块 +2. uv-text 去掉多余的data-index属性,避免警告 +3. uv-upload 在fileList的watch中增加deep属性 +4. uv-pick-color 去掉template中存在的this.导致头条小程序编译警告 +5. uv-image 去掉template中存在的this.导致头条小程序编译警告 +## 1.0.6(2023-05-23) +1. 新增uv-pick-color颜色选择器组件 +2. uv-toolbar组件增加showBorder属性,是否显示下边框 +3. uv-transition组件在百度小程序等平台不支持this.$nextick导致下面的逻辑不执行,使用延时替换方案 +4. uv-ui-tools组件中bem()函数兼容百度/头条小程序等 +5. uv-waterfall组件修复在百度/头条小程序显示异常等BUG,增加changeList回调函数处理数据,同步更新示例等 +6. uv-image组件修复在百度/头条小程序等开启observeLazyLoad后显示异常BUG +7. uv-tabs组件修复上次更新导致的在nvue中不滚动的BUG +8. uv-qrcode组件修复在部分平台不显示加载的BUG +9. 修复其他已知问题等 +## 1.0.5(2023-05-17) +1. 新增uv-qrcode二维码组件 +2. 修复uv-tooltip在vue2模式下的BUG +3. 优化部分问题 +## 1.0.4(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.3(2023-05-12) +1. 修复uv-input在vue3模式下双向绑定问题 +2. 修复uv-textarea在vue3模式下双向绑定问题 +3. 修复uv-rate在vue3模式下双向绑定问题 +## 1.0.2(2023-05-11) +1. 更新文档 +2. 增加插件下载入口 +## 1.0.1(2023-05-10) +1. 所有组件依赖 +2. 上传示例项目 +## 1.0.0(2023-05-10) +1. uv-ui diff --git a/uni_modules/uv-ui/components/uv-ui/uv-ui.vue b/uni_modules/uv-ui/components/uv-ui/uv-ui.vue new file mode 100644 index 0000000..e023095 --- /dev/null +++ b/uni_modules/uv-ui/components/uv-ui/uv-ui.vue @@ -0,0 +1,7 @@ + + + diff --git a/uni_modules/uv-ui/package.json b/uni_modules/uv-ui/package.json new file mode 100644 index 0000000..5e919a2 --- /dev/null +++ b/uni_modules/uv-ui/package.json @@ -0,0 +1,162 @@ +{ + "id": "uv-ui", + "displayName": "uv-ui 破釜沉舟之兼容vue3+2、app、h5、小程序等多端,灵活导入,利剑出击", + "version": "1.1.20", + "description": "uv-ui 是基于uni-app、部分组件基于uView2.x、全端兼容、支持独立导入、内容丰富的UI框架。破釜沉舟之兼容vue3+2、app、h5、小程序等多端,利剑出击,开箱即用。", + "keywords": [ + "uv-ui", + "uvui", + "UI组件库", + "ui框架", + "ui库" + ], + "repository": "https://github.com/climblee/uv-ui", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@climblee/uv-ui" + }, + "uni_modules": { + "dependencies": [ + "uv-skeletons", + "uv-album", + "uv-drop-down", + "uv-calendars", + "uv-scroll-list", + "uv-vtabs", + "uv-pick-color", + "uv-qrcode", + "uv-ui-tools", + "uv-action-sheet", + "uv-alert", + "uv-avatar", + "uv-back-top", + "uv-badge", + "uv-button", + "uv-calendar", + "uv-cell", + "uv-checkbox", + "uv-code", + "uv-code-input", + "uv-collapse", + "uv-count-down", + "uv-count-to", + "uv-datetime-picker", + "uv-divider", + "uv-empty", + "uv-form", + "uv-gap", + "uv-grid", + "uv-icon", + "uv-image", + "uv-index-list", + "uv-input", + "uv-keyboard", + "uv-line", + "uv-line-progress", + "uv-link", + "uv-list", + "uv-loading-icon", + "uv-loading-page", + "uv-load-more", + "uv-modal", + "uv-navbar", + "uv-no-network", + "uv-notice-bar", + "uv-notify", + "uv-number-box", + "uv-overlay", + "uv-parse", + "uv-picker", + "uv-popup", + "uv-radio", + "uv-rate", + "uv-read-more", + "uv-row", + "uv-safe-bottom", + "uv-search", + "uv-skeleton", + "uv-slider", + "uv-status-bar", + "uv-steps", + "uv-sticky", + "uv-subsection", + "uv-swipe-action", + "uv-swiper", + "uv-switch", + "uv-tabbar", + "uv-tabs", + "uv-tags", + "uv-text", + "uv-textarea", + "uv-toast", + "uv-tooltip", + "uv-transition", + "uv-upload", + "uv-waterfall" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-ui/readme.md b/uni_modules/uv-ui/readme.md new file mode 100644 index 0000000..9dfe1df --- /dev/null +++ b/uni_modules/uv-ui/readme.md @@ -0,0 +1,164 @@ +

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 literal 0 HcmV?d00001 diff --git a/static/personal/id01.png b/static/personal/id01.png new file mode 100644 index 0000000000000000000000000000000000000000..bab191bf45175d4a7eeb669a8dba0c51fc66f34a GIT binary patch literal 2822 zcmdT``8$+t8-8Yb$`i#HTS=CrBwI0Mc`+U`7$n;(Ly1BuvgI}6oneF$*+bIQP_i3Q zV{MU&n#nSHku93ZWXU!!WBI1E7n3+)``&zf z(14#j`)zG@cXU%QE!J1BkGg`ogw-UvL|n8K110Wb2~4_wYh2jOan6t!js$>y`{o+L zW+G>Qed{*lCx*=gm3TP1LD|uF`Y`}fOcKjYkk5RI1*ku^pxl!HSf}@{%T^?0uS9Btg-5AxX&NYOz$yUB?jy0p zFb7=80Nf*@TrGq<^W;dWD2U281;`1I@*;fO##NcbT0}samH<`mlHF6JkW%7*DD89> z)0E7H__HI0XS-=A13mIZ%Et0^fnaTgE|?pOj}|OfL@#{5-PqW8D|Yeg>(}vue}6p^ z%ujYcn)44jKNYKpv=GxuRx1YUCqCZJ9W64AAu7CQ_B8b_UIuSSuk!kM>$2+?SP;}u^9=ERh< z?l<&O8(H$%cxHM;Z23tW|DG=I<%_~1!$J5S$7NBf-;OgfcvhHtaT{t&9Ho_e=E+!!k?Bh z35rV^seQ}2On7)2-7$_|ZtrbuqNiI#BR?iMc=c&Z{&aGm%rpw143<=v%#S6cN*lK9 zA!Ea+&T%w=*6k(wbXr>f3e!H*=nl<6B783iAg6EFmoZYq*=oc@9=h^#)@4U_3cUus}gn6|Xr3ux9Xza{hp?6vcG zIWYXxLQ`T~`RabMA57pd-6k~+pT*q%Jc!>j$Q(Ysh4b0%FnXi_D@Bb+-7SR+ajULx zunGzkxHMtLJtk|#_pg2p7EZUHWf@>{>O!(iymzwiWcr>Wv_aSFw9#`bucp_C&-e0B zyU0QaE%S=fD>Lfl(^-*~PX>-152h$mjh${dA)Q61aW<`4qc!o?cxqH-V;wKOWh=Rq zvW!f`o6RTwie_UnI^wcL_z!*Sl6dwHl3DDNJEMNRvgJ73(t2^}&1_+)YWSC%LP(9oTVSJV2Ea>u`khu)*gvJ2pSJ{fq)IFt2ggY^=cf2M9x{tYd6P*?~I zr)#I2?irNbyT3~>^=+O+N6Kobm3x&dyJA^oBVQ z%_Q#k8{ZTo;>$bJYrz|GPMs!#CcDS2EBsou3haO?q%Y@@U2S#ICL^DCxFVM!Y@u6z zKc#fw&=@?h1S#wbpYk-qO{rE3wj}17d8QJ}rl4a#eHD?3kd^{lCODZMVfs~`!=64` zdAT77F<*6JRF{f*^}{y8V16aSrWvzd>H4Gddi{C7r!h9ST5$)j-enwBjhjpRg)b?;Gqli77o!Ru>C($eKZG5kMD_Z$v5|A?RB#YMsGPYl_=~LZU;`MJ9 z5EpJvL?zs9{_aH?X7C3srmhw>xniRGP5oCIp+e$0Rq3*JhShnq=K6WgiIgzWBheMY zyfK{Ud=B3t`zwV-kDLz6X}!gQoBw>(9C|jjExISPSa9!Xxg#$K?q__Mme`St6g(&7 zdQP691{Tr9zfxKzO&2TTW^6jR*BvC?N+XU_w^sApYwmLYP^-5UGMg|&wI*ILBRVF^ z_I4}`ap#Kw>mGJEm)sD zL>Z22no4SPot+a@q;~Q{#w=3xs&rHqyLLL#fBv@-|M3{NP!8q?k#7n{rk-C{l56pi z3TKK^8;>KllCUO7$SY0F(ENchf-*A zw+XK^9s{+LvD*<8Z7R+K+F=DyMFLSbw~*07IpDN9)UFf&mS8JOiy+m6Do_+Js_5=Q zP!!9})x|+u$eNp&vBO#n0qw9DHHTXjN(`hyq;QBiC)iBqJ-JTk?R3HWX3keXHOrS+ z|E@hxXlqS7x`|$u;0%4$dU0nPQYhW%upyt5$!eu-d^F@gjQ*?+fXda0Z6lvvj5K#` ZB6`<)LK<3S#e~KdusPviSqXc`{Rce&Dct}7 literal 0 HcmV?d00001 diff --git a/static/personal/id02.png b/static/personal/id02.png new file mode 100644 index 0000000000000000000000000000000000000000..c39c58f43e513f297e9f6c2b1a365c7289bb71b6 GIT binary patch literal 2070 zcmcgt`&$#&7M+Zv3?Mo|485qB1QAdI77#%}W5P3O!CJAr6fBseASj9=AehjAC?FVl zS_Fm?y;h=N5*37qN`aa*8F?zA_#xDw^18-G3}UCf|HA$559jP3_S)aK&OUpseR@Zb zznO`Z2><|QfdM`{@uz+b&cpx0v>CXVJsaK8zfDsnxvwhcb!o)>o(#s8t z={?LimhCua1#8<6ZAPmPcL}yk=b*dib6t$h`BfaR?+;{Ct*3oh>bHuPxdRU3f#UA! z_C*BvIF+nca0;Cb#oZCC@lgkp4if@AXO5%{XNrRyGUhXV7J$ffzzbK6ddk{gQ%(T{ z>%l2!2XW!mTdDs|F@;;xS9-?e0MIqK(wFBB)5$PFxI`3ipU+3=yw?CIfXT@0sECxh@R`wAgQ5MEkDMsfj$5o;|<2hb}77^3nqfhf=(FN^zslwpp#@nlxZ{Fm@9 zOW{Z{z({E!drAm7t8i8}$u)-)O~(v|Et04N@3Ws1gnrtY5bkI`b!zs6qUC1din|Jh zsHOfOT!8h*%M2fUR5ZcrjKr`>4tl5O5)-y3@|LI4nsj#37O@#h+y7(ZzmYEX8+lP{ zCaFG|b3doNpmA1e6q#E1A(A0aWC5&j=*b<(E97jcUOp^XJWhtDdW{Ak(~k8cN&ZJ-1z% zmLyrFd4rSN(qAh{qz6?@9G$|^-p?wH0V9Gha5E?4a;l73?}pCC8;Y1^M!^@}W8Jsv z$$kmHyC$=1N>8Tj0zHCPgQaE9GN|=$7NS#gOvBL+9uG|jR~dzoiEJmt3YB;~@mi9n zOcW|?9&5)^j~sn;?-1C}8GqzrI{nAL(vJ6gP#|lh!HsRB`_X5H2*tsn6=H6eq0A;zl6H08Q|{W+Ml>&V`tple-~yjQ(}xcPkaYEfIj z6|U0J*hgEm|EnEra8TcS_)&S2YH!CGjBO=*V2+8xV{ghRGVy^8q@!SK`%Sm?&L~AE zS~T$hK^pbXqm(ndebuL#+OM)c?K93Dnk^CkZkSV)q>oD0P;?~9)>C{N5T39PTf7{M zfRMC2r238>SvfZMkgeTo7`nbZ;GfC*d4<5SV#w(F=Zm&?% zU4u-fu$}x_Kgy_+Q)HyDk0F#7NxK!cw<3$&+=cx$tm<`;m*(NEx>9|b^F3m?Sf`b3 z66CsYe@kaQb4<3jFq|K^lSIsp)1o!=RAuG6Zg!l|{XbLuSMBOSy+s2z%D>3-Rm-Vf zTu@~tzQM-n@0X7eLP<9{!|OIOY-E9Gp}iD#UN0&&Ly3cR*hXnsZ%nx2vL8?AZm0W( z`)X|A>nGwADMnK+$g~9G!LGTfry_3IbGY@IeP$I4K$Qd48dW#!EkEHoD*{|BE2=Z- zIhgWHt#=8)`0OkTXiX{g(_XPv{ZAzs+$RNCoGq&}9quLRiG}C;*b_OJyv`%208maClnG7ziP@mPrB!@3-k7Y5 zL498jnxXN5NtITF$!cP_7eV-()cohYFI;sWK91$D2k{PE6}|A+;NKge9h`Gv z4v0oPHiBLjOrCtC_T>yTIzOE|>^#t+(qk{;Tr zY1b2_YWa*jzfoR*!MGXpf4}Yil#LtiqU4^RvX``H?I6FX0vLCKDFk{ALdO+Of`*pS zd3uL60BixmdqS}+emXwaTeBfRz`$+5G#oh;44}_07XjoQ_yXCt-4vWOCd&*K<^W_u z_}fypw|NtU$Eq11pHAUp*$Zj#Z96_T`E3Az*h5HjL(M{h9zq5)OpF0A8(`pG^S>dH zi*fbeAOJ)rLu#td$dL>P5NNB9R*#?v1d*rbsrW8kMnd@fc(B^C;-oN>?Qk*j)Pon4 zLy_Rfi=o{p7jS-#o7Y*K) AU;qFB literal 0 HcmV?d00001 diff --git a/static/personal/id03.png b/static/personal/id03.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4ab87488edfecb35a15d68a58947a8ff64ca10 GIT binary patch literal 1232 zcmV;>1TXuEP)Px(ib+I4RCodHodI&JAPk0kv>vTD>ybP{-((9umkLQpz@UF;9Cg(t$(KJMy3>yj z{2>B}03z_r2yEN-nU=3@+px4_@Hsq75{&O{+kUX9WAHTuP*Mhf*pkv04xp&j(Mn*y z(uT6-3g+9Tq@{kPl>s=WFK>3$pp3byB_}b!1TDk%K>!ppL@@vZ#ppZ0TyLMahGL)? zC`O}vC*zDl9+Pf7P zvonEaG0eVv1aQXgL?NwP_;jHYuaZ^7)NS|T#~Joyy9kWW!z2O5G+1c$2P2Lx38u^F z6yV-#XAcg#?0n0!$%^SxN?~J{)036cW#eUF-WpcyltW>~rEjNBgtHWwuE(u~T5^BT z<@m$_L6?1H7R{)?-G-KG$@_0kD0V8KGjOkUx4*k9GYs7uQ*JP}bt#Zc$Z!X)mjKgk zBonx4TANp7cwnN&=V@I)j5!CQvndPau}p z_U>2PJPF77M+39B*}n{~@j0MZ*|07cN|V8GnotI}9~z9vxIu7OC{G3>3eJE4Y1$oi zqbW*C^1b?ZRUcCtRh zWv~X!SwOu$iw{OBYXKOVG3Ej%QmCLUt{v|95@5&)Hj|msvR}^xRSJd+to8UZVAz0F z)KGP>28bJx)vl|w-wUW}H)r2|e3GH8Y6`_r+1gdI8+)=**xyV5rvZip)>2^Dfj|nJ z2*{C<^g3r%v;eIIhE#D3=*;axk*%P599s?yIc+yuNwg?;9)ah+!|vk+Mw3%hl#@!F zWSGqbT6=t1FxgRceihiW!!!5y_IZS~+E@$UN`s^`aA_ZMy3&2dgo0kB|=Ku`A z@XtbWwqWgX3lMNrb_cL1WhiARWf~0q5gz7O$4N=PMMjYO9iLmJa#~u@_5fK78!UkjC zbvc+RZ&Z#5JolZ(H*YQn!@j}K1t9A2)fGb{6?=9Bqhl@aE-`U1;x=#`-{!O@s}mT_ z82<_90*tXQ7?mUd12CA9(WncGfnuN-C?=>1rh}o`U`?YqmyefA9|JIaptZ@!{u)j+ z*_ZXd8oCEH%cj?geQOiLdk#tryI`e(Rz;Ku=QbzGle#0;j_+mr=5kLfDN8lfH&uuaJguX8T0000Px$J4r-AR9Fe^RzVJgAPnSbKFuHT1fRyHgfVp~IIVbd6H;ZNGo7|bO5e|+K*?z< zIqfBl7V;mZ*#chmNsAk0U%>{&iiCl5LlColW5@D*^_5qS{8$YI8VZvYXC6z zo(~vcDFllfWg4RRjPx$K}keGR9Fe^R8b1TFbv(b6hFL*!-EXEdwDeF5waw0+I7${gbAhHO!Hn|UN%kF zFIa*5oR-HsJ+XqJY5tr84qceJQG;nBd;34pL~U{N8|14N*1!ch5jyZlxJ lnooo4Gmmn(>>Bj1&Oh^giNUp1(?0+J002ovPDHLkV1lPytmgm# literal 0 HcmV?d00001 diff --git a/static/personal/userimg.png b/static/personal/userimg.png new file mode 100644 index 0000000000000000000000000000000000000000..a107a8a4c0fe03d9c71be88a1afe5d77c7a324bb GIT binary patch literal 100218 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