From 18880a1dc64c16958f1b476c995240ff8101dd7d Mon Sep 17 00:00:00 2001 From: xpz2018 <107107461@qq.com> Date: Fri, 8 Jan 2021 17:00:24 +0800 Subject: [PATCH] no message --- app.js | 15 + app.json | 21 + app.wxss | 59 + assets/image/bg-logo.png | Bin 0 -> 37306 bytes assets/image/icon-finace.png | Bin 0 -> 525 bytes assets/image/icon-payment.png | Bin 0 -> 743 bytes assets/image/icon_code.png | Bin 0 -> 463 bytes assets/image/icon_delete.svg | 1 + assets/image/icon_logo.png | Bin 0 -> 2696 bytes assets/image/icon_pdf.svg | 1 + assets/image/icon_phone.png | Bin 0 -> 364 bytes assets/image/icon_pwd.png | Bin 0 -> 390 bytes assets/image/list_empty.png | Bin 0 -> 5822 bytes assets/image/tabbar/home-blue.png | Bin 0 -> 1070 bytes assets/image/tabbar/home-gray.png | Bin 0 -> 1753 bytes assets/image/tabbar/mall-blue.png | Bin 0 -> 1264 bytes assets/image/tabbar/mall-gray.png | Bin 0 -> 1958 bytes assets/image/tabbar/process-blue.png | Bin 0 -> 1268 bytes assets/image/tabbar/process-gray.png | Bin 0 -> 2116 bytes assets/image/ygImg.png | Bin 0 -> 1181 bytes assets/raw/ding.mp3 | Bin 0 -> 1668 bytes colorui/components/cu-custom.js | 100 + colorui/components/cu-custom.json | 4 + colorui/components/cu-custom.wxml | 16 + colorui/components/cu-custom.wxss | 5 + colorui/icon.wxss | 1226 ++++++ colorui/main.wxss | 1546 +++++++ components/action-sheet/index.js | 62 + components/action-sheet/index.json | 8 + components/action-sheet/index.wxml | 67 + components/action-sheet/index.wxss | 1 + components/area/index.js | 210 + components/area/index.json | 6 + components/area/index.wxml | 18 + components/area/index.wxss | 1 + components/button/index.js | 69 + components/button/index.json | 7 + components/button/index.wxml | 44 + components/button/index.wxss | 1 + components/cell-group/index.js | 10 + components/cell-group/index.json | 3 + components/cell-group/index.wxml | 9 + components/cell-group/index.wxss | 1 + components/cell/index.js | 35 + components/cell/index.json | 6 + components/cell/index.wxml | 30 + components/cell/index.wxss | 1 + components/checkbox-group/index.js | 35 + components/checkbox-group/index.json | 3 + components/checkbox-group/index.wxml | 1 + components/checkbox-group/index.wxss | 1 + components/checkbox/index.js | 76 + components/checkbox/index.json | 6 + components/checkbox/index.wxml | 20 + components/checkbox/index.wxs | 20 + components/checkbox/index.wxss | 1 + components/col/index.js | 24 + components/col/index.json | 3 + components/col/index.wxml | 8 + components/col/index.wxss | 1 + components/collapse-item/index.js | 95 + components/collapse-item/index.json | 6 + components/collapse-item/index.wxml | 44 + components/collapse-item/index.wxss | 1 + components/collapse/index.js | 47 + components/collapse/index.json | 3 + components/collapse/index.wxml | 3 + components/collapse/index.wxss | 1 + components/common/classNames.js | 1 + components/common/color.js | 7 + components/common/component.js | 101 + components/common/index.wxss | 1 + components/common/style/clearfix.wxss | 1 + components/common/style/ellipsis.wxss | 1 + components/common/style/hairline.wxss | 1 + components/common/style/mixins/clearfix.wxss | 0 components/common/style/mixins/ellipsis.wxss | 0 components/common/style/mixins/hairline.wxss | 0 components/common/style/theme.wxss | 0 components/common/style/var.wxss | 0 components/common/utils.js | 32 + components/common/version.js | 31 + components/count-down/index.js | 98 + components/count-down/index.json | 3 + components/count-down/index.wxml | 4 + components/count-down/index.wxss | 1 + components/count-down/utils.js | 57 + components/datetime-picker/index.js | 297 ++ components/datetime-picker/index.json | 6 + components/datetime-picker/index.wxml | 16 + components/datetime-picker/index.wxss | 1 + components/dialog/dialog.js | 68 + components/dialog/index.js | 116 + components/dialog/index.json | 7 + components/dialog/index.wxml | 65 + components/dialog/index.wxss | 1 + components/divider/index.js | 33 + components/divider/index.json | 4 + components/divider/index.wxml | 5 + components/divider/index.wxss | 1 + components/empty/index.js | 20 + components/empty/index.json | 4 + components/empty/index.wxml | 15 + components/empty/index.wxss | 1 + components/field/index.js | 90 + components/field/index.json | 7 + components/field/index.wxml | 49 + components/field/index.wxs | 21 + components/field/index.wxss | 1 + components/field/props.js | 63 + components/goods-action-button/index.js | 41 + components/goods-action-button/index.json | 6 + components/goods-action-button/index.wxml | 30 + components/goods-action-button/index.wxss | 1 + components/goods-action-icon/index.js | 22 + components/goods-action-icon/index.json | 7 + components/goods-action-icon/index.wxml | 38 + components/goods-action-icon/index.wxss | 1 + components/goods-action/index.js | 14 + components/goods-action/index.json | 3 + components/goods-action/index.wxml | 5 + components/goods-action/index.wxss | 1 + components/grid-item/index.js | 70 + components/grid-item/index.json | 6 + components/grid-item/index.wxml | 22 + components/grid-item/index.wxss | 1 + components/grid/index.js | 57 + components/grid/index.json | 3 + components/grid/index.wxml | 3 + components/grid/index.wxss | 1 + components/icon/index.js | 27 + components/icon/index.json | 6 + components/icon/index.wxml | 20 + components/icon/index.wxss | 1 + components/image-cropper/index.js | 1108 +++++ components/image-cropper/index.json | 3 + components/image-cropper/index.wxml | 41 + components/image-cropper/index.wxss | 291 ++ components/image/index.js | 101 + components/image/index.json | 7 + components/image/index.wxml | 16 + components/image/index.wxss | 1 + components/index-anchor/index.js | 30 + components/index-anchor/index.json | 3 + components/index-anchor/index.wxml | 14 + components/index-anchor/index.wxss | 1 + components/index-bar/index.js | 269 ++ components/index-bar/index.json | 3 + components/index-bar/index.wxml | 22 + components/index-bar/index.wxss | 1 + components/info/index.js | 10 + components/info/index.json | 3 + components/info/index.wxml | 7 + components/info/index.wxss | 1 + components/keyboard/index.js | 203 + components/keyboard/index.json | 6 + components/keyboard/index.wxml | 42 + components/keyboard/index.wxss | 171 + components/loading/index.js | 16 + components/loading/index.json | 3 + components/loading/index.wxml | 18 + components/loading/index.wxss | 1 + components/mixins/basic.js | 26 + components/mixins/button.js | 15 + components/mixins/link.js | 17 + components/mixins/open-type.js | 25 + components/mixins/page-scroll.js | 28 + components/mixins/touch.js | 35 + components/mixins/transition.js | 118 + components/notice-bar/index.js | 128 + components/notice-bar/index.json | 6 + components/notice-bar/index.wxml | 37 + components/notice-bar/index.wxss | 1 + components/notify/index.js | 60 + components/notify/index.json | 6 + components/notify/index.wxml | 18 + components/notify/index.wxss | 1 + components/notify/notify.js | 42 + components/overlay/index.js | 22 + components/overlay/index.json | 6 + components/overlay/index.wxml | 10 + components/overlay/index.wxss | 1 + components/pdf-image/index.js | 47 + components/pdf-image/index.json | 6 + components/pdf-image/index.wxml | 19 + components/pdf-image/index.wxss | 0 components/picker-column/index.js | 117 + components/picker-column/index.json | 3 + components/picker-column/index.wxml | 22 + components/picker-column/index.wxs | 8 + components/picker-column/index.wxss | 1 + components/picker/index.js | 135 + components/picker/index.json | 7 + components/picker/index.wxml | 41 + components/picker/index.wxss | 1 + components/picker/shared.js | 21 + components/picker/toolbar.wxml | 28 + components/popup/index.js | 81 + components/popup/index.json | 7 + components/popup/index.wxml | 24 + components/popup/index.wxss | 1 + components/radio-group/index.js | 34 + components/radio-group/index.json | 3 + components/radio-group/index.wxml | 1 + components/radio-group/index.wxss | 1 + components/radio/index.js | 48 + components/radio/index.json | 6 + components/radio/index.wxml | 29 + components/radio/index.wxss | 1 + components/rate/index.js | 80 + components/rate/index.json | 6 + components/rate/index.wxml | 34 + components/rate/index.wxss | 1 + components/refresher/index.js | 124 + components/refresher/index.json | 5 + components/refresher/index.wxml | 10 + components/refresher/index.wxss | 33 + components/row/index.js | 40 + components/row/index.json | 3 + components/row/index.wxml | 3 + components/row/index.wxss | 1 + components/search/index.js | 73 + components/search/index.json | 6 + components/search/index.wxml | 50 + components/search/index.wxss | 1 + components/sidebar-item/index.js | 34 + components/sidebar-item/index.json | 6 + components/sidebar-item/index.wxml | 19 + components/sidebar-item/index.wxss | 1 + components/sidebar/index.js | 41 + components/sidebar/index.json | 3 + components/sidebar/index.wxml | 3 + components/sidebar/index.wxss | 1 + components/skeleton-avatar/index.js | 48 + components/skeleton-avatar/index.json | 3 + components/skeleton-avatar/index.wxml | 1 + components/skeleton-avatar/index.wxss | 69 + components/skeleton-paragraph/index.js | 63 + components/skeleton-paragraph/index.json | 3 + components/skeleton-paragraph/index.wxml | 5 + components/skeleton-paragraph/index.wxss | 41 + components/skeleton/index.js | 50 + components/skeleton/index.json | 3 + components/skeleton/index.wxml | 3 + components/skeleton/index.wxss | 4 + components/step/index.js | 43 + components/step/index.json | 6 + components/step/index.wxml | 69 + components/step/index.wxss | 1 + components/stepper/index.js | 184 + components/stepper/index.json | 3 + components/stepper/index.wxml | 37 + components/stepper/index.wxss | 1 + components/steps/index.js | 74 + components/steps/index.json | 6 + components/steps/index.wxml | 3 + components/steps/index.wxss | 1 + components/sticky/index.js | 119 + components/sticky/index.json | 3 + components/sticky/index.wxml | 8 + components/sticky/index.wxs | 37 + components/sticky/index.wxss | 1 + components/submit-bar/index.js | 59 + components/submit-bar/index.json | 7 + components/submit-bar/index.wxml | 42 + components/submit-bar/index.wxss | 1 + components/sudoku-image/index.js | 81 + components/sudoku-image/index.json | 6 + components/sudoku-image/index.wxml | 20 + components/sudoku-image/index.wxss | 4 + components/switch/index.js | 51 + components/switch/index.json | 6 + components/switch/index.wxml | 11 + components/switch/index.wxss | 1 + components/tab/index.js | 59 + components/tab/index.json | 3 + components/tab/index.wxml | 8 + components/tab/index.wxss | 1 + components/tabbar-item/index.js | 48 + components/tabbar-item/index.json | 7 + components/tabbar-item/index.wxml | 30 + components/tabbar-item/index.wxss | 1 + components/tabbar/index.js | 61 + components/tabbar/index.json | 3 + components/tabbar/index.wxml | 4 + components/tabbar/index.wxss | 1 + components/tabs/index.js | 274 ++ components/tabs/index.json | 7 + components/tabs/index.wxml | 63 + components/tabs/index.wxs | 78 + components/tabs/index.wxss | 1 + components/tag/index.js | 21 + components/tag/index.json | 6 + components/tag/index.wxml | 8 + components/tag/index.wxss | 1 + components/transition/index.js | 15 + components/transition/index.json | 3 + components/transition/index.wxml | 8 + components/transition/index.wxss | 1 + components/uploader/index.js | 238 + components/uploader/index.json | 8 + components/uploader/index.wxml | 33 + components/uploader/index.wxss | 1 + components/uploader/shared.js | 30 + components/uploader/utils.js | 61 + components/wxs/add-unit.wxs | 13 + components/wxs/array.wxs | 5 + components/wxs/bem.wxs | 38 + components/wxs/memoize.wxs | 54 + components/wxs/object.wxs | 13 + components/wxs/utils.wxs | 10 + pages/api/axios.js | 62 + pages/api/payment.js | 20 + pages/api/request.js | 209 + pages/api/user.js | 245 ++ pages/enterprise/address-new/index.js | 110 + pages/enterprise/address-new/index.json | 8 + pages/enterprise/address-new/index.wxml | 38 + pages/enterprise/address-new/index.wxss | 1 + pages/enterprise/address/index.js | 81 + pages/enterprise/address/index.json | 8 + pages/enterprise/address/index.wxml | 32 + pages/enterprise/address/index.wxss | 1 + pages/enterprise/employee/index.js | 178 + pages/enterprise/employee/index.json | 12 + pages/enterprise/employee/index.wxml | 70 + pages/enterprise/employee/index.wxss | 37 + pages/enterprise/index/index.js | 17 + pages/enterprise/index/index.json | 5 + pages/enterprise/index/index.wxml | 16 + pages/enterprise/index/index.wxss | 1 + pages/formate.wxs | 32 + pages/home/authory/index.js | 108 + pages/home/authory/index.json | 6 + pages/home/authory/index.wxml | 59 + pages/home/authory/index.wxss | 57 + pages/home/index/index.js | 99 + pages/home/index/index.json | 12 + pages/home/index/index.wxml | 91 + pages/home/index/index.wxss | 9 + pages/home/mobile/index.js | 106 + pages/home/mobile/index.json | 6 + pages/home/mobile/index.wxml | 25 + pages/home/mobile/index.wxss | 4 + pages/htmls/agreement/index.js | 9 + pages/htmls/agreement/index.json | 3 + pages/htmls/agreement/index.wxml | 38 + pages/htmls/agreement/index.wxss | 1 + pages/htmls/auths/index.js | 17 + pages/htmls/auths/index.json | 7 + pages/htmls/auths/index.wxml | 44 + pages/htmls/auths/index.wxss | 22 + pages/index/index.js | 210 + pages/index/index.json | 11 + pages/index/index.wxml | 18 + pages/index/index.wxss | 1 + pages/login/index.js | 271 ++ pages/login/index.json | 8 + pages/login/index.wxml | 94 + pages/login/index.wxss | 24 + pages/mall/components/cell/index.js | 23 + pages/mall/components/cell/index.json | 4 + pages/mall/components/cell/index.wxml | 2 + pages/mall/components/cell/index.wxss | 1 + pages/mall/components/fence/index.js | 23 + pages/mall/components/fence/index.json | 4 + pages/mall/components/fence/index.wxml | 2 + pages/mall/components/fence/index.wxss | 1 + pages/mall/components/sku/index.js | 23 + pages/mall/components/sku/index.json | 4 + pages/mall/components/sku/index.wxml | 2 + pages/mall/components/sku/index.wxss | 1 + pages/mall/index.wxs | 106 + pages/mall/index/index.js | 126 + pages/mall/index/index.json | 14 + pages/mall/index/index.wxml | 40 + pages/mall/index/index.wxss | 4 + pages/mall/search-list/index.js | 136 + pages/mall/search-list/index.json | 7 + pages/mall/search-list/index.wxml | 41 + pages/mall/search-list/index.wxss | 1 + pages/message/detail/index.js | 16 + pages/message/detail/index.json | 3 + pages/message/detail/index.wxml | 2 + pages/message/detail/index.wxss | 1 + pages/message/index/index.js | 190 + pages/message/index/index.json | 12 + pages/message/index/index.wxml | 77 + pages/message/index/index.wxss | 8 + pages/process/index.wxs | 66 + pages/process/index/index.js | 99 + pages/process/index/index.json | 9 + pages/process/index/index.wxml | 48 + pages/process/index/index.wxss | 4 + project.config.json | 74 + sitemap.json | 7 + utils/area.js | 4047 ++++++++++++++++++ utils/event.js | 35 + utils/math.js | 155 + utils/storage.js | 48 + utils/util.js | 197 + 401 files changed, 20462 insertions(+) create mode 100644 app.js create mode 100644 app.json create mode 100644 app.wxss create mode 100644 assets/image/bg-logo.png create mode 100644 assets/image/icon-finace.png create mode 100644 assets/image/icon-payment.png create mode 100644 assets/image/icon_code.png create mode 100644 assets/image/icon_delete.svg create mode 100644 assets/image/icon_logo.png create mode 100644 assets/image/icon_pdf.svg create mode 100644 assets/image/icon_phone.png create mode 100644 assets/image/icon_pwd.png create mode 100644 assets/image/list_empty.png create mode 100644 assets/image/tabbar/home-blue.png create mode 100644 assets/image/tabbar/home-gray.png create mode 100644 assets/image/tabbar/mall-blue.png create mode 100644 assets/image/tabbar/mall-gray.png create mode 100644 assets/image/tabbar/process-blue.png create mode 100644 assets/image/tabbar/process-gray.png create mode 100644 assets/image/ygImg.png create mode 100644 assets/raw/ding.mp3 create mode 100644 colorui/components/cu-custom.js create mode 100644 colorui/components/cu-custom.json create mode 100644 colorui/components/cu-custom.wxml create mode 100644 colorui/components/cu-custom.wxss create mode 100644 colorui/icon.wxss create mode 100644 colorui/main.wxss create mode 100644 components/action-sheet/index.js create mode 100644 components/action-sheet/index.json create mode 100644 components/action-sheet/index.wxml create mode 100644 components/action-sheet/index.wxss create mode 100644 components/area/index.js create mode 100644 components/area/index.json create mode 100644 components/area/index.wxml create mode 100644 components/area/index.wxss create mode 100644 components/button/index.js create mode 100644 components/button/index.json create mode 100644 components/button/index.wxml create mode 100644 components/button/index.wxss create mode 100644 components/cell-group/index.js create mode 100644 components/cell-group/index.json create mode 100644 components/cell-group/index.wxml create mode 100644 components/cell-group/index.wxss create mode 100644 components/cell/index.js create mode 100644 components/cell/index.json create mode 100644 components/cell/index.wxml create mode 100644 components/cell/index.wxss create mode 100644 components/checkbox-group/index.js create mode 100644 components/checkbox-group/index.json create mode 100644 components/checkbox-group/index.wxml create mode 100644 components/checkbox-group/index.wxss create mode 100644 components/checkbox/index.js create mode 100644 components/checkbox/index.json create mode 100644 components/checkbox/index.wxml create mode 100644 components/checkbox/index.wxs create mode 100644 components/checkbox/index.wxss create mode 100644 components/col/index.js create mode 100644 components/col/index.json create mode 100644 components/col/index.wxml create mode 100644 components/col/index.wxss create mode 100644 components/collapse-item/index.js create mode 100644 components/collapse-item/index.json create mode 100644 components/collapse-item/index.wxml create mode 100644 components/collapse-item/index.wxss create mode 100644 components/collapse/index.js create mode 100644 components/collapse/index.json create mode 100644 components/collapse/index.wxml create mode 100644 components/collapse/index.wxss create mode 100644 components/common/classNames.js create mode 100644 components/common/color.js create mode 100644 components/common/component.js create mode 100644 components/common/index.wxss create mode 100644 components/common/style/clearfix.wxss create mode 100644 components/common/style/ellipsis.wxss create mode 100644 components/common/style/hairline.wxss create mode 100644 components/common/style/mixins/clearfix.wxss create mode 100644 components/common/style/mixins/ellipsis.wxss create mode 100644 components/common/style/mixins/hairline.wxss create mode 100644 components/common/style/theme.wxss create mode 100644 components/common/style/var.wxss create mode 100644 components/common/utils.js create mode 100644 components/common/version.js create mode 100644 components/count-down/index.js create mode 100644 components/count-down/index.json create mode 100644 components/count-down/index.wxml create mode 100644 components/count-down/index.wxss create mode 100644 components/count-down/utils.js create mode 100644 components/datetime-picker/index.js create mode 100644 components/datetime-picker/index.json create mode 100644 components/datetime-picker/index.wxml create mode 100644 components/datetime-picker/index.wxss create mode 100644 components/dialog/dialog.js create mode 100644 components/dialog/index.js create mode 100644 components/dialog/index.json create mode 100644 components/dialog/index.wxml create mode 100644 components/dialog/index.wxss create mode 100644 components/divider/index.js create mode 100644 components/divider/index.json create mode 100644 components/divider/index.wxml create mode 100644 components/divider/index.wxss create mode 100644 components/empty/index.js create mode 100644 components/empty/index.json create mode 100644 components/empty/index.wxml create mode 100644 components/empty/index.wxss create mode 100644 components/field/index.js create mode 100644 components/field/index.json create mode 100644 components/field/index.wxml create mode 100644 components/field/index.wxs create mode 100644 components/field/index.wxss create mode 100644 components/field/props.js create mode 100644 components/goods-action-button/index.js create mode 100644 components/goods-action-button/index.json create mode 100644 components/goods-action-button/index.wxml create mode 100644 components/goods-action-button/index.wxss create mode 100644 components/goods-action-icon/index.js create mode 100644 components/goods-action-icon/index.json create mode 100644 components/goods-action-icon/index.wxml create mode 100644 components/goods-action-icon/index.wxss create mode 100644 components/goods-action/index.js create mode 100644 components/goods-action/index.json create mode 100644 components/goods-action/index.wxml create mode 100644 components/goods-action/index.wxss create mode 100644 components/grid-item/index.js create mode 100644 components/grid-item/index.json create mode 100644 components/grid-item/index.wxml create mode 100644 components/grid-item/index.wxss create mode 100644 components/grid/index.js create mode 100644 components/grid/index.json create mode 100644 components/grid/index.wxml create mode 100644 components/grid/index.wxss create mode 100644 components/icon/index.js create mode 100644 components/icon/index.json create mode 100644 components/icon/index.wxml create mode 100644 components/icon/index.wxss create mode 100644 components/image-cropper/index.js create mode 100644 components/image-cropper/index.json create mode 100644 components/image-cropper/index.wxml create mode 100644 components/image-cropper/index.wxss create mode 100644 components/image/index.js create mode 100644 components/image/index.json create mode 100644 components/image/index.wxml create mode 100644 components/image/index.wxss create mode 100644 components/index-anchor/index.js create mode 100644 components/index-anchor/index.json create mode 100644 components/index-anchor/index.wxml create mode 100644 components/index-anchor/index.wxss create mode 100644 components/index-bar/index.js create mode 100644 components/index-bar/index.json create mode 100644 components/index-bar/index.wxml create mode 100644 components/index-bar/index.wxss create mode 100644 components/info/index.js create mode 100644 components/info/index.json create mode 100644 components/info/index.wxml create mode 100644 components/info/index.wxss create mode 100644 components/keyboard/index.js create mode 100644 components/keyboard/index.json create mode 100644 components/keyboard/index.wxml create mode 100644 components/keyboard/index.wxss create mode 100644 components/loading/index.js create mode 100644 components/loading/index.json create mode 100644 components/loading/index.wxml create mode 100644 components/loading/index.wxss create mode 100644 components/mixins/basic.js create mode 100644 components/mixins/button.js create mode 100644 components/mixins/link.js create mode 100644 components/mixins/open-type.js create mode 100644 components/mixins/page-scroll.js create mode 100644 components/mixins/touch.js create mode 100644 components/mixins/transition.js create mode 100644 components/notice-bar/index.js create mode 100644 components/notice-bar/index.json create mode 100644 components/notice-bar/index.wxml create mode 100644 components/notice-bar/index.wxss create mode 100644 components/notify/index.js create mode 100644 components/notify/index.json create mode 100644 components/notify/index.wxml create mode 100644 components/notify/index.wxss create mode 100644 components/notify/notify.js create mode 100644 components/overlay/index.js create mode 100644 components/overlay/index.json create mode 100644 components/overlay/index.wxml create mode 100644 components/overlay/index.wxss create mode 100644 components/pdf-image/index.js create mode 100644 components/pdf-image/index.json create mode 100644 components/pdf-image/index.wxml create mode 100644 components/pdf-image/index.wxss create mode 100644 components/picker-column/index.js create mode 100644 components/picker-column/index.json create mode 100644 components/picker-column/index.wxml create mode 100644 components/picker-column/index.wxs create mode 100644 components/picker-column/index.wxss create mode 100644 components/picker/index.js create mode 100644 components/picker/index.json create mode 100644 components/picker/index.wxml create mode 100644 components/picker/index.wxss create mode 100644 components/picker/shared.js create mode 100644 components/picker/toolbar.wxml create mode 100644 components/popup/index.js create mode 100644 components/popup/index.json create mode 100644 components/popup/index.wxml create mode 100644 components/popup/index.wxss create mode 100644 components/radio-group/index.js create mode 100644 components/radio-group/index.json create mode 100644 components/radio-group/index.wxml create mode 100644 components/radio-group/index.wxss create mode 100644 components/radio/index.js create mode 100644 components/radio/index.json create mode 100644 components/radio/index.wxml create mode 100644 components/radio/index.wxss create mode 100644 components/rate/index.js create mode 100644 components/rate/index.json create mode 100644 components/rate/index.wxml create mode 100644 components/rate/index.wxss create mode 100644 components/refresher/index.js create mode 100644 components/refresher/index.json create mode 100644 components/refresher/index.wxml create mode 100644 components/refresher/index.wxss create mode 100644 components/row/index.js create mode 100644 components/row/index.json create mode 100644 components/row/index.wxml create mode 100644 components/row/index.wxss create mode 100644 components/search/index.js create mode 100644 components/search/index.json create mode 100644 components/search/index.wxml create mode 100644 components/search/index.wxss create mode 100644 components/sidebar-item/index.js create mode 100644 components/sidebar-item/index.json create mode 100644 components/sidebar-item/index.wxml create mode 100644 components/sidebar-item/index.wxss create mode 100644 components/sidebar/index.js create mode 100644 components/sidebar/index.json create mode 100644 components/sidebar/index.wxml create mode 100644 components/sidebar/index.wxss create mode 100644 components/skeleton-avatar/index.js create mode 100644 components/skeleton-avatar/index.json create mode 100644 components/skeleton-avatar/index.wxml create mode 100644 components/skeleton-avatar/index.wxss create mode 100644 components/skeleton-paragraph/index.js create mode 100644 components/skeleton-paragraph/index.json create mode 100644 components/skeleton-paragraph/index.wxml create mode 100644 components/skeleton-paragraph/index.wxss create mode 100644 components/skeleton/index.js create mode 100644 components/skeleton/index.json create mode 100644 components/skeleton/index.wxml create mode 100644 components/skeleton/index.wxss create mode 100644 components/step/index.js create mode 100644 components/step/index.json create mode 100644 components/step/index.wxml create mode 100644 components/step/index.wxss create mode 100644 components/stepper/index.js create mode 100644 components/stepper/index.json create mode 100644 components/stepper/index.wxml create mode 100644 components/stepper/index.wxss create mode 100644 components/steps/index.js create mode 100644 components/steps/index.json create mode 100644 components/steps/index.wxml create mode 100644 components/steps/index.wxss create mode 100644 components/sticky/index.js create mode 100644 components/sticky/index.json create mode 100644 components/sticky/index.wxml create mode 100644 components/sticky/index.wxs create mode 100644 components/sticky/index.wxss create mode 100644 components/submit-bar/index.js create mode 100644 components/submit-bar/index.json create mode 100644 components/submit-bar/index.wxml create mode 100644 components/submit-bar/index.wxss create mode 100644 components/sudoku-image/index.js create mode 100644 components/sudoku-image/index.json create mode 100644 components/sudoku-image/index.wxml create mode 100644 components/sudoku-image/index.wxss create mode 100644 components/switch/index.js create mode 100644 components/switch/index.json create mode 100644 components/switch/index.wxml create mode 100644 components/switch/index.wxss create mode 100644 components/tab/index.js create mode 100644 components/tab/index.json create mode 100644 components/tab/index.wxml create mode 100644 components/tab/index.wxss create mode 100644 components/tabbar-item/index.js create mode 100644 components/tabbar-item/index.json create mode 100644 components/tabbar-item/index.wxml create mode 100644 components/tabbar-item/index.wxss create mode 100644 components/tabbar/index.js create mode 100644 components/tabbar/index.json create mode 100644 components/tabbar/index.wxml create mode 100644 components/tabbar/index.wxss create mode 100644 components/tabs/index.js create mode 100644 components/tabs/index.json create mode 100644 components/tabs/index.wxml create mode 100644 components/tabs/index.wxs create mode 100644 components/tabs/index.wxss create mode 100644 components/tag/index.js create mode 100644 components/tag/index.json create mode 100644 components/tag/index.wxml create mode 100644 components/tag/index.wxss create mode 100644 components/transition/index.js create mode 100644 components/transition/index.json create mode 100644 components/transition/index.wxml create mode 100644 components/transition/index.wxss create mode 100644 components/uploader/index.js create mode 100644 components/uploader/index.json create mode 100644 components/uploader/index.wxml create mode 100644 components/uploader/index.wxss create mode 100644 components/uploader/shared.js create mode 100644 components/uploader/utils.js create mode 100644 components/wxs/add-unit.wxs create mode 100644 components/wxs/array.wxs create mode 100644 components/wxs/bem.wxs create mode 100644 components/wxs/memoize.wxs create mode 100644 components/wxs/object.wxs create mode 100644 components/wxs/utils.wxs create mode 100644 pages/api/axios.js create mode 100644 pages/api/payment.js create mode 100644 pages/api/request.js create mode 100644 pages/api/user.js create mode 100644 pages/enterprise/address-new/index.js create mode 100644 pages/enterprise/address-new/index.json create mode 100644 pages/enterprise/address-new/index.wxml create mode 100644 pages/enterprise/address-new/index.wxss create mode 100644 pages/enterprise/address/index.js create mode 100644 pages/enterprise/address/index.json create mode 100644 pages/enterprise/address/index.wxml create mode 100644 pages/enterprise/address/index.wxss create mode 100644 pages/enterprise/employee/index.js create mode 100644 pages/enterprise/employee/index.json create mode 100644 pages/enterprise/employee/index.wxml create mode 100644 pages/enterprise/employee/index.wxss create mode 100644 pages/enterprise/index/index.js create mode 100644 pages/enterprise/index/index.json create mode 100644 pages/enterprise/index/index.wxml create mode 100644 pages/enterprise/index/index.wxss create mode 100644 pages/formate.wxs create mode 100644 pages/home/authory/index.js create mode 100644 pages/home/authory/index.json create mode 100644 pages/home/authory/index.wxml create mode 100644 pages/home/authory/index.wxss create mode 100644 pages/home/index/index.js create mode 100644 pages/home/index/index.json create mode 100644 pages/home/index/index.wxml create mode 100644 pages/home/index/index.wxss create mode 100644 pages/home/mobile/index.js create mode 100644 pages/home/mobile/index.json create mode 100644 pages/home/mobile/index.wxml create mode 100644 pages/home/mobile/index.wxss create mode 100644 pages/htmls/agreement/index.js create mode 100644 pages/htmls/agreement/index.json create mode 100644 pages/htmls/agreement/index.wxml create mode 100644 pages/htmls/agreement/index.wxss create mode 100644 pages/htmls/auths/index.js create mode 100644 pages/htmls/auths/index.json create mode 100644 pages/htmls/auths/index.wxml create mode 100644 pages/htmls/auths/index.wxss create mode 100644 pages/index/index.js create mode 100644 pages/index/index.json create mode 100644 pages/index/index.wxml create mode 100644 pages/index/index.wxss create mode 100644 pages/login/index.js create mode 100644 pages/login/index.json create mode 100644 pages/login/index.wxml create mode 100644 pages/login/index.wxss create mode 100644 pages/mall/components/cell/index.js create mode 100644 pages/mall/components/cell/index.json create mode 100644 pages/mall/components/cell/index.wxml create mode 100644 pages/mall/components/cell/index.wxss create mode 100644 pages/mall/components/fence/index.js create mode 100644 pages/mall/components/fence/index.json create mode 100644 pages/mall/components/fence/index.wxml create mode 100644 pages/mall/components/fence/index.wxss create mode 100644 pages/mall/components/sku/index.js create mode 100644 pages/mall/components/sku/index.json create mode 100644 pages/mall/components/sku/index.wxml create mode 100644 pages/mall/components/sku/index.wxss create mode 100644 pages/mall/index.wxs create mode 100644 pages/mall/index/index.js create mode 100644 pages/mall/index/index.json create mode 100644 pages/mall/index/index.wxml create mode 100644 pages/mall/index/index.wxss create mode 100644 pages/mall/search-list/index.js create mode 100644 pages/mall/search-list/index.json create mode 100644 pages/mall/search-list/index.wxml create mode 100644 pages/mall/search-list/index.wxss create mode 100644 pages/message/detail/index.js create mode 100644 pages/message/detail/index.json create mode 100644 pages/message/detail/index.wxml create mode 100644 pages/message/detail/index.wxss create mode 100644 pages/message/index/index.js create mode 100644 pages/message/index/index.json create mode 100644 pages/message/index/index.wxml create mode 100644 pages/message/index/index.wxss create mode 100644 pages/process/index.wxs create mode 100644 pages/process/index/index.js create mode 100644 pages/process/index/index.json create mode 100644 pages/process/index/index.wxml create mode 100644 pages/process/index/index.wxss create mode 100644 project.config.json create mode 100644 sitemap.json create mode 100644 utils/area.js create mode 100644 utils/event.js create mode 100644 utils/math.js create mode 100644 utils/storage.js create mode 100644 utils/util.js diff --git a/app.js b/app.js new file mode 100644 index 0000000..5255751 --- /dev/null +++ b/app.js @@ -0,0 +1,15 @@ +//app.js +App({ + //----------------------------------------------globalData-------------------------------------- + release: 1, + tmplIds: ['kg0T1ve0FpYrEtZ4ExbypHm8mtS7OJaehvqN_T9ypoI'], + version: 152, + xAppId: '503258978847952896', + accountInfo: null, + globalData: { + openId: null, + token: null, + isIPhoneX: false, + isIos: false + } +}) \ No newline at end of file diff --git a/app.json b/app.json new file mode 100644 index 0000000..8803a30 --- /dev/null +++ b/app.json @@ -0,0 +1,21 @@ +{ + "pages":[ + "pages/index/index", + "pages/login/index", + "pages/home/mobile/index", + "pages/home/authory/index", + "pages/htmls/agreement/index", + "pages/message/index/index" + ], + "window":{ + "backgroundTextStyle":"light", + "navigationBarTextStyle": "black", + "navigationBarBackgroundColor": "#fff", + "navigationBarTitleText": "", + "navigationStyle": "custom" + }, + "usingComponents": { + "cu-custom": "/colorui/components/cu-custom" + }, + "sitemapLocation": "sitemap.json" +} diff --git a/app.wxss b/app.wxss new file mode 100644 index 0000000..a885a81 --- /dev/null +++ b/app.wxss @@ -0,0 +1,59 @@ +@import "colorui/main.wxss"; +@import "colorui/icon.wxss"; + +/**app.wxss**/ +.scrollPage { + height: 100vh; +} + +.flex-center { + align-items: center; + justify-content: center; +} + +.flex-column { + -webkit-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} + +.flex-justify { + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.page-outline { + font-size: 24rpx; + font-family: PingFang-SC-Regular, PingFang-SC; + font-weight: 400; + color: #999999; + line-height: 16px; + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + word-wrap: break-word; + white-space: normal !important; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.weui_goback { + font-size: 28rpx; + width: 1em; + height: 2em; + -webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%; + mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%; + -webkit-mask-size: cover; + mask-size: cover; + background-color: currentColor +} + +.weui_goback:active { + opacity: .5 +} + + \ No newline at end of file diff --git a/assets/image/bg-logo.png b/assets/image/bg-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..61da39b802395249c843ae0e462d1a7494896dbb GIT binary patch literal 37306 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 literal 0 HcmV?d00001 diff --git a/assets/image/icon-payment.png b/assets/image/icon-payment.png new file mode 100644 index 0000000000000000000000000000000000000000..a72c6b5db761639d10c2cfcf28cba79861cd3ddf GIT binary patch literal 743 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~m(&Q)G+$o^ zEg+kNfw4W4fd!-lh^2s-fq{7eBLg##W(0{XV1mnvEMP{kK?*nB{qUE8fho|_#WBP} z@NS52hH#+3yvmzbYJHgx3Moe{nbNfOOHh;J-YI_+JgP4%tWc;55O8%gSIuAIFKQzubdF55EJcn z^QailES}%pf1fo4?{i$>w=Vh0s;4r`m5yB#{`|2ry4i_6)9bfb*gjj;pyk%a#eX$o z%T6ud(q3KFroU`{yvl;w?1Q~YE)Qn!Gx0 zkD0@d18M0^4+G?9-`)6X3bXs(XKrfj_I!CoD|rv!JbE)wuWhTC;~jR9Ou4$J{=D2A z`#Pg8$#Jz-y${{5AGhgM7GFo-hl&YXqrK*PAJ*Icu}P=rLwA+@`HwpqW5Xry9&Eao zwaCid<%Y3tzmQ|!<6OC)`3`(v3oRChKl0{YczfZmn^AYp75#PJpzxiI>yw)F+pLFc zm+e`ccWFnF&yjnD)8oSf`zpd3_spDBS)Ap%GW_kCh-j(){_{Jk^7&I8=dmwUo9$!m z8!%^c(6!v@@7DV22JSxk?!4943pRCM)n}$WTX)XZ*=5O$jn5er?5-r-7CxBfn`dEC zq|qI@bmzUPrH;>@Ix2kaC~jvDdLC|Odd)&`T18sFuYKIgp2+#L4E*-+nI7;qJr-+c z;K-9QX*%;J@0{<7YCqC9#7i7|aqhy2XHlo@w#}RQEyL=ryi4%I{oZxV+YcXooEmJr Q2$aY?UHx3vIVCg!0Cpxc4*&oF literal 0 HcmV?d00001 diff --git a/assets/image/icon_code.png b/assets/image/icon_code.png new file mode 100644 index 0000000000000000000000000000000000000000..ced35d44fc5a61c3dc4370afd875eb6641157911 GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxKmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIC>0X`wFKADBi9=;4^-x)k&ug{kzkNH)u7#5#uYOF7QEOZC ahsmQ(`-@4m%O;?g89ZJ6T-G@yGywp3^}&Mx literal 0 HcmV?d00001 diff --git a/assets/image/icon_delete.svg b/assets/image/icon_delete.svg new file mode 100644 index 0000000..e2ede04 --- /dev/null +++ b/assets/image/icon_delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/image/icon_logo.png b/assets/image/icon_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..02966f399277fefbb4e3e202e16534721fc441c3 GIT binary patch literal 2696 zcmX|Ddpy(YAD_!yhU&~ALPDa6jBVta%V-QC2g$X}B_tNPG^ylvOfDJCorpASLWW#U z9CIzi2#IDg<(?3~Z@*rz^Lag=%lqG9fVo2L%#A^m0qI2mn0h;5a8_0z7%&TfxZ?dlyuU0! z9s?2t;wj_;{o0G`7gxyrpXyS`^WTj7Wvmnu3kBN2MeHRs*6$_?g*qDl7N}>6J|YkZ zV1OB10ETmVNUi?|zyN_nB7w?(vki~{T3cKDHwo~+B>+P39ZES9|4F|M;t%^&i$5x4 zi~#U={6XlJ&wMZbpcj_^0bmrf#!iyPREwthgI^1WcM9P<08&14R4}w%rEo?tw2jn^ zAT?`dw;+H8%by~(Ajr)ckLU(Dbam~g1KD&qiH>lgJdS*fP>QcpDVPGT2YA3itun-S zg7|ikh&RA-N>3(4@AgQ<52%&RliQI=O%~|#S7((%&jO#q3~y&`4>E^v_K!_*9}yU` zlG9W9%vLHm`$Oxm8}(j}%HwM(|H38bJ&a;DQEb+&=awl?jmeC*X6kD6Fm|b|?~eH2 zu)QF!)ypXvYET;Rf8sEvMwfi2mvj8WKQ%%hdMBiP7Q25`7?oY4$OS!Nsk9i#nhyPh zKOv=gaL|CoXy7z0S?OoLZ;(aF7q)FHE-8xf7PV~r-0CLLySo>)@E)_1yY$74KM+6H z+t`!4=GJ^u$1}05`U7pL!)NCU*}D&fuYMpvBXwGK2aWXCuIlg@5?&odjC zM;I6Qu^&e(|2}hAW{m9;u+^@43LdpHx56Hu4}_a0{1aZQZ$h{^G#xRUv!AQ zAQRftU~}!@hvZkjE%!oMF^Uf3(qESbuc_}JoyWGU&b&U@=fU^gB1U$r?Cfkd+xA3f z=2vW_rb1in^GdpQo8uZ{iGxwH#dDDdJ3rZ;WhMMcOGRDHiS>GYUErO4_P`hzGPWDR zhs+{-X@9I9+=`on-RV9bERWLJ!*@ctv`ADlU5lcRScw!)}J$kyH>xZsXmo zSvPIZkyZP5nFGGhJyJmf>UU0-XE1m-a%-xZx4teg8Vt)Y*P;OaAHVDoBu z)wPV%vjn=~`I=I@RIZ0=kTuxUySi`|B`j>X#K9JT7uG)$?*yw$+V9lldqqTa)G-D& zoHm;EH^cILf51oQVc_F5rCtv9TV_1#GsRxy{;c%0vx*;M2+jNf7RYqho0*bTgkKDU#C{F8-YWe4`4Mh`zV+|@9{iEuy3suAuHp$PU4K%ZnhpK~MZ1;-k#VeUU zPn=1M_~7^kyw0r+m)DyIa@cp)Y#CYc;7ajbLAi7Z2z2GC)9U$?mzc?=dDpiPez4Qf ze;Qq=VsAoSrk;4dQVtOFdYM$^*h@q})+~}?zN?*YuAtBlkA~~EroF5R^Vmj$!%Oal zH zoUi6QNO95dX`q_550m5Csw>&*0Rm!)EwOpf@zZ(I-pSk~dGl8JGk&a$E4dX& zeO2oxxia1&Fei&s$y6UI&Gx!UZsX0e%G*Mdu(vW**TJq~gK9MxIYvL#&#z!wat5xe zY^OywvMvqB5Lp2teZ;i%i~q>_G=N1%0;J?xmi9kEJQjCP68)G-y3LRe-{nN>@xyWX^iY7?;{*z7!3s_-JnX zKE9Jo&8q^R^L3sYKc)rwQ$EH2Z?rVm9CrYq> znv#)9tByI-s;p~<3#qqr?mDnZGWNr)C>l)LEkmi$DWSM>A%ZelDc-bF_%?{&`MGLv zr{4Gl2!*%+SDr{(SP6JkckgiqjY(NTWVA5L-UT#0J1%X?M6DEVsC%HQyq+2RwTURz z)62+G zqU{HNPY1jpTz|c=%|%U7&@e0u{UNKa4l`lAr;6YfP$)Oj0@x zxt2b!Ow8efI>x1anaEc~q|HABTlv4e7#ip}s&5yZU>T_OylMV)nNp*JefX37#qory zdjkGyVf-xp}2O$f#C9=eYJAw3J z8|5-?$BgBraRraMxg?^sUR-{@1GygSIxM7<=6NADIjPkN^Mx literal 0 HcmV?d00001 diff --git a/assets/image/icon_pdf.svg b/assets/image/icon_pdf.svg new file mode 100644 index 0000000..4810b79 --- /dev/null +++ b/assets/image/icon_pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/image/icon_phone.png b/assets/image/icon_phone.png new file mode 100644 index 0000000000000000000000000000000000000000..7511dcfff80e37bd32168324594405c2dc07c3a9 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxKmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIBG0X`wFKAD9KrQe-AeO@+Vke~nn literal 0 HcmV?d00001 diff --git a/assets/image/icon_pwd.png b/assets/image/icon_pwd.png new file mode 100644 index 0000000000000000000000000000000000000000..f8c4fca61d72d8b0d281c4c6a3f9e7070f29b243 GIT binary patch literal 390 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxKmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIDx0X`wFP98qa9zG0R|6SYz?EU?nJ$xA^{rAZ%bn);5vYkErfKosNW&^pt zP_{cr7RavtwfrE^DB+SIzu@{~8>KkE2{8n&jWWuc*Y)vIRl9Z%k9xPE=p`ZC$YB zO10PV>=(i77MdKZPJZ(J+z(-ol{LSjzbiJnd9c2(HQvSl^&|6z3!X)Xxld%8zTELu RMHT2H22WQ%mvv4FO#lz%np*$> literal 0 HcmV?d00001 diff --git a/assets/image/list_empty.png b/assets/image/list_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d37dd1803de5ef5ab6abe36e2078269471c01c GIT binary patch literal 5822 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 literal 0 HcmV?d00001 diff --git a/assets/image/tabbar/home-blue.png b/assets/image/tabbar/home-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..6f52f911f74056fd8b4e2c76454c92d4af37cdab GIT binary patch literal 1070 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 literal 0 HcmV?d00001 diff --git a/assets/image/tabbar/process-blue.png b/assets/image/tabbar/process-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..7323cfda9a2efbfc6cc6a74e73e07e8466d92922 GIT binary patch literal 1268 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 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/colorui/components/cu-custom.wxss b/colorui/components/cu-custom.wxss new file mode 100644 index 0000000..82e835e --- /dev/null +++ b/colorui/components/cu-custom.wxss @@ -0,0 +1,5 @@ +/* colorui/components/cu-custom.wxss */ +.shadow{ + box-shadow: 0 0rpx 0rpx rgba(0, 0, 0, 0.04) +} + \ No newline at end of file diff --git a/colorui/icon.wxss b/colorui/icon.wxss new file mode 100644 index 0000000..e19a7bb --- /dev/null +++ b/colorui/icon.wxss @@ -0,0 +1,1226 @@ +@keyframes cuIcon-spin { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +.iconfont-spin { + -webkit-animation: cuIcon-spin 2s infinite linear; + animation: cuIcon-spin 2s infinite linear; + display: inline-block; +} + +.iconfont-pulse { + -webkit-animation: cuIcon-spin 1s infinite steps(8); + animation: cuIcon-spin 1s infinite steps(8); + display: inline-block; +} + +[class*="cuIcon-"] { + font-family: "cuIcon"; + font-size: inherit; + font-style: normal; +} + +@font-face { + font-family: "cuIcon"; + src: url('//at.alicdn.com/t/font_533566_yfq2d9wdij.eot?t=1545239985831'); + /* IE9*/ + src: url('//at.alicdn.com/t/font_533566_yfq2d9wdij.eot?t=1545239985831#iefix') format('embedded-opentype'), + /* IE6-IE8 */ + url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'), + url('//at.alicdn.com/t/font_533566_yfq2d9wdij.ttf?t=1545239985831') format('truetype'), + /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ + url('//at.alicdn.com/t/font_533566_yfq2d9wdij.svg?t=1545239985831#iconfont') format('svg'); + /* iOS 4.1- */ +} + +.cuIcon-appreciate:before { + content: "\e644"; +} + +.cuIcon-check:before { + content: "\e645"; +} + +.cuIcon-close:before { + content: "\e646"; +} + +.cuIcon-edit:before { + content: "\e649"; +} + +.cuIcon-emoji:before { + content: "\e64a"; +} + +.cuIcon-favorfill:before { + content: "\e64b"; +} + +.cuIcon-favor:before { + content: "\e64c"; +} + +.cuIcon-loading:before { + content: "\e64f"; +} + +.cuIcon-locationfill:before { + content: "\e650"; +} + +.cuIcon-location:before { + content: "\e651"; +} + +.cuIcon-phone:before { + content: "\e652"; +} + +.cuIcon-roundcheckfill:before { + content: "\e656"; +} + +.cuIcon-roundcheck:before { + content: "\e657"; +} + +.cuIcon-roundclosefill:before { + content: "\e658"; +} + +.cuIcon-roundclose:before { + content: "\e659"; +} + +.cuIcon-roundrightfill:before { + content: "\e65a"; +} + +.cuIcon-roundright:before { + content: "\e65b"; +} + +.cuIcon-search:before { + content: "\e65c"; +} + +.cuIcon-taxi:before { + content: "\e65d"; +} + +.cuIcon-timefill:before { + content: "\e65e"; +} + +.cuIcon-time:before { + content: "\e65f"; +} + +.cuIcon-unfold:before { + content: "\e661"; +} + +.cuIcon-warnfill:before { + content: "\e662"; +} + +.cuIcon-warn:before { + content: "\e663"; +} + +.cuIcon-camerafill:before { + content: "\e664"; +} + +.cuIcon-camera:before { + content: "\e665"; +} + +.cuIcon-commentfill:before { + content: "\e666"; +} + +.cuIcon-comment:before { + content: "\e667"; +} + +.cuIcon-likefill:before { + content: "\e668"; +} + +.cuIcon-like:before { + content: "\e669"; +} + +.cuIcon-notificationfill:before { + content: "\e66a"; +} + +.cuIcon-notification:before { + content: "\e66b"; +} + +.cuIcon-order:before { + content: "\e66c"; +} + +.cuIcon-samefill:before { + content: "\e66d"; +} + +.cuIcon-same:before { + content: "\e66e"; +} + +.cuIcon-deliver:before { + content: "\e671"; +} + +.cuIcon-evaluate:before { + content: "\e672"; +} + +.cuIcon-pay:before { + content: "\e673"; +} + +.cuIcon-send:before { + content: "\e675"; +} + +.cuIcon-shop:before { + content: "\e676"; +} + +.cuIcon-ticket:before { + content: "\e677"; +} + +.cuIcon-back:before { + content: "\e679"; +} + +.cuIcon-cascades:before { + content: "\e67c"; +} + +.cuIcon-discover:before { + content: "\e67e"; +} + +.cuIcon-list:before { + content: "\e682"; +} + +.cuIcon-more:before { + content: "\e684"; +} + +.cuIcon-scan:before { + content: "\e689"; +} + +.cuIcon-settings:before { + content: "\e68a"; +} + +.cuIcon-questionfill:before { + content: "\e690"; +} + +.cuIcon-question:before { + content: "\e691"; +} + +.cuIcon-shopfill:before { + content: "\e697"; +} + +.cuIcon-form:before { + content: "\e699"; +} + +.cuIcon-pic:before { + content: "\e69b"; +} + +.cuIcon-filter:before { + content: "\e69c"; +} + +.cuIcon-footprint:before { + content: "\e69d"; +} + +.cuIcon-top:before { + content: "\e69e"; +} + +.cuIcon-pulldown:before { + content: "\e69f"; +} + +.cuIcon-pullup:before { + content: "\e6a0"; +} + +.cuIcon-right:before { + content: "\e6a3"; +} + +.cuIcon-refresh:before { + content: "\e6a4"; +} + +.cuIcon-moreandroid:before { + content: "\e6a5"; +} + +.cuIcon-deletefill:before { + content: "\e6a6"; +} + +.cuIcon-refund:before { + content: "\e6ac"; +} + +.cuIcon-cart:before { + content: "\e6af"; +} + +.cuIcon-qrcode:before { + content: "\e6b0"; +} + +.cuIcon-remind:before { + content: "\e6b2"; +} + +.cuIcon-delete:before { + content: "\e6b4"; +} + +.cuIcon-profile:before { + content: "\e6b7"; +} + +.cuIcon-home:before { + content: "\e6b8"; +} + +.cuIcon-cartfill:before { + content: "\e6b9"; +} + +.cuIcon-discoverfill:before { + content: "\e6ba"; +} + +.cuIcon-homefill:before { + content: "\e6bb"; +} + +.cuIcon-message:before { + content: "\e6bc"; +} + +.cuIcon-addressbook:before { + content: "\e6bd"; +} + +.cuIcon-link:before { + content: "\e6bf"; +} + +.cuIcon-lock:before { + content: "\e6c0"; +} + +.cuIcon-unlock:before { + content: "\e6c2"; +} + +.cuIcon-vip:before { + content: "\e6c3"; +} + +.cuIcon-weibo:before { + content: "\e6c4"; +} + +.cuIcon-activity:before { + content: "\e6c5"; +} + +.cuIcon-friendaddfill:before { + content: "\e6c9"; +} + +.cuIcon-friendadd:before { + content: "\e6ca"; +} + +.cuIcon-friendfamous:before { + content: "\e6cb"; +} + +.cuIcon-friend:before { + content: "\e6cc"; +} + +.cuIcon-goods:before { + content: "\e6cd"; +} + +.cuIcon-selection:before { + content: "\e6ce"; +} + +.cuIcon-explore:before { + content: "\e6d2"; +} + +.cuIcon-present:before { + content: "\e6d3"; +} + +.cuIcon-squarecheckfill:before { + content: "\e6d4"; +} + +.cuIcon-square:before { + content: "\e6d5"; +} + +.cuIcon-squarecheck:before { + content: "\e6d6"; +} + +.cuIcon-round:before { + content: "\e6d7"; +} + +.cuIcon-roundaddfill:before { + content: "\e6d8"; +} + +.cuIcon-roundadd:before { + content: "\e6d9"; +} + +.cuIcon-add:before { + content: "\e6da"; +} + +.cuIcon-notificationforbidfill:before { + content: "\e6db"; +} + +.cuIcon-explorefill:before { + content: "\e6dd"; +} + +.cuIcon-fold:before { + content: "\e6de"; +} + +.cuIcon-game:before { + content: "\e6df"; +} + +.cuIcon-redpacket:before { + content: "\e6e0"; +} + +.cuIcon-selectionfill:before { + content: "\e6e1"; +} + +.cuIcon-similar:before { + content: "\e6e2"; +} + +.cuIcon-appreciatefill:before { + content: "\e6e3"; +} + +.cuIcon-infofill:before { + content: "\e6e4"; +} + +.cuIcon-info:before { + content: "\e6e5"; +} + +.cuIcon-forwardfill:before { + content: "\e6ea"; +} + +.cuIcon-forward:before { + content: "\e6eb"; +} + +.cuIcon-rechargefill:before { + content: "\e6ec"; +} + +.cuIcon-recharge:before { + content: "\e6ed"; +} + +.cuIcon-vipcard:before { + content: "\e6ee"; +} + +.cuIcon-voice:before { + content: "\e6ef"; +} + +.cuIcon-voicefill:before { + content: "\e6f0"; +} + +.cuIcon-friendfavor:before { + content: "\e6f1"; +} + +.cuIcon-wifi:before { + content: "\e6f2"; +} + +.cuIcon-share:before { + content: "\e6f3"; +} + +.cuIcon-wefill:before { + content: "\e6f4"; +} + +.cuIcon-we:before { + content: "\e6f5"; +} + +.cuIcon-lightauto:before { + content: "\e6f6"; +} + +.cuIcon-lightforbid:before { + content: "\e6f7"; +} + +.cuIcon-lightfill:before { + content: "\e6f8"; +} + +.cuIcon-camerarotate:before { + content: "\e6f9"; +} + +.cuIcon-light:before { + content: "\e6fa"; +} + +.cuIcon-barcode:before { + content: "\e6fb"; +} + +.cuIcon-flashlightclose:before { + content: "\e6fc"; +} + +.cuIcon-flashlightopen:before { + content: "\e6fd"; +} + +.cuIcon-searchlist:before { + content: "\e6fe"; +} + +.cuIcon-service:before { + content: "\e6ff"; +} + +.cuIcon-sort:before { + content: "\e700"; +} + +.cuIcon-down:before { + content: "\e703"; +} + +.cuIcon-mobile:before { + content: "\e704"; +} + +.cuIcon-mobilefill:before { + content: "\e705"; +} + +.cuIcon-copy:before { + content: "\e706"; +} + +.cuIcon-countdownfill:before { + content: "\e707"; +} + +.cuIcon-countdown:before { + content: "\e708"; +} + +.cuIcon-noticefill:before { + content: "\e709"; +} + +.cuIcon-notice:before { + content: "\e70a"; +} + +.cuIcon-upstagefill:before { + content: "\e70e"; +} + +.cuIcon-upstage:before { + content: "\e70f"; +} + +.cuIcon-babyfill:before { + content: "\e710"; +} + +.cuIcon-baby:before { + content: "\e711"; +} + +.cuIcon-brandfill:before { + content: "\e712"; +} + +.cuIcon-brand:before { + content: "\e713"; +} + +.cuIcon-choicenessfill:before { + content: "\e714"; +} + +.cuIcon-choiceness:before { + content: "\e715"; +} + +.cuIcon-clothesfill:before { + content: "\e716"; +} + +.cuIcon-clothes:before { + content: "\e717"; +} + +.cuIcon-creativefill:before { + content: "\e718"; +} + +.cuIcon-creative:before { + content: "\e719"; +} + +.cuIcon-female:before { + content: "\e71a"; +} + +.cuIcon-keyboard:before { + content: "\e71b"; +} + +.cuIcon-male:before { + content: "\e71c"; +} + +.cuIcon-newfill:before { + content: "\e71d"; +} + +.cuIcon-new:before { + content: "\e71e"; +} + +.cuIcon-pullleft:before { + content: "\e71f"; +} + +.cuIcon-pullright:before { + content: "\e720"; +} + +.cuIcon-rankfill:before { + content: "\e721"; +} + +.cuIcon-rank:before { + content: "\e722"; +} + +.cuIcon-bad:before { + content: "\e723"; +} + +.cuIcon-cameraadd:before { + content: "\e724"; +} + +.cuIcon-focus:before { + content: "\e725"; +} + +.cuIcon-friendfill:before { + content: "\e726"; +} + +.cuIcon-cameraaddfill:before { + content: "\e727"; +} + +.cuIcon-apps:before { + content: "\e729"; +} + +.cuIcon-paintfill:before { + content: "\e72a"; +} + +.cuIcon-paint:before { + content: "\e72b"; +} + +.cuIcon-picfill:before { + content: "\e72c"; +} + +.cuIcon-refresharrow:before { + content: "\e72d"; +} + +.cuIcon-colorlens:before { + content: "\e6e6"; +} + +.cuIcon-markfill:before { + content: "\e730"; +} + +.cuIcon-mark:before { + content: "\e731"; +} + +.cuIcon-presentfill:before { + content: "\e732"; +} + +.cuIcon-repeal:before { + content: "\e733"; +} + +.cuIcon-album:before { + content: "\e734"; +} + +.cuIcon-peoplefill:before { + content: "\e735"; +} + +.cuIcon-people:before { + content: "\e736"; +} + +.cuIcon-servicefill:before { + content: "\e737"; +} + +.cuIcon-repair:before { + content: "\e738"; +} + +.cuIcon-file:before { + content: "\e739"; +} + +.cuIcon-repairfill:before { + content: "\e73a"; +} + +.cuIcon-taoxiaopu:before { + content: "\e73b"; +} + +.cuIcon-weixin:before { + content: "\e612"; +} + +.cuIcon-attentionfill:before { + content: "\e73c"; +} + +.cuIcon-attention:before { + content: "\e73d"; +} + +.cuIcon-commandfill:before { + content: "\e73e"; +} + +.cuIcon-command:before { + content: "\e73f"; +} + +.cuIcon-communityfill:before { + content: "\e740"; +} + +.cuIcon-community:before { + content: "\e741"; +} + +.cuIcon-read:before { + content: "\e742"; +} + +.cuIcon-calendar:before { + content: "\e74a"; +} + +.cuIcon-cut:before { + content: "\e74b"; +} + +.cuIcon-magic:before { + content: "\e74c"; +} + +.cuIcon-backwardfill:before { + content: "\e74d"; +} + +.cuIcon-playfill:before { + content: "\e74f"; +} + +.cuIcon-stop:before { + content: "\e750"; +} + +.cuIcon-tagfill:before { + content: "\e751"; +} + +.cuIcon-tag:before { + content: "\e752"; +} + +.cuIcon-group:before { + content: "\e753"; +} + +.cuIcon-all:before { + content: "\e755"; +} + +.cuIcon-backdelete:before { + content: "\e756"; +} + +.cuIcon-hotfill:before { + content: "\e757"; +} + +.cuIcon-hot:before { + content: "\e758"; +} + +.cuIcon-post:before { + content: "\e759"; +} + +.cuIcon-radiobox:before { + content: "\e75b"; +} + +.cuIcon-rounddown:before { + content: "\e75c"; +} + +.cuIcon-upload:before { + content: "\e75d"; +} + +.cuIcon-writefill:before { + content: "\e760"; +} + +.cuIcon-write:before { + content: "\e761"; +} + +.cuIcon-radioboxfill:before { + content: "\e763"; +} + +.cuIcon-punch:before { + content: "\e764"; +} + +.cuIcon-shake:before { + content: "\e765"; +} + +.cuIcon-move:before { + content: "\e768"; +} + +.cuIcon-safe:before { + content: "\e769"; +} + +.cuIcon-activityfill:before { + content: "\e775"; +} + +.cuIcon-crownfill:before { + content: "\e776"; +} + +.cuIcon-crown:before { + content: "\e777"; +} + +.cuIcon-goodsfill:before { + content: "\e778"; +} + +.cuIcon-messagefill:before { + content: "\e779"; +} + +.cuIcon-profilefill:before { + content: "\e77a"; +} + +.cuIcon-sound:before { + content: "\e77b"; +} + +.cuIcon-sponsorfill:before { + content: "\e77c"; +} + +.cuIcon-sponsor:before { + content: "\e77d"; +} + +.cuIcon-upblock:before { + content: "\e77e"; +} + +.cuIcon-weblock:before { + content: "\e77f"; +} + +.cuIcon-weunblock:before { + content: "\e780"; +} + +.cuIcon-my:before { + content: "\e78b"; +} + +.cuIcon-myfill:before { + content: "\e78c"; +} + +.cuIcon-emojifill:before { + content: "\e78d"; +} + +.cuIcon-emojiflashfill:before { + content: "\e78e"; +} + +.cuIcon-flashbuyfill:before { + content: "\e78f"; +} + +.cuIcon-text:before { + content: "\e791"; +} + +.cuIcon-goodsfavor:before { + content: "\e794"; +} + +.cuIcon-musicfill:before { + content: "\e795"; +} + +.cuIcon-musicforbidfill:before { + content: "\e796"; +} + +.cuIcon-card:before { + content: "\e624"; +} + +.cuIcon-triangledownfill:before { + content: "\e79b"; +} + +.cuIcon-triangleupfill:before { + content: "\e79c"; +} + +.cuIcon-roundleftfill-copy:before { + content: "\e79e"; +} + +.cuIcon-font:before { + content: "\e76a"; +} + +.cuIcon-title:before { + content: "\e82f"; +} + +.cuIcon-recordfill:before { + content: "\e7a4"; +} + +.cuIcon-record:before { + content: "\e7a6"; +} + +.cuIcon-cardboardfill:before { + content: "\e7a9"; +} + +.cuIcon-cardboard:before { + content: "\e7aa"; +} + +.cuIcon-formfill:before { + content: "\e7ab"; +} + +.cuIcon-coin:before { + content: "\e7ac"; +} + +.cuIcon-cardboardforbid:before { + content: "\e7af"; +} + +.cuIcon-circlefill:before { + content: "\e7b0"; +} + +.cuIcon-circle:before { + content: "\e7b1"; +} + +.cuIcon-attentionforbid:before { + content: "\e7b2"; +} + +.cuIcon-attentionforbidfill:before { + content: "\e7b3"; +} + +.cuIcon-attentionfavorfill:before { + content: "\e7b4"; +} + +.cuIcon-attentionfavor:before { + content: "\e7b5"; +} + +.cuIcon-titles:before { + content: "\e701"; +} + +.cuIcon-icloading:before { + content: "\e67a"; +} + +.cuIcon-full:before { + content: "\e7bc"; +} + +.cuIcon-mail:before { + content: "\e7bd"; +} + +.cuIcon-peoplelist:before { + content: "\e7be"; +} + +.cuIcon-goodsnewfill:before { + content: "\e7bf"; +} + +.cuIcon-goodsnew:before { + content: "\e7c0"; +} + +.cuIcon-medalfill:before { + content: "\e7c1"; +} + +.cuIcon-medal:before { + content: "\e7c2"; +} + +.cuIcon-newsfill:before { + content: "\e7c3"; +} + +.cuIcon-newshotfill:before { + content: "\e7c4"; +} + +.cuIcon-newshot:before { + content: "\e7c5"; +} + +.cuIcon-news:before { + content: "\e7c6"; +} + +.cuIcon-videofill:before { + content: "\e7c7"; +} + +.cuIcon-video:before { + content: "\e7c8"; +} + +.cuIcon-exit:before { + content: "\e7cb"; +} + +.cuIcon-skinfill:before { + content: "\e7cc"; +} + +.cuIcon-skin:before { + content: "\e7cd"; +} + +.cuIcon-moneybagfill:before { + content: "\e7ce"; +} + +.cuIcon-usefullfill:before { + content: "\e7cf"; +} + +.cuIcon-usefull:before { + content: "\e7d0"; +} + +.cuIcon-moneybag:before { + content: "\e7d1"; +} + +.cuIcon-redpacket_fill:before { + content: "\e7d3"; +} + +.cuIcon-subscription:before { + content: "\e7d4"; +} + +.cuIcon-loading1:before { + content: "\e633"; +} + +.cuIcon-github:before { + content: "\e692"; +} + +.cuIcon-global:before { + content: "\e7eb"; +} + +.cuIcon-settingsfill:before { + content: "\e6ab"; +} + +.cuIcon-back_android:before { + content: "\e7ed"; +} + +.cuIcon-expressman:before { + content: "\e7ef"; +} + +.cuIcon-evaluate_fill:before { + content: "\e7f0"; +} + +.cuIcon-group_fill:before { + content: "\e7f5"; +} + +.cuIcon-play_forward_fill:before { + content: "\e7f6"; +} + +.cuIcon-deliver_fill:before { + content: "\e7f7"; +} + +.cuIcon-notice_forbid_fill:before { + content: "\e7f8"; +} + +.cuIcon-fork:before { + content: "\e60c"; +} + +.cuIcon-pick:before { + content: "\e7fa"; +} + +.cuIcon-wenzi:before { + content: "\e6a7"; +} + +.cuIcon-ellipse:before { + content: "\e600"; +} + +.cuIcon-qr_code:before { + content: "\e61b"; +} + +.cuIcon-dianhua:before { + content: "\e64d"; +} + +.cuIcon-icon:before { + content: "\e602"; +} + +.cuIcon-loading2:before { + content: "\e7f1"; +} + +.cuIcon-btn:before { + content: "\e601"; +} diff --git a/colorui/main.wxss b/colorui/main.wxss new file mode 100644 index 0000000..21dd2d1 --- /dev/null +++ b/colorui/main.wxss @@ -0,0 +1,1546 @@ +/* + ColorUi for MP-weixin v2.1.4 | by 文晓港 2019年4月25日19:15:42 + 仅供学习交流,如作它用所承受的法律责任一概与作者无关 + 使用ColorUi开发扩展与插件时,请注明基于ColorUi开发 + + (QQ交流群:240787041) +*/ + +/* ================== + 初始化 + ==================== */ + +page { + /* Color 可以自定义相关配色 *//* var属性兼容性 --> https://www.caniuse.com/#feat=css-variables *//* 标准色 */ + --red: #e54d42; + --orange: #f37b1d; + --yellow: #fbbd08; + --olive: #8dc63f; + --green: #39b54a; + --cyan: #1cbbb4; + --blue: #008AFF; + --purple: #6739b6; + --mauve: #9c26b0; + --pink: #e03997; + --brown: #a5673f; + --grey: #8799a3; + --black: #333; + --darkGray: #666; + --gray: #aaa; + --ghostWhite: #f1f1f1; + --white: #fff; + /* 浅色 */ + --redLight: #fadbd9; + --orangeLight: #fde6d2; + --yellowLight: #fef2ce; + --oliveLight: #e8f4d9; + --greenLight: #d7f0db; + --cyanLight: #d2f1f0; + --blueLight: #cce6ff; + --purpleLight: #e1d7f0; + --mauveLight: #ebd4ef; + --pinkLight: #f9d7ea; + --brownLight: #ede1d9; + --greyLight: #e7ebed; + /* 渐变色 */ + --gradualRed: linear-gradient(45deg, #f43f3b, #ec008c); + --gradualOrange: linear-gradient(45deg, #ff9700, #ed1c24); + --gradualGreen: linear-gradient(45deg, #39b54a, #8dc63f); + --gradualPurple: linear-gradient(45deg, #9000ff, #5e00ff); + --gradualPink: linear-gradient(45deg, #ec008c, #6739b6); + --gradualBlue: linear-gradient(45deg, #009ee0, #009ee0); + /* 阴影透明色 */ + --ShadowSize: 6rpx 6rpx 8rpx; + --redShadow: rgba(204, 69, 59, 0.2); + --orangeShadow: rgba(217, 109, 26, 0.2); + --yellowShadow: rgba(224, 170, 7, 0.2); + --oliveShadow: rgba(124, 173, 55, 0.2); + --greenShadow: rgba(48, 156, 63, 0.2); + --cyanShadow: rgba(28, 187, 180, 0.2); + --blueShadow: rgba(0, 102, 204, 0.2); + --purpleShadow: rgba(88, 48, 156, 0.2); + --mauveShadow: rgba(133, 33, 150, 0.2); + --pinkShadow: rgba(199, 50, 134, 0.2); + --brownShadow: rgba(140, 88, 53, 0.2); + --greyShadow: rgba(114, 130, 138, 0.2); + --grayShadow: rgba(114, 130, 138, 0.2); + --blackShadow: rgba(26, 26, 26, 0.2); + background-color: var(--ghostWhite); + font-size: 28rpx; + color: var(--black); + font-family: Helvetica Neue, Helvetica, sans-serif; +} + +view, scroll-view, swiper, button, input, textarea, label, navigator, image { + box-sizing: border-box; +} + +.round { + border-radius: 5000rpx; +} + +.radius { + border-radius: 6rpx; +} + +.bg-white{ + background-color: white; +} +/* ================== + 边框 + ==================== */ + +/* -- 实线 -- */ + +.solid, .solid-top, .solid-right, .solid-bottom, .solid-left, .solids, +.solids-top, .solids-right, .solids-bottom, .solids-left, .dashed, .dashed-top, +.dashed-right, .dashed-bottom, .dashed-left { + position: relative; +} + +.solid::after, .solid-top::after, .solid-right::after, .solid-bottom::after, +.solid-left::after, .solids::after, .solids-top::after, .solids-right::after, +.solids-bottom::after, .solids-left::after, .dashed::after, .dashed-top::after, +.dashed-right::after, .dashed-bottom::after, .dashed-left::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border-radius: inherit; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; +} + +.solid::after { + border: 1rpx solid rgba(0, 0, 0, 0.1); +} + +.solid-top::after { + border-top: 1rpx solid rgba(0, 0, 0, 0.1); +} + +.solid-right::after { + border-right: 1rpx solid rgba(0, 0, 0, 0.1); +} + +.solid-bottom::after { + border-bottom: 1rpx solid rgba(0, 0, 0, 0.1); +} + +.solid-left::after { + border-left: 1rpx solid rgba(0, 0, 0, 0.1); +} + +.solids::after { + border: 8rpx solid #eee; +} + +.solids-top::after { + border-top: 8rpx solid #eee; +} + +.solids-right::after { + border-right: 8rpx solid #eee; +} + +.solids-bottom::after { + border-bottom: 8rpx solid #eee; +} + +.solids-left::after { + border-left: 8rpx solid #eee; +} + +/* -- 虚线 -- */ + +.dashed::after { + border: 1rpx dashed #ddd; +} + +.dashed-top::after { + border-top: 1rpx dashed #ddd; +} + +.dashed-right::after { + border-right: 1rpx dashed #ddd; +} + +.dashed-bottom::after { + border-bottom: 1rpx dashed #ddd; +} + +.dashed-left::after { + border-left: 1rpx dashed #ddd; +} + +/* -- 阴影 -- */ + +.shadow[class*='white'] { + --ShadowSize: 0 1rpx 6rpx; +} + +.shadow-lg { + --ShadowSize: 0rpx 40rpx 100rpx 0rpx; +} + +.shadow-warp { + position: relative; + box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1); +} + +.shadow-warp:before, .shadow-warp:after { + position: absolute; + content: ""; + top: 20rpx; + bottom: 30rpx; + left: 20rpx; + width: 50%; + box-shadow: 0 30rpx 20rpx rgba(0, 0, 0, 0.2); + transform: rotate(-3deg); + z-index: -1; +} + +.shadow-warp:after { + right: 20rpx; + left: auto; + transform: rotate(3deg); +} + +.shadow-blur { + position: relative; +} + +.shadow-blur::before { + content: ""; + display: block; + background: inherit; + filter: blur(10rpx); + position: absolute; + width: 100%; + height: 100%; + top: 10rpx; + left: 10rpx; + z-index: -1; + opacity: 0.4; + transform-origin: 0 0; + border-radius: inherit; + transform: scale(1, 1); +} +/* ================== + 徽章 + ==================== */ + +.cu-tag { + font-size: 24rpx; + vertical-align: middle; + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 0rpx 16rpx; + height: 48rpx; + font-family: Helvetica Neue, Helvetica, sans-serif; + white-space: nowrap; +} + +.cu-tag:not([class*="bg"]):not([class*="line"]) { + background-color: var(--ghostWhite); +} + +.cu-tag[class*="line-"]::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1rpx solid currentColor; + transform: scale(0.5); + transform-origin: 0 0; + box-sizing: border-box; + border-radius: inherit; + z-index: 1; + pointer-events: none; +} + +.cu-tag.radius[class*="line"]::after { + border-radius: 12rpx; +} + +.cu-tag.round[class*="line"]::after { + border-radius: 1000rpx; +} + +.cu-tag[class*="line-"]::after { + border-radius: 0; +} + +.cu-tag+.cu-tag { + margin-left: 10rpx; +} + +.cu-tag.sm { + font-size: 20rpx; + padding: 0rpx 12rpx; + height: 32rpx; +} + +.cu-capsule { + display: inline-flex; + vertical-align: middle; +} + +.cu-capsule+.cu-capsule { + margin-left: 10rpx; +} + +.cu-capsule .cu-tag { + margin: 0; +} + +.cu-capsule .cu-tag[class*="line-"]:last-child::after { + border-left: 0rpx solid transparent; +} + +.cu-capsule .cu-tag[class*="line-"]:first-child::after { + border-right: 0rpx solid transparent; +} + +.cu-capsule.radius .cu-tag:first-child { + border-top-left-radius: 6rpx; + border-bottom-left-radius: 6rpx; +} + +.cu-capsule.radius .cu-tag:last-child::after, +.cu-capsule.radius .cu-tag[class*="line-"] { + border-top-right-radius: 12rpx; + border-bottom-right-radius: 12rpx; +} + +.cu-capsule.round .cu-tag:first-child { + border-top-left-radius: 200rpx; + border-bottom-left-radius: 200rpx; + text-indent: 4rpx; +} + +.cu-capsule.round .cu-tag:last-child::after, +.cu-capsule.round .cu-tag:last-child { + border-top-right-radius: 200rpx; + border-bottom-right-radius: 200rpx; + text-indent: -4rpx; +} + +.cu-tag.badge { + border-radius: 200rpx; + position: absolute; + /* top: -10rpx; */ + /* right: -10rpx; */ + font-size: 20rpx; + padding: 0rpx 10rpx; + height: 30rpx; + color: var(--white); +} + +.cu-tag.badge:not([class*="bg-"]) { + background-color: #dd514c; +} + +.cu-tag:empty:not([class*="cuIcon-"]) { + padding: 0rpx; + width: 16rpx; + height: 16rpx; + top: -4rpx; + right: -4rpx; +} + +.cu-tag[class*="cuIcon-"] { + width: 32rpx; + height: 32rpx; + top: -4rpx; + right: -4rpx; +} + +/* ================== + 头像 + ==================== */ + +.cu-avatar { + font-variant: small-caps; + margin: 0; + padding: 0; + display: inline-flex; + text-align: center; + justify-content: center; + align-items: center; + background-color: #ccc; + color: var(--white); + white-space: nowrap; + position: relative; + width: 64rpx; + height: 64rpx; + background-size: cover; + background-position: center; + vertical-align: middle; + font-size: 1.5em; +} + +.cu-avatar.sm { + width: 48rpx; + height: 48rpx; + font-size: 1em; +} + +.cu-avatar.lg { + width: 96rpx; + height: 96rpx; + font-size: 2em; +} + +.cu-avatar.slg { + width: 60rpx; + height: 60rpx; + font-size: 2em; +} + +.cu-avatar.xl { + width: 128rpx; + height: 128rpx; + font-size: 2.5em; +} + +.cu-avatar .avatar-text { + font-size: 0.4em; +} + +.cu-avatar-group { + direction: rtl; + unicode-bidi: bidi-override; + padding: 0 10rpx 0 40rpx; + display: inline-block; +} + +.cu-avatar-group .cu-avatar { + margin-left: -30rpx; + border: 4rpx solid var(--ghostWhite); + vertical-align: middle; +} + +.cu-avatar-group .cu-avatar.sm { + margin-left: -20rpx; + border: 1rpx solid var(--ghostWhite); +} + +/* ================== + 操作条 + ==================== */ + +.cu-bar { + display: flex; + position: relative; + align-items: center; + min-height: 100rpx; + justify-content: space-between; +} + +.cu-bar .action { + display: flex; + align-items: center; + height: 100%; + justify-content: center; + max-width: 100%; +} + +.cu-bar .action.border-title { + position: relative; + top: -10rpx; +} + +.cu-bar .action.border-title text[class*="bg-"]:last-child { + position: absolute; + bottom: -0.5rem; + min-width: 2rem; + height: 6rpx; + left: 0; +} + +.cu-bar .action.sub-title { + position: relative; + top: -0.2rem; +} + +.cu-bar .action.sub-title text { + position: relative; + z-index: 1; +} + +.cu-bar .action.sub-title text[class*="bg-"]:last-child { + position: absolute; + display: inline-block; + bottom: -0.2rem; + border-radius: 6rpx; + width: 100%; + height: 0.6rem; + left: 0.6rem; + opacity: 0.3; + z-index: 0; +} + +.cu-bar .action.sub-title text[class*="text-"]:last-child { + position: absolute; + display: inline-block; + bottom: -0.7rem; + left: 0.5rem; + opacity: 0.2; + z-index: 0; + text-align: right; + font-weight: 900; + font-size: 36rpx; +} + +.cu-bar.justify-center .action.border-title text:last-child, +.cu-bar.justify-center .action.sub-title text:last-child { + left: 0; + right: 0; + margin: auto; + text-align: center; +} + +.cu-bar .action:first-child { + margin-left: 30rpx; + font-size: 30rpx; +} + +.cu-bar .action text.text-cut { + text-align: left; + width: 100%; +} + +.cu-bar .cu-avatar:first-child { + margin-left: 20rpx; +} + +.cu-bar .action:first-child>text[class*="cuIcon-"] { + margin-left: -0.3em; + /* margin-right: 0.3em; */ +} + +.cu-bar .action:last-child { + margin-right: 30rpx; +} + +.cu-bar .action>text[class*="cuIcon-"], .cu-bar .action>view[class*="cuIcon-"] { + font-size: 36rpx; +} + +.cu-bar .action>text[class*="cuIcon-"]+text[class*="cuIcon-"] { + margin-left: 0.5em; +} + +.cu-bar .content { + position: absolute; + text-align: center; + width: calc(100% - 340rpx); + left: 0; + right: 0; + bottom: 0; + top: 0; + margin: auto; + height: 60rpx; + font-size: 32rpx; + line-height: 60rpx; + cursor: none; + pointer-events: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.cu-bar.ios .content { + bottom: 7px; + height: 30px; + font-size: 32rpx; + line-height: 30px; +} + +.cu-bar.btn-group { + justify-content: space-around; +} + +.cu-bar.btn-group button { + padding: 20rpx 32rpx; +} + +.cu-bar.btn-group button { + flex: 1; + margin: 0 20rpx; + max-width: 50%; +} + +.cu-bar .search-form { + background-color: #f5f5f5; + line-height: 64rpx; + height: 64rpx; + font-size: 24rpx; + color: var(--black); + flex: 1; + display: flex; + align-items: center; + margin: 0 24rpx; +} + +.cu-bar .search-form+.action { + margin-right: 20rpx; +} + +.cu-bar .search-form input { + flex: 1; + padding-right: 30rpx; + height: 72rpx; + line-height: 72rpx; + font-size: 30rpx; + background-color: transparent; +} + +.cu-bar .search-form [class*="cuIcon-"] { + margin: 0 0.5em 0 0.8em; +} + +.cu-bar .search-form [class*="cuIcon-"]::before { + top: 0rpx; +} + +.cu-bar.fixed, .nav.fixed { + position: fixed; + width: 100%; + top: 0; + z-index: 19; + box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1); +} + +.cu-bar.foot { + position: fixed; + width: 100%; + bottom: 0; + z-index: 9; + /* box-shadow: 0 -1rpx 6rpx rgba(0, 0, 0, 0.1); */ +} + +.cu-bar.tabbar { + padding: 0; + height: calc(100rpx + env(safe-area-inset-bottom) / 2); + padding-bottom: calc(env(safe-area-inset-bottom) / 2); +} + +.cu-tabbar-height { + min-height: 100rpx; + height: calc(100rpx + env(safe-area-inset-bottom) / 2); +} + +.cu-bar.tabbar.shadow { + box-shadow: 0 -1rpx 6rpx rgba(0, 0, 0, 0.1); +} + +.cu-bar.tabbar .action { + font-size: 22rpx; + position: relative; + flex: 1; + text-align: center; + padding: 0; + display: block; + height: auto; + line-height: 1; + margin: 0; + overflow: initial; +} + +.cu-bar.tabbar.shop .action { + width: 140rpx; + flex: initial; +} + +.cu-bar.tabbar .action.add-action { + position: relative; + z-index: 2; + padding-top: 50rpx; + background-color: inherit; +} + +.cu-bar.tabbar .action.add-action [class*="cuIcon-"] { + position: absolute; + width: 70rpx; + z-index: 2; + height: 70rpx; + border-radius: 50%; + line-height: 70rpx; + font-size: 50rpx; + top: -35rpx; + left: 0; + right: 0; + margin: auto; + padding: 0; +} + +.cu-bar.tabbar .action.add-action::after { + content: ""; + position: absolute; + width: 140rpx; + height: 140rpx; + top: -45rpx; + left: 0; + right: 0; + margin: auto; + box-shadow: 0 -3rpx 8rpx rgba(0, 0, 0, 0.08); + border-radius: 70rpx; + background-color: inherit; + z-index: 0; +} + +.cu-bar.tabbar .action.add-action::before { + content: ""; + position: absolute; + width: 100rpx; + height: 30rpx; + bottom: 30rpx; + left: 0; + right: 0; + margin: auto; + background-color: inherit; + z-index: 1; +} + +.cu-bar.tabbar .btn-group { + flex: 1; + display: flex; + justify-content: space-around; + align-items: center; + padding: 0 10rpx; +} + +.cu-bar.tabbar button.action::after { + border: 0; +} + +.cu-bar.tabbar .action [class*="cuIcon-"] { + width: 100rpx; + position: relative; + display: block; + height: auto; + margin: 0 auto 10rpx; + text-align: center; + font-size: 40rpx; +} + +.cu-bar.tabbar .action .cuIcon-cu-image { + margin: 0 auto; +} + +.cu-bar.tabbar .action .cuIcon-cu-image image { + width: 50rpx; + height: 50rpx; + display: inline-block; +} + +.cu-bar.tabbar .submit { + align-items: center; + display: flex; + justify-content: center; + text-align: center; + position: relative; + flex: 2; + align-self: stretch; +} + +.cu-bar.tabbar .submit:last-child { + flex: 2.6; +} + +.cu-bar.tabbar .submit+.submit { + flex: 2; +} + +.cu-bar.tabbar.border .action::before { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + transform: scale(0.5); + transform-origin: 0 0; + border-right: 1rpx solid rgba(0, 0, 0, 0.1); + z-index: 3; +} + +.cu-bar.tabbar.border .action:last-child:before { + display: none; +} + +.cu-bar.input { + padding-right: 20rpx; + background-color: var(--white); +} + +.cu-bar.input input { + overflow: initial; + line-height: 64rpx; + height: 64rpx; + min-height: 64rpx; + flex: 1; + font-size: 30rpx; + margin: 0 20rpx; +} + +.cu-bar.input .action { + margin-left: 20rpx; +} + +.cu-bar.input .action [class*="cuIcon-"] { + font-size: 48rpx; +} + +.cu-bar.input input+.action { + margin-right: 20rpx; + margin-left: 0rpx; +} + +.cu-bar.input .action:first-child [class*="cuIcon-"] { + margin-left: 0rpx; +} + +.cu-custom { + display: block; + position: relative; +} + +.cu-custom .cu-bar .content { + width: calc(100% - 440rpx); +} + +.cu-custom .cu-bar .content image { + height: 60rpx; + width: 240rpx; +} + +.cu-custom .cu-bar { + min-height: 0px; + padding-right: 220rpx; + z-index: 99; + /* box-shadow: 0rpx 0rpx 0rpx; */ + box-shadow: 0 -1rpx 4rpx rgba(0, 0, 0, 0.04) +} + +.cu-custom .cu-bar .border-custom { + position: relative; + background: rgba(0, 0, 0, 0.15); + border-radius: 1000rpx; + height: 30px; +} + +.cu-custom .cu-bar .border-custom::after { + content: " "; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border-radius: inherit; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; + border: 1rpx solid var(--white); + opacity: 0.5; +} + +.cu-custom .cu-bar .border-custom::before { + content: " "; + width: 1rpx; + height: 110%; + position: absolute; + top: 22.5%; + left: 0; + right: 0; + margin: auto; + transform: scale(0.5); + transform-origin: 0 0; + pointer-events: none; + box-sizing: border-box; + opacity: 0.6; + background-color: var(--white); +} + +.cu-custom .cu-bar .border-custom text { + display: block; + flex: 1; + margin: auto !important; + text-align: center; + font-size: 34rpx; +} + +/* ================== + 导航栏 + ==================== */ + +.nav { + white-space: nowrap; +} + +::-webkit-scrollbar { + display: none; +} + +.nav .cu-item { + height: 90rpx; + display: inline-block; + line-height: 90rpx; + margin: 0 10rpx; + padding: 0 20rpx; +} + +.nav .cu-item.cur { + border-bottom: 4rpx solid; +} +/* ================== + 表单 + ==================== */ + +.cu-form-group { + background-color: var(--white); + padding: 1rpx 30rpx; + display: flex; + align-items: center; + min-height: 100rpx; + justify-content: space-between; +} + +.cu-form-group+.cu-form-group { + border-top: 1rpx solid #eee; +} + +.cu-form-group .title { + text-align: justify; + /* padding-right: 30rpx; */ + font-size: 30rpx; + position: relative; + height: 60rpx; + line-height: 60rpx; +} + +.cu-form-group input { + flex: 1; + font-size: 30rpx; + color: #555; + padding-right: 20rpx; +} + +.cu-form-group>text[class*="cuIcon-"] { + font-size: 36rpx; + padding: 0; + box-sizing: border-box; +} + +.cu-form-group textarea { + margin: 32rpx 0 30rpx; + height: 4.6em; + width: 100%; + line-height: 1.2em; + flex: 1; + font-size: 28rpx; + padding: 0; +} + +.cu-form-group.align-start .title { + height: 1em; + margin-top: 32rpx; + line-height: 1em; +} + +.cu-form-group picker { + flex: 1; + padding-right: 40rpx; + overflow: hidden; + position: relative; +} + +.cu-form-group picker .picker { + line-height: 100rpx; + font-size: 28rpx; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + width: 100%; + text-align: right; +} + +.cu-form-group picker::after { + font-family: "cuIcon"; + display: block; + content: "\e6a3"; + position: absolute; + font-size: 34rpx; + color: var(--grey); + line-height: 100rpx; + width: 60rpx; + text-align: center; + top: 0; + bottom: 0; + right: -20rpx; + margin: auto; +} + +.cu-form-group textarea[disabled], +.cu-form-group textarea[disabled] .placeholder { + color: transparent; +} + +/* ================== + 轮播 + ==================== */ + +swiper .a-swiper-dot { + display: inline-block; + width: 16rpx; + height: 16rpx; + background: rgba(0, 0, 0, 0.3); + border-radius: 50%; + vertical-align: middle; +} + +swiper[class*="-dot"] .wx-swiper-dots { + display: flex; + align-items: center; + width: 100%; + justify-content: center; +} + +swiper.square-dot .wx-swiper-dot { + background-color: var(--white); + opacity: 0.4; + width: 10rpx; + height: 10rpx; + border-radius: 20rpx; + margin: 0 8rpx !important; +} + +swiper.square-dot .wx-swiper-dot.wx-swiper-dot-active { + opacity: 1; + width: 30rpx; +} + +swiper.round-dot .wx-swiper-dot { + width: 10rpx; + height: 10rpx; + position: relative; + margin: 4rpx 8rpx !important; +} + +swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active::after { + content: ""; + position: absolute; + width: 10rpx; + height: 10rpx; + top: 0rpx; + left: 0rpx; + right: 0; + bottom: 0; + margin: auto; + background-color: var(--white); + border-radius: 20rpx; +} + +swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active { + width: 18rpx; + height: 18rpx; +} + +.screen-swiper { + min-height: 300rpx; +} + +.screen-swiper image, .screen-swiper video, .swiper-item image, +.swiper-item video { + width: 100%; + display: block; + height: 100%; + margin: 0; + pointer-events: none; +} + +.card-swiper { + height: 420rpx !important; +} + +.card-swiper swiper-item { + width: 610rpx !important; + left: 70rpx; + box-sizing: border-box; + padding: 40rpx 0rpx 70rpx; + overflow: initial; +} + +.card-swiper swiper-item .swiper-item { + width: 100%; + display: block; + height: 100%; + border-radius: 10rpx; + transform: scale(0.9); + transition: all 0.2s ease-in 0s; + overflow: hidden; +} + +.card-swiper swiper-item.cur .swiper-item { + transform: none; + transition: all 0.2s ease-in 0s; +} + +.tower-swiper { + height: 420rpx; + position: relative; + max-width: 750rpx; + overflow: hidden; +} + +.tower-swiper .tower-item { + position: absolute; + width: 300rpx; + height: 380rpx; + top: 0; + bottom: 0; + left: 50%; + margin: auto; + transition: all 0.2s ease-in 0s; + opacity: 1; +} + +.tower-swiper .tower-item.none { + opacity: 0; +} + +.tower-swiper .tower-item .swiper-item { + width: 100%; + height: 100%; + border-radius: 6rpx; + overflow: hidden; +} +/* -- flex弹性布局 -- */ + +.flex { + display: flex; +} + +.flex-direction { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.align-start { + align-items: flex-start; +} + +.align-end { + align-items: flex-end; +} + +.align-center { + align-items: center; +} + +.align-stretch { + align-items: stretch; +} + +.self-start { + align-self: flex-start; +} + +.self-center { + align-self: flex-center; +} + +.self-end { + align-self: flex-end; +} + +.self-stretch { + align-self: stretch; +} + +.align-stretch { + align-items: stretch; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-around { + justify-content: space-around; +} +/* -- 内外边距 -- */ + +.margin-top-sm { + margin-top: 10rpx; +} + +.margin-top { + margin-top: 20rpx; +} + +.padding-0 { + padding: 0; +} + +.padding-xs { + padding: 10rpx; +} + +.padding-sm { + padding: 20rpx; +} + +.padding { + padding: 30rpx; +} + +.padding-lg { + padding: 40rpx; +} + +.padding-xl { + padding: 50rpx; +} + +.padding-top-xs { + padding-top: 10rpx; +} + +.padding-top-sm { + padding-top: 20rpx; +} + +.padding-top { + padding-top: 30rpx; +} + +.padding-right { + padding-right: 30rpx; +} + +.padding-bottom { + padding-bottom: 30rpx; +} + +.padding-left { + padding-left: 30rpx; +} +/* ================== + 文本 + ==================== */ + +.text-xs { + font-size: 22rpx; +} + +.text-sm { + font-size: 24rpx; +} + +.text-df { + font-size: 28rpx; +} + +.text-sg { + font-size: 30rpx; +} + +.text-lg { + font-size: 32rpx; +} + +.text-xl { + font-size: 36rpx; +} + +.text-xxl { + font-size: 44rpx; +} + +.text-sl { + font-size: 80rpx; +} + +.text-xsl { + font-size: 120rpx; +} + +.text-Abc { + text-transform: Capitalize; +} + +.text-ABC { + text-transform: Uppercase; +} + +.text-abc { + text-transform: Lowercase; +} + +.text-price::before { + content: "¥"; + font-size: 80%; + margin-right: 4rpx; +} + +.text-cut { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.text-bold { + font-weight: bold; +} + +.text-center { + text-align: center; +} + +.text-content { + line-height: 1.6; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-red, .line-red, .lines-red { + color: var(--red); +} + +.text-orange, .line-orange, .lines-orange { + color: var(--orange); +} + +.text-yellow, .line-yellow, .lines-yellow { + color: var(--yellow); +} + +.text-olive, .line-olive, .lines-olive { + color: var(--olive); +} + +.text-green, .line-green, .lines-green { + color: var(--green); +} + +.text-cyan, .line-cyan, .lines-cyan { + color: var(--cyan); +} + +.text-blue, .line-blue, .lines-blue { + color: var(--blue); +} + +.text-purple, .line-purple, .lines-purple { + color: var(--purple); +} + +.text-mauve, .line-mauve, .lines-mauve { + color: var(--mauve); +} + +.text-pink, .line-pink, .lines-pink { + color: var(--pink); +} + +.text-brown, .line-brown, .lines-brown { + color: var(--brown); +} + +.text-grey, .line-grey, .lines-grey { + color: var(--grey); +} + +.text-gray, .line-gray, .lines-gray { + color: var(--gray); +} + +.text-black, .line-black, .lines-black { + color: var(--black); +} + +.text-white, .line-white, .lines-white { + color: var(--white); +} + +.list-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.img-empty { + width: 310rpx; + height: 220rpx; +} + +.text-empty { + margin-top: 48rpx; + font-size: 30rpx; + color: #666; + text-align: center; +} + +.input-grey { + color: #AAA; +} + +.font14 { + font-size: 28rpx; +} + +.cate_item { + min-height: 80rpx; + background-color: #eee; + border-radius: 8rpx; + margin: 0 24rpx; +} + +.margin-b { + margin-bottom: 16rpx; +} + +.flex-sub { + flex: 1; +} +/* grid布局 */ +.grid { + display: flex; + flex-wrap: wrap; +} + +.grid.grid-square { + overflow: hidden; +} + +.grid.grid-square .cu-tag { + position: absolute; + right: 0; + top: 0; + border-bottom-left-radius: 6rpx; + padding: 6rpx 12rpx; + height: auto; + background-color: rgba(0, 0, 0, 0.5); +} + +.grid.grid-square>view>text[class*="cuIcon-"] { + font-size: 52rpx; + position: absolute; + color: var(--grey); + margin: auto; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.grid.grid-square>view { + margin-right: 20rpx; + margin-bottom: 20rpx; + border-radius: 6rpx; + position: relative; + overflow: hidden; +} + +.grid.grid-square>view.bg-img image { + width: 100%; + height: 100%; + position: absolute; +} + +.grid.col-1.grid-square>view { + padding-bottom: 100%; + height: 0; + margin-right: 0; +} + +.grid.col-2.grid-square>view { + /* padding-bottom: calc((100% - 20rpx)/2); */ + height: 0; + width: calc((100% - 20rpx)/2); +} + +.grid.col-3.grid-square>view { + padding-bottom: calc((100% - 40rpx)/3); + height: 0; + width: calc((100% - 40rpx)/3); +} + +.grid.col-4.grid-square>view { + padding-bottom: calc((100% - 60rpx)/4); + height: 0; + width: calc((100% - 60rpx)/4); +} + +.grid.col-5.grid-square>view { + padding-bottom: calc((100% - 80rpx)/5); + height: 0; + width: calc((100% - 80rpx)/5); +} + +.grid.col-2.grid-square>view:nth-child(2n), +.grid.col-3.grid-square>view:nth-child(3n), +.grid.col-4.grid-square>view:nth-child(4n), +.grid.col-5.grid-square>view:nth-child(5n){ + margin-right: 0; +} + +.grid.col-1>view { + width: 100%; +} + +.grid.col-2>view { + width: 50%; +} + +.grid.col-3>view { + width: 33.33%; +} + +.grid.col-4>view { + width: 25%; +} + +.grid.col-5>view { + width: 20%; +} + diff --git a/components/action-sheet/index.js b/components/action-sheet/index.js new file mode 100644 index 0000000..3044481 --- /dev/null +++ b/components/action-sheet/index.js @@ -0,0 +1,62 @@ +import { VantComponent } from '../common/component'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +VantComponent({ + mixins: [button, openType], + props: { + show: Boolean, + title: String, + cancelText: String, + description: String, + round: { + type: Boolean, + value: true + }, + zIndex: { + type: Number, + value: 100 + }, + actions: { + type: Array, + value: [] + }, + overlay: { + type: Boolean, + value: true + }, + closeOnClickOverlay: { + type: Boolean, + value: true + }, + closeOnClickAction: { + type: Boolean, + value: true + }, + safeAreaInsetBottom: { + type: Boolean, + value: true + } + }, + methods: { + onSelect(event) { + const { index } = event.currentTarget.dataset; + const item = this.data.actions[index]; + if (item && !item.disabled && !item.loading) { + this.$emit('select', item); + if (this.data.closeOnClickAction) { + this.onClose(); + } + } + }, + onCancel() { + this.$emit('cancel'); + }, + onClose() { + this.$emit('close'); + }, + onClickOverlay() { + this.$emit('click-overlay'); + this.onClose(); + } + } +}); diff --git a/components/action-sheet/index.json b/components/action-sheet/index.json new file mode 100644 index 0000000..19bf989 --- /dev/null +++ b/components/action-sheet/index.json @@ -0,0 +1,8 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-popup": "../popup/index", + "van-loading": "../loading/index" + } +} diff --git a/components/action-sheet/index.wxml b/components/action-sheet/index.wxml new file mode 100644 index 0000000..7ed2819 --- /dev/null +++ b/components/action-sheet/index.wxml @@ -0,0 +1,67 @@ + + + + + {{ title }} + + + + {{ description }} + + + + + + + + {{ cancelText }} + + diff --git a/components/action-sheet/index.wxss b/components/action-sheet/index.wxss new file mode 100644 index 0000000..dc54840 --- /dev/null +++ b/components/action-sheet/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!important;color:#323233;color:var(--action-sheet-item-text-color,#323233)}.van-action-sheet__cancel,.van-action-sheet__item{text-align:center;font-size:16px;font-size:var(--action-sheet-item-font-size,16px);line-height:50px;line-height:var(--action-sheet-item-height,50px);background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-action-sheet__cancel:before{display:block;content:" ";height:8px;height:var(--action-sheet-cancel-padding-top,8px);background-color:#f7f8fa;background-color:var(--action-sheet-cancel-padding-color,#f7f8fa)}.van-action-sheet__item--disabled{color:#c8c9cc;color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{margin-left:4px;margin-left:var(--padding-base,4px);font-size:12px;font-size:var(--action-sheet-subname-font-size,12px);color:#646566;color:var(--action-sheet-subname-color,#646566)}.van-action-sheet__header{text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--action-sheet-header-font-size,16px);line-height:44px;line-height:var(--action-sheet-header-height,44px)}.van-action-sheet__description{text-align:center;padding:16px;padding:var(--padding-md,16px);color:#646566;color:var(--action-sheet-description-color,#646566);font-size:14px;font-size:var(--action-sheet-description-font-size,14px);line-height:20px;line-height:var(--action-sheet-description-line-height,20px)}.van-action-sheet__close{position:absolute!important;top:0;right:0;line-height:inherit!important;padding:0 12px;padding:var(--action-sheet-close-icon-padding,0 12px);font-size:18px!important;font-size:var(--action-sheet-close-icon-size,18px)!important;color:#969799;color:var(--action-sheet-close-icon-color,#969799)}.van-action-sheet__loading{display:-webkit-flex!important;display:flex!important;height:50px;height:var(--action-sheet-item-height,50px)} \ No newline at end of file diff --git a/components/area/index.js b/components/area/index.js new file mode 100644 index 0000000..e17234c --- /dev/null +++ b/components/area/index.js @@ -0,0 +1,210 @@ +import { VantComponent } from '../common/component'; +import { pickerProps } from '../picker/shared'; +const COLUMNSPLACEHOLDERCODE = '000000'; +VantComponent({ + classes: ['active-class', 'toolbar-class', 'column-class'], + props: Object.assign(Object.assign({}, pickerProps), { value: { + type: String, + observer(value) { + this.code = value; + this.setValues(); + }, + }, areaList: { + type: Object, + value: {}, + observer: 'setValues' + }, columnsNum: { + type: null, + value: 3, + observer(value) { + this.setData({ + displayColumns: this.data.columns.slice(0, +value) + }); + } + }, columnsPlaceholder: { + type: Array, + observer(val) { + this.setData({ + typeToColumnsPlaceholder: { + province: val[0] || '', + city: val[1] || '', + county: val[2] || '', + } + }); + } + } }), + data: { + columns: [{ values: [] }, { values: [] }, { values: [] }], + displayColumns: [{ values: [] }, { values: [] }, { values: [] }], + typeToColumnsPlaceholder: {} + }, + mounted() { + setTimeout(() => { + this.setValues(); + }, 0); + }, + methods: { + getPicker() { + if (this.picker == null) { + this.picker = this.selectComponent('.van-area__picker'); + } + return this.picker; + }, + onCancel(event) { + this.emit('cancel', event.detail); + }, + onConfirm(event) { + const { index } = event.detail; + let { value } = event.detail; + value = this.parseOutputValues(value); + this.emit('confirm', { value, index }); + }, + emit(type, detail) { + detail.values = detail.value; + delete detail.value; + this.$emit(type, detail); + }, + // parse output columns data + parseOutputValues(values) { + const { columnsPlaceholder } = this.data; + return values.map((value, index) => { + // save undefined value + if (!value) + return value; + value = JSON.parse(JSON.stringify(value)); + if (!value.code || value.name === columnsPlaceholder[index]) { + value.code = ''; + value.name = ''; + } + return value; + }); + }, + onChange(event) { + const { index, picker, value } = event.detail; + this.code = value[index].code; + this.setValues().then(() => { + this.$emit('change', { + picker, + values: this.parseOutputValues(picker.getValues()), + index + }); + }); + }, + getConfig(type) { + const { areaList } = this.data; + return (areaList && areaList[`${type}_list`]) || {}; + }, + getList(type, code) { + const { typeToColumnsPlaceholder } = this.data; + let result = []; + if (type !== 'province' && !code) { + return result; + } + const list = this.getConfig(type); + result = Object.keys(list).map(code => ({ + code, + name: list[code] + })); + if (code) { + // oversea code + if (code[0] === '9' && type === 'city') { + code = '9'; + } + result = result.filter(item => item.code.indexOf(code) === 0); + } + if (typeToColumnsPlaceholder[type] && result.length) { + // set columns placeholder + const codeFill = type === 'province' ? '' : type === 'city' ? COLUMNSPLACEHOLDERCODE.slice(2, 4) : COLUMNSPLACEHOLDERCODE.slice(4, 6); + result.unshift({ + code: `${code}${codeFill}`, + name: typeToColumnsPlaceholder[type] + }); + } + return result; + }, + getIndex(type, code) { + let compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6; + const list = this.getList(type, code.slice(0, compareNum - 2)); + // oversea code + if (code[0] === '9' && type === 'province') { + compareNum = 1; + } + code = code.slice(0, compareNum); + for (let i = 0; i < list.length; i++) { + if (list[i].code.slice(0, compareNum) === code) { + return i; + } + } + return 0; + }, + setValues() { + const county = this.getConfig('county'); + let { code } = this; + if (!code) { + if (this.data.columnsPlaceholder.length) { + code = COLUMNSPLACEHOLDERCODE; + } + else if (Object.keys(county)[0]) { + code = Object.keys(county)[0]; + } + else { + code = ''; + } + } + const province = this.getList('province'); + const city = this.getList('city', code.slice(0, 2)); + const picker = this.getPicker(); + if (!picker) { + return; + } + const stack = []; + stack.push(picker.setColumnValues(0, province, false)); + stack.push(picker.setColumnValues(1, city, false)); + if (city.length && code.slice(2, 4) === '00') { + [{ code }] = city; + } + stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false)); + return Promise.all(stack) + .catch(() => { }) + .then(() => picker.setIndexes([ + this.getIndex('province', code), + this.getIndex('city', code), + this.getIndex('county', code) + ])) + .catch(() => { }); + }, + getValues() { + const picker = this.getPicker(); + return picker ? picker.getValues().filter(value => !!value) : []; + }, + getDetail() { + const values = this.getValues(); + const area = { + code: '', + country: '', + province: '', + city: '', + county: '' + }; + if (!values.length) { + return area; + } + const names = values.map((item) => item.name); + area.code = values[values.length - 1].code; + if (area.code[0] === '9') { + area.country = names[1] || ''; + area.province = names[2] || ''; + } + else { + area.province = names[0] || ''; + area.city = names[1] || ''; + area.county = names[2] || ''; + } + return area; + }, + reset(code) { + this.code = code || ''; + return this.setValues(); + } + } +}); diff --git a/components/area/index.json b/components/area/index.json new file mode 100644 index 0000000..a778e91 --- /dev/null +++ b/components/area/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-picker": "../picker/index" + } +} diff --git a/components/area/index.wxml b/components/area/index.wxml new file mode 100644 index 0000000..6075794 --- /dev/null +++ b/components/area/index.wxml @@ -0,0 +1,18 @@ + diff --git a/components/area/index.wxss b/components/area/index.wxss new file mode 100644 index 0000000..99694d6 --- /dev/null +++ b/components/area/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss'; \ No newline at end of file diff --git a/components/button/index.js b/components/button/index.js new file mode 100644 index 0000000..599aa98 --- /dev/null +++ b/components/button/index.js @@ -0,0 +1,69 @@ +import { VantComponent } from '../common/component'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +VantComponent({ + mixins: [button, openType], + classes: ['hover-class', 'loading-class'], + data: { + baseStyle: '' + }, + props: { + icon: String, + plain: Boolean, + block: Boolean, + round: Boolean, + square: Boolean, + loading: Boolean, + hairline: Boolean, + disabled: Boolean, + loadingText: String, + customStyle: String, + loadingType: { + type: String, + value: 'circular' + }, + type: { + type: String, + value: 'default' + }, + size: { + type: String, + value: 'normal' + }, + loadingSize: { + type: String, + value: '20px' + }, + color: { + type: String, + observer(color) { + let style = ''; + if (color) { + style += `color: ${this.data.plain ? color : 'white'};`; + if (!this.data.plain) { + // Use background instead of backgroundColor to make linear-gradient work + style += `background: ${color};`; + } + // hide border when color is linear-gradient + if (color.indexOf('gradient') !== -1) { + style += 'border: 0;'; + } + else { + style += `border-color: ${color};`; + } + } + if (style !== this.data.baseStyle) { + this.setData({ baseStyle: style }); + } + } + } + }, + methods: { + onClick() { + if (!this.data.loading) { + this.$emit('click'); + } + }, + noop() { } + } +}); diff --git a/components/button/index.json b/components/button/index.json new file mode 100644 index 0000000..e00a588 --- /dev/null +++ b/components/button/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-loading": "../loading/index" + } +} diff --git a/components/button/index.wxml b/components/button/index.wxml new file mode 100644 index 0000000..9c1f1c6 --- /dev/null +++ b/components/button/index.wxml @@ -0,0 +1,44 @@ + + + + + + + function get(type, color, plain) { + if (plain) { + return color ? color : '#c9c9c9'; + } + + if (type === 'default') { + return '#c9c9c9'; + } + return 'white'; + } + + module.exports = get; + \ No newline at end of file diff --git a/components/button/index.wxss b/components/button/index.wxss new file mode 100644 index 0000000..5a591fb --- /dev/null +++ b/components/button/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-button{position:relative;display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:0;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%;height:44px;height:var(--button-default-height,44px);line-height:20px;line-height:var(--button-line-height,20px);font-size:16px;font-size:var(--button-default-font-size,16px);transition:opacity .2s;transition:opacity var(--animation-duration-fast,.2s);border-radius:2px;border-radius:var(--button-border-radius,2px)}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;border:inherit;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" ";background-color:#000;background-color:var(--black,#000);border-color:#000;border-color:var(--black,#000)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#323233;color:var(--button-default-color,#323233);background:#fff;background:var(--button-default-background-color,#fff);border:1px solid #ebedf0;border:var(--button-border-width,1px) solid var(--button-default-border-color,#ebedf0)}.van-button--primary{color:#fff;color:var(--button-primary-color,#fff);background:#07c160;background:var(--button-primary-background-color,#07c160);border:1px solid #07c160;border:var(--button-border-width,1px) solid var(--button-primary-border-color,#07c160)}.van-button--info{color:#fff;color:var(--button-info-color,#fff);background:#1989fa;background:var(--button-info-background-color,#1989fa);border:1px solid #1989fa;border:var(--button-border-width,1px) solid var(--button-info-border-color,#1989fa)}.van-button--danger{color:#fff;color:var(--button-danger-color,#fff);background:#ee0a24;background:var(--button-danger-background-color,#ee0a24);border:1px solid #ee0a24;border:var(--button-border-width,1px) solid var(--button-danger-border-color,#ee0a24)}.van-button--warning{color:#fff;color:var(--button-warning-color,#fff);background:#ff976a;background:var(--button-warning-background-color,#ff976a);border:1px solid #ff976a;border:var(--button-border-width,1px) solid var(--button-warning-border-color,#ff976a)}.van-button--plain{background:#fff;background:var(--button-plain-background-color,#fff)}.van-button--plain.van-button--primary{color:#07c160;color:var(--button-primary-background-color,#07c160)}.van-button--plain.van-button--info{color:#1989fa;color:var(--button-info-background-color,#1989fa)}.van-button--plain.van-button--danger{color:#ee0a24;color:var(--button-danger-background-color,#ee0a24)}.van-button--plain.van-button--warning{color:#ff976a;color:var(--button-warning-background-color,#ff976a)}.van-button--large{width:100%;height:50px;height:var(--button-large-height,50px)}.van-button--normal{padding:0 15px;font-size:14px;font-size:var(--button-normal-font-size,14px)}.van-button--small{min-width:60px;min-width:var(--button-small-min-width,60px);height:30px;height:var(--button-small-height,30px);padding:0 8px;padding:0 var(--padding-xs,8px);font-size:12px;font-size:var(--button-small-font-size,12px)}.van-button--mini{display:inline-block;min-width:50px;min-width:var(--button-mini-min-width,50px);height:22px;height:var(--button-mini-height,22px);font-size:10px;font-size:var(--button-mini-font-size,10px)}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:-webkit-flex;display:flex;width:100%}.van-button--round{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5;opacity:var(--button-disabled-opacity,.5)}.van-button__text{display:inline}.van-button__icon+.van-button__text:not(:empty),.van-button__loading-text{margin-left:4px}.van-button__icon{min-width:1em;line-height:inherit!important;vertical-align:top}.van-button--hairline{padding-top:1px;border-width:0}.van-button--hairline:after{border-color:inherit;border-width:1px;border-radius:4px;border-radius:calc(var(--button-border-radius, 2px)*2)}.van-button--hairline.van-button--round:after{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--hairline.van-button--square:after{border-radius:0} \ No newline at end of file diff --git a/components/cell-group/index.js b/components/cell-group/index.js new file mode 100644 index 0000000..3611e09 --- /dev/null +++ b/components/cell-group/index.js @@ -0,0 +1,10 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + props: { + title: String, + border: { + type: Boolean, + value: true + } + } +}); diff --git a/components/cell-group/index.json b/components/cell-group/index.json new file mode 100644 index 0000000..32640e0 --- /dev/null +++ b/components/cell-group/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/cell-group/index.wxml b/components/cell-group/index.wxml new file mode 100644 index 0000000..6e0b471 --- /dev/null +++ b/components/cell-group/index.wxml @@ -0,0 +1,9 @@ + + {{ title }} + + + + diff --git a/components/cell-group/index.wxss b/components/cell-group/index.wxss new file mode 100644 index 0000000..edbccd5 --- /dev/null +++ b/components/cell-group/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)} \ No newline at end of file diff --git a/components/cell/index.js b/components/cell/index.js new file mode 100644 index 0000000..bba1242 --- /dev/null +++ b/components/cell/index.js @@ -0,0 +1,35 @@ +import { link } from '../mixins/link' +import { VantComponent } from '../common/component' + +VantComponent({ + classes: [ + 'title-class', + 'label-class', + 'value-class', + 'right-icon-class', + 'hover-class' + ], + mixins: [link], + props: { + title: null, + value: null, + icon: String, + size: String, + label: String, + center: Boolean, + isLink: Boolean, + required: Boolean, + clickable: Boolean, + titleWidth: String, + customStyle: String, + arrowDirection: String, + useLabelSlot: Boolean, + border: { type: Boolean, value: true } + }, + methods: { + onClick(event) { + this.$emit('click', event.detail) + this.jumpLink() + } + } +}) \ No newline at end of file diff --git a/components/cell/index.json b/components/cell/index.json new file mode 100644 index 0000000..a9ab393 --- /dev/null +++ b/components/cell/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} \ No newline at end of file diff --git a/components/cell/index.wxml b/components/cell/index.wxml new file mode 100644 index 0000000..d4b0a32 --- /dev/null +++ b/components/cell/index.wxml @@ -0,0 +1,30 @@ + + + + + + + + {{ title }} + + + + + {{ label }} + + + + + {{ value }} + + + + + + + + \ No newline at end of file diff --git a/components/cell/index.wxss b/components/cell/index.wxss new file mode 100644 index 0000000..7afd1c4 --- /dev/null +++ b/components/cell/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:auto;right:0;bottom:0;left:16px;border-bottom:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__value{font-size:16px;font-size:var(--cell-large-value-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)} \ No newline at end of file diff --git a/components/checkbox-group/index.js b/components/checkbox-group/index.js new file mode 100644 index 0000000..bc90d74 --- /dev/null +++ b/components/checkbox-group/index.js @@ -0,0 +1,35 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + field: true, + relation: { + name: 'checkbox', + type: 'descendant', + current: 'checkbox-group', + linked(target) { + this.updateChild(target); + }, + }, + props: { + max: Number, + value: { + type: Array, + observer: 'updateChildren' + }, + disabled: { + type: Boolean, + observer: 'updateChildren' + } + }, + methods: { + updateChildren() { + (this.children || []).forEach((child) => this.updateChild(child)); + }, + updateChild(child) { + const { value, disabled } = this.data; + child.setData({ + value: value.indexOf(child.data.name) !== -1, + parentDisabled: disabled + }); + } + } +}); diff --git a/components/checkbox-group/index.json b/components/checkbox-group/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/checkbox-group/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/checkbox-group/index.wxml b/components/checkbox-group/index.wxml new file mode 100644 index 0000000..4fa864c --- /dev/null +++ b/components/checkbox-group/index.wxml @@ -0,0 +1 @@ + diff --git a/components/checkbox-group/index.wxss b/components/checkbox-group/index.wxss new file mode 100644 index 0000000..99694d6 --- /dev/null +++ b/components/checkbox-group/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss'; \ No newline at end of file diff --git a/components/checkbox/index.js b/components/checkbox/index.js new file mode 100644 index 0000000..db5b551 --- /dev/null +++ b/components/checkbox/index.js @@ -0,0 +1,76 @@ +import { VantComponent } from '../common/component'; +function emit(target, value) { + target.$emit('input', value); + target.$emit('change', value); +} +VantComponent({ + field: true, + relation: { + name: 'checkbox-group', + type: 'ancestor', + current: 'checkbox', + }, + classes: ['icon-class', 'label-class'], + props: { + value: Boolean, + disabled: Boolean, + useIconSlot: Boolean, + checkedColor: String, + labelPosition: String, + labelDisabled: Boolean, + shape: { + type: String, + value: 'round' + }, + iconSize: { + type: null, + value: 20 + } + }, + data: { + parentDisabled: false + }, + methods: { + emitChange(value) { + if (this.parent) { + this.setParentValue(this.parent, value); + } + else { + emit(this, value); + } + }, + toggle() { + const { parentDisabled, disabled, value } = this.data; + if (!disabled && !parentDisabled) { + this.emitChange(!value); + } + }, + onClickLabel() { + const { labelDisabled, parentDisabled, disabled, value } = this.data; + if (!disabled && !labelDisabled && !parentDisabled) { + this.emitChange(!value); + } + }, + setParentValue(parent, value) { + const parentValue = parent.data.value.slice(); + const { name } = this.data; + const { max } = parent.data; + if (value) { + if (max && parentValue.length >= max) { + return; + } + if (parentValue.indexOf(name) === -1) { + parentValue.push(name); + emit(parent, parentValue); + } + } + else { + const index = parentValue.indexOf(name); + if (index !== -1) { + parentValue.splice(index, 1); + emit(parent, parentValue); + } + } + } + } +}); diff --git a/components/checkbox/index.json b/components/checkbox/index.json new file mode 100644 index 0000000..0a336c0 --- /dev/null +++ b/components/checkbox/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} diff --git a/components/checkbox/index.wxml b/components/checkbox/index.wxml new file mode 100644 index 0000000..94789d8 --- /dev/null +++ b/components/checkbox/index.wxml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/components/checkbox/index.wxs b/components/checkbox/index.wxs new file mode 100644 index 0000000..927eb55 --- /dev/null +++ b/components/checkbox/index.wxs @@ -0,0 +1,20 @@ +/* eslint-disable */ +var utils = require('../wxs/utils.wxs'); + +function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) { + var styles = [['font-size', utils.addUnit(iconSize)]]; + if (checkedColor && value && !disabled && !parentDisabled) { + styles.push(['border-color', checkedColor]); + styles.push(['background-color', checkedColor]); + } + + return styles + .map(function(item) { + return item.join(':'); + }) + .join(';'); +} + +module.exports = { + iconStyle: iconStyle +}; diff --git a/components/checkbox/index.wxss b/components/checkbox/index.wxss new file mode 100644 index 0000000..afaf37b --- /dev/null +++ b/components/checkbox/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-checkbox{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:20px;line-height:var(--checkbox-size,20px)}.van-checkbox__icon-wrap{-webkit-flex:none;flex:none}.van-checkbox__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;font-size:20px;font-size:var(--checkbox-size,20px);border:1px solid #c8c9cc;border:1px solid var(--checkbox-border-color,#c8c9cc);transition-duration:.2s;transition-duration:var(--checkbox-transition-duration,.2s)}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--checkbox-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--checkbox-checked-icon-color,#1989fa)}.van-checkbox__icon--disabled{background-color:#ebedf0;background-color:var(--checkbox-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c8c9cc;color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__label{word-wrap:break-word;margin-left:10px;margin-left:var(--checkbox-label-margin,10px);color:#323233;color:var(--checkbox-label-color,#323233)}.van-checkbox__label--left{float:left;margin:0 10px 0 0;margin:0 var(--checkbox-label-margin,10px) 0 0}.van-checkbox__label--disabled{color:#c8c9cc;color:var(--checkbox-disabled-label-color,#c8c9cc)}.van-checkbox__label:empty{margin:0} \ No newline at end of file diff --git a/components/col/index.js b/components/col/index.js new file mode 100644 index 0000000..ec12aa9 --- /dev/null +++ b/components/col/index.js @@ -0,0 +1,24 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + name: 'row', + type: 'ancestor', + current: 'col', + }, + props: { + span: Number, + offset: Number + }, + data: { + viewStyle: '' + }, + methods: { + setGutter(gutter) { + const padding = `${gutter / 2}px`; + const viewStyle = gutter ? `padding-left: ${padding}; padding-right: ${padding};` : ''; + if (viewStyle !== this.data.viewStyle) { + this.setData({ viewStyle }); + } + } + } +}); diff --git a/components/col/index.json b/components/col/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/col/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/col/index.wxml b/components/col/index.wxml new file mode 100644 index 0000000..52544f0 --- /dev/null +++ b/components/col/index.wxml @@ -0,0 +1,8 @@ + + + + + diff --git a/components/col/index.wxss b/components/col/index.wxss new file mode 100644 index 0000000..44c896a --- /dev/null +++ b/components/col/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-col{float:left;box-sizing:border-box}.van-col--1{width:4.16666667%}.van-col--offset-1{margin-left:4.16666667%}.van-col--2{width:8.33333333%}.van-col--offset-2{margin-left:8.33333333%}.van-col--3{width:12.5%}.van-col--offset-3{margin-left:12.5%}.van-col--4{width:16.66666667%}.van-col--offset-4{margin-left:16.66666667%}.van-col--5{width:20.83333333%}.van-col--offset-5{margin-left:20.83333333%}.van-col--6{width:25%}.van-col--offset-6{margin-left:25%}.van-col--7{width:29.16666667%}.van-col--offset-7{margin-left:29.16666667%}.van-col--8{width:33.33333333%}.van-col--offset-8{margin-left:33.33333333%}.van-col--9{width:37.5%}.van-col--offset-9{margin-left:37.5%}.van-col--10{width:41.66666667%}.van-col--offset-10{margin-left:41.66666667%}.van-col--11{width:45.83333333%}.van-col--offset-11{margin-left:45.83333333%}.van-col--12{width:50%}.van-col--offset-12{margin-left:50%}.van-col--13{width:54.16666667%}.van-col--offset-13{margin-left:54.16666667%}.van-col--14{width:58.33333333%}.van-col--offset-14{margin-left:58.33333333%}.van-col--15{width:62.5%}.van-col--offset-15{margin-left:62.5%}.van-col--16{width:66.66666667%}.van-col--offset-16{margin-left:66.66666667%}.van-col--17{width:70.83333333%}.van-col--offset-17{margin-left:70.83333333%}.van-col--18{width:75%}.van-col--offset-18{margin-left:75%}.van-col--19{width:79.16666667%}.van-col--offset-19{margin-left:79.16666667%}.van-col--20{width:83.33333333%}.van-col--offset-20{margin-left:83.33333333%}.van-col--21{width:87.5%}.van-col--offset-21{margin-left:87.5%}.van-col--22{width:91.66666667%}.van-col--offset-22{margin-left:91.66666667%}.van-col--23{width:95.83333333%}.van-col--offset-23{margin-left:95.83333333%}.van-col--24{width:100%}.van-col--offset-24{margin-left:100%} \ No newline at end of file diff --git a/components/collapse-item/index.js b/components/collapse-item/index.js new file mode 100644 index 0000000..9ff56b8 --- /dev/null +++ b/components/collapse-item/index.js @@ -0,0 +1,95 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + classes: ['title-class', 'content-class'], + relation: { + name: 'collapse', + type: 'ancestor', + current: 'collapse-item', + }, + props: { + name: null, + title: null, + value: null, + icon: String, + label: String, + disabled: Boolean, + clickable: Boolean, + border: { + type: Boolean, + value: true, + }, + isLink: { + type: Boolean, + value: true, + }, + }, + data: { + expanded: false, + }, + created() { + this.animation = wx.createAnimation({ + duration: 0, + timingFunction: 'ease-in-out', + }); + }, + mounted() { + this.updateExpanded(); + this.inited = true; + }, + methods: { + updateExpanded() { + if (!this.parent) { + return Promise.resolve(); + } + const { value, accordion } = this.parent.data; + const { children = [] } = this.parent; + const { name } = this.data; + const index = children.indexOf(this); + const currentName = name == null ? index : name; + const expanded = accordion + ? value === currentName + : (value || []).some((name) => name === currentName); + if (expanded !== this.data.expanded) { + this.updateStyle(expanded); + } + this.setData({ index, expanded }); + }, + updateStyle(expanded) { + const { inited } = this; + this.getRect('.van-collapse-item__content') + .then((rect) => rect.height) + .then((height) => { + const { animation } = this; + if (expanded) { + animation + .height(height) + .top(1) + .step({ + duration: inited ? 300 : 1, + }) + .height('auto') + .step(); + this.setData({ + animation: animation.export(), + }); + return; + } + animation.height(height).top(0).step({ duration: 1 }).height(0).step({ + duration: 300, + }); + this.setData({ + animation: animation.export(), + }); + }); + }, + onClick() { + if (this.data.disabled) { + return; + } + const { name, expanded } = this.data; + const index = this.parent.children.indexOf(this); + const currentName = name == null ? index : name; + this.parent.switch(currentName, !expanded); + }, + }, +}); diff --git a/components/collapse-item/index.json b/components/collapse-item/index.json new file mode 100644 index 0000000..0e5425c --- /dev/null +++ b/components/collapse-item/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-cell": "../cell/index" + } +} diff --git a/components/collapse-item/index.wxml b/components/collapse-item/index.wxml new file mode 100644 index 0000000..ae4cc83 --- /dev/null +++ b/components/collapse-item/index.wxml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + diff --git a/components/collapse-item/index.wxss b/components/collapse-item/index.wxss new file mode 100644 index 0000000..0bb936c --- /dev/null +++ b/components/collapse-item/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;transition:-webkit-transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s),-webkit-transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c8c9cc!important;color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important;background-color:var(--white,#fff)!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__content{padding:15px;padding:var(--collapse-item-content-padding,15px);color:#969799;color:var(--collapse-item-content-text-color,#969799);font-size:13px;font-size:var(--collapse-item-content-font-size,13px);line-height:1.5;line-height:var(--collapse-item-content-line-height,1.5);background-color:#fff;background-color:var(--collapse-item-content-background-color,#fff)} \ No newline at end of file diff --git a/components/collapse/index.js b/components/collapse/index.js new file mode 100644 index 0000000..33dae31 --- /dev/null +++ b/components/collapse/index.js @@ -0,0 +1,47 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + name: 'collapse-item', + type: 'descendant', + current: 'collapse', + }, + props: { + value: { + type: null, + observer: 'updateExpanded', + }, + accordion: { + type: Boolean, + observer: 'updateExpanded', + }, + border: { + type: Boolean, + value: true, + }, + }, + methods: { + updateExpanded() { + this.children.forEach((child) => { + child.updateExpanded(); + }); + }, + switch(name, expanded) { + const { accordion, value } = this.data; + const changeItem = name; + if (!accordion) { + name = expanded + ? (value || []).concat(name) + : (value || []).filter((activeName) => activeName !== name); + } else { + name = expanded ? name : ''; + } + if (expanded) { + this.$emit('open', changeItem); + } else { + this.$emit('close', changeItem); + } + this.$emit('change', name); + this.$emit('input', name); + }, + }, +}); diff --git a/components/collapse/index.json b/components/collapse/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/collapse/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/collapse/index.wxml b/components/collapse/index.wxml new file mode 100644 index 0000000..fd4e171 --- /dev/null +++ b/components/collapse/index.wxml @@ -0,0 +1,3 @@ + + + diff --git a/components/collapse/index.wxss b/components/collapse/index.wxss new file mode 100644 index 0000000..99694d6 --- /dev/null +++ b/components/collapse/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss'; \ No newline at end of file diff --git a/components/common/classNames.js b/components/common/classNames.js new file mode 100644 index 0000000..9a61073 --- /dev/null +++ b/components/common/classNames.js @@ -0,0 +1 @@ +"use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var hasOwn={}.hasOwnProperty;function classNames(){for(var e=[],t=0;t it !== child); + }, + }, +}; +function mapKeys(source, target, map) { + Object.keys(map).forEach(key => { + if (source[key]) { + target[map[key]] = source[key]; + } + }); +} +function makeRelation(options, vantOptions, relation) { + const { type, name, linked, unlinked, linkChanged } = relation; + const { beforeCreate, destroyed } = vantOptions; + if (type === 'descendant') { + options.created = function () { + beforeCreate && beforeCreate.bind(this)(); + this.children = this.children || []; + }; + options.detached = function () { + this.children = []; + destroyed && destroyed.bind(this)(); + }; + } + options.relations = Object.assign(options.relations || {}, { + [`../${name}/index`]: { + type, + linked(node) { + relationFunctions[type].linked.bind(this)(node); + linked && linked.bind(this)(node); + }, + linkChanged(node) { + linkChanged && linkChanged.bind(this)(node); + }, + unlinked(node) { + relationFunctions[type].unlinked.bind(this)(node); + unlinked && unlinked.bind(this)(node); + }, + } + }); +} +function VantComponent(vantOptions = {}) { + const options = {}; + mapKeys(vantOptions, options, { + data: 'data', + props: 'properties', + mixins: 'behaviors', + methods: 'methods', + beforeCreate: 'created', + created: 'attached', + mounted: 'ready', + relations: 'relations', + destroyed: 'detached', + classes: 'externalClasses' + }); + const { relation } = vantOptions; + if (relation) { + makeRelation(options, vantOptions, relation); + } + // add default externalClasses + options.externalClasses = options.externalClasses || []; + options.externalClasses.push('custom-class'); + // add default behaviors + options.behaviors = options.behaviors || []; + options.behaviors.push(basic); + // map field to form-field behavior + if (vantOptions.field) { + options.behaviors.push('wx://form-field'); + } + if (options.properties) { + Object.keys(options.properties).forEach(name => { + if (Array.isArray(options.properties[name])) { + // miniprogram do not allow multi type + options.properties[name] = null; + } + }); + } + // add default options + options.options = { + multipleSlots: true, + addGlobalClass: true + }; + Component(options); +} +export { VantComponent }; diff --git a/components/common/index.wxss b/components/common/index.wxss new file mode 100644 index 0000000..6e6891f --- /dev/null +++ b/components/common/index.wxss @@ -0,0 +1 @@ +.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{display:table;clear:both;content:""}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px} \ No newline at end of file diff --git a/components/common/style/clearfix.wxss b/components/common/style/clearfix.wxss new file mode 100644 index 0000000..a0ca838 --- /dev/null +++ b/components/common/style/clearfix.wxss @@ -0,0 +1 @@ +.van-clearfix:after{display:table;clear:both;content:""} \ No newline at end of file diff --git a/components/common/style/ellipsis.wxss b/components/common/style/ellipsis.wxss new file mode 100644 index 0000000..1e9dbc9 --- /dev/null +++ b/components/common/style/ellipsis.wxss @@ -0,0 +1 @@ +.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3} \ No newline at end of file diff --git a/components/common/style/hairline.wxss b/components/common/style/hairline.wxss new file mode 100644 index 0000000..f64e2f8 --- /dev/null +++ b/components/common/style/hairline.wxss @@ -0,0 +1 @@ +.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px} \ No newline at end of file diff --git a/components/common/style/mixins/clearfix.wxss b/components/common/style/mixins/clearfix.wxss new file mode 100644 index 0000000..e69de29 diff --git a/components/common/style/mixins/ellipsis.wxss b/components/common/style/mixins/ellipsis.wxss new file mode 100644 index 0000000..e69de29 diff --git a/components/common/style/mixins/hairline.wxss b/components/common/style/mixins/hairline.wxss new file mode 100644 index 0000000..e69de29 diff --git a/components/common/style/theme.wxss b/components/common/style/theme.wxss new file mode 100644 index 0000000..e69de29 diff --git a/components/common/style/var.wxss b/components/common/style/var.wxss new file mode 100644 index 0000000..e69de29 diff --git a/components/common/utils.js b/components/common/utils.js new file mode 100644 index 0000000..cc0f8f1 --- /dev/null +++ b/components/common/utils.js @@ -0,0 +1,32 @@ +export function isDef(value) { + return value !== undefined && value !== null; +} +export function isObj(x) { + const type = typeof x; + return x !== null && (type === 'object' || type === 'function'); +} +export function isNumber(value) { + return /^\d+(\.\d+)?$/.test(value); +} +export function range(num, min, max) { + return Math.min(Math.max(num, min), max); +} +export function nextTick(fn) { + setTimeout(() => { + fn(); + }, 1000 / 30); +} +let systemInfo = null; +export function getSystemInfoSync() { + if (systemInfo == null) { + systemInfo = wx.getSystemInfoSync(); + } + return systemInfo; +} +export function addUnit(value) { + if (!isDef(value)) { + return undefined; + } + value = String(value); + return isNumber(value) ? `${value}px` : value; +} diff --git a/components/common/version.js b/components/common/version.js new file mode 100644 index 0000000..01f24f8 --- /dev/null +++ b/components/common/version.js @@ -0,0 +1,31 @@ +import { getSystemInfoSync } from './utils'; +function compareVersion(v1, v2) { + v1 = v1.split('.'); + v2 = v2.split('.'); + const len = Math.max(v1.length, v2.length); + while (v1.length < len) { + v1.push('0'); + } + while (v2.length < len) { + v2.push('0'); + } + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i], 10); + const num2 = parseInt(v2[i], 10); + if (num1 > num2) { + return 1; + } + if (num1 < num2) { + return -1; + } + } + return 0; +} +export function canIUseModel() { + const system = getSystemInfoSync(); + return compareVersion(system.SDKVersion, '2.9.3') >= 0; +} +export function canIUseFormFieldButton() { + const system = getSystemInfoSync(); + return compareVersion(system.SDKVersion, '2.10.3') >= 0; +} diff --git a/components/count-down/index.js b/components/count-down/index.js new file mode 100644 index 0000000..28fe551 --- /dev/null +++ b/components/count-down/index.js @@ -0,0 +1,98 @@ +import { VantComponent } from '../common/component'; +import { isSameSecond, parseFormat, parseTimeData } from './utils'; +function simpleTick(fn) { + return setTimeout(fn, 30); +} +VantComponent({ + props: { + useSlot: Boolean, + millisecond: Boolean, + time: { + type: Number, + observer: 'reset' + }, + format: { + type: String, + value: 'HH:mm:ss' + }, + autoStart: { + type: Boolean, + value: true + } + }, + data: { + timeData: parseTimeData(0), + formattedTime: '0' + }, + destroyed() { + clearTimeout(this.tid); + this.tid = null; + }, + methods: { + // 开始 + start() { + if (this.counting) { + return; + } + this.counting = true; + this.endTime = Date.now() + this.remain; + this.tick(); + }, + // 暂停 + pause() { + this.counting = false; + clearTimeout(this.tid); + }, + // 重置 + reset() { + this.pause(); + this.remain = this.data.time; + this.setRemain(this.remain); + if (this.data.autoStart) { + this.start(); + } + }, + tick() { + if (this.data.millisecond) { + this.microTick(); + } + else { + this.macroTick(); + } + }, + microTick() { + this.tid = simpleTick(() => { + this.setRemain(this.getRemain()); + if (this.remain !== 0) { + this.microTick(); + } + }); + }, + macroTick() { + this.tid = simpleTick(() => { + const remain = this.getRemain(); + if (!isSameSecond(remain, this.remain) || remain === 0) { + this.setRemain(remain); + } + if (this.remain !== 0) { + this.macroTick(); + } + }); + }, + getRemain() { + return Math.max(this.endTime - Date.now(), 0); + }, + setRemain(remain) { + this.remain = remain; + const timeData = parseTimeData(remain); + if (this.data.useSlot) { + this.$emit('change', timeData); + } + this.setData({ formattedTime: parseFormat(this.data.format, timeData) }) + if (remain === 0) { + this.pause(); + this.$emit('finish'); + } + } + } +}); diff --git a/components/count-down/index.json b/components/count-down/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/count-down/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/count-down/index.wxml b/components/count-down/index.wxml new file mode 100644 index 0000000..e206e16 --- /dev/null +++ b/components/count-down/index.wxml @@ -0,0 +1,4 @@ + + + {{ formattedTime }} + diff --git a/components/count-down/index.wxss b/components/count-down/index.wxss new file mode 100644 index 0000000..bc33f5d --- /dev/null +++ b/components/count-down/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-count-down{color:#323233;color:var(--count-down-text-color,#323233);font-size:14px;font-size:var(--count-down-font-size,14px);line-height:20px;line-height:var(--count-down-line-height,20px)} \ No newline at end of file diff --git a/components/count-down/utils.js b/components/count-down/utils.js new file mode 100644 index 0000000..3237988 --- /dev/null +++ b/components/count-down/utils.js @@ -0,0 +1,57 @@ +function padZero(num, targetLength = 2) { + let str = num + ''; + while (str.length < targetLength) { + str = '0' + str; + } + return str; +} +const SECOND = 1000; +const MINUTE = 60 * SECOND; +const HOUR = 60 * MINUTE; +const DAY = 24 * HOUR; +export function parseTimeData(time) { + const days = Math.floor(time / DAY); + const hours = Math.floor((time % DAY) / HOUR); + const minutes = Math.floor((time % HOUR) / MINUTE); + const seconds = Math.floor((time % MINUTE) / SECOND); + const milliseconds = Math.floor(time % SECOND); + return { + days, + hours, + minutes, + seconds, + milliseconds + }; +} +export function parseFormat(format, timeData) { + const { days } = timeData; + let { hours, minutes, seconds, milliseconds } = timeData; + if (format.indexOf('DD') === -1) { + hours += days * 24; + } + else { + format = format.replace('DD', padZero(days)); + } + if (format.indexOf('HH') === -1) { + minutes += hours * 60; + } + else { + format = format.replace('HH', padZero(hours)); + } + if (format.indexOf('mm') === -1) { + seconds += minutes * 60; + } + else { + format = format.replace('mm', padZero(minutes)); + } + if (format.indexOf('ss') === -1) { + milliseconds += seconds * 1000; + } + else { + format = format.replace('ss', padZero(seconds)); + } + return format.replace('SSS', padZero(milliseconds, 3)); +} +export function isSameSecond(time1, time2) { + return Math.floor(time1 / 1000) === Math.floor(time2 / 1000); +} diff --git a/components/datetime-picker/index.js b/components/datetime-picker/index.js new file mode 100644 index 0000000..5944619 --- /dev/null +++ b/components/datetime-picker/index.js @@ -0,0 +1,297 @@ +import { VantComponent } from '../common/component'; +import { isDef } from '../common/utils'; +import { pickerProps } from '../picker/shared'; +const currentYear = new Date().getFullYear(); +function isValidDate(date) { + return isDef(date) && !isNaN(new Date(date).getTime()); +} +function range(num, min, max) { + return Math.min(Math.max(num, min), max); +} +function padZero(val) { + return `00${val}`.slice(-2); +} +function times(n, iteratee) { + let index = -1; + const result = Array(n < 0 ? 0 : n); + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} +function getTrueValue(formattedValue) { + if (!formattedValue) + return; + while (isNaN(parseInt(formattedValue, 10))) { + formattedValue = formattedValue.slice(1); + } + return parseInt(formattedValue, 10); +} +function getMonthEndDay(year, month) { + return 32 - new Date(year, month - 1, 32).getDate(); +} +const defaultFormatter = (_, value) => value; +VantComponent({ + classes: ['active-class', 'toolbar-class', 'column-class'], + props: Object.assign(Object.assign({}, pickerProps), { value: { + type: null, + observer: 'updateValue' + }, filter: null, type: { + type: String, + value: 'datetime', + observer: 'updateValue' + }, showToolbar: { + type: Boolean, + value: true + }, formatter: { + type: null, + value: defaultFormatter + }, minDate: { + type: Number, + value: new Date(currentYear - 10, 0, 1).getTime(), + observer: 'updateValue' + }, maxDate: { + type: Number, + value: new Date(currentYear + 10, 11, 31).getTime(), + observer: 'updateValue' + }, minHour: { + type: Number, + value: 0, + observer: 'updateValue' + }, maxHour: { + type: Number, + value: 23, + observer: 'updateValue' + }, minMinute: { + type: Number, + value: 0, + observer: 'updateValue' + }, maxMinute: { + type: Number, + value: 59, + observer: 'updateValue' + } }), + data: { + innerValue: Date.now(), + columns: [] + }, + methods: { + updateValue() { + const { data } = this; + const val = this.correctValue(this.data.value); + const isEqual = val === data.innerValue; + if (!isEqual) { + this.updateColumnValue(val).then(() => { + this.$emit('input', val); + }); + } + else { + this.updateColumns(); + } + }, + getPicker() { + if (this.picker == null) { + this.picker = this.selectComponent('.van-datetime-picker'); + const { picker } = this; + const { setColumnValues } = picker; + picker.setColumnValues = (...args) => setColumnValues.apply(picker, [...args, false]); + } + return this.picker; + }, + updateColumns() { + const { formatter = defaultFormatter } = this.data; + const results = this.getOriginColumns().map(column => ({ + values: column.values.map(value => formatter(column.type, value)) + })); + return this.set({ columns: results }); + }, + getOriginColumns() { + const { filter } = this.data; + const results = this.getRanges().map(({ type, range }) => { + let values = times(range[1] - range[0] + 1, index => { + let value = range[0] + index; + value = type === 'year' ? `${value}` : padZero(value); + return value; + }); + if (filter) { + values = filter(type, values); + } + return { type, values }; + }); + return results; + }, + getRanges() { + const { data } = this; + if (data.type === 'time') { + return [ + { + type: 'hour', + range: [data.minHour, data.maxHour] + }, + { + type: 'minute', + range: [data.minMinute, data.maxMinute] + } + ]; + } + const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', data.innerValue); + const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', data.innerValue); + const result = [ + { + type: 'year', + range: [minYear, maxYear] + }, + { + type: 'month', + range: [minMonth, maxMonth] + }, + { + type: 'day', + range: [minDate, maxDate] + }, + { + type: 'hour', + range: [minHour, maxHour] + }, + { + type: 'minute', + range: [minMinute, maxMinute] + } + ]; + if (data.type === 'date') + result.splice(3, 2); + if (data.type === 'year-month') + result.splice(2, 3); + return result; + }, + correctValue(value) { + const { data } = this; + // validate value + const isDateType = data.type !== 'time'; + if (isDateType && !isValidDate(value)) { + value = data.minDate; + } + else if (!isDateType && !value) { + const { minHour } = data; + value = `${padZero(minHour)}:00`; + } + // time type + if (!isDateType) { + let [hour, minute] = value.split(':'); + hour = padZero(range(hour, data.minHour, data.maxHour)); + minute = padZero(range(minute, data.minMinute, data.maxMinute)); + return `${hour}:${minute}`; + } + // date type + value = Math.max(value, data.minDate); + value = Math.min(value, data.maxDate); + return value; + }, + getBoundary(type, innerValue) { + const value = new Date(innerValue); + const boundary = new Date(this.data[`${type}Date`]); + const year = boundary.getFullYear(); + let month = 1; + let date = 1; + let hour = 0; + let minute = 0; + if (type === 'max') { + month = 12; + date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1); + hour = 23; + minute = 59; + } + if (value.getFullYear() === year) { + month = boundary.getMonth() + 1; + if (value.getMonth() + 1 === month) { + date = boundary.getDate(); + if (value.getDate() === date) { + hour = boundary.getHours(); + if (value.getHours() === hour) { + minute = boundary.getMinutes(); + } + } + } + } + return { + [`${type}Year`]: year, + [`${type}Month`]: month, + [`${type}Date`]: date, + [`${type}Hour`]: hour, + [`${type}Minute`]: minute + }; + }, + onCancel() { + this.$emit('cancel'); + }, + onConfirm() { + this.$emit('confirm', this.data.innerValue); + }, + onChange() { + const { data } = this; + let value; + const picker = this.getPicker(); + if (data.type === 'time') { + const indexes = picker.getIndexes(); + value = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1].values[indexes[1]]}`; + } + else { + const values = picker.getValues(); + const year = getTrueValue(values[0]); + const month = getTrueValue(values[1]); + const maxDate = getMonthEndDay(year, month); + let date = getTrueValue(values[2]); + if (data.type === 'year-month') { + date = 1; + } + date = date > maxDate ? maxDate : date; + let hour = 0; + let minute = 0; + if (data.type === 'datetime') { + hour = getTrueValue(values[3]); + minute = getTrueValue(values[4]); + } + value = new Date(year, month - 1, date, hour, minute); + } + value = this.correctValue(value); + this.updateColumnValue(value).then(() => { + this.$emit('input', value); + this.$emit('change', picker); + }); + }, + updateColumnValue(value) { + let values = []; + const { type, formatter = defaultFormatter } = this.data; + const picker = this.getPicker(); + if (type === 'time') { + const pair = value.split(':'); + values = [ + formatter('hour', pair[0]), + formatter('minute', pair[1]) + ]; + } + else { + const date = new Date(value); + values = [ + formatter('year', `${date.getFullYear()}`), + formatter('month', padZero(date.getMonth() + 1)) + ]; + if (type === 'date') { + values.push(formatter('day', padZero(date.getDate()))); + } + if (type === 'datetime') { + values.push(formatter('day', padZero(date.getDate())), formatter('hour', padZero(date.getHours())), formatter('minute', padZero(date.getMinutes()))); + } + } + return this.set({ innerValue: value }) + .then(() => this.updateColumns()) + .then(() => picker.setValues(values)); + } + }, + created() { + const innerValue = this.correctValue(this.data.value); + this.updateColumnValue(innerValue).then(() => { + this.$emit('input', innerValue); + }); + } +}); diff --git a/components/datetime-picker/index.json b/components/datetime-picker/index.json new file mode 100644 index 0000000..a778e91 --- /dev/null +++ b/components/datetime-picker/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-picker": "../picker/index" + } +} diff --git a/components/datetime-picker/index.wxml b/components/datetime-picker/index.wxml new file mode 100644 index 0000000..ade2202 --- /dev/null +++ b/components/datetime-picker/index.wxml @@ -0,0 +1,16 @@ + diff --git a/components/datetime-picker/index.wxss b/components/datetime-picker/index.wxss new file mode 100644 index 0000000..99694d6 --- /dev/null +++ b/components/datetime-picker/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss'; \ No newline at end of file diff --git a/components/dialog/dialog.js b/components/dialog/dialog.js new file mode 100644 index 0000000..19aab17 --- /dev/null +++ b/components/dialog/dialog.js @@ -0,0 +1,68 @@ +let queue = []; + +function getContext() { + const pages = getCurrentPages(); + return pages[pages.length - 1]; +} +const Dialog = options => { + options = Object.assign(Object.assign({}, Dialog.currentOptions), options); + return new Promise((resolve, reject) => { + const context = options.context || getContext(); + const dialog = context.selectComponent(options.selector); + delete options.context; + delete options.selector; + if (dialog) { + dialog.setData(Object.assign({ + onCancel: reject, + onConfirm: resolve + }, options)); + queue.push(dialog); + } else { + console.warn('未找到 van-dialog 节点,请确认 selector 及 context 是否正确'); + } + }); +}; +Dialog.defaultOptions = { + show: true, + title: '', + width: null, + message: '', + zIndex: 100, + overlay: true, + selector: '#van-dialog', + className: '', + asyncClose: false, + transition: 'scale', + customStyle: '', + messageAlign: '', + overlayStyle: '', + confirmButtonText: '确认', + cancelButtonText: '取消', + showConfirmButton: true, + showCancelButton: false, + closeOnClickOverlay: false, + confirmButtonOpenType: '' +}; +Dialog.alert = Dialog; +Dialog.confirm = options => Dialog(Object.assign({ + showCancelButton: true +}, options)); +Dialog.close = () => { + queue.forEach(dialog => { + dialog.close(); + }); + queue = []; +}; +Dialog.stopLoading = () => { + queue.forEach(dialog => { + dialog.stopLoading(); + }); +}; +Dialog.setDefaultOptions = options => { + Object.assign(Dialog.currentOptions, options); +}; +Dialog.resetDefaultOptions = () => { + Dialog.currentOptions = Object.assign({}, Dialog.defaultOptions); +}; +Dialog.resetDefaultOptions(); +export default Dialog; \ No newline at end of file diff --git a/components/dialog/index.js b/components/dialog/index.js new file mode 100644 index 0000000..f786e42 --- /dev/null +++ b/components/dialog/index.js @@ -0,0 +1,116 @@ +import { VantComponent } from '../common/component'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +import { GRAY, BLUE } from '../common/color'; +VantComponent({ + mixins: [button, openType], + props: { + show: { + type: Boolean, + observer(show) { + !show && this.stopLoading(); + } + }, + title: String, + message: String, + useSlot: Boolean, + className: String, + customStyle: String, + asyncClose: Boolean, + messageAlign: String, + overlayStyle: String, + useTitleSlot: Boolean, + showCancelButton: Boolean, + closeOnClickOverlay: Boolean, + confirmButtonOpenType: String, + width: null, + zIndex: { + type: Number, + value: 20 + }, + confirmButtonText: { + type: String, + value: '确认' + }, + cancelButtonText: { + type: String, + value: '取消' + }, + confirmButtonColor: { + type: String, + value: BLUE + }, + cancelButtonColor: { + type: String, + value: GRAY + }, + showConfirmButton: { + type: Boolean, + value: true + }, + overlay: { + type: Boolean, + value: true + }, + transition: { + type: String, + value: 'scale' + }, + logined: { + type: Boolean, + value: false + } + }, + data: { + loading: { + confirm: false, + cancel: false + } + }, + methods: { + onConfirm() { + this.handleAction('confirm'); + }, + onCancel() { + this.handleAction('cancel'); + }, + onClickOverlay() { + this.onClose('overlay'); + }, + handleAction(action) { + if (this.data.asyncClose) { + this.setData({ + [`loading.${action}`]: true + }); + } + if(!this.data.logined){ + this.onClose(action) + } + }, + close() { + this.setData({ + show: false + }); + }, + stopLoading() { + this.setData({ + loading: { + confirm: false, + cancel: false + } + }); + }, + onClose(action) { + if (!this.data.asyncClose) { + this.close(); + } + this.$emit('close', action); + // 把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading + this.$emit(action, { dialog: this }); + const callback = this.data[action === 'confirm' ? 'onConfirm' : 'onCancel']; + if (callback) { + callback(this); + } + } + } +}); diff --git a/components/dialog/index.json b/components/dialog/index.json new file mode 100644 index 0000000..e2ee09a --- /dev/null +++ b/components/dialog/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-popup": "../popup/index", + "van-button": "../button/index" + } +} diff --git a/components/dialog/index.wxml b/components/dialog/index.wxml new file mode 100644 index 0000000..d814a3c --- /dev/null +++ b/components/dialog/index.wxml @@ -0,0 +1,65 @@ + + + + + + {{ title }} + + + + + {{ message }} + + + + + {{ cancelButtonText }} + + + {{ confirmButtonText }} + + + \ No newline at end of file diff --git a/components/dialog/index.wxss b/components/dialog/index.wxss new file mode 100644 index 0000000..9e3d20f --- /dev/null +++ b/components/dialog/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-dialog{top:45%!important;overflow:hidden;width:320px;width:var(--dialog-width,320px);font-size:16px;font-size:var(--dialog-font-size,16px);border-radius:16rpx;border-radius:var(--dialog-border-radius,16rpx);background-color:#fff;background-color:var(--dialog-background-color,#fff)}@media (max-width:321px){.van-dialog{width:90%;width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{font-size:32rpx;color:#333333;text-align:center;padding-top:24px;padding-top:var(--dialog-header-padding-top,24px);font-weight:500;font-weight:var(--dialog-header-font-weight,500);line-height:24px;line-height:var(--dialog-header-line-height,24px)}.van-dialog__header--isolated{padding:24px 0;padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{overflow-y:auto;text-align:center;-webkit-overflow-scrolling:touch;font-size:14px;font-size:var(--dialog-message-font-size,14px);line-height:20px;line-height:var(--dialog-message-line-height,20px);max-height:60vh;max-height:var(--dialog-message-max-height,60vh);padding:24px;padding:var(--dialog-message-padding,24px)}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--has-title{padding-top:12px;padding-top:var(--dialog-has-title-message-padding-top,12px);color:#646566;color:var(--dialog-has-title-message-text-color,#646566)}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-dialog-bounce-leave-active{-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9);opacity:0} \ No newline at end of file diff --git a/components/divider/index.js b/components/divider/index.js new file mode 100644 index 0000000..73f833d --- /dev/null +++ b/components/divider/index.js @@ -0,0 +1,33 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + props: { + dashed: { + type: Boolean, + value: false + }, + hairline: { + type: Boolean, + value: false + }, + contentPosition: { + type: String, + value: '' + }, + fontSize: { + type: Number, + value: '' + }, + borderColor: { + type: String, + value: '' + }, + textColor: { + type: String, + value: '' + }, + customStyle: { + type: String, + value: '' + } + } +}); diff --git a/components/divider/index.json b/components/divider/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/components/divider/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/components/divider/index.wxml b/components/divider/index.wxml new file mode 100644 index 0000000..3237bb4 --- /dev/null +++ b/components/divider/index.wxml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/components/divider/index.wxss b/components/divider/index.wxss new file mode 100644 index 0000000..89e0bc2 --- /dev/null +++ b/components/divider/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-divider{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin:16px 0;margin:var(--divider-margin,24rpx 0);color:#969799;color:var(--divider-text-color,#969799);font-size:14px;font-size:var(--divider-font-size,14px);line-height:24px;line-height:var(--divider-line-height,24px);border:0 solid #ebedf0;border-color:var(--divider-border-color,#ebedf0)}.van-divider:after,.van-divider:before{display:block;-webkit-flex:1;flex:1;box-sizing:border-box;height:1px;border-color:inherit;border-style:inherit;border-width:1px 0 0}.van-divider:before{content:""}.van-divider--hairline:after,.van-divider--hairline:before{-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-divider--dashed{border-style:dashed}.van-divider--center:before,.van-divider--left:before,.van-divider--right:before{margin-right:16px;margin-right:var(--divider-content-padding,16px)}.van-divider--center:after,.van-divider--left:after,.van-divider--right:after{content:"";margin-left:16px;margin-left:var(--divider-content-padding,16px)}.van-divider--left:before{max-width:10%;max-width:var(--divider-content-left-width,10%)}.van-divider--right:after{max-width:10%;max-width:var(--divider-content-right-width,10%)} \ No newline at end of file diff --git a/components/empty/index.js b/components/empty/index.js new file mode 100644 index 0000000..0fee8a4 --- /dev/null +++ b/components/empty/index.js @@ -0,0 +1,20 @@ +import { VantComponent } from '../common/component'; +const PRESETS = ['error', 'search', 'default', 'network']; +VantComponent({ + props: { + description: String, + image: { + type: String, + value: 'default', + }, + }, + created() { + if (PRESETS.indexOf(this.data.image) !== -1) { + this.setData({ + imageUrl: `https://img.yzcdn.cn/vant/empty-image-${this.data.image}.png`, + }); + } else { + this.setData({ imageUrl: this.data.image }); + } + }, +}); diff --git a/components/empty/index.json b/components/empty/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/components/empty/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/components/empty/index.wxml b/components/empty/index.wxml new file mode 100644 index 0000000..1c28469 --- /dev/null +++ b/components/empty/index.wxml @@ -0,0 +1,15 @@ + + + + + + +

+ {{ description }} +

+ + + + \ No newline at end of file diff --git a/components/empty/index.wxss b/components/empty/index.wxss new file mode 100644 index 0000000..931518d --- /dev/null +++ b/components/empty/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-empty{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:32px 0}.van-empty__image{width:160px;height:160px}.van-empty__image__img{width:100%;height:100%}.van-empty__description{margin-top:16px;padding:0 60px;color:#969799;font-size:14px;line-height:20px}.van-empty__bottom{margin-top:24px} \ No newline at end of file diff --git a/components/field/index.js b/components/field/index.js new file mode 100644 index 0000000..088020f --- /dev/null +++ b/components/field/index.js @@ -0,0 +1,90 @@ +import { VantComponent } from '../common/component'; +import { commonProps, inputProps, textareaProps } from './props'; +VantComponent({ + field: true, + classes: ['input-class', 'right-icon-class'], + props: Object.assign(Object.assign(Object.assign(Object.assign({}, commonProps), inputProps), textareaProps), { size: String, icon: String, label: String, error: Boolean, center: Boolean, isLink: Boolean, leftIcon: String, rightIcon: String, autosize: [Boolean, Object], readonly: { + type: Boolean, + observer: 'setShowClear' + }, required: Boolean, iconClass: String, clearable: { + type: Boolean, + observer: 'setShowClear' + }, clickable: Boolean, inputAlign: String, customStyle: String, errorMessage: String, arrowDirection: String, showWordLimit: Boolean, errorMessageAlign: String, border: { + type: Boolean, + value: true + }, titleWidth: { + type: String, + value: '90px' + } }), + data: { + focused: false, + innerValue: '', + showClear: false + }, + created() { + this.value = this.data.value + this.setData({ innerValue: this.value }) + }, + methods: { + onInput(event) { + const { value = '' } = event.detail || {} + this.value = value + this.setShowClear() + this.emitChange() + }, + onFocus(event) { + this.focused = true + this.setShowClear() + this.$emit('focus', event.detail) + }, + onBlur(event) { + this.focused = false + this.setShowClear() + this.$emit('blur', event.detail) + }, + onClickIcon() { + this.$emit('click-icon') + }, + onClear() { + this.setData({ innerValue: '' }) + this.value = '' + this.setShowClear() + wx.nextTick(() => { + this.emitChange() + this.$emit('clear', '') + }); + }, + onConfirm(event) { + const { value = '' } = event.detail || {} + this.value = value + this.setShowClear() + this.$emit('confirm', value) + }, + setValue(value) { + this.value = value + this.setShowClear() + if (value === '') { + this.setData({ innerValue: '' }) + } + this.emitChange(); + }, + onLineChange(event) { + this.$emit('linechange', event.detail) + }, + onKeyboardHeightChange(event) { + this.$emit('keyboardheightchange', event.detail) + }, + emitChange() { + this.setData({ value: this.value }); + wx.nextTick(() => { + this.$emit('input', this.value); + this.$emit('change', this.value); + }) + }, + setShowClear() { + const { clearable, readonly, focused, value } = this.data + this.setData({ showClear: clearable && focused && !!value && !readonly }) + }, + noop() { } + } +}); diff --git a/components/field/index.json b/components/field/index.json new file mode 100644 index 0000000..8809c46 --- /dev/null +++ b/components/field/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-cell": "../cell/index", + "van-icon": "../icon/index" + } +} \ No newline at end of file diff --git a/components/field/index.wxml b/components/field/index.wxml new file mode 100644 index 0000000..46305f5 --- /dev/null +++ b/components/field/index.wxml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + {{ value.length }} + /{{ maxlength }} + + + {{ errorMessage }} + + \ No newline at end of file diff --git a/components/field/index.wxs b/components/field/index.wxs new file mode 100644 index 0000000..51b0378 --- /dev/null +++ b/components/field/index.wxs @@ -0,0 +1,21 @@ +/* eslint-disable */ +var utils = require('../wxs/utils.wxs'); + +function inputStyle(autosize) { + if (autosize.constructor === 'Object') { + var style = ''; + if (autosize.minHeight) { + style += 'min-height:' + utils.addUnit(autosize.minHeight) + ';'; + } + if (autosize.maxHeight) { + style += 'max-height:' + utils.addUnit(autosize.maxHeight) + ';'; + } + return style; + } + + return ''; +} + +module.exports = { + inputStyle: inputStyle +}; diff --git a/components/field/index.wxss b/components/field/index.wxss new file mode 100644 index 0000000..782b802 --- /dev/null +++ b/components/field/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-field{--cell-icon-size:16px;--cell-icon-size:var(--field-icon-size,16px)}.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{line-height:1.2em}.van-field__body--textarea,.van-field__input{min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__input{position:relative;display:block;box-sizing:border-box;width:100%;margin:0;padding:0;line-height:inherit;text-align:left;background-color:initial;border:0;resize:none;color:#323233;color:var(--field-input-text-color,#323233);height:24px;height:var(--cell-line-height,24px)}.van-field__input--textarea{height:18px;height:var(--field-text-area-min-height,18px);min-height:18px;min-height:var(--field-text-area-min-height,18px)}.van-field__input--error{color:#ee0a24;color:var(--field-input-error-text-color,#ee0a24)}.van-field__input--disabled{background-color:initial;opacity:1;color:#969799;color:var(--field-input-disabled-text-color,#969799)}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__placeholder{position:absolute;top:0;right:0;left:0;pointer-events:none;color:#969799;color:var(--field-placeholder-text-color,#969799)}.van-field__placeholder--error{color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;vertical-align:middle;padding:0 8px;padding:0 var(--padding-xs,8px);margin-right:-8px;margin-right:-var(--padding-xs,8px)}.van-field__button,.van-field__clear-root,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear-root{font-size:16px;font-size:var(--field-clear-icon-size,16px);color:#c8c9cc;color:var(--field-clear-icon-color,#c8c9cc)}.van-field__icon-container{font-size:16px;font-size:var(--field-icon-size,16px);color:#969799;color:var(--field-icon-container-color,#969799)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:8px;padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{text-align:left;font-size:12px;font-size:var(--field-error-message-text-font-size,12px);color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right}.van-field__word-limit{text-align:right;margin-top:4px;margin-top:var(--padding-base,4px);color:#646566;color:var(--field-word-limit-color,#646566);font-size:12px;font-size:var(--field-word-limit-font-size,12px);line-height:16px;line-height:var(--field-word-limit-line-height,16px)}.van-field__word-num{display:inline}.van-field__word-num--full{color:#ee0a24;color:var(--field-word-num-full-color,#ee0a24)} \ No newline at end of file diff --git a/components/field/props.js b/components/field/props.js new file mode 100644 index 0000000..bceb8fd --- /dev/null +++ b/components/field/props.js @@ -0,0 +1,63 @@ +export const commonProps = { + value: { + type: String, + observer(value) { + if (value !== this.value) { + this.setData({ innerValue: value }); + this.value = value; + } + } + }, + placeholder: String, + placeholderStyle: String, + placeholderClass: String, + disabled: Boolean, + maxlength: { + type: Number, + value: -1 + }, + cursorSpacing: { + type: Number, + value: 50 + }, + autoFocus: Boolean, + focus: Boolean, + cursor: { + type: Number, + value: -1 + }, + selectionStart: { + type: Number, + value: -1 + }, + selectionEnd: { + type: Number, + value: -1 + }, + adjustPosition: { + type: Boolean, + value: true + }, + holdKeyboard: Boolean +}; +export const inputProps = { + type: { + type: String, + value: 'text' + }, + password: Boolean, + confirmType: String, + confirmHold: Boolean +}; +export const textareaProps = { + autoHeight: Boolean, + fixed: Boolean, + showConfirmBar: { + type: Boolean, + value: true + }, + disableDefaultPadding: { + type: Boolean, + value: true + }, +}; diff --git a/components/goods-action-button/index.js b/components/goods-action-button/index.js new file mode 100644 index 0000000..513d921 --- /dev/null +++ b/components/goods-action-button/index.js @@ -0,0 +1,41 @@ +import { VantComponent } from '../common/component'; +import { link } from '../mixins/link'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +VantComponent({ + mixins: [link, button, openType], + relation: { + type: 'ancestor', + name: 'goods-action', + current: 'goods-action-button', + }, + props: { + text: String, + color: String, + loading: Boolean, + disabled: Boolean, + plain: Boolean, + type: { + type: String, + value: 'danger' + } + }, + mounted() { + this.updateStyle(); + }, + methods: { + onClick(event) { + this.$emit('click', event.detail); + this.jumpLink(); + }, + updateStyle() { + const { children = [] } = this.parent; + const { length } = children; + const index = children.indexOf(this); + this.setData({ + isFirst: index === 0, + isLast: index === length - 1 + }); + } + } +}); diff --git a/components/goods-action-button/index.json b/components/goods-action-button/index.json new file mode 100644 index 0000000..b567686 --- /dev/null +++ b/components/goods-action-button/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-button": "../button/index" + } +} diff --git a/components/goods-action-button/index.wxml b/components/goods-action-button/index.wxml new file mode 100644 index 0000000..499e1d0 --- /dev/null +++ b/components/goods-action-button/index.wxml @@ -0,0 +1,30 @@ + + + {{ text }} + + \ No newline at end of file diff --git a/components/goods-action-button/index.wxss b/components/goods-action-button/index.wxss new file mode 100644 index 0000000..cbc4b44 --- /dev/null +++ b/components/goods-action-button/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-goods-action-button{--button-warning-background-color:linear-gradient(90deg,#ffd01e,#ff8917);--button-warning-background-color:var(--goods-action-button-warning-color,linear-gradient(90deg,#ffd01e,#ff8917));--button-danger-background-color:linear-gradient(90deg,#ff6034,#ee0a24);--button-danger-background-color:var(--goods-action-button-danger-color,linear-gradient(90deg,#ff6034,#ee0a24));--button-default-height:40px;--button-default-height:var(--goods-action-button-height,40px);--button-line-height:40px;--button-line-height:var(--goods-action-button-height,40px);--button-plain-background-color:#fff;--button-plain-background-color:var(--goods-action-button-plain-color,#fff);display:block;--button-border-width:0}.van-goods-action-button--first{margin-left:5px;--button-border-radius:20px 0 0 20px;--button-border-radius:var(--goods-action-button-border-radius,20px) 0 0 var(--goods-action-button-border-radius,20px)}.van-goods-action-button--last{margin-right:5px;--button-border-radius:0 20px 20px 0;--button-border-radius:0 var(--goods-action-button-border-radius,20px) var(--goods-action-button-border-radius,20px) 0}.van-goods-action-button--first.van-goods-action-button--last{--button-border-radius:20px;--button-border-radius:var(--goods-action-button-border-radius,20px)}.van-goods-action-button--plain{--button-border-width:1px}.van-goods-action-button__inner{width:100%;font-weight:500!important;font-weight:var(--font-weight-bold,500)!important}@media (max-width:321px){.van-goods-action-button{font-size:13px}} \ No newline at end of file diff --git a/components/goods-action-icon/index.js b/components/goods-action-icon/index.js new file mode 100644 index 0000000..5a32e70 --- /dev/null +++ b/components/goods-action-icon/index.js @@ -0,0 +1,22 @@ +import { VantComponent } from '../common/component'; +import { link } from '../mixins/link'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +VantComponent({ + classes: ['icon-class', 'text-class'], + mixins: [link, button, openType], + props: { + text: String, + dot: Boolean, + info: String, + icon: String, + disabled: Boolean, + loading: Boolean + }, + methods: { + onClick(event) { + this.$emit('click', event.detail); + this.jumpLink(); + } + } +}); diff --git a/components/goods-action-icon/index.json b/components/goods-action-icon/index.json new file mode 100644 index 0000000..93bfe8a --- /dev/null +++ b/components/goods-action-icon/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-button": "../button/index" + } +} diff --git a/components/goods-action-icon/index.wxml b/components/goods-action-icon/index.wxml new file mode 100644 index 0000000..f3f0052 --- /dev/null +++ b/components/goods-action-icon/index.wxml @@ -0,0 +1,38 @@ + + + + + {{ text }} + + diff --git a/components/goods-action-icon/index.wxss b/components/goods-action-icon/index.wxss new file mode 100644 index 0000000..30fff3d --- /dev/null +++ b/components/goods-action-icon/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-goods-action-icon{border:none!important;width:50px!important;width:var(--goods-action-icon-height,50px)!important}.van-goods-action-icon__content{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:center;justify-content:center;height:100%;line-height:1;font-size:10px;font-size:var(--goods-action-icon-font-size,10px);color:#646566;color:var(--goods-action-icon-text-color,#646566)}.van-goods-action-icon__icon{margin-bottom:4px} \ No newline at end of file diff --git a/components/goods-action/index.js b/components/goods-action/index.js new file mode 100644 index 0000000..a0f36f5 --- /dev/null +++ b/components/goods-action/index.js @@ -0,0 +1,14 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + type: 'descendant', + name: 'goods-action-button', + current: 'goods-action', + }, + props: { + safeAreaInsetBottom: { + type: Boolean, + value: true + } + } +}); diff --git a/components/goods-action/index.json b/components/goods-action/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/goods-action/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/goods-action/index.wxml b/components/goods-action/index.wxml new file mode 100644 index 0000000..569450c --- /dev/null +++ b/components/goods-action/index.wxml @@ -0,0 +1,5 @@ + + + + + diff --git a/components/goods-action/index.wxss b/components/goods-action/index.wxss new file mode 100644 index 0000000..b5961be --- /dev/null +++ b/components/goods-action/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-goods-action{width: 750rpx;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;background-color:#fff;background-color:var(--goods-action-background-color,#fff)} \ No newline at end of file diff --git a/components/grid-item/index.js b/components/grid-item/index.js new file mode 100644 index 0000000..e75d9c4 --- /dev/null +++ b/components/grid-item/index.js @@ -0,0 +1,70 @@ +import { link } from '../mixins/link'; +import { VantComponent } from '../common/component'; +import { addUnit } from '../common/utils'; +VantComponent({ + relation: { + name: 'grid', + type: 'ancestor', + current: 'grid-item', + }, + classes: ['content-class', 'icon-class', 'text-class'], + mixins: [link], + props: { + icon: String, + dot: Boolean, + info: null, + text: String, + useSlot: Boolean + }, + data: { + viewStyle: '', + }, + mounted() { + this.updateStyle(); + }, + methods: { + updateStyle() { + if (!this.parent) { + return; + } + const { data, children } = this.parent; + const { columnNum, border, square, gutter, clickable, center } = data; + const width = `${100 / columnNum}%`; + const styleWrapper = []; + styleWrapper.push(`width: ${width}`); + if (square) { + styleWrapper.push(`padding-top: ${width}`); + } + if (gutter) { + const gutterValue = addUnit(gutter); + styleWrapper.push(`padding-right: ${gutterValue}`); + const index = children.indexOf(this); + if (index >= columnNum) { + styleWrapper.push(`margin-top: ${gutterValue}`); + } + } + let contentStyle = ''; + if (square && gutter) { + const gutterValue = addUnit(gutter); + contentStyle = ` + right: ${gutterValue}; + bottom: ${gutterValue}; + height: auto; + `; + } + this.setData({ + viewStyle: styleWrapper.join('; '), + contentStyle, + center, + border, + square, + gutter, + clickable + }); + }, + onClick() { + this.$emit('click'); + this.jumpLink(); + } + } +}); diff --git a/components/grid-item/index.json b/components/grid-item/index.json new file mode 100644 index 0000000..0a336c0 --- /dev/null +++ b/components/grid-item/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} diff --git a/components/grid-item/index.wxml b/components/grid-item/index.wxml new file mode 100644 index 0000000..061f43c --- /dev/null +++ b/components/grid-item/index.wxml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + {{ text }} + + + + + diff --git a/components/grid-item/index.wxss b/components/grid-item/index.wxss new file mode 100644 index 0000000..7f2e818 --- /dev/null +++ b/components/grid-item/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-grid-item{position:relative;float:left;box-sizing:border-box}.van-grid-item--square{height:0}.van-grid-item__content{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;box-sizing:border-box;height:100%;padding:16px 8px;padding:var(--grid-item-content-padding,16px 8px);background-color:#fff;background-color:var(--grid-item-content-background-color,#fff)}.van-grid-item__content:after{z-index:1;border-width:0 1px 1px 0;border-bottom-width:var(--border-width-base,1px);border-right-width:var(--border-width-base,1px);border-top-width:0}.van-grid-item__content--surround:after{border-width:1px;border-width:var(--border-width-base,1px)}.van-grid-item__content--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-grid-item__content--square{position:absolute;top:0;right:0;left:0}.van-grid-item__content--clickable:active{background-color:#f2f3f5;background-color:var(--grid-item-content-active-color,#f2f3f5)}.van-grid-item__icon{font-size:26px;font-size:var(--grid-item-icon-size,26px)}.van-grid-item__text{word-wrap:break-word;color:#646566;color:var(--grid-item-text-color,#646566);font-size:12px;font-size:var(--grid-item-text-font-size,12px)} \ No newline at end of file diff --git a/components/grid/index.js b/components/grid/index.js new file mode 100644 index 0000000..a56af1d --- /dev/null +++ b/components/grid/index.js @@ -0,0 +1,57 @@ +import { VantComponent } from '../common/component'; +import { addUnit } from '../common/utils'; +VantComponent({ + relation: { + name: 'grid-item', + type: 'descendant', + current: 'grid', + }, + props: { + square: { + type: Boolean, + observer: 'updateChildren' + }, + gutter: { + type: [Number, String], + value: 0, + observer: 'updateChildren' + }, + clickable: { + type: Boolean, + observer: 'updateChildren' + }, + columnNum: { + type: Number, + value: 4, + observer: 'updateChildren' + }, + center: { + type: Boolean, + value: true, + observer: 'updateChildren' + }, + border: { + type: Boolean, + value: true, + observer: 'updateChildren' + } + }, + data: { + viewStyle: '', + }, + created() { + const { gutter } = this.data; + if (gutter) { + this.setData({ + viewStyle: `padding-left: ${addUnit(gutter)}` + }); + } + }, + methods: { + updateChildren() { + this.children.forEach((child) => { + child.updateStyle(); + }); + } + } +}); diff --git a/components/grid/index.json b/components/grid/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/grid/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/grid/index.wxml b/components/grid/index.wxml new file mode 100644 index 0000000..c5a545f --- /dev/null +++ b/components/grid/index.wxml @@ -0,0 +1,3 @@ + + + diff --git a/components/grid/index.wxss b/components/grid/index.wxss new file mode 100644 index 0000000..327fc5e --- /dev/null +++ b/components/grid/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-grid{position:relative;box-sizing:border-box;overflow:hidden} \ No newline at end of file diff --git a/components/icon/index.js b/components/icon/index.js new file mode 100644 index 0000000..2cfe253 --- /dev/null +++ b/components/icon/index.js @@ -0,0 +1,27 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + props: { + dot: Boolean, + info: null, + size: null, + color: String, + customStyle: String, + classPrefix: { + type: String, + value: 'van-icon' + }, + name: { + type: String, + observer(val) { + this.setData({ + isImageName: val.indexOf('/') !== -1 + }); + } + } + }, + methods: { + onClick() { + this.$emit('click'); + } + } +}); diff --git a/components/icon/index.json b/components/icon/index.json new file mode 100644 index 0000000..bf0ebe0 --- /dev/null +++ b/components/icon/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-info": "../info/index" + } +} diff --git a/components/icon/index.wxml b/components/icon/index.wxml new file mode 100644 index 0000000..fe4065a --- /dev/null +++ b/components/icon/index.wxml @@ -0,0 +1,20 @@ + + + + + + diff --git a/components/icon/index.wxss b/components/icon/index.wxss new file mode 100644 index 0000000..aaafa1e --- /dev/null +++ b/components/icon/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';@font-face{font-weight:400;font-family:vant-icon;font-style:normal;font-display:auto;src:url(https://img.yzcdn.cn/vant/vant-icon-d3825a.woff) format("woff"),url(https://img.yzcdn.cn/vant/vant-icon-d3825a.ttf) format("truetype")}.van-icon{position:relative;font:normal normal normal 14px/1 vant-icon;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased}.van-icon,.van-icon:before{display:inline-block}.van-icon-add-o:before{content:"\F000"}.van-icon-add-square:before{content:"\F001"}.van-icon-add:before{content:"\F002"}.van-icon-after-sale:before{content:"\F003"}.van-icon-aim:before{content:"\F004"}.van-icon-alipay:before{content:"\F005"}.van-icon-apps-o:before{content:"\F006"}.van-icon-arrow-down:before{content:"\F007"}.van-icon-arrow-left:before{content:"\F008"}.van-icon-arrow-up:before{content:"\F009"}.van-icon-arrow:before{content:"\F00A"}.van-icon-ascending:before{content:"\F00B"}.van-icon-audio:before{content:"\F00C"}.van-icon-award-o:before{content:"\F00D"}.van-icon-award:before{content:"\F00E"}.van-icon-bag-o:before{content:"\F00F"}.van-icon-bag:before{content:"\F010"}.van-icon-balance-list-o:before{content:"\F011"}.van-icon-balance-list:before{content:"\F012"}.van-icon-balance-o:before{content:"\F013"}.van-icon-balance-pay:before{content:"\F014"}.van-icon-bar-chart-o:before{content:"\F015"}.van-icon-bars:before{content:"\F016"}.van-icon-bell:before{content:"\F017"}.van-icon-bill-o:before{content:"\F018"}.van-icon-bill:before{content:"\F019"}.van-icon-birthday-cake-o:before{content:"\F01A"}.van-icon-bookmark-o:before{content:"\F01B"}.van-icon-bookmark:before{content:"\F01C"}.van-icon-browsing-history-o:before{content:"\F01D"}.van-icon-browsing-history:before{content:"\F01E"}.van-icon-brush-o:before{content:"\F01F"}.van-icon-bulb-o:before{content:"\F020"}.van-icon-bullhorn-o:before{content:"\F021"}.van-icon-calender-o:before{content:"\F022"}.van-icon-card:before{content:"\F023"}.van-icon-cart-circle-o:before{content:"\F024"}.van-icon-cart-circle:before{content:"\F025"}.van-icon-cart-o:before{content:"\F026"}.van-icon-cart:before{content:"\F027"}.van-icon-cash-back-record:before{content:"\F028"}.van-icon-cash-on-deliver:before{content:"\F029"}.van-icon-cashier-o:before{content:"\F02A"}.van-icon-certificate:before{content:"\F02B"}.van-icon-chart-trending-o:before{content:"\F02C"}.van-icon-chat-o:before{content:"\F02D"}.van-icon-chat:before{content:"\F02E"}.van-icon-checked:before{content:"\F02F"}.van-icon-circle:before{content:"\F030"}.van-icon-clear:before{content:"\F031"}.van-icon-clock-o:before{content:"\F032"}.van-icon-clock:before{content:"\F033"}.van-icon-close:before{content:"\F034"}.van-icon-closed-eye:before{content:"\F035"}.van-icon-cluster-o:before{content:"\F036"}.van-icon-cluster:before{content:"\F037"}.van-icon-column:before{content:"\F038"}.van-icon-comment-circle-o:before{content:"\F039"}.van-icon-comment-circle:before{content:"\F03A"}.van-icon-comment-o:before{content:"\F03B"}.van-icon-comment:before{content:"\F03C"}.van-icon-completed:before{content:"\F03D"}.van-icon-contact:before{content:"\F03E"}.van-icon-coupon-o:before{content:"\F03F"}.van-icon-coupon:before{content:"\F040"}.van-icon-credit-pay:before{content:"\F041"}.van-icon-cross:before{content:"\F042"}.van-icon-debit-pay:before{content:"\F043"}.van-icon-delete:before{content:"\F044"}.van-icon-descending:before{content:"\F045"}.van-icon-description:before{content:"\F046"}.van-icon-desktop-o:before{content:"\F047"}.van-icon-diamond-o:before{content:"\F048"}.van-icon-diamond:before{content:"\F049"}.van-icon-discount:before{content:"\F04A"}.van-icon-down:before{content:"\F04B"}.van-icon-ecard-pay:before{content:"\F04C"}.van-icon-edit:before{content:"\F04D"}.van-icon-ellipsis:before{content:"\F04E"}.van-icon-empty:before{content:"\F04F"}.van-icon-envelop-o:before{content:"\F050"}.van-icon-exchange:before{content:"\F051"}.van-icon-expand-o:before{content:"\F052"}.van-icon-expand:before{content:"\F053"}.van-icon-eye-o:before{content:"\F054"}.van-icon-eye:before{content:"\F055"}.van-icon-fail:before{content:"\F056"}.van-icon-failure:before{content:"\F057"}.van-icon-filter-o:before{content:"\F058"}.van-icon-fire-o:before{content:"\F059"}.van-icon-fire:before{content:"\F05A"}.van-icon-flag-o:before{content:"\F05B"}.van-icon-flower-o:before{content:"\F05C"}.van-icon-free-postage:before{content:"\F05D"}.van-icon-friends-o:before{content:"\F05E"}.van-icon-friends:before{content:"\F05F"}.van-icon-gem-o:before{content:"\F060"}.van-icon-gem:before{content:"\F061"}.van-icon-gift-card-o:before{content:"\F062"}.van-icon-gift-card:before{content:"\F063"}.van-icon-gift-o:before{content:"\F064"}.van-icon-gift:before{content:"\F065"}.van-icon-gold-coin-o:before{content:"\F066"}.van-icon-gold-coin:before{content:"\F067"}.van-icon-good-job-o:before{content:"\F068"}.van-icon-good-job:before{content:"\F069"}.van-icon-goods-collect-o:before{content:"\F06A"}.van-icon-goods-collect:before{content:"\F06B"}.van-icon-graphic:before{content:"\F06C"}.van-icon-home-o:before{content:"\F06D"}.van-icon-hot-o:before{content:"\F06E"}.van-icon-hot-sale-o:before{content:"\F06F"}.van-icon-hot-sale:before{content:"\F070"}.van-icon-hot:before{content:"\F071"}.van-icon-hotel-o:before{content:"\F072"}.van-icon-idcard:before{content:"\F073"}.van-icon-info-o:before{content:"\F074"}.van-icon-info:before{content:"\F075"}.van-icon-invition:before{content:"\F076"}.van-icon-label-o:before{content:"\F077"}.van-icon-label:before{content:"\F078"}.van-icon-like-o:before{content:"\F079"}.van-icon-like:before{content:"\F07A"}.van-icon-live:before{content:"\F07B"}.van-icon-location-o:before{content:"\F07C"}.van-icon-location:before{content:"\F07D"}.van-icon-lock:before{content:"\F07E"}.van-icon-logistics:before{content:"\F07F"}.van-icon-manager-o:before{content:"\F080"}.van-icon-manager:before{content:"\F081"}.van-icon-map-marked:before{content:"\F082"}.van-icon-medal-o:before{content:"\F083"}.van-icon-medal:before{content:"\F084"}.van-icon-more-o:before{content:"\F085"}.van-icon-more:before{content:"\F086"}.van-icon-music-o:before{content:"\F087"}.van-icon-music:before{content:"\F088"}.van-icon-new-arrival-o:before{content:"\F089"}.van-icon-new-arrival:before{content:"\F08A"}.van-icon-new-o:before{content:"\F08B"}.van-icon-new:before{content:"\F08C"}.van-icon-newspaper-o:before{content:"\F08D"}.van-icon-notes-o:before{content:"\F08E"}.van-icon-orders-o:before{content:"\F08F"}.van-icon-other-pay:before{content:"\F090"}.van-icon-paid:before{content:"\F091"}.van-icon-passed:before{content:"\F092"}.van-icon-pause-circle-o:before{content:"\F093"}.van-icon-pause-circle:before{content:"\F094"}.van-icon-pause:before{content:"\F095"}.van-icon-peer-pay:before{content:"\F096"}.van-icon-pending-payment:before{content:"\F097"}.van-icon-phone-circle-o:before{content:"\F098"}.van-icon-phone-circle:before{content:"\F099"}.van-icon-phone-o:before{content:"\F09A"}.van-icon-phone:before{content:"\F09B"}.van-icon-photo-o:before{content:"\F09C"}.van-icon-photo:before{content:"\F09D"}.van-icon-photograph:before{content:"\F09E"}.van-icon-play-circle-o:before{content:"\F09F"}.van-icon-play-circle:before{content:"\F0A0"}.van-icon-play:before{content:"\F0A1"}.van-icon-plus:before{content:"\F0A2"}.van-icon-point-gift-o:before{content:"\F0A3"}.van-icon-point-gift:before{content:"\F0A4"}.van-icon-points:before{content:"\F0A5"}.van-icon-printer:before{content:"\F0A6"}.van-icon-qr-invalid:before{content:"\F0A7"}.van-icon-qr:before{content:"\F0A8"}.van-icon-question-o:before{content:"\F0A9"}.van-icon-question:before{content:"\F0AA"}.van-icon-records:before{content:"\F0AB"}.van-icon-refund-o:before{content:"\F0AC"}.van-icon-replay:before{content:"\F0AD"}.van-icon-scan:before{content:"\F0AE"}.van-icon-search:before{content:"\F0AF"}.van-icon-send-gift-o:before{content:"\F0B0"}.van-icon-send-gift:before{content:"\F0B1"}.van-icon-service-o:before{content:"\F0B2"}.van-icon-service:before{content:"\F0B3"}.van-icon-setting-o:before{content:"\F0B4"}.van-icon-setting:before{content:"\F0B5"}.van-icon-share:before{content:"\F0B6"}.van-icon-shop-collect-o:before{content:"\F0B7"}.van-icon-shop-collect:before{content:"\F0B8"}.van-icon-shop-o:before{content:"\F0B9"}.van-icon-shop:before{content:"\F0BA"}.van-icon-shopping-cart-o:before{content:"\F0BB"}.van-icon-shopping-cart:before{content:"\F0BC"}.van-icon-shrink:before{content:"\F0BD"}.van-icon-sign:before{content:"\F0BE"}.van-icon-smile-comment-o:before{content:"\F0BF"}.van-icon-smile-comment:before{content:"\F0C0"}.van-icon-smile-o:before{content:"\F0C1"}.van-icon-smile:before{content:"\F0C2"}.van-icon-star-o:before{content:"\F0C3"}.van-icon-star:before{content:"\F0C4"}.van-icon-stop-circle-o:before{content:"\F0C5"}.van-icon-stop-circle:before{content:"\F0C6"}.van-icon-stop:before{content:"\F0C7"}.van-icon-success:before{content:"\F0C8"}.van-icon-thumb-circle-o:before{content:"\F0C9"}.van-icon-thumb-circle:before{content:"\F0CA"}.van-icon-todo-list-o:before{content:"\F0CB"}.van-icon-todo-list:before{content:"\F0CC"}.van-icon-tosend:before{content:"\F0CD"}.van-icon-tv-o:before{content:"\F0CE"}.van-icon-umbrella-circle:before{content:"\F0CF"}.van-icon-underway-o:before{content:"\F0D0"}.van-icon-underway:before{content:"\F0D1"}.van-icon-upgrade:before{content:"\F0D2"}.van-icon-user-circle-o:before{content:"\F0D3"}.van-icon-user-o:before{content:"\F0D4"}.van-icon-video-o:before{content:"\F0D5"}.van-icon-video:before{content:"\F0D6"}.van-icon-vip-card-o:before{content:"\F0D7"}.van-icon-vip-card:before{content:"\F0D8"}.van-icon-volume-o:before{content:"\F0D9"}.van-icon-volume:before{content:"\F0DA"}.van-icon-wap-home-o:before{content:"\F0DB"}.van-icon-wap-home:before{content:"\F0DC"}.van-icon-wap-nav:before{content:"\F0DD"}.van-icon-warn-o:before{content:"\F0DE"}.van-icon-warning-o:before{content:"\F0DF"}.van-icon-warning:before{content:"\F0E0"}.van-icon-weapp-nav:before{content:"\F0E1"}.van-icon-wechat:before{content:"\F0E2"}.van-icon-youzan-shield:before{content:"\F0E3"}:host{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-icon--image{width:1em;height:1em}.van-icon__image{width:100%;height:100%}.van-icon__info{z-index:1} \ No newline at end of file diff --git a/components/image-cropper/index.js b/components/image-cropper/index.js new file mode 100644 index 0000000..89263fd --- /dev/null +++ b/components/image-cropper/index.js @@ -0,0 +1,1108 @@ +Component({ + properties: { + /** + * 图片路径 + */ + 'imgSrc': { + type: String + }, + srcList: { + type: Array, + value: [] + }, + /** + * 裁剪框高度 + */ + 'height': { + type: Number, + value: 320 + }, + /** + * 裁剪框宽度 + */ + 'width': { + type: Number, + value: 320 + }, + /** + * 裁剪框最小尺寸 + */ + 'min_width': { + type: Number, + value: 100 + }, + 'min_height': { + type: Number, + value: 100 + }, + /** + * 裁剪框最大尺寸 + */ + 'max_width': { + type: Number, + value: 300 + }, + 'max_height': { + type: Number, + value: 300 + }, + /** + * 裁剪框禁止拖动 + */ + 'disable_width': { + type: Boolean, + value: true + }, + 'disable_height': { + type: Boolean, + value: true + }, + /** + * 锁定裁剪框比例 + */ + 'disable_ratio': { + type: Boolean, + value: false + }, + /** + * 生成的图片尺寸相对剪裁框的比例 + */ + 'export_scale': { + type: Number, + value: 3 + }, + /** + * 生成的图片质量0-1 + */ + 'quality': { + type: Number, + value: 1 + }, + 'cut_top': { + type: Number, + value: null + }, + 'cut_left': { + type: Number, + value: null + }, + /** + * canvas上边距(不设置默认不显示) + */ + 'canvas_top': { + type: Number, + value: null + }, + /** + * canvas左边距(不设置默认不显示) + */ + 'canvas_left': { + type: Number, + value: null + }, + /** + * 图片宽度 + */ + 'img_width': { + type: null, + value: null + }, + /** + * 图片高度 + */ + 'img_height': { + type: null, + value: null + }, + /** + * 图片缩放比 + */ + 'scale': { + type: Number, + value: 1 + }, + /** + * 图片旋转角度 + */ + 'angle': { + type: Number, + value: 0 + }, + /** + * 最小缩放比 + */ + 'min_scale': { + type: Number, + value: 0.5 + }, + /** + * 最大缩放比 + */ + 'max_scale': { + type: Number, + value: 2 + }, + /** + * 是否禁用旋转 + */ + 'disable_rotate': { + type: Boolean, + value: true + }, + /** + * 是否限制移动范围(剪裁框只能在图片内) + */ + 'limit_move': { + type: Boolean, + value: true + }, + imageIndex: { + type: Number, + value: 0 + } + }, + data: { + el: 'image-cropper', //暂时无用 + info: wx.getSystemInfoSync(), + MOVE_THROTTLE: null, //触摸移动节流settimeout + MOVE_THROTTLE_FLAG: true, //节流标识 + INIT_IMGWIDTH: 0, //图片设置尺寸,此值不变(记录最初设定的尺寸) + INIT_IMGHEIGHT: 0, //图片设置尺寸,此值不变(记录最初设定的尺寸) + TIME_BG: null, //背景变暗延时函数 + TIME_CUT_CENTER: null, + _touch_img_relative: [{ + x: 0, + y: 0 + }], //鼠标和图片中心的相对位置 + _flag_cut_touch: false, //是否是拖动裁剪框 + _hypotenuse_length: 0, //双指触摸时斜边长度 + _flag_img_endtouch: false, //是否结束触摸 + _flag_bright: true, //背景是否亮 + _canvas_overflow: true, //canvas缩略图是否在屏幕外面 + _canvas_width: 200, + _canvas_height: 200, + origin_x: 0.5, //图片旋转中心 + origin_y: 0.5, //图片旋转中心 + _cut_animation: false, //是否开启图片和裁剪框过渡 + _img_top: wx.getSystemInfoSync().windowHeight / 2, //图片上边距 + _img_left: wx.getSystemInfoSync().windowWidth / 2, //图片左边距 + scrollLeft: 0, + cropList: [], + watch: { + //监听截取框宽高变化 + width(value, that) { + if (value < that.data.min_width) { + that.setData({ + width: that.data.min_width + }); + } + that._computeCutSize(); + }, + height(value, that) { + if (value < that.data.min_height) { + that.setData({ + height: that.data.min_height + }); + } + that._computeCutSize(); + }, + angle(value, that) { + //停止居中裁剪框,继续修改图片位置 + that._moveStop(); + if (that.data.limit_move) { + if (that.data.angle % 90) { + that.setData({ + angle: Math.round(that.data.angle / 90) * 90 + }) + return + } + } + }, + _cut_animation(value, that) { + //开启过渡300毫秒之后自动关闭 + clearTimeout(that.data._cut_animation_time); + if (value) { + that.data._cut_animation_time = setTimeout(() => { + that.setData({ + _cut_animation: false + }); + }, 300) + } + }, + limit_move(value, that) { + if (value) { + if (that.data.angle % 90) { + that.setData({ + angle: Math.round(that.data.angle / 90) * 90 + }); + } + that._imgMarginDetectionScale(); + !that.data._canvas_overflow && that._draw(); + } + }, + canvas_top(value, that) { + that._canvasDetectionPosition(); + }, + canvas_left(value, that) { + that._canvasDetectionPosition(); + }, + cut_top(value, that) { + that._cutDetectionPosition(); + if (that.data.limit_move) { + !that.data._canvas_overflow && that._draw(); + } + }, + cut_left(value, that) { + that._cutDetectionPosition(); + if (that.data.limit_move) { + !that.data._canvas_overflow && that._draw(); + } + } + } + }, + + observers: { + 'srcList': function () { + this.setImage() + }, + 'imageIndex': function () { + let scrollLeft = (this.data.imageIndex * 90 + 10) - (375 - 90) / 2 + this.setData({ + scrollLeft: scrollLeft + }) + } + }, + + attached() { + this.data.info = wx.getSystemInfoSync() + //启用数据监听 + this._watcher(); + this.data.INIT_IMGWIDTH = this.data.img_width + this.data.INIT_IMGHEIGHT = this.data.img_height + this.setData({ + _canvas_height: this.data.height, + _canvas_width: this.data.width, + }); + this._initCanvas(); + this.data.imgSrc && (this.data.imgSrc = this.data.imgSrc); + //根据开发者设置的图片目标尺寸计算实际尺寸 + this._initImageSize(); + //设置裁剪框大小>设置图片尺寸>绘制canvas + this._computeCutSize(); + //检查裁剪框是否在范围内 + this._cutDetectionPosition(); + //检查canvas是否在范围内 + this._canvasDetectionPosition(); + //初始化完成 + this.triggerEvent('load', { + cropper: this + }) + }, + methods: { + /** + * 上传图片 + */ + upload() { + let that = this; + wx.chooseImage({ + count: 1, + sizeType: ['original', 'compressed'], + sourceType: ['album', 'camera'], + success(res) { + const tempFilePaths = res.tempFilePaths[0]; + that.pushImg(tempFilePaths) + wx.showLoading({ + title: '加载中...' + }) + } + }) + }, + + setImage: function () { + var self = this + var src = this.data.srcList.length ? this.data.srcList[this.data.imageIndex] : null + if (src == null && src == '') { + return + } + var type = Object.prototype.toString.call(src) + if (type !== '[object String]') { // 字符串 + return + } + wx.showLoading({ + title: '正在加载图片...' + }) + wx.getImageInfo({ + src: src, + success: (res) => { + self.data.imageObject = res + self.data.imgSrc = res.path + //图片非本地路径需要换成本地路径 + + //计算最后图片尺寸 + self._imgComputeSize() + if (self.data.limit_move) { + //限制移动,不留空白处理 + self._imgMarginDetectionScale() + } + self._draw() + }, + fail: (err) => { + self.setData({ + imgSrc: '' + }) + } + }) + }, + /** + * 返回图片信息 + */ + cropImage() { + wx.showLoading({ + title: '正在裁剪...' + }) + this._draw(() => { + wx.canvasToTempFilePath({ + width: this.data.width * this.data.export_scale, + height: Math.round(this.data.height * this.data.export_scale), + destWidth: this.data.width * this.data.export_scale, + destHeight: Math.round(this.data.height) * this.data.export_scale, + fileType: 'png', + quality: this.data.quality, + canvasId: this.data.el, + success: (res) => { + wx.hideLoading() + this.data.cropList.push(res.tempFilePath) + this.data.imageIndex++ + if (this.data.imageIndex < this.data.srcList.length) { + this.setImage() + } else { + this.triggerEvent('croped', this.data.cropList) + this.data.cropList = [] + this.data.imageIndex = 0 + } + } + }, this) + }); + }, + /** + * 设置图片动画 + * { + * x:10,//图片在原有基础上向下移动10px + * y:10,//图片在原有基础上向右移动10px + * angle:10,//图片在原有基础上旋转10deg + * scale:0.5,//图片在原有基础上增加0.5倍 + * } + */ + setTransform(transform) { + if (!transform) return; + if (!this.data.disable_rotate) { + this.setData({ + angle: transform.angle ? this.data.angle + transform.angle : this.data.angle + }); + } + var scale = this.data.scale; + if (transform.scale) { + scale = this.data.scale + transform.scale; + scale = scale <= this.data.min_scale ? this.data.min_scale : scale; + scale = scale >= this.data.max_scale ? this.data.max_scale : scale; + } + this.data.scale = scale; + let cutX = this.data.cut_left; + let cutY = this.data.cut_top; + if (transform.cutX) { + this.setData({ + cut_left: cutX + transform.cutX + }); + this.data.watch.cut_left(null, this); + } + if (transform.cutY) { + this.setData({ + cut_top: cutY + transform.cutY + }); + this.data.watch.cut_top(null, this); + } + this.data._img_top = transform.y ? this.data._img_top + transform.y : this.data._img_top; + this.data._img_left = transform.x ? this.data._img_left + transform.x : this.data._img_left; + //图像边缘检测,防止截取到空白 + this._imgMarginDetectionScale(); + //停止居中裁剪框,继续修改图片位置 + this._moveDuring(); + this.setData({ + scale: this.data.scale, + _img_top: this.data._img_top, + _img_left: this.data._img_left + }); + !this.data._canvas_overflow && this._draw(); + //可以居中裁剪框了 + this._moveStop(); //结束操作 + }, + /** + * 设置剪裁框位置 + */ + setCutXY(x, y) { + this.setData({ + cut_top: y, + cut_left: x + }); + }, + /** + * 设置剪裁框尺寸 + */ + setCutSize(w, h) { + this.setData({ + width: w, + height: h + }); + this._computeCutSize(); + }, + + _setCutCenter() { + let cut_top = (this.data.info.windowHeight - this.data.height) * 0.5; + let cut_left = (this.data.info.windowWidth - this.data.width) * 0.5; + this.setData({ + cut_top: cut_top, //截取的框上边距 + cut_left: cut_left, //截取的框左边距 + }); + }, + /** + * 设置剪裁框宽度-即将废弃 + */ + setWidth(width) { + this.setData({ + width: width + }); + this._computeCutSize(); + }, + /** + * 设置剪裁框高度-即将废弃 + */ + setHeight(height) { + this.setData({ + height: height + }); + this._computeCutSize(); + }, + /** + * 是否锁定旋转 + */ + setDisableRotate(value) { + this.data.disable_rotate = value; + }, + /** + * 是否限制移动 + */ + setLimitMove(value) { + this.setData({ + _cut_animation: true, + limit_move: !!value + }); + }, + //关闭 + close: function () { + this.triggerEvent('close', {}) + }, + rotate: function () { + var angle = this.data.angle + 90 + this.setAngle(angle) + }, + /** + * 初始化图片,包括位置、大小、旋转角度 + */ + reset() { + this.setData({ + scale: 1, + angle: 0, + _img_top: wx.getSystemInfoSync().windowHeight / 2, + _img_left: wx.getSystemInfoSync().windowWidth / 2 + }) + }, + + imageLoad: function (e) { + this.reset() + this.triggerEvent('imageload', this.data.imageObject) + wx.hideLoading() + }, + /** + * 设置图片放大缩小 + */ + setScale(scale) { + if (!scale) return; + this.setData({ + scale: scale + }); + !this.data._canvas_overflow && this._draw(); + }, + /** + * 设置图片旋转角度 + */ + setAngle(angle) { + if (!angle) return; + this.setData({ + _cut_animation: true, + angle: angle + }); + this._imgMarginDetectionScale(); + !this.data._canvas_overflow && this._draw(); + }, + _initCanvas() { + //初始化canvas + if (!this.data.ctx) { + this.data.ctx = wx.createCanvasContext("image-cropper", this); + } + }, + /** + * 根据开发者设置的图片目标尺寸计算实际尺寸 + */ + _initImageSize() { + //处理宽高特殊单位 %>px + if (this.data.INIT_IMGWIDTH && typeof this.data.INIT_IMGWIDTH == "string" && this.data.INIT_IMGWIDTH.indexOf("%") != -1) { + let width = this.data.INIT_IMGWIDTH.replace("%", ""); + this.data.INIT_IMGWIDTH = this.data.img_width = this.data.info.windowWidth / 100 * width; + } + if (this.data.INIT_IMGHEIGHT && typeof this.data.INIT_IMGHEIGHT == "string" && this.data.INIT_IMGHEIGHT.indexOf("%") != -1) { + let height = this.data.img_height.replace("%", ""); + this.data.INIT_IMGHEIGHT = this.data.img_height = this.data.info.windowHeight / 100 * height; + } + }, + /** + * 检测剪裁框位置是否在允许的范围内(屏幕内) + */ + _cutDetectionPosition() { + let _cutDetectionPositionTop = () => { + //检测上边距是否在范围内 + if (this.data.cut_top < 0) { + this.setData({ + cut_top: 0 + }); + } + if (this.data.cut_top > this.data.info.windowHeight - this.data.height) { + this.setData({ + cut_top: this.data.info.windowHeight - this.data.height + }); + } + }, + _cutDetectionPositionLeft = () => { + //检测左边距是否在范围内 + if (this.data.cut_left < 0) { + this.setData({ + cut_left: 0 + }); + } + if (this.data.cut_left > this.data.info.windowWidth - this.data.width) { + this.setData({ + cut_left: this.data.info.windowWidth - this.data.width + }); + } + }; + //裁剪框坐标处理(如果只写一个参数则另一个默认为0,都不写默认居中) + if (this.data.cut_top == null && this.data.cut_left == null) { + this._setCutCenter(); + } else if (this.data.cut_top != null && this.data.cut_left != null) { + _cutDetectionPositionTop(); + _cutDetectionPositionLeft(); + } else if (this.data.cut_top != null && this.data.cut_left == null) { + _cutDetectionPositionTop(); + this.setData({ + cut_left: (this.data.info.windowWidth - this.data.width) / 2 + }); + } else if (this.data.cut_top == null && this.data.cut_left != null) { + _cutDetectionPositionLeft(); + this.setData({ + cut_top: (this.data.info.windowHeight - this.data.height) / 2 + }); + } + }, + /** + * 检测canvas位置是否在允许的范围内(屏幕内)如果在屏幕外则不开启实时渲染 + * 如果只写一个参数则另一个默认为0,都不写默认超出屏幕外 + */ + _canvasDetectionPosition() { + if (this.data.canvas_top == null && this.data.canvas_left == null) { + this.data._canvas_overflow = false; + this.setData({ + canvas_top: -5000, + canvas_left: -5000 + }); + } else if (this.data.canvas_top != null && this.data.canvas_left != null) { + if (this.data.canvas_top < -this.data.height || this.data.canvas_top > this.data.info.windowHeight) { + this.data._canvas_overflow = true; + } else { + this.data._canvas_overflow = false; + } + } else if (this.data.canvas_top != null && this.data.canvas_left == null) { + this.setData({ + canvas_left: 0 + }); + } else if (this.data.canvas_top == null && this.data.canvas_left != null) { + this.setData({ + canvas_top: 0 + }); + if (this.data.canvas_left < -this.data.width || this.data.canvas_left > this.data.info.windowWidth) { + this.data._canvas_overflow = true; + } else { + this.data._canvas_overflow = false; + } + } + }, + /** + * 图片边缘检测-位置 + */ + _imgMarginDetectionPosition(scale) { + if (!this.data.limit_move) return; + let left = this.data._img_left; + let top = this.data._img_top; + var scale = scale || this.data.scale; + let img_width = this.data.img_width; + let img_height = this.data.img_height; + if (this.data.angle / 90 % 2) { + img_width = this.data.img_height; + img_height = this.data.img_width; + } + left = this.data.cut_left + img_width * scale / 2 >= left ? left : this.data.cut_left + img_width * scale / 2; + left = this.data.cut_left + this.data.width - img_width * scale / 2 <= left ? left : this.data.cut_left + this.data.width - img_width * scale / 2; + top = this.data.cut_top + img_height * scale / 2 >= top ? top : this.data.cut_top + img_height * scale / 2; + top = this.data.cut_top + this.data.height - img_height * scale / 2 <= top ? top : this.data.cut_top + this.data.height - img_height * scale / 2; + this.setData({ + _img_left: left, + _img_top: top, + scale: scale + }) + }, + /** + * 图片边缘检测-缩放 + */ + _imgMarginDetectionScale() { + if (!this.data.limit_move) return; + let scale = this.data.scale; + let img_width = this.data.img_width; + let img_height = this.data.img_height; + if (this.data.angle / 90 % 2) { + img_width = this.data.img_height; + img_height = this.data.img_width; + } + if (img_width * scale < this.data.width) { + scale = this.data.width / img_width; + } + if (img_height * scale < this.data.height) { + scale = Math.max(scale, this.data.height / img_height); + } + this._imgMarginDetectionPosition(scale); + }, + _setData(obj) { + let data = {}; + for (var key in obj) { + if (this.data[key] != obj[key]) { + data[key] = obj[key]; + } + } + this.setData(data); + return data; + }, + /** + * 计算图片尺寸 + */ + _imgComputeSize() { + let img_width = this.data.img_width, + img_height = this.data.img_height; + if (!this.data.INIT_IMGHEIGHT && !this.data.INIT_IMGWIDTH) { + //默认按图片最小边 = 对应裁剪框尺寸 + img_width = this.data.imageObject.width; + img_height = this.data.imageObject.height; + if (img_width / img_height > this.data.width / this.data.height) { + img_height = this.data.height; + img_width = this.data.imageObject.width / this.data.imageObject.height * img_height; + } else { + img_width = this.data.width; + img_height = this.data.imageObject.height / this.data.imageObject.width * img_width; + } + } else if (this.data.INIT_IMGHEIGHT && !this.data.INIT_IMGWIDTH) { + img_width = this.data.imageObject.width / this.data.imageObject.height * this.data.INIT_IMGHEIGHT; + } else if (!this.data.INIT_IMGHEIGHT && this.data.INIT_IMGWIDTH) { + img_height = this.data.imageObject.height / this.data.imageObject.width * this.data.INIT_IMGWIDTH; + } + this.setData({ + img_width: img_width, + img_height: img_height, + imgSrc: this.data.imgSrc, + imageIndex: this.data.imageIndex + }) + }, + //改变截取框大小 + _computeCutSize() { + if (this.data.width > this.data.info.windowWidth) { + this.setData({ + width: this.data.info.windowWidth, + }); + } else if (this.data.width + this.data.cut_left > this.data.info.windowWidth) { + this.setData({ + cut_left: this.data.info.windowWidth - this.data.cut_left, + }); + }; + if (this.data.height > this.data.info.windowHeight) { + this.setData({ + height: this.data.info.windowHeight, + }); + } else if (this.data.height + this.data.cut_top > this.data.info.windowHeight) { + this.setData({ + cut_top: this.data.info.windowHeight - this.data.cut_top, + }); + }!this.data._canvas_overflow && this._draw(); + }, + //开始触摸 + _start(event) { + this.data._flag_img_endtouch = false; + if (event.touches.length == 1) { + //单指拖动 + this.data._touch_img_relative[0] = { + x: (event.touches[0].clientX - this.data._img_left), + y: (event.touches[0].clientY - this.data._img_top) + } + } else { + //双指放大 + let width = Math.abs(event.touches[0].clientX - event.touches[1].clientX); + let height = Math.abs(event.touches[0].clientY - event.touches[1].clientY); + this.data._touch_img_relative = [{ + x: (event.touches[0].clientX - this.data._img_left), + y: (event.touches[0].clientY - this.data._img_top) + }, { + x: (event.touches[1].clientX - this.data._img_left), + y: (event.touches[1].clientY - this.data._img_top) + }]; + this.data._hypotenuse_length = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + }!this.data._canvas_overflow && this._draw(); + }, + _move_throttle() { + //安卓需要节流 + if (this.data.info.platform == 'android') { + clearTimeout(this.data.MOVE_THROTTLE); + this.data.MOVE_THROTTLE = setTimeout(() => { + this.data.MOVE_THROTTLE_FLAG = true; + }, 1000 / 40) + return this.data.MOVE_THROTTLE_FLAG; + } else { + this.data.MOVE_THROTTLE_FLAG = true; + } + }, + _move(event) { + if (this.data._flag_img_endtouch || !this.data.MOVE_THROTTLE_FLAG) return; + this.data.MOVE_THROTTLE_FLAG = false; + this._move_throttle(); + this._moveDuring(); + if (event.touches.length == 1) { + //单指拖动 + let left = (event.touches[0].clientX - this.data._touch_img_relative[0].x), + top = (event.touches[0].clientY - this.data._touch_img_relative[0].y); + //图像边缘检测,防止截取到空白 + this.data._img_left = left; + this.data._img_top = top; + this._imgMarginDetectionPosition(); + this.setData({ + _img_left: this.data._img_left, + _img_top: this.data._img_top + }); + } else { + //双指放大 + let width = (Math.abs(event.touches[0].clientX - event.touches[1].clientX)), + height = (Math.abs(event.touches[0].clientY - event.touches[1].clientY)), + hypotenuse = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)), + scale = this.data.scale * (hypotenuse / this.data._hypotenuse_length), + current_deg = 0; + scale = scale <= this.data.min_scale ? this.data.min_scale : scale; + scale = scale >= this.data.max_scale ? this.data.max_scale : scale; + //图像边缘检测,防止截取到空白 + this.data.scale = scale; + this._imgMarginDetectionScale(); + //双指旋转(如果没禁用旋转) + let _touch_img_relative = [{ + x: (event.touches[0].clientX - this.data._img_left), + y: (event.touches[0].clientY - this.data._img_top) + }, { + x: (event.touches[1].clientX - this.data._img_left), + y: (event.touches[1].clientY - this.data._img_top) + }]; + if (!this.data.disable_rotate) { + let first_atan = 180 / Math.PI * Math.atan2(_touch_img_relative[0].y, _touch_img_relative[0].x); + let first_atan_old = 180 / Math.PI * Math.atan2(this.data._touch_img_relative[0].y, this.data._touch_img_relative[0].x); + let second_atan = 180 / Math.PI * Math.atan2(_touch_img_relative[1].y, _touch_img_relative[1].x); + let second_atan_old = 180 / Math.PI * Math.atan2(this.data._touch_img_relative[1].y, this.data._touch_img_relative[1].x); + //当前旋转的角度 + let first_deg = first_atan - first_atan_old, + second_deg = second_atan - second_atan_old; + if (first_deg != 0) { + current_deg = first_deg; + } else if (second_deg != 0) { + current_deg = second_deg; + } + } + this.data._touch_img_relative = _touch_img_relative; + this.data._hypotenuse_length = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + //更新视图 + this.setData({ + angle: this.data.angle + current_deg, + scale: this.data.scale + }); + }!this.data._canvas_overflow && this._draw(); + }, + //结束操作 + _end(event) { + this.data._flag_img_endtouch = true; + this._moveStop(); + }, + //渲染 + _draw(callback) { + let draw = () => { + //图片实际大小 + let img_width = this.data.img_width * this.data.scale * this.data.export_scale; + let img_height = this.data.img_height * this.data.scale * this.data.export_scale; + //canvas和图片的相对距离 + var xpos = this.data._img_left - this.data.cut_left; + var ypos = this.data._img_top - this.data.cut_top; + //旋转画布 + this.data.ctx.translate(xpos * this.data.export_scale, ypos * this.data.export_scale); + this.data.ctx.rotate(this.data.angle * Math.PI / 180); + this.data.ctx.drawImage(this.data.imgSrc, -img_width / 2, -img_height / 2, img_width, img_height); + this.data.ctx.draw(false, () => { + callback && callback() + }) + } + if (this.data.ctx.width != this.data.width || this.data.ctx.height != this.data.height) { + //优化拖动裁剪框,所以必须把宽高设置放在离用户触发渲染最近的地方 + this.setData({ + _canvas_height: this.data.height, + _canvas_width: this.data.width, + }, () => { + //延迟40毫秒防止点击过快出现拉伸或裁剪过多 + setTimeout(() => { + draw() + }, 40) + }); + } else { + draw() + } + }, + //裁剪框处理 + _cutTouchMove(e) { + if (this.data._flag_cut_touch && this.data.MOVE_THROTTLE_FLAG) { + if (this.data.disable_ratio && (this.data.disable_width || this.data.disable_height)){ + return + } + //节流 + this.data.MOVE_THROTTLE_FLAG = false + this._move_throttle(); + let width = this.data.width, + height = this.data.height, + cut_top = this.data.cut_top, + cut_left = this.data.cut_left, + size_correct = () => { + width = width <= this.data.max_width ? width >= this.data.min_width ? width : this.data.min_width : this.data.max_width; + height = height <= this.data.max_height ? height >= this.data.min_height ? height : this.data.min_height : this.data.max_height; + }, + size_inspect = () => { + if ((width > this.data.max_width || width < this.data.min_width || height > this.data.max_height || height < this.data.min_height) && this.data.disable_ratio) { + size_correct(); + return false; + } else { + size_correct(); + return true; + } + }; + height = this.data.CUT_START.height + ((this.data.CUT_START.corner > 1 && this.data.CUT_START.corner < 4 ? 1 : -1) * (this.data.CUT_START.y - e.touches[0].clientY)); + switch (this.data.CUT_START.corner) { + case 1: + width = this.data.CUT_START.width + this.data.CUT_START.x - e.touches[0].clientX; + if (this.data.disable_ratio) { + height = width / (this.data.width / this.data.height) + } + if (!size_inspect()) return; + cut_left = this.data.CUT_START.cut_left - (width - this.data.CUT_START.width); + break + case 2: + width = this.data.CUT_START.width + this.data.CUT_START.x - e.touches[0].clientX; + if (this.data.disable_ratio) { + height = width / (this.data.width / this.data.height) + } + if (!size_inspect()) return; + cut_top = this.data.CUT_START.cut_top - (height - this.data.CUT_START.height) + cut_left = this.data.CUT_START.cut_left - (width - this.data.CUT_START.width) + break + case 3: + width = this.data.CUT_START.width - this.data.CUT_START.x + e.touches[0].clientX; + if (this.data.disable_ratio) { + height = width / (this.data.width / this.data.height) + } + if (!size_inspect()) return; + cut_top = this.data.CUT_START.cut_top - (height - this.data.CUT_START.height); + break + case 4: + width = this.data.CUT_START.width - this.data.CUT_START.x + e.touches[0].clientX; + if (this.data.disable_ratio) { + height = width / (this.data.width / this.data.height) + } + if (!size_inspect()) return; + break + } + if (!this.data.disable_width && !this.data.disable_height) { + this.setData({ + width: width, + cut_left: cut_left, + height: height, + cut_top: cut_top, + }) + } else if (!this.data.disable_width) { + this.setData({ + width: width, + cut_left: cut_left + }) + } else if (!this.data.disable_height) { + this.setData({ + height: height, + cut_top: cut_top + }) + } + this._imgMarginDetectionScale(); + } + }, + _cutTouchStart(e) { + let currentX = e.touches[0].clientX; + let currentY = e.touches[0].clientY; + let cutbox_top4 = this.data.cut_top + this.data.height - 30; + let cutbox_bottom4 = this.data.cut_top + this.data.height + 20; + let cutbox_left4 = this.data.cut_left + this.data.width - 30; + let cutbox_right4 = this.data.cut_left + this.data.width + 30; + + let cutbox_top3 = this.data.cut_top - 30; + let cutbox_bottom3 = this.data.cut_top + 30; + let cutbox_left3 = this.data.cut_left + this.data.width - 30; + let cutbox_right3 = this.data.cut_left + this.data.width + 30; + + let cutbox_top2 = this.data.cut_top - 30; + let cutbox_bottom2 = this.data.cut_top + 30; + let cutbox_left2 = this.data.cut_left - 30; + let cutbox_right2 = this.data.cut_left + 30; + + let cutbox_top1 = this.data.cut_top + this.data.height - 30; + let cutbox_bottom1 = this.data.cut_top + this.data.height + 30; + let cutbox_left1 = this.data.cut_left - 30; + let cutbox_right1 = this.data.cut_left + 30; + if (currentX > cutbox_left4 && currentX < cutbox_right4 && currentY > cutbox_top4 && currentY < cutbox_bottom4) { + this._moveDuring(); + this.data._flag_cut_touch = true; + this.data._flag_img_endtouch = true; + this.data.CUT_START = { + width: this.data.width, + height: this.data.height, + x: currentX, + y: currentY, + corner: 4 + } + } else if (currentX > cutbox_left3 && currentX < cutbox_right3 && currentY > cutbox_top3 && currentY < cutbox_bottom3) { + this._moveDuring(); + this.data._flag_cut_touch = true; + this.data._flag_img_endtouch = true; + this.data.CUT_START = { + width: this.data.width, + height: this.data.height, + x: currentX, + y: currentY, + cut_top: this.data.cut_top, + cut_left: this.data.cut_left, + corner: 3 + } + } else if (currentX > cutbox_left2 && currentX < cutbox_right2 && currentY > cutbox_top2 && currentY < cutbox_bottom2) { + this._moveDuring(); + this.data._flag_cut_touch = true; + this.data._flag_img_endtouch = true; + this.data.CUT_START = { + width: this.data.width, + height: this.data.height, + cut_top: this.data.cut_top, + cut_left: this.data.cut_left, + x: currentX, + y: currentY, + corner: 2 + } + } else if (currentX > cutbox_left1 && currentX < cutbox_right1 && currentY > cutbox_top1 && currentY < cutbox_bottom1) { + this._moveDuring(); + this.data._flag_cut_touch = true; + this.data._flag_img_endtouch = true; + this.data.CUT_START = { + width: this.data.width, + height: this.data.height, + cut_top: this.data.cut_top, + cut_left: this.data.cut_left, + x: currentX, + y: currentY, + corner: 1 + } + } + }, + _cutTouchEnd(e) { + this._moveStop(); + this.data._flag_cut_touch = false; + }, + //停止移动时需要做的操作 + _moveStop() { + //清空之前的自动居中延迟函数并添加最新的 + clearTimeout(this.data.TIME_CUT_CENTER); + this.data.TIME_CUT_CENTER = setTimeout(() => { + //动画启动 + if (!this.data._cut_animation) { + this.setData({ + _cut_animation: true + }) + } + // this.setCutCenter() + }, 1000) + //清空之前的背景变化延迟函数并添加最新的 + clearTimeout(this.data.TIME_BG); + this.data.TIME_BG = setTimeout(() => { + if (this.data._flag_bright) { + this.setData({ + _flag_bright: false + }); + } + }, 2000) + }, + //移动中 + _moveDuring() { + //清空之前的自动居中延迟函数 + clearTimeout(this.data.TIME_CUT_CENTER); + //清空之前的背景变化延迟函数 + clearTimeout(this.data.TIME_BG); + //高亮背景 + if (!this.data._flag_bright) { + this.setData({ + _flag_bright: true + }); + } + }, + //监听器 + _watcher() { + Object.keys(this.data).forEach(v => { + this._observe(this.data, v, this.data.watch[v]); + }) + }, + _observe(obj, key, watchFun) { + var val = obj[key]; + Object.defineProperty(obj, key, { + configurable: true, + enumerable: true, + set: (value) => { + val = value; + watchFun && watchFun(val, this); + }, + get() { + if (val && '_img_top|img_left||width|height|min_width|max_width|min_height|max_height|export_scale|cut_top|cut_left|canvas_top|canvas_left|img_width|img_height|scale|angle|min_scale|max_scale'.indexOf(key) != -1) { + let ret = parseFloat(parseFloat(val).toFixed(3)); + if (typeof val == "string" && val.indexOf("%") != -1) { + ret += '%'; + } + return ret; + } + return val; + } + }) + }, + _preventTouchMove() {} + } +}) \ No newline at end of file diff --git a/components/image-cropper/index.json b/components/image-cropper/index.json new file mode 100644 index 0000000..32640e0 --- /dev/null +++ b/components/image-cropper/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/image-cropper/index.wxml b/components/image-cropper/index.wxml new file mode 100644 index 0000000..89d6dd2 --- /dev/null +++ b/components/image-cropper/index.wxml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/image-cropper/index.wxss b/components/image-cropper/index.wxss new file mode 100644 index 0000000..22a78c4 --- /dev/null +++ b/components/image-cropper/index.wxss @@ -0,0 +1,291 @@ +.image-cropper{ + background:rgba(14, 13, 13); + position: fixed; + top:0; + left:0; + width:100vw; + height:100vh; + z-index: 999; +} +.main{ + position: absolute; + width:100vw; + height:100vh; + overflow: hidden; +} +.content{ + z-index: 995; + position: absolute; + width:100vw; + height:100vh; + display: flex; + flex-direction:column; + pointer-events:none; +} +.bg_black{ + background: rgba(0, 0, 0, 0.8)!important; +} +.bg_gray{ + background: rgba(0, 0, 0, 0.45); + transition-duration: .35s; +} +.content>.content_top{ + pointer-events:none; +} +.content>.content_middle{ + display: flex; + height: 200px; + width:100%; +} +.content_middle_middle{ + width:200px; + box-sizing:border-box; + position: relative; + transition-duration: .3s; +} +.content_middle_right{ + flex: auto; +} +.content>.content_bottom{ + flex: auto; +} +.image-cropper .img{ + z-index: 992; + top:0; + left:0; + position: absolute; + border:none; + width:100%; + backface-visibility: hidden; + transform-origin:center; +} +.image-cropper-canvas{ + position: fixed; + background: white; + width:150px; + height:150px; + z-index: 999; + top:-200%; + pointer-events:none; +} +.border{ + background: white; + pointer-events:auto; + position:absolute; +} +.border-top-left{ + left:-2.5px; + top:-2.5px; + height:2.5px; + width:33rpx; +} +.border-top-right{ + right:-2.5px; + top:-2.5px; + height:2.5px; + width:33rpx; +} +.border-right-top{ + top:-1px; + width:2.5px; + height:30rpx; + right:-2.5px; +} +.border-right-bottom{ + width:2.5px; + height:30rpx; + right:-2.5px; + bottom:-1px; +} +.border-bottom-left{ + height:2.5px; + width:33rpx; + bottom:-2.5px; + left:-2.5px; +} +.border-bottom-right{ + height:2.5px; + width:33rpx; + bottom:-2.5px; + right:-2.5px; +} +.border-left-top{ + top:-1px; + width:2.5px; + height:30rpx; + left:-2.5px; +} +.border-left-bottom{ + width:2.5px; + height:30rpx; + left:-2.5px; + bottom:-1px; +} + + +/* 旋转 */ +.image-cropper .crop-list { + width: 97.5%; + height: 200rpx; + position: absolute; + bottom: 100rpx; + padding: 10rpx; + left: 0; + right: 0; + white-space: nowrap; + display: flex; + z-index: 999; +} + +.image-cropper .crop-list .crop-image{ + height: 180rpx; + width: 180rpx; + margin: 6rpx; +} +.img_border{ + border: 4rpx solid #008AFF; +} +.start{ + justify-content:start +} +.center{ + justify-content: center; +} + +/* 旋转 */ +.image-cropper .crop-rotate { + width: 92%; + height: 66px; + position: absolute; + bottom: 68px; + left: 0; + right: 0; + margin: auto; + overflow: hidden; + -webkit-mask-image: linear-gradient(90deg, rgba(255, 255, 255, 0.00) 0%, rgba(255, 255, 255, 0.64) 50%, rgba(255, 255, 255, 0.00) 100%); + mask-image: linear-gradient(90deg, rgba(255, 255, 255, 0.00) 0%, rgba(255, 255, 255, 0.64) 50%, rgba(255, 255, 255, 0.00) 100%); +} + +.image-cropper .crop-rotate .current { + margin: auto; + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 9px solid #D8D8D8; + border-radius: 1px; +} + +.image-cropper .crop-rotate .lineation { + height: 50px; + display: flex; + justify-content: flex-start; + align-items: center; + font-size: 0; + margin: 0; + padding: 0 0 8px 0; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.image-cropper .crop-rotate .lineation>view { + flex: 1; + height: 100%; + display: inline-block; +} + +.image-cropper .crop-rotate .lineation .number { + width: 100%; + height: 32px; + font-size: 16px; + line-height: 36px; + text-align: center; + font-family: DINCondensed-Bold; + overflow: hidden; + color: #fff; +} + +.image-cropper .crop-rotate .lineation .bg { + width: 100%; + height: 18px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAAAkCAQAAABbaR7PAAAA3ElEQVR42u2YMQ6DMAxFfSOuVRjKWSBsyRT3nq9zFxvJpEQoGbEUvTzs6CsiFy4mdnYm6Xexoyhbz4iViqJ9IypKHRYvsDgQ+0dkZjHrK2sM0d5BhMUmEA4Os54pDuLHnmgK2SFINmJyEXPQYrEO6Us6YzGKmKMWPcTi/ujmFpN9BtdibW/xH72Y2/Ziub8XU/jSiVtMLS2qn3Tut1jbW7xiXB5gsfQ/0eGru/uJfgRi+6s7nHRGXhx5ceTFkRdHXnxUXtyoKHtbizOz89zxNqonHpLtHURYeP1++QJbckm6SmQBuQAAAABJRU5ErkJggg==); + background-size: 100% 100%; + background-repeat: no-repeat; +} + +/* 功能按钮 */ +.image-cropper .crop-btns { + position: absolute; + bottom: 16px; + width: 100%; + height: 24px; + display: flex; + z-index: 999; +} + +.image-cropper .crop-btns>view { + flex: 1; + height: 100%; + background-color: transparent; + border: none; + padding: 0; + display: inline-block; + margin: auto; + position: relative; +} + +.image-cropper .crop-btns>view:after { + position: absolute; + top: 0; + bottom: 0; + left:0; + right:0; + margin: auto; + content: ''; + display: inline-block; +} + +.image-cropper .crop-close:after { + width: 18px; + height: 18px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAAArElEQVR42q2WWw6AIAwEuQ/eh+t4cMkajCERH7R1+ifZnSCUtikdoawUi4tTqzaVCEpFm1Z1TIsA6sC0aCjl88ON6pjmzOOCGfXo8qNeHT7Up9qOmiptKJNqLjLv+1voOsl3sftunw2hbLubYkl7N0YxA6qqhjED6g/mRNWOqWEMBoJ+DTps6PqhhISeCPRooTICFTao1ELFH2pHUIOEWrYWbohgxhpw0GJGvx1lZkUZoxUOQQAAAABJRU5ErkJggg==); + background-size: 100% 100%; +} + +.image-cropper .crop-btn:after { + right: 16px; + width: 21px; + height: 15px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAeCAYAAABaKIzgAAAAgklEQVR4AezOAQaEMQwF4d4nB+p1evBlFn4KFBheyAOCjG+lDqiVPmADP+DkI+9OByTfXR2QuwtykIMc5CCB6oA89zEb+Q4EIOsdcpBC0Ec6YaHlY4WGhxWQAlZAClgBKWAFpIcVkA5WQDpYASlgBaSCjUb+h+TYACB+DMUBSFKjAAABevZOv672hAAAAABJRU5ErkJggg==); + background-size: 100% 100%; +} + +.image-cropper .crop-reset:after { + width: 22px; + height: 19px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAmCAQAAAAVFrHsAAAB3klEQVR42u3XPUhVUQAH8OuzngaF1pAFVkQJElFEoPaxRELY0uAQVLS5REM0JCQYpNELiqitpoaGdKjN0cCKIFoSxOGRROJTEBoqkj6ev/B0faJpXOk9IvD8h3M4h/Pjcr7gRqKiJi0jJycTaTHq78ssnJnrKAY7B+fmOvwfcOZ3uOibV1y4kBW4hHCJTsUf4RrVS06rULVoUkngl96o0Wh8Xt6Hse4lLsj2JPAek7IaXAt5ZyzUV2P4m7NxJvQX2muTrfFuN5SF1gF5V1QURrpNidzWq1feYKh71S5389KG8NC4vfPgYVk9cZ5iVxK43quQmY3qkUe7rLfWz4NfaI9zLylc65Y+bDDgq9M4r8kPj+LX61OAc57FGUwKz+QU7vrimMoAR7pwVOS+bID7tMbpXC5crUlUgFc7E7bziQGRIXl504Q6vzz416mYhWfzXI9InQsqtYUFO+J48it9B1sWgdM+65L22oh1MfzYh6THrcO0YWPOaVLnsmZbbVOvRjP2uynvsMjFAG80qT/Jla7yUadyl0wtuLYnnDQi5YHrUiZ8N6FcpNWgTUm+uEE61Cmb7dPooEMha0R2hpGywLXZEc9Y9Y+fzRV4BS5RKSE8WhJ3tFi/CgtYLZES5Sdy/jxAWzo1BgAAAABJRU5ErkJggg==); + background-size: 100% 100%; +} + +.image-cropper .crop-around:after { + width: 18px; + height: 22px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAsCAQAAACnWtJ+AAABHklEQVR42u3UsUrDQBzH8YvFrYOhvoLp0BcohA5dhIzZdexrZHMU+wrt2sG9Q9LBICg4CkV0CfQFdBP9OpikqebSS//UQfJbj3zucv/7/5WqCBaWkocBz9xIkUMu+ACQMSfckUbCjHgDIcQx12xkN+aUFYghLvmkPK8siZhwhr2d6WGSd0L8auiAK+2JfibGrX1H2oxp1a4abRyGBDxsLM052vkd0WVWoB63UQ73+vLT56Vwqpag1+iwWN+VSfc/cavdaE25Jo9UO4/o5D8YS0dNPz+TL6WyCoZSqJs3ji2lsid6rvBIjFoiwSuBgnR1qgwZgKQEGqZrkaJGSnvgO0sp1M5GnxBS+fcN9AfQL7GBGuifQaJRW4REw38P+QIQNLRX56aQYgAAAABJRU5ErkJggg==); + background-size: 100% 100%; +} + +/* iphoneX */ +@media only screen and (device-width : 375px) and (device-height : 812px) and (-webkit-device-pixel-ratio : 3), +(device-width : 414px) and (device-height : 896px) { + .image-cropper .crop-btns { + bottom: 43px; + } + + .image-cropper .crop-rotate { + bottom: 95px; + } +} \ No newline at end of file diff --git a/components/image/index.js b/components/image/index.js new file mode 100644 index 0000000..580715f --- /dev/null +++ b/components/image/index.js @@ -0,0 +1,101 @@ +import { addUnit, isDef } from '../common/utils'; +import { VantComponent } from '../common/component'; +import { button } from '../mixins/button'; +import { openType } from '../mixins/open-type'; +const FIT_MODE_MAP = { + none: 'center', + fill: 'scaleToFill', + cover: 'aspectFill', + contain: 'aspectFit', + widthFix: 'widthFix', + heightFix: 'heightFix' +}; +VantComponent({ + mixins: [button, openType], + classes: ['custom-class', 'loading-class', 'error-class', 'image-class'], + props: { + src: { + type: String, + observer() { + this.setData({ + error: false, + loading: true + }); + } + }, + round: Boolean, + width: { + type: null, + observer: 'setStyle' + }, + height: { + type: null, + observer: 'setStyle' + }, + radius: null, + lazyLoad: Boolean, + useErrorSlot: Boolean, + useLoadingSlot: Boolean, + showMenuByLongpress: Boolean, + fit: { + type: String, + value: 'fill', + observer: 'setMode' + }, + showError: { + type: Boolean, + value: true + }, + showLoading: { + type: Boolean, + value: true + } + }, + data: { + error: false, + loading: true, + viewStyle: '', + }, + mounted() { + this.setMode(); + this.setStyle(); + }, + methods: { + setMode() { + this.setData({ + mode: FIT_MODE_MAP[this.data.fit], + }); + }, + setStyle() { + const { width, height, radius } = this.data; + let style = ''; + if (isDef(width)) { + style += `width: ${addUnit(width)};`; + } + if (isDef(height)) { + style += `height: ${addUnit(height)};`; + } + if (isDef(radius)) { + style += 'overflow: hidden;'; + style += `border-radius: ${addUnit(radius)};`; + } + this.setData({ viewStyle: style }); + }, + onLoad(event) { + this.setData({ + loading: false + }); + this.$emit('load', event.detail); + }, + onError(event) { + this.setData({ + loading: false, + error: true + }); + this.$emit('error', event.detail); + }, + onClick(event) { + this.$emit('click', event.detail); + } + } +}); diff --git a/components/image/index.json b/components/image/index.json new file mode 100644 index 0000000..e00a588 --- /dev/null +++ b/components/image/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-loading": "../loading/index" + } +} diff --git a/components/image/index.wxml b/components/image/index.wxml new file mode 100644 index 0000000..ba70376 --- /dev/null +++ b/components/image/index.wxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/image/index.wxss b/components/image/index.wxss new file mode 100644 index 0000000..e5f1637 --- /dev/null +++ b/components/image/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-image{position:relative;display:inline-block}.van-image--round{overflow:hidden;border-radius:50%}.van-image--round .van-image__img{border-radius:inherit}.van-image__error,.van-image__img,.van-image__loading{display:block;width:100%;height:100%}.van-image__error,.van-image__loading{position:absolute;top:0;left:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#969799;color:var(--image-placeholder-text-color,#969799);font-size:14px;font-size:var(--image-placeholder-font-size,14px);background-color:#f7f8fa;background-color:var(--image-placeholder-background-color,#f7f8fa)} \ No newline at end of file diff --git a/components/index-anchor/index.js b/components/index-anchor/index.js new file mode 100644 index 0000000..94f5060 --- /dev/null +++ b/components/index-anchor/index.js @@ -0,0 +1,30 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + name: 'index-bar', + type: 'ancestor', + current: 'index-anchor' + }, + props: { + useSlot: Boolean, + index: null + }, + data: { + active: false, + wrapperStyle: '', + anchorStyle: '' + }, + methods: { + scrollIntoView(scrollTop) { + this.getBoundingClientRect().then((rect) => { + wx.pageScrollTo({ + duration: 0, + scrollTop: scrollTop + rect.top - this.parent.data.stickyOffsetTop + }); + }); + }, + getBoundingClientRect() { + return this.getRect('.van-index-anchor-wrapper'); + } + } +}); diff --git a/components/index-anchor/index.json b/components/index-anchor/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/index-anchor/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/index-anchor/index.wxml b/components/index-anchor/index.wxml new file mode 100644 index 0000000..49affa7 --- /dev/null +++ b/components/index-anchor/index.wxml @@ -0,0 +1,14 @@ + + + + + {{ index }} + + + diff --git a/components/index-anchor/index.wxss b/components/index-anchor/index.wxss new file mode 100644 index 0000000..b8c3c0a --- /dev/null +++ b/components/index-anchor/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-index-anchor{padding:0 16px;padding:var(--index-anchor-padding,0 16px);color:#323233;color:var(--index-anchor-text-color,#323233);font-weight:500;font-weight:var(--index-anchor-font-weight,500);font-size:14px;font-size:var(--index-anchor-font-size,14px);line-height:32px;line-height:var(--index-anchor-line-height,32px);background-color:initial;background-color:var(--index-anchor-background-color,transparent)}.van-index-anchor--active{right:0;left:0;color:#07c160;color:var(--index-anchor-active-text-color,#07c160);background-color:#fff;background-color:var(--index-anchor-active-background-color,#fff)} \ No newline at end of file diff --git a/components/index-bar/index.js b/components/index-bar/index.js new file mode 100644 index 0000000..a80fcb0 --- /dev/null +++ b/components/index-bar/index.js @@ -0,0 +1,269 @@ +import { + VantComponent +} from '../common/component'; +import { + GREEN +} from '../common/color'; +import { + pageScrollMixin +} from '../mixins/page-scroll'; +const indexList = () => { + const indexList = []; + const charCodeOfA = 'A'.charCodeAt(0); + for (let i = 0; i < 26; i++) { + indexList.push(String.fromCharCode(charCodeOfA + i)); + } + return indexList; +}; +VantComponent({ + relation: { + name: 'index-anchor', + type: 'descendant', + current: 'index-bar', + linked() { + this.updateData(); + }, + unlinked() { + this.updateData(); + } + }, + props: { + sticky: { + type: Boolean, + value: true + }, + zIndex: { + type: Number, + value: 1 + }, + highlightColor: { + type: String, + value: GREEN + }, + stickyOffsetTop: { + type: Number, + value: 0 + }, + indexList: { + type: Array, + value: indexList() + } + }, + mixins: [ + pageScrollMixin(function (event) { + this.scrollTop = event.scrollTop || 0; + this.onScroll(); + }) + ], + data: { + activeAnchorIndex: null, + showSidebar: false + }, + created() { + this.scrollTop = 0; + }, + methods: { + updateData() { + wx.nextTick(() => { + if (this.timer != null) { + clearTimeout(this.timer); + } + this.timer = setTimeout(() => { + this.setData({ + showSidebar: !!this.children.length + }); + this.setRect().then(() => { + this.onScroll(); + }); + }, 0); + }); + }, + setRect() { + return Promise.all([ + this.setAnchorsRect(), + this.setListRect(), + this.setSiderbarRect() + ]); + }, + setAnchorsRect() { + return Promise.all(this.children.map(anchor => anchor + .getRect('.van-index-anchor-wrapper') + .then((rect) => { + Object.assign(anchor, { + height: rect.height, + top: rect.top + this.scrollTop + }); + }))); + }, + setListRect() { + return this.getRect('.van-index-bar').then((rect) => { + Object.assign(this, { + height: rect.height, + top: rect.top + this.scrollTop + }); + }); + }, + setSiderbarRect() { + return this.getRect('.van-index-bar__sidebar').then(res => { + this.sidebar = { + height: res.height, + top: res.top + }; + }); + }, + setDiffData({ + target, + data + }) { + const diffData = {}; + Object.keys(data).forEach(key => { + if (target.data[key] !== data[key]) { + diffData[key] = data[key]; + } + }); + if (Object.keys(diffData).length) { + target.setData(diffData); + } + }, + getAnchorRect(anchor) { + return anchor + .getRect('.van-index-anchor-wrapper') + .then((rect) => ({ + height: rect.height, + top: rect.top + })); + }, + getActiveAnchorIndex() { + const { + children, + scrollTop + } = this; + const { + sticky, + stickyOffsetTop + } = this.data; + for (let i = this.children.length - 1; i >= 0; i--) { + const preAnchorHeight = i > 0 ? children[i - 1].height : 0; + const reachTop = sticky ? preAnchorHeight + stickyOffsetTop : 0; + if (reachTop + scrollTop >= children[i].top) { + return i; + } + } + return -1; + }, + onScroll() { + const { + children = [], scrollTop + } = this; + if (!children.length) { + return; + } + const { + sticky, + stickyOffsetTop, + zIndex, + highlightColor + } = this.data; + const active = this.getActiveAnchorIndex(); + this.setDiffData({ + target: this, + data: { + activeAnchorIndex: active + } + }); + if (sticky) { + let isActiveAnchorSticky = false; + if (active !== -1) { + isActiveAnchorSticky = + children[active].top <= stickyOffsetTop + scrollTop; + } + children.forEach((item, index) => { + if (index === active) { + let wrapperStyle = ''; + let anchorStyle = ` + color: ${highlightColor}; + `; + if (isActiveAnchorSticky) { + wrapperStyle = ` + height: ${children[index].height}px; + `; + anchorStyle = ` + position: fixed; + top: ${stickyOffsetTop}px; + z-index: ${zIndex}; + color: ${highlightColor}; + `; + } + this.setDiffData({ + target: item, + data: { + active: true, + anchorStyle, + wrapperStyle + } + }); + } else if (index === active - 1) { + const currentAnchor = children[index]; + const currentOffsetTop = currentAnchor.top; + const targetOffsetTop = index === children.length - 1 ? + this.top : + children[index + 1].top; + const parentOffsetHeight = targetOffsetTop - currentOffsetTop; + const translateY = parentOffsetHeight - currentAnchor.height; + const anchorStyle = ` + position: relative; + transform: translate3d(0, ${translateY}px, 0); + z-index: ${zIndex}; + color: ${highlightColor}; + `; + this.setDiffData({ + target: item, + data: { + active: true, + anchorStyle + } + }); + } else { + this.setDiffData({ + target: item, + data: { + active: false, + anchorStyle: '', + wrapperStyle: '' + } + }); + } + }); + } + }, + onClick(event) { + this.scrollToAnchor(event.target.dataset.index); + }, + onTouchMove(event) { + const sidebarLength = this.children.length; + const touch = event.touches[0]; + const itemHeight = this.sidebar.height / sidebarLength; + let index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight); + if (index < 0) { + index = 0; + } else if (index > sidebarLength - 1) { + index = sidebarLength - 1; + } + this.scrollToAnchor(index); + }, + onTouchStop() { + this.scrollToAnchorIndex = null; + }, + scrollToAnchor(index) { + if (typeof index !== 'number' || this.scrollToAnchorIndex === index) { + return; + } + this.scrollToAnchorIndex = index; + const anchor = this.children.find((item) => item.data.index === this.data.indexList[index]); + if (anchor) { + anchor.scrollIntoView(this.scrollTop); + this.$emit('select', anchor.data.index); + } + } + } +}); diff --git a/components/index-bar/index.json b/components/index-bar/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/index-bar/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/index-bar/index.wxml b/components/index-bar/index.wxml new file mode 100644 index 0000000..19a59cf --- /dev/null +++ b/components/index-bar/index.wxml @@ -0,0 +1,22 @@ + + + + + + {{ item }} + + + diff --git a/components/index-bar/index.wxss b/components/index-bar/index.wxss new file mode 100644 index 0000000..dba5dc0 --- /dev/null +++ b/components/index-bar/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-index-bar{position:relative}.van-index-bar__sidebar{position:fixed;top:50%;right:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;text-align:center;-webkit-transform:translateY(-50%);transform:translateY(-50%);-webkit-user-select:none;user-select:none}.van-index-bar__index{font-weight:500;padding:0 4px 0 16px;padding:0 var(--padding-base,4px) 0 var(--padding-md,16px);font-size:10px;font-size:var(--index-bar-index-font-size,10px);line-height:14px;line-height:var(--index-bar-index-line-height,14px)} \ No newline at end of file diff --git a/components/info/index.js b/components/info/index.js new file mode 100644 index 0000000..a08ad2c --- /dev/null +++ b/components/info/index.js @@ -0,0 +1,10 @@ +'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); +var component_1 = require('../common/component'); +component_1.VantComponent({ + props: { + dot: Boolean, + info: null, + customStyle: String, + }, +}); diff --git a/components/info/index.json b/components/info/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/info/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/info/index.wxml b/components/info/index.wxml new file mode 100644 index 0000000..210431b --- /dev/null +++ b/components/info/index.wxml @@ -0,0 +1,7 @@ + + +{{ dot ? '' : info }} \ No newline at end of file diff --git a/components/info/index.wxss b/components/info/index.wxss new file mode 100644 index 0000000..6d44b8e --- /dev/null +++ b/components/info/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-info{position:absolute;top:0;right:0;box-sizing:border-box;white-space:nowrap;text-align:center;-webkit-transform:translate(50%,-50%);transform:translate(50%,-50%);-webkit-transform-origin:100%;transform-origin:100%;min-width:16px;min-width:var(--info-size,16px);padding:0 3px;padding:var(--info-padding,0 3px);color:#fff;color:var(--info-color,#fff);font-weight:500;font-weight:var(--info-font-weight,500);font-size:12px;font-size:var(--info-font-size,12px);font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--info-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif);line-height:14px;line-height:calc(var(--info-size, 16px) - var(--info-border-width, 1px)*2);background-color:#ee0a24;background-color:var(--info-background-color,#ee0a24);border:1px solid #fff;border:var(--info-border-width,1px) solid var(--white,#fff);border-radius:16px;border-radius:var(--info-size,16px)}.van-info--dot{min-width:0;border-radius:100%;width:8px;width:var(--info-dot-size,8px);height:8px;height:var(--info-dot-size,8px);background-color:#ee0a24;background-color:var(--info-dot-color,#ee0a24)} \ No newline at end of file diff --git a/components/keyboard/index.js b/components/keyboard/index.js new file mode 100644 index 0000000..0d04e87 --- /dev/null +++ b/components/keyboard/index.js @@ -0,0 +1,203 @@ +import classNames from '../common/classNames' + +const defaults = { + prefixCls: 'wux-keyboard', + className: '', + titleText: '安全键盘', + cancelText: '取消', + inputText: '输入数字密码', + showCancel: true, + disorder: false, + password: true, + maxlength: 6, + closeOnReject: true, + onChange(value) {}, + callback(value) {}, + onForget(type) {} + // onClose(value) {}, +} + +/** + * 给指一位数组随机生成二维数组 + * + * @param {boolean} [isRandom=false] 是否随机 + * @param {array} [arr=[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]] 默认数组 + * @returns + */ +const upsetNums = (isRandom = false, arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) => { + if (isRandom) { + const floor = Math.floor + const random = Math.random + const len = arr.length + let i, j, temp, n = floor(len / 2) + 1 + while (n--) { + i = floor(random() * len) + j = floor(random() * len) + if (i !== j) { + temp = arr[i] + arr[i] = arr[j] + arr[j] = temp + } + } + } + let nums = [] + for (let i = 0; i < 4; i++) { + nums.push(arr.slice(i * 3, (i + 1) * 3)) + } + return nums +} + +Component({ + options: { + addGlobalClass: true, + multipleSlots: true + }, + useFunc: true, + data: defaults, + lifetimes: { + // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 + attached: function () { + this.setData({ + classes: this.initwrap(this.data.prefixCls) + }) + } + }, + methods: { + initwrap: function (prefixCls) { + const wrap = classNames(prefixCls) + const hd = `${prefixCls}__hd` + const bd = `${prefixCls}__bd` + const label = `${prefixCls}__label` + const password = `${prefixCls}__password` + const input = `${prefixCls}__input` + const ft = `${prefixCls}__ft` + const title = `${prefixCls}__title` + const numbers = `${prefixCls}__numbers` + const number = `${prefixCls}__number` + const text = `${prefixCls}__text` + const hover = `${prefixCls}__text--hover` + + return { + wrap, + hd, + bd, + label, + password, + input, + ft, + title, + numbers, + number, + text, + hover, + } + }, + /** + * 隐藏 + */ + hide: function () { + this.setData({ + in: false + }) + }, + forget: function () { + if (typeof this.data.onForget === 'function') { + this.data.onForget.call(this, 1) + } + this.hide() + }, + /** + * 上拉键盘组件 + * @param {Object} opts 配置项 + * @param {String} opts.className 自定义类名 + * @param {String} opts.titleText 标题 + * @param {String} opts.cancelText 取消按钮的文字 + * @param {String} opts.inputText 提示文本 + * @param {Boolean} opts.showCancel 是否显示取消按钮 + * @param {Boolean} opts.disorder 是否打乱键盘 + * @param {Boolean} opts.password 是否密码类型 + * @param {Number} opts.maxlength 最大输入长度,设置为 -1 的时候不限制最大长度 + * @param {Boolean} opts.closeOnReject Promise 返回 reject 时关闭组件 + * @param {Function} opts.onChange change 事件触发的回调函数 + * @param {Function} opts.callback 输入完成后的回调函数 + * @param {Function} opts.onClose 输入完成后的回调函数,优先级高于 callback + */ + show: function (opts = {}) { + const nums = upsetNums(opts.disorder) + const maxlength = opts.maxlength <= 0 ? -1 : opts.maxlength + const keys = maxlength !== -1 ? [...new Array(maxlength || defaults.maxlength)].map(() => 1) : [] + const options = Object.assign({ + nums, + keys, + value: '' + }, defaults, opts) + + this.setData({ + in: true, + ...options + }) + return this.hide.bind(this) + }, + /** + * 增加 + */ + increase: function (e) { + const dataset = e.currentTarget.dataset + const nextValue = String(dataset.value) + const { + value, + maxlength + } = this.data + + if (value.length >= maxlength && maxlength !== -1) return + + this.updateValue(value + nextValue) + }, + /** + * 减少 + */ + decrease: function (e) { + const { + value + } = this.data + + if (value.length === 0) return + + this.updateValue(value.substr(0, value.length - 1)) + }, + /** + * 更新 + */ + updateValue: function (value = '') { + this.setData({ + value + }) + // onChange + if (this.data.onChange && typeof this.data.onChange === 'function') { + this.data.onChange.call(this, value) + } + + // onClose + if (value.length === this.data.maxlength) { + const preCloseCallback = this.data.onClose || this.data.callback + const resolveFn = this.hide.bind(this) + const rejectFn = this.data.closeOnReject ? resolveFn : function reject() {} + + if (preCloseCallback && typeof preCloseCallback === 'function') { + const preCloseCallbackResult = preCloseCallback.call(this, value) + if (typeof preCloseCallbackResult === 'object') { + if (preCloseCallbackResult.closePromise) { + preCloseCallbackResult.closePromise.then(resolveFn, rejectFn) + } else { + preCloseCallbackResult.then(resolveFn, rejectFn) + } + } else if (preCloseCallbackResult !== false) { + resolveFn() + } + } else { + resolveFn() + } + } + } + } +}) \ No newline at end of file diff --git a/components/keyboard/index.json b/components/keyboard/index.json new file mode 100644 index 0000000..3cd0e3e --- /dev/null +++ b/components/keyboard/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-popup": "../popup/index" + } +} \ No newline at end of file diff --git a/components/keyboard/index.wxml b/components/keyboard/index.wxml new file mode 100644 index 0000000..b0a54b8 --- /dev/null +++ b/components/keyboard/index.wxml @@ -0,0 +1,42 @@ + + + {{ inputText }} + + + + + {{ !password ? value[index] : '' }} + + + + + + + + + 忘记密码? + + + {{ titleText }} + + + + {{ cancelText }} + + + {{ m }} + + + + + + + + {{ m }} + + + + + + + diff --git a/components/keyboard/index.wxss b/components/keyboard/index.wxss new file mode 100644 index 0000000..de41e2d --- /dev/null +++ b/components/keyboard/index.wxss @@ -0,0 +1,171 @@ +.wux-keyboard { + display: block; + width: 100%; + color: #333; + background-color: #f7f7f7 +} +.wux-keyboard__hd { + height: 100rpx; + display: -ms-flexbox; + display: flex; + -ms-flex-pack: center; + justify-content: center; + -ms-flex-align: center; + align-items: center; + color: #1f2324; + font-size: 36rpx; + /* font-weight: bold; */ + position: relative +} +.wux-keyboard__hd:after { + content: " "; + position: absolute; + left: 0; + bottom: 0; + right: 0; + height: 2rpx; + border-bottom: 2rpx solid #d9d9d9; + color: #d9d9d9; + transform-origin: 0 100%; + transform: scaleY(.5) +} +.wux-keyboard__bd { + margin: 30rpx 80rpx 10rpx 80rpx; + display: -ms-flexbox; + display: flex; + position: relative; + background-color: #fff +} +.wux-keyboard__input { + width: 100%; + padding: 8rpx; + height: 80rpx; + min-height: 80rpx; + text-align: center; + box-sizing: border-box +} +.wux-keyboard__label { + -ms-flex: 1; + flex: 1; + position: relative; + display: -ms-flexbox; + display: flex; + -ms-flex-pack: center; + justify-content: center; + -ms-flex-align: center; + align-items: center; + height: 100rpx +} +.wux-keyboard__label:not(:last-child):after { + content: ""; + width: 2rpx; + height: 50%; + position: absolute; + right: 0; + top: 25%; + background-color: #d9d9d9; + transform: scaleX(.5) +} +.wux-keyboard__password { + width: auto; + height: auto; + display: none +} +.wux-keyboard__password--dot { + width: 12rpx; + height: 12rpx; + border-radius: 50%; + background-color: #000 +} +.wux-keyboard__password--active { + display: block +} +.wux-keyboard__ft { + background-color: #fff; + position: relative +} +.wux-keyboard__ft:before { + content: " "; + position: absolute; + left: 0; + top: 0; + right: 0; + height: 2rpx; + border-top: 2rpx solid #d9d9d9; + color: #d9d9d9; + transform-origin: 0 0; + transform: scaleY(.5) +} +.wux-keyboard__title { + overflow: hidden; + padding: 20rpx 0 12rpx; + color: #222; + margin-bottom: 2rpx; + font-size: 24rpx; + text-align: center; + background-color: #fff +} +.wux-keyboard__title:before { + font-size: 26rpx; + color: #ff2424; + line-height: 1; + margin-right: 6rpx +} +.wux-keyboard__numbers { + font-size: 48rpx; + background-color: #fff +} +.wux-keyboard__number { + display: -ms-flexbox; + display: flex; + width: 100% +} +.wux-keyboard__text { + display: -ms-flexbox; + display: flex; + width: 1%; + -ms-flex: 1; + flex: 1; + color: #222; + height: 100rpx; + position: relative; + -ms-flex-pack: center; + justify-content: center; + -ms-flex-align: center; + align-items: center; + overflow: hidden +} +.wux-keyboard__text:before { + content: " "; + position: absolute; + left: 0; + top: 0; + right: 0; + height: 2rpx; + border-top: 2rpx solid #d9d9d9; + color: #d9d9d9; + transform-origin: 0 0; + transform: scaleY(.5) +} +.wux-keyboard__text:not(:last-child):after { + content: " "; + position: absolute; + right: 0; + top: 0; + width: 2rpx; + bottom: 0; + border-right: 2rpx solid #d9d9d9; + color: #d9d9d9; + transform-origin: 100% 0; + transform: scaleX(.5) +} +.wux-keyboard__text--hover { + background-color: #dedede; + color: rgba(0,0,0,.6) +} +.wux-keyboard__number:last-child .wux-keyboard__text:last-child, +.wux-keyboard__number:last-child .wux-keyboard__text:nth-last-child(3) { + background-color: #f7f7f7; + font-size: 30rpx; + color: #686868 +} \ No newline at end of file diff --git a/components/loading/index.js b/components/loading/index.js new file mode 100644 index 0000000..f5be7ad --- /dev/null +++ b/components/loading/index.js @@ -0,0 +1,16 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + props: { + color: String, + vertical: Boolean, + type: { + type: String, + value: 'circular' + }, + size: String, + textSize: String + }, + data: { + array12: Array.from({ length: 12 }), + }, +}); diff --git a/components/loading/index.json b/components/loading/index.json new file mode 100644 index 0000000..32640e0 --- /dev/null +++ b/components/loading/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/loading/index.wxml b/components/loading/index.wxml new file mode 100644 index 0000000..e934288 --- /dev/null +++ b/components/loading/index.wxml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/components/loading/index.wxss b/components/loading/index.wxss new file mode 100644 index 0000000..f28a6b4 --- /dev/null +++ b/components/loading/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';:host{font-size:0;line-height:1}.van-loading{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#c8c9cc;color:var(--loading-spinner-color,#c8c9cc)}.van-loading__spinner{position:relative;box-sizing:border-box;width:30px;width:var(--loading-spinner-size,30px);max-width:100%;max-height:100%;height:30px;height:var(--loading-spinner-size,30px);-webkit-animation:van-rotate .8s linear infinite;animation:van-rotate .8s linear infinite;-webkit-animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite;animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite}.van-loading__spinner--spinner{-webkit-animation-timing-function:steps(12);animation-timing-function:steps(12)}.van-loading__spinner--circular{border:1px solid transparent;border-top-color:initial;border-radius:100%}.van-loading__text{margin-left:8px;margin-left:var(--padding-xs,8px);color:#969799;color:var(--loading-text-color,#969799);font-size:14px;font-size:var(--loading-text-font-size,14px);line-height:20px;line-height:var(--loading-text-line-height,20px)}.van-loading__text:empty{display:none}.van-loading--vertical{-webkit-flex-direction:column;flex-direction:column}.van-loading--vertical .van-loading__text{margin:8px 0 0;margin:var(--padding-xs,8px) 0 0}.van-loading__dot{position:absolute;top:0;left:0;width:100%;height:100%}.van-loading__dot:before{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%;content:" "}.van-loading__dot:first-of-type{-webkit-transform:rotate(30deg);transform:rotate(30deg);opacity:1}.van-loading__dot:nth-of-type(2){-webkit-transform:rotate(60deg);transform:rotate(60deg);opacity:.9375}.van-loading__dot:nth-of-type(3){-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:.875}.van-loading__dot:nth-of-type(4){-webkit-transform:rotate(120deg);transform:rotate(120deg);opacity:.8125}.van-loading__dot:nth-of-type(5){-webkit-transform:rotate(150deg);transform:rotate(150deg);opacity:.75}.van-loading__dot:nth-of-type(6){-webkit-transform:rotate(180deg);transform:rotate(180deg);opacity:.6875}.van-loading__dot:nth-of-type(7){-webkit-transform:rotate(210deg);transform:rotate(210deg);opacity:.625}.van-loading__dot:nth-of-type(8){-webkit-transform:rotate(240deg);transform:rotate(240deg);opacity:.5625}.van-loading__dot:nth-of-type(9){-webkit-transform:rotate(270deg);transform:rotate(270deg);opacity:.5}.van-loading__dot:nth-of-type(10){-webkit-transform:rotate(300deg);transform:rotate(300deg);opacity:.4375}.van-loading__dot:nth-of-type(11){-webkit-transform:rotate(330deg);transform:rotate(330deg);opacity:.375}.van-loading__dot:nth-of-type(12){-webkit-transform:rotate(1turn);transform:rotate(1turn);opacity:.3125}@-webkit-keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}} \ No newline at end of file diff --git a/components/mixins/basic.js b/components/mixins/basic.js new file mode 100644 index 0000000..dd1f9d5 --- /dev/null +++ b/components/mixins/basic.js @@ -0,0 +1,26 @@ +export const basic = Behavior({ + methods: { + $emit(...args) { + this.triggerEvent(...args); + }, + set(data, callback) { + this.setData(data, callback); + return new Promise(resolve => wx.nextTick(resolve)); + }, + getRect(selector, all) { + return new Promise(resolve => { + wx.createSelectorQuery() + .in(this)[all ? 'selectAll' : 'select'](selector) + .boundingClientRect(rect => { + if (all && Array.isArray(rect) && rect.length) { + resolve(rect); + } + if (!all && rect) { + resolve(rect); + } + }) + .exec(); + }); + } + } +}); diff --git a/components/mixins/button.js b/components/mixins/button.js new file mode 100644 index 0000000..f2d5da6 --- /dev/null +++ b/components/mixins/button.js @@ -0,0 +1,15 @@ +export const button = Behavior({ + externalClasses: ['hover-class'], + properties: { + id: String, + lang: String, + businessId: Number, + sessionFrom: String, + sendMessageTitle: String, + sendMessagePath: String, + sendMessageImg: String, + showMessageCard: Boolean, + appParameter: String, + ariaLabel: String + } +}); diff --git a/components/mixins/link.js b/components/mixins/link.js new file mode 100644 index 0000000..d7aed0c --- /dev/null +++ b/components/mixins/link.js @@ -0,0 +1,17 @@ +export const link = Behavior({ + properties: { + url: String, + linkType: { + type: String, + value: 'navigateTo' + } + }, + methods: { + jumpLink(urlKey = 'url') { + const url = this.data[urlKey]; + if (url) { + wx[this.data.linkType]({ url }); + } + } + } +}); diff --git a/components/mixins/open-type.js b/components/mixins/open-type.js new file mode 100644 index 0000000..514517e --- /dev/null +++ b/components/mixins/open-type.js @@ -0,0 +1,25 @@ +export const openType = Behavior({ + properties: { + openType: String + }, + methods: { + bindGetUserInfo(event) { + this.$emit('getuserinfo', event.detail); + }, + bindContact(event) { + this.$emit('contact', event.detail); + }, + bindGetPhoneNumber(event) { + this.$emit('getphonenumber', event.detail); + }, + bindError(event) { + this.$emit('error', event.detail); + }, + bindLaunchApp(event) { + this.$emit('launchapp', event.detail); + }, + bindOpenSetting(event) { + this.$emit('opensetting', event.detail); + }, + } +}); diff --git a/components/mixins/page-scroll.js b/components/mixins/page-scroll.js new file mode 100644 index 0000000..cbf85e2 --- /dev/null +++ b/components/mixins/page-scroll.js @@ -0,0 +1,28 @@ +function getCurrentPage() { + const pages = getCurrentPages(); + return pages[pages.length - 1] || {}; +} +function onPageScroll(event) { + const { vanPageScroller = [] } = getCurrentPage(); + vanPageScroller.forEach((scroller) => { + if (typeof scroller === 'function') { + scroller(event); + } + }); +} +export const pageScrollMixin = (scroller) => Behavior({ + attached() { + const page = getCurrentPage(); + if (Array.isArray(page.vanPageScroller)) { + page.vanPageScroller.push(scroller.bind(this)); + } + else { + page.vanPageScroller = [page.onPageScroll, scroller.bind(this)]; + } + page.onPageScroll = onPageScroll; + }, + detached() { + const page = getCurrentPage(); + page.vanPageScroller = (page.vanPageScroller || []).filter(item => item !== scroller); + } +}); diff --git a/components/mixins/touch.js b/components/mixins/touch.js new file mode 100644 index 0000000..2a79426 --- /dev/null +++ b/components/mixins/touch.js @@ -0,0 +1,35 @@ +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 const touch = Behavior({ + methods: { + resetTouchStatus() { + this.direction = ''; + this.deltaX = 0; + this.deltaY = 0; + this.offsetX = 0; + this.offsetY = 0; + }, + touchStart(event) { + this.resetTouchStatus(); + const touch = event.touches[0]; + this.startX = touch.clientX; + this.startY = touch.clientY; + }, + touchMove(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 || getDirection(this.offsetX, this.offsetY); + } + } +}); diff --git a/components/mixins/transition.js b/components/mixins/transition.js new file mode 100644 index 0000000..698d40a --- /dev/null +++ b/components/mixins/transition.js @@ -0,0 +1,118 @@ +import { isObj } from '../common/utils'; +const getClassNames = (name) => ({ + enter: `van-${name}-enter van-${name}-enter-active enter-class enter-active-class`, + 'enter-to': `van-${name}-enter-to van-${name}-enter-active enter-to-class enter-active-class`, + leave: `van-${name}-leave van-${name}-leave-active leave-class leave-active-class`, + 'leave-to': `van-${name}-leave-to van-${name}-leave-active leave-to-class leave-active-class` +}); +const nextTick = () => new Promise(resolve => setTimeout(resolve, 1000 / 30)); +export const transition = function (showDefaultValue) { + return Behavior({ + properties: { + customStyle: String, + // @ts-ignore + show: { + type: Boolean, + value: showDefaultValue, + observer: 'observeShow' + }, + // @ts-ignore + duration: { + type: null, + value: 300, + observer: 'observeDuration' + }, + name: { + type: String, + value: 'fade' + } + }, + data: { + type: '', + inited: false, + display: false + }, + methods: { + observeShow(value, old) { + if (value === old) { + return; + } + value ? this.enter() : this.leave(); + }, + enter() { + const { duration, name } = this.data; + const classNames = getClassNames(name); + const currentDuration = isObj(duration) ? duration.enter : duration; + this.status = 'enter'; + this.$emit('before-enter'); + Promise.resolve() + .then(nextTick) + .then(() => { + this.checkStatus('enter'); + this.$emit('enter'); + this.setData({ + inited: true, + display: true, + classes: classNames.enter, + currentDuration + }); + }) + .then(nextTick) + .then(() => { + this.checkStatus('enter'); + this.transitionEnded = false; + this.setData({ + classes: classNames['enter-to'] + }); + }) + .catch(() => { }); + }, + leave() { + if (!this.data.display) { + return; + } + const { duration, name } = this.data; + const classNames = getClassNames(name); + const currentDuration = isObj(duration) ? duration.leave : duration; + this.status = 'leave'; + this.$emit('before-leave'); + Promise.resolve() + .then(nextTick) + .then(() => { + this.checkStatus('leave'); + this.$emit('leave'); + this.setData({ + classes: classNames.leave, + currentDuration + }); + }) + .then(nextTick) + .then(() => { + this.checkStatus('leave'); + this.transitionEnded = false; + setTimeout(() => this.onTransitionEnd(), currentDuration); + this.setData({ + classes: classNames['leave-to'] + }); + }) + .catch(() => { }); + }, + checkStatus(status) { + if (status !== this.status) { + throw new Error(`incongruent status: ${status}`); + } + }, + onTransitionEnd() { + if (this.transitionEnded) { + return; + } + this.transitionEnded = true; + this.$emit(`after-${this.status}`); + const { show, display } = this.data; + if (!show && display) { + this.setData({ display: false }); + } + } + } + }); +}; diff --git a/components/notice-bar/index.js b/components/notice-bar/index.js new file mode 100644 index 0000000..0a1ac0a --- /dev/null +++ b/components/notice-bar/index.js @@ -0,0 +1,128 @@ +import { VantComponent } from '../common/component'; +const FONT_COLOR = '#ed6a0c'; +const BG_COLOR = '#fffbe8'; +VantComponent({ + props: { + text: { + type: String, + value: '', + observer() { + wx.nextTick(() => { + this.init(); + }); + }, + }, + mode: { + type: String, + value: '' + }, + url: { + type: String, + value: '' + }, + openType: { + type: String, + value: 'navigate' + }, + delay: { + type: Number, + value: 1 + }, + speed: { + type: Number, + value: 50, + observer() { + wx.nextTick(() => { + this.init(); + }); + } + }, + scrollable: { + type: Boolean, + value: true + }, + leftIcon: { + type: String, + value: '' + }, + color: { + type: String, + value: FONT_COLOR + }, + backgroundColor: { + type: String, + value: BG_COLOR + }, + wrapable: Boolean + }, + data: { + show: true + }, + created() { + this.resetAnimation = wx.createAnimation({ + duration: 0, + timingFunction: 'linear' + }); + }, + destroyed() { + this.timer && clearTimeout(this.timer); + }, + methods: { + init() { + Promise.all([ + this.getRect('.van-notice-bar__content'), + this.getRect('.van-notice-bar__wrap') + ]).then((rects) => { + const [contentRect, wrapRect] = rects; + if (contentRect == null || + wrapRect == null || + !contentRect.width || + !wrapRect.width) { + return; + } + const { speed, scrollable, delay } = this.data; + if (scrollable && wrapRect.width < contentRect.width) { + const duration = (contentRect.width / speed) * 1000; + this.wrapWidth = wrapRect.width; + this.contentWidth = contentRect.width; + this.duration = duration; + this.animation = wx.createAnimation({ + duration, + timingFunction: 'linear', + delay + }); + this.scroll(); + } + }); + }, + scroll() { + this.timer && clearTimeout(this.timer); + this.timer = null; + this.setData({ + animationData: this.resetAnimation + .translateX(this.wrapWidth) + .step() + .export() + }); + setTimeout(() => { + this.setData({ + animationData: this.animation + .translateX(-this.contentWidth) + .step() + .export() + }); + }, 20); + this.timer = setTimeout(() => { + this.scroll(); + }, this.duration); + }, + onClickIcon() { + this.timer && clearTimeout(this.timer); + this.timer = null; + this.setData({ show: false }); + }, + onClick(event) { + this.$emit('click', event); + } + } +}); diff --git a/components/notice-bar/index.json b/components/notice-bar/index.json new file mode 100644 index 0000000..a9ab393 --- /dev/null +++ b/components/notice-bar/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} \ No newline at end of file diff --git a/components/notice-bar/index.wxml b/components/notice-bar/index.wxml new file mode 100644 index 0000000..eb0851c --- /dev/null +++ b/components/notice-bar/index.wxml @@ -0,0 +1,37 @@ + + + + + + + + + {{ text }} + + + + + + + + + diff --git a/components/notice-bar/index.wxss b/components/notice-bar/index.wxss new file mode 100644 index 0000000..6a49858 --- /dev/null +++ b/components/notice-bar/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-notice-bar{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:40px;height:var(--notice-bar-height,40px);padding:0 16px;padding:var(--notice-bar-padding,0 16px);font-size:14px;font-size:var(--notice-bar-font-size,14px);color:#ed6a0c;color:var(--notice-bar-text-color,#ed6a0c);line-height:24px;line-height:var(--notice-bar-line-height,24px);background-color:#fffbe8;background-color:var(--notice-bar-background-color,#fffbe8)}.van-notice-bar--withicon{position:relative;padding-right:40px}.van-notice-bar--wrapable{height:auto;padding:8px 16px;padding:var(--notice-bar-wrapable-padding,8px 16px)}.van-notice-bar--wrapable .van-notice-bar__wrap{height:auto}.van-notice-bar--wrapable .van-notice-bar__content{position:relative;white-space:normal}.van-notice-bar__left-icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin-right:4px;vertical-align:middle}.van-notice-bar__left-icon,.van-notice-bar__right-icon{font-size:16px;font-size:var(--notice-bar-icon-size,16px);min-width:22px;min-width:var(--notice-bar-icon-min-width,22px)}.van-notice-bar__right-icon{position:absolute;top:10px;right:15px}.van-notice-bar__wrap{position:relative;-webkit-flex:1;flex:1;overflow:hidden;height:24px;height:var(--notice-bar-line-height,24px)}.van-notice-bar__content{position:absolute;white-space:nowrap}.van-notice-bar__content.van-ellipsis{max-width:100%} \ No newline at end of file diff --git a/components/notify/index.js b/components/notify/index.js new file mode 100644 index 0000000..50ea385 --- /dev/null +++ b/components/notify/index.js @@ -0,0 +1,60 @@ +import { VantComponent } from '../common/component'; +import { WHITE } from '../common/color'; +VantComponent({ + props: { + message: String, + background: String, + type: { + type: String, + value: 'danger' + }, + color: { + type: String, + value: WHITE + }, + duration: { + type: Number, + value: 3000 + }, + zIndex: { + type: Number, + value: 110 + }, + safeAreaInsetTop: { + type: Boolean, + value: false + } + }, + data: { + show: false, + }, + created() { + const { statusBarHeight } = wx.getSystemInfoSync(); + this.setData({ statusBarHeight }); + }, + methods: { + show() { + const { duration, onOpened } = this.data; + clearTimeout(this.timer); + this.setData({ show: true }); + wx.nextTick(onOpened); + if (duration > 0 && duration !== Infinity) { + this.timer = setTimeout(() => { + this.hide(); + }, duration); + } + }, + hide() { + const { onClose } = this.data; + clearTimeout(this.timer); + this.setData({ show: false }); + wx.nextTick(onClose); + }, + onTap(event) { + const { onClick } = this.data; + if (onClick) { + onClick(event.detail); + } + } + } +}); diff --git a/components/notify/index.json b/components/notify/index.json new file mode 100644 index 0000000..c14a65f --- /dev/null +++ b/components/notify/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-transition": "../transition/index" + } +} diff --git a/components/notify/index.wxml b/components/notify/index.wxml new file mode 100644 index 0000000..5ef0d8c --- /dev/null +++ b/components/notify/index.wxml @@ -0,0 +1,18 @@ + + + + {{ message }} + + diff --git a/components/notify/index.wxss b/components/notify/index.wxss new file mode 100644 index 0000000..3b4aba6 --- /dev/null +++ b/components/notify/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-notify{text-align:center;word-wrap:break-word;padding:6px 15px;padding:var(--notify-padding,6px 15px);font-size:14px;font-size:var(--notify-font-size,14px);line-height:20px;line-height:var(--notify-line-height,20px)}.van-notify__container{position:fixed;top:0;box-sizing:border-box;width:100%}.van-notify--primary{background-color:#1989fa;background-color:var(--notify-primary-background-color,#1989fa)}.van-notify--success{background-color:#07c160;background-color:var(--notify-success-background-color,#07c160)}.van-notify--danger{background-color:#ee0a24;background-color:var(--notify-danger-background-color,#ee0a24)}.van-notify--warning{background-color:#ff976a;background-color:var(--notify-warning-background-color,#ff976a)} \ No newline at end of file diff --git a/components/notify/notify.js b/components/notify/notify.js new file mode 100644 index 0000000..767c6e2 --- /dev/null +++ b/components/notify/notify.js @@ -0,0 +1,42 @@ +import { WHITE } from '../common/color'; +const defaultOptions = { + selector: '#van-notify', + type: 'danger', + message: '', + background: '', + duration: 3000, + zIndex: 110, + color: WHITE, + safeAreaInsetTop: false, + onClick: () => { }, + onOpened: () => { }, + onClose: () => { } +}; +function parseOptions(message) { + return typeof message === 'string' ? { message } : message; +} +function getContext() { + const pages = getCurrentPages(); + return pages[pages.length - 1]; +} +export default function Notify(options) { + options = Object.assign(Object.assign({}, defaultOptions), parseOptions(options)); + const context = options.context || getContext(); + const notify = context.selectComponent(options.selector); + delete options.context; + delete options.selector; + if (notify) { + notify.setData(options); + notify.show(); + return notify; + } + console.warn('未找到 van-notify 节点,请确认 selector 及 context 是否正确'); +} +Notify.clear = function (options) { + options = Object.assign(Object.assign({}, defaultOptions), parseOptions(options)); + const context = options.context || getContext(); + const notify = context.selectComponent(options.selector); + if (notify) { + notify.hide(); + } +}; diff --git a/components/overlay/index.js b/components/overlay/index.js new file mode 100644 index 0000000..848b5a7 --- /dev/null +++ b/components/overlay/index.js @@ -0,0 +1,22 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + props: { + show: Boolean, + customStyle: String, + duration: { + type: null, + value: 0 + }, + zIndex: { + type: Number, + value: 1 + } + }, + methods: { + onClick() { + this.$emit('click'); + }, + // for prevent touchmove + noop() { } + } +}); diff --git a/components/overlay/index.json b/components/overlay/index.json new file mode 100644 index 0000000..c14a65f --- /dev/null +++ b/components/overlay/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-transition": "../transition/index" + } +} diff --git a/components/overlay/index.wxml b/components/overlay/index.wxml new file mode 100644 index 0000000..9212348 --- /dev/null +++ b/components/overlay/index.wxml @@ -0,0 +1,10 @@ + + + diff --git a/components/overlay/index.wxss b/components/overlay/index.wxss new file mode 100644 index 0000000..b338e5a --- /dev/null +++ b/components/overlay/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.8);background-color:var(--overlay-background-color,rgba(0,0,0,.8))} \ No newline at end of file diff --git a/components/pdf-image/index.js b/components/pdf-image/index.js new file mode 100644 index 0000000..4ffebba --- /dev/null +++ b/components/pdf-image/index.js @@ -0,0 +1,47 @@ +const util = require('../../utils/util') //导入模块 + +Component({ + options: { + addGlobalClass: true, + multipleSlots: true + }, + properties: { + src: { + type: String, + value: '' + }, + width: { + type: Number, + value: 80 + }, + height: { + type: Number, + value: 80 + }, + imageList: { + type: Array, + value: [] + } + }, + observers: { + 'imageList': function () { + for (let index = 0; index < this.data.imageList.length; index++) { + if(!this.isPdfUrl(this.data.imageList[index])){ + this.setData({ src: this.data.imageList[index] }) + break + } + } + if(util.isEmpty(this.data.src)){ + this.setData({ src: this.data.imageList[0] }) + } + } + }, + methods: { + isPdfUrl: function (url) { + if (url && (url.indexOf('.pdf') >= 0 || url.indexOf('.PDF') >= 0)) { + return true + } + return false + } + } +}) \ No newline at end of file diff --git a/components/pdf-image/index.json b/components/pdf-image/index.json new file mode 100644 index 0000000..bae998e --- /dev/null +++ b/components/pdf-image/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-image": "/components/image/index" + } +} \ No newline at end of file diff --git a/components/pdf-image/index.wxml b/components/pdf-image/index.wxml new file mode 100644 index 0000000..6cf75da --- /dev/null +++ b/components/pdf-image/index.wxml @@ -0,0 +1,19 @@ + + + + + function checkImage(url) { + if(typeof url === 'undefined' || url === '' || url === null){ + return true + } + if (url.indexOf('.png') >= 0 || url.indexOf('.PNG') >= 0) { + return true + } else if (url.indexOf('.jpg') >= 0 || url.indexOf('.JPG') >= 0) { + return true + } else if (url.indexOf('.jpeg') >= 0 || url.indexOf('.JPEG') >= 0) { + return true + } + return false + } + module.exports = checkImage + \ No newline at end of file diff --git a/components/pdf-image/index.wxss b/components/pdf-image/index.wxss new file mode 100644 index 0000000..e69de29 diff --git a/components/picker-column/index.js b/components/picker-column/index.js new file mode 100644 index 0000000..80ac3fd --- /dev/null +++ b/components/picker-column/index.js @@ -0,0 +1,117 @@ +import { VantComponent } from '../common/component'; +import { isObj, range } from '../common/utils'; +const DEFAULT_DURATION = 200; +VantComponent({ + classes: ['active-class'], + props: { + valueKey: String, + className: String, + itemHeight: Number, + visibleItemCount: Number, + initialOptions: { + type: Array, + value: [] + }, + defaultIndex: { + type: Number, + value: 0, + observer(value) { + this.setIndex(value); + } + } + }, + data: { + startY: 0, + offset: 0, + duration: 0, + startOffset: 0, + options: [], + currentIndex: 0 + }, + created() { + const { defaultIndex, initialOptions } = this.data; + this.set({ + currentIndex: defaultIndex, + options: initialOptions + }).then(() => { + this.setIndex(defaultIndex); + }); + }, + methods: { + getCount() { + return this.data.options.length; + }, + onTouchStart(event) { + this.setData({ + startY: event.touches[0].clientY, + startOffset: this.data.offset, + duration: 0 + }); + }, + onTouchMove(event) { + const { data } = this; + const deltaY = event.touches[0].clientY - data.startY; + this.setData({ + offset: range(data.startOffset + deltaY, -(this.getCount() * data.itemHeight), data.itemHeight) + }); + }, + onTouchEnd() { + const { data } = this; + if (data.offset !== data.startOffset) { + this.setData({ duration: DEFAULT_DURATION }); + const index = range(Math.round(-data.offset / data.itemHeight), 0, this.getCount() - 1); + this.setIndex(index, true); + } + }, + onClickItem(event) { + const { index } = event.currentTarget.dataset; + this.setIndex(index, true); + }, + adjustIndex(index) { + const { data } = this; + const count = this.getCount(); + index = range(index, 0, count); + for (let i = index; i < count; i++) { + if (!this.isDisabled(data.options[i])) + return i; + } + for (let i = index - 1; i >= 0; i--) { + if (!this.isDisabled(data.options[i])) + return i; + } + }, + isDisabled(option) { + return isObj(option) && option.disabled; + }, + getOptionText(option) { + const { data } = this; + return isObj(option) && data.valueKey in option + ? option[data.valueKey] + : option; + }, + setIndex(index, userAction) { + const { data } = this; + index = this.adjustIndex(index) || 0; + const offset = -index * data.itemHeight; + if (index !== data.currentIndex) { + return this.set({ offset, currentIndex: index }).then(() => { + userAction && this.$emit('change', index); + }); + } + return this.set({ offset }); + }, + setValue(value) { + const { options } = this.data; + for (let i = 0; i < options.length; i++) { + if (this.getOptionText(options[i]) === value) { + return this.setIndex(i); + } + } + return Promise.resolve(); + }, + getValue() { + const { data } = this; + return data.options[data.currentIndex]; + } + } +}); diff --git a/components/picker-column/index.json b/components/picker-column/index.json new file mode 100644 index 0000000..32640e0 --- /dev/null +++ b/components/picker-column/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/picker-column/index.wxml b/components/picker-column/index.wxml new file mode 100644 index 0000000..f052ed9 --- /dev/null +++ b/components/picker-column/index.wxml @@ -0,0 +1,22 @@ + + + + + {{ getOptionText(option, valueKey) }} + + diff --git a/components/picker-column/index.wxs b/components/picker-column/index.wxs new file mode 100644 index 0000000..3c8fc68 --- /dev/null +++ b/components/picker-column/index.wxs @@ -0,0 +1,8 @@ +function isObj(x) { + var type = typeof x; + return x !== null && (type === 'object' || type === 'function'); +} + +module.exports = function (option, valueKey) { + return isObj(option) && option[valueKey] != null ? option[valueKey] : option; +} diff --git a/components/picker-column/index.wxss b/components/picker-column/index.wxss new file mode 100644 index 0000000..c5c6910 --- /dev/null +++ b/components/picker-column/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-picker-column{overflow:hidden;text-align:center;color:#000;color:var(--picker-option-text-color,#000);font-size:16px;font-size:var(--picker-option-font-size,16px)}.van-picker-column__item{padding:0 5px}.van-picker-column__item--selected{font-weight:500;font-weight:var(--font-weight-bold,500);color:#323233;color:var(--picker-option-selected-text-color,#323233)}.van-picker-column__item--disabled{opacity:.3;opacity:var(--picker-option-disabled-opacity,.3)} \ No newline at end of file diff --git a/components/picker/index.js b/components/picker/index.js new file mode 100644 index 0000000..8e78e66 --- /dev/null +++ b/components/picker/index.js @@ -0,0 +1,135 @@ +import { VantComponent } from '../common/component'; +import { pickerProps } from './shared'; +VantComponent({ + classes: ['active-class', 'toolbar-class', 'column-class'], + props: Object.assign(Object.assign({}, pickerProps), { valueKey: { + type: String, + value: 'text' + }, toolbarPosition: { + type: String, + value: 'top' + }, defaultIndex: { + type: Number, + value: 0 + }, columns: { + type: Array, + value: [], + observer(columns = []) { + this.simple = columns.length && !columns[0].values; + this.children = this.selectAllComponents('.van-picker__column'); + if (Array.isArray(this.children) && this.children.length) { + this.setColumns().catch(() => { }); + } + } + } }), + beforeCreate() { + this.children = []; + }, + methods: { + noop() { }, + setColumns() { + const { data } = this; + const columns = this.simple ? [{ values: data.columns }] : data.columns; + const stack = columns.map((column, index) => this.setColumnValues(index, column.values)); + return Promise.all(stack); + }, + emit(event) { + const { type } = event.currentTarget.dataset; + if (this.simple) { + this.$emit(type, { + value: this.getColumnValue(0), + index: this.getColumnIndex(0) + }); + } + else { + this.$emit(type, { + value: this.getValues(), + index: this.getIndexes() + }); + } + }, + onChange(event) { + if (this.simple) { + this.$emit('change', { + picker: this, + value: this.getColumnValue(0), + index: this.getColumnIndex(0) + }); + } + else { + this.$emit('change', { + picker: this, + value: this.getValues(), + index: event.currentTarget.dataset.index + }); + } + }, + // get column instance by index + getColumn(index) { + return this.children[index]; + }, + // get column value by index + getColumnValue(index) { + const column = this.getColumn(index); + return column && column.getValue(); + }, + // set column value by index + setColumnValue(index, value) { + const column = this.getColumn(index); + if (column == null) { + return Promise.reject(new Error('setColumnValue: 对应列不存在')); + } + return column.setValue(value); + }, + // get column option index by column index + getColumnIndex(columnIndex) { + return (this.getColumn(columnIndex) || {}).data.currentIndex; + }, + // set column option index by column index + setColumnIndex(columnIndex, optionIndex) { + const column = this.getColumn(columnIndex); + if (column == null) { + return Promise.reject(new Error('setColumnIndex: 对应列不存在')); + } + return column.setIndex(optionIndex); + }, + // get options of column by index + getColumnValues(index) { + return (this.children[index] || {}).data.options; + }, + // set options of column by index + setColumnValues(index, options, needReset = true) { + const column = this.children[index]; + if (column == null) { + return Promise.reject(new Error('setColumnValues: 对应列不存在')); + } + const isSame = JSON.stringify(column.data.options) === JSON.stringify(options); + if (isSame) { + return Promise.resolve(); + } + return column.set({ options }).then(() => { + if (needReset) { + column.setIndex(0); + } + }); + }, + // get values of all columns + getValues() { + return this.children.map((child) => child.getValue()); + }, + // set values of all columns + setValues(values) { + const stack = values.map((value, index) => this.setColumnValue(index, value)); + return Promise.all(stack); + }, + // get indexes of all columns + getIndexes() { + return this.children.map((child) => child.data.currentIndex); + }, + // set indexes of all columns + setIndexes(indexes) { + const stack = indexes.map((optionIndex, columnIndex) => this.setColumnIndex(columnIndex, optionIndex)); + return Promise.all(stack); + } + } +}); diff --git a/components/picker/index.json b/components/picker/index.json new file mode 100644 index 0000000..2fcec89 --- /dev/null +++ b/components/picker/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "picker-column": "../picker-column/index", + "loading": "../loading/index" + } +} diff --git a/components/picker/index.wxml b/components/picker/index.wxml new file mode 100644 index 0000000..519adb5 --- /dev/null +++ b/components/picker/index.wxml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + function isSimple(columns) { + return columns.length && !columns[0].values; + } + module.exports = isSimple; + diff --git a/components/picker/index.wxss b/components/picker/index.wxss new file mode 100644 index 0000000..f8bfa93 --- /dev/null +++ b/components/picker/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-picker{position:relative;overflow:hidden;-webkit-text-size-adjust:100%;-webkit-user-select:none;user-select:none;background-color:#fff;background-color:var(--picker-background-color,#fff)}.van-picker__toolbar{display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;height:44px;height:var(--picker-toolbar-height,44px);line-height:44px;line-height:var(--picker-toolbar-height,44px)}.van-picker__cancel{padding:0 16px;padding:var(--picker-action-padding,0 16px);font-size:14px;font-size:var(--picker-action-font-size,14px);color:#666666;color:var(--picker-action-text-color,#666666)}.van-picker__confirm{padding:0 16px;padding:var(--picker-action-padding,0 16px);font-size:14px;font-size:var(--picker-action-font-size,14px);color:#1989fa;color:var(--picker-action-text-color,#1989fa)}.van-picker__cancel--hover,.van-picker__confirm--hover{background-color:#f2f3f5;background-color:var(--picker-action-active-color,#f2f3f5)}.van-picker__title{max-width:50%;text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--picker-option-font-size,16px)}.van-picker__columns{position:relative;display:-webkit-flex;display:flex}.van-picker__column{-webkit-flex:1 1;flex:1 1;width:0}.van-picker__loading{position:absolute;top:0;right:0;bottom:0;left:0;z-index:4;display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;background-color:hsla(0,0%,100%,.9);background-color:var(--picker-loading-mask-color,hsla(0,0%,100%,.9))}.van-picker__mask{position:absolute;top:0;left:0;z-index:2;width:100%;height:100%;background-image:linear-gradient(180deg,hsla(0,0%,100%,.9),hsla(0,0%,100%,.4)),linear-gradient(0deg,hsla(0,0%,100%,.9),hsla(0,0%,100%,.4));background-repeat:no-repeat;background-position:top,bottom;-webkit-backface-visibility:hidden;backface-visibility:hidden;pointer-events:none}.van-picker__frame,.van-picker__loading .van-loading{position:absolute;top:50%;left:0;z-index:1;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);pointer-events:none} \ No newline at end of file diff --git a/components/picker/shared.js b/components/picker/shared.js new file mode 100644 index 0000000..cf57d1d --- /dev/null +++ b/components/picker/shared.js @@ -0,0 +1,21 @@ +export const pickerProps = { + title: String, + loading: Boolean, + showToolbar: Boolean, + cancelButtonText: { + type: String, + value: '取消' + }, + confirmButtonText: { + type: String, + value: '确认' + }, + visibleItemCount: { + type: Number, + value: 5 + }, + itemHeight: { + type: Number, + value: 44 + } +}; diff --git a/components/picker/toolbar.wxml b/components/picker/toolbar.wxml new file mode 100644 index 0000000..4fa9db5 --- /dev/null +++ b/components/picker/toolbar.wxml @@ -0,0 +1,28 @@ + diff --git a/components/popup/index.js b/components/popup/index.js new file mode 100644 index 0000000..c80ba39 --- /dev/null +++ b/components/popup/index.js @@ -0,0 +1,81 @@ +import { VantComponent } from '../common/component'; +import { transition } from '../mixins/transition'; +VantComponent({ + classes: [ + 'enter-class', + 'enter-active-class', + 'enter-to-class', + 'leave-class', + 'leave-active-class', + 'leave-to-class', + 'close-icon-class' + ], + mixins: [transition(false)], + props: { + round: Boolean, + closeable: Boolean, + customStyle: String, + overlayStyle: String, + transition: { + type: String, + observer: 'observeClass' + }, + zIndex: { + type: Number, + value: 29 + }, + overlay: { + type: Boolean, + value: true + }, + closeIcon: { + type: String, + value: 'cross' + }, + closeIconPosition: { + type: String, + value: 'top-right' + }, + closeOnClickOverlay: { + type: Boolean, + value: true + }, + position: { + type: String, + value: 'center', + observer: 'observeClass' + }, + safeAreaInsetBottom: { + type: Boolean, + value: true + }, + safeAreaInsetTop: { + type: Boolean, + value: false + } + }, + created() { + this.observeClass(); + }, + methods: { + onClickCloseIcon() { + this.$emit('close'); + }, + onClickOverlay() { + this.$emit('click-overlay'); + if (this.data.closeOnClickOverlay) { + this.$emit('close'); + } + }, + observeClass() { + const { transition, position } = this.data; + const updateData = { + name: transition || position + }; + if (transition === 'none') { + updateData.duration = 0; + } + this.setData(updateData); + } + } +}); diff --git a/components/popup/index.json b/components/popup/index.json new file mode 100644 index 0000000..88a6eab --- /dev/null +++ b/components/popup/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-overlay": "../overlay/index" + } +} diff --git a/components/popup/index.wxml b/components/popup/index.wxml new file mode 100644 index 0000000..9b41e5c --- /dev/null +++ b/components/popup/index.wxml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/components/popup/index.wxss b/components/popup/index.wxss new file mode 100644 index 0000000..60e6e5d --- /dev/null +++ b/components/popup/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-popup{position:fixed;box-sizing:border-box;max-height:100%;overflow-y:auto;transition-timing-function:ease;-webkit-animation:ease both;animation:ease both;-webkit-overflow-scrolling:touch;background-color:#fff;background-color:var(--popup-background-color,#fff)}.van-popup--center{top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.van-popup--center.van-popup--round{border-radius:20px;border-radius:var(--popup-round-border-radius,20px)}.van-popup--top{top:0;left:0;width:100%}.van-popup--top.van-popup--round{border-radius:0 0 20px 20px;border-radius:0 0 var(--popup-round-border-radius,20px) var(--popup-round-border-radius,20px)}.van-popup--right{top:50%;right:0;-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.van-popup--right.van-popup--round{border-radius:20px 0 0 20px;border-radius:var(--popup-round-border-radius,20px) 0 0 var(--popup-round-border-radius,20px)}.van-popup--bottom{bottom:0;left:0;width:100%}.van-popup--bottom.van-popup--round{border-radius:20px 20px 0 0;border-radius:var(--popup-round-border-radius,20px) var(--popup-round-border-radius,20px) 0 0}.van-popup--left{top:50%;left:0;-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.van-popup--left.van-popup--round{border-radius:0 20px 20px 0;border-radius:0 var(--popup-round-border-radius,20px) var(--popup-round-border-radius,20px) 0}.van-popup--safeTop{padding-top:env(safe-area-inset-top)}.van-popup__close-icon{position:absolute;z-index:1;z-index:var(--popup-close-icon-z-index,1);color:#969799;color:var(--popup-close-icon-color,#969799);font-size:18px;font-size:var(--popup-close-icon-size,18px)}.van-popup__close-icon--top-left{top:16px;top:var(--popup-close-icon-margin,16px);left:16px;left:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--top-right{top:16px;top:var(--popup-close-icon-margin,16px);right:16px;right:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-left{bottom:16px;bottom:var(--popup-close-icon-margin,16px);left:16px;left:var(--popup-close-icon-margin,16px)}.van-popup__close-icon--bottom-right{right:16px;right:var(--popup-close-icon-margin,16px);bottom:16px;bottom:var(--popup-close-icon-margin,16px)}.van-popup__close-icon:active{opacity:.6}.van-scale-enter-active,.van-scale-leave-active{transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.van-scale-enter,.van-scale-leave-to{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-fade-enter-active,.van-fade-leave-active{transition-property:opacity}.van-fade-enter,.van-fade-leave-to{opacity:0}.van-center-enter-active,.van-center-leave-active{transition-property:opacity}.van-center-enter,.van-center-leave-to{opacity:0}.van-bottom-enter-active,.van-bottom-leave-active,.van-left-enter-active,.van-left-leave-active,.van-right-enter-active,.van-right-leave-active,.van-top-enter-active,.van-top-leave-active{transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.van-bottom-enter,.van-bottom-leave-to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.van-top-enter,.van-top-leave-to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.van-left-enter,.van-left-leave-to{-webkit-transform:translate3d(-100%,-50%,0);transform:translate3d(-100%,-50%,0)}.van-right-enter,.van-right-leave-to{-webkit-transform:translate3d(100%,-50%,0);transform:translate3d(100%,-50%,0)} \ No newline at end of file diff --git a/components/radio-group/index.js b/components/radio-group/index.js new file mode 100644 index 0000000..2fa6c25 --- /dev/null +++ b/components/radio-group/index.js @@ -0,0 +1,34 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + field: true, + relation: { + name: 'radio', + type: 'descendant', + current: 'radio-group', + linked(target) { + this.updateChild(target); + }, + }, + props: { + value: { + type: null, + observer: 'updateChildren' + }, + disabled: { + type: Boolean, + observer: 'updateChildren' + } + }, + methods: { + updateChildren() { + (this.children || []).forEach((child) => this.updateChild(child)); + }, + updateChild(child) { + const { value, disabled } = this.data; + child.setData({ + value, + disabled: disabled || child.data.disabled + }); + } + } +}); diff --git a/components/radio-group/index.json b/components/radio-group/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/radio-group/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/radio-group/index.wxml b/components/radio-group/index.wxml new file mode 100644 index 0000000..4fa864c --- /dev/null +++ b/components/radio-group/index.wxml @@ -0,0 +1 @@ + diff --git a/components/radio-group/index.wxss b/components/radio-group/index.wxss new file mode 100644 index 0000000..99694d6 --- /dev/null +++ b/components/radio-group/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss'; \ No newline at end of file diff --git a/components/radio/index.js b/components/radio/index.js new file mode 100644 index 0000000..228523f --- /dev/null +++ b/components/radio/index.js @@ -0,0 +1,48 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + field: true, + relation: { + name: 'radio-group', + type: 'ancestor', + current: 'radio', + }, + classes: ['icon-class', 'label-class'], + props: { + name: null, + value: null, + disabled: Boolean, + useIconSlot: Boolean, + checkedColor: String, + labelPosition: { + type: String, + value: 'right' + }, + labelDisabled: Boolean, + shape: { + type: String, + value: 'round' + }, + iconSize: { + type: null, + value: 20 + } + }, + methods: { + emitChange(value) { + const instance = this.parent || this; + instance.$emit('input', value); + instance.$emit('change', value); + }, + onChange() { + if (!this.data.disabled) { + this.emitChange(this.data.name); + } + }, + onClickLabel() { + const { disabled, labelDisabled, name } = this.data; + if (!disabled && !labelDisabled) { + this.emitChange(name); + } + } + } +}); diff --git a/components/radio/index.json b/components/radio/index.json new file mode 100644 index 0000000..0a336c0 --- /dev/null +++ b/components/radio/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} diff --git a/components/radio/index.wxml b/components/radio/index.wxml new file mode 100644 index 0000000..0b748ef --- /dev/null +++ b/components/radio/index.wxml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/components/radio/index.wxss b/components/radio/index.wxss new file mode 100644 index 0000000..96c81f0 --- /dev/null +++ b/components/radio/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-radio{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-radio__icon-wrap{-webkit-flex:none;flex:none}.van-radio__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;border:1px solid #c8c9cc;border:1px solid var(--radio-border-color,#c8c9cc);font-size:20px;font-size:var(--radio-size,20px);transition-duration:.2s;transition-duration:var(--radio-transition-duration,.2s)}.van-radio__icon--round{border-radius:100%}.van-radio__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--radio-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--radio-checked-icon-color,#1989fa)}.van-radio__icon--disabled{background-color:#ebedf0;background-color:var(--radio-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--radio-disabled-icon-color,#c8c9cc)}.van-radio__icon--disabled.van-radio__icon--checked{color:#c8c9cc;color:var(--radio-disabled-icon-color,#c8c9cc)}.van-radio__label{word-wrap:break-word;margin-left:10px;margin-left:var(--radio-label-margin,10px);color:#323233;color:var(--radio-label-color,#323233);line-height:20px;line-height:var(--radio-size,20px)}.van-radio__label--left{float:left;margin:0 10px 0 0;margin:0 var(--radio-label-margin,10px) 0 0}.van-radio__label--disabled{color:#c8c9cc;color:var(--radio-disabled-label-color,#c8c9cc)}.van-radio__label:empty{margin:0} \ No newline at end of file diff --git a/components/rate/index.js b/components/rate/index.js new file mode 100644 index 0000000..4efefda --- /dev/null +++ b/components/rate/index.js @@ -0,0 +1,80 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + field: true, + classes: ['icon-class'], + props: { + value: { + type: Number, + observer(value) { + if (value !== this.data.innerValue) { + this.setData({ innerValue: value }); + } + } + }, + readonly: Boolean, + disabled: Boolean, + allowHalf: Boolean, + size: null, + icon: { + type: String, + value: 'star' + }, + voidIcon: { + type: String, + value: 'star-o' + }, + color: { + type: String, + value: '#ffd21e' + }, + voidColor: { + type: String, + value: '#c7c7c7' + }, + disabledColor: { + type: String, + value: '#bdbdbd' + }, + count: { + type: Number, + value: 5, + observer(value) { + this.setData({ innerCountArray: Array.from({ length: value }) }); + }, + }, + gutter: null, + touchable: { + type: Boolean, + value: true + } + }, + data: { + innerValue: 0, + innerCountArray: Array.from({ length: 5 }), + }, + methods: { + onSelect(event) { + const { data } = this; + const { score } = event.currentTarget.dataset; + if (!data.disabled && !data.readonly) { + this.setData({ innerValue: score + 1 }); + this.$emit('input', score + 1); + this.$emit('change', score + 1); + } + }, + onTouchMove(event) { + const { touchable } = this.data; + if (!touchable) + return; + const { clientX } = event.touches[0]; + this.getRect('.van-rate__icon', true).then((list) => { + const target = list + .sort(item => item.right - item.left) + .find(item => clientX >= item.left && clientX <= item.right); + if (target != null) { + this.onSelect(Object.assign(Object.assign({}, event), { currentTarget: target })); + } + }); + } + } +}); diff --git a/components/rate/index.json b/components/rate/index.json new file mode 100644 index 0000000..0a336c0 --- /dev/null +++ b/components/rate/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} diff --git a/components/rate/index.wxml b/components/rate/index.wxml new file mode 100644 index 0000000..58eee5c --- /dev/null +++ b/components/rate/index.wxml @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/components/rate/index.wxss b/components/rate/index.wxss new file mode 100644 index 0000000..6fd3435 --- /dev/null +++ b/components/rate/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-rate{display:-webkit-inline-flex;display:inline-flex;-webkit-user-select:none;user-select:none}.van-rate__item{position:relative;padding:0 2px;padding:0 var(--rate-horizontal-padding,2px)}.van-rate__icon{display:block;height:1em;font-size:20px;font-size:var(--rate-icon-size,20px)}.van-rate__icon--half{position:absolute;top:0;width:.5em;overflow:hidden;left:2px;left:var(--rate-horizontal-padding,2px)} \ No newline at end of file diff --git a/components/refresher/index.js b/components/refresher/index.js new file mode 100644 index 0000000..10d5476 --- /dev/null +++ b/components/refresher/index.js @@ -0,0 +1,124 @@ +Component({ + options: { + multipleSlots: true + }, + properties: { + height: { + type: Number, + value: 800 + }, + refresherTextStyle: { + type: String, + value: "black" + }, + refresherBackground: { + type: String, + value: "inherit" + }, + scrollTop: { + type: Number, + value: 0 + }, + triggered: { + type: Boolean, + value: false + }, + threshold: { + type: Number, + value: 50 + }, + restoredText: { + type: String, + value: "下拉刷新" + }, + pullingText: { + type: String, + value: "松开刷新" + }, + refreshingText: { + type: String, + value: "正在刷新" + }, + useSlotStyle: Boolean, + scrollX: Boolean, + scrollY: { + type: Boolean, + value: true + }, + upperThreshold: { + type: Number, + value: 50 + }, + owerThreshold: { + type: Number, + value: 50 + }, + scrollLeft: Number, + scrollIntoView: String, + scrollWithAnimation: Boolean, + enableBackToTop: { + type: Boolean, + value: true + }, + enableFlex: Boolean, + scrollAnchoring: Boolean + }, + data: { + stateText: "下拉刷新", + stateCode: 0, + process: 0 + }, + lifetimes: { + // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 + detached: function () {} + }, + methods: { + $emit(type, e) { + this.triggerEvent(type, e) + }, + on2Upper(e) { + this.$emit("scrolltoupper", e) + }, + on2Lower(e) { + this.$emit("scrolltolower", e) + }, + onScroll(e) { + this.$emit("scroll", e) + }, + onPulling(e) { + const dy = e.detail.dy, + threshold = this.properties.threshold + this.setData({ + process: dy / threshold, + stateCode: 1, + stateText: dy < threshold ? + this.properties.restoredText : this.properties.pullingText + }) + this.$emit("pulling", e) + }, + onRefreshed(e) { + this.setData({ + stateText: this.properties.refreshingText, + stateCode: 2, + process: 1 + }) + this.$emit("refresh", e) + }, + onRestored(e) { + this.setData({ + stateText: "", + stateCode: 0, + process: 0 + }) + this.$emit("restore", e) + }, + onAbort(e) { + this.setData({ + stateText: "", + stateCode: 0, + process: 0 + }) + this.$emit("abort", e) + } + } +}) \ No newline at end of file diff --git a/components/refresher/index.json b/components/refresher/index.json new file mode 100644 index 0000000..ac34bd7 --- /dev/null +++ b/components/refresher/index.json @@ -0,0 +1,5 @@ +{ + "component": true, + "usingComponents": { + } +} diff --git a/components/refresher/index.wxml b/components/refresher/index.wxml new file mode 100644 index 0000000..cae6e6e --- /dev/null +++ b/components/refresher/index.wxml @@ -0,0 +1,10 @@ + + + + + + {{ stateText }} + + + + \ No newline at end of file diff --git a/components/refresher/index.wxss b/components/refresher/index.wxss new file mode 100644 index 0000000..81a089f --- /dev/null +++ b/components/refresher/index.wxss @@ -0,0 +1,33 @@ +.jan-refresh--node { + width: 100%; + height: 50px; + background-color: var(--bg-color); + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} + +.jan-refresher--safety-block { + width: 2rpx; + height: 2rpx; + bottom: -2rpx; + position: absolute; +} + +.jan-refresher--icon.refreshing { + transition: all 0.3s; + animation: rotate 0.5s linear infinite; +} + +@keyframes rotate { + 0% { + transform: rotate(0); + } + 50% { + transform: rotate(180deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/components/row/index.js b/components/row/index.js new file mode 100644 index 0000000..72d6006 --- /dev/null +++ b/components/row/index.js @@ -0,0 +1,40 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + name: 'col', + type: 'descendant', + current: 'row', + linked(target) { + if (this.data.gutter) { + target.setGutter(this.data.gutter); + } + } + }, + props: { + gutter: { + type: Number, + observer: 'setGutter' + } + }, + data: { + viewStyle: '', + }, + mounted() { + if (this.data.gutter) { + this.setGutter(); + } + }, + methods: { + setGutter() { + const { gutter } = this.data; + const margin = `-${Number(gutter) / 2}px`; + const viewStyle = gutter + ? `margin-right: ${margin}; margin-left: ${margin};` + : ''; + this.setData({ viewStyle }); + this.getRelationNodes('../col/index').forEach(col => { + col.setGutter(this.data.gutter); + }); + } + } +}); diff --git a/components/row/index.json b/components/row/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/row/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/row/index.wxml b/components/row/index.wxml new file mode 100644 index 0000000..ab8fcf5 --- /dev/null +++ b/components/row/index.wxml @@ -0,0 +1,3 @@ + + + diff --git a/components/row/index.wxss b/components/row/index.wxss new file mode 100644 index 0000000..32a098b --- /dev/null +++ b/components/row/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-row:after{display:table;clear:both;content:""} \ No newline at end of file diff --git a/components/search/index.js b/components/search/index.js new file mode 100644 index 0000000..931dd6c --- /dev/null +++ b/components/search/index.js @@ -0,0 +1,73 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + field: true, + classes: ['field-class', 'input-class', 'cancel-class'], + props: { + label: String, + focus: Boolean, + error: Boolean, + disabled: Boolean, + readonly: Boolean, + inputAlign: String, + showAction: Boolean, + useActionSlot: Boolean, + useLeftIconSlot: Boolean, + useRightIconSlot: Boolean, + leftIcon: { + type: String, + value: 'search' + }, + rightIcon: String, + placeholder: String, + placeholderStyle: String, + actionText: { + type: String, + value: '取消' + }, + background: { + type: String, + value: '#ffffff' + }, + maxlength: { + type: Number, + value: -1 + }, + shape: { + type: String, + value: 'square' + }, + clearable: { + type: Boolean, + value: true + } + }, + methods: { + onChange(event) { + this.setData({ value: event.detail }); + this.$emit('change', event.detail); + }, + onCancel() { + /** + * 修复修改输入框值时,输入框失焦和赋值同时触发,赋值失效 + * https://github.com/youzan/@vant/weapp/issues/1768 + */ + setTimeout(() => { + this.setData({ value: '' }); + this.$emit('cancel'); + this.$emit('change', ''); + }, 200); + }, + onSearch() { + this.$emit('search', this.data.value); + }, + onFocus() { + this.$emit('focus'); + }, + onBlur() { + this.$emit('blur'); + }, + onClear() { + this.$emit('clear'); + }, + } +}); diff --git a/components/search/index.json b/components/search/index.json new file mode 100644 index 0000000..b4cfe91 --- /dev/null +++ b/components/search/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-field": "../field/index" + } +} diff --git a/components/search/index.wxml b/components/search/index.wxml new file mode 100644 index 0000000..1d0e6f1 --- /dev/null +++ b/components/search/index.wxml @@ -0,0 +1,50 @@ + + + + + {{ label }} + + + + + + + + + + + {{ actionText }} + + diff --git a/components/search/index.wxss b/components/search/index.wxss new file mode 100644 index 0000000..d7d5f23 --- /dev/null +++ b/components/search/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-search{-webkit-align-items:center;align-items:center;box-sizing:border-box;padding:10px 12px;padding:var(--search-padding,8px 12px)}.van-search,.van-search__content{display:-webkit-flex;display:flex}.van-search__content{-webkit-flex:1;flex:1;padding-left:8px;padding-left:var(--padding-xs,8px);border-radius:2px;border-radius:var(--border-radius-sm,2px);background-color:#f7f8fa;background-color:var(--search-background-color,#f7f8fa)}.van-search__content--round{border-radius:17px;border-radius:calc(var(--search-input-height, 34px)/2)}.van-search__label{padding:0 5px;padding:var(--search-label-padding,0 5px);font-size:14px;font-size:var(--search-label-font-size,14px);line-height:34px;line-height:var(--search-input-height,34px);color:#323233;color:var(--search-label-color,#323233)}.van-search__field{-webkit-flex:1;flex:1}.van-search__field__left-icon{color:#969799;color:var(--search-left-icon-color,#969799)}.van-search--withaction{padding-right:0}.van-search__action{padding:0 8px;padding:var(--search-action-padding,0 8px);font-size:14px;font-size:var(--search-action-font-size,14px);line-height:34px;line-height:var(--search-input-height,34px);color:#323233;color:var(--search-action-text-color,#323233)}.van-search__action--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)} \ No newline at end of file diff --git a/components/sidebar-item/index.js b/components/sidebar-item/index.js new file mode 100644 index 0000000..a3e02ca --- /dev/null +++ b/components/sidebar-item/index.js @@ -0,0 +1,34 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + classes: [ + 'active-class', + 'disabled-class', + ], + relation: { + type: 'ancestor', + name: 'sidebar', + current: 'sidebar-item', + }, + props: { + dot: Boolean, + info: null, + title: String, + disabled: Boolean + }, + methods: { + onClick() { + const { parent } = this; + if (!parent || this.data.disabled) { + return; + } + const index = parent.children.indexOf(this); + parent.setActive(index).then(() => { + this.$emit('click', index); + parent.$emit('change', index); + }); + }, + setActive(selected) { + return this.setData({ selected }); + } + } +}); diff --git a/components/sidebar-item/index.json b/components/sidebar-item/index.json new file mode 100644 index 0000000..bf0ebe0 --- /dev/null +++ b/components/sidebar-item/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-info": "../info/index" + } +} diff --git a/components/sidebar-item/index.wxml b/components/sidebar-item/index.wxml new file mode 100644 index 0000000..ab8c6c4 --- /dev/null +++ b/components/sidebar-item/index.wxml @@ -0,0 +1,19 @@ + + + + + + {{ title }} + + + diff --git a/components/sidebar-item/index.wxss b/components/sidebar-item/index.wxss new file mode 100644 index 0000000..308dc9c --- /dev/null +++ b/components/sidebar-item/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-sidebar-item{display:block;box-sizing:border-box;overflow:hidden;word-wrap:break-word;border-left:3px solid transparent;-webkit-user-select:none;user-select:none;padding:20px 12px 20px 8px;padding:var(--sidebar-padding,20px 12px 20px 8px);font-size:14px;font-size:var(--sidebar-font-size,14px);line-height:20px;line-height:var(--sidebar-line-height,20px);color:#323233;color:var(--sidebar-text-color,#323233);background-color:#f7f8fa;background-color:var(--sidebar-background-color,#f7f8fa)}.van-sidebar-item__text{position:relative;display:inline-block}.van-sidebar-item--hover:not(.van-sidebar-item--disabled){background-color:#f2f3f5;background-color:var(--sidebar-active-color,#f2f3f5)}.van-sidebar-item:after{border-bottom-width:1px}.van-sidebar-item--selected{color:#323233;color:var(--sidebar-selected-text-color,#323233);font-weight:500;font-weight:var(--sidebar-selected-font-weight,500);border-color:#ee0a24;border-color:var(--sidebar-selected-border-color,#ee0a24)}.van-sidebar-item--selected:after{border-right-width:1px}.van-sidebar-item--selected,.van-sidebar-item--selected.van-sidebar-item--hover{background-color:#fff;background-color:var(--sidebar-selected-background-color,#fff)}.van-sidebar-item--disabled{color:#c8c9cc;color:var(--sidebar-disabled-text-color,#c8c9cc)} \ No newline at end of file diff --git a/components/sidebar/index.js b/components/sidebar/index.js new file mode 100644 index 0000000..008fe99 --- /dev/null +++ b/components/sidebar/index.js @@ -0,0 +1,41 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + name: 'sidebar-item', + type: 'descendant', + current: 'sidebar', + linked() { + this.setActive(this.data.activeKey); + }, + unlinked() { + this.setActive(this.data.activeKey); + } + }, + props: { + activeKey: { + type: Number, + value: 0, + observer: 'setActive' + } + }, + beforeCreate() { + this.currentActive = -1; + }, + methods: { + setActive(activeKey) { + const { children, currentActive } = this; + if (!children.length) { + return Promise.resolve(); + } + this.currentActive = activeKey; + const stack = []; + if (currentActive !== activeKey && children[currentActive]) { + stack.push(children[currentActive].setActive(false)); + } + if (children[activeKey]) { + stack.push(children[activeKey].setActive(true)); + } + return Promise.all(stack); + } + } +}); diff --git a/components/sidebar/index.json b/components/sidebar/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/sidebar/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/sidebar/index.wxml b/components/sidebar/index.wxml new file mode 100644 index 0000000..96b11c7 --- /dev/null +++ b/components/sidebar/index.wxml @@ -0,0 +1,3 @@ + + + diff --git a/components/sidebar/index.wxss b/components/sidebar/index.wxss new file mode 100644 index 0000000..ba3ba94 --- /dev/null +++ b/components/sidebar/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-sidebar{width:85px;width:var(--sidebar-width,85px)} \ No newline at end of file diff --git a/components/skeleton-avatar/index.js b/components/skeleton-avatar/index.js new file mode 100644 index 0000000..f541b28 --- /dev/null +++ b/components/skeleton-avatar/index.js @@ -0,0 +1,48 @@ +import classNames from '../common/classNames' + +Component({ + properties: { + prefixCls: { + type: String, + value: 'wux-skeleton-avatar', + }, + size: { + type: String, + value: 'default', + }, + shape: { + type: String, + value: 'circle', + }, + }, + data: { + active: true, + classes: null + }, + lifetimes: { + attached: function () { + this.setData({ + classes: this.initwrap(this.data.prefixCls, this.data.active, this.data.size, this.data.shape) + }) + } + }, + methods: { + initwrap: function (prefixCls, active, size, shape) { + const wrap = classNames(prefixCls, { + [`${prefixCls}--active`]: active, + [`${prefixCls}--${size}`]: size, + [`${prefixCls}--${shape}`]: shape, + }) + return { + wrap, + } + }, + updated(active) { + if (this.data.active !== active) { + this.setData({ + active + }) + } + }, + }, +}) \ No newline at end of file diff --git a/components/skeleton-avatar/index.json b/components/skeleton-avatar/index.json new file mode 100644 index 0000000..fba482a --- /dev/null +++ b/components/skeleton-avatar/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/skeleton-avatar/index.wxml b/components/skeleton-avatar/index.wxml new file mode 100644 index 0000000..eae9f02 --- /dev/null +++ b/components/skeleton-avatar/index.wxml @@ -0,0 +1 @@ + diff --git a/components/skeleton-avatar/index.wxss b/components/skeleton-avatar/index.wxss new file mode 100644 index 0000000..0875329 --- /dev/null +++ b/components/skeleton-avatar/index.wxss @@ -0,0 +1,69 @@ +.wux-skeleton-avatar { + display: inline-block; + vertical-align: top; + background: #f2f2f2; + width: 80rpx; + height: 80rpx; + line-height: 80rpx +} +.wux-skeleton-avatar--tag { + width: 32rpx; + height: 32rpx; + line-height: 64rpx +} +.wux-skeleton-avatar--small { + width: 64rpx; + height: 64rpx; + line-height: 64rpx +} +.wux-skeleton-avatar--large { + width: 96rpx; + height: 96rpx; + line-height: 96rpx +} +.wux-skeleton-avatar--page { + width: 220rpx; + height: 220rpx; + line-height: 220rpx +} + +.wux-skeleton-avatar--title { + width: 100%; + height: 120rpx; + line-height: 120rpx +} + +.wux-skeleton-avatar--tab { + width: 100%; + height: 60rpx; + line-height: 60rpx +} + +.wux-skeleton-avatar--full { + width: 100%; + height: 240rpx; + line-height: 240rpx +} + +.wux-skeleton-avatar--circle { + border-radius: 50% +} +.wux-skeleton-avatar--rounded { + border-radius: 8rpx +} +.wux-skeleton-avatar--square { + border-radius: 0 +} +.wux-skeleton-avatar--active { + background: linear-gradient(90deg,#f2f2f2 25%,#e6e6e6 37%,#f2f2f2 63%); + animation: loading 1.4s ease infinite; + background-size: 400% 100% +} +@keyframes loading { + 0% { + background-position: 100% 50% + } + 100% { + background-position: 0 50% + } +} \ No newline at end of file diff --git a/components/skeleton-paragraph/index.js b/components/skeleton-paragraph/index.js new file mode 100644 index 0000000..0bc8d0c --- /dev/null +++ b/components/skeleton-paragraph/index.js @@ -0,0 +1,63 @@ +import classNames from '../common/classNames' + +Component({ + options: { + addGlobalClass: true, + multipleSlots: true + }, + properties: { + prefixCls: { + type: String, + value: 'wux-skeleton-paragraph', + }, + rows: { + type: Number, + value: 3, + }, + rounded: { + type: Boolean, + value: true, + }, + widths: { + type: Array, + value: [], + } + }, + data: { + active: true, + rowList: [], + }, + lifetimes: { + attached: function () { + this.updateRows() + this.setData({ + classes: this.initwrap(this.data.prefixCls, this.data.active, this.data.rounded) + }) + } + }, + methods: { + initwrap: function (prefixCls, active, rounded) { + const wrap = classNames(prefixCls, { + [`${prefixCls}--active`]: active, + [`${prefixCls}--rounded`]: rounded, + }) + const row = `${prefixCls}__row` + return { + wrap, + row, + } + }, + updated(active) { + if (this.data.active !== active) { + this.setData({ + active, + }) + } + }, + updateRows(rows = this.data.rows) { + this.setData({ + rowList: [...Array(rows)].map((_, index) => index), + }) + }, + } +}) \ No newline at end of file diff --git a/components/skeleton-paragraph/index.json b/components/skeleton-paragraph/index.json new file mode 100644 index 0000000..fba482a --- /dev/null +++ b/components/skeleton-paragraph/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/skeleton-paragraph/index.wxml b/components/skeleton-paragraph/index.wxml new file mode 100644 index 0000000..2ea00af --- /dev/null +++ b/components/skeleton-paragraph/index.wxml @@ -0,0 +1,5 @@ + + + + + diff --git a/components/skeleton-paragraph/index.wxss b/components/skeleton-paragraph/index.wxss new file mode 100644 index 0000000..5702cd7 --- /dev/null +++ b/components/skeleton-paragraph/index.wxss @@ -0,0 +1,41 @@ +.wux-skeleton-paragraph { + position: relative; + overflow: hidden +} +.wux-skeleton-paragraph__row { + height: 32rpx; + background: #f2f2f2; + width: 100%; + margin-top: 32rpx +} +.wux-skeleton-paragraph__row:first-child { + margin-top: 0 +} +.wux-skeleton-paragraph__row:nth-child(4n+1) { + width: 80% +} +.wux-skeleton-paragraph__row:nth-child(4n+2) { + width: 100% +} +.wux-skeleton-paragraph__row:nth-child(4n+3) { + width: 70% +} +.wux-skeleton-paragraph__row:nth-child(4n+4) { + width: 85% +} +.wux-skeleton-paragraph--rounded .wux-skeleton-paragraph__row { + border-radius: 8rpx +} +.wux-skeleton-paragraph--active .wux-skeleton-paragraph__row { + background: linear-gradient(90deg,#f2f2f2 25%,#e6e6e6 37%,#f2f2f2 63%); + animation: loading 1.4s ease infinite; + background-size: 400% 100% +} +@keyframes loading { + 0% { + background-position: 100% 50% + } + 100% { + background-position: 0 50% + } +} \ No newline at end of file diff --git a/components/skeleton/index.js b/components/skeleton/index.js new file mode 100644 index 0000000..17dfd1e --- /dev/null +++ b/components/skeleton/index.js @@ -0,0 +1,50 @@ +import classNames from '../common/classNames' + +Component({ + properties: { + prefixCls: { + type: String, + value: 'wux-skeleton', + }, + active: { + type: Boolean, + value: true, + observer: 'updated', + }, + }, + data: { + classes: null + }, + lifetimes: { + // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 + attached: function () { + this.setData({ + classes: this.initwrap(this.data.prefixCls, this.data.active) + }) + } + }, + methods: { + initwrap: function(prefixCls, active){ + const wrap = classNames(prefixCls, { + [`${prefixCls}--active`]: active, + }) + return { + wrap, + } + }, + updated(active = this.data.active) { + const avatar = this.getRelationNodes('../skeleton-avatar/index') + const paragraph = this.getRelationNodes('../skeleton-paragraph/index') + if (avatar && avatar.length > 0) { + avatar.forEach((element) => { + element.updated(active) + }) + } + if (paragraph && paragraph.length > 0) { + paragraph.forEach((element) => { + element.updated(active) + }) + } + }, + }, +}) diff --git a/components/skeleton/index.json b/components/skeleton/index.json new file mode 100644 index 0000000..fba482a --- /dev/null +++ b/components/skeleton/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/skeleton/index.wxml b/components/skeleton/index.wxml new file mode 100644 index 0000000..2cf2c40 --- /dev/null +++ b/components/skeleton/index.wxml @@ -0,0 +1,3 @@ + + + diff --git a/components/skeleton/index.wxss b/components/skeleton/index.wxss new file mode 100644 index 0000000..1498f39 --- /dev/null +++ b/components/skeleton/index.wxss @@ -0,0 +1,4 @@ +.wux-skeleton { + position: relative; + width: 100% +} \ No newline at end of file diff --git a/components/step/index.js b/components/step/index.js new file mode 100644 index 0000000..323a281 --- /dev/null +++ b/components/step/index.js @@ -0,0 +1,43 @@ +Component({ + /** + * 组件的属性列表 + */ + externalClasses: [ + 'l-class', + 'l-step-class', + 'l-title-class', + 'l-describe-class', + 'l-line-class' + ], + options: { + multipleSlots: true // 在组件定义时的选项中启用多slot支持 + }, + relations: { + '../steps/index': { + type: 'parent' + }, + }, + properties: { + icon: String, + title: String, + describe: String, + iconSize: { + type: Number, + value: 24 + }, + iconColor: String, + custom: Boolean + }, + + /** + * 组件的方法列表 + */ + methods: { + // 与父组件通信并绑定相关配置数据 + updateDataChange(options) { + this.setData({ + ...options + }) + } + } +}) \ No newline at end of file diff --git a/components/step/index.json b/components/step/index.json new file mode 100644 index 0000000..d538b90 --- /dev/null +++ b/components/step/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon":"../icon/index" + } +} \ No newline at end of file diff --git a/components/step/index.wxml b/components/step/index.wxml new file mode 100644 index 0000000..610be19 --- /dev/null +++ b/components/step/index.wxml @@ -0,0 +1,69 @@ + + + + + + + + + + {{index+1}} + + + + + + {{title}} + + + + {{describe}} + + + + + + + + + var setStatus = function (activeIndex, index, status) { + if (activeIndex === index) { + return status || 'process' + } else if (activeIndex > index) { + return 'finish' + } else { + return 'wait' + } + } + + var statusStyle = function (activeIndex, index, color, status) { + if (activeIndex === index) { + return status === 'error' ? '' : ('background-color:' + color) + } else if (activeIndex > index) { + return ('border-color:' + color + ';color:' + color) + } else { + return '' + } + } + + var dotStyle = function (activeIndex, index, color) { + if (activeIndex >= index) { + return ('background-color:' + color) + } else { + return '' + } + } + + module.exports = { + setStatus: setStatus, + statusStyle: statusStyle, + dotStyle: dotStyle + } + \ No newline at end of file diff --git a/components/step/index.wxss b/components/step/index.wxss new file mode 100644 index 0000000..aa7919e --- /dev/null +++ b/components/step/index.wxss @@ -0,0 +1 @@ +.step{display:flex;position:relative}.step-custom{z-index:2}.step-row{flex-direction:column;align-items:center}.step-column{flex-direction:row;padding-left:30rpx;box-sizing:border-box}.step-container{display:flex;justify-content:center;z-index:2;align-items:center;background-color:#fff}.step-container-row{width:70rpx;height:40rpx}.step-container-column{height:60rpx;width:40rpx}.step-icon{width:40rpx;height:40rpx;display:flex;align-items:center;justify-content:center;font-size:22rpx;transition:.5s;box-sizing:border-box}.step-process{color:#fff;background-color:#008AFF;border-radius:50%}.step-error{background-color:#fff;border:1px solid #f4516c;color:#f4516c;border-radius:50%}.step-finish{background-color:#fff;color:#008AFF;border:1px solid #008AFF;border-radius:50%}.step-wait{background-color:#fff;color:#c4c9d2;border:1px solid #c4c9d2;border-radius:50%}.step-dot{width:24rpx;height:24rpx;border-radius:50%;transition:.5s}.step-dot-process{background-color:#008AFF}.step-dot-wait{background-color:#c4c9d2}.step-dot-error{background-color:#f4516c}.step-dot-finish{background-color:#008AFF}.step-line{background:#c4c9d2;transition:.5s;position:absolute;z-index:0}.step-line-row{height:2rpx;width:100%;left:50%;top:18rpx}.step-line-column{width:2rpx;height:100%;top:20rpx;left:48rpx}.step-line-wait{background-color:#e8e8e8}.step-line-finish{background-color:#008AFF}.step-content{display:flex;flex-direction:column}.step-content-row{align-items:center;width:100%}.step-content-column{margin-left:15rpx}.step-title{color:#595959;font-size:26rpx;line-height:40rpx;margin:10rpx 0}.step-title-process{color:#333;font-size:28rpx;line-height:40rpx;margin:10rpx 0}.step-describe{color:#8c98ae;font-size:22rpx}@font-face{font-family:iconfont;src:url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAK8AAsAAAAABpQAAAJvAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgp8gQsBNgIkAwwLCAAEIAWEbQc2G9EFyK4wbuGJaCgrSmkBCSe/ZeUtviBzEXztx/bd3f+oNEiuzaerJhKN6WQSJFqlZELxTOZqTS9l0hsflgVC/bD3z/dzv8lMXAksyeryeByfVkhgV93EvwdIwC+b/hetH5jPyAA+z+X0JtCBXONbltMcw496AcYBBbYnRoEEXEQBcAqyOwK15PsEmg2KiewMTy6yCoWzLBD3lqGwilJKUaRqo1C37C3iRaUxPaUnPMffj18LUUFSZc7a3bshnfV++DD/2GVISBPo4QoZU5hCXLeWThULiSvWbCrpb64VIS2VhYlVpqU+6B8vETWnsxWM0XLiI19G8OGABDKoy5VBzDRje98gRHertt+2fLx2cdC6ZJwcnK226Ifh0uzy4vzK8sLSytxprqHAHexGbz8/6za6C3ePjwW29viP3ailnm7Zz+SntAd5IV0IBHuvvy3Xd/41thTw/osdBRahcefh4Gepwb5iah13LrrKV9mRrBsIJKhCjvrnxLq9Trf0wb2ERn0TIg0GcmSNhsjCTqHSYgm1RutoNmnkcIseUrEoTZiwRRA63SBp94as0zNZ2BdU+v2h1hnFaHYczWe2GAmrakCiQqiDmgdLEz73vFSVdM+jkXUVWdTG/DLK0MpCOpGqVkfQR7nEhjBnZIg4cCk8GCaPoesKCKSwUaOESRS0J5O87UUJTXisyjYJKQjSAVUesGgEHw+Hk6ra5+chQ5ZLIXsEDfllSApZ44O0hBRAjph8SPAoz4RyDBmEcICTBA8YJrOQyyWAoH2WDWlIgjmhEGiXdAdx1JTY3uL93xFo5kzMkSJHUT+g+5BNxVpWMAYAAA==') format('woff2')}.iconfont{font-family:iconfont!important;font-size:24rpx;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-finish:before{content:"\e600"}.icon-error:before{content:"\e6cf"} \ No newline at end of file diff --git a/components/stepper/index.js b/components/stepper/index.js new file mode 100644 index 0000000..fa41915 --- /dev/null +++ b/components/stepper/index.js @@ -0,0 +1,184 @@ +import { VantComponent } from '../common/component'; +import { isDef } from '../common/utils'; +const LONG_PRESS_START_TIME = 600; +const LONG_PRESS_INTERVAL = 200; +// add num and avoid float number +function add(num1, num2) { + const cardinal = Math.pow(10, 10); + return Math.round((num1 + num2) * cardinal) / cardinal; +} +function equal(value1, value2) { + return String(value1) === String(value2); +} +VantComponent({ + field: true, + classes: ['input-class', 'plus-class', 'minus-class'], + props: { + value: { + type: null, + observer(value) { + if (!equal(value, this.data.currentValue)) { + this.setData({ currentValue: this.format(value) }); + } + } + }, + integer: { + type: Boolean, + observer: 'check' + }, + disabled: Boolean, + inputWidth: null, + buttonSize: null, + asyncChange: Boolean, + disableInput: Boolean, + decimalLength: { + type: Number, + value: null, + observer: 'check' + }, + min: { + type: null, + value: 1, + observer: 'check' + }, + max: { + type: null, + value: Number.MAX_SAFE_INTEGER, + observer: 'check' + }, + step: { + type: null, + value: 1 + }, + showPlus: { + type: Boolean, + value: true + }, + showMinus: { + type: Boolean, + value: true + }, + disablePlus: Boolean, + disableMinus: Boolean, + longPress: { + type: Boolean, + value: true + } + }, + data: { + currentValue: '' + }, + created() { + this.setData({ + currentValue: this.format(this.data.value) + }); + }, + methods: { + check() { + const val = this.format(this.data.currentValue); + if (!equal(val, this.data.currentValue)) { + this.setData({ currentValue: val }); + } + }, + isDisabled(type) { + if (type === 'plus') { + return (this.data.disabled || + this.data.disablePlus || + this.data.currentValue >= this.data.max); + } + return (this.data.disabled || + this.data.disableMinus || + this.data.currentValue <= this.data.min); + }, + onFocus(event) { + this.$emit('focus', event.detail); + }, + onBlur(event) { + const value = this.format(event.detail.value); + this.emitChange(value); + this.$emit('blur', Object.assign(Object.assign({}, event.detail), { value })); + }, + // filter illegal characters + filter(value) { + value = String(value).replace(/[^0-9.-]/g, ''); + if (this.data.integer && value.indexOf('.') !== -1) { + value = value.split('.')[0]; + } + return value; + }, + // limit value range + format(value) { + value = this.filter(value); + // format range + value = value === '' ? 0 : +value; + value = Math.max(Math.min(this.data.max, value), this.data.min); + // format decimal + if (isDef(this.data.decimalLength)) { + value = value.toFixed(this.data.decimalLength); + } + return value; + }, + onInput(event) { + const { value = '' } = event.detail || {}; + // allow input to be empty + if (value === '') { + return; + } + let formatted = this.filter(value); + // limit max decimal length + if (isDef(this.data.decimalLength) && formatted.indexOf('.') !== -1) { + const pair = formatted.split('.'); + formatted = `${pair[0]}.${pair[1].slice(0, this.data.decimalLength)}`; + } + this.emitChange(formatted); + }, + emitChange(value) { + if (!this.data.asyncChange) { + this.setData({ currentValue: value }); + } + this.$emit('change', value); + }, + onChange() { + const { type } = this; + if (this.isDisabled(type)) { + this.$emit('overlimit', type); + return; + } + const diff = type === 'minus' ? -this.data.step : +this.data.step; + const value = this.format(add(+this.data.currentValue, diff)); + this.emitChange(value); + this.$emit(type); + }, + longPressStep() { + this.longPressTimer = setTimeout(() => { + this.onChange(); + this.longPressStep(); + }, LONG_PRESS_INTERVAL); + }, + onTap(event) { + const { type } = event.currentTarget.dataset; + this.type = type; + this.onChange(); + }, + onTouchStart(event) { + if (!this.data.longPress) { + return; + } + clearTimeout(this.longPressTimer); + const { type } = event.currentTarget.dataset; + this.type = type; + this.isLongPress = false; + this.longPressTimer = setTimeout(() => { + this.isLongPress = true; + this.onChange(); + this.longPressStep(); + }, LONG_PRESS_START_TIME); + }, + onTouchEnd() { + if (!this.data.longPress) { + return; + } + clearTimeout(this.longPressTimer); + } + } +}); diff --git a/components/stepper/index.json b/components/stepper/index.json new file mode 100644 index 0000000..32640e0 --- /dev/null +++ b/components/stepper/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/stepper/index.wxml b/components/stepper/index.wxml new file mode 100644 index 0000000..9570420 --- /dev/null +++ b/components/stepper/index.wxml @@ -0,0 +1,37 @@ + + + + + + + diff --git a/components/stepper/index.wxss b/components/stepper/index.wxss new file mode 100644 index 0000000..5da5b79 --- /dev/null +++ b/components/stepper/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-stepper{font-size:0}.van-stepper__minus,.van-stepper__plus{position:relative;display:inline-block;box-sizing:border-box;margin:1px;vertical-align:middle;border:0;background-color:#f2f3f5;background-color:var(--stepper-background-color,#f2f3f5);color:#323233;color:var(--stepper-button-icon-color,#323233);width:28px;width:var(--stepper-input-height,28px);height:28px;height:var(--stepper-input-height,28px);padding:4px;padding:var(--padding-base,4px)}.van-stepper__minus:before,.van-stepper__plus:before{width:9px;height:1px}.van-stepper__minus:after,.van-stepper__plus:after{width:1px;height:9px}.van-stepper__minus:after,.van-stepper__minus:before,.van-stepper__plus:after,.van-stepper__plus:before{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;background-color:currentColor;content:""}.van-stepper__minus--hover,.van-stepper__plus--hover{background-color:#e8e8e8;background-color:var(--stepper-active-color,#e8e8e8)}.van-stepper__minus--disabled,.van-stepper__plus--disabled{color:#c8c9cc;color:var(--stepper-button-disabled-icon-color,#c8c9cc)}.van-stepper__minus--disabled,.van-stepper__minus--disabled.van-stepper__minus--hover,.van-stepper__minus--disabled.van-stepper__plus--hover,.van-stepper__plus--disabled,.van-stepper__plus--disabled.van-stepper__minus--hover,.van-stepper__plus--disabled.van-stepper__plus--hover{background-color:#f7f8fa;background-color:var(--stepper-button-disabled-color,#f7f8fa)}.van-stepper__minus{border-radius:4px 0 0 4px;border-radius:var(--stepper-border-radius,4px) 0 0 var(--stepper-border-radius,4px)}.van-stepper__minus:after{display:none}.van-stepper__plus{border-radius:0 4px 4px 0;border-radius:0 var(--stepper-border-radius,4px) var(--stepper-border-radius,4px) 0}.van-stepper__input{display:inline-block;box-sizing:border-box;min-height:0;margin:1px;padding:1px;text-align:center;vertical-align:middle;border:0;border-width:1px 0;border-radius:0;-webkit-appearance:none;font-size:14px;font-size:var(--stepper-input-font-size,14px);color:#323233;color:var(--stepper-input-text-color,#323233);background-color:#f2f3f5;background-color:var(--stepper-background-color,#f2f3f5);width:32px;width:var(--stepper-input-width,32px);height:28px;height:var(--stepper-input-height,28px)}.van-stepper__input--disabled{color:#c8c9cc;color:var(--stepper-input-disabled-text-color,#c8c9cc);background-color:#f2f3f5;background-color:var(--stepper-input-disabled-background-color,#f2f3f5)} \ No newline at end of file diff --git a/components/steps/index.js b/components/steps/index.js new file mode 100644 index 0000000..47772cd --- /dev/null +++ b/components/steps/index.js @@ -0,0 +1,74 @@ +Component({ + externalClasses: [ + 'l-class' + ], + options: { + multipleSlots: true // 在组件定义时的选项中启用多slot支持 + }, + relations: { + '../step/index': { + type: 'child', + linked() { + this.initSteps(); + }, + unlinked() { + this.initSteps(); + } + }, + }, + + properties: { + direction: { + type: String, + value: 'row', + options: ['row', 'column'] + }, + activeIndex: { + type: Number, + value: 0 + }, + color: String, + stepMinHeight: { + type: String, + value: '120' + }, + status: { + type: String, + value: 'process', + options: ['process', 'error'] + }, + dot: Boolean + }, + + observers: { + 'activeIndex': function () { + this.initSteps() + } + }, + + /** + * 组件的初始数据 + */ + data: { + + }, + + /** + * 组件的方法列表 + */ + methods: { + initSteps() { + let steps = this.getRelationNodes('../step/index') + this.data.length = steps.length + if (this.data.length > 0) { + steps.forEach((step, index) => { + step.updateDataChange({ + index, + ...this.data, + stepsWidth: 375 + }); + }); + } + } + } +}); \ No newline at end of file diff --git a/components/steps/index.json b/components/steps/index.json new file mode 100644 index 0000000..9109978 --- /dev/null +++ b/components/steps/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "l-step":"../step/index" + } +} \ No newline at end of file diff --git a/components/steps/index.wxml b/components/steps/index.wxml new file mode 100644 index 0000000..a5bc7e6 --- /dev/null +++ b/components/steps/index.wxml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/components/steps/index.wxss b/components/steps/index.wxss new file mode 100644 index 0000000..b4df18c --- /dev/null +++ b/components/steps/index.wxss @@ -0,0 +1 @@ +.steps-container{display:flex;width:100%}.steps-container-row{flex-direction:row}.steps-container-column{flex-direction:column} \ No newline at end of file diff --git a/components/sticky/index.js b/components/sticky/index.js new file mode 100644 index 0000000..11d0c07 --- /dev/null +++ b/components/sticky/index.js @@ -0,0 +1,119 @@ +'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); +var component_1 = require('../common/component'); +var page_scroll_1 = require('../mixins/page-scroll'); +var ROOT_ELEMENT = '.van-sticky'; +component_1.VantComponent({ + props: { + zIndex: { + type: Number, + value: 99, + }, + offsetTop: { + type: Number, + value: 0, + observer: 'onScroll', + }, + disabled: { + type: Boolean, + observer: 'onScroll', + }, + container: { + type: null, + observer: 'onScroll', + }, + scrollTop: { + type: null, + observer: function (val) { + this.onScroll({ scrollTop: val }); + }, + }, + }, + mixins: [ + page_scroll_1.pageScrollMixin(function (event) { + if (this.data.scrollTop != null) { + return; + } + this.onScroll(event); + }), + ], + data: { + height: 0, + fixed: false, + transform: 0, + }, + mounted: function () { + this.onScroll(); + }, + methods: { + onScroll: function (_a) { + var _this = this; + var scrollTop = (_a === void 0 ? {} : _a).scrollTop; + var _b = this.data, + container = _b.container, + offsetTop = _b.offsetTop, + disabled = _b.disabled; + if (disabled) { + this.setDataAfterDiff({ + fixed: false, + transform: 0, + }); + return; + } + this.scrollTop = scrollTop || this.scrollTop; + if (typeof container === 'function') { + Promise.all([this.getRect(ROOT_ELEMENT), this.getContainerRect()]).then( + function (_a) { + var root = _a[0], + container = _a[1]; + if (offsetTop + root.height > container.height + container.top) { + _this.setDataAfterDiff({ + fixed: false, + transform: container.height - root.height, + }); + } else if (offsetTop >= root.top) { + _this.setDataAfterDiff({ + fixed: true, + height: root.height, + transform: 0, + }); + } else { + _this.setDataAfterDiff({ fixed: false, transform: 0 }); + } + } + ); + return; + } + this.getRect(ROOT_ELEMENT).then(function (root) { + if (offsetTop >= root.top) { + _this.setDataAfterDiff({ fixed: true, height: root.height }); + _this.transform = 0; + } else { + _this.setDataAfterDiff({ fixed: false }); + } + }); + }, + setDataAfterDiff: function (data) { + var _this = this; + wx.nextTick(function () { + var diff = Object.keys(data).reduce(function (prev, key) { + if (data[key] !== _this.data[key]) { + prev[key] = data[key]; + } + return prev; + }, {}); + _this.setData(diff); + _this.$emit('scroll', { + scrollTop: _this.scrollTop, + isFixed: data.fixed || _this.data.fixed, + }); + }); + }, + getContainerRect: function () { + var nodesRef = this.data.container(); + return new Promise(function (resolve) { + return nodesRef.boundingClientRect(resolve).exec(); + }); + }, + }, +}); diff --git a/components/sticky/index.json b/components/sticky/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/sticky/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/sticky/index.wxml b/components/sticky/index.wxml new file mode 100644 index 0000000..15e9f4a --- /dev/null +++ b/components/sticky/index.wxml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/components/sticky/index.wxs b/components/sticky/index.wxs new file mode 100644 index 0000000..18efe14 --- /dev/null +++ b/components/sticky/index.wxs @@ -0,0 +1,37 @@ +/* eslint-disable */ +function wrapStyle(data) { + var style = ''; + + if (data.transform) { + style += 'transform: translate3d(0, ' + data.transform + 'px, 0);'; + } + + if (data.fixed) { + style += 'top: ' + data.offsetTop + 'px;'; + } + + if (data.zIndex) { + style += 'z-index: ' + data.zIndex + ';'; + } + + return style; +} + +function containerStyle(data) { + var style = ''; + + if (data.fixed) { + style += 'height: ' + data.height + 'px;'; + } + + if (data.zIndex) { + style += 'z-index: ' + data.zIndex + ';'; + } + + return style; +} + +module.exports = { + wrapStyle: wrapStyle, + containerStyle: containerStyle +}; diff --git a/components/sticky/index.wxss b/components/sticky/index.wxss new file mode 100644 index 0000000..5269387 --- /dev/null +++ b/components/sticky/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-sticky{position:relative}.van-sticky-wrap--fixed{position:fixed;right:0;left:0} \ No newline at end of file diff --git a/components/submit-bar/index.js b/components/submit-bar/index.js new file mode 100644 index 0000000..a457aba --- /dev/null +++ b/components/submit-bar/index.js @@ -0,0 +1,59 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + classes: [ + 'bar-class', + 'price-class', + 'button-class' + ], + props: { + tip: { + type: null, + observer: 'updateTip' + }, + tipIcon: String, + type: Number, + price: { + type: null, + observer: 'updatePrice' + }, + label: String, + loading: Boolean, + disabled: Boolean, + buttonText: String, + currency: { + type: String, + value: '¥' + }, + buttonType: { + type: String, + value: 'danger' + }, + decimalLength: { + type: Number, + value: 2, + observer: 'updatePrice' + }, + suffixLabel: String, + safeAreaInsetBottom: { + type: Boolean, + value: true + } + }, + methods: { + updatePrice() { + const { price, decimalLength } = this.data; + const priceStrArr = typeof price === 'number' && (price / 100).toFixed(decimalLength).split('.'); + this.setData({ + hasPrice: typeof price === 'number', + integerStr: priceStrArr && priceStrArr[0], + decimalStr: decimalLength && priceStrArr ? `.${priceStrArr[1]}` : '' + }); + }, + updateTip() { + this.setData({ hasTip: typeof this.data.tip === 'string' }); + }, + onSubmit(event) { + this.$emit('submit', event.detail); + } + } +}); diff --git a/components/submit-bar/index.json b/components/submit-bar/index.json new file mode 100644 index 0000000..bda9b8d --- /dev/null +++ b/components/submit-bar/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-button": "../button/index", + "van-icon": "../icon/index" + } +} diff --git a/components/submit-bar/index.wxml b/components/submit-bar/index.wxml new file mode 100644 index 0000000..805c38a --- /dev/null +++ b/components/submit-bar/index.wxml @@ -0,0 +1,42 @@ + + + + + + + + + {{ tip }} + + + + + + + + {{ label || '合计:' }} + + {{ currency }} + {{ integerStr }}{{decimalStr}} + + {{ suffixLabel }} + + + {{ loading ? '' : buttonText }} + + + diff --git a/components/submit-bar/index.wxss b/components/submit-bar/index.wxss new file mode 100644 index 0000000..2fe0245 --- /dev/null +++ b/components/submit-bar/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-submit-bar{width:750rpx;background-color:#fff;background-color:var(--submit-bar-background-color,#fff)}.van-submit-bar__tip{padding:10px;padding:var(--submit-bar-tip-padding,10px);color:#f56723;color:var(--submit-bar-tip-color,#f56723);font-size:12px;font-size:var(--submit-bar-tip-font-size,12px);line-height:1.5;line-height:var(--submit-bar-tip-line-height,1.5);background-color:#fff7cc;background-color:var(--submit-bar-tip-background-color,#fff7cc)}.van-submit-bar__tip:empty{display:none}.van-submit-bar__tip-icon{width:12px;height:12px;margin-right:4px;vertical-align:middle;font-size:12px;font-size:var(--submit-bar-tip-icon-size,12px);min-width:18px;min-width:calc(var(--submit-bar-tip-icon-size, 12px)*1.5)}.van-submit-bar__tip-text{display:inline;vertical-align:middle}.van-submit-bar__bar{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:flex-end;justify-content:flex-end;padding:0 16px;padding:var(--submit-bar-padding,0 16px);height:50px;height:var(--submit-bar-height,50px);font-size:14px;font-size:var(--submit-bar-text-font-size,14px);background-color:#fff;background-color:var(--submit-bar-background-color,#fff)}.van-submit-bar__text{-webkit-flex:1;flex:1;text-align:right;color:#323233;color:var(--submit-bar-text-color,#323233);padding-right:12px;padding-right:var(--padding-sm,12px)}.van-submit-bar__price,.van-submit-bar__text{font-weight:500;font-weight:var(--font-weight-bold,500)}.van-submit-bar__price{color:#ee0a24;color:var(--submit-bar-price-color,#ee0a24);font-size:12px;font-size:var(--submit-bar-price-font-size,12px)}.van-submit-bar__price-integer{font-size:20px;font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif}.van-submit-bar__currency{font-size:12px;font-size:var(--submit-bar-currency-font-size,12px)}.van-submit-bar__suffix-label{margin-left:5px}.van-submit-bar__button{width:110px;width:var(--submit-bar-button-width,110px);font-weight:500;font-weight:var(--font-weight-bold,500);--button-default-height:40px!important;--button-default-height:var(--submit-bar-button-height,40px)!important;--button-line-height:40px!important;--button-line-height:var(--submit-bar-button-height,40px)!important} \ No newline at end of file diff --git a/components/sudoku-image/index.js b/components/sudoku-image/index.js new file mode 100644 index 0000000..3e40729 --- /dev/null +++ b/components/sudoku-image/index.js @@ -0,0 +1,81 @@ +const math = require('../../utils/math') //导入模块 + +Component({ + options: { + addGlobalClass: true, + multipleSlots: true + }, + properties: { + imageList: { + type: Array, + value: [] + }, + clickable: { + type: Boolean, + value: false + }, + column: { + type: Number, + value: 5 + } + }, + data: { + width: '138rpx', + heightList: [] + }, + observers: { + 'column': function () { + var square = math.minus(math.divide(750, this.data.column), 12) + 'rpx' + this.setData({ width: square }) + } + }, + methods: { + viewImage: function (e) { + if (!this.data.clickable) { + return + } + var index = e.currentTarget.dataset.index + var url = this.data.imageList[index] + if (this.isPdfUrl(url)) { + var filepath = wx.env.USER_DATA_PATH + url.substring(url.lastIndexOf('/')) + // 1: 获取本地是否有文件, + wx.getFileInfo({ + filePath: filepath, + success (res) { + // 2: 如果有变打开 + wx.openDocument({ filePath: filepath }) + }, + fail: function (error) { + // 2: 没有就开始下载 + wx.showLoading({ title: '加载中', mask: true }) + wx.downloadFile({ + url: url, + filePath: filepath, + // 3: 下载之后便打开 + success: function (res) { + wx.openDocument({filePath: res.filePath}) + }, + complete: function (res) { + wx.hideLoading() + } + }) + } + }) + return + } + var imgList = [] + for (let index = 0; index < this.data.imageList.length; index++) { + if(!this.isPdfUrl(this.data.imageList[index])){ + imgList.push(this.data.imageList[index]) + } + } + wx.previewImage({ urls: imgList, current: url }) + }, + isPdfUrl: function (url) { + if (url && (url.indexOf('.pdf') >= 0 || url.indexOf('.PDF') >= 0)) { + return true + } + return false + } + } +}) \ No newline at end of file diff --git a/components/sudoku-image/index.json b/components/sudoku-image/index.json new file mode 100644 index 0000000..bae998e --- /dev/null +++ b/components/sudoku-image/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-image": "/components/image/index" + } +} \ No newline at end of file diff --git a/components/sudoku-image/index.wxml b/components/sudoku-image/index.wxml new file mode 100644 index 0000000..821ef7b --- /dev/null +++ b/components/sudoku-image/index.wxml @@ -0,0 +1,20 @@ + + + + + + + + + function checkImage(url) { + if (url.indexOf('.png') >= 0 || url.indexOf('.PNG') >= 0) { + return true + } else if (url.indexOf('.jpg') >= 0 || url.indexOf('.JPG') >= 0) { + return true + } else if (url.indexOf('.jpeg') >= 0 || url.indexOf('.JPEG') >= 0) { + return true + } + return false + } + module.exports = checkImage + \ No newline at end of file diff --git a/components/sudoku-image/index.wxss b/components/sudoku-image/index.wxss new file mode 100644 index 0000000..a12c39e --- /dev/null +++ b/components/sudoku-image/index.wxss @@ -0,0 +1,4 @@ +.view-load { + margin-right: 12rpx; + margin-bottom: 12rpx +} \ No newline at end of file diff --git a/components/switch/index.js b/components/switch/index.js new file mode 100644 index 0000000..af301c5 --- /dev/null +++ b/components/switch/index.js @@ -0,0 +1,51 @@ +import { VantComponent } from '../common/component'; +import { BLUE, GRAY_DARK } from '../common/color'; +VantComponent({ + field: true, + classes: ['node-class'], + props: { + checked: { + type: null, + observer(value) { + const loadingColor = this.getLoadingColor(value); + this.setData({ value, loadingColor }); + } + }, + loading: Boolean, + disabled: Boolean, + activeColor: String, + inactiveColor: String, + size: { + type: String, + value: '30px' + }, + activeValue: { + type: null, + value: true + }, + inactiveValue: { + type: null, + value: false + } + }, + created() { + const { checked: value } = this.data; + const loadingColor = this.getLoadingColor(value); + this.setData({ value, loadingColor }); + }, + methods: { + getLoadingColor(checked) { + const { activeColor, inactiveColor } = this.data; + return checked ? activeColor || BLUE : inactiveColor || GRAY_DARK; + }, + onClick() { + const { activeValue, inactiveValue } = this.data; + if (!this.data.disabled && !this.data.loading) { + const checked = this.data.checked === activeValue; + const value = checked ? inactiveValue : activeValue; + this.$emit('input', value); + this.$emit('change', value); + } + } + } +}); diff --git a/components/switch/index.json b/components/switch/index.json new file mode 100644 index 0000000..01077f5 --- /dev/null +++ b/components/switch/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-loading": "../loading/index" + } +} diff --git a/components/switch/index.wxml b/components/switch/index.wxml new file mode 100644 index 0000000..31a104d --- /dev/null +++ b/components/switch/index.wxml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/components/switch/index.wxss b/components/switch/index.wxss new file mode 100644 index 0000000..e32a72a --- /dev/null +++ b/components/switch/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-switch{position:relative;display:inline-block;box-sizing:initial;width:2em;width:var(--switch-width,2em);height:1em;height:var(--switch-height,1em);background-color:#fff;background-color:var(--switch-background-color,#fff);border:1px solid rgba(0,0,0,.1);border:var(--switch-border,1px solid rgba(0,0,0,.1));border-radius:1em;border-radius:var(--switch-node-size,1em);transition:background-color .3s;transition:background-color var(--switch-transition-duration,.3s)}.van-switch__node{position:absolute;top:0;left:0;border-radius:100%;z-index:1;z-index:var(--switch-node-z-index,1);width:1em;width:var(--switch-node-size,1em);height:1em;height:var(--switch-node-size,1em);background-color:#fff;background-color:var(--switch-node-background-color,#fff);box-shadow:0 3px 1px 0 rgba(0,0,0,.05),0 2px 2px 0 rgba(0,0,0,.1),0 3px 3px 0 rgba(0,0,0,.05);box-shadow:var(--switch-node-box-shadow,0 3px 1px 0 rgba(0,0,0,.05),0 2px 2px 0 rgba(0,0,0,.1),0 3px 3px 0 rgba(0,0,0,.05));transition:-webkit-transform .3s cubic-bezier(.3,1.05,.4,1.05);transition:transform .3s cubic-bezier(.3,1.05,.4,1.05);transition:transform .3s cubic-bezier(.3,1.05,.4,1.05),-webkit-transform .3s cubic-bezier(.3,1.05,.4,1.05);transition:-webkit-transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05);transition:transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05);transition:transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05),-webkit-transform var(--switch-transition-duration,.3s) cubic-bezier(.3,1.05,.4,1.05)}.van-switch__loading{position:absolute!important;top:25%;left:25%;width:50%;height:50%}.van-switch--on{background-color:#1989fa;background-color:var(--switch-on-background-color,#1989fa)}.van-switch--on .van-switch__node{-webkit-transform:translateX(1em);transform:translateX(1em);-webkit-transform:translateX(calc(var(--switch-width, 2em) - var(--switch-node-size, 1em)));transform:translateX(calc(var(--switch-width, 2em) - var(--switch-node-size, 1em)))}.van-switch--disabled{opacity:.4;opacity:var(--switch-disabled-opacity,.4)} \ No newline at end of file diff --git a/components/tab/index.js b/components/tab/index.js new file mode 100644 index 0000000..79a3c23 --- /dev/null +++ b/components/tab/index.js @@ -0,0 +1,59 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + name: 'tabs', + type: 'ancestor', + current: 'tab', + }, + props: { + dot: { + type: Boolean, + observer: 'update' + }, + info: { + type: null, + observer: 'update' + }, + title: { + type: String, + observer: 'update' + }, + disabled: { + type: Boolean, + observer: 'update' + }, + titleStyle: { + type: String, + observer: 'update' + }, + name: { + type: [Number, String], + value: '', + } + }, + data: { + active: false + }, + methods: { + getComputedName() { + if (this.data.name !== '') { + return this.data.name; + } + return this.index; + }, + updateRender(active, parent) { + const { data: parentData } = parent; + this.inited = this.inited || active; + this.setData({ + active, + shouldRender: this.inited || !parentData.lazyRender, + shouldShow: active || parentData.animated + }); + }, + update() { + if (this.parent) { + this.parent.updateTabs(); + } + } + } +}); diff --git a/components/tab/index.json b/components/tab/index.json new file mode 100644 index 0000000..32640e0 --- /dev/null +++ b/components/tab/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} \ No newline at end of file diff --git a/components/tab/index.wxml b/components/tab/index.wxml new file mode 100644 index 0000000..f5e99f2 --- /dev/null +++ b/components/tab/index.wxml @@ -0,0 +1,8 @@ + + + + + diff --git a/components/tab/index.wxss b/components/tab/index.wxss new file mode 100644 index 0000000..76ddf06 --- /dev/null +++ b/components/tab/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';:host{-webkit-flex-shrink:0;flex-shrink:0;width:100%}.van-tab__pane,:host{box-sizing:border-box}.van-tab__pane{overflow-y:auto;-webkit-overflow-scrolling:touch}.van-tab__pane--active{height:auto}.van-tab__pane--inactive{height:0;overflow:visible} \ No newline at end of file diff --git a/components/tabbar-item/index.js b/components/tabbar-item/index.js new file mode 100644 index 0000000..3555a26 --- /dev/null +++ b/components/tabbar-item/index.js @@ -0,0 +1,48 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + props: { + info: null, + name: null, + icon: String, + dot: Boolean + }, + relation: { + name: 'tabbar', + type: 'ancestor', + current: 'tabbar-item', + }, + data: { + active: false + }, + methods: { + onClick() { + if (this.parent) { + this.parent.onChange(this); + } + this.$emit('click'); + }, + updateFromParent() { + const { parent } = this; + if (!parent) { + return; + } + const index = parent.children.indexOf(this); + const parentData = parent.data; + const { data } = this; + const active = (data.name || index) === parentData.active; + const patch = {}; + if (active !== data.active) { + patch.active = active; + } + if (parentData.activeColor !== data.activeColor) { + patch.activeColor = parentData.activeColor; + } + if (parentData.inactiveColor !== data.inactiveColor) { + patch.inactiveColor = parentData.inactiveColor; + } + return Object.keys(patch).length > 0 + ? this.set(patch) + : Promise.resolve(); + } + } +}); diff --git a/components/tabbar-item/index.json b/components/tabbar-item/index.json new file mode 100644 index 0000000..16f174c --- /dev/null +++ b/components/tabbar-item/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-info": "../info/index" + } +} diff --git a/components/tabbar-item/index.wxml b/components/tabbar-item/index.wxml new file mode 100644 index 0000000..d83b061 --- /dev/null +++ b/components/tabbar-item/index.wxml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/components/tabbar-item/index.wxss b/components/tabbar-item/index.wxss new file mode 100644 index 0000000..35d3e71 --- /dev/null +++ b/components/tabbar-item/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-tabbar-item{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;height:100%;color:#646566;color:var(--tabbar-item-text-color,#646566);font-size:12px;font-size:var(--tabbar-item-font-size,12px);line-height:1;line-height:var(--tabbar-item-line-height,1)}.van-tabbar-item__icon{position:relative;font-size:18px;font-size:var(--tabbar-item-icon-size,18px)}.van-tabbar-item__icon__inner{display:block;min-width:1em}.van-tabbar-item--active{color:#1989fa;color:var(--tabbar-item-active-color,#1989fa)}.van-tabbar-item__info{margin-top:2px} \ No newline at end of file diff --git a/components/tabbar/index.js b/components/tabbar/index.js new file mode 100644 index 0000000..620936f --- /dev/null +++ b/components/tabbar/index.js @@ -0,0 +1,61 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + relation: { + name: 'tabbar-item', + type: 'descendant', + current: 'tabbar', + linked(target) { + target.parent = this; + target.updateFromParent(); + }, + unlinked() { + this.updateChildren(); + } + }, + props: { + active: { + type: null, + observer: 'updateChildren' + }, + activeColor: { + type: String, + observer: 'updateChildren' + }, + inactiveColor: { + type: String, + observer: 'updateChildren' + }, + fixed: { + type: Boolean, + value: true + }, + border: { + type: Boolean, + value: true + }, + zIndex: { + type: Number, + value: 1 + }, + safeAreaInsetBottom: { + type: Boolean, + value: true + } + }, + methods: { + updateChildren() { + const { children } = this; + if (!Array.isArray(children) || !children.length) { + return Promise.resolve(); + } + return Promise.all(children.map((child) => child.updateFromParent())); + }, + onChange(child) { + const index = this.children.indexOf(child); + const active = child.data.name || index; + if (active !== this.data.active) { + this.$emit('change', active); + } + } + } +}); diff --git a/components/tabbar/index.json b/components/tabbar/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/tabbar/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/tabbar/index.wxml b/components/tabbar/index.wxml new file mode 100644 index 0000000..9239d21 --- /dev/null +++ b/components/tabbar/index.wxml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/components/tabbar/index.wxss b/components/tabbar/index.wxss new file mode 100644 index 0000000..4824e24 --- /dev/null +++ b/components/tabbar/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-tabbar{display:-webkit-flex;display:flex;width:100%;height:100rpx;height:var(--tabbar-height, 100rpx);background-color:#fff;background-color:var(--tabbar-background-color,#fff)}.van-tabbar--fixed{position:fixed;bottom:0;left:0} \ No newline at end of file diff --git a/components/tabs/index.js b/components/tabs/index.js new file mode 100644 index 0000000..2786b3b --- /dev/null +++ b/components/tabs/index.js @@ -0,0 +1,274 @@ +import { VantComponent } from '../common/component'; +import { touch } from '../mixins/touch'; +import { isDef, addUnit } from '../common/utils'; +VantComponent({ + mixins: [touch], + classes: ['nav-class', 'tab-class', 'tab-active-class', 'line-class'], + relation: { + name: 'tab', + type: 'descendant', + current: 'tabs', + linked(target) { + target.index = this.children.length - 1; + this.updateTabs(); + }, + unlinked() { + this.children = this.children + .map((child, index) => { + child.index = index; + return child; + }); + this.updateTabs(); + } + }, + props: { + color: { + type: String, + observer: 'setLine' + }, + sticky: Boolean, + animated: { + type: Boolean, + observer() { + this.children.forEach((child, index) => child.updateRender(index === this.data.currentIndex, this)); + } + }, + swipeable: Boolean, + lineWidth: { + type: [String, Number], + value: -1, + observer: 'setLine' + }, + lineHeight: { + type: [String, Number], + value: -1, + observer: 'setLine' + }, + titleActiveColor: String, + titleInactiveColor: String, + active: { + type: [String, Number], + value: 0, + observer(name) { + if (name !== this.getCurrentName()) { + this.setCurrentIndexByName(name); + } + } + }, + type: { + type: String, + value: 'line' + }, + border: { + type: Boolean, + value: true + }, + ellipsis: { + type: Boolean, + value: true + }, + duration: { + type: Number, + value: 0.3 + }, + zIndex: { + type: Number, + value: 1 + }, + swipeThreshold: { + type: Number, + value: 4, + observer(value) { + this.setData({ + scrollable: this.children.length > value || !this.data.ellipsis + }); + } + }, + offsetTop: { + type: Number, + value: 0 + }, + lazyRender: { + type: Boolean, + value: true + } + }, + data: { + tabs: [], + lineStyle: '', + scrollLeft: 0, + scrollable: false, + trackStyle: '', + currentIndex: null, + container: null + }, + mounted() { + wx.nextTick(() => { + this.setLine(true); + this.scrollIntoView(); + }); + }, + methods: { + updateContainer() { + this.setData({ + container: () => this.createSelectorQuery().select('.van-tabs') + }); + }, + updateTabs() { + const { children = [], data } = this; + this.setData({ + tabs: children.map((child) => child.data), + scrollable: this.children.length > data.swipeThreshold || !data.ellipsis + }); + this.setCurrentIndexByName(this.getCurrentName() || data.active); + }, + trigger(eventName, child) { + const { currentIndex } = this.data; + const currentChild = child || this.children[currentIndex]; + if (!isDef(currentChild)) { + return; + } + this.$emit(eventName, { + index: currentChild.index, + name: currentChild.getComputedName(), + title: currentChild.data.title + }); + }, + onTap(event) { + const { index } = event.currentTarget.dataset; + const child = this.children[index]; + if (child.data.disabled) { + this.trigger('disabled', child); + } + else { + this.setCurrentIndex(index); + wx.nextTick(() => { + this.trigger('click'); + }); + } + }, + // correct the index of active tab + setCurrentIndexByName(name) { + const { children = [] } = this; + const matched = children.filter((child) => child.getComputedName() === name); + if (matched.length) { + this.setCurrentIndex(matched[0].index); + } + }, + setCurrentIndex(currentIndex) { + const { data, children = [] } = this; + if (!isDef(currentIndex) || + currentIndex >= children.length || + currentIndex < 0) { + return; + } + children.forEach((item, index) => { + const active = index === currentIndex; + if (active !== item.data.active || !item.inited) { + item.updateRender(active, this); + } + }); + if (currentIndex === data.currentIndex) { + return; + } + const shouldEmitChange = data.currentIndex !== null; + this.setData({ currentIndex }); + wx.nextTick(() => { + this.setLine(); + this.scrollIntoView(); + this.updateContainer(); + this.trigger('input'); + if (shouldEmitChange) { + this.trigger('change'); + } + }); + }, + getCurrentName() { + const activeTab = this.children[this.data.currentIndex]; + if (activeTab) { + return activeTab.getComputedName(); + } + }, + setLine(skipTransition) { + if (this.data.type !== 'line') { + return; + } + const { color, duration, currentIndex, lineWidth, lineHeight } = this.data; + this.getRect('.van-tab', true).then((rects = []) => { + const rect = rects[currentIndex]; + if (rect == null) { + return; + } + const width = lineWidth !== -1 ? lineWidth : rect.width / 2; + const height = lineHeight !== -1 + ? `height: ${addUnit(lineHeight)}; border-radius: ${addUnit(lineHeight)};` + : ''; + let left = rects + .slice(0, currentIndex) + .reduce((prev, curr) => prev + curr.width, 0); + left += (rect.width - width) / 2; + const transition = skipTransition + ? '' + : `transition-duration: ${duration}s; -webkit-transition-duration: ${duration}s;`; + this.setData({ + lineStyle: ` + ${height} + width: ${addUnit(width)}; + background-color: ${color}; + -webkit-transform: translateX(${left}px); + transform: translateX(${left}px); + ${transition} + ` + }); + }); + }, + // scroll active tab into view + scrollIntoView() { + const { currentIndex, scrollable } = this.data; + if (!scrollable) { + return; + } + Promise.all([ + this.getRect('.van-tab', true), + this.getRect('.van-tabs__nav') + ]).then(([tabRects, navRect]) => { + const tabRect = tabRects[currentIndex]; + const offsetLeft = tabRects + .slice(0, currentIndex) + .reduce((prev, curr) => prev + curr.width, 0); + this.setData({ + scrollLeft: offsetLeft - (navRect.width - tabRect.width) / 2 + }); + }); + }, + onTouchScroll(event) { + this.$emit('scroll', event.detail); + }, + onTouchStart(event) { + if (!this.data.swipeable) + return; + this.touchStart(event); + }, + onTouchMove(event) { + if (!this.data.swipeable) + return; + this.touchMove(event); + }, + // watch swipe touch end + onTouchEnd() { + if (!this.data.swipeable) + return; + const { tabs, currentIndex } = this.data; + const { direction, deltaX, offsetX } = this; + const minSwipeDistance = 50; + if (direction === 'horizontal' && offsetX >= minSwipeDistance) { + if (deltaX > 0 && currentIndex !== 0) { + this.setCurrentIndex(currentIndex - 1); + } + else if (deltaX < 0 && currentIndex !== tabs.length - 1) { + this.setCurrentIndex(currentIndex + 1); + } + } + } + } +}); diff --git a/components/tabs/index.json b/components/tabs/index.json new file mode 100644 index 0000000..19c0bc3 --- /dev/null +++ b/components/tabs/index.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "van-info": "../info/index", + "van-sticky": "../sticky/index" + } +} diff --git a/components/tabs/index.wxml b/components/tabs/index.wxml new file mode 100644 index 0000000..9fe5a2f --- /dev/null +++ b/components/tabs/index.wxml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + {{ item.title }} + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/tabs/index.wxs b/components/tabs/index.wxs new file mode 100644 index 0000000..88bcafd --- /dev/null +++ b/components/tabs/index.wxs @@ -0,0 +1,78 @@ +/* eslint-disable */ +function tabClass(active, ellipsis) { + var classes = ['tab-class']; + + if (active) { + classes.push('tab-active-class'); + } + + if (ellipsis) { + classes.push('van-ellipsis'); + } + + return classes.join(' '); +} + +function tabStyle( + active, + ellipsis, + color, + type, + disabled, + activeColor, + inactiveColor, + swipeThreshold, + scrollable +) { + var styles = []; + var isCard = type === 'card'; + // card theme color + if (color && isCard) { + styles.push('border-color:' + color); + + if (!disabled) { + if (active) { + styles.push('background-color:' + color); + } else { + styles.push('color:' + color); + } + } + } + + var titleColor = active ? activeColor : inactiveColor; + if (titleColor) { + styles.push('color:' + titleColor); + } + + if (scrollable && ellipsis) { + styles.push('flex-basis:' + 88 / swipeThreshold + '%'); + } + + return styles.join(';'); +} + +function tabCardTypeBorderStyle(color, type) { + var isCard = type === 'card'; + var styles = []; + if (isCard && color) { + styles.push('border-color:' + color); + } + return styles.join(';'); +} + +function trackStyle(data) { + if (!data.animated) { + return ''; + } + + return [ + 'transform: translate3d(' + -100 * data.currentIndex + '%, 0, 0)', + '-webkit-transition-duration: ' + data.duration + 's', + 'transition-duration: ' + data.duration + 's' + ].join(';'); +} + +module.exports.tabClass = tabClass; +module.exports.tabStyle = tabStyle; +module.exports.trackStyle = trackStyle; +module.exports.tabCardTypeBorderStyle = tabCardTypeBorderStyle; diff --git a/components/tabs/index.wxss b/components/tabs/index.wxss new file mode 100644 index 0000000..41523be --- /dev/null +++ b/components/tabs/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-tabs{position:relative;-webkit-tap-highlight-color:transparent}.van-tabs__wrap{display:-webkit-flex;display:flex;overflow:hidden}.van-tabs__wrap--scrollable .van-tab{-webkit-flex:0 0 22%;flex:0 0 22%}.van-tabs__scroll{background-color:#fff;background-color:var(--tabs-nav-background-color,#fff)}.van-tabs__scroll--line{box-sizing:initial;height:calc(100% + 15px)}.van-tabs__scroll--card{margin:0 16px;margin:0 var(--padding-md,16px)}.van-tabs__nav{position:relative;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none}.van-tabs__nav--card{box-sizing:border-box;height:30px;height:var(--tabs-card-height,30px);border:1px solid #ee0a24;border:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24);border-radius:2px;border-radius:var(--border-radius-sm,2px)}.van-tabs__nav--card .van-tab{color:#ee0a24;color:var(--tabs-default-color,#ee0a24);line-height:28px;line-height:calc(var(--tabs-card-height, 30px) - 2*var(--border-width-base, 1px));border-right:1px solid #ee0a24;border-right:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{color:#fff;color:var(--white,#fff);background-color:#ee0a24;background-color:var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tabs__line{position:absolute;bottom:0;left:0;z-index:1;height:3px;height:var(--tabs-bottom-bar-height,3px);border-radius:3px;border-radius:var(--tabs-bottom-bar-height,3px);background-color:#ee0a24;background-color:var(--tabs-bottom-bar-color,#ee0a24)}.van-tabs__track{position:relative;width:100%;height:100%}.van-tabs__track--animated{display:-webkit-flex;display:flex;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.van-tabs__content{overflow:hidden}.van-tabs--line .van-tabs__wrap{height:88rpx;height:var(--tabs-line-height,88rpx)}.van-tabs--card .van-tabs__wrap{height:30px;height:var(--tabs-card-height,30px)}.van-tab{position:relative;-webkit-flex:1;flex:1;box-sizing:border-box;min-width:0;padding:0 5px;text-align:center;cursor:pointer;color:#646566;color:var(--tab-text-color,#646566);font-size:14px;font-size:var(--tab-font-size,14px);line-height:88rpx;line-height:var(--tabs-line-height,88rpx)}.van-tab--active{font-weight:500;font-weight:var(--font-weight-bold,500);color:#323233;color:var(--tab-active-text-color,#323233)}.van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tab--complete{-webkit-flex:1 0 auto!important;flex:1 0 auto!important}.van-tab__title__info{top:8px!important;right:10px;display:inline-block;-webkit-transform:translateX(0)!important;transform:translateX(0)!important} \ No newline at end of file diff --git a/components/tag/index.js b/components/tag/index.js new file mode 100644 index 0000000..093acb5 --- /dev/null +++ b/components/tag/index.js @@ -0,0 +1,21 @@ +import { VantComponent } from '../common/component'; +VantComponent({ + props: { + size: String, + mark: Boolean, + color: String, + plain: Boolean, + round: Boolean, + textColor: String, + type: { + type: String, + value: 'default' + }, + closeable: Boolean + }, + methods: { + onClose() { + this.$emit('close'); + } + } +}); diff --git a/components/tag/index.json b/components/tag/index.json new file mode 100644 index 0000000..0a336c0 --- /dev/null +++ b/components/tag/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index" + } +} diff --git a/components/tag/index.wxml b/components/tag/index.wxml new file mode 100644 index 0000000..86702bd --- /dev/null +++ b/components/tag/index.wxml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/components/tag/index.wxss b/components/tag/index.wxss new file mode 100644 index 0000000..211e376 --- /dev/null +++ b/components/tag/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-tag{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;line-height:normal;padding:.2em .5em;padding:var(--tag-padding,.2em .5em);color:#fff;color:var(--tag-text-color,#fff);font-size:10px;font-size:var(--tag-font-size,10px);border-radius:.2em;border-radius:var(--tag-border-radius,.2em)}.van-tag:after{border-color:currentColor;border-radius:.2em * 2;border-radius:var(--tag-border-radius,.2em) * 2}.van-tag--default{background-color:#969799;background-color:var(--tag-default-color,#969799)}.van-tag--default.van-tag--plain{color:#969799;color:var(--tag-default-color,#969799)}.van-tag--danger{background-color:#ee0a24;background-color:var(--tag-dander-color,#ee0a24)}.van-tag--danger.van-tag--plain{color:#ee0a24;color:var(--tag-dander-color,#ee0a24)}.van-tag--primary{background-color:#1989fa;background-color:var(--tag-primary-color,#1989fa)}.van-tag--primary.van-tag--plain{color:#1989fa;color:var(--tag-primary-color,#1989fa)}.van-tag--success{background-color:#07c160;background-color:var(--tag-success-color,#07c160)}.van-tag--success.van-tag--plain{color:#07c160;color:var(--tag-success-color,#07c160)}.van-tag--warning{background-color:#ff976a;background-color:var(--tag-warning-color,#ff976a)}.van-tag--warning.van-tag--plain{color:#ff976a;color:var(--tag-warning-color,#ff976a)}.van-tag--plain{background-color:#fff;background-color:var(--tag-plain-background-color,#fff)}.van-tag--mark{padding-right:.7em}.van-tag--mark,.van-tag--mark:after{border-radius:0 999px 999px 0;border-radius:0 var(--tag-round-border-radius,999px) var(--tag-round-border-radius,999px) 0}.van-tag--round,.van-tag--round:after{border-radius:999px;border-radius:var(--tag-round-border-radius,999px)}.van-tag--medium{font-size:12px;font-size:var(--tag-medium-font-size,12px)}.van-tag--large{font-size:14px;font-size:var(--tag-large-font-size,14px)}.van-tag__close{margin-left:2px} \ No newline at end of file diff --git a/components/transition/index.js b/components/transition/index.js new file mode 100644 index 0000000..f3c96e4 --- /dev/null +++ b/components/transition/index.js @@ -0,0 +1,15 @@ +'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); +var component_1 = require('../common/component'); +var transition_1 = require('../mixins/transition'); +component_1.VantComponent({ + classes: [ + 'enter-class', + 'enter-active-class', + 'enter-to-class', + 'leave-class', + 'leave-active-class', + 'leave-to-class', + ], + mixins: [transition_1.transition(true)], +}); diff --git a/components/transition/index.json b/components/transition/index.json new file mode 100644 index 0000000..467ce29 --- /dev/null +++ b/components/transition/index.json @@ -0,0 +1,3 @@ +{ + "component": true +} diff --git a/components/transition/index.wxml b/components/transition/index.wxml new file mode 100644 index 0000000..f030137 --- /dev/null +++ b/components/transition/index.wxml @@ -0,0 +1,8 @@ + + + diff --git a/components/transition/index.wxss b/components/transition/index.wxss new file mode 100644 index 0000000..d459f5c --- /dev/null +++ b/components/transition/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-transition{transition-timing-function:ease}.van-fade-enter-active,.van-fade-leave-active{transition-property:opacity}.van-fade-enter,.van-fade-leave-to{opacity:0}.van-fade-down-enter-active,.van-fade-down-leave-active,.van-fade-left-enter-active,.van-fade-left-leave-active,.van-fade-right-enter-active,.van-fade-right-leave-active,.van-fade-up-enter-active,.van-fade-up-leave-active{transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.van-fade-up-enter,.van-fade-up-leave-to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);opacity:0}.van-fade-down-enter,.van-fade-down-leave-to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);opacity:0}.van-fade-left-enter,.van-fade-left-leave-to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);opacity:0}.van-fade-right-enter,.van-fade-right-leave-to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);opacity:0}.van-slide-down-enter-active,.van-slide-down-leave-active,.van-slide-left-enter-active,.van-slide-left-leave-active,.van-slide-right-enter-active,.van-slide-right-leave-active,.van-slide-up-enter-active,.van-slide-up-leave-active{transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.van-slide-up-enter,.van-slide-up-leave-to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}.van-slide-down-enter,.van-slide-down-leave-to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.van-slide-left-enter,.van-slide-left-leave-to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.van-slide-right-enter,.van-slide-right-leave-to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)} \ No newline at end of file diff --git a/components/uploader/index.js b/components/uploader/index.js new file mode 100644 index 0000000..33f96a0 --- /dev/null +++ b/components/uploader/index.js @@ -0,0 +1,238 @@ +import { VantComponent } from '../common/component' +import { isImageFile, isVideo, chooseFile, isPromise } from './utils' +import { chooseImageProps, chooseVideoProps } from './shared' +const app = getApp() + +VantComponent({ + props: Object.assign(Object.assign({ + disabled: Boolean, + multiple: Boolean, + crop: Boolean, + uploadText: String, + useBeforeRead: Boolean, + afterRead: null, + beforeRead: null, + previewSize: { type: null, value: 90 }, + name: { type: [Number, String], value: '' }, + accept: { type: String, value: 'image' }, + fileList: { type: Array, value: [], observer: 'formatFileList' }, + maxSize: { type: Number, value: Number.MAX_VALUE }, + url: { type: String, value: 'uploadImage' }, + maxCount: { type: Number, value: 100 }, + deletable: { type: Boolean, value: true }, + showUpload: { type: Boolean, value: true }, + previewImage: { type: Boolean, value: true }, + previewFullImage: { type: Boolean, value: true }, + imageFit: { type: String, value: 'aspectFill' }, + uploadIcon: { type: String, value: 'photograph' } + }, chooseImageProps), chooseVideoProps), + data: { + lists: [], + isInCount: true, + cropList: [], + taskList: [], + visible: false + }, + lifetimes: { + // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 + detached: function () { + for (let i = 0; i < this.data.taskList.length; i++) { + if (this.data.taskList[index]) { + this.data.taskList[index].abort() // 取消上传任务 + } + } + } + }, + methods: { + isEmpty: function(val) { + return typeof val === 'undefined' || val === '' || val === null + }, + formatFileList() { + const { fileList = [], maxCount } = this.data; + const lists = fileList.map(item => (Object.assign(Object.assign({}, item), { + isImage: typeof item.isImage === 'undefined' ? isImageFile(item) : item.isImage + }))) + this.setData({ lists, isInCount: lists.length < maxCount }) + }, + getDetail(index) { + return { name: this.data.name, index: index == null ? this.data.fileList.length : index } + }, + startUpload() { + if (disabled) + return + const { maxCount, multiple, accept, lists, disabled } = this.data + chooseFile(Object.assign(Object.assign({}, this.data), { maxCount: maxCount - lists.length })).then(res => { + let file = null + if (isVideo(res, accept)) { + file = Object.assign({ path: res.tempFilePath }, res) + } else { + file = multiple ? res.tempFiles : res.tempFiles[0] + } + this.onBeforeRead(file) + }).catch(error => { + this.$emit('error', error) + }) + }, + onBeforeRead(file) { + const { beforeRead, useBeforeRead } = this.data + let res = true + if (typeof beforeRead === 'function') { + res = beforeRead(file, this.getDetail()) + } + if (useBeforeRead) { + res = new Promise((resolve, reject) => { + this.$emit('before-read', Object.assign(Object.assign({ file}, this.getDetail()), { callback: (ok) => { ok ? resolve() : reject() }})) + }) + } + if (!res) { + return + } + if (isPromise(res)) { + res.then((data) => this.onAfterRead(data || file)) + } else { + this.onAfterRead(file) + } + }, + onAfterRead(file) { + const { maxSize } = this.data; + const oversize = Array.isArray(file) ? file.some(item => item.size > maxSize) : file.size > maxSize + if (oversize) { + this.$emit('oversize', Object.assign({ file }, this.getDetail())) + return + } + if (typeof this.data.afterRead === 'function') { + this.data.afterRead(file, this.getDetail()) + } + if(this.data.crop){ + var cropList = [] + for (let index = 0; index < file.length; index++) { + cropList.push(file[index].path) + } + this.setData({ visible: true, cropList:cropList }) + } else { + this.handFiles(file) + } + }, + deleteItem(event) { + var index = event.currentTarget.dataset.index + var fsList = this.data.fileList + // 如果是正在上传的; + if (fsList[index]) { + if (fsList[index].status === 'uploading') { + if (this.data.taskList[index] && this.data.taskList[index].task) { + this.data.taskList[index].task.abort() // 取消上传任务 + } + this.data.taskList.splice(index, 1) + } + fsList.splice(index, 1) + } + this.formatFileList() + this.onUploadChange() + }, + onPreviewImage(event) { + const { index } = event.currentTarget.dataset; + const { lists } = this.data; + const item = lists[index]; + this.$emit('click-preview', Object.assign({ url: item.url || item.path }, this.getDetail(index))); + if (!this.data.previewFullImage) + return; + wx.previewImage({ + urls: lists.filter(item => item.isImage).map(item => item.url || item.path), + current: item.url || item.path, + fail() { + wx.showToast({title: '预览图片失败',icon: 'none'}) + } + }) + }, + /*********************************************************************************************************************************************/ + onUploadChange: function(){ + var fileList = this.data.fileList + var uploading = false + for (let index = 0; index < fileList.length; index++) { + const element = fileList[index] + if(element.status == 'uploading'){ + uploading = true + break + } + } + if(!uploading){ + this.$emit('file-change', Object.assign({ fileList }, this.getDetail())) + } + }, + updateFile: function(path, url, status, message){ + var fsList = this.data.fileList + var index = -1 + for (let i = 0; i < fsList.length; i++) { + const element = fsList[i] + if(element.status == 'uploading' && element.path == path){ + index = i + break + } + } + if(index >= 0){ + this.setData({ ['fileList[' + index + ']']: { path, url, status, message } }) + } + }, + uploadFile: function (path) { + var that = this + const task = wx.uploadFile({ + url: app.httpUrl + '/saas-user/utils/uploadImage', + filePath: path, + name: 'image', + header: { 'Content-Type': 'multipart/form-data', 'appversion': app.version }, + success: function (result) { + var resp = null + if (!that.isEmpty(result.data)) { + resp = JSON.parse(result.data) + } + if (resp && resp.code === 0) { + that.updateFile(path, resp.data, 'done', '') + } else { + that.updateFile(path, null, 'failed', '上传失败') + } + that.onUploadChange() + }, + fail: function (res) { + that.updateFile(path, null, 'failed', '上传失败') + that.onUploadChange() + }, + complete: function (res) { + for (let i = 0; i < that.data.taskList.length; i++) { + if (that.data.taskList[i].path === path) { + that.data.taskList.splice(i, 1); + break + } + } + } + }) + that.data.taskList.push({ path: path, task: task }) + }, + handFiles: function(fsList){ + if(!this.isEmpty(this.data.url)){ + // 进行文件上传。 + for (let i = 0; i < fsList.length; i++) { + const element = fsList[i] + element.status = 'uploading' + element.message = '上传中' + this.uploadFile(element.path) + } + const fileList = this.data.fileList + this.setData({ visible: false, fileList: fileList.concat(fsList) }) + } else { + this.$emit('after-read', Object.assign({ fsList }, this.getDetail())) + } + }, + //裁剪图片回调 + onCroped: function (event) { + var fsList = [] + for (let index = 0; index < event.detail.length; index++) { + fsList.push({ path: event.detail[index] }) + } + this.handFiles(fsList) + }, + //关闭回调 + onClose: function () { + this.setData({ visible: false }) + } + } +}) \ No newline at end of file diff --git a/components/uploader/index.json b/components/uploader/index.json new file mode 100644 index 0000000..89006ec --- /dev/null +++ b/components/uploader/index.json @@ -0,0 +1,8 @@ +{ + "component": true, + "usingComponents": { + "van-icon": "../icon/index", + "van-loading": "../loading/index", + "van-cropper": "../image-cropper/index" + } +} diff --git a/components/uploader/index.wxml b/components/uploader/index.wxml new file mode 100644 index 0000000..7f1c4ff --- /dev/null +++ b/components/uploader/index.wxml @@ -0,0 +1,33 @@ + + + + + + + {{ item.name || ('图片' + index) }} + + + {{ item.name || item.url || item.path }} + + + + + {{ item.message }} + + + + + + + + + + + + {{ uploadText }} + + + + + + \ No newline at end of file diff --git a/components/uploader/index.wxss b/components/uploader/index.wxss new file mode 100644 index 0000000..da44e47 --- /dev/null +++ b/components/uploader/index.wxss @@ -0,0 +1 @@ +@import '../common/index.wxss';.van-uploader{position:relative;display:inline-block}.van-uploader__wrapper{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}.van-uploader__slot:empty{display:none}.van-uploader__slot:not(:empty)+.van-uploader__upload{display:none!important}.van-uploader__upload{position:relative;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:80px;height:80px;margin:0 8px 8px 0;background-color:#f7f8fa;border-radius:8px}.van-uploader__upload:active{background-color:#f2f3f5}.van-uploader__upload-icon{color:#dcdee0;font-size:24px}.van-uploader__upload-text{margin-top:8px;color:#969799;font-size:12px}.van-uploader__upload--disabled{opacity:.5;opacity:var(--uploader-disabled-opacity,.5)}.van-uploader__preview{position:relative;margin:0 8px 8px 0;cursor:pointer}.van-uploader__preview-image{display:block;width:80px;height:80px;overflow:hidden;border-radius:8px}.van-uploader__preview-delete{position:absolute;top:-8px;right:-8px;color:#969799;font-size:18px;background-color:#fff;border-radius:100%}.van-uploader__file{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;width:80px;height:80px;background-color:#f7f8fa;border-radius:8px}.van-uploader__file-icon{color:#646566;font-size:20px}.van-uploader__file-name{box-sizing:border-box;width:100%;margin-top:8px;padding:0 4px;color:#646566;font-size:12px;text-align:center}.van-uploader__mask{position:absolute;top:0;right:0;bottom:0;left:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#fff;background-color:rgba(50,50,51,.88);border-radius:8px}.van-uploader__mask-icon{font-size:22px}.van-uploader__mask-message{margin-top:6px;padding:0 4px;font-size:12px;line-height:14px}.van-uploader__loading{width:22px;height:22px;color:#fff} \ No newline at end of file diff --git a/components/uploader/shared.js b/components/uploader/shared.js new file mode 100644 index 0000000..871a07a --- /dev/null +++ b/components/uploader/shared.js @@ -0,0 +1,30 @@ +// props for choose image +export const chooseImageProps = { + sizeType: { + type: Array, + value: ['original', 'compressed'] + }, + capture: { + type: Array, + value: ['album', 'camera'] + } +}; +// props for choose video +export const chooseVideoProps = { + capture: { + type: Array, + value: ['album', 'camera'] + }, + compressed: { + type: Boolean, + value: true + }, + maxDuration: { + type: Number, + value: 60 + }, + camera: { + type: String, + value: 'back' + } +}; diff --git a/components/uploader/utils.js b/components/uploader/utils.js new file mode 100644 index 0000000..26389ac --- /dev/null +++ b/components/uploader/utils.js @@ -0,0 +1,61 @@ +const IMAGE_EXT = ['jpeg', 'jpg', 'gif', 'png', 'svg', 'webp']; +export function isImageUrl(url) { + return IMAGE_EXT.some(ext => url.indexOf(`.${ext}`) !== -1 || url.indexOf(`.${ext.toLocaleUpperCase()}`) !== -1); // 有些七牛返回来的后缀的大写,加以判断 +} +export function isImageFile(item) { + if (item.type) { + return item.type.indexOf('image') === 0; + } + if (item.path) { + return isImageUrl(item.path); + } + if (item.url) { + return isImageUrl(item.url); + } + return false; +} +export function isVideo(res, accept) { + return accept === 'video'; +} +export function chooseFile({ accept, multiple, capture, compressed, maxDuration, sizeType, camera, maxCount }) { + if (accept === 'image') { + return new Promise((resolve, reject) => { + wx.chooseImage({ + count: multiple ? Math.min(maxCount, 9) : 1, + sourceType: capture, + sizeType, + success: resolve, + fail: reject + }); + }); + } + if (accept === 'video') { + return new Promise((resolve, reject) => { + wx.chooseVideo({ + sourceType: capture, + compressed, + maxDuration, + camera, + success: resolve, + fail: reject + }); + }); + } + return new Promise((resolve, reject) => { + wx.chooseMessageFile({ + count: multiple ? maxCount : 1, + type: 'file', + success: resolve, + fail: reject + }); + }); +} +export function isFunction(val) { + return typeof val === 'function'; +} +export function isObject(val) { + return val !== null && typeof val === 'object'; +} +export function isPromise(val) { + return isObject(val) && isFunction(val.then) && isFunction(val.catch); +} diff --git a/components/wxs/add-unit.wxs b/components/wxs/add-unit.wxs new file mode 100644 index 0000000..7d24fd5 --- /dev/null +++ b/components/wxs/add-unit.wxs @@ -0,0 +1,13 @@ +/* eslint-disable */ +var REGEXP = getRegExp('^\d+(\.\d+)?$'); + +function addUnit(value) { + if (value == null) { + return undefined; + } + return REGEXP.test('' + value) ? value + 'px' : value; +} + +module.exports = { + addUnit: addUnit +}; diff --git a/components/wxs/array.wxs b/components/wxs/array.wxs new file mode 100644 index 0000000..610089c --- /dev/null +++ b/components/wxs/array.wxs @@ -0,0 +1,5 @@ +function isArray(array) { + return array && array.constructor === 'Array'; +} + +module.exports.isArray = isArray; diff --git a/components/wxs/bem.wxs b/components/wxs/bem.wxs new file mode 100644 index 0000000..93b2777 --- /dev/null +++ b/components/wxs/bem.wxs @@ -0,0 +1,38 @@ +var array = require('./array.wxs'); +var object = require('./object.wxs'); +var PREFIX = 'van-'; + +function join(name, mods) { + name = PREFIX + name; + mods = mods.map(function(mod) { + return name + '--' + mod; + }); + mods.unshift(name); + return mods.join(' '); +} + +function traversing(mods, conf) { + if (!conf) { + return; + } + + if (typeof conf === 'string' || typeof conf === 'number') { + mods.push(conf); + } else if (array.isArray(conf)) { + conf.forEach(function(item) { + traversing(mods, item); + }); + } else if (typeof conf === 'object') { + object.keys(conf).forEach(function(key) { + conf[key] && mods.push(key); + }); + } +} + +function bem(name, conf) { + var mods = []; + traversing(mods, conf); + return join(name, mods); +} + +module.exports.bem = bem; diff --git a/components/wxs/memoize.wxs b/components/wxs/memoize.wxs new file mode 100644 index 0000000..261ae67 --- /dev/null +++ b/components/wxs/memoize.wxs @@ -0,0 +1,54 @@ +/** + * Simple memoize + * wxs doesn't support fn.apply, so this memoize only support up to 2 args + */ + +function isPrimitive(value) { + var type = typeof value; + return ( + type === 'boolean' || + type === 'number' || + type === 'string' || + type === 'undefined' || + value === null + ); +} + +// mock simple fn.call in wxs +function call(fn, args) { + if (args.length === 2) { + return fn(args[0], args[1]); + } + + if (args.length === 1) { + return fn(args[0]); + } + + return fn(); +} + +function serializer(args) { + if (args.length === 1 && isPrimitive(args[0])) { + return args[0]; + } + var obj = {}; + for (var i = 0; i < args.length; i++) { + obj['key' + i] = args[i]; + } + return JSON.stringify(obj); +} + +function memoize(fn) { + var cache = {}; + + return function() { + var key = serializer(arguments); + if (cache[key] === undefined) { + cache[key] = call(fn, arguments); + } + + return cache[key]; + }; +} + +module.exports.memoize = memoize; diff --git a/components/wxs/object.wxs b/components/wxs/object.wxs new file mode 100644 index 0000000..e077107 --- /dev/null +++ b/components/wxs/object.wxs @@ -0,0 +1,13 @@ +/* eslint-disable */ +var REGEXP = getRegExp('{|}|"', 'g'); + +function keys(obj) { + return JSON.stringify(obj) + .replace(REGEXP, '') + .split(',') + .map(function(item) { + return item.split(':')[0]; + }); +} + +module.exports.keys = keys; diff --git a/components/wxs/utils.wxs b/components/wxs/utils.wxs new file mode 100644 index 0000000..d5c9d8c --- /dev/null +++ b/components/wxs/utils.wxs @@ -0,0 +1,10 @@ +/* eslint-disable */ +var bem = require('./bem.wxs').bem; +var memoize = require('./memoize.wxs').memoize; +var addUnit = require('./add-unit.wxs').addUnit; + +module.exports = { + bem: memoize(bem), + memoize: memoize, + addUnit: addUnit +}; diff --git a/pages/api/axios.js b/pages/api/axios.js new file mode 100644 index 0000000..a9d9948 --- /dev/null +++ b/pages/api/axios.js @@ -0,0 +1,62 @@ +/** + * Copyright © 2020-present LiuDanYang. All rights Reserved. + */ + +const axios = (function () { + class Axios { + constructor() { + this.defaults = { baseUrl: "" } + this.interceptors = { request: new InterceptorManager(), response: new InterceptorManager() } + } + + wxRequest(c) { + return new Promise((resolve, reject) => { + c = this.interceptors.request.func(c) + c.url = c.url.startsWith("http") ? c.url : c.baseUrl + c.url + c.success = (res) => { + resolve(this.interceptors.response.func(res)); + } + c.fail = (res) => { + reject(this.interceptors.response.func(res)); + } + wx.request(c) + }) + } + } + + Array.prototype.forEach.call(["options", "get", "head", "post", "put", "delete", "trace", "connect"], function (m) { + Axios.prototype[m] = function (url, data, config) { + return this.wxRequest( + merge( this.defaults, { url: url, method: m, data: data }, config || {} ) + ) + } + } + ) + + class InterceptorManager { + constructor() { + this.func = function (data) { + return data + } + } + use(fn) { + this.func = fn + } + } + + function merge(axiosDefaultConfig, data, config) { + let cloneAxios = deepClone(axiosDefaultConfig) + let cloneData = deepClone(data) + let cloneConfig = deepClone(config) + return Object.assign(cloneAxios, cloneData, cloneConfig) + } + + // 深拷贝 + function deepClone(obj) { + let _obj = JSON.stringify(obj), objClone = JSON.parse(_obj) + return objClone + } + return new Axios() +})() + +export default axios \ No newline at end of file diff --git a/pages/api/payment.js b/pages/api/payment.js new file mode 100644 index 0000000..f407f8a --- /dev/null +++ b/pages/api/payment.js @@ -0,0 +1,20 @@ +/** + * Copyright © 2020-present LiuDanYang. All rights Reserved. + */ +import { mGet, mPost } from "./request" +const app = getApp() + +const pconfig = { + baseUrl: app.release ? `https://psc.qniao.cn` : `http://psc-dev.qniao.cn` +} +// *******************************************************************账户业务*********************************************************** +// /credit/get/self-enterprise-credit-by-enterprise-id查看个人的采购额度 +const getCreditInfo = (params) => mGet(`/payment-settlement-center/credit/get/self-enterprise-credit-by-enterprise-id`, params, pconfig) + +const paymentInfo = (params) => mPost(`/payment-settlement-center/pay`, params, pconfig) + +export { + pconfig, + getCreditInfo, + paymentInfo +} \ No newline at end of file diff --git a/pages/api/request.js b/pages/api/request.js new file mode 100644 index 0000000..a38ef92 --- /dev/null +++ b/pages/api/request.js @@ -0,0 +1,209 @@ +/** + * Copyright © 2020-present LiuDanYang. All rights Reserved. + */ + +import axios from "./axios" +const event = require('../../utils/event') +const app = getApp() +/** + * axios defaults 配置 + */ +axios.defaults = { + timeout: 60000 +} + +/** + * 全局 请求拦截器, 支持添加多个拦截器 + * 例如: 配置token、添加一些默认的参数 + * `return config` 继续发送请求 + */ +axios.interceptors.request.use( + config => { + config.header = { ...config.header, 'X-APP-ID': app.xAppId, appversion: app.version } + return config + }, + error => { + // 做一些请求错误 + console.error(error) + return Promise.reject(error) + } +) + +/** + * 全局 响应拦截器, 支持添加多个拦截器 + * 例如: 根据状态码选择性拦截、过滤转换数据 + * @param {Object} res 请求返回的数据 + * @return {Promise} + */ +axios.interceptors.response.use( + async (res) => { + const { data, statusCode: status } = res + try { + return await handleResponse({ data, status }) + } catch (err) { + return Promise.reject(err) + } + }, + (err) => { + // 做一些请求错误 + console.error(err) + return Promise.reject(err) + } +) + +/** + * 处理 HTTP 状态码 + * @param data {Object} 请求返回的数据 + * @param status {String} HTTP状态码 + * @returns {Promise|*} + */ +function handleResponse({ data, status }) { + if(!data){ + return Promise.reject('服务器错误') + } + const STATUS = { + "200"() { + return handleResult(data) + }, + "400"() { + return Promise.reject('请求错误') + }, + "401"() { + return Promise.reject('请求未授权') + }, + "403"() { + return Promise.reject('拒绝请求') + }, + "404"() { + return Promise.reject('URL错误') + }, + "500"() { + return Promise.reject('服务器错误') + } + } + // 有状态码但不在这个封装的配置里,就直接返回错误 + return STATUS[status] ? STATUS[status]() : Promise.reject('请求错误') +} + +function handleResult(result) { + if (result.code === 0) { + return result + } + if (result.code === 401) { + app.globalData.token = null + app.globalData.userToken = null + wx.removeStorageSync('Authorization') + event.emit('EventMessage', { what: 666, desc: 'Logout' }) + let pages = getCurrentPages() //当前页面栈 + let prevPage = pages[pages.length - 1] //当前页面 + if (prevPage.route != 'pages/login/index') { + wx.showModal({ + title: '温馨提示', + content: '登录信息已经过期,请重新登录', + showCancel: false, + success: function (res) { + if (res.confirm) { + wx.reLaunch({ url: '/pages/login/index' }) + } + } + }) + } + var message = 'Token异常' + if (result.message) { + message = result.message + } + return Promise.reject(message) + } + var message = '数据错误' + if (result.message) { + message = result.message + } + return Promise.reject(message) +} + +export default axios + + +/** + * get 请求方式 + * @param url {String} 接口地址 + * @param params {Object} 接口参数 + * @returns {AxiosPromise} + * @constructor + */ +export function mGet(url, params, config) { + return new Promise((resolve, reject) => { + axios.get(url, params, config).then((res) => { + resolve(res) + }).catch((err) => { + reject(err) + }) + }) +} + +/** + * post 请求方式 + * @param url {String} 接口地址 + * @param data {Object} 接口参数 + * @returns {AxiosPromise} + * @constructor + */ +export function mPost(url, data, config) { + return new Promise((resolve, reject) => { + axios.post(url, data, config).then((res) => { + resolve(res) + }).catch((err) => { + reject(err) + }) + }) +} + +/** + * put 请求方式-用于修改全部数据 + * @param url {String} 接口地址 + * @param data {Object} 接口参数 + * @returns {AxiosPromise} + * @constructor + */ +export function mPut(url, data, config) { + return new Promise((resolve, reject) => { + axios.put(url, data, config).then((res) => { + resolve(res) + }).catch((err) => { + reject(err) + }) + }) +} + +/** + * patch 请求方式-用于修改单项或多项数据 + * @param url {String} 接口地址 + * @param data {Object} 接口参数 + * @returns {AxiosPromise} + * @constructor + */ +export function mPatch(url, data, config) { + return new Promise((resolve, reject) => { + axios.patch(url, data, config).then((res) => { + resolve(res) + }).catch((err) => { + reject(err) + }) + }) +} + +/** + * delete 请求方式 + * @param url {String} 接口地址 + * @param params {Object} 接口参数 + * @returns {AxiosPromise} + */ +export function mDelete(url, params, config) { + return new Promise((resolve, reject) => { + axios.delete(url, params, config).then((res) => { + resolve(res) + }).catch((err) => { + reject(err) + }) + }) +} \ No newline at end of file diff --git a/pages/api/user.js b/pages/api/user.js new file mode 100644 index 0000000..12f76aa --- /dev/null +++ b/pages/api/user.js @@ -0,0 +1,245 @@ +/** + * Copyright © 2020-present LiuDanYang. All rights Reserved. + */ +import { mGet, mPost, mDelete } from "./request" +// import { mconfig } from "./mall" +// import { cconfig } from "./cloud" +import { pconfig } from "./payment" +const util = require('../../utils/util') +const storage = require('../../utils/storage') +const app = getApp() + +const config = { + baseUrl: app.release ? 'https://uec.qniao.cn' : 'http://47.107.97.166:9000', + header: { + 'Authorization': `QNT ` + storage.get('Authorization') + } +} +const checkTestCode = (params) => mGet(`/uec/get/check/qr-code`, params, config) +///uec/get/auth-captcha +const verifyCode = (code, params) => mGet(`/uec/verify/qrcode${code}`, params, config) + +const qrcodeEmploye = (params) => mPost(`/uec/generate/qrcode`, params, config) +// /uec/get/wechat-applet-session +const wechatApplet = (params) => mPost('/uec/get/wechat-applet-session', params, config) +const authCaptcha = (params) => mPost(`/uec/get/auth-captcha`, params, config) +const verifyCaptcha = (params) => mPost(`/uec/authorize/by-captcha`, params, config) +const getUserInfo = (params) => mGet('/uec/get/user-info', params, config) + +const getAuthSession = () => mGet('/uec/create/identity-auth-session', null, config) + +const certificateImage = (params) => mPost('/uec/recognize/certificate-img', params, config) + +const certificateIdentity = (params) => mPost('/uec/identify/identity', params, config) + +const bindingAdmin = (params) => mPost(`/uec/bind/primary-account`, params, config) + +const bindingAccount = (params) => mPost(`/uec/apply/to/be/emplyee/of/enterprise`, params, config) + +const getCheckList = (params) => mGet(`/uec/get/auditing-joining-enterprise-application-list`, params, config) + +const getEmployeList = (params) => mGet(`/uec/get/passed-employees`, params, config) + +const auditEmploye = (params) => mPost(`/uec/audit/employee-joining-application`, params, config) + +const deleteEmploye = (params) => mPost(`/uec/remove/employees`, params, config) + +const adminEmploye = (params) => mPost(`/uec/grant/admin-role/to/employees`, params, config) + +const getAddressList = () => mGet(`/uec/get/enterprise-shipping-address-list/by-userId`, null, config) + +const getAddressInfo = (id) => mGet(`/uec/get/enterprise-shipping-address-list/by-userId`, null, config) + +const saveAddress = (params) => mPost(`/uec/save/enterprise-shipping-address`, params, config) +// /uec/delete/enterprise-shipping-address/{id} +const deleteAddress = (id) => mDelete(`/uec/delete/enterprise-shipping-address/${id}`, null, config) + + +// **************************************************************************************************************************************** +// /authorize/by-wechat-applet小程序登录 +function loginWechat(form) { + let promise = new Promise(function (resolve, reject) { + if (!form.encryptedData) { + util.showToast('授权被拒绝,获取微信用户失败') + reject('授权被拒绝,获取微信用户失败') + return + } + wx.showLoading({ title: '登录中', mask: true }) + var tempToken = storage.get('tmpAuthToken') + if(!util.isEmpty(tempToken)){ + form.tmpAuthToken = tempToken + unionWechat(form, resolve, reject) + } else { + wx.login({ + success: res => { + // 获取openId + wx.request({ + header: { 'X-APP-ID': app.xAppId }, + url: config.baseUrl + '/uec/get/wechat-applet-session', + data: { authCode: res.code }, + method: 'POST', + success: function (result) { + if (result.data.code == 0) { + form.tmpAuthToken = result.data.data.tmpAuthToken + storage.put('tmpAuthToken', form.tmpAuthToken, 98) + // 微信登录,获取unionId + unionWechat(form, resolve, reject) + } else { + wx.hideLoading() + util.showToast('登录失败,请稍后再试') + reject('登录失败,请稍后再试') + } + }, + fail: function (err) { + wx.hideLoading() + util.showToast('登录失败,请稍后再试') + reject('登录失败,请稍后再试') + } + }) + }, + fail: function (err) { + wx.hideLoading() + util.showToast('登录失败,请稍后再试') + reject('登录失败,请稍后再试') + } + }) + } + }) + return promise +} + +// POST ​/uec​/authorize​/by-wechat-applet 通过小程序的方式进行认证 +function unionWechat(form, resolve, reject) { + wx.request({ + header: { 'X-APP-ID': app.xAppId }, + url: config.baseUrl + '/uec/authorize/by-wechat-applet', + data: form, + method: 'POST', + success: function (result) { + wx.hideLoading() + if (result.data.code == 0) { + storage.remove('tempToken') + resolve(result.data) + } else { + reject(result.data) + } + }, + fail: function () { + wx.hideLoading() + wx.showToast({ title: '获取用户信息,请稍后再试', icon: "none" }) + reject('请求错误!') + } + }) +} +// **************************************************************************************************************************************** +// 通过微信的方式登录,onGotPhoneNumber中统一处理/uec/decrypt/wechat-applet-mobile +function gotPhoneNumber(form, resolve, reject) { + // 获取手机号码 /authorize/encrypt/mobile + wx.request({ + header: { 'X-APP-ID': app.xAppId }, + url: config.baseUrl + '/uec/decrypt/wechat-applet-mobile', + data: form, + method: 'POST', + success: function (result) { + // 绑定手机号码,进行登录 + wx.hideLoading() + if (result.data.code != 0) { + wx.showToast({ title: '登录失败,请稍后再试', icon: "none" }) + reject('登录失败,请稍后再试') + return + } + result.data.tmpAuthToken = form.tmpAuthToken + resolve(result.data) + }, + fail: function (res) { + wx.hideLoading() + wx.showToast({ title: '登录失败,请稍后再试', icon: "none" }) + reject('登录失败,请稍后再试') + } + }) +} + +function phoneWechat(form) { + let promise = new Promise(function (resolve, reject) { + if (!form.encryptedData) { + wx.showToast({ title: '授权被拒绝,登录失败', icon: "none" }) + reject('授权被拒绝,登录失败') + return + } + wx.showLoading({ title: '登录中', mask: true }) + // 没有获取到openId,获取之后进行登录 + wx.login({ + success: res => { + // 获取openId + wx.request({ + header: { 'X-APP-ID': app.xAppId }, + url: config.baseUrl + '/uec/get/wechat-applet-session', + data: { authCode: res.code }, + method: 'POST', + success: function (result) { + if (result.data.code == 0) { + form.tmpAuthToken = result.data.data.tmpAuthToken + // 获取手机号码 + gotPhoneNumber(form, resolve, reject) + } else { + wx.hideLoading() + wx.showToast({ title: '登录失败,请稍后再试', icon: "none" }) + reject('登录失败,请稍后再试') + } + }, + fail: function (res) { + wx.hideLoading() + wx.showToast({ title: '登录失败,请稍后再试', icon: "none" }) + reject('登录失败,请稍后再试') + } + }) + }, + fail: function (res) { + wx.hideLoading() + wx.showToast({ title: '登录失败,请稍后再试', icon: "none" }) + reject('登录失败,请稍后再试') + } + }) + }) + return promise +} + +function finalizeToken() { + config.header = null + mconfig.header = null + pconfig.header = null + cconfig.header = null +} + +export { + config, + qrcodeEmploye, + verifyCode, + checkTestCode, + wechatApplet, + authCaptcha, + verifyCaptcha, + getUserInfo, + getAuthSession, + certificateImage, + certificateIdentity, + phoneWechat, + loginWechat, + bindingAdmin, + bindingAccount, + getCheckList, + getEmployeList, + auditEmploye, + deleteEmploye, + adminEmploye, + getAddressList, + saveAddress, + getAddressInfo, + deleteAddress, + finalizeToken +} + +// module.exports = { +// phoneWechat: phoneWechat, +// loginWechat: loginWechat +// } \ No newline at end of file diff --git a/pages/enterprise/address-new/index.js b/pages/enterprise/address-new/index.js new file mode 100644 index 0000000..a69cccf --- /dev/null +++ b/pages/enterprise/address-new/index.js @@ -0,0 +1,110 @@ +// pages/enterprise/address-new/index.js +import { deleteAddress, saveAddress } from "../../api/user" +const util = require('../../../utils/util') +const region = require('../../../utils/area') +const storage = require('../../../utils/storage') +const event = require('../../../utils/event') +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + id: null, + show: false, + areaList: region.default, + form: { + receiver:'', + receiverMobile:'', + detail:'', + isDefault: 0, + provinceId: '', + provinceName: '', + cityId: '', + cityName: '', + districtId: '', + districtName: '' + }, + requesting: false + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + if(options.id){ + this.setData({ id: Number(options.id)}) + } + var json = storage.get('gdw-address') + if(json){ + storage.remove('gdw-address') + var form = JSON.parse(json) + form.areaStr = form.provinceName + ' ' + form.cityName + ' ' + form.districtName + this.setData({ form: form}) + } + }, + showRegion: function(){ + if(this.data.disabled){ + return + } + this.setData({ show: true }) + }, + bindinput: function(e){ + this.data.form[e.target.id] = e.detail.value + }, + onChange: function({ detail }) { + // 需要手动对 checked 状态进行更新 + this.setData({ ['form.isDefault']: detail ? 1 : 0 }) + }, + onConfirm: function({ detail }){ + this.data.form.enterpriseId = app.accountInfo.enterpriseId + this.data.form.provinceId = detail.values[0].code + this.data.form.provinceName = detail.values[0].name + this.data.form.cityId = detail.values[1].code + this.data.form.cityName = detail.values[1].name + this.data.form.districtId = detail.values[2].code + this.data.form.districtName = detail.values[2].name + var areaStr = detail.values[0].name + ' ' + detail.values[1].name + ' ' + detail.values[2].name + this.setData({ show: false, ['form.areaStr']: areaStr }) + }, + deleteForm: function(){ + wx.showLoading({ title: '处理中', mask: true }) + deleteAddress(this.data.form.id).then(result => { + wx.hideLoading() + event.emit('EventMessage', { what: 40, desc: 'Address' }) + util.showBackToast('地址已删除') + }).catch(err => { + wx.hideLoading() + }) + }, + submitForm: function () { + if(util.isEmpty(this.data.form.receiver)){ + util.showToast('请输入联系人') + return + } + if(util.isEmpty(this.data.form.receiverMobile)){ + util.showToast('请输入联系电话') + return + } + if(util.isEmpty(this.data.form.districtId)){ + util.showToast('请选择所在地区') + return + } + if(util.isEmpty(this.data.form.detail)){ + util.showToast('请输入详细地址') + return + } + wx.showLoading({ title: '处理中', mask: true }) + saveAddress(this.data.form).then(result => { + wx.hideLoading() + event.emit('EventMessage', { what: 40, desc: 'Address' }) + util.showBackToast('添加成功') + }).catch(err => { + wx.hideLoading() + util.showToast(err) + }) + }, + onClose: function() { + this.setData({ show: false }) + } +}) \ No newline at end of file diff --git a/pages/enterprise/address-new/index.json b/pages/enterprise/address-new/index.json new file mode 100644 index 0000000..05ed41f --- /dev/null +++ b/pages/enterprise/address-new/index.json @@ -0,0 +1,8 @@ +{ + "usingComponents": { + "van-switch": "/components/switch/index", + "van-popup": "/components/popup/index", + "van-area": "/components/area/index", + "van-button": "/components/button/index" + } +} \ No newline at end of file diff --git a/pages/enterprise/address-new/index.wxml b/pages/enterprise/address-new/index.wxml new file mode 100644 index 0000000..b4d68f0 --- /dev/null +++ b/pages/enterprise/address-new/index.wxml @@ -0,0 +1,38 @@ + + + {{ id ? '编辑' : '新增' }}地址 + + + + + 收货人: + + + + 手机号码: + + + + 所在地区: + {{form.areaStr||'请选择所在地区'}} + + + + + 详细地址: + + + + + 设为默认地址: + + + + + 删除 + 保存 + + + + + diff --git a/pages/enterprise/address-new/index.wxss b/pages/enterprise/address-new/index.wxss new file mode 100644 index 0000000..4c495eb --- /dev/null +++ b/pages/enterprise/address-new/index.wxss @@ -0,0 +1 @@ +/* pages/enterprise/address-new/index.wxss */ \ No newline at end of file diff --git a/pages/enterprise/address/index.js b/pages/enterprise/address/index.js new file mode 100644 index 0000000..d7a5b2a --- /dev/null +++ b/pages/enterprise/address/index.js @@ -0,0 +1,81 @@ +// pages/enterprise/address/index.js +import Dialog from '../../../components/dialog/dialog' +import { getAddressList, deleteAddress } from "../../api/user" +const event = require('../../../utils/event') +const util = require('../../../utils/util') +const storage = require('../../../utils/storage') + +Page({ + /** + * 页面的初始数据 + */ + data: { + type: 0, + addressList: [] + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + if(options.type){ + this.data.type = Number(options.type) + } + event.on('EventMessage', this, this.onEvent) + this.fetchAddressList() + }, + onEvent: function (message) { + if (message.what == 40) { + this.fetchAddressList() + } + }, + fetchAddressList: function(){ + wx.showLoading({ title: '加载中', mask: true }) + // /product/{id}产品详情 + getAddressList().then(result => { + wx.hideLoading() + this.setData({ addressList: result.data}) + }).catch(err => { + wx.hideLoading() + }) + }, + lookItem: function(e){ + var item = this.data.addressList[e.currentTarget.dataset.index] + if(this.data.type == 1){ + event.emit('EventMessage', { what: 41, obj: item, desc: 'Address' }) + wx.navigateBack() + } else { + storage.put('gdw-address', JSON.stringify(item), 1) + wx.navigateTo({ url: '/pages/enterprise/address-new/index?id=' + item.id }) + } + }, + /** + * 生命周期函数--监听页面初次渲染完成 + */ + addAddress: function (e) { + if(e.currentTarget.dataset.index >= 0){ + var item = this.data.addressList[e.currentTarget.dataset.index] + storage.put('gdw-address', JSON.stringify(item), 1) + wx.navigateTo({ url: '/pages/enterprise/address-new/index?id=' + item.id }) + } else { + wx.navigateTo({ url: '/pages/enterprise/address-new/index' }) + } + }, + delAddress: function(e){ + var item = this.data.addressList[e.currentTarget.dataset.index] + var that = this + Dialog.confirm({ title: '温馨提示', message: '确定删除该地址?' }).then(() => { + wx.showLoading({ title: '处理中', mask: true }) + deleteAddress(item.id).then(result => { + wx.hideLoading() + util.showToast('地址已删除') + that.fetchAddressList() + }).catch(err => { + console.log(err) + wx.hideLoading() + }) + }) + }, + onUnload: function(){ + event.remove('EventMessage', this) + } +}) \ No newline at end of file diff --git a/pages/enterprise/address/index.json b/pages/enterprise/address/index.json new file mode 100644 index 0000000..c9bdfd2 --- /dev/null +++ b/pages/enterprise/address/index.json @@ -0,0 +1,8 @@ +{ + "usingComponents": { + "van-cell": "/components/cell/index", + "van-checkbox": "/components/checkbox/index", + "van-button": "/components/button/index", + "van-dialog": "/components/dialog/index" + } +} \ No newline at end of file diff --git a/pages/enterprise/address/index.wxml b/pages/enterprise/address/index.wxml new file mode 100644 index 0000000..eec6d6a --- /dev/null +++ b/pages/enterprise/address/index.wxml @@ -0,0 +1,32 @@ + + + 地址管理 + + + + + + + {{item.receiver}} + {{item.receiverMobile}} + + {{item.provinceName + item.cityName + item.districtName + item.detail}} + + + + + + 已设为默认 + + + 删除 + 编辑 + + + + + + 新增地址 + + + \ No newline at end of file diff --git a/pages/enterprise/address/index.wxss b/pages/enterprise/address/index.wxss new file mode 100644 index 0000000..d84f111 --- /dev/null +++ b/pages/enterprise/address/index.wxss @@ -0,0 +1 @@ +/* pages/enterprise/address/index.wxss */ \ No newline at end of file diff --git a/pages/enterprise/employee/index.js b/pages/enterprise/employee/index.js new file mode 100644 index 0000000..21672c3 --- /dev/null +++ b/pages/enterprise/employee/index.js @@ -0,0 +1,178 @@ +// pages/home/employee/index.js +import { getCheckList, getEmployeList, auditEmploye, adminEmploye, deleteEmploye, qrcodeEmploye } from "../../api/user" +const util = require('../../../utils/util') +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + height: app.globalData.fragmentHeight, + base64: null, + loading: true, + checkList: [], + memberList: [], + eemidList: [], + showEmbedded: false + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.setData({ height: app.globalData.fragmentHeight }) + wx.showLoading({ title: '加载中', mask: true }) + this.fetchMemberList() + }, + fetchMemberList: function(){ + getCheckList({enterpriseId: app.accountInfo.enterpriseId}).then(result => { + //成功回调 + this.setData({ checkList: result.data, loading: false}) + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + this.data.eemidList = [] + getEmployeList({enterpriseId: app.accountInfo.enterpriseId, isPassFromBackstage: 1}).then(result => { + //成功回调 + for (let index = 0; index < result.data.length; index++) { + const element = result.data[index] + if(element.position == 'ADMINISTRATOR'){ + this.data.eemidList.push(element.id) + } + } + this.setData({ memberList: result.data, loading: false }) + wx.hideLoading() + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + }, + lookItem: function(event){ + var item = this.data.memberList[event.currentTarget.dataset.index] + if(item.position == 'ADMINISTRATOR'){ + return + } + var that = this + wx.showActionSheet({ + itemList: ['设为管理员'], + success(res){ + if (res.tapIndex === 0){ + that.setAdmin(event.currentTarget.dataset.index, item) + }if (res.tapIndex === 1){ + that.deleteItem(event.currentTarget.dataset.index, item) + } + } + }) + }, + setAdmin: function(index, item){ + wx.showLoading({ title: '加载中', mask: true }) + if(item.position == 'ADMINISTRATOR'){ + var sindex = -1 + for (var i = 0; i < this.data.eemidList.length; i++) { + if (this.data.eemidList[i] == item.id){ + sindex = i + break + } + } + this.data.eemidList.splice(sindex, 1) + } else { + if(this.data.eemidList.indexOf(item.id) < 0){ + this.data.eemidList.push(item.id) + } + } + adminEmploye({ids: this.data.eemidList }).then(result => { + //成功回调 + this.setData({ ['memberList[' + index + '].position'] : item.position == 'ADMINISTRATOR' ? 'ORDINARY' : 'ADMINISTRATOR'}) + wx.hideLoading() + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + }, + deleteItem: function(index, item){ + wx.showLoading({ title: '加载中', mask: true }) + deleteEmploye({idList: [item.id] }).then(result => { + //成功回调 + this.fetchMemberList() + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + }, + agreeItem: function(event){ + // /employees/audit 员工审核 + wx.showLoading({ title: '加载中', mask: true }) + var item = this.data.checkList[event.currentTarget.dataset.index] + auditEmploye({id: item.id, status: 1 }).then(result => { + //成功回调 + this.fetchMemberList() + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + }, + refuseItem: function(event){ + wx.showLoading({ title: '加载中', mask: true }) + var item = this.data.checkList[event.currentTarget.dataset.index] + auditEmploye({id: item.id, status: 2 }).then(result => { + //成功回调 + this.setData({ ['checkList[' + event.currentTarget.dataset.index + '].applicantStatus']: 2}) + wx.hideLoading() + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + }, + onClickHideEmbedded: function(){ + this.setData({ showEmbedded: false }) + }, + addEmployee: function(event){ + wx.showLoading({ title: '加载中', mask: true }) + const form = { id: 2, action: '/page/index/shenqing' } + form.metaData = { enterpriseId: app.accountInfo.enterpriseId, name: app.accountInfo.enterpriseName } + qrcodeEmploye(form).then(result => { + //成功回调 + this.setData({ showEmbedded: true, base64: result.data }) + wx.hideLoading() + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + }, + saveQrcode: function(){ + var fsm = wx.getFileSystemManager() + var ten = parseInt( Math.random() * 10) + var that = this + var number = Math.random().toString().replace('.', '') + fsm.writeFile({ + filePath: wx.env.USER_DATA_PATH + '/qrcode' + (ten + number) + '.png', + data: that.data.base64, + encoding: 'base64', + success: res => { + wx.saveImageToPhotosAlbum({ + filePath: wx.env.USER_DATA_PATH + '/qrcode' + (ten + number) + '.png', + success: function (res) { + that.setData({ showEmbedded: false }) + util.showToast('保存成功') + }, + fail: function (err) { + that.setData({ showEmbedded: false }) + } + }) + }, fail: err => { + that.setData({ showEmbedded: false }) + } + }) + }, + noop: function() { + + } +}) \ No newline at end of file diff --git a/pages/enterprise/employee/index.json b/pages/enterprise/employee/index.json new file mode 100644 index 0000000..3190622 --- /dev/null +++ b/pages/enterprise/employee/index.json @@ -0,0 +1,12 @@ +{ + "usingComponents": { + "van-cell": "/components/cell/index", + "van-button": "/components/button/index", + "van-image": "/components/image/index", + "van-index-bar": "/components/index-bar/index", + "van-index-anchor": "/components/index-anchor/index", + "van-tag": "/components/tag/index", + "van-icon": "/components/icon/index", + "van-overlay": "/components/overlay/index" + } +} \ No newline at end of file diff --git a/pages/enterprise/employee/index.wxml b/pages/enterprise/employee/index.wxml new file mode 100644 index 0000000..269debe --- /dev/null +++ b/pages/enterprise/employee/index.wxml @@ -0,0 +1,70 @@ + + + + 企业员工 + + + + + + + + {{loading? '正在加载' : '暂无数据'}} + + + + 待审核 + + + + + + {{item.userName}} + {{item.phone || ''}} + + + + 同意加入 + 拒绝加入 + + 已拒绝 + + + + + + 所有员工 + + + + + + {{item.userName || ''}} + 企业主 + 管理员 + + {{item.phone || ''}} + + + + + + + + + + + + + + + + + 保存二维码 + + 为保证企业账户安全,二维码仅在3小时内有效,失效后,可重新生成。 + + + \ No newline at end of file diff --git a/pages/enterprise/employee/index.wxss b/pages/enterprise/employee/index.wxss new file mode 100644 index 0000000..634c182 --- /dev/null +++ b/pages/enterprise/employee/index.wxss @@ -0,0 +1,37 @@ +/* pages/home/employee/index.wxss */ +.e-image{ + width: 90rpx; + height: 90rpx; + margin-top: 12rpx; +} + + +.booking-tool { + width: calc(100% - 20px); + background-color: #008AFF; + position: fixed; + bottom: 150px; + left: 25px; +} + +.roder-add { + display: flex; + justify-content: center; + align-items: center; + width: 100rpx; + height: 100rpx; + background-color: #008AFF; + border-radius: 50rpx; + position: absolute; + top: 24px; + right: 24px; + box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16); +} + +.wrapper { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + padding: 0px 15%; +} \ No newline at end of file diff --git a/pages/enterprise/index/index.js b/pages/enterprise/index/index.js new file mode 100644 index 0000000..b9ce91f --- /dev/null +++ b/pages/enterprise/index/index.js @@ -0,0 +1,17 @@ +// pages/enterprise/index/index.js +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + userInfo: null, + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.setData({ userInfo: app.accountInfo }) + } +}) \ No newline at end of file diff --git a/pages/enterprise/index/index.json b/pages/enterprise/index/index.json new file mode 100644 index 0000000..19fdd72 --- /dev/null +++ b/pages/enterprise/index/index.json @@ -0,0 +1,5 @@ +{ + "usingComponents": { + "van-cell": "/components/cell/index" + } +} \ No newline at end of file diff --git a/pages/enterprise/index/index.wxml b/pages/enterprise/index/index.wxml new file mode 100644 index 0000000..6cd20ea --- /dev/null +++ b/pages/enterprise/index/index.wxml @@ -0,0 +1,16 @@ + + + 我的企业 + + + + + {{userInfo.realName}} + 管理员 + + {{userInfo.enterpriseName}} + + + + + \ No newline at end of file diff --git a/pages/enterprise/index/index.wxss b/pages/enterprise/index/index.wxss new file mode 100644 index 0000000..212b56a --- /dev/null +++ b/pages/enterprise/index/index.wxss @@ -0,0 +1 @@ +/* pages/enterprise/index/index.wxss */ \ No newline at end of file diff --git a/pages/formate.wxs b/pages/formate.wxs new file mode 100644 index 0000000..ceed13d --- /dev/null +++ b/pages/formate.wxs @@ -0,0 +1,32 @@ +function isEmpty(val) { + return typeof val === 'undefined' || val === '' || val === null +} + +function formatTime(time) { + if (isEmpty(time)) { + return '' + } + var minute = 60 * 1000 + var just = 3 * 60 * 1000 + var onehour = 60 * 60 * 1000 + var oneday = 24 * 60 * 60 * 1000 + time = time.replace(getRegExp('/\s/g', 'g'), '') + var datetime = getDate(time.trim()) + var gap = getDate().getTime() - datetime.getTime() + + if (gap > oneday) { + return time.substring(0, 10) + } else if (gap > onehour) { + return parseInt(gap / onehour) + '小时前' + } else if (gap > onehour) { + return parseInt(gap / onehour) + '小时前' + } else if (gap > just) { + return parseInt(gap / minute) + '分钟前' + } else { + return '刚刚更新' + } +} + +module.exports = { + formatTime: formatTime +} \ No newline at end of file diff --git a/pages/home/authory/index.js b/pages/home/authory/index.js new file mode 100644 index 0000000..2ace65b --- /dev/null +++ b/pages/home/authory/index.js @@ -0,0 +1,108 @@ +// pages/home/authory/index.js +import { getAuthSession, certificateImage, certificateIdentity} from "../../api/user" +import Dialog from '../../../components/dialog/dialog' +const util = require('../../../utils/util') +const event = require('../../../utils/event') +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + step: 0, + form: { identityAuthToken: null }, + flag: false, // 是否不可以编辑, false:可编辑;true:不可编辑 + imgList: [null, null] + }, + onLoad: function(){ + wx.showLoading({ title: '加载中', mask: true }) + getAuthSession().then(result => { + wx.hideLoading() + this.data.form.identityAuthToken = result.data.token + }).catch(error => { + wx.hideLoading() + }) + }, + submitImage: function(){ + if (util.isEmpty(this.data.form.frontImg)) { + util.showToast('请上传身份证正面照片') + return + } + if (util.isEmpty(this.data.form.backImg)) { + util.showToast('请上传身份证背面照片') + return + } + wx.showLoading({ title: '处理中', mask: true }) + certificateImage(this.data.form).then(result => { + wx.hideLoading() + this.data.form.identityAuthToken = result.data.token + this.setData({ step: 1, form: result.data }) + }).catch(error => { + wx.hideLoading() + util.showToast(error) + }) + }, + submitForm: function(){ + wx.showLoading({ title: '处理中', mask: true }) + certificateIdentity(this.data.form).then(result => { + wx.hideLoading() + app.accountInfo.isAuth = 1 + event.emit('EventMessage', { what: 82, desc: 'Auth Success' }) + Dialog.alert({ title: '温馨提示', message: '个人信息认证成功' }).then(() => { + wx.navigateBack() + }) + }).catch(error => { + wx.hideLoading() + util.showToast(error) + }) + }, + /*******************************************************图片上传************************************************************/ + chooseImage: function(e) { + if (this.data.flag) { + return + } + var index = e.currentTarget.dataset.index + var that = this + wx.chooseImage({ + count: 1, //默认9 + sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 + sourceType: ['album', 'camera'], //从相册选择 + success: (res) => { + that.setData({ ['imgList[' + index + ']']: res.tempFilePaths[0] }) + const fileSystemManager = wx.getFileSystemManager() + var type = that.suffixImage(res.tempFilePaths[0]) + fileSystemManager.readFile({ + filePath: that.data.imgList[index], // 例如图片临时路径 + encoding: 'base64', + success(res) { + let { data } = res // 编码后的数据 + if(index == 0){ + that.data.form.frontImg = {base64: data, type} + } else { + that.data.form.backImg = {base64: data, type} + } + } + }) + } + }) + }, + suffixImage: function(path){ + return path.substring(path.lastIndexOf('.') + 1) + }, + viewImage: function(e) { + var urlList = [] + for (var i = 0; i < this.data.imgList.length; i++) { + if (!util.isEmpty(this.data.imgList[i])) { + urlList.push(this.data.imgList[i]) + } + } + wx.previewImage({ urls: urlList, current: e.currentTarget.dataset.url }) + }, + deleteImg: function(e) { + var index = e.currentTarget.dataset.index + this.data.imgList[index] = null; + this.setData({ imgList: this.data.imgList }) + } + +}) \ No newline at end of file diff --git a/pages/home/authory/index.json b/pages/home/authory/index.json new file mode 100644 index 0000000..0de7687 --- /dev/null +++ b/pages/home/authory/index.json @@ -0,0 +1,6 @@ +{ + "usingComponents": { + "van-button": "/components/button/index", + "van-dialog": "/components/dialog/index" + } +} \ No newline at end of file diff --git a/pages/home/authory/index.wxml b/pages/home/authory/index.wxml new file mode 100644 index 0000000..eb46fda --- /dev/null +++ b/pages/home/authory/index.wxml @@ -0,0 +1,59 @@ + + + 实名认证 + + + + + *请拍摄/上传本人身份证(头像面) + + + + + + + + + + + + + + + + *请拍摄/上传本人身份证(国徽面) + + + + + + + + + + + + + + + + + + + 姓名: + + + + 身份证号码: + + + + + + 提交 + + + 进行认证 + + + diff --git a/pages/home/authory/index.wxss b/pages/home/authory/index.wxss new file mode 100644 index 0000000..041c0bb --- /dev/null +++ b/pages/home/authory/index.wxss @@ -0,0 +1,57 @@ +/* pages/home/authory/index.wxss */ +page { + background-color: #fff; +} + +.margin-top { + margin-top: 18rpx +} + +.image-reader-item { + position: relative; + width: 99%; + height: 400rpx; + background-color: #f8f8f8; + box-sizing: border-box; + list-style: none; + background-size: cover; + border-radius: 6rpx; +} + +.image-reader-item .md-icon { + position: absolute; + top: 45%; + left: 50%; + transform: translate(-50%, -50%); + opacity: 0.5; +} + +.image-reader-item .md-load { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.image-reader-item .md-hint { + position: absolute; + top: 50%; + left: 0; + width: 100%; + margin-top: 10px; + font-size: 12px; + color: #bababa; + text-align: center; +} + +.image-reader-item .delete { + position: absolute; + top: 0px; + right: 0px; + opacity: 0.8; + border-top-right-radius: 6rpx; + border-bottom-left-radius: 8rpx; + padding: 6rpx 12rpx; + height: auto; + background-color: rgba(0, 0, 0, 0.5); +} \ No newline at end of file diff --git a/pages/home/index/index.js b/pages/home/index/index.js new file mode 100644 index 0000000..0a4c832 --- /dev/null +++ b/pages/home/index/index.js @@ -0,0 +1,99 @@ +// pages/stock/index.js +import Dialog from '../../../components/dialog/dialog' +import { finalizeToken } from "../../api/user" +import { getCreditInfo } from "../../api/payment" +const util = require('../../../utils/util') +const event = require('../../../utils/event.js') +const app = getApp() + +Component({ + options: { + addGlobalClass: true, + multipleSlots: true + }, + /** + * 页面的初始数据 + */ + data: { + height: app.globalData.safeFragmentHeight, + firstShow: false, + userInfo: null, + avatarUrl: '/assets/image/ygImg.png', + creditInfo: { availableCreditLine: 0, creditLine: 0, usedCreditLine: 0.00 } + }, + lifetimes: { + // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 + attached: function () { + event.on('EventMessage', this, this.onEvent) + }, + detached: function () { + event.remove('EventMessage', this) + } + }, + methods: { + // resume的处理; + onRestart: function () { + this.setUserInfo() + this.fetchCreditInfo() + this.data.firstShow = true + }, + onEvent: function (message) { + if (message.what == 82) { + // 认证成功 + } else if (message.what == 888) { + this.setData({creditInfo: { availableCreditLine: 0, creditLine: 0, usedCreditLine: 0.00 }}) + } + }, + setUserInfo: function(){ + if(!app.accountInfo){ + return + } + var nickname = '' + if(app.accountInfo.isAuth) { + nickname = app.accountInfo.realName.substring(0, 14) + } else if(!util.isEmpty(app.accountInfo.nickname)){ + nickname = app.accountInfo.nickname.substring(0, 14) + } else if(!util.isEmpty(app.accountInfo.realName)){ + nickname = app.accountInfo.realName.substring(0, 14) + } + this.setData({ + avatarUrl: util.isEmpty(app.accountInfo.avatarUrl) ? '/assets/image/ygImg.png' : app.accountInfo.avatarUrl, + userInfo: app.accountInfo, + userName: nickname, + height: app.globalData.safeFragmentHeight + }) + }, + toUserInfo: function(){ + if(!app.accountInfo){ + return + } + if(!app.accountInfo.isAuth){ + wx.navigateTo({ url: '/pages/home/authory/index' }) + } + }, + fetchCreditInfo: function(){ + if(!app.accountInfo || util.isEmpty(app.accountInfo.enterpriseId)){ + return + } + getCreditInfo({enterpriseId: app.accountInfo.enterpriseId}).then(result => { + this.setData({ creditInfo: result.data }) + }).catch(error => { }) + }, + orderList: function(){ + wx.navigateTo({ url: '/pages/mall/order-list/index' }) + }, + tipApply: function(){ + wx.navigateTo({ url: '/pages/htmls/credit/index' }) + }, + loginOut: function () { + Dialog.confirm({ title: '温馨提示', message: '确定退出云印通账号?' }).then(() => { + wx.removeStorageSync('Authorization') + app.globalData.token = null + app.accountInfo = null + this.setData({ userInfo: null, avatarUrl: '/assets/image/ygImg.png', creditInfo: { availableCreditLine: 0, creditLine: 0, usedCreditLine: 0.00 }}) + finalizeToken() + event.emit('EventMessage', { what: 888, desc: 'Logout' }) + }) + } + } +}) \ No newline at end of file diff --git a/pages/home/index/index.json b/pages/home/index/index.json new file mode 100644 index 0000000..0a12914 --- /dev/null +++ b/pages/home/index/index.json @@ -0,0 +1,12 @@ +{ + "component": true, + "usingComponents": { + "van-image": "/components/image/index", + "van-grid": "/components/grid/index", + "van-grid-item": "/components/grid-item/index", + "van-cell": "/components/cell/index", + "van-cell-group": "/components/cell-group/index", + "van-info": "/components/info/index", + "van-icon": "/components/icon/index" + } +} \ No newline at end of file diff --git a/pages/home/index/index.wxml b/pages/home/index/index.wxml new file mode 100644 index 0000000..898e516 --- /dev/null +++ b/pages/home/index/index.wxml @@ -0,0 +1,91 @@ + + + 我的 + + + + + + + + + + + + + + + {{userName || ''}} + + {{userInfo.isAuth == 1 ? '已认证' : '未实名认证'}} + 去认证 + + + + {{userInfo.mobile || ''}} + + + + + + + + + 先用后付 + 最高200万限额采购商品,满意了再付款 + + + + 剩余使用采购量 + {{formate.formateAmount(creditInfo.availableCreditLine)}} + 如何获得采购量? + + + 待付款订单 + {{formate.formateAmount(creditInfo.usedCreditLine)}} + 查看订单明细 + + + + + + + + + 商城订单 + + + + + + + + + + + + + + + + + 我的企业 + + + + + + 申请企业入驻 + + + + + + 退出当前账号 + + + + + + \ No newline at end of file diff --git a/pages/home/index/index.wxss b/pages/home/index/index.wxss new file mode 100644 index 0000000..d85ac49 --- /dev/null +++ b/pages/home/index/index.wxss @@ -0,0 +1,9 @@ +/* pages/home/index.wxss */ +.image-load { + width: 60px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 60rpx; +} \ No newline at end of file diff --git a/pages/home/mobile/index.js b/pages/home/mobile/index.js new file mode 100644 index 0000000..21fc640 --- /dev/null +++ b/pages/home/mobile/index.js @@ -0,0 +1,106 @@ +// pages/home/mobile/index.js +const util = require('../../../utils/util'); +const app = getApp() + +Page({ + + /** + * 页面的初始数据 + */ + data: { + mobileEnable: false, + codeEnable: true, + loginEnable: true, + second: '获取验证码', + form: { + accountType: 'MOBILE', + mobile: null, + captcha: null + }, + mobile: null + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.setData({ mobile: app.accountInfo.mobile }) + }, + bindInput: function (e) { + this.data.form[e.target.id] = e.detail.value + if ('mobile' == e.target.id) { + if ((/^1\d{10}$/.test(e.detail.value)) && e.detail.value.length == 11) { + this.setData({ mobileEnable: true }) + } + } + if ((/^1\d{10}$/.test(this.data.form.mobile)) && this.data.form.mobile.length == 11) { + if (!util.isEmpty(this.data.form.captcha)) { + this.setData({ loginEnable: false }) + } else { + this.setData({ loginEnable: true }) + } + } else { + this.setData({ loginEnable: true }) + } + }, + fetchCode: function () { + if (!(/^1\d{10}$/.test(this.data.form.mobile)) || this.data.form.mobile.length < 11) { + utill.showToast('请输入11位手机号码') + return + } + if (this.data.form.mobile == this.data.mobile) { + util.showToast('新手机号码不能和当前号码一致!') + return + } + wx.showLoading({ title: '正在获取', mask: true }) + var form = {account: this.data.form.mobile, accountType: 'MOBILE', purpose: 'RECYCLE_CLIENT_UPDATE_MOBILE' } + // /send/captcha 发送验证码 + // request.post('/cloud-print-user-center/send/captcha', form).then(result => { + // wx.hideLoading() + // this.setData({ codeEnable: false }) + // util.showToast('验证码已经发送') + // this.countDown = this.countDown || this.selectComponent('#count-down') + // this.countDown.reset() + // this.countDown.start() + // }).catch(error => { + // wx.hideLoading() + // util.showToast(error) + // }) + }, + onChange: function(e) { + this.setData({ second: e.detail.seconds + ' 秒 ' }) + }, + onFinished: function(){ + this.setData({ second: '重新获取验证码', codeEnable: true }) + }, + submitForm: function () { + if (this.data.requesting) { + return + } + if (!(/^1\d{10}$/.test(this.data.form.mobile)) || this.data.form.mobile.length < 11) { + utill.showToast('请输入11位手机号码') + return + } + if (this.data.form.mobile == this.data.mobile) { + util.showToast('新手机号码不能和当前号码一致!') + return + } + if (util.isEmpty(this.data.form.captcha)) { + util.showToast('请输入验证码') + return + } + wx.showLoading({ title: '处理中', mask: true }) + var data = { mobile: this.data.form.mobile, captcha: this.data.form.captcha } + this.data.requesting = true + // /front/customer/mobile修改手机号码 + // request.post('/cloud-print-user-center/user/modify/mobile', data).then(res => { + // wx.hideLoading() + // app.accountInfo.mobile = this.data.form.mobile + // util.showBackToast('修改成功') + // }).catch(error => { + // wx.hideLoading() + // this.data.requesting = false + // util.showToast(error) + // }) + } +}) \ No newline at end of file diff --git a/pages/home/mobile/index.json b/pages/home/mobile/index.json new file mode 100644 index 0000000..346e5d4 --- /dev/null +++ b/pages/home/mobile/index.json @@ -0,0 +1,6 @@ +{ + "usingComponents": { + "van-button": "/components/button/index", + "van-count-down": "/components/count-down/index" + } +} \ No newline at end of file diff --git a/pages/home/mobile/index.wxml b/pages/home/mobile/index.wxml new file mode 100644 index 0000000..e3dcf3f --- /dev/null +++ b/pages/home/mobile/index.wxml @@ -0,0 +1,25 @@ + + + 修改手机号码 + + +{{mobile ? '当前手机号码:' + mobile : '您还没有绑定手机号码'}} + + + + 手机号: + + + + 验证码: + + + + {{second}} + + + + + + 提交 + \ No newline at end of file diff --git a/pages/home/mobile/index.wxss b/pages/home/mobile/index.wxss new file mode 100644 index 0000000..4f147c6 --- /dev/null +++ b/pages/home/mobile/index.wxss @@ -0,0 +1,4 @@ +/* pages/home/mobile/index.wxss */ +page { + background-color: #fff; +} \ No newline at end of file diff --git a/pages/htmls/agreement/index.js b/pages/htmls/agreement/index.js new file mode 100644 index 0000000..c21ccb4 --- /dev/null +++ b/pages/htmls/agreement/index.js @@ -0,0 +1,9 @@ +// pages/home/agreement/index.js +Page({ + /** + * 页面的初始数据 + */ + data: { + + } +}) \ No newline at end of file diff --git a/pages/htmls/agreement/index.json b/pages/htmls/agreement/index.json new file mode 100644 index 0000000..8835af0 --- /dev/null +++ b/pages/htmls/agreement/index.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/htmls/agreement/index.wxml b/pages/htmls/agreement/index.wxml new file mode 100644 index 0000000..ee637fc --- /dev/null +++ b/pages/htmls/agreement/index.wxml @@ -0,0 +1,38 @@ + + + 用户服务协议 + + + + 软件许可使用协议 + 发布时间:2020年 7 月 1 日 + + 提示条款 + 本软件许可使用协议(以下称"本协议")由您与广州千鸟电商科技有限公司(以下称“我们”)于广东省广州市天河区共同签署。 + + 在使用“云印通”软件(软件名称以实际展示为准,以下称许可软件)之前,请您认真阅读并同意《千鸟互联服务协议》以及《隐私权政策》,这是我们向您提供许可软件及许可软件相关服务的前提。我们特别在此提示您注意阅读免除或者限制责任的条款、法律适用和争议解决条款,相关条款将以粗体标识,您需要重点阅读。如您对协议有任何疑问,可向客服咨询。如果您完全同意并接受本协议,您可下载安装或开始使用许可软件。 + + 本协议的内容包括协议正文及所有我们已经公布的适用于所有使用者的各类服务条款及规则(诸如《千鸟互联服务协议》、千鸟平台规则等),未来我们会继续丰富相关的服务条款与规则,并依法定程序公布生效。所有条款与规则为协议不可分割的组成部分,与协议具有同等法律效力。 + + 一、 定义 + 1、许可软件:是指由我们开发的,供您从下载平台下载,并仅限在相应系统手持移动终端中安装、使用的软件系统。 + 2、千鸟互联服务:我们基于互联网,以包含千鸟互联网站、本软件等在内的各种形态(包括未来技术发展出现的新的服务形态)向您提供的各项服务。 + + 二、许可范围 + 1、 由于软件适配平台及终端限制,您理解您仅可在许可软件列明的系统终端使用许可软件;您将许可软件安装在非对应系统的其他终端设备上的,可能会对您硬件或软件功能造成损害。 + 2、 许可软件仅限用于非商业目的,供您个人消费合理自用。未经许可,您不可为商业运营目的安装、使用、运行许可软件。 + 3、为了改善用户体验、完善服务内容、保证许可软件与我们提供服务的商业诉求一致,我们会对许可软件及/或其相关服务、功能、界面进行更新、修改,包括开发新的功能、删除旧功能等。您可按照变更后许可软件的实际情况取得相应功能或服务的授权,并可适用本协议相关约定。 + + 三、使用规范 + 1、 您应该规范使用许可软件,以下方式是违反使用规范的: + + (1)从事危害网络信息安全、欺诈、盗用他人账户、资金等违法犯罪活动,发表、传送、传播、储存侵害我们及他人知识产权、商业秘密权,或其他违反国家法律法规政策、破坏公序良俗、损害公共利益的行为; + (2) 擅自对许可软件及/或其组成部分进行出租、出借、再许可、复制、修改、链接、转载、汇编、发表、出版、建立镜像站点,或借助许可软件发展与之有关的衍生产品、作品、服务、插件、外挂、兼容、互联等; + (3) 通过非由我们或我们关联公司开发、授权或认可的第三方兼容软件、系统登录或使用许可软件,或针对许可软件使用非我们及我们关联公司开发、授权或认证的插件和外挂; + (4) 删除许可软件及其他副本上关于版权的信息、内容,或修改、删除或避开为保护知识产权而设置的任何技术措施; + (5)对许可软件或者许可软件运行过程中释放在终端中的任何数据及许可软件运行过程中终端与服务器端的交互数据进行获取、复制、修改或创作任何衍生作品,包括使用插件、外挂或非经授权的第三方工具/服务接入许可软件和相关系统等形式; + (6)通过修改或伪造许可软件运行中的指令、数据、数据包,增加、删减、变动许可软件的功能或运行效果,及/或将具有上述用途的软件通过信息网络向公众传播或者运营; + (7) 其他以任何不合法的方式、不合法的目的或以任何与本协议约定不一致的方式使用许可软件。 + + + \ No newline at end of file diff --git a/pages/htmls/agreement/index.wxss b/pages/htmls/agreement/index.wxss new file mode 100644 index 0000000..8dff873 --- /dev/null +++ b/pages/htmls/agreement/index.wxss @@ -0,0 +1 @@ +/* pages/home/agreement/index.wxss */ \ No newline at end of file diff --git a/pages/htmls/auths/index.js b/pages/htmls/auths/index.js new file mode 100644 index 0000000..8082ddc --- /dev/null +++ b/pages/htmls/auths/index.js @@ -0,0 +1,17 @@ +// pages/home/agreement/index.js +Page({ + /** + * 页面的初始数据 + */ + data: { + + }, + onImageLoad: function(e){ + console.log(e) + }, + tellPhone: function(){ + wx.makePhoneCall({ + phoneNumber: '020-82516486', + }) + } +}) \ No newline at end of file diff --git a/pages/htmls/auths/index.json b/pages/htmls/auths/index.json new file mode 100644 index 0000000..63eed5b --- /dev/null +++ b/pages/htmls/auths/index.json @@ -0,0 +1,7 @@ +{ + "usingComponents": { + "van-image": "/components/image/index", + "van-loading": "/components/loading/index", + "van-button": "/components/button/index" + } +} \ No newline at end of file diff --git a/pages/htmls/auths/index.wxml b/pages/htmls/auths/index.wxml new file mode 100644 index 0000000..a2e77e5 --- /dev/null +++ b/pages/htmls/auths/index.wxml @@ -0,0 +1,44 @@ + + + 云印通SaaS服务 + + + + + + + + + + + + + + + + + + + 长按屏幕扫一扫客服微信二维码 + 更多详情请联系客服020-8251 6486 + + + + + + + + + + + 联系客服 + + + + + + \ No newline at end of file diff --git a/pages/htmls/auths/index.wxss b/pages/htmls/auths/index.wxss new file mode 100644 index 0000000..93aa562 --- /dev/null +++ b/pages/htmls/auths/index.wxss @@ -0,0 +1,22 @@ +/* pages/htmls/saas/index.wxss */ +.image-load { + width: 750rpx; + height: 750rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.relative{ + height: 100%; + width: 100%; + position: relative; +} + +.container { + width: 100%; + flex-direction: column; + position: absolute; + left: 0rpx; + top: 0rpx; +} \ No newline at end of file diff --git a/pages/index/index.js b/pages/index/index.js new file mode 100644 index 0000000..52699f8 --- /dev/null +++ b/pages/index/index.js @@ -0,0 +1,210 @@ +// pages/administ/index.js +import Dialog from '../../components/dialog/dialog' +import { config, getUserInfo, verifyCode } from "../api/user" +// import { loginToken, cconfig } from "../api/cloud" +// import { mconfig } from "../api/mall" +import { pconfig } from "../api/payment" +const storage = require('../../utils/storage') +const event = require('../../utils/event') +const util = require('../../utils/util') +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + safeBottom: app.globalData.safeBottom, + fragment: app.globalData.safeFragmentHeight, + tabList: [ + { index: 0, value: 'mall', badge: 0, name: '商城', blue: '/assets/image/tabbar/mall-blue.png', gray: '/assets/image/tabbar/mall-gray.png' }, + { index: 1, value: 'work', badge: 0, name: '工作台', blue: '/assets/image/tabbar/process-blue.png', gray: '/assets/image/tabbar/process-gray.png' }, + { index: 2, value: 'home', badge: 0, name: '我的', blue: '/assets/image/tabbar/home-blue.png', gray: '/assets/image/tabbar/home-gray.png' } + ], + tabIndex: 0, + inited: false, + authorization: null, + code: null, + // code: '?mark=cloudprint&QrCodeRecordId=541755014083907584' + }, + /************************************** 初始化流程 ********************************************/ + onLoad: function (options) { + const updateManager = wx.getUpdateManager() + updateManager.onCheckForUpdate() + updateManager.onUpdateReady(function () { + // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 + updateManager.applyUpdate() + }) + if(options.q){ + //扫二维码进入的, + let q = decodeURIComponent(options.q) + this.data.code = q.substring(q.indexOf('?')) + } + event.on('EventMessage', this, this.onEvent) + }, + onReady: function () { + wx.showLoading({ title: '获取中', mask: true }) + wx.getSystemInfo({ + success: e => { + app.globalData.isIPhoneX = this.checkIPhoneX(e) + app.globalData.isIos = this.checkIos(e) + app.globalData.dev = e.platform == 'devtools' + + let custom = wx.getMenuButtonBoundingClientRect() + app.globalData.Custom = custom + // 顶部操作栏高度 + app.globalData.CustomBar = custom.bottom + custom.top - e.statusBarHeight + (app.globalData.isIos ? 4 : 0) + let windowHeight = e.windowHeight * (750 / e.windowWidth) + + let safeBottom = e.windowHeight - e.safeArea.bottom + if(safeBottom > e.windowHeight){ + safeBottom = 34 + } + app.globalData.safeBottom = safeBottom * (750 / e.windowWidth) + // 状态栏高度 + app.globalData.StatusBar = e.statusBarHeight * (750 / e.windowWidth) + let statusBarHeight = app.globalData.CustomBar * (750 / e.windowWidth) + app.globalData.statusBarHeight = statusBarHeight + // fragmentHeight:指的是整个页面statusBarHeight以下的高度 + app.globalData.fragmentHeight = windowHeight - statusBarHeight + app.globalData.safeFragmentHeight = windowHeight - statusBarHeight - app.globalData.safeBottom + app.globalData.windowWidth = e.windowWidth + + this.data.inited = true + const fheght = (app.globalData.safeFragmentHeight + app.globalData.statusBarHeight) - 100 + event.emit('InitMessage', { what: 8, desc: 'Inited' }) + this.setData({fragment: fheght, safeBottom: app.globalData.safeBottom, inited: true }) + this.data.authorization = app.globalData.token || storage.get('Authorization') + if(this.data.code){ + // 进入登录绑定页面 + this.fetchCode(this.data.code) + } else if(this.data.authorization){ + app.globalData.token = this.data.authorization + this.fetchUserInfo() + } else { + wx.hideLoading() + this.onResume() + } + } + }) + }, + checkIos: function (e) { + if ('ios' === e.platform) { + return true + } + if (e.system.startsWith('iOS')) { + return true + } + return false + }, + checkIPhoneX: function (e) { + var t = e.model + return (/iPhone 11/.test(t) || /iPhone X/.test(t) || /iPhone 12/.test(t)) && this.checkIos(e) + }, + /************************************** 登录流程 ********************************************/ + onEvent: function (message) { + if (message.what == 888) { + if(!app.accountInfo){ + this.setData({ tabIndex: 0 }) + } else if(app.accountInfo && app.accountInfo.applicationStatus == 0){ + this.setData({ tabIndex: 1 }) + } + } + }, + fetchUserInfo: function(){ + if(!app.globalData.token){ + wx.hideLoading() + this.onResume() + return + } + config.header = { 'Authorization': 'QNT ' + app.globalData.token } + getUserInfo().then(result => { + if (result.data.token) { + storage.put('Authorization', result.data.token) + app.globalData.token = result.data.token + } + app.accountInfo = result.data + loginToken({loginToken: app.globalData.token}).then(result => { + mconfig.header = { 'Authorization': 'QNT ' + result.data } + cconfig.header = { 'Authorization': 'QNT ' + result.data } + pconfig.header = { 'Authorization': 'QNT ' + result.data } + // 登录流程完成; + wx.hideLoading() + // 如果是员工,或者 + if(app.accountInfo && app.accountInfo.applicationStatus == 0){ + this.setData({ tabIndex: 1 }) + } + this.onResume() + // event.emit('EventMessage', { what: 888, desc: 'Logined' }) + }).catch(err => { + wx.hideLoading() + this.onResume() + }) + }).catch(err => { + wx.hideLoading() + this.onResume() + }) + }, + // 根据二维码的code获取相关的内容; + fetchCode: function(code){ + verifyCode(code).then(result => { + this.data.code = null + if(result.data.redirectUrl == '/login'){ + // 根据userId来获取用户信息;并且直接登录 + app.globalData.token = result.data.metaData.token + storage.put('Authorization', app.globalData.token) + this.fetchUserInfo() + } else if('/page/index/yaoqing' == result.data.redirectUrl || '/page/index/shenqing' == result.data.redirectUrl){ + storage.put('metaData', JSON.stringify(result.data), 1) + wx.hideLoading() + // 进入login页面; + wx.navigateTo({ url: '/pages/index/index?code=11' }) + } else { + wx.hideLoading() + if(!result.data.message){ + result.data.message = '二维码解析失败,请重新扫码' + } + util.showToast(result.data.message) + } + }).catch(err => { + //异常回调 + wx.hideLoading() + if(this.data.authorization){ + Dialog.alert({ title: '温馨提示', message: '二维码解析失败,以当前账号进行登录!' }).then(() => { + wx.showLoading({ title: '登录中', mask: true }) + app.globalData.token = this.data.authorization + this.fetchUserInfo() + }) + } else { + util.showToast(err) + this.onResume() + } + }) + }, + /************************************** 生命周期函数--监听页面初次渲染完成 ********************************************/ + onShow: function () { + if(this.data.inited){ + this.onResume() + } + }, + onResume: function(){ + var pageView = this.selectComponent('#' + this.data.tabList[this.data.tabIndex].value) + if (pageView && this.data.inited) { + pageView.onRestart() + } + }, + onChange: function ({detail}) { + if(detail == 2 && !app.accountInfo){ + wx.navigateTo({ url: '/pages/login/index' }) + return + } + this.setData({ tabIndex: detail }) + this.onResume() + }, + stopTouchMove: function(e){ + return false + }, + onUnload: function(){ + event.remove('EventMessage', this) + } +}) \ No newline at end of file diff --git a/pages/index/index.json b/pages/index/index.json new file mode 100644 index 0000000..176b038 --- /dev/null +++ b/pages/index/index.json @@ -0,0 +1,11 @@ +{ + "usingComponents": { + "van-icon": "/components/icon/index", + "van-tabbar": "/components/tabbar/index", + "van-tabbar-item": "/components/tabbar-item/index", + "mall": "/pages/mall/index/index", + "workbench": "/pages/process/index/index", + "home": "/pages/home/index/index", + "van-dialog": "/components/dialog/index" + } +} \ No newline at end of file diff --git a/pages/index/index.wxml b/pages/index/index.wxml new file mode 100644 index 0000000..f14268c --- /dev/null +++ b/pages/index/index.wxml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + {{item.name}} + + + + + \ No newline at end of file diff --git a/pages/index/index.wxss b/pages/index/index.wxss new file mode 100644 index 0000000..feead45 --- /dev/null +++ b/pages/index/index.wxss @@ -0,0 +1 @@ +/* pages/administ/index.wxss */ \ No newline at end of file diff --git a/pages/login/index.js b/pages/login/index.js new file mode 100644 index 0000000..01a637b --- /dev/null +++ b/pages/login/index.js @@ -0,0 +1,271 @@ +//获取应用实例 +import Dialog from '../../components/dialog/dialog' +import { config, wechatApplet, getUserInfo, loginWechat, authCaptcha, verifyCaptcha, bindingAdmin, bindingAccount } from "../api/user" +// import { loginToken, cconfig } from "../api/cloud" +// import { mconfig } from "../api/mall" +import { pconfig } from "../api/payment" +const util = require('../../utils/util') +const storage = require('../../utils/storage') +const event = require('../../utils/event') +const app = getApp() + +Page({ + data: { + type: 1, + mobileEnable: false, + codeEnable: true, + loginEnable: true, + second: '获取验证码', + form: { + accountType: 2, + tmpAuthToken: null, + account: null, + captcha: null + }, + loging: false, + regist: false, + qrPage: null, + metaData: null, + code: null, + checked: true, + height: app.globalData.fragmentHeight + }, + /************************************** 初始化登录流程 ********************************************/ + onLoad: function (options) { + var json = storage.get('metaData') + if(options.code && json){ + //分享带code进入的, + this.setData({ code: options.code, height: app.globalData.fragmentHeight }) + storage.remove('metaData') + var form = JSON.parse(json) + this.data.metaData = form.metaData + this.data.qrPage = form.redirectUrl + } else { + this.setData({ height: app.globalData.fragmentHeight }) + } + this.wxLogin() + }, + onEvent: function (message) { + if (message.what == 888) { + this.initAccountInfo() + } + }, + wxLogin: function(){ + wx.login({ + success: res => { + // 获取openId + wechatApplet({ authCode: res.code }).then(result => { + storage.put('tmpAuthToken', result.data.tmpAuthToken, 98) + }) + } + }) + }, + // 获取用户信息,进行登录 + fetchUserInfo: function(){ + config.header = { 'Authorization': 'QNT ' + app.globalData.token } + this.setData({ loging: true}) + getUserInfo().then(result => { + this.setData({ loging: false}) + if(!result.data.mobile){ + wx.hideLoading() + //小白用户;注册流程; + this.setData({ regist: true }) + return + } + if (result.data.token) { + storage.put('Authorization', result.data.token) + app.globalData.token = result.data.token + } + app.accountInfo = result.data + if(result.data.enterpriseId){ + // 企业不一致 + var invaild = false + if(this.data.metaData && this.data.metaData.enterpriseId){ + invaild = result.data.enterpriseId != this.data.metaData.enterpriseId + } else if(this.data.metaData && this.data.metaData.joiningEnterprisePublicInvitationId){ + invaild = result.data.enterpriseId != this.data.metaData.joiningEnterprisePublicInvitationId + } + if(invaild){ + wx.hideLoading() + Dialog.alert({ title: '温馨提示', message: '您已经绑定过企业,现在就进入?' }).then(() => { + this.toIndex() + }) + } else { + this.toIndex() + } + } else if(this.data.metaData){ + // 如果有metaData + wx.hideLoading() + this.setData({ metaData: this.data.metaData, qrPage: this.data.qrPage, regist: false, loging: false }) + } else { + //如果绑定过手机号码; + wx.hideLoading() + this.toIndex() + } + }).catch(err => { + //异常回调 + wx.hideLoading() + this.setData({ loging: false}) + }) + }, + toIndex: function(){ + loginToken({loginToken: app.globalData.token}).then(result => { + mconfig.header = { 'Authorization': 'QNT ' + result.data } + cconfig.header = { 'Authorization': 'QNT ' + result.data } + pconfig.header = { 'Authorization': 'QNT ' + result.data } + // 登录完成... + wx.hideLoading() + event.emit('EventMessage', { what: 888, desc: 'Logined' }) + wx.navigateBack() + }).catch(err => { + wx.hideLoading() + }) + }, + onBoxChange: function({detail}){ + this.setData({ checked: detail }) + }, + /************************************** 注册流程 ********************************************/ + readAgreement: function () { + wx.navigateTo({ url: '/pages/htmls/agreement/index' }) + }, + onGotUserInfo: function (e) { + if(!this.data.checked){ + util.showToast('请阅读并同意《服务与隐私协议》') + return + } + if(this.data.loging){ + return + } + this.setData({ loging: true }) + if(this.data.form.tmpAuthToken){ + this.registAccount() + return + } + loginWechat({ encryptedData: e.detail.encryptedData, iv: e.detail.iv }).then(result => { + storage.put('Authorization', result.data.token) + app.globalData.token = result.data.token + this.data.form.tmpAuthToken = result.data.tmpAuthToken + if(e.currentTarget.id == 'btn-login'){ + this.registAccount() + } else { + this.fetchUserInfo() + } + }).catch(error => { + if(error.data && error.data.tmpAuthToken){ + this.data.form.tmpAuthToken = error.data.tmpAuthToken + this.setData({ regist: true, loging: false }) + } else { + this.setData({ loging: false }) + } + util.showToast(error.message) + }) + }, + inputFocus: function(e) { + storage.put('keyboardHeight', e.detail.height) + }, + bindInput: function (e) { + this.data.form[e.target.id] = e.detail.value + if ('account' == e.target.id) { + if ((/^1\d{10}$/.test(e.detail.value)) && e.detail.value.length == 11) { + this.setData({ mobileEnable: true }) + } + } + if ((/^1\d{10}$/.test(this.data.form.account)) && this.data.form.account.length == 11) { + if (this.data.type == 1 && !util.isEmpty(this.data.form.captcha)) { + this.setData({ loginEnable: false }) + } else if (this.data.type == 0 && !util.isEmpty(this.data.form.password)) { + this.setData({ loginEnable: false }) + } else { + this.setData({ loginEnable: true }) + } + } else { + this.setData({ loginEnable: true }) + } + }, + onChange: function(e) { + if(e.detail.minutes != 0){ + return + } + this.setData({ second: e.detail.seconds + ' 秒 ' }) + }, + onFinished: function(){ + this.setData({ second: '重新获取验证码', codeEnable: true }) + }, + loginFrom: function(){ + this.setData({ regist: true }) + }, + fetchCaptcha: function(){ + if (!(/^1\d{10}$/.test(this.data.form.account)) || this.data.form.account.length < 11) { + util.showToast('请输入11位手机号码') + return + } + wx.showLoading({ title: '正在获取', mask: true }) + authCaptcha({ verifiableAccount: this.data.form.account, verifiableAccountType: 1, purpose: 1 }).then(result => { + wx.hideLoading() + this.setData({ codeEnable: false }) + util.showToast('验证码已经发送') + this.countDown = this.countDown || this.selectComponent('.count-down') + this.countDown.reset() + this.countDown.start() + }).catch(error => { + wx.hideLoading() + util.showToast(error) + }) + }, + registAccount: function(){ + if (!(/^1\d{10}$/.test(this.data.form.account)) || this.data.form.account.length < 11) { + util.showToast('请输入11位手机号码') + return + } + if (this.data.type == 1 && util.isEmpty(this.data.form.captcha)) { + util.showToast('请输入验证码') + return + } + if (this.data.type == 0 && util.isEmpty(this.data.form.password)) { + util.showToast('请输入密码') + return + } + wx.showLoading({ title: '登录中', mask: true }) + this.setData({ loging: true }) + // this.data.form.password = md5.hexMD5(this.data.form.password).toUpperCase() + if (this.data.type == 1) { + verifyCaptcha(this.data.form).then(result => { + wx.setStorageSync('Authorization', result.data.token) + app.globalData.token = result.data.token + this.fetchUserInfo() + }).catch(error => { + wx.hideLoading() + this.setData({ loging: false }) + util.showToast(error) + }) + } else { + // authorize/by-password 密码登录 + } + }, + /************************************** 二维码流程 ********************************************/ + bindAccount: function(){ + if (util.isEmpty(this.data.form.userName)) { + util.showToast('请输入您的姓名,以便于识别') + return + } + this.setData({ loging: true }) + this.data.metaData.userName = this.data.form.userName + if(this.data.qrPage == '/page/index/yaoqing'){ + bindingAdmin(this.data.metaData).then(result => { + this.data.metaData = null + this.fetchUserInfo() + }).catch(error => { + this.setData({loging: false}) + util.showToast(error) + }) + } else { + bindingAccount(this.data.metaData).then(result => { + this.data.metaData = null + this.fetchUserInfo() + }).catch(error => { + this.setData({loging: false}) + util.showToast(error) + }) + } + } +}) \ No newline at end of file diff --git a/pages/login/index.json b/pages/login/index.json new file mode 100644 index 0000000..db02766 --- /dev/null +++ b/pages/login/index.json @@ -0,0 +1,8 @@ +{ + "usingComponents": { + "van-button": "/components/button/index", + "van-dialog": "/components/dialog/index", + "van-count-down": "/components/count-down/index", + "van-checkbox": "/components/checkbox/index" + } +} \ No newline at end of file diff --git a/pages/login/index.wxml b/pages/login/index.wxml new file mode 100644 index 0000000..fc5a6ca --- /dev/null +++ b/pages/login/index.wxml @@ -0,0 +1,94 @@ + + + 登录 + + + + + + + + + 欢迎您使用千鸟跟单王! + + 现邀请您成为{{metaData.name}}的管理员 + + + 现邀请您成为{{metaData.name}}的员工 + + + + + + 提交 + + + + + + + 手机号码 + + + + + + + {{type == 1 ? '验证码' : '密码'}} + + + + + + + {{second}} + + + + + + + + + 登录 + + + + + + + + + + 千鸟互联云印通 + 专注服务于印刷包装企业 + + + + 微信用户一键登录 + + + 手机验证码登录 + + + + 登录即同意 + + 《服务与隐私协议》 + + + + + + + \ No newline at end of file diff --git a/pages/login/index.wxss b/pages/login/index.wxss new file mode 100644 index 0000000..e83520a --- /dev/null +++ b/pages/login/index.wxss @@ -0,0 +1,24 @@ +/* pages/login/index.wxss */ +page { + background-color: #fff; +} + +.relative{ + height: 100%; + width: 100%; + position:relative; +} + +.container { + width: 100%; + flex-direction: column; + position: fixed; + bottom: 64rpx; +} + +.label { + font-size: 30rpx; + font-family: PingFang-SC-Regular, PingFang-SC; + font-weight: 400; + color: rgba(83, 83, 83, 1); +} \ No newline at end of file diff --git a/pages/mall/components/cell/index.js b/pages/mall/components/cell/index.js new file mode 100644 index 0000000..e5d500e --- /dev/null +++ b/pages/mall/components/cell/index.js @@ -0,0 +1,23 @@ +// pages/mall/components/sku.js +Component({ + /** + * 组件的属性列表 + */ + properties: { + + }, + + /** + * 组件的初始数据 + */ + data: { + + }, + + /** + * 组件的方法列表 + */ + methods: { + + } +}) diff --git a/pages/mall/components/cell/index.json b/pages/mall/components/cell/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/pages/mall/components/cell/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/mall/components/cell/index.wxml b/pages/mall/components/cell/index.wxml new file mode 100644 index 0000000..8a7f9b8 --- /dev/null +++ b/pages/mall/components/cell/index.wxml @@ -0,0 +1,2 @@ + +pages/mall/components/sku.wxml diff --git a/pages/mall/components/cell/index.wxss b/pages/mall/components/cell/index.wxss new file mode 100644 index 0000000..8562a32 --- /dev/null +++ b/pages/mall/components/cell/index.wxss @@ -0,0 +1 @@ +/* pages/mall/components/sku.wxss */ \ No newline at end of file diff --git a/pages/mall/components/fence/index.js b/pages/mall/components/fence/index.js new file mode 100644 index 0000000..e5d500e --- /dev/null +++ b/pages/mall/components/fence/index.js @@ -0,0 +1,23 @@ +// pages/mall/components/sku.js +Component({ + /** + * 组件的属性列表 + */ + properties: { + + }, + + /** + * 组件的初始数据 + */ + data: { + + }, + + /** + * 组件的方法列表 + */ + methods: { + + } +}) diff --git a/pages/mall/components/fence/index.json b/pages/mall/components/fence/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/pages/mall/components/fence/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/mall/components/fence/index.wxml b/pages/mall/components/fence/index.wxml new file mode 100644 index 0000000..8a7f9b8 --- /dev/null +++ b/pages/mall/components/fence/index.wxml @@ -0,0 +1,2 @@ + +pages/mall/components/sku.wxml diff --git a/pages/mall/components/fence/index.wxss b/pages/mall/components/fence/index.wxss new file mode 100644 index 0000000..8562a32 --- /dev/null +++ b/pages/mall/components/fence/index.wxss @@ -0,0 +1 @@ +/* pages/mall/components/sku.wxss */ \ No newline at end of file diff --git a/pages/mall/components/sku/index.js b/pages/mall/components/sku/index.js new file mode 100644 index 0000000..e5d500e --- /dev/null +++ b/pages/mall/components/sku/index.js @@ -0,0 +1,23 @@ +// pages/mall/components/sku.js +Component({ + /** + * 组件的属性列表 + */ + properties: { + + }, + + /** + * 组件的初始数据 + */ + data: { + + }, + + /** + * 组件的方法列表 + */ + methods: { + + } +}) diff --git a/pages/mall/components/sku/index.json b/pages/mall/components/sku/index.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/pages/mall/components/sku/index.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/mall/components/sku/index.wxml b/pages/mall/components/sku/index.wxml new file mode 100644 index 0000000..8a7f9b8 --- /dev/null +++ b/pages/mall/components/sku/index.wxml @@ -0,0 +1,2 @@ + +pages/mall/components/sku.wxml diff --git a/pages/mall/components/sku/index.wxss b/pages/mall/components/sku/index.wxss new file mode 100644 index 0000000..8562a32 --- /dev/null +++ b/pages/mall/components/sku/index.wxss @@ -0,0 +1 @@ +/* pages/mall/components/sku.wxss */ \ No newline at end of file diff --git a/pages/mall/index.wxs b/pages/mall/index.wxs new file mode 100644 index 0000000..89eca6e --- /dev/null +++ b/pages/mall/index.wxs @@ -0,0 +1,106 @@ +function formatePrice(price) { + return Number(price).toFixed(2) +} + +function formateNumber(price, fixed) { + if(price == null || price == undefined){ + price = 0 + } + return Number(price).toFixed(fixed) +} + +function isEmpty(val) { + return typeof val === 'undefined' || val === '' || val === null +} + +function formateDate(datetime) { + if (isEmpty(datetime)) { + return '' + } + var date = getDate(datetime.trim()) + var today = getDate() + var dayCode = 24 * 60 * 60 * 1000 + var week = '' + if (date.getTime() === today.getTime()) { + week = '(今天)' + } else if (date.getTime() === today.getTime() + dayCode) { + week = '(明天)' + } else if (date.getTime() === today.getTime() - dayCode) { + week = '(昨天)' + } else if (date.getTime() === today.getTime() + dayCode * 2) { + week = '(后天)' + } else { + week = ['(周日)', '(周一)', '(周二)', '(周三)', '(周四)', '(周五)', '(周六)'][date.getDay()] + } + if (isEmpty(week)) { + week = '' + } + return datetime + week +} + +function formateText(text, length) { + if (!text) { + return '' + } + if (text.length <= length) { + return text + } + return text.substring(0, length) + '...' +} + +function isVideoUrl(url){ + if(url && url.indexOf('.mp4') >= 0){ + return true + } + return false +} + +function minNumber(order, num){ + if(order && parseInt(order.minBuyNum) > 0){ + return Number(order.minBuyNum) + } + return num +} + +function getOrderInfo(item) { + var attributes = '' + for (var i = 0; i < item.attributesJSONArray.length; i++) { + var element = item.attributesJSONArray[i] + if(i == 0){ + attributes = element.arriName + ':' + element.arriVal + } else { + attributes += ';' + element.arriName + ':' + element.arriVal + } + } + return attributes +} + +function orderStatus(status){ + if(status == 1 || status == 2){ + return '取消订单' + } else if(status == 3){ + return '确认收货' + } + return '' +} + +function submitPrice(price){ + return Number(price) * 100 +} + +function formateAmount(amount) { + return Number(amount).toFixed(2) +} + +module.exports = { + formatePrice: formatePrice, + formateDate: formateDate, + formateText: formateText, + isVideoUrl: isVideoUrl, + minNumber: minNumber, + orderStatus: orderStatus, + getOrderInfo: getOrderInfo, + submitPrice: submitPrice, + formateAmount: formateAmount, + formateNumber: formateNumber +} \ No newline at end of file diff --git a/pages/mall/index/index.js b/pages/mall/index/index.js new file mode 100644 index 0000000..748045f --- /dev/null +++ b/pages/mall/index/index.js @@ -0,0 +1,126 @@ +// pages/process/supply/index.js +// import { getCategoryList, getProductList } from "../../api/mall" +const event = require('../../../utils/event') +const util = require('../../../utils/util') +const app = getApp() + +Component({ + options: { + addGlobalClass: true, + multipleSlots: true + }, + /** + * 页面的初始数据 + */ + data: { + height: app.globalData.safeFragmentHeight - 190, + CustomBar: app.globalData.CustomBar, + userInfo: null, + firstShow: false, + tabIndex: 0, + tabList: [], + loading: true, + requesting: false, + finished: false, + top: 0, + orderList: [], + form: { categoryId: '', pageNum: 1, pageSize: 10 } + }, + lifetimes: { + // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 + attached: function () { + event.on('EventMessage', this, this.onEvent) + }, + detached: function () { + event.remove('EventMessage', this) + } + }, + methods: { + onRestart: function () { + if (this.data.firstShow) { + return + } + this.setData({ height: app.globalData.safeFragmentHeight - 190, CustomBar: app.globalData.CustomBar, userInfo: app.accountInfo }) + this.fetchCategoryList() + this.fetchOrderList() + this.data.firstShow = true + }, + onEvent: function (message) { + if (message.what == 888) { + this.setData({ userInfo: app.accountInfo }) + } + }, + fetchCategoryList: function(){ + getCategoryList().then(result => { + this.setData({ tabList: [{id: '', name: '全部'}].concat(result.data) }) + }) + }, + onTabChange: function ({detail}) { + if (this.data.tabIndex == Number(detail.index)) { + return + } + this.setData({ tabIndex: detail.index}) + this.data.form.categoryId = this.data.tabList[this.data.tabIndex].id + this.onRefreshList() + }, + onRefreshList: function () { + this.setData({ + orderList: [], + ['form.pageNum']: 1, + loading: true, + finished: false + }) + this.fetchOrderList() + }, + fetchOrderList: function () { + if (this.data.requesting || this.data.finished) { + return + } + if (this.data.loading) { + this.data.requesting = true + } else { + this.setData({ requesting: true }) + } + getProductList(this.data.form).then(result => { + //成功回调 + if (result.data.records.length) { + var respList = result.data.records + let nowList = `orderList[${this.data.orderList.length}]` + var num = this.data.form.pageNum + var finished = ((num - 1) * this.data.form.pageSize + respList.length) >= result.data.total + if(this.data.form.pageNum == 1){ + this.setData({ + [nowList]: respList, + ['form.pageNum']: (num + 1), + top: 0, + finished, + requesting: false, + loading: false + }) + } else { + this.setData({ + [nowList]: respList, + ['form.pageNum']: (num + 1), + finished, + requesting: false, + loading: false + }) + } + } else { + this.setData({ finished: true, requesting: false, loading: false }) + } + }).catch(err => { + //异常回调 + this.setData({ requesting: false, loading: false }) + util.showToast(err) + }) + }, + lookItem: function (e) { + var item = this.data.orderList[e.currentTarget.dataset.page][e.currentTarget.dataset.index] + wx.navigateTo({ url: '/pages/process/purchase-detail/index?id=' + item.id }) + }, + searchList: function(){ + wx.navigateTo({ url: '/pages/mall/search-list/index' }) + } + } +}) \ No newline at end of file diff --git a/pages/mall/index/index.json b/pages/mall/index/index.json new file mode 100644 index 0000000..81c56b8 --- /dev/null +++ b/pages/mall/index/index.json @@ -0,0 +1,14 @@ +{ + "component": true, + "usingComponents": { + "van-search": "/components/search/index", + "refresh-view": "/components/refresher/index", + "van-tabs": "/components/tabs/index", + "van-tab": "/components/tab/index", + "van-divider": "/components/divider/index", + "van-loading": "/components/loading/index", + "skeleton": "/components/skeleton/index", + "skeleton-avatar": "/components/skeleton-avatar/index", + "skeleton-paragraph": "/components/skeleton-paragraph/index" + } +} \ No newline at end of file diff --git a/pages/mall/index/index.wxml b/pages/mall/index/index.wxml new file mode 100644 index 0000000..450178f --- /dev/null +++ b/pages/mall/index/index.wxml @@ -0,0 +1,40 @@ + + + {{userInfo.enterpriseName}} + 原纸商场 + + + + + + + + + + + + + + + + + + + + + {{loading? '正在加载' : '暂无数据'}} + + + + + + + + + + + + {{finished?'到底啦~':'加载中...'}} + + + diff --git a/pages/mall/index/index.wxss b/pages/mall/index/index.wxss new file mode 100644 index 0000000..13a97eb --- /dev/null +++ b/pages/mall/index/index.wxss @@ -0,0 +1,4 @@ +/* pages/mall/index/index.wxss */ +.margin-l{ + margin-left: 32rpx; +} \ No newline at end of file diff --git a/pages/mall/search-list/index.js b/pages/mall/search-list/index.js new file mode 100644 index 0000000..7f2653d --- /dev/null +++ b/pages/mall/search-list/index.js @@ -0,0 +1,136 @@ +// pages/mall/search-list/index.js +const util = require('../../../utils/util') +const app = getApp() + +Page({ + /** + * 页面的初始数据 + */ + data: { + height: app.globalData.fragmentHeight - 100, + loading: false, + finished: false, + requesting: false, + top: 0, + rearchStringList: [], + taskList: [], + form: { + name: '', + pageSize: 10, + pageNum: 1 + }, + focus: true + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.setData({ height: app.globalData.fragmentHeight - 100, CustomBar: app.globalData.CustomBar }) + var that = this + wx.getStorage({ key: 'mall-search', success (res) { + that.setData({ rearchStringList: res.data.split(',') }) + } + }) + }, + onChange(e) { + this.setData({ ['form.name']: e.detail }) + }, + /** + * 生命周期函数--监听页面显示 + */ + onSearch: function (e) { + if(util.isEmpty(this.data.form.name)){ + util.showToast('请输入要搜索的关键字') + return + } + this.setData({ taskList: [], ['form.pageNum']: 1, finished: false }) + this.fetchTaskList() + }, + fetchTaskList: function () { + if (this.data.requesting || this.data.finished) { + return + } + if (this.data.form.pageNum == 1 && this.data.taskList.length == 0) { + this.setData({ loading: true }) + } + this.data.requesting = true + // /product/list产品列表 + searchProductList(this.data.form).then(result => { + //成功回调 + this.data.requesting = false + if(this.data.form.pageNum == 1){ + this.setData({ focus: false, top: 0 }) + } else { + this.setData({ focus: false }) + } + if (result.data.records.length) { + var respList = result.data.records + let nowList = `taskList[${this.data.taskList.length}]` + var num = this.data.form.pageNum + var finished = ((num - 1) * this.data.form.pageSize + respList.length) >= result.data.total + var strList = this.data.rearchStringList + if(!util.isEmpty(this.data.form.name) && strList.indexOf(this.data.form.name) < 0){ + strList.splice(0, 0, this.data.form.name) + } + this.setData({ + rearchStringList: strList, + [nowList]: respList, + ['form.pageNum']: (num + 1), + finished, + loading: false + }) + } else { + var strList = this.data.rearchStringList + if(!util.isEmpty(this.data.form.name) && strList.indexOf(this.data.form.name) < 0){ + strList.splice(0, 0, this.data.form.name) + } + this.setData({ + rearchStringList: strList, + focus: false, + finished: true, + loading: false + }) + } + // wx.hideLoading() + }).catch(err => { + //异常回调 + // wx.hideLoading() + this.setData({ loading: false }) + this.data.requesting = false + var strList = this.data.rearchStringList + if(strList.indexOf(this.data.form.name) < 0){ + strList.splice(0, 0, this.data.form.name) + } + this.setData({ + rearchStringList: strList, + focus: false + }) + util.showToast(err) + }); + }, + clearHistory: function (e) { + var that = this + wx.removeStorage({ + key: 'mall-search', + success (res) { + that.setData({ + rearchStringList: [] + }) + } + }) + }, + tagClick: function(e){ + this.setData({ ['form.name']: this.data.rearchStringList[e.currentTarget.dataset.index] }) + this.onSearch(null) + }, + onUnload() { + if(this.data.rearchStringList.length){ + try { + wx.setStorageSync('mall-search', this.data.rearchStringList.toString()) + } catch (e) { + + } + } + } + +}) \ No newline at end of file diff --git a/pages/mall/search-list/index.json b/pages/mall/search-list/index.json new file mode 100644 index 0000000..59bc8c4 --- /dev/null +++ b/pages/mall/search-list/index.json @@ -0,0 +1,7 @@ +{ + "usingComponents": { + "van-search": "/components/search/index", + "van-divider": "/components/divider/index", + "van-loading": "/components/loading/index" + } +} \ No newline at end of file diff --git a/pages/mall/search-list/index.wxml b/pages/mall/search-list/index.wxml new file mode 100644 index 0000000..59d5fe0 --- /dev/null +++ b/pages/mall/search-list/index.wxml @@ -0,0 +1,41 @@ + + + 原纸商城 + + + + 搜索 + + + + + 搜索历史 + + + + + {{item}} + + + + + + 加载中... + + + + 暂无数据 + + + + + + + + + + + + {{finished?'到底啦~':'加载中...'}} + + \ No newline at end of file diff --git a/pages/mall/search-list/index.wxss b/pages/mall/search-list/index.wxss new file mode 100644 index 0000000..188f7a3 --- /dev/null +++ b/pages/mall/search-list/index.wxss @@ -0,0 +1 @@ +/* pages/mall/search-list/index.wxss */ \ No newline at end of file diff --git a/pages/message/detail/index.js b/pages/message/detail/index.js new file mode 100644 index 0000000..41bf9dd --- /dev/null +++ b/pages/message/detail/index.js @@ -0,0 +1,16 @@ +// pages/message/detail/index.js +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + + } +}) \ No newline at end of file diff --git a/pages/message/detail/index.json b/pages/message/detail/index.json new file mode 100644 index 0000000..8835af0 --- /dev/null +++ b/pages/message/detail/index.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/message/detail/index.wxml b/pages/message/detail/index.wxml new file mode 100644 index 0000000..d86696b --- /dev/null +++ b/pages/message/detail/index.wxml @@ -0,0 +1,2 @@ + +pages/message/detail/index.wxml diff --git a/pages/message/detail/index.wxss b/pages/message/detail/index.wxss new file mode 100644 index 0000000..f42776e --- /dev/null +++ b/pages/message/detail/index.wxss @@ -0,0 +1 @@ +/* pages/message/detail/index.wxss */ \ No newline at end of file diff --git a/pages/message/index/index.js b/pages/message/index/index.js new file mode 100644 index 0000000..71e5813 --- /dev/null +++ b/pages/message/index/index.js @@ -0,0 +1,190 @@ +// pages/bidding/index/index.js +const util = require('../../../utils/util') +const event = require('../../../utils/event.js') +const app = getApp() +const urlList = ['/message-center/message/get/message-list', '/message-center/message/get/notification-list'] + +Page({ + /** + * 页面的初始数据 + */ + data: { + height: app.globalData.fragmentHeight, + loading: true, + requesting: false, + finished: false, + tabList: [ + {id: 0, name: '订单', badge: 12}, + {id: 1, name: '系统', badge: 0} + ], + tabIndex: 0, + top: 0, + messageList: [], + form: { + pageNum: 1 + } + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.setData({ + height: app.globalData.fragmentHeight - 90, + CustomBar: app.globalData.CustomBar + }) + event.on('EventMessage', this, this.onEvent) + // this.fetchMessageNumber() + // this.fetchMessageList() + }, + onEvent: function (message) { + if (message.what == 320) { + this.onRefreshList() + } + }, + onRefreshList: function () { + this.setData({ + messageList: [], + tabIndex: this.data.tabIndex, + ['form.pageNum']: 1, + loading: true, + finished: false + }) + this.fetchMessageNumber() + this.fetchMessageList() + }, + fetchMessageNumber: function () { + // request.get('/message-center/message/get/unread-number').then(result => { + // this.setData({ ['tabList[0].badge']: result.data.messageNumber, ['tabList[1].badge']: result.data.notificationNumber }) + // }) + }, + fetchMessageList: function () { + if (this.data.requesting || this.data.finished) { + return + } + if (this.data.loading) { + this.data.requesting = true + } else { + this.setData({ requesting: true }) + } + // /product/cheapList特价产品列表 + request.get(urlList[this.data.tabIndex], this.data.form).then(result => { + //成功回调 + if (result.data.records.length) { + var respList = result.data.records + let nowList = `messageList[${this.data.messageList.length}]` + var num = this.data.form.pageNum + var finished = this.data.form.pageNum >= result.data.pages + if(this.data.form.pageNum == 1){ + this.setData({ + [nowList]: respList, + total: result.data.total, + ['form.pageNum']: (num + 1), + top: 0, + finished, + requesting: false, + loading: false + }) + } else { + this.setData({ + [nowList]: respList, + total: result.data.total, + ['form.pageNum']: (num + 1), + finished, + requesting: false, + loading: false + }) + } + } else { + this.setData({ + finished: true, + requesting: false, + loading: false + }) + } + }).catch(err => { + //异常回调 + this.setData({ + requesting: false, + loading: false + }) + util.showToast(err) + }) + }, + lookItem: function (e) { + var item = this.data.messageList[e.currentTarget.dataset.page][e.currentTarget.dataset.index] + if(item.status == 0){ + request.post('/message-center/message/read', { idList: [item.id] }).then(result => { + //成功回调 + this.setData({ + ['tabList[' + this.data.tabIndex + '].badge']: this.data.tabList[this.data.tabIndex].badge - 1, + ['messageList[' + e.currentTarget.dataset.page + '][' + e.currentTarget.dataset.index + '].status']: 1 + }) + this.redirectInfo(item.redirectInfo) + }) + } else { + this.redirectInfo(item.redirectInfo) + } + }, + redirectInfo: function(redirect){ + if(!redirect){ + return + } + if(redirect.targetView == 'biddingDetail'){ + // 买家竞价的详情页 + wx.navigateTo({ + url: '/pages/bidding/detail/index?id=' + redirect.params.id + }) + } else if(redirect.targetView == 'buyerOrderDetail'){ + // 买家订单的详情页 + wx.navigateTo({ + url: '/pages/morder/detail/index?orderId=' + redirect.params.id + }) + } else if(redirect.targetView == 'sellerOrderDetail'){ + // 卖家订单的详情页 sellerOrderDetail + wx.navigateTo({ + url: '/pages/morder/detail/index?type=1&orderId=' + redirect.params.id + }) + } else if(redirect.targetView == 'storeIndex'){ + // 店铺首页 storeIndex + wx.navigateTo({ + url: '/pages/shop/detail/index?storeId=' + redirect.params.id + }) + } else if(redirect.targetView == 'personalBillDetail'){ + // 账单详情页 personalBillDetail + wx.navigateTo({ + url: '/pages/bank/bill-detail/index?id=' + redirect.params.id + }) + } else if(redirect.targetView == 'member'){ + // 会员页 member + wx.navigateTo({ + url: '/pages/ztbvip/index' + }) + } else { + wx.navigateTo({ + url: '/pages/message/detail/index?id=' + redirect.params.id + }) + } + }, + onTabChange: function (e) { + if (this.data.tabIndex == Number(e.detail.index)) { + return + } + this.data.tabIndex = Number(e.detail.index) + this.onRefreshList() + }, + readMessage: function(){ + wx.showLoading({ title: '加载中', mask: true }) + request.post('/message-center/message/read').then(result => { + //成功回调 + this.setData({ ['tabList[0].badge']: 0, ['tabList[1].badge']: 0 }) + wx.hideLoading() + }).catch(err => { + //异常回调 + wx.hideLoading() + util.showToast(err) + }) + }, + onUnload: function(){ + event.remove('EventMessage', this) + } +}) \ No newline at end of file diff --git a/pages/message/index/index.json b/pages/message/index/index.json new file mode 100644 index 0000000..fc99fda --- /dev/null +++ b/pages/message/index/index.json @@ -0,0 +1,12 @@ +{ + "usingComponents": { + "refresh-view": "/components/refresher/index", + "van-tabs": "/components/tabs/index", + "van-tab": "/components/tab/index", + "van-button": "/components/button/index", + "van-cell": "/components/cell/index", + "van-info": "/components/info/index", + "van-divider": "/components/divider/index", + "van-loading": "/components/loading/index" + } +} \ No newline at end of file diff --git a/pages/message/index/index.wxml b/pages/message/index/index.wxml new file mode 100644 index 0000000..70fbbb3 --- /dev/null +++ b/pages/message/index/index.wxml @@ -0,0 +1,77 @@ + + + 消息 + + + + + + + + + 全部标识已读 + + + + + + + + + + + {{loading? '正在加载' : '暂无数据'}} + + + + + + + + [{{item.categoryName}}] + {{util.formateDate(item.createTime)}} + + {{item.content}} + + + + + + + + {{finished?'到底啦~':'加载中...'}} + + + + + + function isEmpty(val) { + return typeof val === 'undefined' || val === '' || val === null + } + function formateDate(datetime) { + if (isEmpty(datetime)) { + return '' + } + var dayCode = 24 * 60 * 60 * 1000 + datetime = datetime.replace(getRegExp('/\s/g', 'g'), '') + var date = getDate(datetime.trim()) + var today = getDate() + var yestoday = getDate(getDate().getTime() - dayCode) + var week = '' + if (date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === + today.getDate()) { + week = '今天 ' + datetime.substring(10) + } else if (date.getFullYear() === yestoday.getFullYear() && date.getMonth() === yestoday.getMonth() && date.getDate() + === yestoday.getDate()) { + week = '昨天 ' + datetime.substring(10) + } + if (isEmpty(week)) { + return datetime + } + return week + } + module.exports = { + formateDate: formateDate + } + \ No newline at end of file diff --git a/pages/message/index/index.wxss b/pages/message/index/index.wxss new file mode 100644 index 0000000..867151b --- /dev/null +++ b/pages/message/index/index.wxss @@ -0,0 +1,8 @@ +/* pages/message/index/index.wxss */ +.tab__badge { + width: 100rpx; + height: 80rpx; + line-height: 80rpx; + text-align: center; + font-size: 30rpx; +} \ No newline at end of file diff --git a/pages/process/index.wxs b/pages/process/index.wxs new file mode 100644 index 0000000..7d865fd --- /dev/null +++ b/pages/process/index.wxs @@ -0,0 +1,66 @@ +function itemStatus(status) { + if(status == -1){ + return '待设计工序' + } else if(status == 0){ + return '生产中' + } else if(status == 1){ + return '待生产' + } else if(status == 3){ + return '已完成' + } else if(status == 4){ + return '待分配' + } + return '' +} + +// 已完成:3;已发货:5;生成中:0 +function orderStatus(status, type) { + if(status == -1){ + return '待提交' + } else if(status == 0 || status == 4){ + if(type == 1){ + return '采购中' + } else { + return '进行中' + } + } else if(status == 3){ + return '已完成' + } else if(status == 5){ + return '' + } else if(status == 6){ + return '已终止' + } + return '' +} + +// 生产单状态:待生产:1;已完成:3;生产中:0;已终止:6 +function prodStatus(status) { + if(status == 1){ + return '待生产' + } else if(status == 0){ + return '生产中' + } else if(status == 3){ + return '已完成' + } else if(status == 6){ + return '已终止' + } + return '' +} + +function orderType(type) { + if(type == 0){ + return '加工件' + } else if(type == 1){ + return '物料' + } else if(type == 2){ + return '成品' + } + return '' +} + +module.exports = { + itemStatus: itemStatus, + orderStatus: orderStatus, + prodStatus: prodStatus, + orderType: orderType +} \ No newline at end of file diff --git a/pages/process/index/index.js b/pages/process/index/index.js new file mode 100644 index 0000000..6dedb6c --- /dev/null +++ b/pages/process/index/index.js @@ -0,0 +1,99 @@ +// pages/index/index.js +import { getUserInfo } from "../../api/user" +const event = require('../../../utils/event') +const app = getApp() + +Component({ + options: { + addGlobalClass: true, + multipleSlots: true + }, + /** + * 页面的初始数据 + */ + data: { + userInfo: app.accountInfo, + height: app.globalData.fragmentHeight - 100, + tabIndex: 0, + tabList: [ + {id: 0, name: '供货单', badge: 0, value: 'supply' }, + {id: 1, name: '采购单', badge: 0, value: 'purchase'}, + {id: 2, name: '生产单', badge: 0, value: 'production' } + ], + loading: true + }, + lifetimes: { + // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 + attached: function () { + event.on('EventMessage', this, this.onEvent) + }, + detached: function () { + event.remove('EventMessage', this) + } + }, + methods: { + onRestart: function () { + if(this.data.loading){ + this.initAccountInfo() + } + var fragment = this.selectComponent('#' + this.data.tabList[this.data.tabIndex].value) + if (fragment) { + fragment.onRestart() + } + }, + onEvent: function (message) { + if (message.what == 888) { + this.initAccountInfo() + } + }, + initAccountInfo: function(){ + if(app.accountInfo && app.accountInfo.position == 'ORDINARY'){ + this.setData({ + loading: false, + userInfo: app.accountInfo, height: app.globalData.safeFragmentHeight - 100, + tabList: [ + {id: 0, name: '生产中', badge: 0, value: 'supply', status: 0 }, + {id: 1, name: '待生产', badge: 0, value: 'purchase', status: 1 }, + {id: 2, name: '已完成', badge: 0, value: 'production', status: 3 }, + {id: 3, name: '已终止', badge: 0, value: 'termination', status: 6 } + ] + }) + } else { + this.setData({ loading: false, userInfo: app.accountInfo, height: app.globalData.safeFragmentHeight - 100 }) + } + // 您的申请正在处理,请等待,轮询去查询userInfo + if(app.accountInfo && app.accountInfo.applicationStatus == 0){ + this.fetchUserInfo() + } + }, + onTabChange: function (event) { + if (this.data.tabIndex == Number(event.detail.index)) { + return + } + this.setData({ tabIndex: event.detail.index}) + var fragment = this.selectComponent('#' + this.data.tabList[this.data.tabIndex].value) + if (fragment) { + fragment.onRestart() + } + }, + fetchUserInfo: function(){ + getUserInfo().then(result => { + app.accountInfo = result.data + if(result.data.enterpriseId && result.data.applicationStatus == 1){ + this.initAccountInfo() + } else { + var that = this + setTimeout(function () { that.fetchUserInfo() }, 3000) + } + }).catch(err => { + console.log(err) + }) + }, + loginFrom: function(){ + wx.navigateTo({ url: '/pages/index/index' }) + }, + applyFrom: function(){ + wx.navigateTo({ url: '/pages/htmls/saas/index' }) + } + } +}) \ No newline at end of file diff --git a/pages/process/index/index.json b/pages/process/index/index.json new file mode 100644 index 0000000..1269718 --- /dev/null +++ b/pages/process/index/index.json @@ -0,0 +1,9 @@ +{ + "component": true, + "usingComponents": { + "van-tabs": "/components/tabs/index", + "van-tab": "/components/tab/index", + "van-loading": "/components/loading/index", + "van-button": "/components/button/index" + } +} \ No newline at end of file diff --git a/pages/process/index/index.wxml b/pages/process/index/index.wxml new file mode 100644 index 0000000..143c2c8 --- /dev/null +++ b/pages/process/index/index.wxml @@ -0,0 +1,48 @@ + + + 工作台 + + + + + 正在加载 + + + + + + + + + + + + + + + + + + + + + + + 您的申请还在审核中,如有疑问请联系管理员。 + + + + + 您还没有入驻云印通 + + 现在去申请 + + + + + + 您还没有云印通账号 + + 现在去登录 + + \ No newline at end of file diff --git a/pages/process/index/index.wxss b/pages/process/index/index.wxss new file mode 100644 index 0000000..1bb28ac --- /dev/null +++ b/pages/process/index/index.wxss @@ -0,0 +1,4 @@ +/* pages/index/index.wxss */ +.menu:active { + opacity: .5 +} \ No newline at end of file diff --git a/project.config.json b/project.config.json new file mode 100644 index 0000000..abc836e --- /dev/null +++ b/project.config.json @@ -0,0 +1,74 @@ +{ + "description": "项目配置文件", + "packOptions": { + "ignore": [] + }, + "setting": { + "urlCheck": false, + "es6": true, + "enhance": false, + "postcss": true, + "preloadBackgroundData": false, + "minified": true, + "newFeature": false, + "coverView": true, + "nodeModules": false, + "autoAudits": false, + "showShadowRootInWxmlPanel": true, + "scopeDataCheck": false, + "uglifyFileName": false, + "checkInvalidKey": true, + "checkSiteMap": true, + "uploadWithSourceMap": true, + "compileHotReLoad": false, + "useMultiFrameRuntime": true, + "useApiHook": true, + "babelSetting": { + "ignore": [], + "disablePlugins": [], + "outputPath": "" + }, + "enableEngineNative": false, + "bundle": false, + "useIsolateContext": true, + "useCompilerModule": true, + "userConfirmedUseCompilerModuleSwitch": false, + "userConfirmedBundleSwitch": false, + "packNpmManually": false, + "packNpmRelationList": [], + "minifyWXSS": true, + "useApiHostProcess": false + }, + "compileType": "miniprogram", + "libVersion": "2.14.0", + "appid": "wx0e4e0fc5432db6d8", + "projectname": "ztb-saas-mini", + "debugOptions": { + "hidedInDevtools": [] + }, + "scripts": {}, + "isGameTourist": false, + "simulatorType": "wechat", + "simulatorPluginLibVersion": {}, + "condition": { + "plugin": { + "list": [] + }, + "game": { + "list": [] + }, + "gamePlugin": { + "list": [] + }, + "miniprogram": { + "list": [ + { + "name": "启动模式", + "pathName": "pages/login/index", + "query": "", + "scene": null + } + ] + } + } +} \ No newline at end of file diff --git a/sitemap.json b/sitemap.json new file mode 100644 index 0000000..ca02add --- /dev/null +++ b/sitemap.json @@ -0,0 +1,7 @@ +{ + "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", + "rules": [{ + "action": "allow", + "page": "*" + }] +} \ No newline at end of file diff --git a/utils/area.js b/utils/area.js new file mode 100644 index 0000000..a8672ee --- /dev/null +++ b/utils/area.js @@ -0,0 +1,4047 @@ +export default { + province_list: { + 110000: '北京市', + 120000: '天津市', + 130000: '河北省', + 140000: '山西省', + 150000: '内蒙古', + 210000: '辽宁省', + 220000: '吉林省', + 230000: '黑龙江省', + 310000: '上海市', + 320000: '江苏省', + 330000: '浙江省', + 340000: '安徽省', + 350000: '福建省', + 360000: '江西省', + 370000: '山东省', + 410000: '河南省', + 420000: '湖北省', + 430000: '湖南省', + 440000: '广东省', + 450000: '广西', + 460000: '海南省', + 500000: '重庆市', + 510000: '四川省', + 520000: '贵州省', + 530000: '云南省', + 540000: '西藏', + 610000: '陕西省', + 620000: '甘肃省', + 630000: '青海省', + 640000: '宁夏', + 650000: '新疆', + 710000: '台湾省', + 810000: '香港', + 820000: '澳门', + 900000: '海外', + }, + city_list: { + 110100: '北京市', + 120100: '天津市', + 130100: '石家庄市', + 130200: '唐山市', + 130300: '秦皇岛市', + 130400: '邯郸市', + 130500: '邢台市', + 130600: '保定市', + 130700: '张家口市', + 130800: '承德市', + 130900: '沧州市', + 131000: '廊坊市', + 131100: '衡水市', + 140100: '太原市', + 140200: '大同市', + 140300: '阳泉市', + 140400: '长治市', + 140500: '晋城市', + 140600: '朔州市', + 140700: '晋中市', + 140800: '运城市', + 140900: '忻州市', + 141000: '临汾市', + 141100: '吕梁市', + 150100: '呼和浩特市', + 150200: '包头市', + 150300: '乌海市', + 150400: '赤峰市', + 150500: '通辽市', + 150600: '鄂尔多斯市', + 150700: '呼伦贝尔市', + 150800: '巴彦淖尔市', + 150900: '乌兰察布市', + 152200: '兴安盟', + 152500: '锡林郭勒盟', + 152900: '阿拉善盟', + 210100: '沈阳市', + 210200: '大连市', + 210300: '鞍山市', + 210400: '抚顺市', + 210500: '本溪市', + 210600: '丹东市', + 210700: '锦州市', + 210800: '营口市', + 210900: '阜新市', + 211000: '辽阳市', + 211100: '盘锦市', + 211200: '铁岭市', + 211300: '朝阳市', + 211400: '葫芦岛市', + 220100: '长春市', + 220200: '吉林市', + 220300: '四平市', + 220400: '辽源市', + 220500: '通化市', + 220600: '白山市', + 220700: '松原市', + 220800: '白城市', + 222400: '延边', + 230100: '哈尔滨市', + 230200: '齐齐哈尔市', + 230300: '鸡西市', + 230400: '鹤岗市', + 230500: '双鸭山市', + 230600: '大庆市', + 230700: '伊春市', + 230800: '佳木斯市', + 230900: '七台河市', + 231000: '牡丹江市', + 231100: '黑河市', + 231200: '绥化市', + 232700: '大兴安岭', + 310100: '上海市', + 320100: '南京市', + 320200: '无锡市', + 320300: '徐州市', + 320400: '常州市', + 320500: '苏州市', + 320600: '南通市', + 320700: '连云港市', + 320800: '淮安市', + 320900: '盐城市', + 321000: '扬州市', + 321100: '镇江市', + 321200: '泰州市', + 321300: '宿迁市', + 330100: '杭州市', + 330200: '宁波市', + 330300: '温州市', + 330400: '嘉兴市', + 330500: '湖州市', + 330600: '绍兴市', + 330700: '金华市', + 330800: '衢州市', + 330900: '舟山市', + 331000: '台州市', + 331100: '丽水市', + 340100: '合肥市', + 340200: '芜湖市', + 340300: '蚌埠市', + 340400: '淮南市', + 340500: '马鞍山市', + 340600: '淮北市', + 340700: '铜陵市', + 340800: '安庆市', + 341000: '黄山市', + 341100: '滁州市', + 341200: '阜阳市', + 341300: '宿州市', + 341500: '六安市', + 341600: '亳州市', + 341700: '池州市', + 341800: '宣城市', + 350100: '福州市', + 350200: '厦门市', + 350300: '莆田市', + 350400: '三明市', + 350500: '泉州市', + 350600: '漳州市', + 350700: '南平市', + 350800: '龙岩市', + 350900: '宁德市', + 360100: '南昌市', + 360200: '景德镇市', + 360300: '萍乡市', + 360400: '九江市', + 360500: '新余市', + 360600: '鹰潭市', + 360700: '赣州市', + 360800: '吉安市', + 360900: '宜春市', + 361000: '抚州市', + 361100: '上饶市', + 370100: '济南市', + 370200: '青岛市', + 370300: '淄博市', + 370400: '枣庄市', + 370500: '东营市', + 370600: '烟台市', + 370700: '潍坊市', + 370800: '济宁市', + 370900: '泰安市', + 371000: '威海市', + 371100: '日照市', + 371300: '临沂市', + 371400: '德州市', + 371500: '聊城市', + 371600: '滨州市', + 371700: '菏泽市', + 410100: '郑州市', + 410200: '开封市', + 410300: '洛阳市', + 410400: '平顶山市', + 410500: '安阳市', + 410600: '鹤壁市', + 410700: '新乡市', + 410800: '焦作市', + 410900: '濮阳市', + 411000: '许昌市', + 411100: '漯河市', + 411200: '三门峡市', + 411300: '南阳市', + 411400: '商丘市', + 411500: '信阳市', + 411600: '周口市', + 411700: '驻马店市', + 419000: '省直辖县', + 420100: '武汉市', + 420200: '黄石市', + 420300: '十堰市', + 420500: '宜昌市', + 420600: '襄阳市', + 420700: '鄂州市', + 420800: '荆门市', + 420900: '孝感市', + 421000: '荆州市', + 421100: '黄冈市', + 421200: '咸宁市', + 421300: '随州市', + 422800: '恩施', + 429000: '省直辖县', + 430100: '长沙市', + 430200: '株洲市', + 430300: '湘潭市', + 430400: '衡阳市', + 430500: '邵阳市', + 430600: '岳阳市', + 430700: '常德市', + 430800: '张家界市', + 430900: '益阳市', + 431000: '郴州市', + 431100: '永州市', + 431200: '怀化市', + 431300: '娄底市', + 433100: '湘西', + 440100: '广州市', + 440200: '韶关市', + 440300: '深圳市', + 440400: '珠海市', + 440500: '汕头市', + 440600: '佛山市', + 440700: '江门市', + 440800: '湛江市', + 440900: '茂名市', + 441200: '肇庆市', + 441300: '惠州市', + 441400: '梅州市', + 441500: '汕尾市', + 441600: '河源市', + 441700: '阳江市', + 441800: '清远市', + 441900: '东莞市', + 442000: '中山市', + 445100: '潮州市', + 445200: '揭阳市', + 445300: '云浮市', + 450100: '南宁市', + 450200: '柳州市', + 450300: '桂林市', + 450400: '梧州市', + 450500: '北海市', + 450600: '防城港市', + 450700: '钦州市', + 450800: '贵港市', + 450900: '玉林市', + 451000: '百色市', + 451100: '贺州市', + 451200: '河池市', + 451300: '来宾市', + 451400: '崇左市', + 460100: '海口市', + 460200: '三亚市', + 460300: '三沙市', + 460400: '儋州市', + 469000: '省直辖县', + 500100: '重庆市', + 500200: '县', + 510100: '成都市', + 510300: '自贡市', + 510400: '攀枝花市', + 510500: '泸州市', + 510600: '德阳市', + 510700: '绵阳市', + 510800: '广元市', + 510900: '遂宁市', + 511000: '内江市', + 511100: '乐山市', + 511300: '南充市', + 511400: '眉山市', + 511500: '宜宾市', + 511600: '广安市', + 511700: '达州市', + 511800: '雅安市', + 511900: '巴中市', + 512000: '资阳市', + 513200: '阿坝藏族羌族自治州', + 513300: '甘孜藏族自治州', + 513400: '凉山彝族自治州', + 520100: '贵阳市', + 520200: '六盘水市', + 520300: '遵义市', + 520400: '安顺市', + 520500: '毕节市', + 520600: '铜仁市', + 522300: '黔西南布依族苗族自治州', + 522600: '黔东南苗族侗族自治州', + 522700: '黔南布依族苗族自治州', + 530100: '昆明市', + 530300: '曲靖市', + 530400: '玉溪市', + 530500: '保山市', + 530600: '昭通市', + 530700: '丽江市', + 530800: '普洱市', + 530900: '临沧市', + 532300: '楚雄彝族自治州', + 532500: '红河哈尼族彝族自治州', + 532600: '文山壮族苗族自治州', + 532800: '西双版纳傣族自治州', + 532900: '大理白族自治州', + 533100: '德宏傣族景颇族自治州', + 533300: '怒江傈僳族自治州', + 533400: '迪庆藏族自治州', + 540100: '拉萨市', + 540200: '日喀则市', + 540300: '昌都市', + 540400: '林芝市', + 540500: '山南市', + 540600: '那曲市', + 542500: '阿里地区', + 610100: '西安市', + 610200: '铜川市', + 610300: '宝鸡市', + 610400: '咸阳市', + 610500: '渭南市', + 610600: '延安市', + 610700: '汉中市', + 610800: '榆林市', + 610900: '安康市', + 611000: '商洛市', + 620100: '兰州市', + 620200: '嘉峪关市', + 620300: '金昌市', + 620400: '白银市', + 620500: '天水市', + 620600: '武威市', + 620700: '张掖市', + 620800: '平凉市', + 620900: '酒泉市', + 621000: '庆阳市', + 621100: '定西市', + 621200: '陇南市', + 622900: '临夏回族自治州', + 623000: '甘南藏族自治州', + 630100: '西宁市', + 630200: '海东市', + 632200: '海北藏族自治州', + 632300: '黄南藏族自治州', + 632500: '海南藏族自治州', + 632600: '果洛藏族自治州', + 632700: '玉树藏族自治州', + 632800: '海西蒙古族藏族自治州', + 640100: '银川市', + 640200: '石嘴山市', + 640300: '吴忠市', + 640400: '固原市', + 640500: '中卫市', + 650100: '乌鲁木齐市', + 650200: '克拉玛依市', + 650400: '吐鲁番市', + 650500: '哈密市', + 652300: '昌吉回族自治州', + 652700: '博尔塔拉蒙古自治州', + 652800: '巴音郭楞蒙古自治州', + 652900: '阿克苏地区', + 653000: '克孜勒苏柯尔克孜自治州', + 653100: '喀什地区', + 653200: '和田地区', + 654000: '伊犁哈萨克自治州', + 654200: '塔城地区', + 654300: '阿勒泰地区', + 659000: '自治区直辖县级行政区划', + 710100: '台北市', + 710200: '高雄市', + 710300: '台南市', + 710400: '台中市', + 710500: '金门县', + 710600: '南投县', + 710700: '基隆市', + 710800: '新竹市', + 710900: '嘉义市', + 711100: '新北市', + 711200: '宜兰县', + 711300: '新竹县', + 711400: '桃园县', + 711500: '苗栗县', + 711700: '彰化县', + 711900: '嘉义县', + 712100: '云林县', + 712400: '屏东县', + 712500: '台东县', + 712600: '花莲县', + 712700: '澎湖县', + 712800: '连江县', + 810100: '香港岛', + 810200: '九龙', + 810300: '新界', + 820100: '澳门半岛', + 820200: '离岛', + 900400: '阿富汗', + 900800: '阿尔巴尼亚', + 901000: '南极洲', + 901200: '阿尔及利亚', + 901600: '美属萨摩亚', + 902000: '安道尔', + 902400: '安哥拉', + 902800: '安提瓜和巴布达', + 903100: '阿塞拜疆', + 903200: '阿根廷', + 903600: '澳大利亚', + 904000: '奥地利', + 904400: '巴哈马', + 904800: '巴林', + 905000: '孟加拉', + 905100: '亚美尼亚', + 905200: '巴巴多斯', + 905600: '比利时', + 906000: '百慕大', + 906400: '不丹', + 906800: '玻利维亚', + 907000: '波黑', + 907200: '博茨瓦纳', + 907400: '布韦岛', + 907600: '巴西', + 908400: '伯利兹', + 908600: '英属印度洋领地', + 909000: '所罗门群岛', + 909200: '英属维尔京群岛', + 909600: '文莱', + 910000: '保加利亚', + 910400: '缅甸', + 910800: '布隆迪', + 911200: '白俄罗斯', + 911600: '柬埔寨', + 912000: '喀麦隆', + 912400: '加拿大', + 913200: '佛得角', + 913600: '开曼群岛', + 914000: '中非', + 914400: '斯里兰卡', + 914800: '乍得', + 915200: '智利', + 916200: '圣诞岛', + 916600: '科科斯群岛', + 917000: '哥伦比亚', + 917400: '科摩罗', + 917500: '马约特', + 917800: '刚果(布)', + 918000: '刚果(金)', + 918400: '库克群岛', + 918800: '哥斯达黎加', + 919100: '克罗地亚', + 919200: '古巴', + 919600: '塞浦路斯', + 920300: '捷克', + 920400: '贝宁', + 920800: '丹麦', + 921200: '多米尼克', + 921400: '多米尼加', + 921800: '厄瓜多尔', + 922200: '萨尔瓦多', + 922600: '赤道几内亚', + 923100: '埃塞俄比亚', + 923200: '厄立特里亚', + 923300: '爱沙尼亚', + 923400: '法罗群岛', + 923800: '马尔维纳斯群岛( 福克兰)', + 923900: '南乔治亚岛和南桑威奇群岛', + 924200: '斐济群岛', + 924600: '芬兰', + 924800: '奥兰群岛', + 925000: '法国', + 925400: '法属圭亚那', + 925800: '法属波利尼西亚', + 926000: '法属南部领地', + 926200: '吉布提', + 926600: '加蓬', + 926800: '格鲁吉亚', + 927000: '冈比亚', + 927500: '巴勒斯坦', + 927600: '德国', + 928800: '加纳', + 929200: '直布罗陀', + 929600: '基里巴斯', + 930000: '希腊', + 930400: '格陵兰', + 930800: '格林纳达', + 931200: '瓜德罗普', + 931600: '关岛', + 932000: '危地马拉', + 932400: '几内亚', + 932800: '圭亚那', + 933200: '海地', + 933400: '赫德岛和麦克唐纳群岛', + 933600: '梵蒂冈', + 934000: '洪都拉斯', + 934800: '匈牙利', + 935200: '冰岛', + 935600: '印度', + 936000: '印尼', + 936400: '伊朗', + 936800: '伊拉克', + 937200: '爱尔兰', + 937600: '以色列', + 938000: '意大利', + 938400: '科特迪瓦', + 938800: '牙买加', + 939200: '日本', + 939800: '哈萨克斯坦', + 940000: '约旦', + 940400: '肯尼亚', + 940800: '朝鲜 北朝鲜', + 941000: '韩国', + 941400: '科威特', + 941700: '吉尔吉斯斯坦', + 941800: '老挝', + 942200: '黎巴嫩', + 942600: '莱索托', + 942800: '拉脱维亚', + 943000: '利比里亚', + 943400: '利比亚', + 943800: '列支敦士登', + 944000: '立陶宛', + 944200: '卢森堡', + 945000: '马达加斯加', + 945400: '马拉维', + 945800: '马来西亚', + 946200: '马尔代夫', + 946600: '马里', + 947000: '马耳他', + 947400: '马提尼克', + 947800: '毛里塔尼亚', + 948000: '毛里求斯', + 948400: '墨西哥', + 949200: '摩纳哥', + 949600: '蒙古国', + 949800: '摩尔多瓦', + 949900: '黑山', + 950000: '蒙塞拉特岛', + 950400: '摩洛哥', + 950800: '莫桑比克', + 951200: '阿曼', + 951600: '纳米比亚', + 952000: '瑙鲁', + 952400: '尼泊尔', + 952800: '荷兰', + 953300: '阿鲁巴', + 953500: '荷兰加勒比区', + 954000: '新喀里多尼亚', + 954800: '瓦努阿图', + 955400: '新西兰', + 955800: '尼加拉瓜', + 956200: '尼日尔', + 956600: '尼日利亚', + 957000: '纽埃', + 957400: '诺福克岛', + 957800: '挪威', + 958000: '北马里亚纳群岛', + 958100: '美国本土外小岛屿', + 958300: '密克罗尼西亚联邦', + 958400: '马绍尔群岛', + 958500: '帕劳', + 958600: '巴基斯坦', + 959100: '巴拿马', + 959800: '巴布亚新几内亚', + 960000: '巴拉圭', + 960400: '秘鲁', + 960800: '菲律宾', + 961200: '皮特凯恩群岛', + 961600: '波兰', + 962000: '葡萄牙', + 962400: '几内亚比绍', + 962600: '东帝汶', + 963000: '波多黎各', + 963400: '卡塔尔', + 963800: '留尼汪', + 964200: '罗马尼亚', + 964300: '俄罗斯', + 964600: '卢旺达', + 965200: '圣巴泰勒米岛', + 965400: '圣赫勒拿', + 965900: '圣基茨和尼维斯', + 966000: '安圭拉', + 966200: '圣卢西亚', + 966300: '法属圣马丁', + 966600: '圣皮埃尔和密克隆', + 967000: '圣文森特和格林纳丁斯', + 967400: '圣马力诺', + 967800: '圣多美和普林西比', + 968200: '沙特阿拉伯', + 968600: '塞内加尔', + 968800: '塞尔维亚', + 969000: '塞舌尔', + 969400: '塞拉利昂', + 970200: '新加坡', + 970300: '斯洛伐克', + 970400: '越南', + 970500: '斯洛文尼亚', + 970600: '索马里', + 971000: '南非', + 971600: '津巴布韦', + 972400: '西班牙', + 972800: '南苏丹', + 972900: '苏丹', + 973200: '西撒哈拉', + 974000: '苏里南', + 974400: '斯瓦尔巴群岛和 扬马延岛', + 974800: '斯威士兰', + 975200: '瑞典', + 975600: '瑞士', + 976000: '叙利亚', + 976200: '塔吉克斯坦', + 976400: '泰国', + 976800: '多哥', + 977200: '托克劳', + 977600: '汤加', + 978000: '特立尼达和多巴哥', + 978400: '阿联酋', + 978800: '突尼斯', + 979200: '土耳其', + 979500: '土库曼斯坦', + 979600: '特克斯和凯科斯群岛', + 979800: '图瓦卢', + 980000: '乌干达', + 980400: '乌克兰', + 980700: '马其顿', + 981800: '埃及', + 982600: '英国', + 983100: '根西岛', + 983200: '泽西岛', + 983300: '马恩岛', + 983400: '坦桑尼亚', + 984000: '美国', + 985000: '美属维尔京群岛', + 985400: '布基纳法索', + 985800: '乌拉圭', + 986000: '乌兹别克斯坦', + 986200: '委内瑞拉', + 987600: '瓦利斯和富图纳', + 988200: '萨摩亚', + 988700: '也门', + 989400: '赞比亚', + }, + county_list: { + 110101: '东城区', + 110102: '西城区', + 110105: '朝阳区', + 110106: '丰台区', + 110107: '石景山区', + 110108: '海淀区', + 110109: '门头沟区', + 110111: '房山区', + 110112: '通州区', + 110113: '顺义区', + 110114: '昌平区', + 110115: '大兴区', + 110116: '怀柔区', + 110117: '平谷区', + 110118: '密云区', + 110119: '延庆区', + 120101: '和平区', + 120102: '河东区', + 120103: '河西区', + 120104: '南开区', + 120105: '河北区', + 120106: '红桥区', + 120110: '东丽区', + 120111: '西青区', + 120112: '津南区', + 120113: '北辰区', + 120114: '武清区', + 120115: '宝坻区', + 120116: '滨海新区', + 120117: '宁河区', + 120118: '静海区', + 120119: '蓟州区', + 130102: '长安区', + 130104: '桥西区', + 130105: '新华区', + 130107: '井陉矿区', + 130108: '裕华区', + 130109: '藁城区', + 130110: '鹿泉区', + 130111: '栾城区', + 130121: '井陉县', + 130123: '正定县', + 130125: '行唐县', + 130126: '灵寿县', + 130127: '高邑县', + 130128: '深泽县', + 130129: '赞皇县', + 130130: '无极县', + 130131: '平山县', + 130132: '元氏县', + 130133: '赵县', + 130181: '辛集市', + 130183: '晋州市', + 130184: '新乐市', + 130202: '路南区', + 130203: '路北区', + 130204: '古冶区', + 130205: '开平区', + 130207: '丰南区', + 130208: '丰润区', + 130209: '曹妃甸区', + 130224: '滦南县', + 130225: '乐亭县', + 130227: '迁西县', + 130229: '玉田县', + 130281: '遵化市', + 130283: '迁安市', + 130284: '滦州市', + 130302: '海港区', + 130303: '山海关区', + 130304: '北戴河区', + 130306: '抚宁区', + 130321: '青龙满族自治县', + 130322: '昌黎县', + 130324: '卢龙县', + 130390: '经济技术开发区', + 130402: '邯山区', + 130403: '丛台区', + 130404: '复兴区', + 130406: '峰峰矿区', + 130407: '肥乡区', + 130408: '永年区', + 130423: '临漳县', + 130424: '成安县', + 130425: '大名县', + 130426: '涉县', + 130427: '磁县', + 130430: '邱县', + 130431: '鸡泽县', + 130432: '广平县', + 130433: '馆陶县', + 130434: '魏县', + 130435: '曲周县', + 130481: '武安市', + 130502: '桥东区', + 130503: '桥西区', + 130521: '邢台县', + 130522: '临城县', + 130523: '内丘县', + 130524: '柏乡县', + 130525: '隆尧县', + 130526: '任县', + 130527: '南和县', + 130528: '宁晋县', + 130529: '巨鹿县', + 130530: '新河县', + 130531: '广宗县', + 130532: '平乡县', + 130533: '威县', + 130534: '清河县', + 130535: '临西县', + 130581: '南宫市', + 130582: '沙河市', + 130602: '竞秀区', + 130606: '莲池区', + 130607: '满城区', + 130608: '清苑区', + 130609: '徐水区', + 130623: '涞水县', + 130624: '阜平县', + 130626: '定兴县', + 130627: '唐县', + 130628: '高阳县', + 130629: '容城县', + 130630: '涞源县', + 130631: '望都县', + 130632: '安新县', + 130633: '易县', + 130634: '曲阳县', + 130635: '蠡县', + 130636: '顺平县', + 130637: '博野县', + 130638: '雄县', + 130681: '涿州市', + 130682: '定州市', + 130683: '安国市', + 130684: '高碑店市', + 130702: '桥东区', + 130703: '桥西区', + 130705: '宣化区', + 130706: '下花园区', + 130708: '万全区', + 130709: '崇礼区', + 130722: '张北县', + 130723: '康保县', + 130724: '沽源县', + 130725: '尚义县', + 130726: '蔚县', + 130727: '阳原县', + 130728: '怀安县', + 130730: '怀来县', + 130731: '涿鹿县', + 130732: '赤城县', + 130802: '双桥区', + 130803: '双滦区', + 130804: '鹰手营子矿区', + 130821: '承德县', + 130822: '兴隆县', + 130824: '滦平县', + 130825: '隆化县', + 130826: '丰宁满族自治县', + 130827: '宽城满族自治县', + 130828: '围场满族蒙古族自治县', + 130881: '平泉市', + 130902: '新华区', + 130903: '运河区', + 130921: '沧县', + 130922: '青县', + 130923: '东光县', + 130924: '海兴县', + 130925: '盐山县', + 130926: '肃宁县', + 130927: '南皮县', + 130928: '吴桥县', + 130929: '献县', + 130930: '孟村回族自治县', + 130981: '泊头市', + 130982: '任丘市', + 130983: '黄骅市', + 130984: '河间市', + 131002: '安次区', + 131003: '广阳区', + 131022: '固安县', + 131023: '永清县', + 131024: '香河县', + 131025: '大城县', + 131026: '文安县', + 131028: '大厂回族自治县', + 131081: '霸州市', + 131082: '三河市', + 131090: '开发区', + 131102: '桃城区', + 131103: '冀州区', + 131121: '枣强县', + 131122: '武邑县', + 131123: '武强县', + 131124: '饶阳县', + 131125: '安平县', + 131126: '故城县', + 131127: '景县', + 131128: '阜城县', + 131182: '深州市', + 140105: '小店区', + 140106: '迎泽区', + 140107: '杏花岭区', + 140108: '尖草坪区', + 140109: '万柏林区', + 140110: '晋源区', + 140121: '清徐县', + 140122: '阳曲县', + 140123: '娄烦县', + 140181: '古交市', + 140212: '新荣区', + 140213: '平城区', + 140214: '云冈区', + 140215: '云州区', + 140221: '阳高县', + 140222: '天镇县', + 140223: '广灵县', + 140224: '灵丘县', + 140225: '浑源县', + 140226: '左云县', + 140302: '城区', + 140303: '矿区', + 140311: '郊区', + 140321: '平定县', + 140322: '盂县', + 140403: '潞州区', + 140404: '上党区', + 140405: '屯留区', + 140406: '潞城区', + 140423: '襄垣县', + 140425: '平顺县', + 140426: '黎城县', + 140427: '壶关县', + 140428: '长子县', + 140429: '武乡县', + 140430: '沁县', + 140431: '沁源县', + 140502: '城区', + 140521: '沁水县', + 140522: '阳城县', + 140524: '陵川县', + 140525: '泽州县', + 140581: '高平市', + 140602: '朔城区', + 140603: '平鲁区', + 140621: '山阴县', + 140622: '应县', + 140623: '右玉县', + 140681: '怀仁市', + 140702: '榆次区', + 140721: '榆社县', + 140722: '左权县', + 140723: '和顺县', + 140724: '昔阳县', + 140725: '寿阳县', + 140726: '太谷县', + 140727: '祁县', + 140728: '平遥县', + 140729: '灵石县', + 140781: '介休市', + 140802: '盐湖区', + 140821: '临猗县', + 140822: '万荣县', + 140823: '闻喜县', + 140824: '稷山县', + 140825: '新绛县', + 140826: '绛县', + 140827: '垣曲县', + 140828: '夏县', + 140829: '平陆县', + 140830: '芮城县', + 140881: '永济市', + 140882: '河津市', + 140902: '忻府区', + 140921: '定襄县', + 140922: '五台县', + 140923: '代县', + 140924: '繁峙县', + 140925: '宁武县', + 140926: '静乐县', + 140927: '神池县', + 140928: '五寨县', + 140929: '岢岚县', + 140930: '河曲县', + 140931: '保德县', + 140932: '偏关县', + 140981: '原平市', + 141002: '尧都区', + 141021: '曲沃县', + 141022: '翼城县', + 141023: '襄汾县', + 141024: '洪洞县', + 141025: '古县', + 141026: '安泽县', + 141027: '浮山县', + 141028: '吉县', + 141029: '乡宁县', + 141030: '大宁县', + 141031: '隰县', + 141032: '永和县', + 141033: '蒲县', + 141034: '汾西县', + 141081: '侯马市', + 141082: '霍州市', + 141102: '离石区', + 141121: '文水县', + 141122: '交城县', + 141123: '兴县', + 141124: '临县', + 141125: '柳林县', + 141126: '石楼县', + 141127: '岚县', + 141128: '方山县', + 141129: '中阳县', + 141130: '交口县', + 141181: '孝义市', + 141182: '汾阳市', + 150102: '新城区', + 150103: '回民区', + 150104: '玉泉区', + 150105: '赛罕区', + 150121: '土默特左旗', + 150122: '托克托县', + 150123: '和林格尔县', + 150124: '清水河县', + 150125: '武川县', + 150202: '东河区', + 150203: '昆都仑区', + 150204: '青山区', + 150205: '石拐区', + 150206: '白云鄂博矿区', + 150207: '九原区', + 150221: '土默特右旗', + 150222: '固阳县', + 150223: '达尔罕茂明安联合旗', + 150302: '海勃湾区', + 150303: '海南区', + 150304: '乌达区', + 150402: '红山区', + 150403: '元宝山区', + 150404: '松山区', + 150421: '阿鲁科尔沁旗', + 150422: '巴林左旗', + 150423: '巴林右旗', + 150424: '林西县', + 150425: '克什克腾旗', + 150426: '翁牛特旗', + 150428: '喀喇沁旗', + 150429: '宁城县', + 150430: '敖汉旗', + 150502: '科尔沁区', + 150521: '科尔沁左翼中旗', + 150522: '科尔沁左翼后旗', + 150523: '开鲁县', + 150524: '库伦旗', + 150525: '奈曼旗', + 150526: '扎鲁特旗', + 150581: '霍林郭勒市', + 150602: '东胜区', + 150603: '康巴什区', + 150621: '达拉特旗', + 150622: '准格尔旗', + 150623: '鄂托克前旗', + 150624: '鄂托克旗', + 150625: '杭锦旗', + 150626: '乌审旗', + 150627: '伊金霍洛旗', + 150702: '海拉尔区', + 150703: '扎赉诺尔区', + 150721: '阿荣旗', + 150722: '莫力达瓦达斡尔族自治旗', + 150723: '鄂伦春自治旗', + 150724: '鄂温克族自治旗', + 150725: '陈巴尔虎旗', + 150726: '新巴尔虎左旗', + 150727: '新巴尔虎右旗', + 150781: '满洲里市', + 150782: '牙克石市', + 150783: '扎兰屯市', + 150784: '额尔古纳市', + 150785: '根河市', + 150802: '临河区', + 150821: '五原县', + 150822: '磴口县', + 150823: '乌拉特前旗', + 150824: '乌拉特中旗', + 150825: '乌拉特后旗', + 150826: '杭锦后旗', + 150902: '集宁区', + 150921: '卓资县', + 150922: '化德县', + 150923: '商都县', + 150924: '兴和县', + 150925: '凉城县', + 150926: '察哈尔右翼前旗', + 150927: '察哈尔右翼中旗', + 150928: '察哈尔右翼后旗', + 150929: '四子王旗', + 150981: '丰镇市', + 152201: '乌兰浩特市', + 152202: '阿尔山市', + 152221: '科尔沁右翼前旗', + 152222: '科尔沁右翼中旗', + 152223: '扎赉特旗', + 152224: '突泉县', + 152501: '二连浩特市', + 152502: '锡林浩特市', + 152522: '阿巴嘎旗', + 152523: '苏尼特左旗', + 152524: '苏尼特右旗', + 152525: '东乌珠穆沁旗', + 152526: '西乌珠穆沁旗', + 152527: '太仆寺旗', + 152528: '镶黄旗', + 152529: '正镶白旗', + 152530: '正蓝旗', + 152531: '多伦县', + 152921: '阿拉善左旗', + 152922: '阿拉善右旗', + 152923: '额济纳旗', + 210102: '和平区', + 210103: '沈河区', + 210104: '大东区', + 210105: '皇姑区', + 210106: '铁西区', + 210111: '苏家屯区', + 210112: '浑南区', + 210113: '沈北新区', + 210114: '于洪区', + 210115: '辽中区', + 210123: '康平县', + 210124: '法库县', + 210181: '新民市', + 210190: '经济技术开发区', + 210202: '中山区', + 210203: '西岗区', + 210204: '沙河口区', + 210211: '甘井子区', + 210212: '旅顺口区', + 210213: '金州区', + 210214: '普兰店区', + 210224: '长海县', + 210281: '瓦房店市', + 210283: '庄河市', + 210302: '铁东区', + 210303: '铁西区', + 210304: '立山区', + 210311: '千山区', + 210321: '台安县', + 210323: '岫岩满族自治县', + 210381: '海城市', + 210390: '高新区', + 210402: '新抚区', + 210403: '东洲区', + 210404: '望花区', + 210411: '顺城区', + 210421: '抚顺县', + 210422: '新宾满族自治县', + 210423: '清原满族自治县', + 210502: '平山区', + 210503: '溪湖区', + 210504: '明山区', + 210505: '南芬区', + 210521: '本溪满族自治县', + 210522: '桓仁满族自治县', + 210602: '元宝区', + 210603: '振兴区', + 210604: '振安区', + 210624: '宽甸满族自治县', + 210681: '东港市', + 210682: '凤城市', + 210702: '古塔区', + 210703: '凌河区', + 210711: '太和区', + 210726: '黑山县', + 210727: '义县', + 210781: '凌海市', + 210782: '北镇市', + 210793: '经济技术开发区', + 210802: '站前区', + 210803: '西市区', + 210804: '鲅鱼圈区', + 210811: '老边区', + 210881: '盖州市', + 210882: '大石桥市', + 210902: '海州区', + 210903: '新邱区', + 210904: '太平区', + 210905: '清河门区', + 210911: '细河区', + 210921: '阜新蒙古族自治县', + 210922: '彰武县', + 211002: '白塔区', + 211003: '文圣区', + 211004: '宏伟区', + 211005: '弓长岭区', + 211011: '太子河区', + 211021: '辽阳县', + 211081: '灯塔市', + 211102: '双台子区', + 211103: '兴隆台区', + 211104: '大洼区', + 211122: '盘山县', + 211202: '银州区', + 211204: '清河区', + 211221: '铁岭县', + 211223: '西丰县', + 211224: '昌图县', + 211281: '调兵山市', + 211282: '开原市', + 211302: '双塔区', + 211303: '龙城区', + 211321: '朝阳县', + 211322: '建平县', + 211324: '喀喇沁左翼蒙古族自治县', + 211381: '北票市', + 211382: '凌源市', + 211402: '连山区', + 211403: '龙港区', + 211404: '南票区', + 211421: '绥中县', + 211422: '建昌县', + 211481: '兴城市', + 220102: '南关区', + 220103: '宽城区', + 220104: '朝阳区', + 220105: '二道区', + 220106: '绿园区', + 220112: '双阳区', + 220113: '九台区', + 220122: '农安县', + 220182: '榆树市', + 220183: '德惠市', + 220192: '经济技术开发区', + 220202: '昌邑区', + 220203: '龙潭区', + 220204: '船营区', + 220211: '丰满区', + 220221: '永吉县', + 220281: '蛟河市', + 220282: '桦甸市', + 220283: '舒兰市', + 220284: '磐石市', + 220302: '铁西区', + 220303: '铁东区', + 220322: '梨树县', + 220323: '伊通满族自治县', + 220381: '公主岭市', + 220382: '双辽市', + 220402: '龙山区', + 220403: '西安区', + 220421: '东丰县', + 220422: '东辽县', + 220502: '东昌区', + 220503: '二道江区', + 220521: '通化县', + 220523: '辉南县', + 220524: '柳河县', + 220581: '梅河口市', + 220582: '集安市', + 220602: '浑江区', + 220605: '江源区', + 220621: '抚松县', + 220622: '靖宇县', + 220623: '长白朝鲜族自治县', + 220681: '临江市', + 220702: '宁江区', + 220721: '前郭尔罗斯蒙古族自治县', + 220722: '长岭县', + 220723: '乾安县', + 220781: '扶余市', + 220802: '洮北区', + 220821: '镇赉县', + 220822: '通榆县', + 220881: '洮南市', + 220882: '大安市', + 222401: '延吉市', + 222402: '图们市', + 222403: '敦化市', + 222404: '珲春市', + 222405: '龙井市', + 222406: '和龙市', + 222424: '汪清县', + 222426: '安图县', + 230102: '道里区', + 230103: '南岗区', + 230104: '道外区', + 230108: '平房区', + 230109: '松北区', + 230110: '香坊区', + 230111: '呼兰区', + 230112: '阿城区', + 230113: '双城区', + 230123: '依兰县', + 230124: '方正县', + 230125: '宾县', + 230126: '巴彦县', + 230127: '木兰县', + 230128: '通河县', + 230129: '延寿县', + 230183: '尚志市', + 230184: '五常市', + 230202: '龙沙区', + 230203: '建华区', + 230204: '铁锋区', + 230205: '昂昂溪区', + 230206: '富拉尔基区', + 230207: '碾子山区', + 230208: '梅里斯达斡尔族区', + 230221: '龙江县', + 230223: '依安县', + 230224: '泰来县', + 230225: '甘南县', + 230227: '富裕县', + 230229: '克山县', + 230230: '克东县', + 230231: '拜泉县', + 230281: '讷河市', + 230302: '鸡冠区', + 230303: '恒山区', + 230304: '滴道区', + 230305: '梨树区', + 230306: '城子河区', + 230307: '麻山区', + 230321: '鸡东县', + 230381: '虎林市', + 230382: '密山市', + 230402: '向阳区', + 230403: '工农区', + 230404: '南山区', + 230405: '兴安区', + 230406: '东山区', + 230407: '兴山区', + 230421: '萝北县', + 230422: '绥滨县', + 230502: '尖山区', + 230503: '岭东区', + 230505: '四方台区', + 230506: '宝山区', + 230521: '集贤县', + 230522: '友谊县', + 230523: '宝清县', + 230524: '饶河县', + 230602: '萨尔图区', + 230603: '龙凤区', + 230604: '让胡路区', + 230605: '红岗区', + 230606: '大同区', + 230621: '肇州县', + 230622: '肇源县', + 230623: '林甸县', + 230624: '杜尔伯特蒙古族自治县', + 230702: '伊春区', + 230703: '南岔区', + 230704: '友好区', + 230705: '西林区', + 230706: '翠峦区', + 230707: '新青区', + 230708: '美溪区', + 230709: '金山屯区', + 230710: '五营区', + 230711: '乌马河区', + 230712: '汤旺河区', + 230713: '带岭区', + 230714: '乌伊岭区', + 230715: '红星区', + 230716: '上甘岭区', + 230722: '嘉荫县', + 230781: '铁力市', + 230803: '向阳区', + 230804: '前进区', + 230805: '东风区', + 230811: '郊区', + 230822: '桦南县', + 230826: '桦川县', + 230828: '汤原县', + 230881: '同江市', + 230882: '富锦市', + 230883: '抚远市', + 230902: '新兴区', + 230903: '桃山区', + 230904: '茄子河区', + 230921: '勃利县', + 231002: '东安区', + 231003: '阳明区', + 231004: '爱民区', + 231005: '西安区', + 231025: '林口县', + 231081: '绥芬河市', + 231083: '海林市', + 231084: '宁安市', + 231085: '穆棱市', + 231086: '东宁市', + 231102: '爱辉区', + 231121: '嫩江县', + 231123: '逊克县', + 231124: '孙吴县', + 231181: '北安市', + 231182: '五大连池市', + 231202: '北林区', + 231221: '望奎县', + 231222: '兰西县', + 231223: '青冈县', + 231224: '庆安县', + 231225: '明水县', + 231226: '绥棱县', + 231281: '安达市', + 231282: '肇东市', + 231283: '海伦市', + 232701: '漠河市', + 232721: '呼玛县', + 232722: '塔河县', + 232790: '松岭区', + 232791: '呼中区', + 232792: '加格达奇区', + 232793: '新林区', + 310101: '黄浦区', + 310104: '徐汇区', + 310105: '长宁区', + 310106: '静安区', + 310107: '普陀区', + 310109: '虹口区', + 310110: '杨浦区', + 310112: '闵行区', + 310113: '宝山区', + 310114: '嘉定区', + 310115: '浦东新区', + 310116: '金山区', + 310117: '松江区', + 310118: '青浦区', + 310120: '奉贤区', + 310151: '崇明区', + 320102: '玄武区', + 320104: '秦淮区', + 320105: '建邺区', + 320106: '鼓楼区', + 320111: '浦口区', + 320113: '栖霞区', + 320114: '雨花台区', + 320115: '江宁区', + 320116: '六合区', + 320117: '溧水区', + 320118: '高淳区', + 320205: '锡山区', + 320206: '惠山区', + 320211: '滨湖区', + 320213: '梁溪区', + 320214: '新吴区', + 320281: '江阴市', + 320282: '宜兴市', + 320302: '鼓楼区', + 320303: '云龙区', + 320305: '贾汪区', + 320311: '泉山区', + 320312: '铜山区', + 320321: '丰县', + 320322: '沛县', + 320324: '睢宁县', + 320381: '新沂市', + 320382: '邳州市', + 320391: '工业园区', + 320402: '天宁区', + 320404: '钟楼区', + 320411: '新北区', + 320412: '武进区', + 320413: '金坛区', + 320481: '溧阳市', + 320505: '虎丘区', + 320506: '吴中区', + 320507: '相城区', + 320508: '姑苏区', + 320509: '吴江区', + 320581: '常熟市', + 320582: '张家港市', + 320583: '昆山市', + 320585: '太仓市', + 320590: '工业园区', + 320591: '高新区', + 320602: '崇川区', + 320611: '港闸区', + 320612: '通州区', + 320623: '如东县', + 320681: '启东市', + 320682: '如皋市', + 320684: '海门市', + 320685: '海安市', + 320691: '高新区', + 320703: '连云区', + 320706: '海州区', + 320707: '赣榆区', + 320722: '东海县', + 320723: '灌云县', + 320724: '灌南县', + 320803: '淮安区', + 320804: '淮阴区', + 320812: '清江浦区', + 320813: '洪泽区', + 320826: '涟水县', + 320830: '盱眙县', + 320831: '金湖县', + 320890: '经济开发区', + 320902: '亭湖区', + 320903: '盐都区', + 320904: '大丰区', + 320921: '响水县', + 320922: '滨海县', + 320923: '阜宁县', + 320924: '射阳县', + 320925: '建湖县', + 320981: '东台市', + 321002: '广陵区', + 321003: '邗江区', + 321012: '江都区', + 321023: '宝应县', + 321081: '仪征市', + 321084: '高邮市', + 321090: '经济开发区', + 321102: '京口区', + 321111: '润州区', + 321112: '丹徒区', + 321181: '丹阳市', + 321182: '扬中市', + 321183: '句容市', + 321202: '海陵区', + 321203: '高港区', + 321204: '姜堰区', + 321281: '兴化市', + 321282: '靖江市', + 321283: '泰兴市', + 321302: '宿城区', + 321311: '宿豫区', + 321322: '沭阳县', + 321323: '泗阳县', + 321324: '泗洪县', + 330102: '上城区', + 330103: '下城区', + 330104: '江干区', + 330105: '拱墅区', + 330106: '西湖区', + 330108: '滨江区', + 330109: '萧山区', + 330110: '余杭区', + 330111: '富阳区', + 330112: '临安区', + 330122: '桐庐县', + 330127: '淳安县', + 330182: '建德市', + 330203: '海曙区', + 330205: '江北区', + 330206: '北仑区', + 330211: '镇海区', + 330212: '鄞州区', + 330213: '奉化区', + 330225: '象山县', + 330226: '宁海县', + 330281: '余姚市', + 330282: '慈溪市', + 330302: '鹿城区', + 330303: '龙湾区', + 330304: '瓯海区', + 330305: '洞头区', + 330324: '永嘉县', + 330326: '平阳县', + 330327: '苍南县', + 330328: '文成县', + 330329: '泰顺县', + 330381: '瑞安市', + 330382: '乐清市', + 330402: '南湖区', + 330411: '秀洲区', + 330421: '嘉善县', + 330424: '海盐县', + 330481: '海宁市', + 330482: '平湖市', + 330483: '桐乡市', + 330502: '吴兴区', + 330503: '南浔区', + 330521: '德清县', + 330522: '长兴县', + 330523: '安吉县', + 330602: '越城区', + 330603: '柯桥区', + 330604: '上虞区', + 330624: '新昌县', + 330681: '诸暨市', + 330683: '嵊州市', + 330702: '婺城区', + 330703: '金东区', + 330723: '武义县', + 330726: '浦江县', + 330727: '磐安县', + 330781: '兰溪市', + 330782: '义乌市', + 330783: '东阳市', + 330784: '永康市', + 330802: '柯城区', + 330803: '衢江区', + 330822: '常山县', + 330824: '开化县', + 330825: '龙游县', + 330881: '江山市', + 330902: '定海区', + 330903: '普陀区', + 330921: '岱山县', + 330922: '嵊泗县', + 331002: '椒江区', + 331003: '黄岩区', + 331004: '路桥区', + 331022: '三门县', + 331023: '天台县', + 331024: '仙居县', + 331081: '温岭市', + 331082: '临海市', + 331083: '玉环市', + 331102: '莲都区', + 331121: '青田县', + 331122: '缙云县', + 331123: '遂昌县', + 331124: '松阳县', + 331125: '云和县', + 331126: '庆元县', + 331127: '景宁畲族自治县', + 331181: '龙泉市', + 340102: '瑶海区', + 340103: '庐阳区', + 340104: '蜀山区', + 340111: '包河区', + 340121: '长丰县', + 340122: '肥东县', + 340123: '肥西县', + 340124: '庐江县', + 340181: '巢湖市', + 340190: '高新技术开发区', + 340191: '经济技术开发区', + 340202: '镜湖区', + 340203: '弋江区', + 340207: '鸠江区', + 340208: '三山区', + 340221: '芜湖县', + 340222: '繁昌县', + 340223: '南陵县', + 340225: '无为县', + 340302: '龙子湖区', + 340303: '蚌山区', + 340304: '禹会区', + 340311: '淮上区', + 340321: '怀远县', + 340322: '五河县', + 340323: '固镇县', + 340402: '大通区', + 340403: '田家庵区', + 340404: '谢家集区', + 340405: '八公山区', + 340406: '潘集区', + 340421: '凤台县', + 340422: '寿县', + 340503: '花山区', + 340504: '雨山区', + 340506: '博望区', + 340521: '当涂县', + 340522: '含山县', + 340523: '和县', + 340602: '杜集区', + 340603: '相山区', + 340604: '烈山区', + 340621: '濉溪县', + 340705: '铜官区', + 340706: '义安区', + 340711: '郊区', + 340722: '枞阳县', + 340802: '迎江区', + 340803: '大观区', + 340811: '宜秀区', + 340822: '怀宁县', + 340824: '潜山县', + 340825: '太湖县', + 340826: '宿松县', + 340827: '望江县', + 340828: '岳西县', + 340881: '桐城市', + 341002: '屯溪区', + 341003: '黄山区', + 341004: '徽州区', + 341021: '歙县', + 341022: '休宁县', + 341023: '黟县', + 341024: '祁门县', + 341102: '琅琊区', + 341103: '南谯区', + 341122: '来安县', + 341124: '全椒县', + 341125: '定远县', + 341126: '凤阳县', + 341181: '天长市', + 341182: '明光市', + 341202: '颍州区', + 341203: '颍东区', + 341204: '颍泉区', + 341221: '临泉县', + 341222: '太和县', + 341225: '阜南县', + 341226: '颍上县', + 341282: '界首市', + 341302: '埇桥区', + 341321: '砀山县', + 341322: '萧县', + 341323: '灵璧县', + 341324: '泗县', + 341390: '经济开发区', + 341502: '金安区', + 341503: '裕安区', + 341504: '叶集区', + 341522: '霍邱县', + 341523: '舒城县', + 341524: '金寨县', + 341525: '霍山县', + 341602: '谯城区', + 341621: '涡阳县', + 341622: '蒙城县', + 341623: '利辛县', + 341702: '贵池区', + 341721: '东至县', + 341722: '石台县', + 341723: '青阳县', + 341802: '宣州区', + 341821: '郎溪县', + 341822: '广德县', + 341823: '泾县', + 341824: '绩溪县', + 341825: '旌德县', + 341881: '宁国市', + 350102: '鼓楼区', + 350103: '台江区', + 350104: '仓山区', + 350105: '马尾区', + 350111: '晋安区', + 350112: '长乐区', + 350121: '闽侯县', + 350122: '连江县', + 350123: '罗源县', + 350124: '闽清县', + 350125: '永泰县', + 350128: '平潭县', + 350181: '福清市', + 350203: '思明区', + 350205: '海沧区', + 350206: '湖里区', + 350211: '集美区', + 350212: '同安区', + 350213: '翔安区', + 350302: '城厢区', + 350303: '涵江区', + 350304: '荔城区', + 350305: '秀屿区', + 350322: '仙游县', + 350402: '梅列区', + 350403: '三元区', + 350421: '明溪县', + 350423: '清流县', + 350424: '宁化县', + 350425: '大田县', + 350426: '尤溪县', + 350427: '沙县', + 350428: '将乐县', + 350429: '泰宁县', + 350430: '建宁县', + 350481: '永安市', + 350502: '鲤城区', + 350503: '丰泽区', + 350504: '洛江区', + 350505: '泉港区', + 350521: '惠安县', + 350524: '安溪县', + 350525: '永春县', + 350526: '德化县', + 350527: '金门县', + 350581: '石狮市', + 350582: '晋江市', + 350583: '南安市', + 350602: '芗城区', + 350603: '龙文区', + 350622: '云霄县', + 350623: '漳浦县', + 350624: '诏安县', + 350625: '长泰县', + 350626: '东山县', + 350627: '南靖县', + 350628: '平和县', + 350629: '华安县', + 350681: '龙海市', + 350702: '延平区', + 350703: '建阳区', + 350721: '顺昌县', + 350722: '浦城县', + 350723: '光泽县', + 350724: '松溪县', + 350725: '政和县', + 350781: '邵武市', + 350782: '武夷山市', + 350783: '建瓯市', + 350802: '新罗区', + 350803: '永定区', + 350821: '长汀县', + 350823: '上杭县', + 350824: '武平县', + 350825: '连城县', + 350881: '漳平市', + 350902: '蕉城区', + 350921: '霞浦县', + 350922: '古田县', + 350923: '屏南县', + 350924: '寿宁县', + 350925: '周宁县', + 350926: '柘荣县', + 350981: '福安市', + 350982: '福鼎市', + 360102: '东湖区', + 360103: '西湖区', + 360104: '青云谱区', + 360105: '湾里区', + 360111: '青山湖区', + 360112: '新建区', + 360121: '南昌县', + 360123: '安义县', + 360124: '进贤县', + 360190: '经济技术开发区', + 360192: '高新区', + 360202: '昌江区', + 360203: '珠山区', + 360222: '浮梁县', + 360281: '乐平市', + 360302: '安源区', + 360313: '湘东区', + 360321: '莲花县', + 360322: '上栗县', + 360323: '芦溪县', + 360402: '濂溪区', + 360403: '浔阳区', + 360404: '柴桑区', + 360423: '武宁县', + 360424: '修水县', + 360425: '永修县', + 360426: '德安县', + 360428: '都昌县', + 360429: '湖口县', + 360430: '彭泽县', + 360481: '瑞昌市', + 360482: '共青城市', + 360483: '庐山市', + 360490: '经济技术开发区', + 360502: '渝水区', + 360521: '分宜县', + 360602: '月湖区', + 360603: '余江区', + 360681: '贵溪市', + 360702: '章贡区', + 360703: '南康区', + 360704: '赣县区', + 360722: '信丰县', + 360723: '大余县', + 360724: '上犹县', + 360725: '崇义县', + 360726: '安远县', + 360727: '龙南县', + 360728: '定南县', + 360729: '全南县', + 360730: '宁都县', + 360731: '于都县', + 360732: '兴国县', + 360733: '会昌县', + 360734: '寻乌县', + 360735: '石城县', + 360781: '瑞金市', + 360802: '吉州区', + 360803: '青原区', + 360821: '吉安县', + 360822: '吉水县', + 360823: '峡江县', + 360824: '新干县', + 360825: '永丰县', + 360826: '泰和县', + 360827: '遂川县', + 360828: '万安县', + 360829: '安福县', + 360830: '永新县', + 360881: '井冈山市', + 360902: '袁州区', + 360921: '奉新县', + 360922: '万载县', + 360923: '上高县', + 360924: '宜丰县', + 360925: '靖安县', + 360926: '铜鼓县', + 360981: '丰城市', + 360982: '樟树市', + 360983: '高安市', + 361002: '临川区', + 361003: '东乡区', + 361021: '南城县', + 361022: '黎川县', + 361023: '南丰县', + 361024: '崇仁县', + 361025: '乐安县', + 361026: '宜黄县', + 361027: '金溪县', + 361028: '资溪县', + 361030: '广昌县', + 361102: '信州区', + 361103: '广丰区', + 361121: '上饶县', + 361123: '玉山县', + 361124: '铅山县', + 361125: '横峰县', + 361126: '弋阳县', + 361127: '余干县', + 361128: '鄱阳县', + 361129: '万年县', + 361130: '婺源县', + 361181: '德兴市', + 370102: '历下区', + 370103: '市中区', + 370104: '槐荫区', + 370105: '天桥区', + 370112: '历城区', + 370113: '长清区', + 370114: '章丘区', + 370115: '济阳区', + 370116: '莱芜区', + 370117: '钢城区', + 370124: '平阴县', + 370126: '商河县', + 370190: '高新区', + 370202: '市南区', + 370203: '市北区', + 370211: '黄岛区', + 370212: '崂山区', + 370213: '李沧区', + 370214: '城阳区', + 370215: '即墨区', + 370281: '胶州市', + 370283: '平度市', + 370285: '莱西市', + 370290: '开发区', + 370302: '淄川区', + 370303: '张店区', + 370304: '博山区', + 370305: '临淄区', + 370306: '周村区', + 370321: '桓台县', + 370322: '高青县', + 370323: '沂源县', + 370402: '市中区', + 370403: '薛城区', + 370404: '峄城区', + 370405: '台儿庄区', + 370406: '山亭区', + 370481: '滕州市', + 370502: '东营区', + 370503: '河口区', + 370505: '垦利区', + 370522: '利津县', + 370523: '广饶县', + 370602: '芝罘区', + 370611: '福山区', + 370612: '牟平区', + 370613: '莱山区', + 370634: '长岛县', + 370681: '龙口市', + 370682: '莱阳市', + 370683: '莱州市', + 370684: '蓬莱市', + 370685: '招远市', + 370686: '栖霞市', + 370687: '海阳市', + 370690: '开发区', + 370702: '潍城区', + 370703: '寒亭区', + 370704: '坊子区', + 370705: '奎文区', + 370724: '临朐县', + 370725: '昌乐县', + 370781: '青州市', + 370782: '诸城市', + 370783: '寿光市', + 370784: '安丘市', + 370785: '高密市', + 370786: '昌邑市', + 370790: '开发区', + 370791: '高新区', + 370811: '任城区', + 370812: '兖州区', + 370826: '微山县', + 370827: '鱼台县', + 370828: '金乡县', + 370829: '嘉祥县', + 370830: '汶上县', + 370831: '泗水县', + 370832: '梁山县', + 370881: '曲阜市', + 370883: '邹城市', + 370890: '高新区', + 370902: '泰山区', + 370911: '岱岳区', + 370921: '宁阳县', + 370923: '东平县', + 370982: '新泰市', + 370983: '肥城市', + 371002: '环翠区', + 371003: '文登区', + 371082: '荣成市', + 371083: '乳山市', + 371091: '经济技术开发区', + 371102: '东港区', + 371103: '岚山区', + 371121: '五莲县', + 371122: '莒县', + 371302: '兰山区', + 371311: '罗庄区', + 371312: '河东区', + 371321: '沂南县', + 371322: '郯城县', + 371323: '沂水县', + 371324: '兰陵县', + 371325: '费县', + 371326: '平邑县', + 371327: '莒南县', + 371328: '蒙阴县', + 371329: '临沭县', + 371402: '德城区', + 371403: '陵城区', + 371422: '宁津县', + 371423: '庆云县', + 371424: '临邑县', + 371425: '齐河县', + 371426: '平原县', + 371427: '夏津县', + 371428: '武城县', + 371481: '乐陵市', + 371482: '禹城市', + 371502: '东昌府区', + 371521: '阳谷县', + 371522: '莘县', + 371523: '茌平县', + 371524: '东阿县', + 371525: '冠县', + 371526: '高唐县', + 371581: '临清市', + 371602: '滨城区', + 371603: '沾化区', + 371621: '惠民县', + 371622: '阳信县', + 371623: '无棣县', + 371625: '博兴县', + 371681: '邹平市', + 371702: '牡丹区', + 371703: '定陶区', + 371721: '曹县', + 371722: '单县', + 371723: '成武县', + 371724: '巨野县', + 371725: '郓城县', + 371726: '鄄城县', + 371728: '东明县', + 410102: '中原区', + 410103: '二七区', + 410104: '管城回族区', + 410105: '金水区', + 410106: '上街区', + 410108: '惠济区', + 410122: '中牟县', + 410181: '巩义市', + 410182: '荥阳市', + 410183: '新密市', + 410184: '新郑市', + 410185: '登封市', + 410190: '高新技术开发区', + 410191: '经济技术开发区', + 410202: '龙亭区', + 410203: '顺河回族区', + 410204: '鼓楼区', + 410205: '禹王台区', + 410212: '祥符区', + 410221: '杞县', + 410222: '通许县', + 410223: '尉氏县', + 410225: '兰考县', + 410302: '老城区', + 410303: '西工区', + 410304: '瀍河回族区', + 410305: '涧西区', + 410306: '吉利区', + 410311: '洛龙区', + 410322: '孟津县', + 410323: '新安县', + 410324: '栾川县', + 410325: '嵩县', + 410326: '汝阳县', + 410327: '宜阳县', + 410328: '洛宁县', + 410329: '伊川县', + 410381: '偃师市', + 410402: '新华区', + 410403: '卫东区', + 410404: '石龙区', + 410411: '湛河区', + 410421: '宝丰县', + 410422: '叶县', + 410423: '鲁山县', + 410425: '郏县', + 410481: '舞钢市', + 410482: '汝州市', + 410502: '文峰区', + 410503: '北关区', + 410505: '殷都区', + 410506: '龙安区', + 410522: '安阳县', + 410523: '汤阴县', + 410526: '滑县', + 410527: '内黄县', + 410581: '林州市', + 410590: '开发区', + 410602: '鹤山区', + 410603: '山城区', + 410611: '淇滨区', + 410621: '浚县', + 410622: '淇县', + 410702: '红旗区', + 410703: '卫滨区', + 410704: '凤泉区', + 410711: '牧野区', + 410721: '新乡县', + 410724: '获嘉县', + 410725: '原阳县', + 410726: '延津县', + 410727: '封丘县', + 410728: '长垣县', + 410781: '卫辉市', + 410782: '辉县市', + 410802: '解放区', + 410803: '中站区', + 410804: '马村区', + 410811: '山阳区', + 410821: '修武县', + 410822: '博爱县', + 410823: '武陟县', + 410825: '温县', + 410882: '沁阳市', + 410883: '孟州市', + 410902: '华龙区', + 410922: '清丰县', + 410923: '南乐县', + 410926: '范县', + 410927: '台前县', + 410928: '濮阳县', + 411002: '魏都区', + 411003: '建安区', + 411024: '鄢陵县', + 411025: '襄城县', + 411081: '禹州市', + 411082: '长葛市', + 411102: '源汇区', + 411103: '郾城区', + 411104: '召陵区', + 411121: '舞阳县', + 411122: '临颍县', + 411202: '湖滨区', + 411203: '陕州区', + 411221: '渑池县', + 411224: '卢氏县', + 411281: '义马市', + 411282: '灵宝市', + 411302: '宛城区', + 411303: '卧龙区', + 411321: '南召县', + 411322: '方城县', + 411323: '西峡县', + 411324: '镇平县', + 411325: '内乡县', + 411326: '淅川县', + 411327: '社旗县', + 411328: '唐河县', + 411329: '新野县', + 411330: '桐柏县', + 411381: '邓州市', + 411402: '梁园区', + 411403: '睢阳区', + 411421: '民权县', + 411422: '睢县', + 411423: '宁陵县', + 411424: '柘城县', + 411425: '虞城县', + 411426: '夏邑县', + 411481: '永城市', + 411502: '浉河区', + 411503: '平桥区', + 411521: '罗山县', + 411522: '光山县', + 411523: '新县', + 411524: '商城县', + 411525: '固始县', + 411526: '潢川县', + 411527: '淮滨县', + 411528: '息县', + 411602: '川汇区', + 411621: '扶沟县', + 411622: '西华县', + 411623: '商水县', + 411624: '沈丘县', + 411625: '郸城县', + 411626: '淮阳县', + 411627: '太康县', + 411628: '鹿邑县', + 411681: '项城市', + 411690: '经济开发区', + 411702: '驿城区', + 411721: '西平县', + 411722: '上蔡县', + 411723: '平舆县', + 411724: '正阳县', + 411725: '确山县', + 411726: '泌阳县', + 411727: '汝南县', + 411728: '遂平县', + 411729: '新蔡县', + 419001: '济源市', + 420102: '江岸区', + 420103: '江汉区', + 420104: '硚口区', + 420105: '汉阳区', + 420106: '武昌区', + 420107: '青山区', + 420111: '洪山区', + 420112: '东西湖区', + 420113: '汉南区', + 420114: '蔡甸区', + 420115: '江夏区', + 420116: '黄陂区', + 420117: '新洲区', + 420202: '黄石港区', + 420203: '西塞山区', + 420204: '下陆区', + 420205: '铁山区', + 420222: '阳新县', + 420281: '大冶市', + 420302: '茅箭区', + 420303: '张湾区', + 420304: '郧阳区', + 420322: '郧西县', + 420323: '竹山县', + 420324: '竹溪县', + 420325: '房县', + 420381: '丹江口市', + 420502: '西陵区', + 420503: '伍家岗区', + 420504: '点军区', + 420505: '猇亭区', + 420506: '夷陵区', + 420525: '远安县', + 420526: '兴山县', + 420527: '秭归县', + 420528: '长阳土家族自治县', + 420529: '五峰土家族自治县', + 420581: '宜都市', + 420582: '当阳市', + 420583: '枝江市', + 420590: '经济开发区', + 420602: '襄城区', + 420606: '樊城区', + 420607: '襄州区', + 420624: '南漳县', + 420625: '谷城县', + 420626: '保康县', + 420682: '老河口市', + 420683: '枣阳市', + 420684: '宜城市', + 420702: '梁子湖区', + 420703: '华容区', + 420704: '鄂城区', + 420802: '东宝区', + 420804: '掇刀区', + 420822: '沙洋县', + 420881: '钟祥市', + 420882: '京山市', + 420902: '孝南区', + 420921: '孝昌县', + 420922: '大悟县', + 420923: '云梦县', + 420981: '应城市', + 420982: '安陆市', + 420984: '汉川市', + 421002: '沙市区', + 421003: '荆州区', + 421022: '公安县', + 421023: '监利县', + 421024: '江陵县', + 421081: '石首市', + 421083: '洪湖市', + 421087: '松滋市', + 421102: '黄州区', + 421121: '团风县', + 421122: '红安县', + 421123: '罗田县', + 421124: '英山县', + 421125: '浠水县', + 421126: '蕲春县', + 421127: '黄梅县', + 421181: '麻城市', + 421182: '武穴市', + 421202: '咸安区', + 421221: '嘉鱼县', + 421222: '通城县', + 421223: '崇阳县', + 421224: '通山县', + 421281: '赤壁市', + 421303: '曾都区', + 421321: '随县', + 421381: '广水市', + 422801: '恩施市', + 422802: '利川市', + 422822: '建始县', + 422823: '巴东县', + 422825: '宣恩县', + 422826: '咸丰县', + 422827: '来凤县', + 422828: '鹤峰县', + 429004: '仙桃市', + 429005: '潜江市', + 429006: '天门市', + 429021: '神农架林区', + 430102: '芙蓉区', + 430103: '天心区', + 430104: '岳麓区', + 430105: '开福区', + 430111: '雨花区', + 430112: '望城区', + 430121: '长沙县', + 430181: '浏阳市', + 430182: '宁乡市', + 430202: '荷塘区', + 430203: '芦淞区', + 430204: '石峰区', + 430211: '天元区', + 430212: '渌口区', + 430223: '攸县', + 430224: '茶陵县', + 430225: '炎陵县', + 430281: '醴陵市', + 430302: '雨湖区', + 430304: '岳塘区', + 430321: '湘潭县', + 430381: '湘乡市', + 430382: '韶山市', + 430405: '珠晖区', + 430406: '雁峰区', + 430407: '石鼓区', + 430408: '蒸湘区', + 430412: '南岳区', + 430421: '衡阳县', + 430422: '衡南县', + 430423: '衡山县', + 430424: '衡东县', + 430426: '祁东县', + 430481: '耒阳市', + 430482: '常宁市', + 430502: '双清区', + 430503: '大祥区', + 430511: '北塔区', + 430521: '邵东县', + 430522: '新邵县', + 430523: '邵阳县', + 430524: '隆回县', + 430525: '洞口县', + 430527: '绥宁县', + 430528: '新宁县', + 430529: '城步苗族自治县', + 430581: '武冈市', + 430602: '岳阳楼区', + 430603: '云溪区', + 430611: '君山区', + 430621: '岳阳县', + 430623: '华容县', + 430624: '湘阴县', + 430626: '平江县', + 430681: '汨罗市', + 430682: '临湘市', + 430702: '武陵区', + 430703: '鼎城区', + 430721: '安乡县', + 430722: '汉寿县', + 430723: '澧县', + 430724: '临澧县', + 430725: '桃源县', + 430726: '石门县', + 430781: '津市市', + 430802: '永定区', + 430811: '武陵源区', + 430821: '慈利县', + 430822: '桑植县', + 430902: '资阳区', + 430903: '赫山区', + 430921: '南县', + 430922: '桃江县', + 430923: '安化县', + 430981: '沅江市', + 431002: '北湖区', + 431003: '苏仙区', + 431021: '桂阳县', + 431022: '宜章县', + 431023: '永兴县', + 431024: '嘉禾县', + 431025: '临武县', + 431026: '汝城县', + 431027: '桂东县', + 431028: '安仁县', + 431081: '资兴市', + 431102: '零陵区', + 431103: '冷水滩区', + 431121: '祁阳县', + 431122: '东安县', + 431123: '双牌县', + 431124: '道县', + 431125: '江永县', + 431126: '宁远县', + 431127: '蓝山县', + 431128: '新田县', + 431129: '江华瑶族自治县', + 431202: '鹤城区', + 431221: '中方县', + 431222: '沅陵县', + 431223: '辰溪县', + 431224: '溆浦县', + 431225: '会同县', + 431226: '麻阳苗族自治县', + 431227: '新晃侗族自治县', + 431228: '芷江侗族自治县', + 431229: '靖州苗族侗族自治县', + 431230: '通道侗族自治县', + 431281: '洪江市', + 431302: '娄星区', + 431321: '双峰县', + 431322: '新化县', + 431381: '冷水江市', + 431382: '涟源市', + 433101: '吉首市', + 433122: '泸溪县', + 433123: '凤凰县', + 433124: '花垣县', + 433125: '保靖县', + 433126: '古丈县', + 433127: '永顺县', + 433130: '龙山县', + 440103: '荔湾区', + 440104: '越秀区', + 440105: '海珠区', + 440106: '天河区', + 440111: '白云区', + 440112: '黄埔区', + 440113: '番禺区', + 440114: '花都区', + 440115: '南沙区', + 440117: '从化区', + 440118: '增城区', + 440203: '武江区', + 440204: '浈江区', + 440205: '曲江区', + 440222: '始兴县', + 440224: '仁化县', + 440229: '翁源县', + 440232: '乳源瑶族自治县', + 440233: '新丰县', + 440281: '乐昌市', + 440282: '南雄市', + 440303: '罗湖区', + 440304: '福田区', + 440305: '南山区', + 440306: '宝安区', + 440307: '龙岗区', + 440308: '盐田区', + 440309: '龙华区', + 440310: '坪山区', + 440311: '光明区', + 440402: '香洲区', + 440403: '斗门区', + 440404: '金湾区', + 440507: '龙湖区', + 440511: '金平区', + 440512: '濠江区', + 440513: '潮阳区', + 440514: '潮南区', + 440515: '澄海区', + 440523: '南澳县', + 440604: '禅城区', + 440605: '南海区', + 440606: '顺德区', + 440607: '三水区', + 440608: '高明区', + 440703: '蓬江区', + 440704: '江海区', + 440705: '新会区', + 440781: '台山市', + 440783: '开平市', + 440784: '鹤山市', + 440785: '恩平市', + 440802: '赤坎区', + 440803: '霞山区', + 440804: '坡头区', + 440811: '麻章区', + 440823: '遂溪县', + 440825: '徐闻县', + 440881: '廉江市', + 440882: '雷州市', + 440883: '吴川市', + 440890: '经济技术开发区', + 440902: '茂南区', + 440904: '电白区', + 440981: '高州市', + 440982: '化州市', + 440983: '信宜市', + 441202: '端州区', + 441203: '鼎湖区', + 441204: '高要区', + 441223: '广宁县', + 441224: '怀集县', + 441225: '封开县', + 441226: '德庆县', + 441284: '四会市', + 441302: '惠城区', + 441303: '惠阳区', + 441322: '博罗县', + 441323: '惠东县', + 441324: '龙门县', + 441402: '梅江区', + 441403: '梅县区', + 441422: '大埔县', + 441423: '丰顺县', + 441424: '五华县', + 441426: '平远县', + 441427: '蕉岭县', + 441481: '兴宁市', + 441502: '城区', + 441521: '海丰县', + 441523: '陆河县', + 441581: '陆丰市', + 441602: '源城区', + 441621: '紫金县', + 441622: '龙川县', + 441623: '连平县', + 441624: '和平县', + 441625: '东源县', + 441702: '江城区', + 441704: '阳东区', + 441721: '阳西县', + 441781: '阳春市', + 441802: '清城区', + 441803: '清新区', + 441821: '佛冈县', + 441823: '阳山县', + 441825: '连山壮族瑶族自治县', + 441826: '连南瑶族自治县', + 441881: '英德市', + 441882: '连州市', + 441901: '中堂镇', + 441903: '南城街道办事处', + 441904: '长安镇', + 441905: '东坑镇', + 441906: '樟木头镇', + 441907: '莞城街道办事处', + 441908: '石龙镇', + 441909: '桥头镇', + 441910: '万江街道办事处', + 441911: '麻涌镇', + 441912: '虎门镇', + 441913: '谢岗镇', + 441914: '石碣镇', + 441915: '茶山镇', + 441916: '东城街道办事处', + 441917: '洪梅镇', + 441918: '道滘镇', + 441919: '高埗镇', + 441920: '企石镇', + 441921: '凤岗镇', + 441922: '大岭山镇', + 441923: '松山湖管委会', + 441924: '清溪镇', + 441925: '望牛墩镇', + 441926: '厚街镇', + 441927: '常平镇', + 441928: '寮步镇', + 441929: '石排镇', + 441930: '横沥镇', + 441931: '塘厦镇', + 441932: '黄江镇', + 441933: '大朗镇', + 441934: '东莞港', + 441935: '东莞生态园', + 441990: '沙田镇', + 442001: '南头镇', + 442002: '神湾镇', + 442003: '东凤镇', + 442004: '五桂山街道办事处', + 442005: '黄圃镇', + 442006: '小榄镇', + 442007: '石岐区街道办事处', + 442008: '横栏镇', + 442009: '三角镇', + 442010: '三乡镇', + 442011: '港口镇', + 442012: '沙溪镇', + 442013: '板芙镇', + 442015: '东升镇', + 442016: '阜沙镇', + 442017: '民众镇', + 442018: '东区街道办事处', + 442019: '火炬开发区街道办事处', + 442020: '西区街道办事处', + 442021: '南区街道办事处', + 442022: '古镇镇', + 442023: '坦洲镇', + 442024: '大涌镇', + 442025: '南朗镇', + 445102: '湘桥区', + 445103: '潮安区', + 445122: '饶平县', + 445202: '榕城区', + 445203: '揭东区', + 445222: '揭西县', + 445224: '惠来县', + 445281: '普宁市', + 445302: '云城区', + 445303: '云安区', + 445321: '新兴县', + 445322: '郁南县', + 445381: '罗定市', + 450102: '兴宁区', + 450103: '青秀区', + 450105: '江南区', + 450107: '西乡塘区', + 450108: '良庆区', + 450109: '邕宁区', + 450110: '武鸣区', + 450123: '隆安县', + 450124: '马山县', + 450125: '上林县', + 450126: '宾阳县', + 450127: '横县', + 450202: '城中区', + 450203: '鱼峰区', + 450204: '柳南区', + 450205: '柳北区', + 450206: '柳江区', + 450222: '柳城县', + 450223: '鹿寨县', + 450224: '融安县', + 450225: '融水苗族自治县', + 450226: '三江侗族自治县', + 450302: '秀峰区', + 450303: '叠彩区', + 450304: '象山区', + 450305: '七星区', + 450311: '雁山区', + 450312: '临桂区', + 450321: '阳朔县', + 450323: '灵川县', + 450324: '全州县', + 450325: '兴安县', + 450326: '永福县', + 450327: '灌阳县', + 450328: '龙胜各族自治县', + 450329: '资源县', + 450330: '平乐县', + 450332: '恭城瑶族自治县', + 450381: '荔浦市', + 450403: '万秀区', + 450405: '长洲区', + 450406: '龙圩区', + 450421: '苍梧县', + 450422: '藤县', + 450423: '蒙山县', + 450481: '岑溪市', + 450502: '海城区', + 450503: '银海区', + 450512: '铁山港区', + 450521: '合浦县', + 450602: '港口区', + 450603: '防城区', + 450621: '上思县', + 450681: '东兴市', + 450702: '钦南区', + 450703: '钦北区', + 450721: '灵山县', + 450722: '浦北县', + 450802: '港北区', + 450803: '港南区', + 450804: '覃塘区', + 450821: '平南县', + 450881: '桂平市', + 450902: '玉州区', + 450903: '福绵区', + 450921: '容县', + 450922: '陆川县', + 450923: '博白县', + 450924: '兴业县', + 450981: '北流市', + 451002: '右江区', + 451021: '田阳县', + 451022: '田东县', + 451023: '平果县', + 451024: '德保县', + 451026: '那坡县', + 451027: '凌云县', + 451028: '乐业县', + 451029: '田林县', + 451030: '西林县', + 451031: '隆林各族自治县', + 451081: '靖西市', + 451102: '八步区', + 451103: '平桂区', + 451121: '昭平县', + 451122: '钟山县', + 451123: '富川瑶族自治县', + 451202: '金城江区', + 451203: '宜州区', + 451221: '南丹县', + 451222: '天峨县', + 451223: '凤山县', + 451224: '东兰县', + 451225: '罗城仫佬族自治县', + 451226: '环江毛南族自治县', + 451227: '巴马瑶族自治县', + 451228: '都安瑶族自治县', + 451229: '大化瑶族自治县', + 451302: '兴宾区', + 451321: '忻城县', + 451322: '象州县', + 451323: '武宣县', + 451324: '金秀瑶族自治县', + 451381: '合山市', + 451402: '江州区', + 451421: '扶绥县', + 451422: '宁明县', + 451423: '龙州县', + 451424: '大新县', + 451425: '天等县', + 451481: '凭祥市', + 460105: '秀英区', + 460106: '龙华区', + 460107: '琼山区', + 460108: '美兰区', + 460202: '海棠区', + 460203: '吉阳区', + 460204: '天涯区', + 460205: '崖州区', + 460321: '西沙群岛', + 460322: '南沙群岛', + 460323: '中沙群岛的岛礁及其海域', + 460401: '那大镇', + 460402: '和庆镇', + 460403: '南丰镇', + 460404: '大成镇', + 460405: '雅星镇', + 460406: '兰洋镇', + 460407: '光村镇', + 460408: '木棠镇', + 460409: '海头镇', + 460410: '峨蔓镇', + 460411: '王五镇', + 460412: '白马井镇', + 460413: '中和镇', + 460414: '排浦镇', + 460415: '东成镇', + 460416: '新州镇', + 460417: '洋浦经济开发区', + 460418: '华南热作学院', + 469001: '五指山市', + 469002: '琼海市', + 469005: '文昌市', + 469006: '万宁市', + 469007: '东方市', + 469021: '定安县', + 469022: '屯昌县', + 469023: '澄迈县', + 469024: '临高县', + 469025: '白沙黎族自治县', + 469026: '昌江黎族自治县', + 469027: '乐东黎族自治县', + 469028: '陵水黎族自治县', + 469029: '保亭黎族苗族自治县', + 469030: '琼中黎族苗族自治县', + 500101: '万州区', + 500102: '涪陵区', + 500103: '渝中区', + 500104: '大渡口区', + 500105: '江北区', + 500106: '沙坪坝区', + 500107: '九龙坡区', + 500108: '南岸区', + 500109: '北碚区', + 500110: '綦江区', + 500111: '大足区', + 500112: '渝北区', + 500113: '巴南区', + 500114: '黔江区', + 500115: '长寿区', + 500116: '江津区', + 500117: '合川区', + 500118: '永川区', + 500119: '南川区', + 500120: '璧山区', + 500151: '铜梁区', + 500152: '潼南区', + 500153: '荣昌区', + 500154: '开州区', + 500155: '梁平区', + 500156: '武隆区', + 500229: '城口县', + 500230: '丰都县', + 500231: '垫江县', + 500233: '忠县', + 500235: '云阳县', + 500236: '奉节县', + 500237: '巫山县', + 500238: '巫溪县', + 500240: '石柱土家族自治县', + 500241: '秀山土家族苗族自治县', + 500242: '酉阳土家族苗族自治县', + 500243: '彭水苗族土家族自治县', + 510104: '锦江区', + 510105: '青羊区', + 510106: '金牛区', + 510107: '武侯区', + 510108: '成华区', + 510112: '龙泉驿区', + 510113: '青白江区', + 510114: '新都区', + 510115: '温江区', + 510116: '双流区', + 510117: '郫都区', + 510121: '金堂县', + 510129: '大邑县', + 510131: '蒲江县', + 510132: '新津县', + 510181: '都江堰市', + 510182: '彭州市', + 510183: '邛崃市', + 510184: '崇州市', + 510185: '简阳市', + 510191: '高新区', + 510302: '自流井区', + 510303: '贡井区', + 510304: '大安区', + 510311: '沿滩区', + 510321: '荣县', + 510322: '富顺县', + 510402: '东区', + 510403: '西区', + 510411: '仁和区', + 510421: '米易县', + 510422: '盐边县', + 510502: '江阳区', + 510503: '纳溪区', + 510504: '龙马潭区', + 510521: '泸县', + 510522: '合江县', + 510524: '叙永县', + 510525: '古蔺县', + 510603: '旌阳区', + 510604: '罗江区', + 510623: '中江县', + 510681: '广汉市', + 510682: '什邡市', + 510683: '绵竹市', + 510703: '涪城区', + 510704: '游仙区', + 510705: '安州区', + 510722: '三台县', + 510723: '盐亭县', + 510725: '梓潼县', + 510726: '北川羌族自治县', + 510727: '平武县', + 510781: '江油市', + 510791: '高新区', + 510802: '利州区', + 510811: '昭化区', + 510812: '朝天区', + 510821: '旺苍县', + 510822: '青川县', + 510823: '剑阁县', + 510824: '苍溪县', + 510903: '船山区', + 510904: '安居区', + 510921: '蓬溪县', + 510922: '射洪县', + 510923: '大英县', + 511002: '市中区', + 511011: '东兴区', + 511024: '威远县', + 511025: '资中县', + 511083: '隆昌市', + 511102: '市中区', + 511111: '沙湾区', + 511112: '五通桥区', + 511113: '金口河区', + 511123: '犍为县', + 511124: '井研县', + 511126: '夹江县', + 511129: '沐川县', + 511132: '峨边彝族自治县', + 511133: '马边彝族自治县', + 511181: '峨眉山市', + 511302: '顺庆区', + 511303: '高坪区', + 511304: '嘉陵区', + 511321: '南部县', + 511322: '营山县', + 511323: '蓬安县', + 511324: '仪陇县', + 511325: '西充县', + 511381: '阆中市', + 511402: '东坡区', + 511403: '彭山区', + 511421: '仁寿县', + 511423: '洪雅县', + 511424: '丹棱县', + 511425: '青神县', + 511502: '翠屏区', + 511503: '南溪区', + 511504: '叙州区', + 511523: '江安县', + 511524: '长宁县', + 511525: '高县', + 511526: '珙县', + 511527: '筠连县', + 511528: '兴文县', + 511529: '屏山县', + 511602: '广安区', + 511603: '前锋区', + 511621: '岳池县', + 511622: '武胜县', + 511623: '邻水县', + 511681: '华蓥市', + 511702: '通川区', + 511703: '达川区', + 511722: '宣汉县', + 511723: '开江县', + 511724: '大竹县', + 511725: '渠县', + 511781: '万源市', + 511802: '雨城区', + 511803: '名山区', + 511822: '荥经县', + 511823: '汉源县', + 511824: '石棉县', + 511825: '天全县', + 511826: '芦山县', + 511827: '宝兴县', + 511902: '巴州区', + 511903: '恩阳区', + 511921: '通江县', + 511922: '南江县', + 511923: '平昌县', + 512002: '雁江区', + 512021: '安岳县', + 512022: '乐至县', + 513201: '马尔康市', + 513221: '汶川县', + 513222: '理县', + 513223: '茂县', + 513224: '松潘县', + 513225: '九寨沟县', + 513226: '金川县', + 513227: '小金县', + 513228: '黑水县', + 513230: '壤塘县', + 513231: '阿坝县', + 513232: '若尔盖县', + 513233: '红原县', + 513301: '康定市', + 513322: '泸定县', + 513323: '丹巴县', + 513324: '九龙县', + 513325: '雅江县', + 513326: '道孚县', + 513327: '炉霍县', + 513328: '甘孜县', + 513329: '新龙县', + 513330: '德格县', + 513331: '白玉县', + 513332: '石渠县', + 513333: '色达县', + 513334: '理塘县', + 513335: '巴塘县', + 513336: '乡城县', + 513337: '稻城县', + 513338: '得荣县', + 513401: '西昌市', + 513422: '木里藏族自治县', + 513423: '盐源县', + 513424: '德昌县', + 513425: '会理县', + 513426: '会东县', + 513427: '宁南县', + 513428: '普格县', + 513429: '布拖县', + 513430: '金阳县', + 513431: '昭觉县', + 513432: '喜德县', + 513433: '冕宁县', + 513434: '越西县', + 513435: '甘洛县', + 513436: '美姑县', + 513437: '雷波县', + 520102: '南明区', + 520103: '云岩区', + 520111: '花溪区', + 520112: '乌当区', + 520113: '白云区', + 520115: '观山湖区', + 520121: '开阳县', + 520122: '息烽县', + 520123: '修文县', + 520181: '清镇市', + 520201: '钟山区', + 520203: '六枝特区', + 520221: '水城县', + 520281: '盘州市', + 520302: '红花岗区', + 520303: '汇川区', + 520304: '播州区', + 520322: '桐梓县', + 520323: '绥阳县', + 520324: '正安县', + 520325: '道真仡佬族苗族自治县', + 520326: '务川仡佬族苗族自治县', + 520327: '凤冈县', + 520328: '湄潭县', + 520329: '余庆县', + 520330: '习水县', + 520381: '赤水市', + 520382: '仁怀市', + 520402: '西秀区', + 520403: '平坝区', + 520422: '普定县', + 520423: '镇宁布依族苗族自治县', + 520424: '关岭布依族苗族自治县', + 520425: '紫云苗族布依族自治县', + 520502: '七星关区', + 520521: '大方县', + 520522: '黔西县', + 520523: '金沙县', + 520524: '织金县', + 520525: '纳雍县', + 520526: '威宁彝族回族苗族自治县', + 520527: '赫章县', + 520602: '碧江区', + 520603: '万山区', + 520621: '江口县', + 520622: '玉屏侗族自治县', + 520623: '石阡县', + 520624: '思南县', + 520625: '印江土家族苗族自治县', + 520626: '德江县', + 520627: '沿河土家族自治县', + 520628: '松桃苗族自治县', + 522301: '兴义市', + 522302: '兴仁市', + 522323: '普安县', + 522324: '晴隆县', + 522325: '贞丰县', + 522326: '望谟县', + 522327: '册亨县', + 522328: '安龙县', + 522601: '凯里市', + 522622: '黄平县', + 522623: '施秉县', + 522624: '三穗县', + 522625: '镇远县', + 522626: '岑巩县', + 522627: '天柱县', + 522628: '锦屏县', + 522629: '剑河县', + 522630: '台江县', + 522631: '黎平县', + 522632: '榕江县', + 522633: '从江县', + 522634: '雷山县', + 522635: '麻江县', + 522636: '丹寨县', + 522701: '都匀市', + 522702: '福泉市', + 522722: '荔波县', + 522723: '贵定县', + 522725: '瓮安县', + 522726: '独山县', + 522727: '平塘县', + 522728: '罗甸县', + 522729: '长顺县', + 522730: '龙里县', + 522731: '惠水县', + 522732: '三都水族自治县', + 530102: '五华区', + 530103: '盘龙区', + 530111: '官渡区', + 530112: '西山区', + 530113: '东川区', + 530114: '呈贡区', + 530115: '晋宁区', + 530124: '富民县', + 530125: '宜良县', + 530126: '石林彝族自治县', + 530127: '嵩明县', + 530128: '禄劝彝族苗族自治县', + 530129: '寻甸回族彝族自治县', + 530181: '安宁市', + 530302: '麒麟区', + 530303: '沾益区', + 530304: '马龙区', + 530322: '陆良县', + 530323: '师宗县', + 530324: '罗平县', + 530325: '富源县', + 530326: '会泽县', + 530381: '宣威市', + 530402: '红塔区', + 530403: '江川区', + 530422: '澄江县', + 530423: '通海县', + 530424: '华宁县', + 530425: '易门县', + 530426: '峨山彝族自治县', + 530427: '新平彝族傣族自治县', + 530428: '元江哈尼族彝族傣族自治县', + 530502: '隆阳区', + 530521: '施甸县', + 530523: '龙陵县', + 530524: '昌宁县', + 530581: '腾冲市', + 530602: '昭阳区', + 530621: '鲁甸县', + 530622: '巧家县', + 530623: '盐津县', + 530624: '大关县', + 530625: '永善县', + 530626: '绥江县', + 530627: '镇雄县', + 530628: '彝良县', + 530629: '威信县', + 530681: '水富市', + 530702: '古城区', + 530721: '玉龙纳西族自治县', + 530722: '永胜县', + 530723: '华坪县', + 530724: '宁蒗彝族自治县', + 530802: '思茅区', + 530821: '宁洱哈尼族彝族自治县', + 530822: '墨江哈尼族自治县', + 530823: '景东彝族自治县', + 530824: '景谷傣族彝族自治县', + 530825: '镇沅彝族哈尼族拉祜族自治县', + 530826: '江城哈尼族彝族自治县', + 530827: '孟连傣族拉祜族佤族自治县', + 530828: '澜沧拉祜族自治县', + 530829: '西盟佤族自治县', + 530902: '临翔区', + 530921: '凤庆县', + 530922: '云县', + 530923: '永德县', + 530924: '镇康县', + 530925: '双江拉祜族佤族布朗族傣族自治县', + 530926: '耿马傣族佤族自治县', + 530927: '沧源佤族自治县', + 532301: '楚雄市', + 532322: '双柏县', + 532323: '牟定县', + 532324: '南华县', + 532325: '姚安县', + 532326: '大姚县', + 532327: '永仁县', + 532328: '元谋县', + 532329: '武定县', + 532331: '禄丰县', + 532501: '个旧市', + 532502: '开远市', + 532503: '蒙自市', + 532504: '弥勒市', + 532523: '屏边苗族自治县', + 532524: '建水县', + 532525: '石屏县', + 532527: '泸西县', + 532528: '元阳县', + 532529: '红河县', + 532530: '金平苗族瑶族傣族自治县', + 532531: '绿春县', + 532532: '河口瑶族自治县', + 532601: '文山市', + 532622: '砚山县', + 532623: '西畴县', + 532624: '麻栗坡县', + 532625: '马关县', + 532626: '丘北县', + 532627: '广南县', + 532628: '富宁县', + 532801: '景洪市', + 532822: '勐海县', + 532823: '勐腊县', + 532901: '大理市', + 532922: '漾濞彝族自治县', + 532923: '祥云县', + 532924: '宾川县', + 532925: '弥渡县', + 532926: '南涧彝族自治县', + 532927: '巍山彝族回族自治县', + 532928: '永平县', + 532929: '云龙县', + 532930: '洱源县', + 532931: '剑川县', + 532932: '鹤庆县', + 533102: '瑞丽市', + 533103: '芒市', + 533122: '梁河县', + 533123: '盈江县', + 533124: '陇川县', + 533301: '泸水市', + 533323: '福贡县', + 533324: '贡山独龙族怒族自治县', + 533325: '兰坪白族普米族自治县', + 533401: '香格里拉市', + 533422: '德钦县', + 533423: '维西傈僳族自治县', + 540102: '城关区', + 540103: '堆龙德庆区', + 540104: '达孜区', + 540121: '林周县', + 540122: '当雄县', + 540123: '尼木县', + 540124: '曲水县', + 540127: '墨竹工卡县', + 540202: '桑珠孜区', + 540221: '南木林县', + 540222: '江孜县', + 540223: '定日县', + 540224: '萨迦县', + 540225: '拉孜县', + 540226: '昂仁县', + 540227: '谢通门县', + 540228: '白朗县', + 540229: '仁布县', + 540230: '康马县', + 540231: '定结县', + 540232: '仲巴县', + 540233: '亚东县', + 540234: '吉隆县', + 540235: '聂拉木县', + 540236: '萨嘎县', + 540237: '岗巴县', + 540302: '卡若区', + 540321: '江达县', + 540322: '贡觉县', + 540323: '类乌齐县', + 540324: '丁青县', + 540325: '察雅县', + 540326: '八宿县', + 540327: '左贡县', + 540328: '芒康县', + 540329: '洛隆县', + 540330: '边坝县', + 540402: '巴宜区', + 540421: '工布江达县', + 540422: '米林县', + 540423: '墨脱县', + 540424: '波密县', + 540425: '察隅县', + 540426: '朗县', + 540502: '乃东区', + 540521: '扎囊县', + 540522: '贡嘎县', + 540523: '桑日县', + 540524: '琼结县', + 540525: '曲松县', + 540526: '措美县', + 540527: '洛扎县', + 540528: '加查县', + 540529: '隆子县', + 540530: '错那县', + 540531: '浪卡子县', + 540602: '色尼区', + 540621: '嘉黎县', + 540622: '比如县', + 540623: '聂荣县', + 540624: '安多县', + 540625: '申扎县', + 540626: '索县', + 540627: '班戈县', + 540628: '巴青县', + 540629: '尼玛县', + 540630: '双湖县', + 542521: '普兰县', + 542522: '札达县', + 542523: '噶尔县', + 542524: '日土县', + 542525: '革吉县', + 542526: '改则县', + 542527: '措勤县', + 610102: '新城区', + 610103: '碑林区', + 610104: '莲湖区', + 610111: '灞桥区', + 610112: '未央区', + 610113: '雁塔区', + 610114: '阎良区', + 610115: '临潼区', + 610116: '长安区', + 610117: '高陵区', + 610118: '鄠邑区', + 610122: '蓝田县', + 610124: '周至县', + 610202: '王益区', + 610203: '印台区', + 610204: '耀州区', + 610222: '宜君县', + 610302: '渭滨区', + 610303: '金台区', + 610304: '陈仓区', + 610322: '凤翔县', + 610323: '岐山县', + 610324: '扶风县', + 610326: '眉县', + 610327: '陇县', + 610328: '千阳县', + 610329: '麟游县', + 610330: '凤县', + 610331: '太白县', + 610402: '秦都区', + 610403: '杨陵区', + 610404: '渭城区', + 610422: '三原县', + 610423: '泾阳县', + 610424: '乾县', + 610425: '礼泉县', + 610426: '永寿县', + 610428: '长武县', + 610429: '旬邑县', + 610430: '淳化县', + 610431: '武功县', + 610481: '兴平市', + 610482: '彬州市', + 610502: '临渭区', + 610503: '华州区', + 610522: '潼关县', + 610523: '大荔县', + 610524: '合阳县', + 610525: '澄城县', + 610526: '蒲城县', + 610527: '白水县', + 610528: '富平县', + 610581: '韩城市', + 610582: '华阴市', + 610602: '宝塔区', + 610603: '安塞区', + 610621: '延长县', + 610622: '延川县', + 610623: '子长县', + 610625: '志丹县', + 610626: '吴起县', + 610627: '甘泉县', + 610628: '富县', + 610629: '洛川县', + 610630: '宜川县', + 610631: '黄龙县', + 610632: '黄陵县', + 610702: '汉台区', + 610703: '南郑区', + 610722: '城固县', + 610723: '洋县', + 610724: '西乡县', + 610725: '勉县', + 610726: '宁强县', + 610727: '略阳县', + 610728: '镇巴县', + 610729: '留坝县', + 610730: '佛坪县', + 610802: '榆阳区', + 610803: '横山区', + 610822: '府谷县', + 610824: '靖边县', + 610825: '定边县', + 610826: '绥德县', + 610827: '米脂县', + 610828: '佳县', + 610829: '吴堡县', + 610830: '清涧县', + 610831: '子洲县', + 610881: '神木市', + 610902: '汉滨区', + 610921: '汉阴县', + 610922: '石泉县', + 610923: '宁陕县', + 610924: '紫阳县', + 610925: '岚皋县', + 610926: '平利县', + 610927: '镇坪县', + 610928: '旬阳县', + 610929: '白河县', + 611002: '商州区', + 611021: '洛南县', + 611022: '丹凤县', + 611023: '商南县', + 611024: '山阳县', + 611025: '镇安县', + 611026: '柞水县', + 620102: '城关区', + 620103: '七里河区', + 620104: '西固区', + 620105: '安宁区', + 620111: '红古区', + 620121: '永登县', + 620122: '皋兰县', + 620123: '榆中县', + 620201: '市辖区', + 620290: '雄关区', + 620291: '长城区', + 620292: '镜铁区', + 620293: '新城镇', + 620294: '峪泉镇', + 620295: '文殊镇', + 620302: '金川区', + 620321: '永昌县', + 620402: '白银区', + 620403: '平川区', + 620421: '靖远县', + 620422: '会宁县', + 620423: '景泰县', + 620502: '秦州区', + 620503: '麦积区', + 620521: '清水县', + 620522: '秦安县', + 620523: '甘谷县', + 620524: '武山县', + 620525: '张家川回族自治县', + 620602: '凉州区', + 620621: '民勤县', + 620622: '古浪县', + 620623: '天祝藏族自治县', + 620702: '甘州区', + 620721: '肃南裕固族自治县', + 620722: '民乐县', + 620723: '临泽县', + 620724: '高台县', + 620725: '山丹县', + 620802: '崆峒区', + 620821: '泾川县', + 620822: '灵台县', + 620823: '崇信县', + 620825: '庄浪县', + 620826: '静宁县', + 620881: '华亭市', + 620902: '肃州区', + 620921: '金塔县', + 620922: '瓜州县', + 620923: '肃北蒙古族自治县', + 620924: '阿克塞哈萨克族自治县', + 620981: '玉门市', + 620982: '敦煌市', + 621002: '西峰区', + 621021: '庆城县', + 621022: '环县', + 621023: '华池县', + 621024: '合水县', + 621025: '正宁县', + 621026: '宁县', + 621027: '镇原县', + 621102: '安定区', + 621121: '通渭县', + 621122: '陇西县', + 621123: '渭源县', + 621124: '临洮县', + 621125: '漳县', + 621126: '岷县', + 621202: '武都区', + 621221: '成县', + 621222: '文县', + 621223: '宕昌县', + 621224: '康县', + 621225: '西和县', + 621226: '礼县', + 621227: '徽县', + 621228: '两当县', + 622901: '临夏市', + 622921: '临夏县', + 622922: '康乐县', + 622923: '永靖县', + 622924: '广河县', + 622925: '和政县', + 622926: '东乡族自治县', + 622927: '积石山保安族东乡族撒拉族自治县', + 623001: '合作市', + 623021: '临潭县', + 623022: '卓尼县', + 623023: '舟曲县', + 623024: '迭部县', + 623025: '玛曲县', + 623026: '碌曲县', + 623027: '夏河县', + 630102: '城东区', + 630103: '城中区', + 630104: '城西区', + 630105: '城北区', + 630121: '大通回族土族自治县', + 630122: '湟中县', + 630123: '湟源县', + 630202: '乐都区', + 630203: '平安区', + 630222: '民和回族土族自治县', + 630223: '互助土族自治县', + 630224: '化隆回族自治县', + 630225: '循化撒拉族自治县', + 632221: '门源回族自治县', + 632222: '祁连县', + 632223: '海晏县', + 632224: '刚察县', + 632321: '同仁县', + 632322: '尖扎县', + 632323: '泽库县', + 632324: '河南蒙古族自治县', + 632521: '共和县', + 632522: '同德县', + 632523: '贵德县', + 632524: '兴海县', + 632525: '贵南县', + 632621: '玛沁县', + 632622: '班玛县', + 632623: '甘德县', + 632624: '达日县', + 632625: '久治县', + 632626: '玛多县', + 632701: '玉树市', + 632722: '杂多县', + 632723: '称多县', + 632724: '治多县', + 632725: '囊谦县', + 632726: '曲麻莱县', + 632801: '格尔木市', + 632802: '德令哈市', + 632803: '茫崖市', + 632821: '乌兰县', + 632822: '都兰县', + 632823: '天峻县', + 640104: '兴庆区', + 640105: '西夏区', + 640106: '金凤区', + 640121: '永宁县', + 640122: '贺兰县', + 640181: '灵武市', + 640202: '大武口区', + 640205: '惠农区', + 640221: '平罗县', + 640302: '利通区', + 640303: '红寺堡区', + 640323: '盐池县', + 640324: '同心县', + 640381: '青铜峡市', + 640402: '原州区', + 640422: '西吉县', + 640423: '隆德县', + 640424: '泾源县', + 640425: '彭阳县', + 640502: '沙坡头区', + 640521: '中宁县', + 640522: '海原县', + 650102: '天山区', + 650103: '沙依巴克区', + 650104: '新市区', + 650105: '水磨沟区', + 650106: '头屯河区', + 650107: '达坂城区', + 650109: '米东区', + 650121: '乌鲁木齐县', + 650202: '独山子区', + 650203: '克拉玛依区', + 650204: '白碱滩区', + 650205: '乌尔禾区', + 650402: '高昌区', + 650421: '鄯善县', + 650422: '托克逊县', + 650502: '伊州区', + 650521: '巴里坤哈萨克自治县', + 650522: '伊吾县', + 652301: '昌吉市', + 652302: '阜康市', + 652323: '呼图壁县', + 652324: '玛纳斯县', + 652325: '奇台县', + 652327: '吉木萨尔县', + 652328: '木垒哈萨克自治县', + 652701: '博乐市', + 652702: '阿拉山口市', + 652722: '精河县', + 652723: '温泉县', + 652801: '库尔勒市', + 652822: '轮台县', + 652823: '尉犁县', + 652824: '若羌县', + 652825: '且末县', + 652826: '焉耆回族自治县', + 652827: '和静县', + 652828: '和硕县', + 652829: '博湖县', + 652901: '阿克苏市', + 652922: '温宿县', + 652923: '库车县', + 652924: '沙雅县', + 652925: '新和县', + 652926: '拜城县', + 652927: '乌什县', + 652928: '阿瓦提县', + 652929: '柯坪县', + 653001: '阿图什市', + 653022: '阿克陶县', + 653023: '阿合奇县', + 653024: '乌恰县', + 653101: '喀什市', + 653121: '疏附县', + 653122: '疏勒县', + 653123: '英吉沙县', + 653124: '泽普县', + 653125: '莎车县', + 653126: '叶城县', + 653127: '麦盖提县', + 653128: '岳普湖县', + 653129: '伽师县', + 653130: '巴楚县', + 653131: '塔什库尔干塔吉克自治县', + 653201: '和田市', + 653221: '和田县', + 653222: '墨玉县', + 653223: '皮山县', + 653224: '洛浦县', + 653225: '策勒县', + 653226: '于田县', + 653227: '民丰县', + 654002: '伊宁市', + 654003: '奎屯市', + 654004: '霍尔果斯市', + 654021: '伊宁县', + 654022: '察布查尔锡伯自治县', + 654023: '霍城县', + 654024: '巩留县', + 654025: '新源县', + 654026: '昭苏县', + 654027: '特克斯县', + 654028: '尼勒克县', + 654201: '塔城市', + 654202: '乌苏市', + 654221: '额敏县', + 654223: '沙湾县', + 654224: '托里县', + 654225: '裕民县', + 654226: '和布克赛尔蒙古自治县', + 654301: '阿勒泰市', + 654321: '布尔津县', + 654322: '富蕴县', + 654323: '福海县', + 654324: '哈巴河县', + 654325: '青河县', + 654326: '吉木乃县', + 659001: '石河子市', + 659002: '阿拉尔市', + 659003: '图木舒克市', + 659004: '五家渠市', + 659005: '北屯市', + 659006: '铁门关市', + 659007: '双河市', + 659008: '可克达拉市', + 659009: '昆玉市', + 710101: '中正区', + 710102: '大同区', + 710103: '中山区', + 710104: '松山区', + 710105: '大安区', + 710106: '万华区', + 710107: '信义区', + 710108: '士林区', + 710109: '北投区', + 710110: '内湖区', + 710111: '南港区', + 710112: '文山区', + 710199: '其它区', + 710201: '新兴区', + 710202: '前金区', + 710203: '芩雅区', + 710204: '盐埕区', + 710205: '鼓山区', + 710206: '旗津区', + 710207: '前镇区', + 710208: '三民区', + 710209: '左营区', + 710210: '楠梓区', + 710211: '小港区', + 710241: '苓雅区', + 710242: '仁武区', + 710243: '大社区', + 710244: '冈山区', + 710245: '路竹区', + 710246: '阿莲区', + 710247: '田寮区', + 710248: '燕巢区', + 710249: '桥头区', + 710250: '梓官区', + 710251: '弥陀区', + 710252: '永安区', + 710253: '湖内区', + 710254: '凤山区', + 710255: '大寮区', + 710256: '林园区', + 710257: '鸟松区', + 710258: '大树区', + 710259: '旗山区', + 710260: '美浓区', + 710261: '六龟区', + 710262: '内门区', + 710263: '杉林区', + 710264: '甲仙区', + 710265: '桃源区', + 710266: '那玛夏区', + 710267: '茂林区', + 710268: '茄萣区', + 710299: '其它区', + 710301: '中西区', + 710302: '东区', + 710303: '南区', + 710304: '北区', + 710305: '安平区', + 710306: '安南区', + 710339: '永康区', + 710340: '归仁区', + 710341: '新化区', + 710342: '左镇区', + 710343: '玉井区', + 710344: '楠西区', + 710345: '南化区', + 710346: '仁德区', + 710347: '关庙区', + 710348: '龙崎区', + 710349: '官田区', + 710350: '麻豆区', + 710351: '佳里区', + 710352: '西港区', + 710353: '七股区', + 710354: '将军区', + 710355: '学甲区', + 710356: '北门区', + 710357: '新营区', + 710358: '后壁区', + 710359: '白河区', + 710360: '东山区', + 710361: '六甲区', + 710362: '下营区', + 710363: '柳营区', + 710364: '盐水区', + 710365: '善化区', + 710366: '大内区', + 710367: '山上区', + 710368: '新市区', + 710369: '安定区', + 710399: '其它区', + 710401: '中区', + 710402: '东区', + 710403: '南区', + 710404: '西区', + 710405: '北区', + 710406: '北屯区', + 710407: '西屯区', + 710408: '南屯区', + 710431: '太平区', + 710432: '大里区', + 710433: '雾峰区', + 710434: '乌日区', + 710435: '丰原区', + 710436: '后里区', + 710437: '石冈区', + 710438: '东势区', + 710439: '和平区', + 710440: '新社区', + 710441: '潭子区', + 710442: '大雅区', + 710443: '神冈区', + 710444: '大肚区', + 710445: '沙鹿区', + 710446: '龙井区', + 710447: '梧栖区', + 710448: '清水区', + 710449: '大甲区', + 710450: '外埔区', + 710451: '大安区', + 710499: '其它区', + 710507: '金沙镇', + 710508: '金湖镇', + 710509: '金宁乡', + 710510: '金城镇', + 710511: '烈屿乡', + 710512: '乌坵乡', + 710614: '南投市', + 710615: '中寮乡', + 710616: '草屯镇', + 710617: '国姓乡', + 710618: '埔里镇', + 710619: '仁爱乡', + 710620: '名间乡', + 710621: '集集镇', + 710622: '水里乡', + 710623: '鱼池乡', + 710624: '信义乡', + 710625: '竹山镇', + 710626: '鹿谷乡', + 710701: '仁爱区', + 710702: '信义区', + 710703: '中正区', + 710704: '中山区', + 710705: '安乐区', + 710706: '暖暖区', + 710707: '七堵区', + 710799: '其它区', + 710801: '东区', + 710802: '北区', + 710803: '香山区', + 710899: '其它区', + 710901: '东区', + 710902: '西区', + 710999: '其它区', + 711130: '万里区', + 711132: '板桥区', + 711133: '汐止区', + 711134: '深坑区', + 711135: '石碇区', + 711136: '瑞芳区', + 711137: '平溪区', + 711138: '双溪区', + 711139: '贡寮区', + 711140: '新店区', + 711141: '坪林区', + 711142: '乌来区', + 711143: '永和区', + 711144: '中和区', + 711145: '土城区', + 711146: '三峡区', + 711147: '树林区', + 711148: '莺歌区', + 711149: '三重区', + 711150: '新庄区', + 711151: '泰山区', + 711152: '林口区', + 711153: '芦洲区', + 711154: '五股区', + 711155: '八里区', + 711156: '淡水区', + 711157: '三芝区', + 711158: '石门区', + 711287: '宜兰市', + 711288: '头城镇', + 711289: '礁溪乡', + 711290: '壮围乡', + 711291: '员山乡', + 711292: '罗东镇', + 711293: '三星乡', + 711294: '大同乡', + 711295: '五结乡', + 711296: '冬山乡', + 711297: '苏澳镇', + 711298: '南澳乡', + 711299: '钓鱼台', + 711387: '竹北市', + 711388: '湖口乡', + 711389: '新丰乡', + 711390: '新埔镇', + 711391: '关西镇', + 711392: '芎林乡', + 711393: '宝山乡', + 711394: '竹东镇', + 711395: '五峰乡', + 711396: '横山乡', + 711397: '尖石乡', + 711398: '北埔乡', + 711399: '峨眉乡', + 711414: '中坜区', + 711415: '平镇区', + 711417: '杨梅区', + 711418: '新屋区', + 711419: '观音区', + 711420: '桃园区', + 711421: '龟山区', + 711422: '八德区', + 711423: '大溪区', + 711425: '大园区', + 711426: '芦竹区', + 711487: '中坜市', + 711488: '平镇市', + 711489: '龙潭乡', + 711490: '杨梅市', + 711491: '新屋乡', + 711492: '观音乡', + 711493: '桃园市', + 711494: '龟山乡', + 711495: '八德市', + 711496: '大溪镇', + 711497: '复兴乡', + 711498: '大园乡', + 711499: '芦竹乡', + 711520: '头份市', + 711582: '竹南镇', + 711583: '头份镇', + 711584: '三湾乡', + 711585: '南庄乡', + 711586: '狮潭乡', + 711587: '后龙镇', + 711588: '通霄镇', + 711589: '苑里镇', + 711590: '苗栗市', + 711591: '造桥乡', + 711592: '头屋乡', + 711593: '公馆乡', + 711594: '大湖乡', + 711595: '泰安乡', + 711596: '铜锣乡', + 711597: '三义乡', + 711598: '西湖乡', + 711599: '卓兰镇', + 711736: '员林市', + 711774: '彰化市', + 711775: '芬园乡', + 711776: '花坛乡', + 711777: '秀水乡', + 711778: '鹿港镇', + 711779: '福兴乡', + 711780: '线西乡', + 711781: '和美镇', + 711782: '伸港乡', + 711783: '员林镇', + 711784: '社头乡', + 711785: '永靖乡', + 711786: '埔心乡', + 711787: '溪湖镇', + 711788: '大村乡', + 711789: '埔盐乡', + 711790: '田中镇', + 711791: '北斗镇', + 711792: '田尾乡', + 711793: '埤头乡', + 711794: '溪州乡', + 711795: '竹塘乡', + 711796: '二林镇', + 711797: '大城乡', + 711798: '芳苑乡', + 711799: '二水乡', + 711982: '番路乡', + 711983: '梅山乡', + 711984: '竹崎乡', + 711985: '阿里山乡', + 711986: '中埔乡', + 711987: '大埔乡', + 711988: '水上乡', + 711989: '鹿草乡', + 711990: '太保市', + 711991: '朴子市', + 711992: '东石乡', + 711993: '六脚乡', + 711994: '新港乡', + 711995: '民雄乡', + 711996: '大林镇', + 711997: '溪口乡', + 711998: '义竹乡', + 711999: '布袋镇', + 712180: '斗南镇', + 712181: '大埤乡', + 712182: '虎尾镇', + 712183: '土库镇', + 712184: '褒忠乡', + 712185: '东势乡', + 712186: '台西乡', + 712187: '仑背乡', + 712188: '麦寮乡', + 712189: '斗六市', + 712190: '林内乡', + 712191: '古坑乡', + 712192: '莿桐乡', + 712193: '西螺镇', + 712194: '二仑乡', + 712195: '北港镇', + 712196: '水林乡', + 712197: '口湖乡', + 712198: '四湖乡', + 712199: '元长乡', + 712451: '崁顶乡', + 712467: '屏东市', + 712468: '三地门乡', + 712469: '雾台乡', + 712470: '玛家乡', + 712471: '九如乡', + 712472: '里港乡', + 712473: '高树乡', + 712474: '盐埔乡', + 712475: '长治乡', + 712476: '麟洛乡', + 712477: '竹田乡', + 712478: '内埔乡', + 712479: '万丹乡', + 712480: '潮州镇', + 712481: '泰武乡', + 712482: '来义乡', + 712483: '万峦乡', + 712484: '莰顶乡', + 712485: '新埤乡', + 712486: '南州乡', + 712487: '林边乡', + 712488: '东港镇', + 712489: '琉球乡', + 712490: '佳冬乡', + 712491: '新园乡', + 712492: '枋寮乡', + 712493: '枋山乡', + 712494: '春日乡', + 712495: '狮子乡', + 712496: '车城乡', + 712497: '牡丹乡', + 712498: '恒春镇', + 712499: '满州乡', + 712584: '台东市', + 712585: '绿岛乡', + 712586: '兰屿乡', + 712587: '延平乡', + 712588: '卑南乡', + 712589: '鹿野乡', + 712590: '关山镇', + 712591: '海端乡', + 712592: '池上乡', + 712593: '东河乡', + 712594: '成功镇', + 712595: '长滨乡', + 712596: '金峰乡', + 712597: '大武乡', + 712598: '达仁乡', + 712599: '太麻里乡', + 712686: '花莲市', + 712687: '新城乡', + 712688: '太鲁阁', + 712689: '秀林乡', + 712690: '吉安乡', + 712691: '寿丰乡', + 712692: '凤林镇', + 712693: '光复乡', + 712694: '丰滨乡', + 712695: '瑞穗乡', + 712696: '万荣乡', + 712697: '玉里镇', + 712698: '卓溪乡', + 712699: '富里乡', + 712794: '马公市', + 712795: '西屿乡', + 712796: '望安乡', + 712797: '七美乡', + 712798: '白沙乡', + 712799: '湖西乡', + 712896: '南竿乡', + 712897: '北竿乡', + 712898: '东引乡', + 712899: '莒光乡', + 810101: '中西区', + 810102: '湾仔区', + 810103: '东区', + 810104: '南区', + 810201: '九龙城区', + 810202: '油尖旺区', + 810203: '深水埗区', + 810204: '黄大仙区', + 810205: '观塘区', + 810301: '北区', + 810302: '大埔区', + 810303: '沙田区', + 810304: '西贡区', + 810305: '元朗区', + 810306: '屯门区', + 810307: '荃湾区', + 810308: '葵青区', + 810309: '离岛区', + 820102: '花地玛堂区', + 820103: '花王堂区', + 820104: '望德堂区', + 820105: '大堂区', + 820106: '风顺堂区', + 820202: '嘉模堂区', + 820203: '路氹填海区', + 820204: '圣方济各堂区', + }, +} \ No newline at end of file diff --git a/utils/event.js b/utils/event.js new file mode 100644 index 0000000..ae46512 --- /dev/null +++ b/utils/event.js @@ -0,0 +1,35 @@ +var events = {} + +function on(name, self, callback) { + var tuple = [self, callback] + var callbacks = events[name] + if (Array.isArray(callbacks)) { + callbacks.push(tuple) + } else { + events[name] = [tuple] + } +} + +function remove(name, self) { + var callbacks = events[name] + if (Array.isArray(callbacks)) { + events[name] = callbacks.filter((tuple) => { + return tuple[0] != self + }) + } +} + +function emit(name, data) { + var callbacks = events[name] + if (Array.isArray(callbacks)) { + callbacks.map((tuple) => { + var self = tuple[0] + var callback = tuple[1] + callback.call(self, data) + }) + } +} + +exports.on = on +exports.remove = remove +exports.emit = emit \ No newline at end of file diff --git a/utils/math.js b/utils/math.js new file mode 100644 index 0000000..5d9f81d --- /dev/null +++ b/utils/math.js @@ -0,0 +1,155 @@ +/** + * https://github.com/nefe/number-precision + */ + +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +/** + * @desc 解决浮动运算问题,避免小数点后产生多位数和计算精度损失。 + * 问题示例:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998 + */ +/** + * 把错误的数据转正 + * strip(0.09999999999999998)=0.1 + */ +function strip(num, precision) { + if (precision === void 0) { + precision = 12; + } + return +parseFloat(num.toPrecision(precision)); +} +/** + * Return digits length of a number + * @param {*number} num Input number + */ +function digitLength(num) { + // Get digit length of e + var eSplit = num.toString().split(/[eE]/); + var len = (eSplit[0].split('.')[1] || '').length - (+(eSplit[1] || 0)); + return len > 0 ? len : 0; +} +/** + * 把小数转成整数,支持科学计数法。如果是小数则放大成整数 + * @param {*number} num 输入数 + */ +function float2Fixed(num) { + if (num.toString().indexOf('e') === -1) { + return Number(num.toString().replace('.', '')); + } + var dLen = digitLength(num); + return dLen > 0 ? strip(num * Math.pow(10, dLen)) : num; +} +/** + * 检测数字是否越界,如果越界给出提示 + * @param {*number} num 输入数 + */ +function checkBoundary(num) { + if (_boundaryCheckingState) { + if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { + console.warn(num + " is beyond boundary when transfer to integer, the results may not be accurate"); + } + } +} +/** + * 精确乘法 + */ +function times(num1, num2) { + var others = []; + for (var _i = 2; _i < arguments.length; _i++) { + others[_i - 2] = arguments[_i]; + } + if (others.length > 0) { + return times.apply(void 0, [times(num1, num2), others[0]].concat(others.slice(1))); + } + var num1Changed = float2Fixed(num1); + var num2Changed = float2Fixed(num2); + var baseNum = digitLength(num1) + digitLength(num2); + var leftValue = num1Changed * num2Changed; + checkBoundary(leftValue); + return leftValue / Math.pow(10, baseNum); +} +/** + * 精确加法 + */ +function plus(num1, num2) { + var others = []; + for (var _i = 2; _i < arguments.length; _i++) { + others[_i - 2] = arguments[_i]; + } + if (others.length > 0) { + return plus.apply(void 0, [plus(num1, num2), others[0]].concat(others.slice(1))); + } + var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; +} +/** + * 精确减法 + */ +function minus(num1, num2) { + var others = []; + for (var _i = 2; _i < arguments.length; _i++) { + others[_i - 2] = arguments[_i]; + } + if (others.length > 0) { + return minus.apply(void 0, [minus(num1, num2), others[0]].concat(others.slice(1))); + } + var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; +} +/** + * 精确除法 + */ +function divide(num1, num2) { + var others = []; + for (var _i = 2; _i < arguments.length; _i++) { + others[_i - 2] = arguments[_i]; + } + if (others.length > 0) { + return divide.apply(void 0, [divide(num1, num2), others[0]].concat(others.slice(1))); + } + var num1Changed = float2Fixed(num1); + var num2Changed = float2Fixed(num2); + checkBoundary(num1Changed); + checkBoundary(num2Changed); + return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1))); +} +/** + * 四舍五入 + */ +function round(num, ratio) { + var base = Math.pow(10, ratio); + return divide(Math.round(times(num, base)), base); +} +var _boundaryCheckingState = true; +/** + * 是否进行边界检查,默认开启 + * @param flag 标记开关,true 为开启,false 为关闭,默认为 true + */ +function enableBoundaryChecking(flag) { + if (flag === void 0) { + flag = true; + } + _boundaryCheckingState = flag; +} + +function formateAmount(amount){ + amount = Math.ceil(times(amount, 100)) + return divide(amount, 100) +} + +module.exports = { + strip: strip, + plus: plus, + minus: minus, + times: times, + divide: divide, + round: round, + digitLength: digitLength, + float2Fixed: float2Fixed, + enableBoundaryChecking: enableBoundaryChecking, + formateAmount: formateAmount +} \ No newline at end of file diff --git a/utils/storage.js b/utils/storage.js new file mode 100644 index 0000000..57eb42b --- /dev/null +++ b/utils/storage.js @@ -0,0 +1,48 @@ +/** + * 获取缓存 + * @param String $key key + * @param String $def 若想要无缓存时,返回默认值则get('key','默认值')(支持字符串、json、数组、boolean等等) + * @return value; + */ + function get (key, def = '') { + const timeout = parseInt(wx.getStorageSync(`${key}__separator__`) || 0); + // 过期失效 + if (timeout) { + if (Date.now() > timeout) { + this.remove(key); + return; + } + } + let value = wx.getStorageSync(key); + return value ? value : def; +} + +/** + * 设置缓存 + * @param String $key key + * @param String $value value(支持字符串、json、数组、boolean等等) + * @param Number $timeout 过期时间(单位:分钟)不设置时间即为永久保存 + * @return value; + */ +function put (key, value, timeout = 0) { + let _timeout = parseInt(timeout); + wx.setStorageSync(key, value); + if (_timeout) { + wx.setStorageSync(`${key}__separator__`, Date.now() + 1000 * 60 * _timeout); + } else { + wx.removeStorageSync(`${key}__separator__`); + } + return value; +} + +function remove (key) { + wx.removeStorageSync(key); + wx.removeStorageSync(`${key}__separator__`); + return undefined; +} + +module.exports = { + remove: remove, + put: put, + get: get +} \ No newline at end of file diff --git a/utils/util.js b/utils/util.js new file mode 100644 index 0000000..b5ef4ef --- /dev/null +++ b/utils/util.js @@ -0,0 +1,197 @@ +const formatTime = date => { + const year = date.getFullYear() + const month = date.getMonth() + 1 + const day = date.getDate() + const hour = date.getHours() + const minute = date.getMinutes() + const second = date.getSeconds() + return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') +} + +const formatNumber = n => { + n = n.toString() + return n[1] ? n : '0' + n +} + +function beforeDay(day, format) { + var date = new Date() + var formateArr = ['Y', 'M', 'D', 'h', 'm', 's']; + var returnArr = []; + returnArr.push(date.getFullYear()); + returnArr.push(formatNumber(date.getMonth() + 1)); + returnArr.push(formatNumber(date.getDate() - day)); + returnArr.push(formatNumber(date.getHours())); + returnArr.push(formatNumber(date.getMinutes())); + returnArr.push(formatNumber(date.getSeconds())); + for (var i in returnArr) { + format = format.replace(formateArr[i], returnArr[i]); + } + return format; +} + +function formatDate(date, format) { + var formateArr = ['Y', 'M', 'D', 'h', 'm', 's']; + var returnArr = []; + returnArr.push(date.getFullYear()); + returnArr.push(formatNumber(date.getMonth() + 1)); + returnArr.push(formatNumber(date.getDate())); + returnArr.push(formatNumber(date.getHours())); + returnArr.push(formatNumber(date.getMinutes())); + returnArr.push(formatNumber(date.getSeconds())); + for (var i in returnArr) { + format = format.replace(formateArr[i], returnArr[i]); + } + return format; +} + +function json2Form(json) { + var str = []; + for (var p in json) { + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(json[p])); + } + return str.join("&"); +} + +function isEmpty(val) { + return typeof val === 'undefined' || val === '' || val === null +} + +function showTip(content) { + wx.showModal({ + content: content, + showCancel: false + }) +} + +function showToast(content) { + if (isEmpty(content)) { + return + } + wx.showToast({ + title: content, + icon: 'none' + }) +} + +function extend(obj) { + var o = {}, + attr = Array.prototype.slice.call(arguments).slice(1); + attr.forEach(function (val, index) { + if (val in obj) { + o[val] = obj[val]; + } + }); + return o; +} + +function playDing() { + const innerAudioContext = wx.createInnerAudioContext(); //新建一个createInnerAudioContext(); + innerAudioContext.autoplay = true; //音频自动播放设置 + innerAudioContext.src = '/assets/raw/ptt_playfinish.mp3'; //链接到音频的地址 + innerAudioContext.onPlay(() => {}); //播放音效 + innerAudioContext.onError((res) => { //打印错误 + console.log(res.errMsg) //错误信息 + console.log(res.errCode) //错误码 + }) +} + +function showBackToast(content) { + if (isEmpty(content)) { + return + } + wx.showToast({ + title: content, + icon: 'none', + duration: 500, + success: function () { + setTimeout(function () { + wx.navigateBack() + }, 500) + } + }) +} + +/* 验证手机号 */ +function checkPhone(phone) { + var re = /^1\d{10}$/ + return re.test(phone) && phone.length === 11 +} + +function checkId(id) { + // 1 "验证通过!", 0 //校验不通过 // id为身份证号码 + var format = /^(([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([5][0-4])|([6][1-5])|([7][1])|([8][1-2]))\d{4}(([1][9]\d{2})|([2]\d{3}))(([0][1-9])|([1][0-2]))(([0][1-9])|([1-2][0-9])|([3][0-1]))\d{3}[0-9xX]$/; + //号码规则校验 + if (!format.test(id)) { + return { + 'status': 0, + 'msg': '身份证号码不合规' + }; + } + //区位码校验 + //出生年月日校验 前正则限制起始年份为1900; + var year = id.substr(6, 4), //身份证年 + month = id.substr(10, 2), //身份证月 + date = id.substr(12, 2), //身份证日 + time = Date.parse(month + '-' + date + '-' + year), //身份证日期时间戳date + now_time = Date.parse(new Date()), //当前时间戳 + dates = (new Date(year, month, 0)).getDate(); //身份证当月天数 + if (time > now_time || date > dates) { + return { + 'status': 0, + 'msg': '出生日期不合规' + } + } + //校验码判断 + var c = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); //系数 + var b = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'); //校验码对照表 + var id_array = id.split(""); + var sum = 0; + for (var k = 0; k < 17; k++) { + sum += parseInt(id_array[k]) * parseInt(c[k]); + } + if (id_array[17].toUpperCase() != b[sum % 11].toUpperCase()) { + return { + 'status': 0, + 'msg': '身份证校验码不合规' + } + } + return { + 'status': 1, + 'msg': '校验通过' + } +} + +function combination(arr, m) { + let r = []; + _([], arr, m); + return r; + function _(t, a, m) { + //t:临时数组 a:目标数组 m:多少个数进行组合 + if (m === 0) { + r[r.length] = t; //相当于push + return; + } + for (let i = 0; i <= a.length - m; i++) { + //从0开始 到n-m + let b = t.slice(); //将t赋值给b 不能用=赋值,使用slice会形成新的数组赋值 + b.push(a[i]) + _(b, a.slice(i + 1), m - 1); + } + } +} + +module.exports = { + isEmpty: isEmpty, + extend: extend, + formatTime: formatTime, + beforeDay: beforeDay, + formatDate: formatDate, + json2Form: json2Form, + showToast: showToast, + showTip: showTip, + playDing: playDing, + showBackToast: showBackToast, + checkPhone: checkPhone, + checkId: checkId, + combination: combination +} \ No newline at end of file