From 7d879ff3bc7f7e6a5a699cc1cbca2d37fb9b8ebb Mon Sep 17 00:00:00 2001 From: wtq <2394975549@qq.com> Date: Thu, 13 Nov 2025 14:42:30 +0800 Subject: [PATCH] '!' --- .gitignore | 23 + .hbuilderx/launch.json | 27 + .prettierrc.json | 5 + .stignore | 3 + README.md | 353 + dfslkf | 59 + index.html | 25 + package-lock.json | 7014 +++++++++++++++++ package.json | 72 + src/App.ts | 192 + src/App.vue | 39 + src/androidPrivacy.json | 3 + src/api/config.ts | 21 + src/api/https/login.ts | 120 + src/api/https/merchant.ts | 267 + src/api/https/message.ts | 48 + src/api/https/order.ts | 519 ++ src/api/https/shopping.ts | 98 + src/api/mockData/index.ts | 135 + src/api/request.ts | 234 + src/components/dialog/dialog.ts | 55 + src/components/dialog/dialogCom.vue | 202 + src/components/dialog/dialogUtil.ts | 42 + src/components/jx-empty/jx-empty.vue | 57 + src/components/jx-icon/jx-icon.vue | 29 + src/components/jx-input/jx-input.vue | 27 + src/components/jx-load-more/jx-load-more.vue | 72 + src/components/jx-loading/jx-loading.vue | 172 + src/components/jx-loading/jxLoading.png | Bin 0 -> 8328 bytes .../jx-login-empty/jx-login-empty.vue | 113 + src/components/jx-price/jx-price.vue | 64 + .../jx-real-income/jx-real-income.vue | 103 + .../jx-upload-img/jx-upload-img.vue | 232 + src/composables/useGlobalFunc.ts | 577 ++ src/composables/useOrderInfo.ts | 290 + src/env.d.ts | 134 + src/main.ts | 15 + src/manifest.json | 174 + src/pages.json | 401 + .../childPages/right-main/right-main.scss | 305 + .../childPages/right-main/right-main.ts | 177 + .../childPages/right-main/right-main.vue | 264 + .../shopping-filter/shopping-filter.vue | 218 + .../shopping-search/shopping-search.vue | 128 + .../component/left-bar/left-bar.scss | 45 + .../component/left-bar/left-bar.ts | 83 + .../component/left-bar/left-bar.vue | 139 + src/pages/goods-manager/main.scss | 124 + src/pages/goods-manager/main.ts | 710 ++ src/pages/goods-manager/main.vue | 244 + src/pages/merchant/index.ts | 189 + src/pages/merchant/index.vue | 156 + src/pages/merchant/options/options.scss | 106 + src/pages/merchant/options/options.ts | 316 + src/pages/merchant/options/options.vue | 280 + src/pages/merchant/orderData/orderData.scss | 49 + src/pages/merchant/orderData/orderData.vue | 151 + src/pages/merchant/userInfo/userInfo.scss | 127 + src/pages/merchant/userInfo/userInfo.ts | 229 + src/pages/merchant/userInfo/userInfo.vue | 97 + src/pages/message/index.ts | 209 + src/pages/message/index.vue | 76 + .../abnormal-order/abnormal-order.scss | 76 + .../abnormal-order/abnormal-order.vue | 80 + .../abnormal-order/abonmrmal-order.ts | 158 + .../abnormal-order/bottom-component.vue | 124 + .../after-sales-order/after-sales-order.scss | 199 + .../after-sales-order/after-sales-order.vue | 285 + .../childPages/completed/completed.vue | 120 + .../childPages/component/orderListTop.vue | 514 ++ .../childPages/component/orderMoney.vue | 79 + .../childPages/jx-tab/jx-tab.scss | 45 + .../order-manager/childPages/jx-tab/jx-tab.ts | 161 + .../childPages/jx-tab/jx-tab.vue | 51 + .../childPages/order-filter/order-filter.scss | 56 + .../childPages/order-filter/order-filter.vue | 273 + .../pending-distribution.vue | 325 + .../pending-order/pending-order.vue | 107 + .../pending-picking/pending-picking.vue | 119 + src/pages/order-manager/main.ts | 407 + src/pages/order-manager/main.vue | 439 ++ src/static/agreement/privacy.html | 103 + src/static/agreement/service.html | 211 + src/static/font/iconfont.css | 343 + src/static/font/iconfont.ttf | Bin 0 -> 8312 bytes src/static/image/global/empty.png | Bin 0 -> 69022 bytes src/static/image/global/error.png | Bin 0 -> 13556 bytes src/static/image/global/order-divider.png | Bin 0 -> 1088 bytes src/static/image/global/success.png | Bin 0 -> 5962 bytes .../image/tabBarIcon/merchant-active.png | Bin 0 -> 501 bytes src/static/image/tabBarIcon/merchant.png | Bin 0 -> 553 bytes src/static/image/tabBarIcon/msg-active.png | Bin 0 -> 2546 bytes src/static/image/tabBarIcon/msg.png | Bin 0 -> 1620 bytes src/static/image/tabBarIcon/order-active.png | Bin 0 -> 357 bytes src/static/image/tabBarIcon/order.png | Bin 0 -> 422 bytes .../image/tabBarIcon/shopping-active.png | Bin 0 -> 378 bytes src/static/image/tabBarIcon/shopping.png | Bin 0 -> 549 bytes src/static/merchant-icon/1.png | Bin 0 -> 6044 bytes src/static/merchant-icon/10.png | Bin 0 -> 3092 bytes src/static/merchant-icon/11.png | Bin 0 -> 3821 bytes src/static/merchant-icon/12.png | Bin 0 -> 5792 bytes src/static/merchant-icon/13.png | Bin 0 -> 4455 bytes src/static/merchant-icon/14.png | Bin 0 -> 2636 bytes src/static/merchant-icon/15.png | Bin 0 -> 2793 bytes src/static/merchant-icon/16.png | Bin 0 -> 4907 bytes src/static/merchant-icon/18.png | Bin 0 -> 4364 bytes src/static/merchant-icon/19.png | Bin 0 -> 13451 bytes src/static/merchant-icon/2.png | Bin 0 -> 2690 bytes src/static/merchant-icon/20.png | Bin 0 -> 3547 bytes src/static/merchant-icon/21.png | Bin 0 -> 4567 bytes src/static/merchant-icon/22.png | Bin 0 -> 2831 bytes src/static/merchant-icon/3.png | Bin 0 -> 3017 bytes src/static/merchant-icon/4.png | Bin 0 -> 2752 bytes src/static/merchant-icon/5.png | Bin 0 -> 3223 bytes src/static/merchant-icon/6.png | Bin 0 -> 2395 bytes src/static/merchant-icon/7.png | Bin 0 -> 3555 bytes src/static/merchant-icon/8.png | Bin 0 -> 4069 bytes src/static/merchant-icon/9.png | Bin 0 -> 5193 bytes src/static/style/mixin-svg.scss | 27 + src/store/index.ts | 45 + src/store/useServeInfoStore/actions.ts | 11 + src/store/useServeInfoStore/getters.ts | 28 + src/store/useServeInfoStore/index.ts | 50 + src/store/useServeInfoStore/mutations.ts | 98 + src/store/useStoreInfoStore/actions.ts | 64 + src/store/useStoreInfoStore/getters.ts | 123 + src/store/useStoreInfoStore/index.ts | 44 + src/store/useStoreInfoStore/mutations.ts | 109 + src/subPages/agreement/about.vue | 31 + src/subPages/agreement/privacy.vue | 102 + src/subPages/agreement/user.vue | 207 + src/subPages/login/bindSNS/bindSNS.vue | 31 + src/subPages/login/codeLogin/codeLogin.vue | 157 + src/subPages/login/index.scss | 184 + src/subPages/login/index.vue | 98 + .../login/paswordLogin/paswordLogin.vue | 98 + src/subPages/login/weixin.ts | 137 + src/subPages/login/wxLogin/wxLogin.scss | 126 + src/subPages/login/wxLogin/wxLogin.ts | 193 + src/subPages/login/wxLogin/wxLogin.vue | 169 + .../accountBalance/accountBalance.vue | 171 + .../merchantChild/activity/activity.vue | 49 + src/subPages/merchantChild/bill/bill.scss | 85 + src/subPages/merchantChild/bill/bill.vue | 80 + .../merchantChild/billDetaile/billDetaile.vue | 30 + .../businessLicense/businessLicense.scss | 60 + .../businessLicense/businessLicense.ts | 220 + .../businessLicense/businessLicense.vue | 145 + .../enterGroupChat/enterGroupChat.vue | 44 + .../evaluateM/commentList/commentList.scss | 134 + .../evaluateM/commentList/commentList.vue | 284 + .../merchantChild/evaluateM/evaluateM.vue | 139 + .../merchantChild/evaluateM/tabs/tabs.vue | 87 + .../merchantChild/helpCenter/helpCenter.vue | 3 + .../merchantChild/invoice/invoice.vue | 495 ++ .../merchantChild/message/message.scss | 84 + .../merchantChild/message/message.vue | 88 + .../messageDetail/messageDetail.scss | 42 + .../messageDetail/messageDetail.vue | 103 + .../modifyPrice/modifyPrice.scss | 148 + .../merchantChild/modifyPrice/modifyPrice.vue | 212 + .../orderRealTime/orderRealTime.scss | 149 + .../orderRealTime/orderRealTime.ts | 455 ++ .../orderRealTime/orderRealTime.vue | 182 + .../merchantChild/payeeInfo/payeeInfo.vue | 207 + .../merchantChild/platformDetail/index.scss | 84 + .../merchantChild/platformDetail/index.vue | 106 + .../merchantChild/platformM/platformM.scss | 80 + .../merchantChild/platformM/platformM.vue | 120 + .../printerSetUp/printerSetUp.scss | 224 + .../printerSetUp/printerSetUp.ts | 386 + .../printerSetUp/printerSetUp.vue | 150 + .../setBusinessStatus/setBusinessStatus.scss | 129 + .../setBusinessStatus/setBusinessStatus.ts | 203 + .../setBusinessStatus/setBusinessStatus.vue | 81 + .../setBusinessTime/setBusinessTime.scss | 68 + .../setBusinessTime/setBusinessTime.ts | 175 + .../setBusinessTime/setBusinessTime.vue | 75 + .../setInvoiceEB/setInvoiceEB.scss | 54 + .../setInvoiceEB/setInvoiceEB.ts | 159 + .../setInvoiceEB/setInvoiceEB.vue | 59 + src/subPages/merchantChild/setUp/setUp.scss | 186 + src/subPages/merchantChild/setUp/setUp.ts | 559 ++ src/subPages/merchantChild/setUp/setUp.vue | 268 + .../merchantChild/shareStore/shareStore.scss | 104 + .../merchantChild/shareStore/shareStore.vue | 163 + .../merchantChild/storeScore/storeScore.scss | 72 + .../merchantChild/storeScore/storeScore.vue | 85 + .../storeScoreDetaile/storeScoreDetaile.vue | 27 + .../merchantChild/useInfo/useInfo.vue | 157 + .../merchantChild/waitGoods/waitGoods.scss | 68 + .../merchantChild/waitGoods/waitGoods.vue | 112 + .../waitGoodsDetaile/skuName/skuName.scss | 233 + .../waitGoodsDetaile/skuName/skuName.vue | 193 + .../waitGoodsDetaile/skuNameID/skuNameID.scss | 172 + .../waitGoodsDetaile/skuNameID/skuNameID.vue | 245 + .../waitGoodsDetaile/waitGoodsDetaile.ts | 158 + .../waitGoodsDetaile/waitGoodsDetaile.vue | 154 + src/subPages/messageChild/appPlay/appPlay.vue | 246 + src/subPages/messageChild/msgChat/msgChat.ts | 573 ++ src/subPages/messageChild/msgChat/msgChat.vue | 99 + .../msgChat/msgChatChild/chat-item.vue | 379 + .../msgChat/msgChatChild/index.scss | 599 ++ .../afterSalesOrderDetail.scss | 205 + .../afterSalesOrderDetail.ts | 293 + .../afterSalesOrderDetail.vue | 206 + .../orderChild/complaint/complaint.vue | 225 + .../createAfterSales/createAfterSales.scss | 274 + .../createAfterSales/createAfterSales.ts | 346 + .../createAfterSales/createAfterSales.vue | 156 + .../deliverManager/deliverManager.scss | 318 + .../deliverManager/deliverManager.ts | 589 ++ .../deliverManager/deliverManager.vue | 273 + .../threeDeliver/threeDeliver.scss | 159 + .../threeDeliver/threeDeliver.ts | 251 + .../threeDeliver/threeDeliver.vue | 154 + src/subPages/orderChild/getPhone/getPhone.vue | 94 + .../orderDetail/detailChild/goodsList.vue | 607 ++ .../orderDetail/detailChild/goodsRefund.vue | 122 + .../orderChild/orderDetail/orderDetail.scss | 485 ++ .../orderChild/orderDetail/orderDetail.ts | 629 ++ .../orderChild/orderDetail/orderDetail.vue | 504 ++ src/subPages/orderChild/seeMap/seeMap.vue | 480 ++ .../createGoods/createGoods.scss | 11 + .../shoppingChild/createGoods/createGoods.ts | 364 + .../shoppingChild/createGoods/createGoods.vue | 140 + .../create-goods-filter.vue | 89 + .../create-goods-search.vue | 93 + .../right-main/right-main.scss | 196 + .../createGoodsChild/right-main/right-main.ts | 142 + .../right-main/right-main.vue | 149 + .../searchGoods/searchGoods.scss | 86 + .../searchGoods/searchGoods.vue | 105 + src/subPages/switchStore/switchStore.scss | 79 + src/subPages/switchStore/switchStore.ts | 166 + src/subPages/switchStore/switchStore.vue | 62 + src/uni.scss | 64 + .../uv-datetime-picker/changelog.md | 15 + .../components/uv-datetime-picker/props.js | 125 + .../uv-datetime-picker/uv-datetime-picker.vue | 369 + .../uv-datetime-picker/package.json | 88 + src/uni_modules/uv-datetime-picker/readme.md | 11 + src/uni_modules/uv-icon/changelog.md | 15 + .../uv-icon/components/uv-icon/icons.js | 157 + .../uv-icon/components/uv-icon/props.js | 90 + .../uv-icon/components/uv-icon/uniicons.css | 663 ++ .../uv-icon/components/uv-icon/uv-icon.vue | 220 + .../uv-icon/components/uv-icon/uvicons.ttf | Bin 0 -> 39500 bytes src/uni_modules/uv-icon/package.json | 83 + src/uni_modules/uv-icon/readme.md | 11 + src/uni_modules/uv-loading-icon/changelog.md | 7 + .../components/uv-loading-icon/props.js | 60 + .../uv-loading-icon/uv-loading-icon.vue | 346 + src/uni_modules/uv-loading-icon/package.json | 87 + src/uni_modules/uv-loading-icon/readme.md | 11 + src/uni_modules/uv-overlay/changelog.md | 9 + .../uv-overlay/components/uv-overlay/props.js | 25 + .../components/uv-overlay/uv-overlay.vue | 85 + src/uni_modules/uv-overlay/package.json | 88 + src/uni_modules/uv-overlay/readme.md | 11 + src/uni_modules/uv-picker/changelog.md | 17 + .../uv-picker/components/uv-picker/props.js | 90 + .../components/uv-picker/uv-picker.vue | 312 + .../uv-picker/components/uv-toolbar/props.js | 39 + .../components/uv-toolbar/uv-toolbar.vue | 109 + src/uni_modules/uv-picker/package.json | 89 + src/uni_modules/uv-picker/readme.md | 11 + src/uni_modules/uv-popup/changelog.md | 9 + .../uv-popup/components/uv-popup/keypress.js | 45 + .../uv-popup/components/uv-popup/props.js | 80 + .../uv-popup/components/uv-popup/uv-popup.vue | 527 ++ src/uni_modules/uv-popup/package.json | 92 + src/uni_modules/uv-popup/readme.md | 11 + src/uni_modules/uv-safe-bottom/changelog.md | 7 + .../uv-safe-bottom/uv-safe-bottom.vue | 67 + src/uni_modules/uv-safe-bottom/package.json | 87 + src/uni_modules/uv-safe-bottom/readme.md | 11 + src/uni_modules/uv-status-bar/changelog.md | 7 + .../components/uv-status-bar/props.js | 8 + .../uv-status-bar/uv-status-bar.vue | 54 + src/uni_modules/uv-status-bar/package.json | 87 + src/uni_modules/uv-status-bar/readme.md | 10 + src/uni_modules/uv-transition/changelog.md | 13 + .../uv-transition/createAnimation.js | 131 + .../uv-transition/uv-transition.vue | 301 + src/uni_modules/uv-transition/package.json | 87 + src/uni_modules/uv-transition/readme.md | 11 + src/uni_modules/uv-ui-tools/changelog.md | 24 + .../components/uv-ui-tools/uv-ui-tools.vue | 6 + src/uni_modules/uv-ui-tools/index.js | 77 + src/uni_modules/uv-ui-tools/index.scss | 7 + .../uv-ui-tools/libs/config/config.js | 34 + .../uv-ui-tools/libs/css/color.scss | 32 + .../uv-ui-tools/libs/css/common.scss | 100 + .../uv-ui-tools/libs/css/components.scss | 23 + .../uv-ui-tools/libs/css/variable.scss | 111 + src/uni_modules/uv-ui-tools/libs/css/vue.scss | 40 + .../libs/function/colorGradient.js | 134 + .../uv-ui-tools/libs/function/debounce.js | 29 + .../uv-ui-tools/libs/function/digit.js | 167 + .../uv-ui-tools/libs/function/index.js | 734 ++ .../uv-ui-tools/libs/function/platform.js | 75 + .../uv-ui-tools/libs/function/test.js | 287 + .../uv-ui-tools/libs/function/throttle.js | 30 + .../libs/luch-request/adapters/index.js | 97 + .../luch-request/core/InterceptorManager.js | 50 + .../libs/luch-request/core/Request.js | 198 + .../libs/luch-request/core/buildFullPath.js | 20 + .../libs/luch-request/core/defaults.js | 29 + .../libs/luch-request/core/dispatchRequest.js | 3 + .../libs/luch-request/core/mergeConfig.js | 103 + .../libs/luch-request/core/settle.js | 16 + .../libs/luch-request/helpers/buildURL.js | 69 + .../libs/luch-request/helpers/combineURLs.js | 14 + .../luch-request/helpers/isAbsoluteURL.js | 14 + .../uv-ui-tools/libs/luch-request/index.d.ts | 116 + .../uv-ui-tools/libs/luch-request/index.js | 3 + .../uv-ui-tools/libs/luch-request/utils.js | 131 + .../libs/luch-request/utils/clone.js | 264 + .../uv-ui-tools/libs/mixin/button.js | 13 + .../uv-ui-tools/libs/mixin/mixin.js | 152 + .../uv-ui-tools/libs/mixin/mpMixin.js | 8 + .../uv-ui-tools/libs/mixin/mpShare.js | 13 + .../uv-ui-tools/libs/mixin/openType.js | 44 + .../uv-ui-tools/libs/mixin/touch.js | 59 + .../uv-ui-tools/libs/util/dayjs.js | 218 + .../uv-ui-tools/libs/util/route.js | 124 + src/uni_modules/uv-ui-tools/package.json | 81 + src/uni_modules/uv-ui-tools/readme.md | 13 + src/uni_modules/uv-ui-tools/theme.scss | 43 + src/utils/bluetoothPrinter/bluetooth.js | 281 + src/utils/bluetoothPrinter/commands.js | 193 + src/utils/bluetoothPrinter/gbk.js | 192 + src/utils/bluetoothPrinter/printerOrder.ts | 179 + src/utils/bluetoothPrinter/printerTemplate.ts | 632 ++ src/utils/bluetoothPrinter/printerjobs.js | 190 + src/utils/bluetoothPrinter/printerutil.js | 93 + src/utils/bluetoothPrinter/util.js | 242 + src/utils/configCms.ts | 544 ++ src/utils/emoji.ts | 464 ++ src/utils/log.js | 32 + src/utils/md5.js | 492 ++ src/utils/qiniuUploader.ts | 163 + src/utils/storage.ts | 84 + src/utils/toast.ts | 49 + src/utils/tools.ts | 319 + src/utils/weapp.qrcode.esm.js | 5 + tsconfig.json | 41 + vite.config.ts | 8 + 349 files changed, 54558 insertions(+) create mode 100644 .gitignore create mode 100644 .hbuilderx/launch.json create mode 100644 .prettierrc.json create mode 100644 .stignore create mode 100644 README.md create mode 100644 dfslkf create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/App.ts create mode 100644 src/App.vue create mode 100644 src/androidPrivacy.json create mode 100644 src/api/config.ts create mode 100644 src/api/https/login.ts create mode 100644 src/api/https/merchant.ts create mode 100644 src/api/https/message.ts create mode 100644 src/api/https/order.ts create mode 100644 src/api/https/shopping.ts create mode 100644 src/api/mockData/index.ts create mode 100644 src/api/request.ts create mode 100644 src/components/dialog/dialog.ts create mode 100644 src/components/dialog/dialogCom.vue create mode 100644 src/components/dialog/dialogUtil.ts create mode 100644 src/components/jx-empty/jx-empty.vue create mode 100644 src/components/jx-icon/jx-icon.vue create mode 100644 src/components/jx-input/jx-input.vue create mode 100644 src/components/jx-load-more/jx-load-more.vue create mode 100644 src/components/jx-loading/jx-loading.vue create mode 100644 src/components/jx-loading/jxLoading.png create mode 100644 src/components/jx-login-empty/jx-login-empty.vue create mode 100644 src/components/jx-price/jx-price.vue create mode 100644 src/components/jx-real-income/jx-real-income.vue create mode 100644 src/components/jx-upload-img/jx-upload-img.vue create mode 100644 src/composables/useGlobalFunc.ts create mode 100644 src/composables/useOrderInfo.ts create mode 100644 src/env.d.ts create mode 100644 src/main.ts create mode 100644 src/manifest.json create mode 100644 src/pages.json create mode 100644 src/pages/goods-manager/childPages/right-main/right-main.scss create mode 100644 src/pages/goods-manager/childPages/right-main/right-main.ts create mode 100644 src/pages/goods-manager/childPages/right-main/right-main.vue create mode 100644 src/pages/goods-manager/childPages/shopping-filter/shopping-filter.vue create mode 100644 src/pages/goods-manager/childPages/shopping-search/shopping-search.vue create mode 100644 src/pages/goods-manager/component/left-bar/left-bar.scss create mode 100644 src/pages/goods-manager/component/left-bar/left-bar.ts create mode 100644 src/pages/goods-manager/component/left-bar/left-bar.vue create mode 100644 src/pages/goods-manager/main.scss create mode 100644 src/pages/goods-manager/main.ts create mode 100644 src/pages/goods-manager/main.vue create mode 100644 src/pages/merchant/index.ts create mode 100644 src/pages/merchant/index.vue create mode 100644 src/pages/merchant/options/options.scss create mode 100644 src/pages/merchant/options/options.ts create mode 100644 src/pages/merchant/options/options.vue create mode 100644 src/pages/merchant/orderData/orderData.scss create mode 100644 src/pages/merchant/orderData/orderData.vue create mode 100644 src/pages/merchant/userInfo/userInfo.scss create mode 100644 src/pages/merchant/userInfo/userInfo.ts create mode 100644 src/pages/merchant/userInfo/userInfo.vue create mode 100644 src/pages/message/index.ts create mode 100644 src/pages/message/index.vue create mode 100644 src/pages/order-manager/childPages/abnormal-order/abnormal-order.scss create mode 100644 src/pages/order-manager/childPages/abnormal-order/abnormal-order.vue create mode 100644 src/pages/order-manager/childPages/abnormal-order/abonmrmal-order.ts create mode 100644 src/pages/order-manager/childPages/abnormal-order/bottom-component.vue create mode 100644 src/pages/order-manager/childPages/after-sales-order/after-sales-order.scss create mode 100644 src/pages/order-manager/childPages/after-sales-order/after-sales-order.vue create mode 100644 src/pages/order-manager/childPages/completed/completed.vue create mode 100644 src/pages/order-manager/childPages/component/orderListTop.vue create mode 100644 src/pages/order-manager/childPages/component/orderMoney.vue create mode 100644 src/pages/order-manager/childPages/jx-tab/jx-tab.scss create mode 100644 src/pages/order-manager/childPages/jx-tab/jx-tab.ts create mode 100644 src/pages/order-manager/childPages/jx-tab/jx-tab.vue create mode 100644 src/pages/order-manager/childPages/order-filter/order-filter.scss create mode 100644 src/pages/order-manager/childPages/order-filter/order-filter.vue create mode 100644 src/pages/order-manager/childPages/pending-distribution/pending-distribution.vue create mode 100644 src/pages/order-manager/childPages/pending-order/pending-order.vue create mode 100644 src/pages/order-manager/childPages/pending-picking/pending-picking.vue create mode 100644 src/pages/order-manager/main.ts create mode 100644 src/pages/order-manager/main.vue create mode 100644 src/static/agreement/privacy.html create mode 100644 src/static/agreement/service.html create mode 100644 src/static/font/iconfont.css create mode 100644 src/static/font/iconfont.ttf create mode 100644 src/static/image/global/empty.png create mode 100644 src/static/image/global/error.png create mode 100644 src/static/image/global/order-divider.png create mode 100644 src/static/image/global/success.png create mode 100644 src/static/image/tabBarIcon/merchant-active.png create mode 100644 src/static/image/tabBarIcon/merchant.png create mode 100644 src/static/image/tabBarIcon/msg-active.png create mode 100644 src/static/image/tabBarIcon/msg.png create mode 100644 src/static/image/tabBarIcon/order-active.png create mode 100644 src/static/image/tabBarIcon/order.png create mode 100644 src/static/image/tabBarIcon/shopping-active.png create mode 100644 src/static/image/tabBarIcon/shopping.png create mode 100644 src/static/merchant-icon/1.png create mode 100644 src/static/merchant-icon/10.png create mode 100644 src/static/merchant-icon/11.png create mode 100644 src/static/merchant-icon/12.png create mode 100644 src/static/merchant-icon/13.png create mode 100644 src/static/merchant-icon/14.png create mode 100644 src/static/merchant-icon/15.png create mode 100644 src/static/merchant-icon/16.png create mode 100644 src/static/merchant-icon/18.png create mode 100644 src/static/merchant-icon/19.png create mode 100644 src/static/merchant-icon/2.png create mode 100644 src/static/merchant-icon/20.png create mode 100644 src/static/merchant-icon/21.png create mode 100644 src/static/merchant-icon/22.png create mode 100644 src/static/merchant-icon/3.png create mode 100644 src/static/merchant-icon/4.png create mode 100644 src/static/merchant-icon/5.png create mode 100644 src/static/merchant-icon/6.png create mode 100644 src/static/merchant-icon/7.png create mode 100644 src/static/merchant-icon/8.png create mode 100644 src/static/merchant-icon/9.png create mode 100644 src/static/style/mixin-svg.scss create mode 100644 src/store/index.ts create mode 100644 src/store/useServeInfoStore/actions.ts create mode 100644 src/store/useServeInfoStore/getters.ts create mode 100644 src/store/useServeInfoStore/index.ts create mode 100644 src/store/useServeInfoStore/mutations.ts create mode 100644 src/store/useStoreInfoStore/actions.ts create mode 100644 src/store/useStoreInfoStore/getters.ts create mode 100644 src/store/useStoreInfoStore/index.ts create mode 100644 src/store/useStoreInfoStore/mutations.ts create mode 100644 src/subPages/agreement/about.vue create mode 100644 src/subPages/agreement/privacy.vue create mode 100644 src/subPages/agreement/user.vue create mode 100644 src/subPages/login/bindSNS/bindSNS.vue create mode 100644 src/subPages/login/codeLogin/codeLogin.vue create mode 100644 src/subPages/login/index.scss create mode 100644 src/subPages/login/index.vue create mode 100644 src/subPages/login/paswordLogin/paswordLogin.vue create mode 100644 src/subPages/login/weixin.ts create mode 100644 src/subPages/login/wxLogin/wxLogin.scss create mode 100644 src/subPages/login/wxLogin/wxLogin.ts create mode 100644 src/subPages/login/wxLogin/wxLogin.vue create mode 100644 src/subPages/merchantChild/accountBalance/accountBalance.vue create mode 100644 src/subPages/merchantChild/activity/activity.vue create mode 100644 src/subPages/merchantChild/bill/bill.scss create mode 100644 src/subPages/merchantChild/bill/bill.vue create mode 100644 src/subPages/merchantChild/billDetaile/billDetaile.vue create mode 100644 src/subPages/merchantChild/businessLicense/businessLicense.scss create mode 100644 src/subPages/merchantChild/businessLicense/businessLicense.ts create mode 100644 src/subPages/merchantChild/businessLicense/businessLicense.vue create mode 100644 src/subPages/merchantChild/enterGroupChat/enterGroupChat.vue create mode 100644 src/subPages/merchantChild/evaluateM/commentList/commentList.scss create mode 100644 src/subPages/merchantChild/evaluateM/commentList/commentList.vue create mode 100644 src/subPages/merchantChild/evaluateM/evaluateM.vue create mode 100644 src/subPages/merchantChild/evaluateM/tabs/tabs.vue create mode 100644 src/subPages/merchantChild/helpCenter/helpCenter.vue create mode 100644 src/subPages/merchantChild/invoice/invoice.vue create mode 100644 src/subPages/merchantChild/message/message.scss create mode 100644 src/subPages/merchantChild/message/message.vue create mode 100644 src/subPages/merchantChild/messageDetail/messageDetail.scss create mode 100644 src/subPages/merchantChild/messageDetail/messageDetail.vue create mode 100644 src/subPages/merchantChild/modifyPrice/modifyPrice.scss create mode 100644 src/subPages/merchantChild/modifyPrice/modifyPrice.vue create mode 100644 src/subPages/merchantChild/orderRealTime/orderRealTime.scss create mode 100644 src/subPages/merchantChild/orderRealTime/orderRealTime.ts create mode 100644 src/subPages/merchantChild/orderRealTime/orderRealTime.vue create mode 100644 src/subPages/merchantChild/payeeInfo/payeeInfo.vue create mode 100644 src/subPages/merchantChild/platformDetail/index.scss create mode 100644 src/subPages/merchantChild/platformDetail/index.vue create mode 100644 src/subPages/merchantChild/platformM/platformM.scss create mode 100644 src/subPages/merchantChild/platformM/platformM.vue create mode 100644 src/subPages/merchantChild/printerSetUp/printerSetUp.scss create mode 100644 src/subPages/merchantChild/printerSetUp/printerSetUp.ts create mode 100644 src/subPages/merchantChild/printerSetUp/printerSetUp.vue create mode 100644 src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.scss create mode 100644 src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.ts create mode 100644 src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.vue create mode 100644 src/subPages/merchantChild/setBusinessTime/setBusinessTime.scss create mode 100644 src/subPages/merchantChild/setBusinessTime/setBusinessTime.ts create mode 100644 src/subPages/merchantChild/setBusinessTime/setBusinessTime.vue create mode 100644 src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.scss create mode 100644 src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.ts create mode 100644 src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.vue create mode 100644 src/subPages/merchantChild/setUp/setUp.scss create mode 100644 src/subPages/merchantChild/setUp/setUp.ts create mode 100644 src/subPages/merchantChild/setUp/setUp.vue create mode 100644 src/subPages/merchantChild/shareStore/shareStore.scss create mode 100644 src/subPages/merchantChild/shareStore/shareStore.vue create mode 100644 src/subPages/merchantChild/storeScore/storeScore.scss create mode 100644 src/subPages/merchantChild/storeScore/storeScore.vue create mode 100644 src/subPages/merchantChild/storeScoreDetaile/storeScoreDetaile.vue create mode 100644 src/subPages/merchantChild/useInfo/useInfo.vue create mode 100644 src/subPages/merchantChild/waitGoods/waitGoods.scss create mode 100644 src/subPages/merchantChild/waitGoods/waitGoods.vue create mode 100644 src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.scss create mode 100644 src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.vue create mode 100644 src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.scss create mode 100644 src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.vue create mode 100644 src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.ts create mode 100644 src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.vue create mode 100644 src/subPages/messageChild/appPlay/appPlay.vue create mode 100644 src/subPages/messageChild/msgChat/msgChat.ts create mode 100644 src/subPages/messageChild/msgChat/msgChat.vue create mode 100644 src/subPages/messageChild/msgChat/msgChatChild/chat-item.vue create mode 100644 src/subPages/messageChild/msgChat/msgChatChild/index.scss create mode 100644 src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.scss create mode 100644 src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.ts create mode 100644 src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.vue create mode 100644 src/subPages/orderChild/complaint/complaint.vue create mode 100644 src/subPages/orderChild/createAfterSales/createAfterSales.scss create mode 100644 src/subPages/orderChild/createAfterSales/createAfterSales.ts create mode 100644 src/subPages/orderChild/createAfterSales/createAfterSales.vue create mode 100644 src/subPages/orderChild/deliverManager/deliverManager.scss create mode 100644 src/subPages/orderChild/deliverManager/deliverManager.ts create mode 100644 src/subPages/orderChild/deliverManager/deliverManager.vue create mode 100644 src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.scss create mode 100644 src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.ts create mode 100644 src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.vue create mode 100644 src/subPages/orderChild/getPhone/getPhone.vue create mode 100644 src/subPages/orderChild/orderDetail/detailChild/goodsList.vue create mode 100644 src/subPages/orderChild/orderDetail/detailChild/goodsRefund.vue create mode 100644 src/subPages/orderChild/orderDetail/orderDetail.scss create mode 100644 src/subPages/orderChild/orderDetail/orderDetail.ts create mode 100644 src/subPages/orderChild/orderDetail/orderDetail.vue create mode 100644 src/subPages/orderChild/seeMap/seeMap.vue create mode 100644 src/subPages/shoppingChild/createGoods/createGoods.scss create mode 100644 src/subPages/shoppingChild/createGoods/createGoods.ts create mode 100644 src/subPages/shoppingChild/createGoods/createGoods.vue create mode 100644 src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-filter/create-goods-filter.vue create mode 100644 src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-search/create-goods-search.vue create mode 100644 src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.scss create mode 100644 src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.ts create mode 100644 src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.vue create mode 100644 src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.scss create mode 100644 src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.vue create mode 100644 src/subPages/switchStore/switchStore.scss create mode 100644 src/subPages/switchStore/switchStore.ts create mode 100644 src/subPages/switchStore/switchStore.vue create mode 100644 src/uni.scss create mode 100644 src/uni_modules/uv-datetime-picker/changelog.md create mode 100644 src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js create mode 100644 src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue create mode 100644 src/uni_modules/uv-datetime-picker/package.json create mode 100644 src/uni_modules/uv-datetime-picker/readme.md create mode 100644 src/uni_modules/uv-icon/changelog.md create mode 100644 src/uni_modules/uv-icon/components/uv-icon/icons.js create mode 100644 src/uni_modules/uv-icon/components/uv-icon/props.js create mode 100644 src/uni_modules/uv-icon/components/uv-icon/uniicons.css create mode 100644 src/uni_modules/uv-icon/components/uv-icon/uv-icon.vue create mode 100644 src/uni_modules/uv-icon/components/uv-icon/uvicons.ttf create mode 100644 src/uni_modules/uv-icon/package.json create mode 100644 src/uni_modules/uv-icon/readme.md create mode 100644 src/uni_modules/uv-loading-icon/changelog.md create mode 100644 src/uni_modules/uv-loading-icon/components/uv-loading-icon/props.js create mode 100644 src/uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue create mode 100644 src/uni_modules/uv-loading-icon/package.json create mode 100644 src/uni_modules/uv-loading-icon/readme.md create mode 100644 src/uni_modules/uv-overlay/changelog.md create mode 100644 src/uni_modules/uv-overlay/components/uv-overlay/props.js create mode 100644 src/uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue create mode 100644 src/uni_modules/uv-overlay/package.json create mode 100644 src/uni_modules/uv-overlay/readme.md create mode 100644 src/uni_modules/uv-picker/changelog.md create mode 100644 src/uni_modules/uv-picker/components/uv-picker/props.js create mode 100644 src/uni_modules/uv-picker/components/uv-picker/uv-picker.vue create mode 100644 src/uni_modules/uv-picker/components/uv-toolbar/props.js create mode 100644 src/uni_modules/uv-picker/components/uv-toolbar/uv-toolbar.vue create mode 100644 src/uni_modules/uv-picker/package.json create mode 100644 src/uni_modules/uv-picker/readme.md create mode 100644 src/uni_modules/uv-popup/changelog.md create mode 100644 src/uni_modules/uv-popup/components/uv-popup/keypress.js create mode 100644 src/uni_modules/uv-popup/components/uv-popup/props.js create mode 100644 src/uni_modules/uv-popup/components/uv-popup/uv-popup.vue create mode 100644 src/uni_modules/uv-popup/package.json create mode 100644 src/uni_modules/uv-popup/readme.md create mode 100644 src/uni_modules/uv-safe-bottom/changelog.md create mode 100644 src/uni_modules/uv-safe-bottom/components/uv-safe-bottom/uv-safe-bottom.vue create mode 100644 src/uni_modules/uv-safe-bottom/package.json create mode 100644 src/uni_modules/uv-safe-bottom/readme.md create mode 100644 src/uni_modules/uv-status-bar/changelog.md create mode 100644 src/uni_modules/uv-status-bar/components/uv-status-bar/props.js create mode 100644 src/uni_modules/uv-status-bar/components/uv-status-bar/uv-status-bar.vue create mode 100644 src/uni_modules/uv-status-bar/package.json create mode 100644 src/uni_modules/uv-status-bar/readme.md create mode 100644 src/uni_modules/uv-transition/changelog.md create mode 100644 src/uni_modules/uv-transition/components/uv-transition/createAnimation.js create mode 100644 src/uni_modules/uv-transition/components/uv-transition/uv-transition.vue create mode 100644 src/uni_modules/uv-transition/package.json create mode 100644 src/uni_modules/uv-transition/readme.md create mode 100644 src/uni_modules/uv-ui-tools/changelog.md create mode 100644 src/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue create mode 100644 src/uni_modules/uv-ui-tools/index.js create mode 100644 src/uni_modules/uv-ui-tools/index.scss create mode 100644 src/uni_modules/uv-ui-tools/libs/config/config.js create mode 100644 src/uni_modules/uv-ui-tools/libs/css/color.scss create mode 100644 src/uni_modules/uv-ui-tools/libs/css/common.scss create mode 100644 src/uni_modules/uv-ui-tools/libs/css/components.scss create mode 100644 src/uni_modules/uv-ui-tools/libs/css/variable.scss create mode 100644 src/uni_modules/uv-ui-tools/libs/css/vue.scss create mode 100644 src/uni_modules/uv-ui-tools/libs/function/colorGradient.js create mode 100644 src/uni_modules/uv-ui-tools/libs/function/debounce.js create mode 100644 src/uni_modules/uv-ui-tools/libs/function/digit.js create mode 100644 src/uni_modules/uv-ui-tools/libs/function/index.js create mode 100644 src/uni_modules/uv-ui-tools/libs/function/platform.js create mode 100644 src/uni_modules/uv-ui-tools/libs/function/test.js create mode 100644 src/uni_modules/uv-ui-tools/libs/function/throttle.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/index.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/utils.js create mode 100644 src/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js create mode 100644 src/uni_modules/uv-ui-tools/libs/mixin/button.js create mode 100644 src/uni_modules/uv-ui-tools/libs/mixin/mixin.js create mode 100644 src/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js create mode 100644 src/uni_modules/uv-ui-tools/libs/mixin/mpShare.js create mode 100644 src/uni_modules/uv-ui-tools/libs/mixin/openType.js create mode 100644 src/uni_modules/uv-ui-tools/libs/mixin/touch.js create mode 100644 src/uni_modules/uv-ui-tools/libs/util/dayjs.js create mode 100644 src/uni_modules/uv-ui-tools/libs/util/route.js create mode 100644 src/uni_modules/uv-ui-tools/package.json create mode 100644 src/uni_modules/uv-ui-tools/readme.md create mode 100644 src/uni_modules/uv-ui-tools/theme.scss create mode 100644 src/utils/bluetoothPrinter/bluetooth.js create mode 100644 src/utils/bluetoothPrinter/commands.js create mode 100644 src/utils/bluetoothPrinter/gbk.js create mode 100644 src/utils/bluetoothPrinter/printerOrder.ts create mode 100644 src/utils/bluetoothPrinter/printerTemplate.ts create mode 100644 src/utils/bluetoothPrinter/printerjobs.js create mode 100644 src/utils/bluetoothPrinter/printerutil.js create mode 100644 src/utils/bluetoothPrinter/util.js create mode 100644 src/utils/configCms.ts create mode 100644 src/utils/emoji.ts create mode 100644 src/utils/log.js create mode 100644 src/utils/md5.js create mode 100644 src/utils/qiniuUploader.ts create mode 100644 src/utils/storage.ts create mode 100644 src/utils/toast.ts create mode 100644 src/utils/tools.ts create mode 100644 src/utils/weapp.qrcode.esm.js create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2561bb4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules/ +unpackage/ +dist/ + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.project +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..a1c56ae --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,27 @@ +{ + // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version" : "0.0", + "configurations" : [ + { + "app-plus" : { + "launchtype" : "local" + }, + "default" : { + "launchtype" : "local" + }, + "mp-weixin" : { + "launchtype" : "local" + }, + "type" : "uniCloud" + }, + { + "playground" : "custom", + "type" : "uni-app:app-android" + }, + { + "playground" : "custom", + "type" : "uni-app:app-ios" + } + ] +} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..1ad9917 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "semi": false, + "trailingComma": "none" +} \ No newline at end of file diff --git a/.stignore b/.stignore new file mode 100644 index 0000000..ac33e3c --- /dev/null +++ b/.stignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +.git/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..7b1419e --- /dev/null +++ b/README.md @@ -0,0 +1,353 @@ +# 京西菜市商家版 +- 开发: + 张树伟 +- 日期: + 2022年12月05日 +- 项目说明: + 京西菜市商家版本,兼容《微信小程序》《Android》《Ios》 +- 技术栈:Vue3/VueX/Ts/Vite/UniApp +- 【注意】:请勿使用pinia +- node版本:16.18.0 + +## 项目仓库名字 +- jx-Applets-Android-Ios + +## 微信小程序 +- 分支名字:微信小程序 +- https://e.coding.net/rosydev/jx-Applets-Android-Ios/zsw-jx-store.git + +## 苹果安卓App +- 分支名字:苹果和微信 +- https://e.coding.net/rosydev/jx-Applets-Android-Ios/zsw-jx-store.git + +## 主分支master +- 微信小程序和苹果安卓App都是从主分支分出来的,主分支受到保护不允许修改,分支不允许合并 + +# 目录解构 +- 【注意】:由于是小程序与App公用这个书名文件,可能有些文件没有 +``` +├── dist # 编译后的文件 +├── nativeplugins # 原生插件 +├── node_modules # 依赖文件 +├── src # 项目文件 +│ │ +│ ├── api # api接口管理 +│ │ │ +│ │ ├── https # 分模块接口管理 +│ │ │ ├── login.ts # 登录类接口 +│ │ │ ├── merchant.ts # 商家管理类接口 +│ │ │ ├── order.ts # 订单管理类接口 +│ │ │ └── shopping.ts # 商品管理类接口 +│ │ │ +│ │ ├── config.ts # 环境配置文件 +│ │ ├── index.ts # 接汇总导出文件 +│ │ └── request.ts # 接口请求文件 +│ │ +│ ├── components # 组件 +│ │ │ +│ │ ├── dialog # 兼容安卓自定义弹窗 +│ │ ├── globalAlert # 兼容安卓与IOS全局弹窗 +│ │ ├── jx-empty # 空状态占位组件 +│ │ ├── jx-icon # icon图标组件 +│ │ ├── jx-input # 三段式input输入组件 +│ │ ├── jx-ios-android # 安卓与ios渲染判断组件 +│ │ ├── jx-loading # 数据加载loading组件 +│ │ ├── jx-load-more # 上拉加载更多展示组件 +│ │ ├── jx-login-empty # 未登录展示组件 +│ │ ├── jx-price # 自动格式化价格组件 +│ │ ├── jx-real-income # 京西菜市订单单价组件 +│ │ ├── jx-real-income-jxgy # 京西果园订单单价组件 +│ │ ├── jx-update # 软件更新组件 +│ │ └── jx-upload-img # 七牛云图片上传组件 +│ │ +│ ├── composables # 公共hooks +│ │ │ +│ │ ├── useGlobalFunc.ts # 全局公用 hooks +│ │ └── useOrderInfo.ts # 订单专用 hooks +│ │ +│ ├── pages # tabbar页面 +│ │ │ +│ │ ├── goods-manager # 商品管理页面 +│ │ ├── merchant # 商家中心页面 +│ │ └── order-manager # 订单管理页面 +│ │ +│ ├── static # 静态文件 +│ │ │ +│ │ ├── agreement # 静态版权文件 +│ │ ├── audio # 项目音频文件 +│ │ ├── font # 项目图标文件 +│ │ ├── image # 项目图片文件 +│ │ ├── merchant-icon # 商家中心图标文件 +│ │ └── style # 公共样式文件 +│ │ +│ ├── store # vuex状态管理 +│ │ │ +│ │ ├── useServeInfoStore # 项目服务类vuex模块 +│ │ ├── useStoreInfoStore # 项目门店类vuex模块 +│ │ └── index.ts # vuex 入口文件 +│ │ +│ ├── subPages # 分包页面 +│ │ │ +│ │ ├── agreement # 静态版权文件 +│ │ ├── login # 登录相关类页面 +│ │ ├── merchantChild # 商家中心类子页面 +│ │ │ │ +│ │ │ ├── activity # 活动信息页面 +│ │ │ ├── backstageApp # 后天运行能力页面 +│ │ │ ├── bill # 我的账单页面 +│ │ │ ├── billDetaile # 账单详情页面 +│ │ │ ├── businessLicense # 营业资质页面 +│ │ │ ├── enterGroupChat # 进入群聊页面 +│ │ │ ├── evaluateM # 评价管理页面 +│ │ │ ├── helpCenter # 帮助中心页面 +│ │ │ ├── message # 消息列表页面 +│ │ │ ├── messageDetail # 消息详情页面 +│ │ │ ├── modifyPrice # 调价包页面 +│ │ │ ├── orderRealTime # 京西菜市营业数据页面 +│ │ │ ├── orderRealTimeJxgy # 京西果园营业数据页面 +│ │ │ ├── platformM # 已开通店铺店铺页面 +│ │ │ ├── printerSetUp # 蓝牙打印机设置页面 +│ │ │ ├── setUp # 设置页面 +│ │ │ ├── storeScore # 门店评分页面 +│ │ │ ├── storeScoreDetaile # 评分详情页面 +│ │ │ ├── useInfo # 个人信息页面 +│ │ │ ├── waitGoods # 待配商品页面 +│ │ │ ├── accountBalance # 配送余额 +│ │ │ └── waitGoodsDetaile # 商品详情页面 +│ │ │ +│ │ ├── orderChild # 订单类子页面 +│ │ │ │ +│ │ │ ├── afterSalesOrderDetail # 售后订单页面 +│ │ │ ├── createAfterSales # 异常订单页面 +│ │ │ ├── deliverManager # 配送管理页面 +│ │ │ ├── getPhone # 联系平台页面 +│ │ │ └── orderDetail # 订单详情页面 +│ │ │ +│ │ ├── shoppingChild # 商品管理类子页面 +│ │ │ │ +│ │ │ └── createGoods # 创建商品 +│ │ │ +│ │ └── switchStore # 切换门店 +│ │ +│ ├── utils # 工具 +│ │ │ +│ │ ├── bluetoothPrinter # 蓝牙打印机类工具 +│ │ ├── android_ios.ts # 安卓插件类工具 +│ │ ├── configCms.ts # 项目系统配置文件 +│ │ ├── location.ts # 本地存储工具 +│ │ ├── toast.ts # 公共请提示工具 +│ │ └── tools.ts # 混合类处理工具 +│ │ +│ ├── androidPrivacy.json # 安卓打包文件 +│ ├── App.ts # 根组件逻辑 +│ ├── App.vue # 根组件页面 +│ ├── apple-app-site-association # ios 关联域 +│ ├── env.d.ts # type 授权文件 +│ ├── main.ts # 入口文件 +│ ├── manifest.json # 打包配置文件 +│ ├── pages.json # 页面路径配置 +│ └── uni.scss # 公共样式 +│ +├── package-lock.json # *** +├── package.json # 包管理文件 +├── README.md # README +├── tsconfig.node.json # ts配置文件 +└── vite.config.ts # vite 配置 +``` + +# 路径管理 + +## 验证登录 + + +路径: +/subPages/login/index + +### 选择门店 + + +路径: +/subPages/switchStore/switchStore + +#### 商家中心 + + +##### 帮助中心 + + +路径: +/subPages/merchantChild/helpCenter/helpCenter + +##### 营业数据 + + +###### 京西菜市 + + +路径: +/subPages/merchantChild/orderRealTime/orderRealTime + +###### 京西果园 + + +路径: +/subPages/merchantChild/orderRealTimeJxgy/orderRealTimeJxgy + +##### 已开通店铺 + + +路径: +/subPages/merchantChild/platformM/platformM + +##### 调价包 + + +路径: +/subPages/merchantChild/modifyPrice/modifyPrice + +##### 我的账单 + + +路径: +/subPages/merchantChild/bill/bill + +##### 账单详情 + + +路径: +/subPages/merchantChild/billDetaile/billDetaile + +##### 评价管理 + + +路径: +/subPages/merchantChild/evaluateM/evaluateM + +##### 门店评分 + + +路径: +/subPages/merchantChild/storeScore/storeScore + +##### 评分详情 + + +路径: +/subPages/merchantChild/storeScoreDetaile/storeScoreDetaile + +##### 待配商品 + + +路径: +/subPages/merchantChild/waitGoods/waitGoods + +##### 商品详情 + + +路径: +/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile + +##### 进入群聊 + + +路径: +/subPages/merchantChild/enterGroupChat/enterGroupChat + +##### 消息列表 + + +路径: +/subPages/merchantChild/message/message + +##### 最新消息 + + +路径: +/subPages/merchantChild/messageDetail/messageDetail + +##### 活动信息 + + +路径: +/subPages/merchantChild/activity/activity + +##### 设置 + + +路径: +/subPages/merchantChild/setUp/setUp + +##### 蓝牙打印机设置 + + +路径: +/subPages/merchantChild/printerSetUp/printerSetUp + +##### 营业资质 + + +路径: +/subPages/merchantChild/businessLicense/businessLicense + +##### 后台运行优化 + + +路径: +/subPages/merchantChild/backstageApp/backstageApp + +##### 个人信息 + + +路径: +/subPages/merchantChild/useInfo/useInfo + +##### 配送余额 + + +路径: +/subPages/merchantChild/accountBalance/accountBalance + +#### 消息 + + +#### 商品管理 + + +##### 创建商品 + + +路径: +/subPages/shoppingChild/createGoods/createGoods + +#### 订单管理 + + +##### 联系平台 + + +路劲: +/subPages/orderChild/getPhone/getPhone + +##### 订单详情 + + +路劲: +/subPages/orderChild/orderDetail/orderDetail + +##### 配送管理 + + +路劲: +/subPages/orderChild/deliverManager/deliverManager + +##### 售后详情 + + +路劲: +/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail + +##### 创建售后订单 + + +路劲: +/subPages/orderChild/createAfterSales/createAfterSales \ No newline at end of file diff --git a/dfslkf b/dfslkf new file mode 100644 index 0000000..8420b37 --- /dev/null +++ b/dfslkf @@ -0,0 +1,59 @@ +commit 7901bd96fe23f9d130bbedfe0bc441fab52fc59e (HEAD -> master, origin/master, origin/HEAD) +Author: ZSW <2966211270@qq.com> +Date: Wed Jan 4 18:39:57 2023 +0800 + + 2023-01-04提交 + +commit f6d6996ffbad8d07f1b129f3f1304c819c53e561 +Author: ZSW <2966211270@qq.com> +Date: Tue Jan 3 18:43:00 2023 +0800 + + ! + +commit 9b41c0ff3a3c875ef455e2d5e8958568f21face2 +Author: ZSW <2966211270@qq.com> +Date: Fri Dec 30 18:32:55 2022 +0800 + + 开发新商家版,手写虚拟列表 + +commit 9658b3d85f6f872d7b72102a3448b52c29bd456d +Author: ZSW <2966211270@qq.com> +Date: Wed Dec 28 18:34:01 2022 +0800 + + ! + +commit 79b2c5bdb5137a457f5f9f690f7ac6b4ac020ca7 +Author: ZSW <2966211270@qq.com> +Date: Tue Dec 27 18:34:44 2022 +0800 + + 重写京西菜市商家版 + +commit 1b8cf88cc744e9f0726645082a26124f6567baa6 +Author: ZSW <2966211270@qq.com> +Date: Mon Dec 26 18:38:37 2022 +0800 + + 新京西菜市商家版开发中 + +commit 7270386733f06f60a35ebd538b49b5dc6a9af967 +Author: ZSW <2966211270@qq.com> +Date: Thu Dec 15 11:53:30 2022 +0800 + + ! + +commit dd19476dcecbe77d51d14bd4b25254b1f737b535 +Author: ZSW <2966211270@qq.com> +Date: Mon Dec 12 18:29:15 2022 +0800 + + 登录界面向店铺切换兼容已经处理 + +commit 38c0633c4276496845d87e8193fc5f9c121ac051 +Author: ZSW <2966211270@qq.com> +Date: Fri Dec 9 18:53:54 2022 +0800 + + 创建新编京西菜市商家版,兼容微信小程序,安卓App,iso + +commit 6095cb13ce5472a9ea46781bf0be4c4c8b107117 +Author: 张树伟 <2966211270@qq.com> +Date: Fri Dec 9 18:50:54 2022 +0800 + + Initial Commit diff --git a/index.html b/index.html new file mode 100644 index 0000000..2b9bfe5 --- /dev/null +++ b/index.html @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cf75248 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7014 @@ +{ + "name": "uni-preset-vue", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "uni-preset-vue", + "version": "0.0.0", + "dependencies": { + "@dcloudio/uni-app": "3.0.0-3061820230117001", + "@dcloudio/uni-app-plus": "3.0.0-3061820230117001", + "@dcloudio/uni-components": "3.0.0-3061820230117001", + "@dcloudio/uni-h5": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-alipay": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-baidu": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-kuaishou": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-lark": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-qq": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-toutiao": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-weixin": "3.0.0-3061820230117001", + "@dcloudio/uni-quickapp-webview": "3.0.0-3061820230117001", + "@dcloudio/uni-ui": "^1.4.23", + "@rollup/plugin-commonjs": "^25.0.1", + "add": "^2.0.6", + "crypto-js": "^4.1.1", + "js-md5": "^0.7.3", + "vue": "3.2.45", + "vue-i18n": "9.2.2", + "vuex": "^4.0.2" + }, + "devDependencies": { + "@dcloudio/types": "3.2.11", + "@dcloudio/uni-automator": "3.0.0-3061820230117001", + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-stacktracey": "3.0.0-3061820230117001", + "@dcloudio/vite-plugin-uni": "3.0.0-3061820230117001", + "@types/js-md5": "^0.4.3", + "@types/node": "^18.11.11", + "sass": "^1.56.1", + "typescript": "^4.8.4", + "vite": "3.2.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "dependencies": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "dependencies": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", + "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", + "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.20.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-typescript": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/standalone": { + "version": "7.20.6", + "resolved": "https://registry.npmmirror.com/@babel/standalone/-/standalone-7.20.6.tgz", + "integrity": "sha512-u5at/CbBLETf7kx2LOY4XdhseD79Y099WZKAOMXeT8qvd9OSR515my2UNBBLY4qIht/Qi9KySeQHQwQwxJN4Sw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@dcloudio/types": { + "version": "3.2.11", + "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.2.11.tgz", + "integrity": "sha512-Ws+pUiQMvCcSjg0soF+vTTwwsdNlK/1cxIfo5LBBDFPoXfUAAh6k9HnCt5cudERNhY0M3wE7ATMx/1Cb9bmUig==" + }, + "node_modules/@dcloudio/uni-app": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app/-/uni-app-3.0.0-3061820230117001.tgz", + "integrity": "sha512-djQ/vtYqjbwctrs4DMQPTKAY1+8mb3MVCJqO6tis34jIOkMUqI/weB4VxZyR1rMT+bahaNtwKrUMr5bNUktArw==", + "dependencies": { + "@dcloudio/uni-cloud": "3.0.0-3061820230117001", + "@dcloudio/uni-components": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-push": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-stat": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + }, + "peerDependencies": { + "@dcloudio/types": "^3.0.20" + } + }, + "node_modules/@dcloudio/uni-app-plus": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-plus/-/uni-app-plus-3.0.0-3061820230117001.tgz", + "integrity": "sha512-+0/CEKKBOq+5jiZsi1Lz9B7rPN781VShJaQY6Urgp5t4ne5sAF68XW00whHKGwdOlloIVHXN4qdblUP7qO9GGw==", + "dependencies": { + "@dcloudio/uni-app-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-app-vue": "3.0.0-3061820230117001" + } + }, + "node_modules/@dcloudio/uni-app-vite": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vite/-/uni-app-vite-3.0.0-3061820230117001.tgz", + "integrity": "sha512-KMMOIzvTxjOnvX15JBLWULXKMU+pBQ/GTerM0KsNEMUnhKo5F8WuO6ZPQBUBgnncD+iQyGbAYn2IWlrRY+ftiQ==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-nvue-styler": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@rollup/pluginutils": "^4.2.0", + "@vitejs/plugin-vue": "^3.2.0", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "debug": "^4.3.3", + "fs-extra": "^10.0.0", + "picocolors": "^1.0.0", + "rollup": "^2.79.1" + } + }, + "node_modules/@dcloudio/uni-app-vue": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vue/-/uni-app-vue-3.0.0-3061820230117001.tgz", + "integrity": "sha512-+EXrTPN13Dt6t8/mdTPsIwKoeekl36S6Rq7Qq+oEVN937BHapRZ8BifwwbRkZI/lvPs3oLS8M4LlH17pEQ2ljg==" + }, + "node_modules/@dcloudio/uni-automator": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-automator/-/uni-automator-3.0.0-3061820230117001.tgz", + "integrity": "sha512-28Li+A3vXHxK34xcyoQyXCy/2NXtpGqc2XUf4Hm73X/cl2zXyUy5oClzolsWQlnN1gAqQhagcHLu4h+zc7J1Dw==", + "dev": true, + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "address": "^1.1.2", + "cross-env": "^7.0.3", + "debug": "^4.3.3", + "default-gateway": "^6.0.3", + "fs-extra": "^10.0.0", + "licia": "^1.29.0", + "postcss-selector-parser": "^6.0.6", + "qrcode-reader": "^1.0.4", + "qrcode-terminal": "^0.12.0", + "ws": "^8.4.2" + } + }, + "node_modules/@dcloudio/uni-cli-shared": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-3.0.0-3061820230117001.tgz", + "integrity": "sha512-MOk7IG2U6iMF4t+2hZsCpWC+ulkC5jU556C9Vh9qpq5ofjs4vqeQ3irz+Z+XcysG6oaneL53pXx0saItQey7fA==", + "dependencies": { + "@ampproject/remapping": "^2.1.2", + "@babel/core": "^7.19.6", + "@babel/parser": "^7.19.6", + "@babel/types": "^7.20.0", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@intlify/core-base": "9.1.9", + "@intlify/shared": "9.1.9", + "@intlify/vue-devtools": "9.1.9", + "@rollup/pluginutils": "^4.2.0", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45", + "autoprefixer": "^10.4.13", + "base64url": "^3.0.1", + "chokidar": "^3.5.3", + "compare-versions": "^3.6.0", + "debug": "^4.3.3", + "es-module-lexer": "^0.9.3", + "esbuild": "^0.15.9", + "estree-walker": "^2.0.2", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.0", + "hash-sum": "^2.0.0", + "jsonc-parser": "^3.0.0", + "magic-string": "^0.26.7", + "merge": "^2.1.1", + "mime": "^3.0.0", + "module-alias": "^2.2.2", + "os-locale-s-fix": "^1.0.8-fix-1", + "picocolors": "^1.0.0", + "postcss-import": "^14.0.2", + "postcss-load-config": "^3.1.1", + "postcss-modules": "^4.3.0", + "postcss-selector-parser": "^6.0.6", + "resolve": "^1.22.1", + "tapable": "^2.2.0", + "xregexp": "3.1.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + } + }, + "node_modules/@dcloudio/uni-cloud": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cloud/-/uni-cloud-3.0.0-3061820230117001.tgz", + "integrity": "sha512-YeDLoA3DTfuU6kSpFk96AIcJKtvbJbGcF+bbZBtW9htkKx7zhpDRTL0Q5zOqsGU9YJn8i3h79k/rusM0XpoG6g==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45", + "fast-glob": "^3.2.11" + } + }, + "node_modules/@dcloudio/uni-components": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-components/-/uni-components-3.0.0-3061820230117001.tgz", + "integrity": "sha512-QL24hL7EzgZj5bNF7xMCg85EVveSaOfb7aYBsSs/3Gv6iq9cXurh7jRA/nJyhb+7G9yt7H3ab9b6DvP/XjwFCg==" + }, + "node_modules/@dcloudio/uni-h5": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-3.0.0-3061820230117001.tgz", + "integrity": "sha512-C600DG4DTVkIPvlPcnR/Z2DiyQnk30zQWrGNjotjH0OZPlInDxvBikXxOStAhbHA9/0sJAb++ZQiDAME2c85HA==", + "dependencies": { + "@dcloudio/uni-h5-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-h5-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45", + "localstorage-polyfill": "^1.0.1", + "safe-area-insets": "^1.4.1", + "vue-router": "^4.1.6", + "xmlhttprequest": "^1.8.0" + } + }, + "node_modules/@dcloudio/uni-h5-vite": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vite/-/uni-h5-vite-3.0.0-3061820230117001.tgz", + "integrity": "sha512-vdyx0Hd5dNWydgElNtZz3cgPJYGUDa1e7TGcpVubcnX6Dda6WhxZhidughyx76j0G/nADY9d7vBZFhA0Xg8nNg==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@rollup/pluginutils": "^4.2.0", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45", + "debug": "^4.3.3", + "fs-extra": "^10.0.0", + "mime": "^3.0.0", + "module-alias": "^2.2.2" + } + }, + "node_modules/@dcloudio/uni-h5-vue": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vue/-/uni-h5-vue-3.0.0-3061820230117001.tgz", + "integrity": "sha512-HsO8I2RfR/87QEmop0T+Heaso/j4FryQrnxzu2mJA2oCtq4sPs3uJvaTA7V2rpYFKsXUVE4rMRq+FkjHCAIlGA==", + "dependencies": { + "@dcloudio/uni-shared": "3.0.0-3061820230117001" + } + }, + "node_modules/@dcloudio/uni-i18n": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-i18n/-/uni-i18n-3.0.0-3061820230117001.tgz", + "integrity": "sha512-Zi9W62ASUJ5302mXi9Ux4cM2cesmmzluYdAUMYyWWhgsycaIMbI8tYEWlIk5j6KAap7Be2hxgIo/O34X9IzJCA==" + }, + "node_modules/@dcloudio/uni-mp-alipay": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-alipay/-/uni-mp-alipay-3.0.0-3061820230117001.tgz", + "integrity": "sha512-Me5Zw6lxr8L0J1g7cTmTVlICW5xjrC4gT15IKjs2ZLVnxpiU/t7J/WbE2KKOHg8mRMDmM77k88PL+MmLMJrc7g==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-mp-baidu": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-baidu/-/uni-mp-baidu-3.0.0-3061820230117001.tgz", + "integrity": "sha512-dCZ+wrh06JvxCAYXvL8WsZDEUz8IQVGD25TAgJ8Uez+CWTScmYYrO6/gP5u6o5a/rAR85ldI1Pv4Xlqyp95MXg==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-weixin": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-mp-compiler": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-compiler/-/uni-mp-compiler-3.0.0-3061820230117001.tgz", + "integrity": "sha512-wxPSdSXs5y+3QPLuxcp3TOzV33/NiBkewWAN0Mij33dLiErZrjRvvUuef7MptOzgc1TJoQizzS5f0PKYmqnhNg==", + "dependencies": { + "@babel/generator": "^7.19.6", + "@babel/parser": "^7.19.6", + "@babel/types": "^7.20.0", + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2" + } + }, + "node_modules/@dcloudio/uni-mp-kuaishou": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-kuaishou/-/uni-mp-kuaishou-3.0.0-3061820230117001.tgz", + "integrity": "sha512-u9vsslqwWmxSSVtHUNIDADXLeumNzSs/L0JlYlX7ofgPEoVLwQqBIRxKoR/RdDtiywPYS9J3VzGeArD9LdZefw==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-weixin": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-mp-lark": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-lark/-/uni-mp-lark-3.0.0-3061820230117001.tgz", + "integrity": "sha512-dZKho5F15CzNZqIALDzlG1GX3Ny5R0zqMYd1Ny6J/rcmtPbxXblHb5uGxBYbDTv3z7/yjRqoqQCQk+9tW9Lb/g==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-toutiao": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-mp-qq": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-qq/-/uni-mp-qq-3.0.0-3061820230117001.tgz", + "integrity": "sha512-MmPR703fqxz8uvqHvagAGPSS8whIf9pxPerbaM1AVXiQfiawOxyhqyIxlIvTFDMbA0Nyq0Zd2U+KjT5yn4f9LQ==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45", + "fs-extra": "^10.0.0" + } + }, + "node_modules/@dcloudio/uni-mp-toutiao": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-toutiao/-/uni-mp-toutiao-3.0.0-3061820230117001.tgz", + "integrity": "sha512-5tKFOXv4JTKA1pfGoWD8AwN28RAe6cPRxSaUkLsNdIzldZ3fozX6vrsfOMkUBSQwcp9au35q5X+mk+KPesBnnA==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-mp-vite": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vite/-/uni-mp-vite-3.0.0-3061820230117001.tgz", + "integrity": "sha512-zyX0DD8NZm7S1qXGp6dUNqK7klkDx4M9onxT61ilSEwCdBHCEs33zjDT/EIyWLXC+8uis+3KmlAUZUgkwXzx1A==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-sfc": "3.2.45", + "@vue/shared": "3.2.45", + "debug": "^4.3.3" + } + }, + "node_modules/@dcloudio/uni-mp-vue": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vue/-/uni-mp-vue-3.0.0-3061820230117001.tgz", + "integrity": "sha512-J/wAfFh269Lx3nZ5CEJonq3dzAxeM1uc+pnGs1MQwBT3ZK8TNopYRUgri4hrEF+srVuCcZWM9RNw8RXsSBosaw==", + "dependencies": { + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-mp-weixin": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-weixin/-/uni-mp-weixin-3.0.0-3061820230117001.tgz", + "integrity": "sha512-qH4TbUPcqCccso8YIir9r9Vu/dyD9VrK3btAWxXY39gq6AahHomO5Y0Jl4+ODvS2qeQMBIDGyg5twL3G+uKPpw==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-nvue-styler": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-nvue-styler/-/uni-nvue-styler-3.0.0-3061820230117001.tgz", + "integrity": "sha512-tAR+wYThaojYFCg2aUv3G6nva9DMDIOkeYZ4WeCTf3cO+V1PAETElJEiPa3De5Apg7Jqb48SiKTFTm9PX9yxUw==", + "dependencies": { + "@vue/shared": "3.2.45", + "parse-css-font": "^4.0.0", + "postcss": "^8.4.18" + } + }, + "node_modules/@dcloudio/uni-push": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-push/-/uni-push-3.0.0-3061820230117001.tgz", + "integrity": "sha512-ilhEPcdZSlih9/6ztm8J87XZJH82/FT0swlpz2EMq8fzRGlk1kSNy7MWpNF9QN3S2WGA/Q2TlMr9qg4buhdAHw==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001" + } + }, + "node_modules/@dcloudio/uni-quickapp-webview": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-quickapp-webview/-/uni-quickapp-webview-3.0.0-3061820230117001.tgz", + "integrity": "sha512-a1O/Wpe2lI0PHLZnDVtEzAYYZ/JGgQ8OAKbJflAD29kgVynpRKx3Imepjqsk1vk1xac2CZvi7C9MBaBA73D6Cw==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-shared": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-shared/-/uni-shared-3.0.0-3061820230117001.tgz", + "integrity": "sha512-vgvBeR5yxQ7quBOT63BN02RbfD2Si1fyll3j1SXqp37wdyRILBzaveFg8xQCMI0DdPL8kdIHTeG8d23ct6W9aQ==", + "dependencies": { + "@vue/shared": "3.2.45" + } + }, + "node_modules/@dcloudio/uni-stacktracey": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-stacktracey/-/uni-stacktracey-3.0.0-3061820230117001.tgz", + "integrity": "sha512-BDNZQWjD14BaOvzs9YU/ajX9KxOqubJXVfbwsXZnHCURNzPYE5j7EtW7Na6f9n8f79X0nkPRvEdIeKHUe3rNtw==", + "dev": true + }, + "node_modules/@dcloudio/uni-stat": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-stat/-/uni-stat-3.0.0-3061820230117001.tgz", + "integrity": "sha512-wYC/cUSEwPmSbT13PcphSywLOK+XrsYGrfRaNfDY5IdGlrHIhtX/BvsJiYh7crAsQEUhgmCcA7VvJmkiQM3DAg==", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "debug": "^4.3.3" + } + }, + "node_modules/@dcloudio/uni-ui": { + "version": "1.4.23", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-ui/-/uni-ui-1.4.23.tgz", + "integrity": "sha512-FJRkhL240gin9WvOunY38Yi2/0FzTLVlEI3dxcjzaV1oYa81o+IWEf/29YDiRrsHuvYDk9g600QgiZLC+A6ycA==" + }, + "node_modules/@dcloudio/vite-plugin-uni": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/vite-plugin-uni/-/vite-plugin-uni-3.0.0-3061820230117001.tgz", + "integrity": "sha512-ANAsCstpdd/FQUIShqYt5V8C7YC2J6LQcfqd5I7jqLiS/VTz7nC3TTA1EzsU0H7jdwJ9mvr9ro3nFXmqF2Hsmw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.19.6", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.20.0", + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@rollup/pluginutils": "^4.2.0", + "@vitejs/plugin-legacy": "^2.3.1", + "@vitejs/plugin-vue": "^3.2.0", + "@vitejs/plugin-vue-jsx": "^2.1.1", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/shared": "3.2.45", + "cac": "6.7.9", + "debug": "^4.3.3", + "estree-walker": "^2.0.2", + "express": "^4.17.1", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.0", + "hash-sum": "^2.0.0", + "jsonc-parser": "^3.0.0", + "picocolors": "^1.0.0", + "terser": "^5.4.0" + }, + "bin": { + "uni": "bin/uni.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "3.2.4" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz", + "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz", + "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@intlify/core-base": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz", + "integrity": "sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==", + "dependencies": { + "@intlify/devtools-if": "9.1.9", + "@intlify/message-compiler": "9.1.9", + "@intlify/message-resolver": "9.1.9", + "@intlify/runtime": "9.1.9", + "@intlify/shared": "9.1.9", + "@intlify/vue-devtools": "9.1.9" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@intlify/devtools-if": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz", + "integrity": "sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==", + "dependencies": { + "@intlify/shared": "9.1.9" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz", + "integrity": "sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==", + "dependencies": { + "@intlify/message-resolver": "9.1.9", + "@intlify/shared": "9.1.9", + "source-map": "0.6.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@intlify/message-resolver": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz", + "integrity": "sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@intlify/runtime": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/runtime/-/runtime-9.1.9.tgz", + "integrity": "sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==", + "dependencies": { + "@intlify/message-compiler": "9.1.9", + "@intlify/message-resolver": "9.1.9", + "@intlify/shared": "9.1.9" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@intlify/shared": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.1.9.tgz", + "integrity": "sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@intlify/vue-devtools": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz", + "integrity": "sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==", + "dependencies": { + "@intlify/message-resolver": "9.1.9", + "@intlify/runtime": "9.1.9", + "@intlify/shared": "9.1.9" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "devOptional": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "devOptional": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "25.0.1", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.1.tgz", + "integrity": "sha512-2DJ4kv4b1xfTJopWhu61ANdNRHvzQZ2fpaIrlgaP2jOfUv1wDJ0Ucqy8AZlbFmn/iUjiwKoqki9j55Y6L8kyNQ==", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.27.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + }, + "node_modules/@types/js-md5": { + "version": "0.4.3", + "resolved": "https://registry.npmmirror.com/@types/js-md5/-/js-md5-0.4.3.tgz", + "integrity": "sha512-BIga/WEqTi35ccnGysOuO4RmwVnpajv9oDB/sDQSY2b7/Ac7RyYR30bv7otZwByMvOJV9Vqq6/O1DFAnOzE4Pg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz", + "integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g==", + "devOptional": true + }, + "node_modules/@vitejs/plugin-legacy": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-2.3.1.tgz", + "integrity": "sha512-J5KaGBlSt2tEYPVjM/C8dA6DkRzkFkbPe+Xb4IX5G+XOV5OGbVAfkMjKywdrkO3gGynO8S98i71Lmsff4cWkCQ==", + "dev": true, + "dependencies": { + "@babel/standalone": "^7.20.0", + "core-js": "^3.26.0", + "magic-string": "^0.26.7", + "regenerator-runtime": "^0.13.10", + "systemjs": "^6.13.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "terser": "^5.4.0", + "vite": "^3.0.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz", + "integrity": "sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==", + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^3.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vitejs/plugin-vue-jsx": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-2.1.1.tgz", + "integrity": "sha512-JgDhxstQlwnHBvZ1BSnU5mbmyQ14/t5JhREc6YH5kWyu2QdAAOsLF6xgHoIWarj8tddaiwFrNzLbWJPudpXKYA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.19.6", + "@babel/plugin-transform-typescript": "^7.20.0", + "@vue/babel-plugin-jsx": "^1.1.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^3.0.0", + "vue": "^3.0.0" + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==", + "dev": true + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", + "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "@vue/babel-helper-vue-transform-on": "^1.0.2", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", + "dependencies": { + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7", + "postcss": "^8.1.10", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", + "dependencies": { + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.4.5", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz", + "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==" + }, + "node_modules/@vue/reactivity": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", + "dependencies": { + "@vue/shared": "3.2.45" + } + }, + "node_modules/@vue/reactivity-transform": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", + "dependencies": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + } + }, + "node_modules/@vue/reactivity-transform/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", + "dependencies": { + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", + "dependencies": { + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", + "csstype": "^2.6.8" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", + "dependencies": { + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" + }, + "peerDependencies": { + "vue": "3.2.45" + } + }, + "node_modules/@vue/shared": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "devOptional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/add": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/add/-/add-2.0.6.tgz", + "integrity": "sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==" + }, + "node_modules/address": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.13", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "devOptional": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.9", + "resolved": "https://registry.npmmirror.com/cac/-/cac-6.7.9.tgz", + "integrity": "sha512-XN5qEpfNQCJ8jRaZgitSkkukjMRCGio+X3Ks5KUbGGlPbV+pSem1l9VuzooCBXOiMFshUZgyYqg6rgN8rjkb/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001436", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001436.tgz", + "integrity": "sha512-ZmWkKsnC2ifEPoWUvSAIGyOYwT+keAaaWPHiQ9DfMqS1t6tfuyFYoWR78TeZtznkEQ64+vGXH9cZrElwR2Mrxg==" + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "devOptional": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/core-js": { + "version": "3.26.1", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.26.1.tgz", + "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", + "dev": true, + "hasInstallScript": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, + "node_modules/css-font-size-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz", + "integrity": "sha512-Q+svMDbMlelgCfH/RVDKtTDaf5021O486ZThQPIpahnIjUkMUslC+WuOQSWTgGSrNCH08Y7tYNEmmy0hkfMI8Q==" + }, + "node_modules/css-font-stretch-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz", + "integrity": "sha512-KmugPO2BNqoyp9zmBIUGwt58UQSfyk1X5DbOlkb2pckDXFSAfjsD5wenb88fNrD6fvS+vu90a/tsPpb9vb0SLg==" + }, + "node_modules/css-font-style-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz", + "integrity": "sha512-0Fn0aTpcDktnR1RzaBYorIxQily85M2KXRpzmxQPgh8pxUN9Fcn00I8u9I3grNr1QXVgCl9T5Imx0ZwKU973Vg==" + }, + "node_modules/css-font-weight-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz", + "integrity": "sha512-5So8/NH+oDD+EzsnF4iaG4ZFHQ3vaViePkL1ZbZ5iC/KrsCY+WHq/lvOgrtmuOQ9pBBZ1ADGpaf+A4lj1Z9eYA==" + }, + "node_modules/css-list-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/css-list-helpers/-/css-list-helpers-2.0.0.tgz", + "integrity": "sha512-9Bj8tZ0jWbAM3u/U6m/boAzAwLPwtjzFvwivr2piSvyVa3K3rChJzQy4RIHkNkKiZCHrEMWDJWtTR8UyVhdDnQ==" + }, + "node_modules/css-system-font-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz", + "integrity": "sha512-1umTtVd/fXS25ftfjB71eASCrYhilmEsvDEI6wG/QplnmlfmVM5HkZ/ZX46DT5K3eblFPgLUHt5BRCb0YXkSFA==" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + }, + "node_modules/esbuild": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.15.18.tgz", + "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.15.18", + "@esbuild/linux-loong64": "0.15.18", + "esbuild-android-64": "0.15.18", + "esbuild-android-arm64": "0.15.18", + "esbuild-darwin-64": "0.15.18", + "esbuild-darwin-arm64": "0.15.18", + "esbuild-freebsd-64": "0.15.18", + "esbuild-freebsd-arm64": "0.15.18", + "esbuild-linux-32": "0.15.18", + "esbuild-linux-64": "0.15.18", + "esbuild-linux-arm": "0.15.18", + "esbuild-linux-arm64": "0.15.18", + "esbuild-linux-mips64le": "0.15.18", + "esbuild-linux-ppc64le": "0.15.18", + "esbuild-linux-riscv64": "0.15.18", + "esbuild-linux-s390x": "0.15.18", + "esbuild-netbsd-64": "0.15.18", + "esbuild-openbsd-64": "0.15.18", + "esbuild-sunos-64": "0.15.18", + "esbuild-windows-32": "0.15.18", + "esbuild-windows-64": "0.15.18", + "esbuild-windows-arm64": "0.15.18" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz", + "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz", + "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz", + "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz", + "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz", + "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz", + "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz", + "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz", + "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz", + "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz", + "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz", + "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz", + "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz", + "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz", + "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz", + "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz", + "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz", + "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz", + "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", + "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz", + "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmmirror.com/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "engines": { + "node": "*" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/generic-names": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/generic-names/-/generic-names-4.0.0.tgz", + "integrity": "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==", + "dependencies": { + "loader-utils": "^3.2.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" + }, + "node_modules/html-tags": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==" + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "devOptional": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/invert-kv": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/invert-kv/-/invert-kv-3.0.1.tgz", + "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-md5": { + "version": "0.7.3", + "resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.7.3.tgz", + "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lcid": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/lcid/-/lcid-3.1.1.tgz", + "integrity": "sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==", + "dependencies": { + "invert-kv": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/licia": { + "version": "1.37.0", + "resolved": "https://registry.npmmirror.com/licia/-/licia-1.37.0.tgz", + "integrity": "sha512-jX49+WmzikOPGNrcy/giS23HCI8Pb7RF585Ei5d7oWF4WMelaZWv4odqQNdT0jtHkoUxqSvPz67Jvyq06xamUA==", + "dev": true + }, + "node_modules/lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/localstorage-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/localstorage-polyfill/-/localstorage-polyfill-1.0.1.tgz", + "integrity": "sha512-m4iHVZxFH5734oQcPKU08025gIz2+4bjWR9lulP8ZYxEJR0BpA0w32oJmkzh8y3UI9ci7xCBehQDc3oA1X+VHw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "node_modules/magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz", + "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==" + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/module-alias": { + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/os-locale-s-fix": { + "version": "1.0.8-fix-1", + "resolved": "https://registry.npmmirror.com/os-locale-s-fix/-/os-locale-s-fix-1.0.8-fix-1.tgz", + "integrity": "sha512-Sv0OvhPiMutICiwORAUefv02DCPb62IelBmo8ZsSrRHyI3FStqIWZvjqDkvtjU+lcujo7UNir+dCwKSqlEQ/5w==", + "dependencies": { + "lcid": "^3.0.0" + }, + "engines": { + "node": ">=10", + "yarn": "^1.22.4" + } + }, + "node_modules/parse-css-font": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/parse-css-font/-/parse-css-font-4.0.0.tgz", + "integrity": "sha512-lnY7dTUfjRXsSo5G5C639L8RaBBaVSgL+5hacIFKsNHzeCJQ5SFSZv1DZmc7+wZv/22PFGOq2YbaEHLdaCS/mQ==", + "dependencies": { + "css-font-size-keywords": "^1.0.0", + "css-font-stretch-keywords": "^1.0.1", + "css-font-style-keywords": "^1.0.1", + "css-font-weight-keywords": "^1.0.0", + "css-list-helpers": "^2.0.0", + "css-system-font-keywords": "^1.0.0", + "unquote": "^1.1.1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "8.4.19", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-modules": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/postcss-modules/-/postcss-modules-4.3.1.tgz", + "integrity": "sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==", + "dependencies": { + "generic-names": "^4.0.0", + "icss-replace-symbols": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "string-hash": "^1.1.1" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qrcode-reader": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/qrcode-reader/-/qrcode-reader-1.0.4.tgz", + "integrity": "sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==", + "dev": true + }, + "node_modules/qrcode-terminal": { + "version": "0.12.0", + "resolved": "https://registry.npmmirror.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", + "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", + "dev": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-area-insets": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/safe-area-insets/-/safe-area-insets-1.4.1.tgz", + "integrity": "sha512-r/nRWTjFGhhm3w1Z6Kd/jY11srN+lHt2mNl1E/emQGW8ic7n3Avu4noibklfSM+Y34peNphHD/BSZecav0sXYQ==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass": { + "version": "1.56.1", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.56.1.tgz", + "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", + "devOptional": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "devOptional": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==" + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/systemjs": { + "version": "6.13.0", + "resolved": "https://registry.npmmirror.com/systemjs/-/systemjs-6.13.0.tgz", + "integrity": "sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.16.1", + "resolved": "https://registry.npmmirror.com/terser/-/terser-5.16.1.tgz", + "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", + "devOptional": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "3.2.4", + "resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.4.tgz", + "integrity": "sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==", + "dependencies": { + "esbuild": "^0.15.9", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", + "dependencies": { + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "node_modules/vue-i18n": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.2.2.tgz", + "integrity": "sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==", + "dependencies": { + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2", + "@vue/devtools-api": "^6.2.1" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-i18n/node_modules/@intlify/core-base": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.2.2.tgz", + "integrity": "sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==", + "dependencies": { + "@intlify/devtools-if": "9.2.2", + "@intlify/message-compiler": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/vue-i18n/node_modules/@intlify/devtools-if": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.2.2.tgz", + "integrity": "sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==", + "dependencies": { + "@intlify/shared": "9.2.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/vue-i18n/node_modules/@intlify/message-compiler": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.2.2.tgz", + "integrity": "sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==", + "dependencies": { + "@intlify/shared": "9.2.2", + "source-map": "0.6.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/vue-i18n/node_modules/@intlify/shared": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.2.2.tgz", + "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/vue-i18n/node_modules/@intlify/vue-devtools": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz", + "integrity": "sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==", + "dependencies": { + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/vue-router": { + "version": "4.1.6", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz", + "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==", + "dependencies": { + "@vue/devtools-api": "^6.4.5" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vuex": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz", + "integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==", + "dependencies": { + "@vue/devtools-api": "^6.0.0-beta.11" + }, + "peerDependencies": { + "vue": "^3.0.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xregexp": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/xregexp/-/xregexp-3.1.0.tgz", + "integrity": "sha512-4Y1x6DyB8xRoxosooa6PlGWqmmSKatbzhrftZ7Purmm4B8R4qIEJG1A2hZsdz5DhmIqS0msC0I7KEq93GphEVg==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" + }, + "@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + } + }, + "@babel/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "requires": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "requires": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", + "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.6" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dev": true, + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + }, + "@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", + "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.20.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-typescript": "^7.20.0" + } + }, + "@babel/standalone": { + "version": "7.20.6", + "resolved": "https://registry.npmmirror.com/@babel/standalone/-/standalone-7.20.6.tgz", + "integrity": "sha512-u5at/CbBLETf7kx2LOY4XdhseD79Y099WZKAOMXeT8qvd9OSR515my2UNBBLY4qIht/Qi9KySeQHQwQwxJN4Sw==", + "dev": true + }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@dcloudio/types": { + "version": "3.2.11", + "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.2.11.tgz", + "integrity": "sha512-Ws+pUiQMvCcSjg0soF+vTTwwsdNlK/1cxIfo5LBBDFPoXfUAAh6k9HnCt5cudERNhY0M3wE7ATMx/1Cb9bmUig==" + }, + "@dcloudio/uni-app": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app/-/uni-app-3.0.0-3061820230117001.tgz", + "integrity": "sha512-djQ/vtYqjbwctrs4DMQPTKAY1+8mb3MVCJqO6tis34jIOkMUqI/weB4VxZyR1rMT+bahaNtwKrUMr5bNUktArw==", + "requires": { + "@dcloudio/uni-cloud": "3.0.0-3061820230117001", + "@dcloudio/uni-components": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-push": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-stat": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-app-plus": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-plus/-/uni-app-plus-3.0.0-3061820230117001.tgz", + "integrity": "sha512-+0/CEKKBOq+5jiZsi1Lz9B7rPN781VShJaQY6Urgp5t4ne5sAF68XW00whHKGwdOlloIVHXN4qdblUP7qO9GGw==", + "requires": { + "@dcloudio/uni-app-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-app-vue": "3.0.0-3061820230117001" + } + }, + "@dcloudio/uni-app-vite": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vite/-/uni-app-vite-3.0.0-3061820230117001.tgz", + "integrity": "sha512-KMMOIzvTxjOnvX15JBLWULXKMU+pBQ/GTerM0KsNEMUnhKo5F8WuO6ZPQBUBgnncD+iQyGbAYn2IWlrRY+ftiQ==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-nvue-styler": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@rollup/pluginutils": "^4.2.0", + "@vitejs/plugin-vue": "^3.2.0", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "debug": "^4.3.3", + "fs-extra": "^10.0.0", + "picocolors": "^1.0.0", + "rollup": "^2.79.1" + } + }, + "@dcloudio/uni-app-vue": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vue/-/uni-app-vue-3.0.0-3061820230117001.tgz", + "integrity": "sha512-+EXrTPN13Dt6t8/mdTPsIwKoeekl36S6Rq7Qq+oEVN937BHapRZ8BifwwbRkZI/lvPs3oLS8M4LlH17pEQ2ljg==" + }, + "@dcloudio/uni-automator": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-automator/-/uni-automator-3.0.0-3061820230117001.tgz", + "integrity": "sha512-28Li+A3vXHxK34xcyoQyXCy/2NXtpGqc2XUf4Hm73X/cl2zXyUy5oClzolsWQlnN1gAqQhagcHLu4h+zc7J1Dw==", + "dev": true, + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "address": "^1.1.2", + "cross-env": "^7.0.3", + "debug": "^4.3.3", + "default-gateway": "^6.0.3", + "fs-extra": "^10.0.0", + "licia": "^1.29.0", + "postcss-selector-parser": "^6.0.6", + "qrcode-reader": "^1.0.4", + "qrcode-terminal": "^0.12.0", + "ws": "^8.4.2" + } + }, + "@dcloudio/uni-cli-shared": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-3.0.0-3061820230117001.tgz", + "integrity": "sha512-MOk7IG2U6iMF4t+2hZsCpWC+ulkC5jU556C9Vh9qpq5ofjs4vqeQ3irz+Z+XcysG6oaneL53pXx0saItQey7fA==", + "requires": { + "@ampproject/remapping": "^2.1.2", + "@babel/core": "^7.19.6", + "@babel/parser": "^7.19.6", + "@babel/types": "^7.20.0", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@intlify/core-base": "9.1.9", + "@intlify/shared": "9.1.9", + "@intlify/vue-devtools": "9.1.9", + "@rollup/pluginutils": "^4.2.0", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45", + "autoprefixer": "^10.4.13", + "base64url": "^3.0.1", + "chokidar": "^3.5.3", + "compare-versions": "^3.6.0", + "debug": "^4.3.3", + "es-module-lexer": "^0.9.3", + "esbuild": "^0.15.9", + "estree-walker": "^2.0.2", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.0", + "hash-sum": "^2.0.0", + "jsonc-parser": "^3.0.0", + "magic-string": "^0.26.7", + "merge": "^2.1.1", + "mime": "^3.0.0", + "module-alias": "^2.2.2", + "os-locale-s-fix": "^1.0.8-fix-1", + "picocolors": "^1.0.0", + "postcss-import": "^14.0.2", + "postcss-load-config": "^3.1.1", + "postcss-modules": "^4.3.0", + "postcss-selector-parser": "^6.0.6", + "resolve": "^1.22.1", + "tapable": "^2.2.0", + "xregexp": "3.1.0" + } + }, + "@dcloudio/uni-cloud": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cloud/-/uni-cloud-3.0.0-3061820230117001.tgz", + "integrity": "sha512-YeDLoA3DTfuU6kSpFk96AIcJKtvbJbGcF+bbZBtW9htkKx7zhpDRTL0Q5zOqsGU9YJn8i3h79k/rusM0XpoG6g==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45", + "fast-glob": "^3.2.11" + } + }, + "@dcloudio/uni-components": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-components/-/uni-components-3.0.0-3061820230117001.tgz", + "integrity": "sha512-QL24hL7EzgZj5bNF7xMCg85EVveSaOfb7aYBsSs/3Gv6iq9cXurh7jRA/nJyhb+7G9yt7H3ab9b6DvP/XjwFCg==" + }, + "@dcloudio/uni-h5": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5/-/uni-h5-3.0.0-3061820230117001.tgz", + "integrity": "sha512-C600DG4DTVkIPvlPcnR/Z2DiyQnk30zQWrGNjotjH0OZPlInDxvBikXxOStAhbHA9/0sJAb++ZQiDAME2c85HA==", + "requires": { + "@dcloudio/uni-h5-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-h5-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45", + "localstorage-polyfill": "^1.0.1", + "safe-area-insets": "^1.4.1", + "vue-router": "^4.1.6", + "xmlhttprequest": "^1.8.0" + } + }, + "@dcloudio/uni-h5-vite": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vite/-/uni-h5-vite-3.0.0-3061820230117001.tgz", + "integrity": "sha512-vdyx0Hd5dNWydgElNtZz3cgPJYGUDa1e7TGcpVubcnX6Dda6WhxZhidughyx76j0G/nADY9d7vBZFhA0Xg8nNg==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@rollup/pluginutils": "^4.2.0", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45", + "debug": "^4.3.3", + "fs-extra": "^10.0.0", + "mime": "^3.0.0", + "module-alias": "^2.2.2" + } + }, + "@dcloudio/uni-h5-vue": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-h5-vue/-/uni-h5-vue-3.0.0-3061820230117001.tgz", + "integrity": "sha512-HsO8I2RfR/87QEmop0T+Heaso/j4FryQrnxzu2mJA2oCtq4sPs3uJvaTA7V2rpYFKsXUVE4rMRq+FkjHCAIlGA==", + "requires": { + "@dcloudio/uni-shared": "3.0.0-3061820230117001" + } + }, + "@dcloudio/uni-i18n": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-i18n/-/uni-i18n-3.0.0-3061820230117001.tgz", + "integrity": "sha512-Zi9W62ASUJ5302mXi9Ux4cM2cesmmzluYdAUMYyWWhgsycaIMbI8tYEWlIk5j6KAap7Be2hxgIo/O34X9IzJCA==" + }, + "@dcloudio/uni-mp-alipay": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-alipay/-/uni-mp-alipay-3.0.0-3061820230117001.tgz", + "integrity": "sha512-Me5Zw6lxr8L0J1g7cTmTVlICW5xjrC4gT15IKjs2ZLVnxpiU/t7J/WbE2KKOHg8mRMDmM77k88PL+MmLMJrc7g==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-mp-baidu": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-baidu/-/uni-mp-baidu-3.0.0-3061820230117001.tgz", + "integrity": "sha512-dCZ+wrh06JvxCAYXvL8WsZDEUz8IQVGD25TAgJ8Uez+CWTScmYYrO6/gP5u6o5a/rAR85ldI1Pv4Xlqyp95MXg==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-weixin": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-mp-compiler": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-compiler/-/uni-mp-compiler-3.0.0-3061820230117001.tgz", + "integrity": "sha512-wxPSdSXs5y+3QPLuxcp3TOzV33/NiBkewWAN0Mij33dLiErZrjRvvUuef7MptOzgc1TJoQizzS5f0PKYmqnhNg==", + "requires": { + "@babel/generator": "^7.19.6", + "@babel/parser": "^7.19.6", + "@babel/types": "^7.20.0", + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2" + } + }, + "@dcloudio/uni-mp-kuaishou": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-kuaishou/-/uni-mp-kuaishou-3.0.0-3061820230117001.tgz", + "integrity": "sha512-u9vsslqwWmxSSVtHUNIDADXLeumNzSs/L0JlYlX7ofgPEoVLwQqBIRxKoR/RdDtiywPYS9J3VzGeArD9LdZefw==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-weixin": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-mp-lark": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-lark/-/uni-mp-lark-3.0.0-3061820230117001.tgz", + "integrity": "sha512-dZKho5F15CzNZqIALDzlG1GX3Ny5R0zqMYd1Ny6J/rcmtPbxXblHb5uGxBYbDTv3z7/yjRqoqQCQk+9tW9Lb/g==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-toutiao": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-mp-qq": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-qq/-/uni-mp-qq-3.0.0-3061820230117001.tgz", + "integrity": "sha512-MmPR703fqxz8uvqHvagAGPSS8whIf9pxPerbaM1AVXiQfiawOxyhqyIxlIvTFDMbA0Nyq0Zd2U+KjT5yn4f9LQ==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45", + "fs-extra": "^10.0.0" + } + }, + "@dcloudio/uni-mp-toutiao": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-toutiao/-/uni-mp-toutiao-3.0.0-3061820230117001.tgz", + "integrity": "sha512-5tKFOXv4JTKA1pfGoWD8AwN28RAe6cPRxSaUkLsNdIzldZ3fozX6vrsfOMkUBSQwcp9au35q5X+mk+KPesBnnA==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-mp-vite": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vite/-/uni-mp-vite-3.0.0-3061820230117001.tgz", + "integrity": "sha512-zyX0DD8NZm7S1qXGp6dUNqK7klkDx4M9onxT61ilSEwCdBHCEs33zjDT/EIyWLXC+8uis+3KmlAUZUgkwXzx1A==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-i18n": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-compiler": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/compiler-sfc": "3.2.45", + "@vue/shared": "3.2.45", + "debug": "^4.3.3" + } + }, + "@dcloudio/uni-mp-vue": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-vue/-/uni-mp-vue-3.0.0-3061820230117001.tgz", + "integrity": "sha512-J/wAfFh269Lx3nZ5CEJonq3dzAxeM1uc+pnGs1MQwBT3ZK8TNopYRUgri4hrEF+srVuCcZWM9RNw8RXsSBosaw==", + "requires": { + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-mp-weixin": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-mp-weixin/-/uni-mp-weixin-3.0.0-3061820230117001.tgz", + "integrity": "sha512-qH4TbUPcqCccso8YIir9r9Vu/dyD9VrK3btAWxXY39gq6AahHomO5Y0Jl4+ODvS2qeQMBIDGyg5twL3G+uKPpw==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-nvue-styler": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-nvue-styler/-/uni-nvue-styler-3.0.0-3061820230117001.tgz", + "integrity": "sha512-tAR+wYThaojYFCg2aUv3G6nva9DMDIOkeYZ4WeCTf3cO+V1PAETElJEiPa3De5Apg7Jqb48SiKTFTm9PX9yxUw==", + "requires": { + "@vue/shared": "3.2.45", + "parse-css-font": "^4.0.0", + "postcss": "^8.4.18" + } + }, + "@dcloudio/uni-push": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-push/-/uni-push-3.0.0-3061820230117001.tgz", + "integrity": "sha512-ilhEPcdZSlih9/6ztm8J87XZJH82/FT0swlpz2EMq8fzRGlk1kSNy7MWpNF9QN3S2WGA/Q2TlMr9qg4buhdAHw==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001" + } + }, + "@dcloudio/uni-quickapp-webview": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-quickapp-webview/-/uni-quickapp-webview-3.0.0-3061820230117001.tgz", + "integrity": "sha512-a1O/Wpe2lI0PHLZnDVtEzAYYZ/JGgQ8OAKbJflAD29kgVynpRKx3Imepjqsk1vk1xac2CZvi7C9MBaBA73D6Cw==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vite": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-vue": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-shared": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-shared/-/uni-shared-3.0.0-3061820230117001.tgz", + "integrity": "sha512-vgvBeR5yxQ7quBOT63BN02RbfD2Si1fyll3j1SXqp37wdyRILBzaveFg8xQCMI0DdPL8kdIHTeG8d23ct6W9aQ==", + "requires": { + "@vue/shared": "3.2.45" + } + }, + "@dcloudio/uni-stacktracey": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-stacktracey/-/uni-stacktracey-3.0.0-3061820230117001.tgz", + "integrity": "sha512-BDNZQWjD14BaOvzs9YU/ajX9KxOqubJXVfbwsXZnHCURNzPYE5j7EtW7Na6f9n8f79X0nkPRvEdIeKHUe3rNtw==", + "dev": true + }, + "@dcloudio/uni-stat": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-stat/-/uni-stat-3.0.0-3061820230117001.tgz", + "integrity": "sha512-wYC/cUSEwPmSbT13PcphSywLOK+XrsYGrfRaNfDY5IdGlrHIhtX/BvsJiYh7crAsQEUhgmCcA7VvJmkiQM3DAg==", + "requires": { + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "debug": "^4.3.3" + } + }, + "@dcloudio/uni-ui": { + "version": "1.4.23", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-ui/-/uni-ui-1.4.23.tgz", + "integrity": "sha512-FJRkhL240gin9WvOunY38Yi2/0FzTLVlEI3dxcjzaV1oYa81o+IWEf/29YDiRrsHuvYDk9g600QgiZLC+A6ycA==" + }, + "@dcloudio/vite-plugin-uni": { + "version": "3.0.0-3061820230117001", + "resolved": "https://registry.npmmirror.com/@dcloudio/vite-plugin-uni/-/vite-plugin-uni-3.0.0-3061820230117001.tgz", + "integrity": "sha512-ANAsCstpdd/FQUIShqYt5V8C7YC2J6LQcfqd5I7jqLiS/VTz7nC3TTA1EzsU0H7jdwJ9mvr9ro3nFXmqF2Hsmw==", + "dev": true, + "requires": { + "@babel/core": "^7.19.6", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.20.0", + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-shared": "3.0.0-3061820230117001", + "@rollup/pluginutils": "^4.2.0", + "@vitejs/plugin-legacy": "^2.3.1", + "@vitejs/plugin-vue": "^3.2.0", + "@vitejs/plugin-vue-jsx": "^2.1.1", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/shared": "3.2.45", + "cac": "6.7.9", + "debug": "^4.3.3", + "estree-walker": "^2.0.2", + "express": "^4.17.1", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.0", + "hash-sum": "^2.0.0", + "jsonc-parser": "^3.0.0", + "picocolors": "^1.0.0", + "terser": "^5.4.0" + } + }, + "@esbuild/android-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz", + "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz", + "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==", + "optional": true + }, + "@intlify/core-base": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz", + "integrity": "sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==", + "requires": { + "@intlify/devtools-if": "9.1.9", + "@intlify/message-compiler": "9.1.9", + "@intlify/message-resolver": "9.1.9", + "@intlify/runtime": "9.1.9", + "@intlify/shared": "9.1.9", + "@intlify/vue-devtools": "9.1.9" + } + }, + "@intlify/devtools-if": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz", + "integrity": "sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==", + "requires": { + "@intlify/shared": "9.1.9" + } + }, + "@intlify/message-compiler": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz", + "integrity": "sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==", + "requires": { + "@intlify/message-resolver": "9.1.9", + "@intlify/shared": "9.1.9", + "source-map": "0.6.1" + } + }, + "@intlify/message-resolver": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz", + "integrity": "sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==" + }, + "@intlify/runtime": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/runtime/-/runtime-9.1.9.tgz", + "integrity": "sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==", + "requires": { + "@intlify/message-compiler": "9.1.9", + "@intlify/message-resolver": "9.1.9", + "@intlify/shared": "9.1.9" + } + }, + "@intlify/shared": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.1.9.tgz", + "integrity": "sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==" + }, + "@intlify/vue-devtools": { + "version": "9.1.9", + "resolved": "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz", + "integrity": "sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==", + "requires": { + "@intlify/message-resolver": "9.1.9", + "@intlify/runtime": "9.1.9", + "@intlify/shared": "9.1.9" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "devOptional": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "devOptional": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@rollup/plugin-commonjs": { + "version": "25.0.1", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.1.tgz", + "integrity": "sha512-2DJ4kv4b1xfTJopWhu61ANdNRHvzQZ2fpaIrlgaP2jOfUv1wDJ0Ucqy8AZlbFmn/iUjiwKoqki9j55Y6L8kyNQ==", + "requires": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.27.0" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.13" + } + } + } + }, + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + }, + "@types/js-md5": { + "version": "0.4.3", + "resolved": "https://registry.npmmirror.com/@types/js-md5/-/js-md5-0.4.3.tgz", + "integrity": "sha512-BIga/WEqTi35ccnGysOuO4RmwVnpajv9oDB/sDQSY2b7/Ac7RyYR30bv7otZwByMvOJV9Vqq6/O1DFAnOzE4Pg==", + "dev": true + }, + "@types/node": { + "version": "18.11.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz", + "integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g==", + "devOptional": true + }, + "@vitejs/plugin-legacy": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-2.3.1.tgz", + "integrity": "sha512-J5KaGBlSt2tEYPVjM/C8dA6DkRzkFkbPe+Xb4IX5G+XOV5OGbVAfkMjKywdrkO3gGynO8S98i71Lmsff4cWkCQ==", + "dev": true, + "requires": { + "@babel/standalone": "^7.20.0", + "core-js": "^3.26.0", + "magic-string": "^0.26.7", + "regenerator-runtime": "^0.13.10", + "systemjs": "^6.13.0" + } + }, + "@vitejs/plugin-vue": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz", + "integrity": "sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==", + "requires": {} + }, + "@vitejs/plugin-vue-jsx": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-2.1.1.tgz", + "integrity": "sha512-JgDhxstQlwnHBvZ1BSnU5mbmyQ14/t5JhREc6YH5kWyu2QdAAOsLF6xgHoIWarj8tddaiwFrNzLbWJPudpXKYA==", + "dev": true, + "requires": { + "@babel/core": "^7.19.6", + "@babel/plugin-transform-typescript": "^7.20.0", + "@vue/babel-plugin-jsx": "^1.1.1" + } + }, + "@vue/babel-helper-vue-transform-on": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==", + "dev": true + }, + "@vue/babel-plugin-jsx": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", + "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "@vue/babel-helper-vue-transform-on": "^1.0.2", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + } + }, + "@vue/compiler-core": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-dom": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", + "requires": { + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/compiler-sfc": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7", + "postcss": "^8.1.10", + "source-map": "^0.6.1" + }, + "dependencies": { + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + } + } + }, + "@vue/compiler-ssr": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", + "requires": { + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/devtools-api": { + "version": "6.4.5", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz", + "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==" + }, + "@vue/reactivity": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", + "requires": { + "@vue/shared": "3.2.45" + } + }, + "@vue/reactivity-transform": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", + "requires": { + "@babel/parser": "^7.16.4", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", + "estree-walker": "^2.0.2", + "magic-string": "^0.25.7" + }, + "dependencies": { + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + } + } + }, + "@vue/runtime-core": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", + "requires": { + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/runtime-dom": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", + "requires": { + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", + "csstype": "^2.6.8" + } + }, + "@vue/server-renderer": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", + "requires": { + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "@vue/shared": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "devOptional": true + }, + "add": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/add/-/add-2.0.6.tgz", + "integrity": "sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==" + }, + "address": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "autoprefixer": { + "version": "10.4.13", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "requires": { + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "devOptional": true + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "cac": { + "version": "6.7.9", + "resolved": "https://registry.npmmirror.com/cac/-/cac-6.7.9.tgz", + "integrity": "sha512-XN5qEpfNQCJ8jRaZgitSkkukjMRCGio+X3Ks5KUbGGlPbV+pSem1l9VuzooCBXOiMFshUZgyYqg6rgN8rjkb/w==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001436", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001436.tgz", + "integrity": "sha512-ZmWkKsnC2ifEPoWUvSAIGyOYwT+keAaaWPHiQ9DfMqS1t6tfuyFYoWR78TeZtznkEQ64+vGXH9cZrElwR2Mrxg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "devOptional": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "core-js": { + "version": "3.26.1", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.26.1.tgz", + "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", + "dev": true + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, + "css-font-size-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz", + "integrity": "sha512-Q+svMDbMlelgCfH/RVDKtTDaf5021O486ZThQPIpahnIjUkMUslC+WuOQSWTgGSrNCH08Y7tYNEmmy0hkfMI8Q==" + }, + "css-font-stretch-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz", + "integrity": "sha512-KmugPO2BNqoyp9zmBIUGwt58UQSfyk1X5DbOlkb2pckDXFSAfjsD5wenb88fNrD6fvS+vu90a/tsPpb9vb0SLg==" + }, + "css-font-style-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz", + "integrity": "sha512-0Fn0aTpcDktnR1RzaBYorIxQily85M2KXRpzmxQPgh8pxUN9Fcn00I8u9I3grNr1QXVgCl9T5Imx0ZwKU973Vg==" + }, + "css-font-weight-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz", + "integrity": "sha512-5So8/NH+oDD+EzsnF4iaG4ZFHQ3vaViePkL1ZbZ5iC/KrsCY+WHq/lvOgrtmuOQ9pBBZ1ADGpaf+A4lj1Z9eYA==" + }, + "css-list-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/css-list-helpers/-/css-list-helpers-2.0.0.tgz", + "integrity": "sha512-9Bj8tZ0jWbAM3u/U6m/boAzAwLPwtjzFvwivr2piSvyVa3K3rChJzQy4RIHkNkKiZCHrEMWDJWtTR8UyVhdDnQ==" + }, + "css-system-font-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz", + "integrity": "sha512-1umTtVd/fXS25ftfjB71eASCrYhilmEsvDEI6wG/QplnmlfmVM5HkZ/ZX46DT5K3eblFPgLUHt5BRCb0YXkSFA==" + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + }, + "esbuild": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.15.18.tgz", + "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==", + "requires": { + "@esbuild/android-arm": "0.15.18", + "@esbuild/linux-loong64": "0.15.18", + "esbuild-android-64": "0.15.18", + "esbuild-android-arm64": "0.15.18", + "esbuild-darwin-64": "0.15.18", + "esbuild-darwin-arm64": "0.15.18", + "esbuild-freebsd-64": "0.15.18", + "esbuild-freebsd-arm64": "0.15.18", + "esbuild-linux-32": "0.15.18", + "esbuild-linux-64": "0.15.18", + "esbuild-linux-arm": "0.15.18", + "esbuild-linux-arm64": "0.15.18", + "esbuild-linux-mips64le": "0.15.18", + "esbuild-linux-ppc64le": "0.15.18", + "esbuild-linux-riscv64": "0.15.18", + "esbuild-linux-s390x": "0.15.18", + "esbuild-netbsd-64": "0.15.18", + "esbuild-openbsd-64": "0.15.18", + "esbuild-sunos-64": "0.15.18", + "esbuild-windows-32": "0.15.18", + "esbuild-windows-64": "0.15.18", + "esbuild-windows-arm64": "0.15.18" + } + }, + "esbuild-android-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz", + "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==", + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz", + "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==", + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz", + "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==", + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz", + "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==", + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz", + "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==", + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz", + "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==", + "optional": true + }, + "esbuild-linux-32": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz", + "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==", + "optional": true + }, + "esbuild-linux-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz", + "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==", + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz", + "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==", + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz", + "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==", + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz", + "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==", + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz", + "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==", + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz", + "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==", + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz", + "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==", + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz", + "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==", + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz", + "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==", + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz", + "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==", + "optional": true + }, + "esbuild-windows-32": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz", + "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==", + "optional": true + }, + "esbuild-windows-64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz", + "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==", + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.15.18", + "resolved": "https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz", + "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==", + "optional": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmmirror.com/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "generic-names": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/generic-names/-/generic-names-4.0.0.tgz", + "integrity": "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==", + "requires": { + "loader-utils": "^3.2.0" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" + }, + "html-tags": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==" + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "requires": {} + }, + "immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "devOptional": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "invert-kv": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/invert-kv/-/invert-kv-3.0.1.tgz", + "integrity": "sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "requires": { + "@types/estree": "*" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "js-md5": { + "version": "0.7.3", + "resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.7.3.tgz", + "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lcid": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/lcid/-/lcid-3.1.1.tgz", + "integrity": "sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==", + "requires": { + "invert-kv": "^3.0.0" + } + }, + "licia": { + "version": "1.37.0", + "resolved": "https://registry.npmmirror.com/licia/-/licia-1.37.0.tgz", + "integrity": "sha512-jX49+WmzikOPGNrcy/giS23HCI8Pb7RF585Ei5d7oWF4WMelaZWv4odqQNdT0jtHkoUxqSvPz67Jvyq06xamUA==", + "dev": true + }, + "lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" + }, + "loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" + }, + "localstorage-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/localstorage-polyfill/-/localstorage-polyfill-1.0.1.tgz", + "integrity": "sha512-m4iHVZxFH5734oQcPKU08025gIz2+4bjWR9lulP8ZYxEJR0BpA0w32oJmkzh8y3UI9ci7xCBehQDc3oA1X+VHw==" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "merge": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz", + "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "module-alias": { + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "os-locale-s-fix": { + "version": "1.0.8-fix-1", + "resolved": "https://registry.npmmirror.com/os-locale-s-fix/-/os-locale-s-fix-1.0.8-fix-1.tgz", + "integrity": "sha512-Sv0OvhPiMutICiwORAUefv02DCPb62IelBmo8ZsSrRHyI3FStqIWZvjqDkvtjU+lcujo7UNir+dCwKSqlEQ/5w==", + "requires": { + "lcid": "^3.0.0" + } + }, + "parse-css-font": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/parse-css-font/-/parse-css-font-4.0.0.tgz", + "integrity": "sha512-lnY7dTUfjRXsSo5G5C639L8RaBBaVSgL+5hacIFKsNHzeCJQ5SFSZv1DZmc7+wZv/22PFGOq2YbaEHLdaCS/mQ==", + "requires": { + "css-font-size-keywords": "^1.0.0", + "css-font-stretch-keywords": "^1.0.1", + "css-font-style-keywords": "^1.0.1", + "css-font-weight-keywords": "^1.0.0", + "css-list-helpers": "^2.0.0", + "css-system-font-keywords": "^1.0.0", + "unquote": "^1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "postcss": { + "version": "8.4.19", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + } + }, + "postcss-modules": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/postcss-modules/-/postcss-modules-4.3.1.tgz", + "integrity": "sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==", + "requires": { + "generic-names": "^4.0.0", + "icss-replace-symbols": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "string-hash": "^1.1.1" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "qrcode-reader": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/qrcode-reader/-/qrcode-reader-1.0.4.tgz", + "integrity": "sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==", + "dev": true + }, + "qrcode-terminal": { + "version": "0.12.0", + "resolved": "https://registry.npmmirror.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", + "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", + "dev": true + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "requires": { + "pify": "^2.3.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "requires": { + "fsevents": "~2.3.2" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-area-insets": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/safe-area-insets/-/safe-area-insets-1.4.1.tgz", + "integrity": "sha512-r/nRWTjFGhhm3w1Z6Kd/jY11srN+lHt2mNl1E/emQGW8ic7n3Avu4noibklfSM+Y34peNphHD/BSZecav0sXYQ==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass": { + "version": "1.56.1", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.56.1.tgz", + "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", + "devOptional": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "devOptional": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "systemjs": { + "version": "6.13.0", + "resolved": "https://registry.npmmirror.com/systemjs/-/systemjs-6.13.0.tgz", + "integrity": "sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==", + "dev": true + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + }, + "terser": { + "version": "5.16.1", + "resolved": "https://registry.npmmirror.com/terser/-/terser-5.16.1.tgz", + "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", + "devOptional": true, + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "vite": { + "version": "3.2.4", + "resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.4.tgz", + "integrity": "sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==", + "requires": { + "esbuild": "^0.15.9", + "fsevents": "~2.3.2", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + } + }, + "vue": { + "version": "3.2.45", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", + "requires": { + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" + } + }, + "vue-i18n": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.2.2.tgz", + "integrity": "sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==", + "requires": { + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2", + "@vue/devtools-api": "^6.2.1" + }, + "dependencies": { + "@intlify/core-base": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.2.2.tgz", + "integrity": "sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==", + "requires": { + "@intlify/devtools-if": "9.2.2", + "@intlify/message-compiler": "9.2.2", + "@intlify/shared": "9.2.2", + "@intlify/vue-devtools": "9.2.2" + } + }, + "@intlify/devtools-if": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.2.2.tgz", + "integrity": "sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==", + "requires": { + "@intlify/shared": "9.2.2" + } + }, + "@intlify/message-compiler": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.2.2.tgz", + "integrity": "sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==", + "requires": { + "@intlify/shared": "9.2.2", + "source-map": "0.6.1" + } + }, + "@intlify/shared": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.2.2.tgz", + "integrity": "sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==" + }, + "@intlify/vue-devtools": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz", + "integrity": "sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==", + "requires": { + "@intlify/core-base": "9.2.2", + "@intlify/shared": "9.2.2" + } + } + } + }, + "vue-router": { + "version": "4.1.6", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz", + "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==", + "requires": { + "@vue/devtools-api": "^6.4.5" + } + }, + "vuex": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz", + "integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==", + "requires": { + "@vue/devtools-api": "^6.0.0-beta.11" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "requires": {} + }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==" + }, + "xregexp": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/xregexp/-/xregexp-3.1.0.tgz", + "integrity": "sha512-4Y1x6DyB8xRoxosooa6PlGWqmmSKatbzhrftZ7Purmm4B8R4qIEJG1A2hZsdz5DhmIqS0msC0I7KEq93GphEVg==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..30d41cd --- /dev/null +++ b/package.json @@ -0,0 +1,72 @@ +{ + "name": "uni-preset-vue", + "version": "0.0.0", + "scripts": { + "dev:app": "uni -p app", + "dev:app-android": "uni -p app-android", + "dev:app-ios": "uni -p app-ios", + "dev:custom": "uni -p", + "dev:h5": "uni", + "dev:h5:ssr": "uni --ssr", + "dev:mp-alipay": "uni -p mp-alipay", + "dev:mp-baidu": "uni -p mp-baidu", + "dev:mp-kuaishou": "uni -p mp-kuaishou", + "dev:mp-lark": "uni -p mp-lark", + "dev:mp-qq": "uni -p mp-qq", + "dev:mp-toutiao": "uni -p mp-toutiao", + "dev:mp-weixin": "uni -p mp-weixin", + "dev:quickapp-webview": "uni -p quickapp-webview", + "dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei", + "dev:quickapp-webview-union": "uni -p quickapp-webview-union", + "build:app": "uni build -p app", + "build:app-android": "uni build -p app-android", + "build:app-ios": "uni build -p app-ios", + "build:custom": "uni build -p", + "build:h5": "uni build", + "build:h5:ssr": "uni build --ssr", + "build:mp-alipay": "uni build -p mp-alipay", + "build:mp-baidu": "uni build -p mp-baidu", + "build:mp-kuaishou": "uni build -p mp-kuaishou", + "build:mp-lark": "uni build -p mp-lark", + "build:mp-qq": "uni build -p mp-qq", + "build:mp-toutiao": "uni build -p mp-toutiao", + "build:mp-weixin": "uni build -p mp-weixin", + "build:quickapp-webview": "uni build -p quickapp-webview", + "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei", + "build:quickapp-webview-union": "uni build -p quickapp-webview-union" + }, + "dependencies": { + "@dcloudio/uni-app": "3.0.0-3061820230117001", + "@dcloudio/uni-app-plus": "3.0.0-3061820230117001", + "@dcloudio/uni-components": "3.0.0-3061820230117001", + "@dcloudio/uni-h5": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-alipay": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-baidu": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-kuaishou": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-lark": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-qq": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-toutiao": "3.0.0-3061820230117001", + "@dcloudio/uni-mp-weixin": "3.0.0-3061820230117001", + "@dcloudio/uni-quickapp-webview": "3.0.0-3061820230117001", + "@dcloudio/uni-ui": "^1.4.23", + "@rollup/plugin-commonjs": "^25.0.1", + "add": "^2.0.6", + "crypto-js": "^4.1.1", + "js-md5": "^0.7.3", + "vue": "3.2.45", + "vue-i18n": "9.2.2", + "vuex": "^4.0.2" + }, + "devDependencies": { + "@dcloudio/types": "3.2.11", + "@dcloudio/uni-automator": "3.0.0-3061820230117001", + "@dcloudio/uni-cli-shared": "3.0.0-3061820230117001", + "@dcloudio/uni-stacktracey": "3.0.0-3061820230117001", + "@dcloudio/vite-plugin-uni": "3.0.0-3061820230117001", + "@types/js-md5": "^0.4.3", + "@types/node": "^18.11.11", + "sass": "^1.56.1", + "typescript": "^4.8.4", + "vite": "3.2.4" + } +} diff --git a/src/App.ts b/src/App.ts new file mode 100644 index 0000000..3af93c8 --- /dev/null +++ b/src/App.ts @@ -0,0 +1,192 @@ +/** + * 全局文件配置 + */ +import { store } from '@/store' +import { setStorage, getStorage } from "@/utils/storage"; +import Bluetooth from '@/utils/bluetoothPrinter/bluetooth' +import useGlobalFunc from './composables/useGlobalFunc'; +import { onShow, onLaunch } from '@dcloudio/uni-app'; +// import log from '@/utils/log' +import login from '@/api/https/login' + +function App() { + // const bluetooth = new Bluetooth() + const bluetooth: any = getStorage('deviceName') ? new Bluetooth() : null + const { setPrinterStatus } = useGlobalFunc() + + /** + * 小程序冷启动 + */ + onLaunch(async (params: any) => { + // 订单管理-新订单通知 + // let logData = { + // '日志记录时间': Date(), + // '启动类型': '冷启动', + // '启动参数': params, + // '用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN', + // '用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号', + // '店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID', + // '店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字', + // } + // log.info(JSON.stringify(logData)) + if (params.query && params.query.jxStoreId) { + setStorage("storeID", +params.query.jxStoreId) + if (getStorage('token')) await store.dispatch('storeInfo/getOneStore', +params.query.jxStoreId) + } + + if (params.scene === 1043) { + // 公众号模板消息进入 + setStorage('templateMessage', params) + } + + // 判断当前用户是否需要绑定手机号 + let getCode = await login.get_jx_code(true); + let userInfo = await login.applets_login({ + authType: "weixinmini", + authSecret: getCode.code, + },true); + if(userInfo.code === '0'){ + store.commit('serveInfo/setIsBindMobile',{ + userInfo:userInfo.data, + need:userInfo.data.tokenType === 1?false:true + }) + } + }) + + /************************************************* + * 页面出现 热启动 + */ + let reconnectTime1: any = null + onShow(async (params: any) => { + + // let logData = { + // '日志记录时间': Date(), + // '启动类型': '热启动', + // '启动参数': params, + // '用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN', + // '用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号', + // '店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID', + // '店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字', + // } + // log.info(JSON.stringify(logData)) + // if (params.query && params.query.jxStoreId) { + // setStorage("storeID", +params.query.jxStoreId) + // if (getStorage('token')) await store.dispatch('storeInfo/getOneStore', +params.query.jxStoreId) + // } + // 订单管理-新订单通知 + // console.log('热启动9999', params) + if (params.scene === 1043) { + // 公众号模板消息进入 + if (JSON.stringify(getStorage("templateMessage")) !== JSON.stringify(params)) setStorage('templateMessage', params) + + } + + if (getStorage('deviceName')) { + reconnectTime1 = setTimeout(async () => { + await bluetooth.reconnect() + clearTimeout(reconnectTime1) + }, 1500) + } + }) + + + /** + * 获取设备信息 + */ + async function SystemInfo() { + uni.getSystemInfo({ + success(res) { + // 保存本机系统信息 + // 详细字段信息参考 https://uniapp.dcloud.net.cn/api/system/info.html#%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF%E7%9A%84%E6%A6%82%E5%BF%B5 + store.commit('serveInfo/setSystemInfo', JSON.stringify(res)) + }, + }) + } + + + /************************************************* + * 监听网络类型 + */ + function onNetWorkStatusChange() { + uni.onNetworkStatusChange((res) => { + store.commit('serveInfo/setIsNetWorkS', res.isConnected) + }) + } + + + /** + * 微信小程序更新机制 + */ + function autoUpdate() { + // 获取小程序更新机制兼容 + if (uni.canIUse('getUpdateManager')) { + const updateManager = uni.getUpdateManager() + // 检查是否有新版本发布 + updateManager.onCheckForUpdate(function (res) { + if (res.hasUpdate) { + //小程序有新版本,则静默下载新版本,做好更新准备 + updateManager.onUpdateReady(function () { + uni.jxAlert({ + title: '更新提示', + content: '应用已经升级到新版本了请及时更新', + success: () => { + updateManager.applyUpdate() + } + }) + }) + // 新的版本下载失败 + updateManager.onUpdateFailed(function () { + uni.showModal({ + title: '温馨提示', + content: '新版本已经上线,请您删除当前小程序,重新搜索打开', + }) + }) + } + }) + } else { + // 提示用户在最新版本的客户端上体验 + uni.showModal({ + title: '温馨提示', + content: '当前微信版本过低,可能无法使用该功能,请升级到最新版本后重试。' + }) + } + } + + + /************************************************* + * 判断用户是否为IOS系统 + * @param {} + * @return {boolean} // 是否为IOS系统 + */ + function isIosSystem() { + setStorage('isIosSystem', true) + } + + + /************************************************* + * 打印机检测 + */ + let reconnectTime: any = null + function onPrinterChange() { + if (getStorage('deviceName')) { + setPrinterStatus() + reconnectTime = setTimeout(async () => { + await bluetooth.reconnect() + clearTimeout(reconnectTime) + }, 1500) + } + } + + + return { + SystemInfo, // 获取本机系统信息 + onNetWorkStatusChange, // 监听网络状态 + autoUpdate, // 小程序更新 + isIosSystem, // 是否为IOS + onPrinterChange, // 监听打印机状态 + } +} + + + +export default App \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..3a91ed2 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,39 @@ + + diff --git a/src/androidPrivacy.json b/src/androidPrivacy.json new file mode 100644 index 0000000..a78485c --- /dev/null +++ b/src/androidPrivacy.json @@ -0,0 +1,3 @@ +{ + "prompt" : "none" +} diff --git a/src/api/config.ts b/src/api/config.ts new file mode 100644 index 0000000..7dfc9eb --- /dev/null +++ b/src/api/config.ts @@ -0,0 +1,21 @@ +/** + * model: 配置文件 + * 作者:zhang-shu-wei + * 日期:2022年8月10日 + * 邮箱:2966211270@qq.com + */ +let url_config = '' // 用户登录 + + +if (process.env.NODE_ENV === 'development') { + // 开发环境 配置域名 + console.log('~开发环境~') + url_config = "https://wx.jxc4.com" +} else { + // 生产环境 + console.log('~生产环境~') + url_config = "https://wx.jxc4.com" +} + + +export default url_config \ No newline at end of file diff --git a/src/api/https/login.ts b/src/api/https/login.ts new file mode 100644 index 0000000..843ac6b --- /dev/null +++ b/src/api/https/login.ts @@ -0,0 +1,120 @@ +/************************************************* + *@description: 登录模块 + *@return {*} + *@param {}- +*/ + +import { setLoading } from '@/utils/tools' +import request from '../request' + + +const login = { + /************************************************* + * 获取微信登录code + */ + get_jx_code: (isLoading?:boolean): Promise => new Promise((resolve, reject) => { + if(!isLoading) setLoading('登录中...') + uni.login({ + provider: 'weixin', + success: (res) => { + resolve(res) + }, + fail: (error) => { + reject(error) + } + }) + }), + + + /************************************************* + * 获取用户信息 + */ + applets_login: (params: AnyObject,isLoading?:boolean): Promise => { + if(!isLoading) setLoading('登录中...') + return request.api('/v2/auth2/Login', 'POST', params) + }, + + + /************************************************* + * 用户绑定手机号 + */ + add_auth_bind: async (params: AnyObject): Promise => { + return await request.api('/v2/auth2/AddAuthBindWithMobile', 'POST', params) + }, + + + /************************************************* + * 获取用户手机号 + */ + getUser_by_mini_info: async (params: AnyObject): Promise => { + return await request.api('/v2/auth2/GetUserByMiniInfo', 'POST', params) + }, + + + /************************************************* + * 刷新token + */ + get_token_info: async (params?: AnyObject): Promise => { + return await request.api('/v2/auth2/GetTokenInfo', 'GET', params) + }, + + + /************************************************* + * 获取手机登录验证码 + */ + send_verify_code: async (params: AnyObject): Promise => { + return await request.api('/v2/auth2/SendVerifyCode', 'POST', params) + }, + + + /************************************************* + * 注册用户 + */ + register_user: async (params: AnyObject): Promise => { + return await request.api('/v2/user2/RegisterUser', 'POST', params) + }, + + + /************************************************* + * 选择门店 + */ + get_my_store_list: async (params?: AnyObject): Promise => { + + return await request.api('/v2/user2/GetMyStoreList', 'GET', params) + }, + + + /************************************************* + * 获取系统数据 + */ + get_service_info: async (params?: AnyObject): Promise => { + return await request.api('/v2/cms/GetServiceInfo', 'GET', params) + }, + + + /************************************************* + * 查询用户其他信息,比如角色等 + */ + get_self_info: async (params?: AnyObject): Promise => { + return await request.api('/v2/user2/GetSelfInfo', 'GET', params) + }, + + + /************************************************* + * 修改密码 + */ + change_password: async (params?: AnyObject): Promise => { + return await request.api('/v2/auth2/ChangePassword', 'PUT', params) + }, + + /************************************************* + * 测试推送消息 + * @param vendorOrderID 订单id + */ + test_uni_app_push: async (params?: AnyObject): Promise => { + return await request.api('/v2/event/TestUniAppPush', 'GET', params) + } +} + + +export default login \ No newline at end of file diff --git a/src/api/https/merchant.ts b/src/api/https/merchant.ts new file mode 100644 index 0000000..e1dd863 --- /dev/null +++ b/src/api/https/merchant.ts @@ -0,0 +1,267 @@ +/** + * @description: 商家中心 + * @return {*} + * @param {}- + */ +import request from "../request"; + + +const merchant = { + /** + * 获取门店营业状态 + */ + get_stores: async (params: AnyObject): Promise => { + return await request.api('/v2/store/GetStores', 'GET', params) + }, + + + /** + * @desc 多用型接口 + * 设置门店营业 休息 + * 切换未拣货提醒方式 + * 修改印业资质 + */ + update_store: async (params: AnyObject): Promise => { + return await request.api('/v2/store/UpdateStore', 'PUT', params) + }, + + + /** + * 修改线上淘鲜达时间 + */ + update_txd_store: async (params: AnyObject): Promise => { + return await request.api('/v2/store/UpdateTxdStore', 'POST', params) + }, + + + /** + * 更新平台营业状态 线上 + */ + update_vendors_store_states: async (params: AnyObject): Promise => { + return await request.api('/v2/store/UpdateVendorStoreBussinessStatus', 'POST', params) + }, + + + /** + * @desc 修改门店映射信息 + * @param {object} params 请求参数 storeID int 门店ID vendorID int 厂商ID + */ + update_store_vendor_map: async (params: AnyObject): Promise => { + return await request.api('v2/store/UpdateStoreVendorMap','PUT',params) + }, + + + /** + * 查询是否有新账单 + */ + get_store_bills: async (params: AnyObject): Promise => { + return await request.api('/v2/financial/GetStoreBills', 'GET', params) + }, + + + /** + * 获取门店今日完成实时数据 + */ + get_store_order_sale_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetStoresOrderSaleInfo', 'GET', params, 30000) + }, + + + /** + * 获取用户注册时间 + */ + get_self_info: async (params?: AnyObject): Promise => { + return await request.api('/v2/user2/GetSelfInfo', 'GET', params) + }, + + + /** + * 获取调价包 + */ + query_configs: async (params: AnyObject): Promise => { + return await request.api('/v2/cms/QueryConfigs', "GET", params) + }, + + + /** + * 修改调价包 + */ + update_store_price_pack: async (params: AnyObject): Promise => { + return await request.api('/v2/store/UpdateStorePricePack', "PUT", params) + }, + + + /** + * 获取差评数量 + */ + tmp_get_jx_bad_comments_no: async (params: AnyObject): Promise => { + return await request.api('/v2/store/TmpGetJxBadCommentsNo', 'GET', params) + }, + + + /** + * 获取评论 + */ + Tmp_get_jx_bad_comments_by_storeId: async (params: AnyObject): Promise => { + return await request.api('/v2/store/TmpGetJxBadCommentsByStoreId', 'GET', params) + }, + + + /** + * 获取店铺评分 + */ + get_weekly_store_score: async (params: AnyObject): Promise => { + return await request.api('/v2/store/GetWeeklyStoreScore', 'GET', params) + }, + + + /** + * 获取待配商品 + */ + get_order_ders_accept: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetOrdersAccept', 'GET', params) + }, + + + /** + * 通过skuID skuName 获取商品 + */ + get_stores_skus: async (params: AnyObject): Promise => { + return await request.api('/v2/store/sku/GetStoresSkus', "GET", params) + }, + + + /** + * 获取信息通知 + */ + Get_store_message_statuses: async (params: AnyObject): Promise => { + return await request.api('/v2/msg/GetStoreMessageStatuses', 'GET', params) + }, + + + /** + * 获取信息详情 + */ + get_store_messages: async (params: AnyObject): Promise => { + return await request.api('/v2/msg/GetStoreMessages', 'GET', params) + }, + + + /** + * 修改信息为已读 + */ + read_store_message: async (params: AnyObject): Promise => { + return await request.api('/v2/msg/ReadStoreMessage', 'PUT', params) + }, + + + /** + * 获取门店活动信息 + */ + query_acts: async (params: AnyObject): Promise => { + return await request.api('/v2/act/QueryActs', 'GET', params) + }, + + + /** + * 获取打印机能识别的数据 + */ + get_order_sku_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetOrderSkuInfo', 'GET', params) + }, + + + /** + * 判断蓝牙打印机是否需要打印标题 + */ + get_brands: async (prams: AnyObject): Promise => { + return await request.api('/v2/store/GetBrands', 'GET', prams) + }, + + + /** + * 修改打印状态为 true + */ + set_order_print_status: async (prams: AnyObject): Promise => { + return await request.api('/v2/order/SetOrderPrintStatus', 'PUT', prams) + }, + + + /** + * 清空打印队列 + */ + delete_printer_seq: async (params: AnyObject): Promise => { + return request.api('/v2/store/DeletePrinterSeq', 'POST', params) + }, + + + /** + * 扫码绑定易联云 + */ + bind_net_printer: async (params: AnyObject): Promise => { + return request.api('/v2/store/BindPrinter', 'POST', params) + }, + + + /** + * 获取七牛云TOKEN + */ + get_qiniu_upload_token: async (params: AnyObject): Promise => { + return request.api('/v2/cms/GetQiniuUploadToken', 'GET', params) + }, + + + /** + * 扫码进店,获取当前门店的二维码 + */ + get_weixin_unlimited: async (params: AnyObject): Promise => { + return request.api('/v2/event/GetWeixinUnlimited', 'POST', params) + }, + + + /** + * 获取app版本号 + */ + get_app_varsion: async (params: AnyObject): Promise => { + return request.api('/v2/version/GetVersionController', 'GET', params) + }, + + + /** + * 获取门店信息 + */ + get_store_vendor_maps: async (params: AnyObject): Promise => { + return request.api('/v2/store/GetStoreVendorMaps', 'GET', params) + }, + + + /** + * 查询美团门店IM单聊开关状态 + * @return {string} appPoiCode:美团门店id + */ + get_mt_store_im_status: async (params: AnyObject): Promise => { + return request.api('/v2/im/GetPoiIMStatus', 'GET', params) + }, + + + /** + * 设置美团门店IM线上状态 + * @param {object} params 请求参数 + * @return {object} appPoiCode:美团门店id imStatus:状态 0-关闭 1-开启 + */ + set_mt_store_im_status: async (params: AnyObject): Promise => { + return request.api('/v2/im/SetPoiIMStatus', 'POST', params) + }, + + + /** + * 查询远端门店的营业状态 + * @param {object} params 请求参数 + */ + get_vendor_store:async(params:AnyObject): Promise =>{ + return request.api('/v2/store/GetVendorStore', 'GET', params) + } +} + + +export default merchant \ No newline at end of file diff --git a/src/api/https/message.ts b/src/api/https/message.ts new file mode 100644 index 0000000..63bda90 --- /dev/null +++ b/src/api/https/message.ts @@ -0,0 +1,48 @@ +/** + * @description: IM消息管理 + * @return {*} + * @param {}- + */ +import request from "../request"; + + +const message = { + /************************************************* + * 获取消息用户列表 + */ + get_IM_user_list: async (params: AnyObject): Promise => { + return request.api('/v2/im/GetIMUserList', 'GET', params) + }, + + /************************************************* + * 解析饿了么消息中的mediaID + */ + get_url_by_mediaID: async (params: AnyObject): Promise => { + return request.api('/v2/im/GetElmMedia', 'GET', params) + }, + + /************************************************* + * 获取聊天详情 + */ + get_IM_chat_detail: async (params: AnyObject): Promise => { + return request.api('/v2/im/GetImChatDetail', 'GET', params) + }, + + + /************************************************* + * 设置消息为已读 + */ + set_IM_msg_read: async (params: AnyObject): Promise => { + return request.api('/v2/im/SetImMsgRead', 'POST', params) + }, + + + /************************************************* + * 发送消息接口 + */ + send_to_vendor: async (params: AnyObject): Promise => { + return request.api('/v2/im/SendToVendorV2', 'POST', params) + }, +} + +export default message \ No newline at end of file diff --git a/src/api/https/order.ts b/src/api/https/order.ts new file mode 100644 index 0000000..7ab2e94 --- /dev/null +++ b/src/api/https/order.ts @@ -0,0 +1,519 @@ +import request from '../request' + + +/** + * 订单类接口 + * @param * + * @return * +*/ +const order = { + /*********************************************************** + * 获取商户订单数量(统计) + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + Get_store_rder_count_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetStoreOrderCountInfo', 'GET', params) + }, + + + /*********************************************************** + * 获取售后单(统计) + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + Get_store_afs_order_countinfo: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetStoreAfsOrderCountInfo', 'GET', params) + }, + + + /*********************************************************** + * 获取对应状态的订单数据 + * @param {object} params 请求参数 + * @return {object} code:状态 data:{totalCount:总条数,data:分页数据} desc:错误信息 + */ + get_orders: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetOrders', 'GET', params) + }, + + + /************************************************************* + * 确认接单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据,desc:错误信息 + */ + accept_or_refuse_order: async (params: AnyObject): Promise => { + return await request.api('/v2/order/AcceptOrRefuseOrder', 'POST', params) + }, + + + /************************************************************* + * 获取打印机状态 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_printer_status: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetPrinterStatus', 'GET', params) + }, + + + /************************************************************* + * 网络打印机打印订单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + print_order: async (params: AnyObject): Promise => { + return await request.api('/v2/order/PrintOrder', 'PUT', params) + }, + + + /************************************************************* + * 拣货完成 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + finished_pickup: async (params: AnyObject): Promise => { + return await request.api('/v2/order/FinishedPickup', 'POST', params) + }, + + + /************************************************************* + * 自提订单 京西订单不用自提 id + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + confirm_self_take: async (params: AnyObject): Promise => { + return await request.api('/v2/order/ConfirmSelfTake', 'POST', params) + }, + + + /************************************************************* + * 确认送送达 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + self_delivered: async (params: AnyObject): Promise => { + return await request.api('/v2/order/SelfDelivered', 'POST', params) + }, + + + /************************************************************* + * 获取售后订单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_afs_orders: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetAfsOrders', 'GET', params) + }, + + + /************************************************************* + * 非饿百订单 退货退款 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + agree_orRefuse_refund: async (params: AnyObject): Promise => { + return await request.api('/v2/order/AgreeOrRefuseRefund', 'PUT', params) + }, + + + /************************************************************* + * @description 扫码枪 到店扫码支付订单退款 收获退款 post jxorder/RefundOnlineOrder + * @Param token header string true "认证token" + * @Param vendorOrderID formData string true "订单ID" + * @Param skuIds formData string true "[key:value]退款商品 skuId:count,int" Map类型 + * @Param Reason formData string true "退单原因" + */ + refund_online_order: async(params: AnyObject): Promise => { + return await request.api('/v2/jxorder/RefundOnlineOrder','POST', params) + }, + + + /************************************************************* + * 饿百订单 京东的异常单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + agree_or_refuse_cancel: async (params: AnyObject): Promise => { + // 原来饿百订单退款或者驳回的接口有问题,更换成原来的退款 + return await request.api('/v2/order/AgreeOrRefuseCancel', 'PUT', params) + }, + + + /************************************************************* + * 退货待确认 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + confirm_received_return_goods: async (params: AnyObject): Promise => { + return await request.api('/v2/order/ConfirmReceivedReturnGoods', 'PUT', params) + }, + + + /************************************************************* + * 退货待确认 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_order_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetOrderInfo', 'GET', params) + }, + + + /************************************************************* + * 查询取消订单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + getafs_orders: async (params: AnyObject): Promise => { + return await request.api('/v2/order/getafsOrders', 'POST', params) + }, + + + /************************************************************* + * 取消订单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + cancel_order: async (params: AnyObject): Promise => { + return await request.api('/v2/order/CancelOrder', 'PUT', params) + }, + + + /************************************************************* + * 获取条形码 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + create_qrOr_bar_code: async (params: AnyObject): Promise => { + return await request.api('/v2/cms/CreateQrOrBarCode', 'POST', params) + }, + + + /************************************************************* + * 查询是否是京西新用户 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_order_user_buy_first: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetOrderUserBuyFirst', 'GET', params) + }, + + + /************************************************************* + * 获取运单状态 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_order_status_list: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetOrderStatusList', 'GET', params) + }, + + + /************************************************************* + * 获取商品列表 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_order_sku_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetOrderSkuInfo', 'GET', params) + }, + + + /************************************************************* + * 获取订单差评骑手列表 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + complaint_rider_list: async (params: AnyObject): Promise => { + return await request.api('/v2/order/ComplaintRiderList', 'GET', params) + }, + + + /************************************************************* + * 差评骑手 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + complaint_rider: async (params: AnyObject): Promise => { + return await request.api('/v2/order/ComplaintRider', 'POST', params) + }, + + + /************************************************************* + * 商品部分退款 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + part_refund_order: async (params: AnyObject): Promise => { + return await request.api('/v2/order/PartRefundOrder', 'PUT', params) + }, + + + /************************************************************* + * 商品全额退款并创建售后单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + refund_order: async (params: AnyObject): Promise => { + return await request.api('/v2/order/RefundOrder', 'PUT', params) + }, + + + /************************************************************* + * 直接部分退款 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + adjust_order: async (params: AnyObject): Promise => { + return await request.api('/v2/order/AdjustOrder', 'PUT', params) + }, + + + /************************************************************* + * 售后商品 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_afs_order_sku_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetAfsOrderSkuInfo', 'GET', params) + }, + + + /************************************************************* + * 获取运单费用 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + query_order_waybill_fee_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/QueryOrderWaybillFeeInfo', 'GET', params) + }, + + + /************************************************************* + * 获取品牌账号余额 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_brands: async (params?: AnyObject): Promise => { + return await request.api('/v2/store/GetBrands', 'GET', params) + }, + + + /************************************************************* + * 获取门店账号余额 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_store_acct_balance: async (params?: AnyObject): Promise => { + return await request.api('/v2/store/GetStoreAcctBalance', 'GET', params) + }, + + + /************************************************************* + * 创建订单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + create_store_acct_order: async (params?: AnyObject): Promise => { + return await request.api('/v2/jxorder/CreateStoreAcctOrder', 'POST', params) + }, + + + /************************************************************* + * 支付订单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + pay4_user: async (params: AnyObject): Promise => { + return await request.api('/v2/jxorder/Pay4User', 'POST', params) + }, + + + /************************************************************* + * 非抖音订单转自送 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + self_delivering: async (params: AnyObject): Promise => { + return await request.api('/v2/order/SelfDelivering', 'POST', params) + }, + + + /************************************************************* + * 添加小费 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + update_order_waybill_tip: async (params: AnyObject): Promise => { + return await request.api('/v2/order/UpdateOrderWaybillTip', 'POST', params) + }, + + + /************************************************************* + * 切换发单方式 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + update_store_courier_map: async (params: AnyObject): Promise => { + return await request.api('/v2/store/UpdateStoreCourierMap', 'PUT', params) + }, + + + /************************************************************* + * 创建三方配送 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + create_waybill_on_providers: async (params: AnyObject): Promise => { + return await request.api('/v2/order/CreateWaybillOnProviders', 'POST', params) + }, + + + /************************************************************* + * 取消订单 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + cancel_waybill: async (params: AnyObject): Promise => { + return await request.api('/v2/order/CancelWaybill', 'POST', params) + }, + + + /************************************************************* + * 骑手 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + accept_or_refuse_failed_get_order: async (params: AnyObject): Promise => { + return await request.api('/v2/order/AcceptOrRefuseFailedGetOrder', 'PUT', params) + }, + + + /************************************************************* + * 重新召唤骑手 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + callP_m_courier: async (params: AnyObject): Promise => { + return await request.api('/v2/order/CallPMCourier', 'PUT', params) + }, + + + /************************************************************* + * 退回货物 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + confirm_receive_goods: async (params: AnyObject): Promise => { + return await request.api('/v2/order/ConfirmReceiveGoods', 'PUT', params) + }, + + /************************************************************* + * 查看客户距离 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_ST_o_U_riding_distance: async (params: AnyObject): Promise => { + return await request.api('/v2/cms/GetSToURidingDistance', 'GET', params) + }, + + + /************************************************************* + * 获取骑手位置 + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_rider_lng: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetRiderLng', 'POST', params) + }, + + /************************************************************* + * 获取骑手位置(实时) + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + get_s_to_u_riding_distance: async (params: AnyObject): Promise => { + return await request.api('/v2/cms/GetSToURidingDistance2', 'GET', params) + }, + + + /************************************************************* + * 取消所有三方运单(取消所有配送) + * @param {object} params 请求参数 + * @return {object} code:状态 data:数据 desc:错误信息 + */ + cancel_all_3rd_waybills: async (params: AnyObject): Promise => { + return await request.api('/v2/order/CancelAll3rdWaybills', 'POST', params) + }, + + + /*************************************************************** + * 查询发票信息,美团 + * @Param storeId formData int false "门店id" + * @Param startTime formData string true "开始时间" + * @Param endTime formData string true "结束时间" + * @Param status formData string false "发票回复状态[1未回复/2回复]" + * @Param offset query int false "结果起始序号(以0开始,缺省为0)" + * @Param pageSize query int false "结果页大小(缺省为50,-1表示全部)" + */ + query_mt_invoice: async (params: AnyObject): Promise => { + return await request.api('/v2/order/GetInvoiceRecord', 'POST', params) + }, + + + /** + * 上传发票图片 + * @Param token header string true "认证token" + * @Param orderId formData string true "订单ID" + * @Param invoiceUrl formData string true "发票地址[10M内pdf/png/jpeg/jpg]" + * @Param invoiceId formData string true "发票号码" + */ + upload_invoice_img: async (params: AnyObject): Promise => { + return await request.api('/v2/order/UploadOrderInvoice', 'POST', params) + }, + + + /** + * 发票设置 饿百 + * @Title 批量更新门店发票设置 + * @Description 批量更新门店发票设置 + * @Param token header string true "认证token" + * @Param vendorId formData string true "平台ID" + * @Param vendorStoreID formData string true "平台门店ID" + * @Param payload formData string true "json数据,格式为 ebaiapi.StoreInvoiceSetting",见JXC4-BACKSTAGE + */ + bath_update_invoice_setting: async (params: AnyObject): Promise => { + return await request.api('/v2/order/BathUpdateInvoiceSetting', 'POST', params) + }, + + + /** + * @Title 查询门店发票设置 + * @Description 查询门店发票设置 + * @Param token header string true "认证token" + * + * @Param vendorId formData string true "平台ID" + * @Param vendorStoreID formData string true "平台门店ID" + */ + query_invoice_setting: async (params: AnyObject): Promise => { + return await request.api('/v2/order/QueryInvoiceSetting', 'GET', params) + }, + + + /** + * @Title 查询门店开票申请 饿百 + * @Description 批量更新店铺开票申请 + * @Param token header string true "认证token" + * @Param vendorId formData string true "平台ID" + * @Param vendorStoreID formData string true "平台门店ID" + * @Param storeID formData int true "京西门店ID" + */ + get_invoice_info: async (params: AnyObject): Promise => { + return await request.api('/v2/order/QueryUnansweredInvoice', 'GET', params) + }, + +} + + +export default order \ No newline at end of file diff --git a/src/api/https/shopping.ts b/src/api/https/shopping.ts new file mode 100644 index 0000000..b06e263 --- /dev/null +++ b/src/api/https/shopping.ts @@ -0,0 +1,98 @@ +/** + * @description: 商品管理 + * @return {*} + * @param {}- + */ +import request from "../request"; + + +const shopping = { + /************************************************* + * 修改商品价格 + */ + update_stores_skus: async (params: AnyObject): Promise => { + return request.api('/v2/store/sku/UpdateStoresSkus', 'PUT', params) + }, + + + /************************************************* + * 修改商品为临时不可售 + */ + update_stores_skus_sale: async (params: AnyObject): Promise => { + return request.api('/v2/store/sku/UpdateStoresSkusSale', 'PUT', params) + }, + + + /************************************************* + * 获取商品分类 + */ + getStore_category_map: async (params: AnyObject): Promise => { + return request.api('/v2/store/GetStoreCategoryMap', 'GET', params) + }, + + + /************************************************* + * 备用获取分类列表 + */ + get_categories: async (params?: AnyObject): Promise => { + return request.api('/v2/sku/GetCategories', 'GET', params) + }, + + + /************************************************* + * 获取商品 + */ + get_stores_skus_for_store: async (params?: AnyObject): Promise => { + return request.api('/v2/store/sku/GetStoresSkusForStore', 'GET', params) + }, + + + /************************************************* + * 获取商品 + */ + get_top_skus_by_city_code: async (params?: AnyObject): Promise => { + return request.api('/v2/store/sku/GetTopSkusByCityCode', 'GET', params) + }, + + + /************************************************* + * 获取待审核列表 + */ + get_store_sku_audit: async (params?: AnyObject): Promise => { + return request.api('/v2/store/sku/GetStoreSkuAudit', 'GET', params) + }, + + + /************************************************* + * 获取待审核列表 + */ + get_sku_names_new: async (params?: AnyObject): Promise => { + return request.api('/v2/sku/GetSkuNamesNew', 'GET', params) + }, + + + /************************************************* + * 审核商品 + */ + store_sku_price_audit: async (params: AnyObject): Promise => { + return request.api('/v2/store/sku/StoreSkuPriceAudit', 'POST', params) + }, + + + /************************************************* + * 请求京东商品库 + */ + get_jd_upc_code_by_name: async (params: AnyObject): Promise => { + return request.api('/v2/sku/GetJdUpcCodeByName', 'GET', params) + }, + + + /************************************************* + * 微信扫码创建商品 + */ + create_skus_and_focus_from_wx: async (params: AnyObject): Promise => { + return request.api('/v2/store/sku/CreateSkusAndFocusFromWx', 'POST', params) + }, +} + +export default shopping \ No newline at end of file diff --git a/src/api/mockData/index.ts b/src/api/mockData/index.ts new file mode 100644 index 0000000..5d6cc1e --- /dev/null +++ b/src/api/mockData/index.ts @@ -0,0 +1,135 @@ +/** + * 模拟后端返回的数据 + */ + +// 聊天消息 +export const msgInfo = { + // 用户列表 + userList: { + code: '0', + data: { + // '5873:18003191:1': ['{"vendorID":1,"userID":"11555094096","orderID":"","NewMessageNum":0,"latestMsg":"eAcvT+OGsaVYx/Avh6VagA==","latestTime":1695691485}'], + '34665:1157916361:3': ['{\"vendorID\":3,\"userID\":\"$2$13205337818$PNM\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"{\\\"extensions\\\":{\\\"appName\\\":\\\"ELEME\\\",\\\"industryType\\\":\\\"NEW_RETAIL\\\",\\\"current_msg_source\\\":\\\"ELEME\\\",\\\"imsdk_role_name\\\":\\\"顾客\\\",\\\"imsdk_self_show_name\\\":\\\"45d46975e\\\",\\\"imsdk_other_show_name\\\":\\\"45d46975e\\\"},\\\"text\\\":\\\"[微笑]\\\"}\", "latestTime": 1695691485}'], + }, + desc: '' + + // code: "0", + // data: { + // '34665:1157916361:3': ['{"vendorID":3,"userID":"$2$13205337818$PNM","orderID":"","NewMessageNum":1,"latestMsg":"{"extensions":{"appName":"ELEME","industryType":"NEW_RETAIL","current_msg_source":"ELEME","imsdk_role_name":"顾客","imsdk_self_show_name":"45d46975e","imsdk_other_show_name":"45d46975e"},"text":"[微笑]"}","latestTime":1698303946914}'], + // '5873:18003191:1': ['{"vendorID":1,"userID":"9533643193","orderID":"","NewMessageNum":0,"latestMsg":"dTZiwxiOJI5b5zwb1/uCwcCxh3F9MrZtyR+ojZoql4wtzgMh/gzuGRffhgWQd4Sz","latestTime":1698295674}", "{"vendorID":1,"userID":"12169240445","orderID":"1100782041270894459","NewMessageNum":0,"latestMsg":"ZiiFa7hQp0BV60OuBKPExiN6IN7fRkjzmcVpaA+kQoQ=","latestTime":1698295257}', '{"vendorID":1,"userID":"10892282642","orderID":"1100782384203287879","NewMessageNum":0,"latestMsg":"K/qIurzlbi2B7zv65/mCQg==","latestTime":1698295422}', '{"vendorID":1,"userID":"11009807262","orderID":"","NewMessageNum":0,"latestMsg":"+tFz6s6u+O8Ndpc2dwP4HA==","latestTime":1698297046}', '{"vendorID":1,"userID":"11436731575","orderID":"","NewMessageNum":0,"latestMsg":"iMqYgHLYMjKY3JoSMG9YLQ==","latestTime":1698295279}', '{"vendorID":1,"userID":"9167982931","orderID":"","NewMessageNum":0,"latestMsg":"R4cR7u9LPax/LDKqVHWVLw==","latestTime":1698300481}', '{"vendorID":1,"userID":"11432640354","orderID":"","NewMessageNum":0,"latestMsg":"QY5plA6VHEKS7GqXV4jJElsh0x90ftjPFGGoZjX4M/84LQn7ucu0ZeruelSd/VmmZ0OD966b6g5+0ZrgsLBIZiDo2sEOk8a02UUwNt60FPKZEhaCURWvYjCBqDJA8laH","latestTime":1698304171}', '{"vendorID":1,"userID":"10946780381","orderID":"1100782881905266609","NewMessageNum":1,"latestMsg":"dtj7qIlXCPm1ZWUjwfEPc65cnsG57UYatDG6g/kYjYU+CSzeFNPE1THgv2cHUB0QhpNo6jEnCDc0Vte2V5h14J7NJ5Zbaprfysx+gLRua68o2Pp4pF0LDSMLQ+7pGh/GRDjdfYYS4qFqU17eBbT82x1LjsuY1HWe8Z2znWyo43nEcLbtPFU09HwXFgxOQLBhF4As08Inc7bvN6BPR8F46QtQR52+PvxiWdsDRV54/F2CqxuoFR3up6wKmxvyzDWyEAgFI8Ym7zqItVBfG8HtEXTezY3gCjtpK0qRoYJqJ+dIuQewnDXbbxyqu/JvXSdiLYVRdrZgY9UI1hBDQU4zN6XI2u/w8tzk3a6mSrTCfUyaB0xr5/bwLYfgwV4WDw0EaLQEr2R0OmMerlRMheR3A+GMYVxl+BcYx0fUrKuH7Fs1TNSRCS4ug4iMr/GoTv76J8jl1b2ihrFDPiVQRxPdSw==","latestTime":1698308642}'] + // }, + // desc: "" + }, + // 聊天详情 + chatDetail: { + // code: '0', + // data: { + // '5873:18003191:1:11555094096': [ + // // '{"sendType":"mt","msgContent":{"app_id":5873,"app_poi_code":"18003191","msg_id":1400636412362739712,"msg_content":"eAcvT+OGsaVYx/Avh6VagA==","msg_source":2,"msg_type":1,"cts":1695691485,"open_user_id":11555094096,"order_id":1100738343654371431,"group_id":0,"app_spu_codes":""}}' + // '{"sendType":"mt","msgContent":{"app_id":5873,"app_poi_code":"18003191","msg_id":1400636412362739712,"msg_content":"kJhw2zGHISMeeNatcB62eoctFxbqneVDKiP75531PhYMisp7wJN44Yk/JpwHwbcg","msg_source":2,"msg_type":1,"cts":1695691485,"open_user_id":11555094096,"order_id":1100738343654371431,"group_id":0,"app_spu_codes":""}}' + // ] + // }, + // desc: '' + code: "0", + // data: { + // "34665:1157916361:3": [ + // // "{"sendType":"mt","msgContent":{"app_id":589,"app_poi_code":"12704348","msg_id":1439524935878283264,"msg_content":"","msg_source":2,"msg_type":4,"cts":1704963231,"open_user_id":11555078706,"order_id":0,"group_id":0,"app_spu_codes":"23163"}}" // 聊天详情 商品卡片 待优化 + // "{\"vendorID\":3,\"userID\":\"$2$13205337818$PNM\",\"orderID\":\"\",\"NewMessageNum\":1,\"latestMsg\":\"{\\\"extensions\\\":{\\\"appName\\\":\\\"ELEME\\\",\\\"industryType\\\":\\\"NEW_RETAIL\\\",\\\"current_msg_source\\\":\\\"ELEME\\\",\\\"imsdk_role_name\\\":\\\"顾客\\\",\\\"imsdk_self_show_name\\\":\\\"45d46975e\\\",\\\"imsdk_other_show_name\\\":\\\"45d46975e\\\"},\\\"text\\\":\\\"[微笑]\\\"}\",\"latestTime\":1698303946914}"], "5873:18003191:1": ["{\"vendorID\":1,\"userID\":\"9533643193\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"dTZiwxiOJI5b5zwb1/uCwcCxh3F9MrZtyR+ojZoql4wtzgMh/gzuGRffhgWQd4Sz\",\"latestTime\":1698295674}", "{\"vendorID\":1,\"userID\":\"12169240445\",\"orderID\":\"1100782041270894459\",\"NewMessageNum\":0,\"latestMsg\":\"ZiiFa7hQp0BV60OuBKPExiN6IN7fRkjzmcVpaA+kQoQ=\",\"latestTime\":1698295257}", "{\"vendorID\":1,\"userID\":\"10892282642\",\"orderID\":\"1100782384203287879\",\"NewMessageNum\":0,\"latestMsg\":\"K/qIurzlbi2B7zv65/mCQg==\",\"latestTime\":1698295422}", "{\"vendorID\":1,\"userID\":\"11009807262\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"+tFz6s6u+O8Ndpc2dwP4HA==\",\"latestTime\":1698297046}", "{\"vendorID\":1,\"userID\":\"11436731575\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"iMqYgHLYMjKY3JoSMG9YLQ==\",\"latestTime\":1698295279}", "{\"vendorID\":1,\"userID\":\"9167982931\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"R4cR7u9LPax/LDKqVHWVLw==\",\"latestTime\":1698300481}", "{\"vendorID\":1,\"userID\":\"11432640354\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"QY5plA6VHEKS7GqXV4jJElsh0x90ftjPFGGoZjX4M/84LQn7ucu0ZeruelSd/VmmZ0OD966b6g5+0ZrgsLBIZiDo2sEOk8a02UUwNt60FPKZEhaCURWvYjCBqDJA8laH\",\"latestTime\":1698304171}", "{\"vendorID\":1,\"userID\":\"10946780381\",\"orderID\":\"1100782881905266609\",\"NewMessageNum\":1,\"latestMsg\":\"dtj7qIlXCPm1ZWUjwfEPc65cnsG57UYatDG6g/kYjYU+CSzeFNPE1THgv2cHUB0QhpNo6jEnCDc0Vte2V5h14J7NJ5Zbaprfysx+gLRua68o2Pp4pF0LDSMLQ+7pGh/GRDjdfYYS4qFqU17eBbT82x1LjsuY1HWe8Z2znWyo43nEcLbtPFU09HwXFgxOQLBhF4As08Inc7bvN6BPR8F46QtQR52+PvxiWdsDRV54/F2CqxuoFR3up6wKmxvyzDWyEAgFI8Ym7zqItVBfG8HtEXTezY3gCjtpK0qRoYJqJ+dIuQewnDXbbxyqu/JvXSdiLYVRdrZgY9UI1hBDQU4zN6XI2u/w8tzk3a6mSrTCfUyaB0xr5/bwLYfgwV4WDw0EaLQEr2R0OmMerlRMheR3A+GMYVxl+BcYx0fUrKuH7Fs1TNSRCS4ug4iMr/GoTv76J8jl1b2ihrFDPiVQRxPdSw==\",\"latestTime\":1698308642}"] + // }, + data: { + "34665:1157916361:3:$2$13205337818$PNM": [ + // "{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"10154538612\",\"receiverIds\":[\"301157916361\",\"10154538612\",\"321921188187760\"],\"createTime\":1698303833173,\"groupId\":\"$2$13205337818$PNM\",\"msgId\":\"1997094742949.PNM\",\"contentType\":2,\"content\":\"{\\\"elements\\\":[{\\\"elementContent\\\":\\\"{\\\\\\\"atAll\\\\\\\":false,\\\\\\\"defaultNick\\\\\\\":\\\\\\\"商家\\\\\\\",\\\\\\\"uid\\\\\\\":{\\\\\\\"appUid\\\\\\\":\\\\\\\"301157916361\\\\\\\",\\\\\\\"domain\\\\\\\":\\\\\\\"eleme\\\\\\\"}}\\\",\\\"elementType\\\":3},{\\\"elementContent\\\":\\\"{\\\\\\\"extensions\\\\\\\":{\\\\\\\"imsdk_self_show_name\\\\\\\":\\\\\\\"45d46975e\\\\\\\",\\\\\\\"appName\\\\\\\":\\\\\\\"ELEME\\\\\\\",\\\\\\\"imsdk_role_name\\\\\\\":\\\\\\\"顾客\\\\\\\",\\\\\\\"imsdk_other_show_name\\\\\\\":\\\\\\\"45d46975e\\\\\\\",\\\\\\\"industryType\\\\\\\":\\\\\\\"NEW_RETAIL\\\\\\\",\\\\\\\"current_msg_source\\\\\\\":\\\\\\\"ELEME\\\\\\\"},\\\\\\\"text\\\\\\\":\\\\\\\"您好,请问我的订单还要多久送达?\\\\\\\"}\\\",\\\"elementType\\\":1}]}\"},\"platformShopId\":\"1157916361\"}}", "{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"10154538612\",\"receiverIds\":[\"301157916361\",\"10154538612\",\"321921188187760\"],\"createTime\":1698303918483,\"groupId\":\"$2$13205337818$PNM\",\"msgId\":\"1996910978679.PNM\",\"contentType\":1,\"content\":\"{\\\"extensions\\\":{\\\"industryType\\\":\\\"NEW_RETAIL\\\",\\\"imsdk_other_show_name\\\":\\\"45d46975e\\\",\\\"imsdk_role_name\\\":\\\"顾客\\\",\\\"imsdk_self_show_name\\\":\\\"45d46975e\\\",\\\"appName\\\":\\\"ELEME\\\",\\\"current_msg_source\\\":\\\"ELEME\\\"},\\\"text\\\":\\\"您好\\\"}\"},\"platformShopId\":\"1157916361\"}}", "{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"10154538612\",\"receiverIds\":[\"301157916361\",\"10154538612\",\"321921188187760\"],\"createTime\":1698303946914,\"groupId\":\"$2$13205337818$PNM\",\"msgId\":\"1991934371357.PNM\",\"contentType\":1,\"content\":\"{\\\"extensions\\\":{\\\"appName\\\":\\\"ELEME\\\",\\\"industryType\\\":\\\"NEW_RETAIL\\\",\\\"current_msg_source\\\":\\\"ELEME\\\",\\\"imsdk_role_name\\\":\\\"顾客\\\",\\\"imsdk_self_show_name\\\":\\\"45d46975e\\\",\\\"imsdk_other_show_name\\\":\\\"45d46975e\\\"},\\\"text\\\":\\\"[微笑]\\\"}\"},\"platformShopId\":\"1157916361\"}}" + + "{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"101000124198002\",\"receiverIds\":[\"321921188187760\",\"101000124198002\",\"301157916361\"],\"createTime\":1699000572978,\"groupId\":\"$2$13315405121$PNM\",\"msgId\":\"2011596619981.PNM\",\"contentType\":\"2\",\"content\":\"{\\\"fileType\\\":3,\\\"mediaId\\\":\\\"$igHNA-kCpGpwZWcDAQTNAc4FzQPoBtoAI4QBpCFQvEYCqrkXr-dN527mZcwDzwAAAYuUU1obBM4Al-xzB88AAFvb7IZscggACgQLzgAB9EQ\\\",\\\"orientation\\\":0,\\\"size\\\":128068}\"},\"platformShopId\":\"1157916361\"}}", + "{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"101000124198002\",\"receiverIds\":[\"321921188187760\",\"101000124198002\",\"301157916361\"],\"createTime\":1699000587153,\"groupId\":\"$2$13315405121$PNM\",\"msgId\":\"2019467437200.PNM\",\"contentType\":\"1\",\"content\":\"{\\\"extensions\\\":{},\\\"text\\\":\\\"是现杀的新鲜鸡\\\"}\"},\"platformShopId\":\"1157916361\"}}", + "{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"101000124198002\",\"receiverIds\":[\"321921188187760\",\"101000124198002\",\"301157916361\"],\"createTime\":1699000598697,\"groupId\":\"$2$13315405121$PNM\",\"msgId\":\"2019605209369.PNM\",\"contentType\":\"8\",\"content\":\"{\\\"elements\\\":[{\\\"elementContent\\\":\\\"{\\\\\\\"atAll\\\\\\\":false,\\\\\\\"defaultNick\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"uid\\\\\\\":{\\\\\\\"appUid\\\\\\\":\\\\\\\"301157916361\\\\\\\",\\\\\\\"domain\\\\\\\":\\\\\\\"eleme\\\\\\\"}}\\\",\\\"elementType\\\":3},{\\\"elementContent\\\":\\\"{\\\\\\\"extensions\\\\\\\":{},\\\\\\\"text\\\\\\\":\\\\\\\"还是冻的?@商家 \\\\\\\"}\\\",\\\"elementType\\\":1}]}\"},\"platformShopId\":\"1157916361\"}}" + ] + }, + desc: "" + } + + // // 美团音频数据 + // code: "0" + // data: "{"5873:18003191:1:11555094096":["{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1411251415327150080,\"msg_content\":\"QYYLNKWSeCO+c2Sw/K73hBtYPD54B+AT5Vndt26ynS0VQW/QJ87hZGwwBVBaM8GB3edmiLPqLzAwR4tzvZjGBO2VmlOjNb6+vYiAWjGY1ACbPdlAq3bLvwlyCe/Kx68Sf2kKF+jWTWFF/bON2VQI/O8C6xBTh2GY4B5jpfEKWllJvqwQXqWc5ietgLEWmuTP7/NcCFZGt8JJfdA7yFQqqb/AS130qAv0/JIvgv9c+ZgAuJmmInjxnEyij7vKntDF5/fDozT+H7zApPunkK+QrE+ewCmErQkk2oWK8m+I1gqLWdYr31sBN72Og81l3u4W8E/hV+sO50U7sQbuHWEASQ==\",\"msg_source\":2,\"msg_type\":3,\"cts\":1698222298,\"open_user_id\":11555094096,\"order_id\":0,\"group_id\":0,\"app_spu_codes\":\"\"}}"]}" + // desc: "" + + // 美团音频数据 + // QYYLNKWSeCO+c2Sw/K73hBtYPD54B+AT5Vndt26ynS0VQW/QJ87hZGwwBVBaM8GB3edmiLPqLzAwR4tzvZjGBO2VmlOjNb6+vYiAWjGY1ACbPdlAq3bLvwlyCe/Kx68Sf2kKF+jWTWFF/bON2VQI/O8C6xBTh2GY4B5jpfEKWllJvqwQXqWc5ietgLEWmuTP7/NcCFZGt8JJfdA7yFQqqb/AS130qAv0/JIvgv9c+ZgAuJmmInjxnEyij7vKntDF5/fDozT+H7zApPunkK+QrE+ewCmErQkk2oWK8m+I1gqLWdYr31sBN72Og81l3u4W8E/hV+sO50U7sQbuHWEASQ== + // https://file.neixin.cn/proxy/0/s3/afc/698bce4c-ddc6-4b10-a24b-3790120a0fa6_1698222298877?AWSAccessKeyId=115479efca564d62820d47f9153702f9&Expires=1698308699&Signature=dOhRnfq0udZFrVPz5sK8j4tj9uo%3D>m=1698222299573&filename=2023-10-25+16%3A24%3A58+907.amr + + + // 用户列表 + // code: "0" + // data: "{"5873:18003191:1":["{\"vendorID\":1,\"userID\":\"9099662511\",\"orderID\":\"1100756014203287879\",\"NewMessageNum\":0,\"latestMsg\":\"sgfc6Fw3EEC+N4h7mR8iLTTIuu6o2eMXVL6JqmAx9LHWroiRUNZXQNLzwrd9bG6I\",\"latestTime\":1696737412}","{\"vendorID\":1,\"userID\":\"11161356777\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"ML73Il8Yl/02TZ7hYx39/Q==\",\"latestTime\":1696748470}","{\"vendorID\":1,\"userID\":\"10492988799\",\"orderID\":\"1100756704146983163\",\"NewMessageNum\":0,\"latestMsg\":\"HFi0BcKs2zyQwwgwk6kUDQ==\",\"latestTime\":1696743753}","{\"vendorID\":1,\"userID\":\"11555094096\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"FskpgyfRcmbvR3Ut0sPVgvRKwIrjZ+uXRjW1HK9k7mQ=\",\"latestTime\":1696752752}","{\"vendorID\":1,\"userID\":\"11121583583\",\"orderID\":\"1100756913067981796\",\"NewMessageNum\":0,\"latestMsg\":\"wXP3NiYAF1hhFM+CD/P3HOzbADez/9KCNvD6L+R0uD0=\",\"latestTime\":1696752253}"]}" + // desc: "" + + // 聊天详情 + // code: "0" + // data: "{"5873:18003191:1:11161356777":["{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1405065885751885824,\"msg_content\":\"dtj7qIlXCPm1ZWUjwfEPc65cnsG57UYatDG6g/kYjYU+CSzeFNPE1THgv2cHUB0QhpNo6jEnCDc0Vte2V5h14J7NJ5Zbaprfysx+gLRua68o2Pp4pF0LDSMLQ+7pGh/GRDjdfYYS4qFqU17eBbT82x1LjsuY1HWe8Z2znWyo43lQ6CpTqmwcGYGriWDe92cWJ9eptuKRkZFmirAkYmuHKyKi3ce9lJ9MH3JogKczw+tmb4ooRd8z9ZiFIMTQ9pG11peV45qLmcZXgMo9Q7t3cZEgX4fU2RGdT2gpGXOTl48599Y79ic49DQU9szebnLslUwZekawLCwt99laGfhPfSZhR5CmeuzfYe/VFlTbQG++BxrK2ZSPrJtqStLVN7gGfnR/cHwmIfSDL3JZwymQ1cA641E8P3BmTQPzboOMNqrbWXYMdiiCbpLfEmYz7i+KoT4CsrBZEmPFuK3C8RynGBUDz9ZTGq+tB1sWC6kFDFN+BbeZz6gzrPFw6ydCHIDh\",\"msg_source\":2,\"msg_type\":5,\"cts\":1696747553,\"open_user_id\":11161356777,\"order_id\":1100756844146983163,\"group_id\":0,\"app_spu_codes\":\"\"}}","{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1405065906828263424,\"msg_content\":\"cCwNlL9ukNzOfS/A76CWnA==\",\"msg_source\":2,\"msg_type\":1,\"cts\":1696747558,\"open_user_id\":11161356777,\"order_id\":1100756844146983163,\"group_id\":0,\"app_spu_codes\":\"\"}}","{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1405065937144692736,\"msg_content\":\"Cx7e5k07X34v9MXn/dPKX3t9cKUo2RTKFegWCoFIg7s=\",\"msg_source\":2,\"msg_type\":1,\"cts\":1696747565,\"open_user_id\":11161356777,\"order_id\":1100756844146983163,\"group_id\":0,\"app_spu_codes\":\"\"}}","{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1405066156422905856,\"msg_content\":\"51kZuOfsFBtHME6GxxkY9SzIP7XDBD1QVKPY/G+RVucUSI32PuK3+5yRI2j2UboLPh8dXFsrLKzbXxwV9P8B6QGlHyiE8V19v4cwFo6hxt0=\",\"msg_source\":2,\"msg_type\":1,\"cts\":1696747618,\"open_user_id\":11161356777,\"order_id\":1100756844146983163,\"group_id\":0,\"app_spu_codes\":\"\"}}","{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1405066372173709312,\"msg_content\":\"TsXJ4usAgosTFgs1ar9DcusMZ5cK5ZfLxBuIjtu3d7k=\",\"msg_source\":2,\"msg_type\":1,\"cts\":1696747669,\"open_user_id\":11161356777,\"order_id\":1100756844146983163,\"group_id\":0,\"app_spu_codes\":\"\"}}","{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1405069732759126016,\"msg_content\":\"ML73Il8Yl/02TZ7hYx39/Q==\",\"msg_source\":2,\"msg_type\":1,\"cts\":1696748470,\"open_user_id\":11161356777,\"order_id\":0,\"group_id\":0,\"app_spu_codes\":\"\"}}"]}" + // desc: "" + + // 加密内容 + // "kJhw2zGHISMeeNatcB62eoctFxbqneVDKiP75531PhYMisp7wJN44Yk/JpwHwbcg" + // 译文:啦啦啦[大哭][睡]忆往昔[嘘]哈哈 + + // 表情 + // code: "0" + // data: "{"5873:18003191:1:11555094096":["{\"sendType\":\"mt\",\"msgContent\":{\"app_id\":5873,\"app_poi_code\":\"18003191\",\"msg_id\":1401396902286315520,\"msg_content\":\"rq+Y2WYA/UjW7inVLzG3IQ==\",\"msg_source\":2,\"msg_type\":1,\"cts\":1695872799,\"open_user_id\":11555094096,\"order_id\":0,\"group_id\":0,\"app_spu_codes\":\"\"}}"]}" + // desc: "" + + // rq+Y2WYA/UjW7inVLzG3IQ==\ + // M/whRohCtpsVTviiMAK8hQ== +} + +// 饿百用户列表 +// code: "0" +// data: "{"34665:1157916361:3":["{\"vendorID\":3,\"userID\":\"$2$13205337818$PNM\",\"orderID\":\"\",\"NewMessageNum\":1,\"latestMsg\":\"{\\\"extensions\\\":{\\\"appName\\\":\\\"ELEME\\\",\\\"industryType\\\":\\\"NEW_RETAIL\\\",\\\"current_msg_source\\\":\\\"ELEME\\\",\\\"imsdk_role_name\\\":\\\"顾客\\\",\\\"imsdk_self_show_name\\\":\\\"45d46975e\\\",\\\"imsdk_other_show_name\\\":\\\"45d46975e\\\"},\\\"text\\\":\\\"[微笑]\\\"}\",\"latestTime\":1698303946914}"],"5873:18003191:1":["{\"vendorID\":1,\"userID\":\"9533643193\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"dTZiwxiOJI5b5zwb1/uCwcCxh3F9MrZtyR+ojZoql4wtzgMh/gzuGRffhgWQd4Sz\",\"latestTime\":1698295674}","{\"vendorID\":1,\"userID\":\"12169240445\",\"orderID\":\"1100782041270894459\",\"NewMessageNum\":0,\"latestMsg\":\"ZiiFa7hQp0BV60OuBKPExiN6IN7fRkjzmcVpaA+kQoQ=\",\"latestTime\":1698295257}","{\"vendorID\":1,\"userID\":\"10892282642\",\"orderID\":\"1100782384203287879\",\"NewMessageNum\":0,\"latestMsg\":\"K/qIurzlbi2B7zv65/mCQg==\",\"latestTime\":1698295422}","{\"vendorID\":1,\"userID\":\"11009807262\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"+tFz6s6u+O8Ndpc2dwP4HA==\",\"latestTime\":1698297046}","{\"vendorID\":1,\"userID\":\"11436731575\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"iMqYgHLYMjKY3JoSMG9YLQ==\",\"latestTime\":1698295279}","{\"vendorID\":1,\"userID\":\"9167982931\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"R4cR7u9LPax/LDKqVHWVLw==\",\"latestTime\":1698300481}","{\"vendorID\":1,\"userID\":\"11432640354\",\"orderID\":\"\",\"NewMessageNum\":0,\"latestMsg\":\"QY5plA6VHEKS7GqXV4jJElsh0x90ftjPFGGoZjX4M/84LQn7ucu0ZeruelSd/VmmZ0OD966b6g5+0ZrgsLBIZiDo2sEOk8a02UUwNt60FPKZEhaCURWvYjCBqDJA8laH\",\"latestTime\":1698304171}","{\"vendorID\":1,\"userID\":\"10946780381\",\"orderID\":\"1100782881905266609\",\"NewMessageNum\":1,\"latestMsg\":\"dtj7qIlXCPm1ZWUjwfEPc65cnsG57UYatDG6g/kYjYU+CSzeFNPE1THgv2cHUB0QhpNo6jEnCDc0Vte2V5h14J7NJ5Zbaprfysx+gLRua68o2Pp4pF0LDSMLQ+7pGh/GRDjdfYYS4qFqU17eBbT82x1LjsuY1HWe8Z2znWyo43nEcLbtPFU09HwXFgxOQLBhF4As08Inc7bvN6BPR8F46QtQR52+PvxiWdsDRV54/F2CqxuoFR3up6wKmxvyzDWyEAgFI8Ym7zqItVBfG8HtEXTezY3gCjtpK0qRoYJqJ+dIuQewnDXbbxyqu/JvXSdiLYVRdrZgY9UI1hBDQU4zN6XI2u/w8tzk3a6mSrTCfUyaB0xr5/bwLYfgwV4WDw0EaLQEr2R0OmMerlRMheR3A+GMYVxl+BcYx0fUrKuH7Fs1TNSRCS4ug4iMr/GoTv76J8jl1b2ihrFDPiVQRxPdSw==\",\"latestTime\":1698308642}"]}" +// desc: "" + +// $2$13205337818$PNM +// 饿百聊天详情 +// code: "0" +// data: "{"34665:1157916361:3:$2$13205337818$PNM":["{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"10154538612\",\"receiverIds\":[\"301157916361\",\"10154538612\",\"321921188187760\"],\"createTime\":1698303833173,\"groupId\":\"$2$13205337818$PNM\",\"msgId\":\"1997094742949.PNM\",\"contentType\":8,\"content\":\"{\\\"elements\\\":[{\\\"elementContent\\\":\\\"{\\\\\\\"atAll\\\\\\\":false,\\\\\\\"defaultNick\\\\\\\":\\\\\\\"商家\\\\\\\",\\\\\\\"uid\\\\\\\":{\\\\\\\"appUid\\\\\\\":\\\\\\\"301157916361\\\\\\\",\\\\\\\"domain\\\\\\\":\\\\\\\"eleme\\\\\\\"}}\\\",\\\"elementType\\\":3},{\\\"elementContent\\\":\\\"{\\\\\\\"extensions\\\\\\\":{\\\\\\\"imsdk_self_show_name\\\\\\\":\\\\\\\"45d46975e\\\\\\\",\\\\\\\"appName\\\\\\\":\\\\\\\"ELEME\\\\\\\",\\\\\\\"imsdk_role_name\\\\\\\":\\\\\\\"顾客\\\\\\\",\\\\\\\"imsdk_other_show_name\\\\\\\":\\\\\\\"45d46975e\\\\\\\",\\\\\\\"industryType\\\\\\\":\\\\\\\"NEW_RETAIL\\\\\\\",\\\\\\\"current_msg_source\\\\\\\":\\\\\\\"ELEME\\\\\\\"},\\\\\\\"text\\\\\\\":\\\\\\\"您好,请问我的订单还要多久送达?\\\\\\\"}\\\",\\\"elementType\\\":1}]}\"},\"platformShopId\":\"1157916361\"}}","{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"10154538612\",\"receiverIds\":[\"301157916361\",\"10154538612\",\"321921188187760\"],\"createTime\":1698303918483,\"groupId\":\"$2$13205337818$PNM\",\"msgId\":\"1996910978679.PNM\",\"contentType\":1,\"content\":\"{\\\"extensions\\\":{\\\"industryType\\\":\\\"NEW_RETAIL\\\",\\\"imsdk_other_show_name\\\":\\\"45d46975e\\\",\\\"imsdk_role_name\\\":\\\"顾客\\\",\\\"imsdk_self_show_name\\\":\\\"45d46975e\\\",\\\"appName\\\":\\\"ELEME\\\",\\\"current_msg_source\\\":\\\"ELEME\\\"},\\\"text\\\":\\\"您好\\\"}\"},\"platformShopId\":\"1157916361\"}}","{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"10154538612\",\"receiverIds\":[\"301157916361\",\"10154538612\",\"321921188187760\"],\"createTime\":1698303946914,\"groupId\":\"$2$13205337818$PNM\",\"msgId\":\"1991934371357.PNM\",\"contentType\":1,\"content\":\"{\\\"extensions\\\":{\\\"appName\\\":\\\"ELEME\\\",\\\"industryType\\\":\\\"NEW_RETAIL\\\",\\\"current_msg_source\\\":\\\"ELEME\\\",\\\"imsdk_role_name\\\":\\\"顾客\\\",\\\"imsdk_self_show_name\\\":\\\"45d46975e\\\",\\\"imsdk_other_show_name\\\":\\\"45d46975e\\\"},\\\"text\\\":\\\"[微笑]\\\"}\"},\"platformShopId\":\"1157916361\"}}"]}" +// desc: "" + +// 饿百用户发送消息时 +// 模拟客户发消息 +// let msg1 = JSON.stringify({ +// sendType: 'elm', +// msgContent: { +// subBizType: 'SEND_MESSAGE', +// bizType: 'IM', +// payLoad: { +// senderId: "10154538612", +// receiverIds: ["301157916361", "10154538612", "321921188187760"], +// createTime: 1698303946914, +// groupId: "$2$13205337818$PNM", +// msgId: new Date().getTime() + '', +// contentType: 1, +// content: JSON.stringify({ +// extensions: { +// appName: "ELEME", +// industryType: "NEW_RETAIL", +// current_msg_source: "ELEME", +// imsdk_role_name: "顾客", +// imsdk_self_show_name: "45d46975e", +// imsdk_other_show_name: "45d46975e" +// }, +// text: "11问问" +// }) +// } +// } +// }) + + +// 饿百,需测试优化 +// 聊天列表 +// code: "0" +// data: "{"34665:32267630646:3:$2$21107997212$PNM":["{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"20115813777\",\"receiverIds\":[\"10494269706\",\"20115813777\",\"302036272194\",\"322233065879\"],\"createTime\":1715677161257,\"groupId\":\"$2$21107997212$PNM\",\"msgId\":\"2902868590187.PNM\",\"contentType\":\"101\",\"content\":\"{\\\"data\\\":\\\"{\\\\\\\"mistTemplate\\\\\\\":{\\\\\\\"error\\\\\\\":\\\\\\\"[当前消息不支持,请升级版本]\\\\\\\",\\\\\\\"layoutId\\\\\\\":\\\\\\\"10007\\\\\\\",\\\\\\\"layoutVersion\\\\\\\":\\\\\\\"20240320171418\\\\\\\",\\\\\\\"placeHolder\\\\\\\":{\\\\\\\"hight\\\\\\\":600,\\\\\\\"width\\\\\\\":300}},\\\\\\\"shortTitle\\\\\\\":\\\\\\\"[卡片消息]\\\\\\\"}\\\",\\\"degradeText\\\":\\\"\\\",\\\"summary\\\":\\\"\\\",\\\"title\\\":\\\"\\\",\\\"type\\\":10007}\"},\"platformShopId\":\"32267630646\"}}"]}" +// desc: "" + + +// 聊天详情 +// code: "0" +// data: "{"34665:32267630646:3:$2$21107997212$PNM":["{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"20115813777\",\"receiverIds\":[\"10494269706\",\"20115813777\",\"302036272194\",\"322233065879\"],\"createTime\":1715677161257,\"groupId\":\"$2$21107997212$PNM\",\"msgId\":\"2902868590187.PNM\",\"contentType\":\"101\",\"content\":\"{\\\"data\\\":\\\"{\\\\\\\"mistTemplate\\\\\\\":{\\\\\\\"error\\\\\\\":\\\\\\\"[当前消息不支持,请升级版本]\\\\\\\",\\\\\\\"layoutId\\\\\\\":\\\\\\\"10007\\\\\\\",\\\\\\\"layoutVersion\\\\\\\":\\\\\\\"20240320171418\\\\\\\",\\\\\\\"placeHolder\\\\\\\":{\\\\\\\"hight\\\\\\\":600,\\\\\\\"width\\\\\\\":300}},\\\\\\\"shortTitle\\\\\\\":\\\\\\\"[卡片消息]\\\\\\\"}\\\",\\\"degradeText\\\":\\\"\\\",\\\"summary\\\":\\\"\\\",\\\"title\\\":\\\"\\\",\\\"type\\\":10007}\"},\"platformShopId\":\"32267630646\"}}","{\"sendType\":\"elm\",\"msgContent\":{\"subBizType\":\"SEND_MESSAGE\",\"bizType\":\"IM\",\"payLoad\":{\"senderId\":\"302036272194\",\"receiverIds\":null,\"createTime\":1715680290254,\"groupId\":\"$2$21107997212$PNM\",\"msgId\":\"2902644397115.PNM\",\"contentType\":\"1\",\"content\":\"{\\\"extensions\\\":{},\\\"text\\\":\\\"1\\\"}\"},\"platformShopId\":\"32267630646\"}}"]}" +// desc: "" \ No newline at end of file diff --git a/src/api/request.ts b/src/api/request.ts new file mode 100644 index 0000000..f8ca5a7 --- /dev/null +++ b/src/api/request.ts @@ -0,0 +1,234 @@ +/** + *@description: 请求接口配置文件 + *@return {*} + *@param +*/ +import urlConfig from "./config"; +import toast from "@/utils/toast"; +import { cleatStorage, getStorage } from "@/utils/storage"; +import { store } from "@/store"; +import { addTask, jx_trembling } from "@/utils/tools"; +import configCms from "@/utils/configCms"; +import log from '@/utils/log' + + +// 定义请求类型 +type methodsType = "GET" | "OPTIONS" | "HEAD" | "POST" | "PUT" | "DELETE" | "TRACE" | "CONNECT" | undefined +// 定义方法中的类型 +type FnApiType = { + (url: string, methods: methodsType, data?: AnyObject | string, timeout?: number, baseURL?: string, contentType?: string): Promise +} +// 定义方法类型 +interface Api { + api: FnApiType +} +// 请求类型请求头 +let cType = 'application/x-www-form-urlencoded' +// 最大超时时间默认15秒 +let timeouts: any = 0 +// 清空定时器,在800毫秒内数据请求回来了就清空定时器 +let timer: any +// 最大请求加载图层时间 +let timer1: any +// 保存请求中断 +let requestTask: any = null + + +/************************************************* + * 封装请求方法 + * @param {string} [url] 请求地址 + * @param {methodsType} [method] 请求方法默认GET + * @param {object} [data] 请求参数默认"" + * @param {number} [timeout] 请求超时时间 + * @param {string} [baseURL] 请求根路径默认https://wx.jxc4.com + * @param {string} [contentType] 请求头类型默认'application/x-www-form-urlencoded' + * @return {promist} [resolve, reject] promist成功与失败 +*/ + +const request: Api = { + api: (url, method = 'GET', data = "", timeout = 1000 * 20, baseURL = urlConfig, contentType = cType) => { + if (requestGuard(url)) { + return new Promise((resolve, reject) => { }) + } + timeouts = timeout + // store.commit('storeInfo/jxLoadingFn', false) // 关闭自定义加载图(vuex) + clearTimeout(timer) + timer = setTimeout(() => { + // 显示自定义加载图(vuex) + // store.commit('storeInfo/jxLoadingFn', true) + // uni.showNavigationBarLoading() + // 最大时间加载图 + tremblingJxLoadingFn() + }, 600) + if (url == '/v2/cms/GetNewOrderMsg') store.commit('storeInfo/jxLoadingFn', false) + return new Promise((resolve, reject) => { + requestTask = uni.request({ + url: baseURL + url, + method: method, + data: data, + timeout: timeout, + header: { + 'content-type': contentType, + 'token': getStorage('token') ? getStorage('token') : 'jxcs' + }, + success: (res) => { + //#region + let logData = { + '日志记录时间': Date(), + '调用接口': url, + '请求方法': method, + '请求参数': data, + '请求超时时间': timeout, + '请求域名': baseURL, + '登录类型': getStorage('loginType') ? getStorage('loginType') : '未获取到用户登录类型', + '用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN', + '权限ID': getStorage('userType') ? getStorage('userType') : '未获取到用户权限ID', + '用户ID': getStorage('userID') ? getStorage('userID') : '未获取到用户ID', + '用户ID2': getStorage('userID2') ? getStorage('userID2') : '未获取到用户ID2', + '用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号', + '店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID', + '店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字', + '网络状态码': res.statusCode, + '服务端数据': res.data + } + //#endregion + // store.commit('storeInfo/jxLoadingFn', false) // 关闭自定义加载图(vuex) + if (res.statusCode >= 200 && res.statusCode < 300) { + log.info(JSON.stringify(logData)) + // 通过token 验证 通过store 验证 + if ((res.data as AnyObject).code == '-2') { + uni.jxAlert({ + title: '提示', + content: '登录信息已过期', + confirmText: '重新登录', + success: () => { + cleatStorage() + uni.reLaunch({ url: '/subPages/login/wxLogin/wxLogin' }) + } + }) + return false + } else { + // 验证通过 + try { + const jsonData = JSON.parse((res.data as AnyObject).data) + resolve({ + code: (res.data as AnyObject).code, + data: jsonData, + desc: (res.data as AnyObject).desc + }) + } catch (error) { + resolve(res.data as AnyObject) + } + } + } else if (res.statusCode >= 400 && res.statusCode < 500) { + log.warn(JSON.stringify(logData)) + toast('客户端出错', 2) + reject('客户端出错') + } else if (res.statusCode >= 500) { + log.warn(JSON.stringify(logData)) + toast('服务端出错', 2) + reject('服务端出错') + } else { + log.warn(JSON.stringify(logData)) + toast('网络请求出错', 2) + } + }, + fail: (error) => { + if (error.errMsg == 'request:fail abort') { + // 中断请求 + return false + } + toast('网络请求超时', 2) + console.log('jx-网络请求超时', error); + reject(`网络请求超时 -- request.ts, ${error}`) + //#region + let logData = { + '日志记录时间': Date(), + '调用接口': url, + '请求方法': method, + '请求参数': data, + '请求超时时间': timeout, + '请求域名': baseURL, + '登录类型': getStorage('loginType') ? getStorage('loginType') : '未获取到用户登录类型', + '用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN', + '权限ID': getStorage('userType') ? getStorage('userType') : '未获取到用户权限ID', + '用户ID': getStorage('userID') ? getStorage('userID') : '未获取到用户ID', + '用户ID2': getStorage('userID2') ? getStorage('userID2') : '未获取到用户ID2', + '用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号', + '店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID', + '店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字', + '请求错误信息': error + } + log.error(JSON.stringify(logData)) // 普通请求日志 + //#endregion + }, + complete: () => { + uni.stopPullDownRefresh() + // uni.hideNavigationBarLoading() + // store.commit('storeInfo/jxLoadingFn', false) // 关闭自定义加载图(vuex) + uni.hideLoading() + clearTimeout(timer) // 清空定时器 + } + }) + + // 添加请求记录到缓存 + if (url == '/v2/cms/GetNewOrderMsg') return + addTask(requestTask) + }) + } +} + +/************************************************* + * 防抖超时加载图层 +*/ +const tremblingJxLoadingFn = jx_trembling(() => { + clearTimeout(timer1) + timer1 = setTimeout(() => { + store.commit('storeInfo/jxLoadingFn', false) // 关闭自定义加载图(vuex) + clearTimeout(timer1) + }, timeouts) +}, 500) + + +/************************************************* + * 登录守卫 +*/ +function requestGuard(url: string) { + // 获取网络状态 + uni.getNetworkType({ + success: (res) => { + if (res.networkType == 'none') { + store.commit('serveInfo/setIsNetWorkS', false) + } else { + store.commit('serveInfo/setIsNetWorkS', true) + } + } + }) + + // 验证token + if (!getStorage('token') && !configCms.whiteListUrl.includes(url)) { + // store.commit('serveInfo/setIsFirestLogin', true) + return true + } + + // 验证storeID + if (!getStorage('storeID') && !configCms.whiteListUrl.includes(url)) { + rulerStoreID() + return true + } + + // 验证网络状态 + if (!store.state.serveInfo.isNetWork) { + return true + } + + store.commit('serveInfo/setIsFirestLogin', getStorage('token') ? false : true) + return false +} +// 门店防抖节流 +const rulerStoreID = jx_trembling(() => { + uni.navigateTo({ url: "/subPages/switchStore/switchStore" }) +}, 1000) + + +export default request \ No newline at end of file diff --git a/src/components/dialog/dialog.ts b/src/components/dialog/dialog.ts new file mode 100644 index 0000000..a64e3ab --- /dev/null +++ b/src/components/dialog/dialog.ts @@ -0,0 +1,55 @@ +export default { + // 链接处理 + getLink(params: AnyObject) { + let url = "/components/dialog/dialogCom"; + if (params) { + let paramStr = ""; + for (let name in params) { + paramStr += `&${name}=${params[name]}` + } + if (paramStr) { + url += `?${paramStr.substr(1)}` + } + } + return url; + }, + + // 全局弹窗 + dialog(params = {}, callback: Function) { + uni.navigateTo({ + url: this.getLink(params), + success(e) { + uni.$off("jx_dialog"); + uni.$on("jx_dialog", (type) => { + callback && callback(type) + }) + } + }) + }, + + // 弹出提示弹窗 + alert(data = {}, callback: Function, close?: Function) { + let obj1 = { type: "alert", isCloseBtn: '0', isMaskClose: '0' }; + let params = Object.assign(obj1, data) + this.dialog(params, (type: string) => { + if ("confirm" == type) { + callback && callback() + } else { + close && close() + } + }) + }, + + // 确认提示框弹窗 + confirm(data = {}, confirm: Function, cancel: Function) { + let obj1 = { type: "confirm", isCloseBtn: '0', isMaskClose: '0' }; + let params = Object.assign(obj1, data) + this.dialog(params, (type: string) => { + if ("confirm" == type) { + confirm && confirm() + } else if ("cancel" == type) { + cancel && cancel() + } + }) + } +} \ No newline at end of file diff --git a/src/components/dialog/dialogCom.vue b/src/components/dialog/dialogCom.vue new file mode 100644 index 0000000..b826d0a --- /dev/null +++ b/src/components/dialog/dialogCom.vue @@ -0,0 +1,202 @@ + + + + + diff --git a/src/components/dialog/dialogUtil.ts b/src/components/dialog/dialogUtil.ts new file mode 100644 index 0000000..961f692 --- /dev/null +++ b/src/components/dialog/dialogUtil.ts @@ -0,0 +1,42 @@ +import dialog from "./dialog" + +const jxMOdal = { + /** + * 弹出提示 + */ + alert(options: any) { + uni.showModal({ + title: options.title, + content: options.content, + confirmText: options.confirmText || '确定', + showCancel: false, + confirmColor: "#51b535", + success: options.success + }) + }, + + /** + * 确认提示框 + */ + confirm(options: any) { + uni.showModal({ + content: options.content, + title: options.title, + confirmText: options.confirmText || '确定', + cancelText: options.cancelText || '取消', + confirmColor: "#51b535", + success: (e) => { + if (e.confirm) { + options.success && options.success() + } else if (e.cancel) { + options.fail && options.fail() + } + }, + fail: (e) => { + console.log(e, '自定义弹窗发生错误') + } + }) + } +} + +export default jxMOdal \ No newline at end of file diff --git a/src/components/jx-empty/jx-empty.vue b/src/components/jx-empty/jx-empty.vue new file mode 100644 index 0000000..06442b8 --- /dev/null +++ b/src/components/jx-empty/jx-empty.vue @@ -0,0 +1,57 @@ + + + + + \ No newline at end of file diff --git a/src/components/jx-icon/jx-icon.vue b/src/components/jx-icon/jx-icon.vue new file mode 100644 index 0000000..b9153e5 --- /dev/null +++ b/src/components/jx-icon/jx-icon.vue @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/src/components/jx-input/jx-input.vue b/src/components/jx-input/jx-input.vue new file mode 100644 index 0000000..825a2bb --- /dev/null +++ b/src/components/jx-input/jx-input.vue @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/src/components/jx-load-more/jx-load-more.vue b/src/components/jx-load-more/jx-load-more.vue new file mode 100644 index 0000000..246f4c4 --- /dev/null +++ b/src/components/jx-load-more/jx-load-more.vue @@ -0,0 +1,72 @@ + + + + + \ No newline at end of file diff --git a/src/components/jx-loading/jx-loading.vue b/src/components/jx-loading/jx-loading.vue new file mode 100644 index 0000000..af17228 --- /dev/null +++ b/src/components/jx-loading/jx-loading.vue @@ -0,0 +1,172 @@ + + + + + \ No newline at end of file diff --git a/src/components/jx-loading/jxLoading.png b/src/components/jx-loading/jxLoading.png new file mode 100644 index 0000000000000000000000000000000000000000..1720ff92619fddba000810f97a9d38579de6e234 GIT binary patch literal 8328 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 S5JWTp0000 + + + + + + + + \ No newline at end of file diff --git a/src/components/jx-price/jx-price.vue b/src/components/jx-price/jx-price.vue new file mode 100644 index 0000000..12f75ed --- /dev/null +++ b/src/components/jx-price/jx-price.vue @@ -0,0 +1,64 @@ + + + + + \ No newline at end of file diff --git a/src/components/jx-real-income/jx-real-income.vue b/src/components/jx-real-income/jx-real-income.vue new file mode 100644 index 0000000..cae8351 --- /dev/null +++ b/src/components/jx-real-income/jx-real-income.vue @@ -0,0 +1,103 @@ + + + + + \ No newline at end of file diff --git a/src/components/jx-upload-img/jx-upload-img.vue b/src/components/jx-upload-img/jx-upload-img.vue new file mode 100644 index 0000000..fb66be0 --- /dev/null +++ b/src/components/jx-upload-img/jx-upload-img.vue @@ -0,0 +1,232 @@ + + + + + + \ No newline at end of file diff --git a/src/composables/useGlobalFunc.ts b/src/composables/useGlobalFunc.ts new file mode 100644 index 0000000..04ee061 --- /dev/null +++ b/src/composables/useGlobalFunc.ts @@ -0,0 +1,577 @@ +import merchant from "@/api/https/merchant"; +import { store } from "@/store"; +import { setStorage, jx_default_storage_plugin, getStorage, cleatStorage } from "@/utils/storage"; +import toast from "@/utils/toast"; +import { timeFormatD } from "@/utils/tools"; +import { utilsMd5 } from '@/utils/md5.js' +import Bluetooth from '@/utils/bluetoothPrinter/bluetooth' +import { store as newStore } from '@/store' +import util from '@/utils/bluetoothPrinter/util' +import login from "@/api/https/login"; +import order from "@/api/https/order"; +import { computed } from "vue"; +import { emojiAnanlyze } from '@/utils/emoji' + +/** + * 今日营业数据 + * @param data 事实订单数据 + */ +function useGlobalFunc() { + const bluetooth: any = getStorage('deviceName') ? new Bluetooth() : null + + + /************************************************* + * 获取实时订单数据 + * @time 2023年2月1日 11点17分 + * @param {data} 请求data数据 + * @return {res} code:响应状态 data:响应数据 desc:错误信息 + */ + async function globGetToDay(data: AnyObject) { + let orderNumber = await merchant.get_store_order_sale_info(data); + if (orderNumber.code == 0) { + return orderNumber.data + } else { + toast("实时订单数据异常", 2); + } + } + + + /************************************************* + * 退出登录 + */ + function logOutFn() { + cleatStorage('token') + cleatStorage('userID') + cleatStorage('userType') + cleatStorage('storeID') + cleatStorage('storeName') + cleatStorage('userID2') + cleatStorage('mobile') + cleatStorage('isAgreement') + cleatStorage('loginType') + store.commit('serveInfo/setIsFirestLogin', true) + } + + + /************************************************* + * 查看详情图片 + * @time 2023-02-01 11:18:09 + * @param {}- + * @return {*} + */ + async function previewImage(url: string | Array,index?:number) { + new Promise((resolve, reject) => { + uni.previewImage({ + current: index ? index : typeof url === 'string' ? url : url[0], + urls: Array.isArray(url) ? url : [url], + success: (res: any) => { + resolve(res) + }, + fail: (err: any) => { + toast(err) + reject(err) + } + }) + }) + uni.vibrateShort({}) + } + + + /************************************************* + * 存储用户信息 + * @param {object} [data] 用户信息数据 + */ + let serveInfoTimer: any = null + async function setUserInfo(data: AnyObject) { + setStorage("token", data.token); + setStorage("userID", data.userID); + setStorage("userID2", data.userID2); + setStorage("mobile", data.mobile); + setStorage("loginType", data.authBindInfo.type); + jx_default_storage_plugin() + // 防止ios app 出现认证信息还没有缓存就已经跳转请求了 + if (getStorage("storeID")) { + await store.dispatch('storeInfo/getOneStore', getStorage("storeID")) + uni.switchTab({ url: '/pages/order-manager/main' }) + } else { + let storeRes = await login.get_my_store_list({ version: '1.3.5' }) + let dataList = storeRes.data || [] + if (dataList.length == 0) { + return uni.jxAlert({ + title: '提示', + content: '该账号未绑定门店,请联系运营绑定,加盟联系电话18048531223' + }) + } + if (dataList.length == 1) { + let data = dataList[0] + setStorage("storeID", data.id); + setStorage("storeName", data.name) + uni.switchTab({ url: '/pages/merchant/index' }) + return + } + + clearTimeout(serveInfoTimer) + serveInfoTimer = setTimeout(() => { + uni.navigateTo({ url: "/subPages/switchStore/switchStore" }) + }, 0) + } + + } + + + /************************************************* + * app 微信登录 + * @bangding {Function} 绑定 + * @seccess {Function} 登录成功 + */ + + + /************************************************* + * 全局判断是否有新信息,有信息就在tabar显示 + */ + async function newMessage() { + let data = { + storeIDs: JSON.stringify([+getStorage('storeID')]), + fromReadCount: 0, + toReadCount: 0, + offset: 0, + pageSize: -1, + fromTime: + timeFormatD(+new Date() - 7 * 24 * 60 * 60 * 1000) + ' 00:00:00', + toTime: timeFormatD(+new Date()) + ' 23:59:59', + } + let msgRes = await merchant.Get_store_message_statuses(data) + if (msgRes.code == 0) { + let num = msgRes.data.totalCount + + // 没有信息,移除 + if (num == 0) { + store.commit('storeInfo/setIsNewMessage', false) + uni.removeTabBarBadge({ index: 3 }) + } else { + store.commit('storeInfo/setIsNewMessage', true) + // 有信息显示 + uni.setTabBarBadge({ + index: 3, + text: num > 100 ? '99+' : '' + num, + }) + } + } + } + + + /************************************************************** + * 复制订单信息内容 + * @param {String} data 需要复制的内容 + * @param {String} [text] 复制成功提示内容(非必填) + * @param {string} [errorT] 复制失败提示内容(非必填) + */ + function copyInfo(data: string, text = '复制成功', errorT = '复制失败') { + uni.setClipboardData({ + data: data, + success() { + toast(text) + }, + fail() { + toast(errorT) + } + }) + uni.vibrateShort({}) + } + + + /************************************************************ + * 拨打电话 + * @param {string} phoneNumber 将要拨号的手机号 + * @param {String} [text] 拨号成功提示内容(非必填) + * @param {string} [errorT] 拨号失败提示内容(非必填) + */ + function phoneCall(phoneNumber: string, text = '拨号完成', errorT = '取消拨号') { + uni.makePhoneCall({ + phoneNumber: phoneNumber, + success() { + console.log(text) + }, + fail() { + toast(errorT) + } + }) + uni.vibrateShort({}) + } + + + const businessKey = 'XKJPOIHJ233adf01KJIXlIeQDSDKFJAD' // 商户秘钥 + /************************************************* + * 统一微信支付功能 + * 说明:app暂未申请支付功能,仅支持小程序支付 + * @param {number} [chargeMoney] 支付金额 + * @param {number | string} [storeID] 门店ID + * @param {Function} [fn] 支付回调,成功或失败都会调用 + * @param {string} [vendorOrderID] 订单id + * + */ + async function globalPlayMoney(orderPayType: number, chargeMoney: number, StoreID: number | string, code: string, fn: Function, vendorOrderID = '') { + let tempMoney = +chargeMoney * 100 + // 创建订单 + let data = { + orderType: orderPayType, + storeID: StoreID, + price: tempMoney, + vendorOrderID: vendorOrderID + } + let orderNum = await order.create_store_acct_order(data) + // 支付订单 + let data1 = { + subAppID: 'wx08a5c2a8581414ff', + payType: orderPayType, + vendorOrderID: orderNum.data, + vendorPayType: 'W06', + code: `weixinappcs_${code}` + } + let orderInfo = await order.pay4_user(data1) + let newOrderInfo = orderInfo.data + // 调用微信支付 + handleCreatePay(newOrderInfo.vendorOrderID, newOrderInfo.prepayID, JSON.parse(newOrderInfo.codeURL), fn) + } + // 微信支付 + function handleCreatePay(orderInfo: any, prepayID: number | string, codeURL: AnyObject, fn: Function) { + let token = '' + token = getStorage('token') + let timeStamp: string + let randomNum: number + let strPay: string + let nonceStr: string + let packageA: string + let paySign: string + let signType = 'MD5' + if (codeURL) { + // 通联收银 payType 2 + timeStamp = codeURL.timeStamp + nonceStr = codeURL.nonceStr + packageA = codeURL.package + signType = codeURL.signType + paySign = codeURL.paySign + } else { + timeStamp = Math.round(new Date().getTime() / 1000).toString() + randomNum = (Math.random() * 5) + 1 + strPay = timeStamp + token + randomNum + nonceStr = utilsMd5.hex_md5(strPay) + packageA = `prepay_id=${prepayID}` + paySign = utilsMd5.hex_md5(`appId=wx4b5930c13f8b1170&nonceStr=${nonceStr}&package=${packageA}&signType=MD5&timeStamp=${timeStamp}&key=${businessKey}`) + } + uni.requestPayment({ + provider: 'wxpay', + orderInfo: orderInfo, + timeStamp: timeStamp, + nonceStr: nonceStr, + package: packageA, + signType: signType, + paySign: paySign, + success: () => { + toast('充值成功', 1) + }, + fail: () => { + toast('取消充值', 2) + }, + complete: () => { + fn && fn() + } + }) + } + + + /************************************************* + * 打开微信小程序 + * @param {string} [url] 跳转地址 + * @param {string} [id] 小程序原始ID + */ + + + /************************************************* + * 判断门店是否在营业中 + * @param {any} [newTime] 需要判断的时间 + */ + function isTrades(newTime: any): boolean { + let storeInfo = newStore.state.storeInfo.allStoreInfo + let businessTime: Array = [] + businessTime[0] = storeInfo.openTime1 + businessTime[1] = storeInfo.closeTime1 + businessTime[2] = storeInfo.openTime2 + businessTime[3] = storeInfo.closeTime2 + + // 获取当前时间进行比较 + let honer = newTime.getHours() + let minutes = newTime.getMinutes() < 10 ? '0' + newTime.getMinutes() : newTime.getMinutes() + let time: number = +(String(honer) + String(minutes)) + + // true-未休息 false-休息中 + return (time >= businessTime[0] && time <= businessTime[1]) || (time >= businessTime[2] && time <= businessTime[3]) + } + + /************************************************* + * 格式化今日订单数据 + */ + function wholeCalcPrice(calcData: AnyObject) { + if (calcData.isPointStore) { + if (calcData.isNotQuote || calcData.isZero) { + return calcData.actualPayPrice + ? (calcData.actualPayPrice / 100).toFixed(2) + : 0; + } else { + if (calcData.isUpperfif) { + return calcData.earningPrice + ? (calcData.earningPrice / 100).toFixed(2) + : 0; + } else { + return "请按平台查看"; + } + } + } else { + if (calcData.isUpperfif || calcData.isZero) { + return calcData.earningPrice + ? (calcData.earningPrice / 100).toFixed(2) + : 0; + } else { + return "请按平台查看"; + } + } + } + + + /************************************************* + * 格式化今日订单数据 + */ + function singleCalcPrice(calcData: AnyObject) { + if (calcData.vendorPayPercentage != 0) { + return calcData.vendorPayPercentage < 50 ? (calcData.actualPayPrice / 100).toFixed(2) : (calcData.earningPrice / 100).toFixed(2) + } else { + return calcData.isPointStore ? (calcData.actualPayPrice / 100).toFixed(2) : (calcData.earningPrice / 100).toFixed(2) + } + } + + + /************************************************* + * 查询打印机状态并连接 + */ + const playVoid = uni.createInnerAudioContext() + function setPrinterStatus() { + // 获取打印机信息 + let data: any = getStorage('commitBTDevCharact') + setInterval(() => { + let isPlay = store.state.storeInfo.isConnectPrinter + // 判断打印机是否在线 + util.notifyBLEState(data.deviceId, data.serviceId, data.uuid) + .then(async (res) => { + if (res != 12) { + console.log('连接失败') + await bluetooth.reconnect() + if (!isPlay) return + playVoidFn() + store.commit('storeInfo/setIsConnectPrinter', false) + + } else { + console.log('连接正常') + store.commit('storeInfo/setIsConnectPrinter', true) + } + }).catch(async () => { + console.log('连接失败') + await bluetooth.reconnect() + if (!isPlay) return + playVoidFn() + store.commit('storeInfo/setIsConnectPrinter', false) + }) + }, 1000 * 10) + } + // 播放音频 + function playVoidFn() { + playVoid.src = 'https://image.jxc4.com/image/ee1174253ee2919a23d7ea5277b2141b.jpg' + playVoid.stop() + playVoid.play() + } + + + /************************************************* + * 提示用户未勾选 + */ + let time: any = null + function isUserAgreementFn() { + store.commit('serveInfo/setIsAgreementIf', false) + clearTimeout(time) + time = setTimeout(() => { + uni.vibrateShort({}) + store.commit('serveInfo/setIsAgreementIf', true) + }, 200) + } + + // ******************** 判断是否有淘鲜达 ***************************** + //#region + const storeMaps = computed(() => { + return store.state.storeInfo.allStoreInfo + }) + function isTxd() { + let state = false + storeMaps.value.StoreMaps.forEach((item: AnyObject) => { + if (item.vendorID == 16) { + state = true + } + }) + return state + } + //#endregion + + /** + * 查询美团/饿百的IM状态 + */ + const getMtStoreIMStatus = async () => { + let mtStore = isExistPlatformID(1) + let ebStore = isExistPlatformID(3) + let data = [] + if (mtStore && mtStore.length > 0) { + data.push({ + vendorID: 1, + vendorOrgCode: mtStore[0].vendorOrgCode + '', + vendorStoreID: mtStore[0].vendorStoreID + '' + }) + } + + if (ebStore && ebStore.length > 0) data.push({ + vendorID: 3, + vendorOrgCode: ebStore[0].vendorOrgCode + '', + vendorStoreID: ebStore[0].vendorStoreID + '' + }) + if (data.length === 0) return + let res = await merchant.get_mt_store_im_status({ data: data }) + let arr: any = [] + if (res.code === '0') { + + res.data.forEach((item: AnyObject) => { + if (item.errMsg && item.errMsg) arr.push({ + ...item, + vendorID: +item.errMsg.substring(0, 1) + }) + else arr.push({ ...item }) + }) + } + store.commit('storeInfo/setImOnlineStatus', arr) + } + + /** + * 是否存在某个平台 + */ + function isExistPlatformID(platformID: number) { + return storeMaps.value.StoreMaps && storeMaps.value.StoreMaps.length > 0 ? storeMaps.value.StoreMaps.filter((item: AnyObject) => item.vendorID == platformID) : [] + } + + /** + * 是否含有聊天表情 + */ + function isCloudEmoji(emoji: string) { + let emojiArr = emoji.match(/\[(.+?)\]/g) + return emojiArr && emojiArr.length > 0 ? true : false + } + + interface emojiType { + type: string, + text: string, + emoji: string + } + + /** + * 解析emoji数据 + */ + function analyEmoji(emoji: string) { + if (!isCloudEmoji(emoji)) { + return [ + { + type: 'text', + text: emoji, + emoji: '' + } + ] + } + + // emoji = '[大哭][大哭][大哭][大哭][心碎][心碎][心碎]11111顶顶顶顶呃零零零零[流泪]iiiihdhggydgjfg kevbuygbhjbnb' + + let arr: emojiType[] = [] + + let emojiArr: string[] = emoji.match(/\[(.+?)\]/g) || [] + if (emojiArr && emojiArr.length > 0) { + emojiArr.map((item, index) => { + let emojiImg = emojiAnanlyze(item) // 返回的emoji解析数据 + if (emojiImg === item) emojiImg = 'unknown:' + item // 未知表情 + let indexOf = emoji.indexOf(item) // item在聊天emoji中的位置 + + if (indexOf === 0) { + // emoji + arr.push({ + type: 'emoji', + text: '', + emoji: emojiImg + }) + + // emoji之后的文字 + let afterSymbol = emoji.substring(indexOf + item.length, indexOf + item.length + 1) + if (afterSymbol !== '[' && afterSymbol.length > 0 && index === emojiArr.length - 1) { + arr.push({ + type: 'text', + text: emoji.substring(indexOf + item.length), + emoji: '' + }) + } + } else { + // emoji之前的文字 + arr.push({ + type: 'text', + text: emoji.substring(0, indexOf), + emoji: '' + }) + + // emoji + arr.push({ + type: 'emoji', + text: '', + emoji: emojiImg + }) + + // emoji之后的文字 + let afterSymbol = emoji.substring(indexOf + item.length, indexOf + item.length + 1) + if (afterSymbol !== '[' && afterSymbol.length > 0 && index === emojiArr.length - 1) { + arr.push({ + type: 'text', + text: emoji.substring(indexOf + item.length), + emoji: '' + }) + } + } + + emoji = emoji.replace(emoji.substring(0, indexOf + item.length), '') // 清除已处理完的数据 + }) + } + return arr || [] + } + + + + return { + globGetToDay, //获取实时订单数据 + previewImage, // 查看详情图 + setUserInfo, // 储存用户信息 + newMessage, // 展示新信息 + copyInfo, // 复制信息 + phoneCall, // 拨打电话 + globalPlayMoney, // 统一支付 + isTrades, // 判断是否是在营业时间 + wholeCalcPrice, // 格式化今日订单数据 + singleCalcPrice, // 格式化今日订单数据 + setPrinterStatus, // 查询打印机状态并连接 + logOutFn, // 退出登录 + isUserAgreementFn, // 提示用户未勾选 + isTxd, // 判断是否有淘鲜达 + getMtStoreIMStatus, // 获取美团IM单聊状态 + analyEmoji, // 解析emoji表情 + isCloudEmoji // 是否含有emoji + } +} + + +export default useGlobalFunc \ No newline at end of file diff --git a/src/composables/useOrderInfo.ts b/src/composables/useOrderInfo.ts new file mode 100644 index 0000000..8a1fe0d --- /dev/null +++ b/src/composables/useOrderInfo.ts @@ -0,0 +1,290 @@ +/** + * 订单管理hooks + */ + +import { getStorage } from "@/utils/storage" +import toast from "@/utils/toast" +import util from "@/utils/bluetoothPrinter/util" +import Bluetooth from '@/utils/bluetoothPrinter/bluetooth' +import printerTemplate from '@/utils/bluetoothPrinter/printerTemplate' +import configCms from "@/utils/configCms" +import merchant from "@/api/https/merchant" +import order from "@/api/https/order" + +function useOrderInfo() { + const bluetooth: any = getStorage('deviceName') ? new Bluetooth() : null + /************************************************************** + * 复制订单信息内容 + * @param {String} data 需要复制的内容 + * @param {String} [text] 复制成功提示内容(非必填) + * @param {string} [errorT] 复制失败提示内容(非必填) + */ + function copyInfo(data: string, text = '复制成功', errorT = '复制失败') { + uni.setClipboardData({ + data: data, + success() { + toast(text, 1) + }, + fail() { + toast(errorT) + } + }) + uni.vibrateShort({}) + } + + + /************************************************************ + * 拨打电话 + * @param {string} phoneNumber 将要拨号的手机号 + * @param {String} [text] 拨号成功提示内容(非必填) + * @param {string} [errorT] 拨号失败提示内容(非必填) + */ + function phoneCall(phoneNumber: string, text = '拨号完成', errorT = '取消拨号') { + uni.makePhoneCall({ + phoneNumber: phoneNumber, + success() { + console.log(text) + }, + fail() { + toast(errorT) + } + }) + uni.vibrateShort({}) + } + + + /************************************************************ + * 跳转到详情页 + * @param {string} vendorOrderID 订单id + * @param {string} vendorID 品牌id + */ + function orderDetail(vendorOrderID: string, vendorID: string) { + uni.navigateTo({ url: `/subPages/orderChild/orderDetail/orderDetail?vendorOrderID=${vendorOrderID}&vendorID=${vendorID}` }) + } + + + /************************************************************* + * 跳转到配送管理页面 + * @param {string} vendorOrderID 订单id + */ + function deliverManager(vendorOrderID: string) { + uni.navigateTo({ url: `/subPages/orderChild/deliverManager/deliverManager?orderId=${vendorOrderID}` }) + } + + + /************************************************************ + * 打印订单 + * @param {string} vendorOrderID 订单号 + * @param {string} vendorID 品牌ID + */ + async function printerOrder(vendorOrderID: string, vendorID: string) { + if (getStorage('defaultPrinter') == '0') { + // 蓝牙打印机 + bluetoothPrinter(vendorOrderID) + } else if (getStorage('defaultPrinter') == '1') { + // 网络打印机 + internetPrinter(vendorOrderID, vendorID) + } else { + // 手动选择 + uni.jxConfirm({ + title: '选择设备', + content: '请选择打印设备进行打印', + confirmText: '网络打印', + cancelText: '蓝牙打印', + isReturn: 1, + success: () => { + internetPrinter(vendorOrderID, vendorID) + }, + fail: () => { + bluetoothPrinter(vendorOrderID) + } + }) + } + } + + /** + * 网络打印 + * @param {string} vendorOrderID 订单号 + */ + async function internetPrinter(vendorOrderID: string, vendorID: string) { + let res = await order.get_printer_status({ + storeID: getStorage('storeID'), + }) + if (res.code == 0) { + if (res.data.printerStatus == 2) { + let data = { + vendorOrderID, + vendorID, + } + let pOorder = await order.print_order(data) + if (pOorder.code == 0) { + toast('订单发送成功', 1) + } else { + toast('订单发送失败', 2) + } + } else { + let data = { + vendorOrderID, + vendorID, + } + let pOorder = await order.print_order(data) + if (pOorder.code == 0) { + uni.jxAlert({ + title: '提示', + content: '打印机已离线,但订单已推动成功' + }) + } else { + toast('订单发送失败', 2) + } + } + } else { + toast('获取打印机数据异常', 2) + } + } + + /** + * 蓝牙打印 + */ + async function bluetoothPrinter(vendorOrderID: any, type = 1) { + if (getStorage('deviceName')) { + let data: any + if (type == 1) { + data = { + vendorOrderID: vendorOrderID + } + } else { + data = vendorOrderID + } + + let orderRes = await order.get_orders(data) + if (orderRes.code == 0) { + getPrinterSku(orderRes.data.data[0]) // 获取订单数据 + } else { + toast('测试订单数据异常') + } + } else { + toast('未连接打印机') + } + } + + // 获取订单数据 + let timer1: any = null + async function getPrinterSku(orderInfo: AnyObject) { + let data = { + vendorOrderID: orderInfo.vendorOrderID, + vendorID: orderInfo.vendorID + } + let skuRes = await merchant.get_order_sku_info(data) + if (skuRes.code) { + let data = { + orderInfo: orderInfo, + skus: skuRes.data, + } + let datas: any = getStorage('commitBTDevCharact') + getBlechData() + util.notifyBLEState(datas.deviceId, datas.serviceId, datas.uuid) + .then(async (res) => { + if (res == 12) { + toast('正在打印订单') + bluetooth.notifyBLECharacteristicValue() // 订阅蓝牙 notify + clearTimeout(timer1) + timer1 = setTimeout(() => { + writeBLECharacteristicValue(data) // 向打印机写入数据 + clearTimeout(timer1) + }, 500) + } else { + toast('打印机异常请检查') + } + }) + .catch(async (error) => { + toast(error) + }) + return + + } else { + toast('订单商品数据异常') + } + } + // 获取写入标识数据 + function getBlechData() { + let datas: any = getStorage('commitBTDevCharact') + bluetooth.deviceId = datas.deviceId + bluetooth.serviceId = datas.serviceId + bluetooth.writeId = datas.uuid + } + //写入控制命令 + async function writeBLECharacteristicValue(data: AnyObject) { + let printerCenter = await printerTemplate(data) + printbuffs(printerCenter) + } + // 分包向打印机发送数据 + function printbuffs(buffer: any) { + // 1.并行调用多次会存在写失败的可能性 + // 2.建议每次写入不超过20字节 + // 分包处理,延时调用 + const maxChunk = 20 + const delay = 20 + for ( + let i = 0, j = 0, length = buffer.byteLength; + i < length; + i += maxChunk, j++ + ) { + let subPackage = buffer.slice( + i, + i + maxChunk <= length ? i + maxChunk : length + ) + setTimeout(printbuff, j * delay, subPackage) + } + } + // 写入数据 + function printbuff(buffer: any) { + bluetooth.writeBLECharacteristicValue(buffer) + } + + + /************************************************************ + * 转换厂商 + */ + function waybillVendor( + waybillVendorID: number, + status: number, + waybillStatus: number + ) { + if (waybillVendorID == -1) { + if (status < 25 && waybillStatus == 0) { + return '暂无配送员' + } else if (waybillStatus >= 20) { + return '商家自送' + } else { + return '暂无配送信息' + } + } else { + return (configCms as AnyObject).serveInfo.vendorName[waybillVendorID] + } + } + + + /************************************************************ + * 售后详情 + */ + function afterSalesDetaile(afsOrderID: number | string) { + uni.navigateTo({ + url: `/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail?afsOrderID=${afsOrderID}`, + }) + } + + + return { + copyInfo, // 复制内容 + phoneCall, // 拨号 + orderDetail, // 查看订单详情 + deliverManager, // 配送管理 + printerOrder, // 打印订单 + waybillVendor, // 转换厂商 + afterSalesDetaile, // 售后详情 + bluetoothPrinter, // 打印订单 + } +} + + +export default useOrderInfo \ No newline at end of file diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..ff7a876 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,134 @@ +/// + + +/************************************************************ + * vue 文件验证 + * @auto zsw + * @time 2023年1月6日 + * @emaile 2966211270@qq.com + * @param {} + * @return {} + */ +declare module '*.vue' { + import { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} + + +/********************************************************** + * nvue 文件验证 + * @auto zsw + * @time 2023年1月6日 + * @emaile 2966211270@qq.com + * @param {} + * @return {} + */ +declare module '*.nvue' { + import { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} + + +/********************************************************** + * ASE加密/解密文件验证 + */ +declare module 'crypto-js' { + const content: any + export = content +} + + + +/************************************************************ + * 自定义挂载 uniapp 全局属性,自定义更改原生 modal 弹窗 +* @auto zsw + * @time 2023年1月6日 + * @emaile 2966211270@qq.com + * @param {jxConfirm} 双按钮仿 ios module + * @param {jxAlert} 单按钮仿 ios module + * @return {} + */ +declare module 'uview-plus' { + interface alertType { + /** + * 提示标题(必填) + */ + title: string + /** + * 提示内容(必填) + */ + content: string + /** + * 确定按钮 + */ + confirmText?: string + /** + * 是否允许安卓按钮返回 + * 默认:0; + * 0:不允许手势返回 + * 1:允许使手势返回 + */ + isReturn?: 0 | 1 + /** + * 成功回调 + */ + success?: Function + } + + interface confirmType { + /** + * 提示标题(必填) + */ + title: string + /** + * 提示内容(必填) + */ + content: string + /** + * 确定按钮 + */ + confirmText?: string + /** + * 取消按钮 + */ + cancelText?: string + /** + * 是否允许安卓按钮返回 + * 默认:0; + * 0:不允许手势返回 + * 1:允许使手势返回 + */ + isReturn?: 0 | 1 + /** + * 成功回调 + */ + success?: Function + /** + * 取消回调 + */ + fail?: Function + } + interface globalAlertType { + data: AnyObject + success?: Function + } + export function install(): void + global { + interface Uni { + /** + * 双按钮模态弹窗 + */ + jxConfirm: ((options: confirmType) => void) + /** + * 单按钮模态弹窗 + */ + jxAlert: ((options: alertType) => void) + + /************************************************************* + * 允许uni 使用 showShareImageMenu 微信分享功能 + */ + } + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..2e48dc6 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,15 @@ +import { createSSRApp } from "vue"; +import App from "./App.vue"; +import { store, key } from "./store"; +export function createApp() { + const app = createSSRApp(App); + app.use(store, key) + app.config.errorHandler = (err, vm, info) => { + console.log(err, '错误信息') + console.log(vm, 'vue实例') + console.log(info, '错误位置') + } + return { + app + } +} \ No newline at end of file diff --git a/src/manifest.json b/src/manifest.json new file mode 100644 index 0000000..ef5c41f --- /dev/null +++ b/src/manifest.json @@ -0,0 +1,174 @@ +{ + "name": "京西菜市商家版", + "appid": "__UNI__F9A47D3", + "description": "1、商户通过京西平台同时管理美团、饿了么、京东等多个外卖平台实现一键上架、下架、修改、删除多个平台商品;2、商户通过京西平台可以同时对、美团专送、达达、顺丰同城等多个专送平台召唤偶骑手", + "versionName": "1.3.0", + "versionCode": 130, + "transformPx": false, + /* 5+App特有相关 */ + "app-plus": { + "compatible": { + "ignoreVersion": true + }, + "usingComponents": true, + "nvueStyleCompiler": "uni-app", + "compilerVersion": 3, + "splashscreen": { + "alwaysShowBeforeRender": false, + "waiting": false, + "autoclose": true, + "delay": 0 + }, + /* 模块配置 */ + "modules": {}, + /* 应用发布信息 */ + "distribute": { + /* android打包配置 */ + "android": { + "permissions": [], + "abiFilters": [ + "armeabi-v7a", + "arm64-v8a", + "x86" + ], + "minSdkVersion": 23, + "targetSdkVersion": 28, + "autoSdkPermissions": false + }, + /* ios打包配置 */ + "ios": { + "dSYMs": false, + "privacyDescription": { + "NSPhotoLibraryUsageDescription": "", + "NSPhotoLibraryAddUsageDescription": "", + "NSBluetoothPeripheralUsageDescription": "", + "NSBluetoothAlwaysUsageDescription": "", + "NSCameraUsageDescription": "" + }, + "capabilities": { + "entitlements": { + "com.apple.developer.associated-domains": [] + } + }, + "UIBackgroundModes": "" + }, + /* SDK配置 */ + "sdkConfigs": { + "share": { + "weixin": { + "appid": "wx18111a41fd17f24f", + "UniversalLinks": "https://www.jxc4.com" + } + }, + "ad": {}, + "payment": { + "weixin": { + "__platform__": [ + "android" + ], + "appid": "wx18111a41fd17f24f", + "UniversalLinks": "https://www.jxc4.com" + } + }, + "geolocation": { + "system": { + "__platform__": [ + "ios" + ] + } + }, + "oauth": { + "weixin": { + "appid": "wx18111a41fd17f24f", + "UniversalLinks": "https://www.jxc4.com" + } + }, + "push": { + "unipush": {} + } + }, + "icons": { + "android": { + "hdpi": "", + "xhdpi": "", + "xxhdpi": "", + "xxxhdpi": "" + }, + "ios": { + "appstore": "", + "ipad": { + "app": "", + "app@2x": "", + "notification": "", + "notification@2x": "", + "proapp@2x": "", + "settings": "", + "settings@2x": "", + "spotlight": "", + "spotlight@2x": "" + }, + "iphone": { + "app@2x": "", + "app@3x": "", + "notification@2x": "", + "notification@3x": "", + "settings@2x": "", + "settings@3x": "", + "spotlight@2x": "", + "spotlight@3x": "" + } + } + }, + "splashscreen": { + "useOriginalMsgbox": false, + "androidStyle": "common", + "iosStyle": "common", + "android": { + "hdpi": "D:/桌面/京西/新商家版/图标(1)/480x762.png", + "xhdpi": "D:/桌面/京西/新商家版/图标(1)/720x1242.png", + "xxhdpi": "D:/桌面/京西/新商家版/图标(1)/1080x1882.png" + } + } + }, + "nativePlugins": {} + }, + /* 快应用特有相关 */ + "quickapp": {}, + /* 小程序特有相关 */ + "mp-weixin": { + "appid": "wx08a5c2a8581414ff", + "libVersion": "latest", + "setting": { + "urlCheck": false + }, + "usingComponents": true, + "lazyCodeLoading": "requiredComponents", + "plugins": { + "chatGroupPlugin": { + "version": "1.1.2", + "provider": "wxaae6519cee98d824" + } + }, + "permission": { + "scope.userLocation": { + "desc": "你的位置信息将用于搜索附近的蓝牙打印机设备" + } + } + }, + "mp-alipay": { + "usingComponents": true + }, + "mp-baidu": { + "usingComponents": true + }, + "mp-toutiao": { + "usingComponents": true + }, + "uniStatistics": { + "enable": false + }, + "vueVersion": "3", + "fallbackLocale": "zh-Hans", + "locale": "zh-Hans", + "_spaceID": "mp-6a99ccda-c7f6-4ef9-8870-35401c55287e" +} \ No newline at end of file diff --git a/src/pages.json b/src/pages.json new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/src/pages.json @@ -0,0 +1,401 @@ +{ + "lazyCodeLoading": "requiredComponents", + "easycom": { + "autoscan": true, + "custom": { + "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue" + } + }, + "pages": [ + { + "path": "pages/merchant/index", + "style": { + "navigationBarTitleText": "商家中心", + "enablePullDownRefresh": true, + "navigationBarBackgroundColor": "#4eb331", + "navigationBarTextStyle": "white" + } + }, + { + "path": "pages/goods-manager/main", + "style": { + "navigationBarTitleText": "商品管理", + "navigationBarBackgroundColor": "#4eb331", + "navigationBarTextStyle": "white" + } + }, + { + "path": "pages/message/index", + "style": { + "navigationBarTitleText": "客户消息", + "enablePullDownRefresh": true + } + }, + { + "path": "pages/order-manager/main", + "style": { + "navigationBarTitleText": "订单管理" + } + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "京西菜市", + "navigationBarBackgroundColor": "#fff", + "backgroundColor": "#F8F8F8", + "rpxCalcBaseDeviceWidth": 750 + }, + "subPackages": [ + { + "root": "subPages/login", + "pages": [ + { + "path": "index", + "style": { + "navigationBarTitleText": "登录" + } + }, + { + "path": "bindSNS/bindSNS", + "style": { + "navigationBarTitleText": "绑定" + } + }, + { + "path": "wxLogin/wxLogin", + "style": { + "navigationBarTitleText": "登录" + } + } + ] + }, + { + "root": "subPages/agreement", + "pages": [ + { + "path": "privacy", + "style": { + "navigationBarTitleText": "京西菜市隐私协议" + } + }, + { + "path": "user", + "style": { + "navigationBarTitleText": "京西菜市用户协议" + } + }, + { + "path": "about", + "style": { + "navigationBarTitleText": "关于京西" + } + } + ] + }, + { + "root": "subPages/switchStore", + "pages": [ + { + "path": "switchStore", + "style": { + "navigationBarTitleText": "选择门店", + "enablePullDownRefresh": true, + "navigationBarBackgroundColor": "#4eb331", + "navigationBarTextStyle": "white" + } + } + ] + }, + { + "root": "subPages/orderChild", + "pages": [ + { + "path": "getPhone/getPhone", + "style": { + "navigationBarTitleText": "联系平台" + } + }, + { + "path": "orderDetail/orderDetail", + "style": { + "navigationBarTitleText": "订单详情" + } + }, + { + "path": "deliverManager/deliverManager", + "style": { + "navigationBarTitleText": "配送管理", + "enablePullDownRefresh": true + } + }, + { + "path": "afterSalesOrderDetail/afterSalesOrderDetail", + "style": { + "navigationBarTitleText": "售后详情" + } + }, + { + "path": "createAfterSales/createAfterSales", + "style": { + "navigationBarTitleText": "创建售后单" + } + }, + { + "path": "seeMap/seeMap", + "style": { + "navigationBarTitleText": "查看地图" + } + }, + { + "path": "complaint/complaint", + "style": { + "navigationBarTitleText": "投诉骑手" + } + } + ] + }, + { + "root": "subPages/merchantChild", + "pages": [ + { + "path": "helpCenter/helpCenter", + "style": { + "navigationBarTitleText": "帮助中心" + } + }, + { + "path": "orderRealTime/orderRealTime", + "style": { + "navigationBarTitleText": "营业数据" + } + }, + { + "path": "platformM/platformM", + "style": { + "navigationBarTitleText": "已开通店铺" + } + }, + { + "path": "modifyPrice/modifyPrice", + "style": { + "navigationBarTitleText": "调价包" + } + }, + { + "path": "bill/bill", + "style": { + "navigationBarTitleText": "我的账单" + } + }, + { + "path": "billDetaile/billDetaile", + "style": { + "navigationBarTitleText": "账单详情" + } + }, + { + "path": "evaluateM/evaluateM", + "style": { + "navigationBarTitleText": "评价管理" + } + }, + { + "path": "storeScore/storeScore", + "style": { + "navigationBarTitleText": "门店评分" + } + }, + { + "path": "storeScoreDetaile/storeScoreDetaile", + "style": { + "navigationBarTitleText": "评分详情" + } + }, + { + "path": "waitGoods/waitGoods", + "style": { + "navigationBarTitleText": "待配商品" + } + }, + { + "path": "waitGoodsDetaile/waitGoodsDetaile", + "style": { + "navigationBarTitleText": "商品详情" + } + }, + { + "path": "shareStore/shareStore", + "style": { + "navigationBarTitleText": "扫码进店" + } + }, + { + "path": "enterGroupChat/enterGroupChat", + "style": { + "navigationBarTitleText": "进入群聊", + "mp-weixin": { + "usingComponents": { + "cell": "plugin://chatGroupPlugin/cell" + } + } + } + }, + { + "path": "message/message", + "style": { + "navigationBarTitleText": "消息列表" + } + }, + { + "path": "messageDetail/messageDetail", + "style": { + "navigationBarTitleText": "最新消息" + } + }, + { + "path": "activity/activity", + "style": { + "navigationBarTitleText": "活动信息" + } + }, + { + "path": "setUp/setUp", + "style": { + "navigationBarTitleText": "设置" + } + }, + { + "path": "printerSetUp/printerSetUp", + "style": { + "navigationBarTitleText": "蓝牙打印机设置" + } + }, + { + "path": "businessLicense/businessLicense", + "style": { + "navigationBarTitleText": "营业资质" + } + }, + { + "path": "useInfo/useInfo", + "style": { + "navigationBarTitleText": "个人信息" + } + }, + { + "path": "payeeInfo/payeeInfo", + "style": { + "navigationBarTitleText": "收款信息" + } + }, + { + "path": "invoice/invoice", + "style": { + "navigationBarTitleText": "发票管理" + } + }, + { + "path": "accountBalance/accountBalance", + "style": { + "navigationBarTitleText": "配送余额" + } + }, + { + "path": "setBusinessTime/setBusinessTime", + "style": { + "navigationBarTitleText": "修改营业时间" + } + }, + { + "path": "setBusinessStatus/setBusinessStatus", + "style": { + "navigationBarTitleText": "营业状态" + } + }, + { + "path": "setInvoiceEB/setInvoiceEB", + "style": { + "navigationBarTitleText": "发票设置" + } + }, + { + "path": "platformDetail/index", + "style": { + "navigationBarTitleText": "平台管理" + } + } + ] + }, + { + "root": "subPages/shoppingChild", + "pages": [ + { + "path": "createGoods/createGoods", + "style": { + "navigationBarTitleText": "创建商品", + "navigationBarBackgroundColor": "#4eb331", + "navigationBarTextStyle": "white" + } + } + ] + }, + { + "root": "subPages/messageChild", + "pages": [ + { + "path": "msgChat/msgChat", + "style": { + "navigationBarTitleText": "消息" + } + }, + { + "path": "appPlay/appPlay", + "style": { + "navigationBarTitleText": "余额充值" + } + } + ] + } + ], + "tabBar": { + "color": "#7A7E83", + "selectedColor": "#4eb331", + "borderStyle": "black", + "backgroundColor": "#ffffff", + "list": [ + { + "pagePath": "pages/order-manager/main", + "text": "订单管理", + "iconPath": "./static/image/tabBarIcon/order.png", + "selectedIconPath": "./static/image/tabBarIcon/order-active.png" + }, + { + "pagePath": "pages/goods-manager/main", + "text": "商品管理", + "iconPath": "./static/image/tabBarIcon/shopping.png", + "selectedIconPath": "./static/image/tabBarIcon/shopping-active.png" + }, + { + "pagePath": "pages/message/index", + "text": "消息", + "iconPath": "./static/image/tabBarIcon/msg.png", + "selectedIconPath": "./static/image/tabBarIcon/msg-active.png" + }, + { + "pagePath": "pages/merchant/index", + "text": "商家中心", + "iconPath": "./static/image/tabBarIcon/merchant.png", + "selectedIconPath": "./static/image/tabBarIcon/merchant-active.png" + } + ] + }, + "condition": { + "current": 0, + "list": [ + { + "name": "订单管理-新订单通知", + "path": "subPages/orderChild/orderDetail/orderDetail?vendorOrderID=3800913802922106022&vendorID=1" + } + ] + } +} \ No newline at end of file diff --git a/src/pages/goods-manager/childPages/right-main/right-main.scss b/src/pages/goods-manager/childPages/right-main/right-main.scss new file mode 100644 index 0000000..5b95a37 --- /dev/null +++ b/src/pages/goods-manager/childPages/right-main/right-main.scss @@ -0,0 +1,305 @@ +.skuName-cell { + box-sizing: border-box; + background: white; + padding: 19rpx; + border-radius: 10rpx; + margin: 15rpx 15rpx; + box-shadow: 0rpx 2rpx 10rpx rgb(207, 207, 207); + + + .skuName { + display: flex; + align-items: flex-start; + position: relative; + + .skuName-img { + position: relative; + + view { + position: absolute; + z-index: 9; + left: 0; + top: 0; + width: 182rpx; + height: 182rpx; + border-radius: 10rpx; + background: rgba(0, 0, 0, .4); + text-align: center; + line-height: 182rpx; + color: #fff; + font-weight: bold; + } + + .imglabel { + width: 180rpx; + height: 180rpx; + border-radius: 10rpx; + border: 1rpx solid rgb(218, 218, 218); + } + } + + .skuName-info { + display: flex; + flex-direction: column; + justify-content: space-between; + margin-left: 17rpx; + width: 100%; + height: 180rpx; + + .input-price { + position: absolute; + border: 1rpx solid rgba(0, 0, 0, 0.1); + background: white; + border-radius: 8rpx; + padding: 20rpx; + top: 60rpx; + color: #333; + } + + .skuName-name { + color: #333; + font-size: 32rpx; + line-height: 1; + display: flex; + align-items: flex-start; + } + + .skuName-monthsale { + font-size: 28rpx; + color: #999; + line-height: 1; + margin-top: 7rpx; + } + + .skuName-failsync { + font-size: 28rpx; + color: #F60D58; + line-height: 1; + margin-top: 7rpx; + margin-bottom: -30rpx; + } + + .skuName-price { + display: flex; + color: #F60D58; + line-height: 1; + + .icon-modify { + margin-left: 15rpx; + } + } + + .skuName-tips { + font-size: 28rpx; + line-height: 1; + color: #333; + } + + .red { + color: #F60D58; + } + + .green { + color: $jx-primary; + } + } + } + + // sku + .skus { + border-top: 1rpx dashed #ccc; + display: flex; + flex-flow: row wrap; + // justify-content: flex-end; + // padding-top: 16rpx; + // overflow: hidden; + margin-top: 10rpx; + align-items: flex-start; + + .sku-cell:nth-of-type(even) { + margin-left: 10rpx; + } + } + + // 价格审核中样式 + .check-display { + color: #f44; + font-size: 24rpx; + font-weight: bold; + animation: rubberBand 1s infinite alternate; + } +} + +.skus-wrapper-new { + border-top: 1rpx solid rgb(219, 219, 219); + + .error { + text-align: center; + font-size: 24rpx; + font-weight: bold; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + .mt { + color: #f29a40; + } + + .eb { + color: #51a7fc; + } + + .sku-cell2 { + padding: 10rpx 0 0 0; + border-bottom: 1rpx solid rgb(219, 219, 219); + position: relative; + } + + .isSale2 {} + + .cell-top { + display: flex; + align-items: center; + + .price { + color: #333; + width: 23%; + flex-shrink: 0; + text-align: center; + display: flex; + justify-content: center; + flex-flow: column; + + .sku-spec { + font-size: 26rpx; + } + + .sku-price { + font-size: 26rpx; + } + } + + .promotion-price { + color: #F60D58; + } + + .btn-group { + width: 78%; + flex-shrink: 0; + display: flex; + justify-content: space-around; + + .btn { + box-sizing: border-box; + flex: 1; + height: 80rpx; + text-align: center; + font-size: 24rpx; + border-radius: 10rpx; + color: $jx-primary; + border: 2rpx solid $jx-primary; + display: flex; + justify-content: center; + align-items: center; + box-sizing: border-box; + margin-right: 8rpx; + } + + .tmpSaleNo { + box-sizing: border-box; + display: flex; + flex-direction: column; + font-size: 28rpx; + line-height: 1.02; + margin: 0; + } + + .onActive { + background: $jx-primary; + color: white; + } + } + } + + .cell-bottom { + font-size: 28rpx; + text-align: center; + color: #666; + padding: 5rpx 0; + } + + .sku-autoSaleAt { + font-size: 26rpx; + text-align: center; + color: #F25340; + padding: 5rpx 0; + + text { + font-weight: bold; + } + } +} + +.checkBoxWrap { + display: flex; + width: 100%; + justify-content: flex-end; + padding-top: 15rpx; +} + +.aduit-type { + font-size: 28rpx; + text-align: center; + color: $jx-primary; +} + +.aduit-btn-group { + display: flex; + align-items: center; + justify-content: center; + padding-top: 20rpx; + + .btn { + font-size: 28rpx; + padding: 20rpx 40rpx; + background: $jx-primary; + border-radius: 10rpx; + color: white; + margin: 0 20rpx; + } + + .refuse { + background: #f44; + } +} + +@keyframes rubberBand { + from { + transform: scale3d(1, 1, 1); + } + + 30% { + transform: scale3d(1.01, 0.75, 1); + } + + 40% { + transform: scale3d(0.95, 1.25, 1); + } + + 50% { + transform: scale3d(1.02, 0.85, 1); + } + + 65% { + transform: scale3d(0.98, 1.05, 1); + } + + 75% { + transform: scale3d(1.01, 0.95, 1); + } + + to { + transform: scale3d(1, 1, 1); + } +} \ No newline at end of file diff --git a/src/pages/goods-manager/childPages/right-main/right-main.ts b/src/pages/goods-manager/childPages/right-main/right-main.ts new file mode 100644 index 0000000..3c5b73c --- /dev/null +++ b/src/pages/goods-manager/childPages/right-main/right-main.ts @@ -0,0 +1,177 @@ +import shopping from "@/api/https/shopping" +import { store } from "@/store" +import { getStorage } from "@/utils/storage" +import toast from "@/utils/toast" +import { jx_throttles, timeFormatD } from "@/utils/tools" +import { computed } from "@vue/reactivity" +import configCms from "@/utils/configCms" + +interface propType { + skuName: AnyObject + isAudit: boolean + isHot: boolean + showMountTab: boolean +} +/************************************************* + * 商品列表 +*/ +function goodsListFn(props: Readonly) { + + /************************************************* + * 列表判断条件 + */ + const isNewPriceDisplay: any = computed(() => { + store.getters['storeInfo/isNewPriceDisplay'] + }) + + /************************************************* + * 获取userType + */ + const userType = computed(() => { + return +getStorage('userType') + }) + + /************************************************* + * 修改商品售卖状态 + */ + function updateSaleStatus(sku: AnyObject, skuName: AnyObject, status: number) { + if (+sku.storeSkuStatus === +status && !sku.autoSaleAt) return false + let data = { + sku, + skuName, + status + } + updateSaleStatusThrottles(data) + } + const updateSaleStatusThrottles = jx_throttles({ + time: 500, + success: async (e: AnyObject) => { + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + payload: JSON.stringify([ + { + nameID: e.skuName.id, + skus: [ + { + skuID: e.sku.id, + isSale: +e.status === 0 ? -1 : +e.status, + }, + ], + }, + ]), + } + let res = await shopping.update_stores_skus(data) + if (res.code == 0) { + changeSaleStatus(e.sku, e.skuName, e.status) + if (e.sku.autoSaleAt) e.sku.autoSaleAt = 0 + } else { + toast('修改失败', 2) + } + }, + fail: (t: number) => { + toast(`操作太快`) + } + }) + + /************************************************* + * 修改商品临时不可售 + */ + function tmpSaleNo(sku: AnyObject, skuName: AnyObject) { + if (sku.storeSkuStatus === 0 && sku.autoSaleAt) return false + let data = { + sku, + skuName, + } + tmpSaleNoThrottles(data) + } + const tmpSaleNoThrottles = jx_throttles({ + time: 500, + success: async (e: AnyObject) => { + let autoSaleAt = computedAutoSaleAt() + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + payload: JSON.stringify([{ + skuID: e.sku.id, + isSale: -1, + isAsync: false, + }]), + autoSaleAt: autoSaleAt + } + let res = await shopping.update_stores_skus_sale(data) + + // let res:AnyObject = { + // code: "-105", + // desc: "本地数据修改成功,但同步失败,请根据错误提示处理!,同步错误信息:[{\"商品ID\":0,\"分类名\":\"\",\"门店ID\":804947,\"平台名\":\"抖店平台\",\"平台商品ID\":\"\",\"商品nameID\":0,\"平台价\":0,\"同步类型\":\"异常同步错误\",\"错误信息\":\"门店:804947,修改没有创建的商品:22807\"},{\"商品ID\":22807,\"分类名\":\"\",\"门店ID\":804947,\"平台名\":\"京东到家\",\"平台商品ID\":\"2792687352\",\"商品nameID\":8643,\"平台价\":0,\"同步类型\":\"更新商品状态\",\"错误信息\":\"未查询到到家商品编码\"}]", + // data: "" + // } + + // if (res.code === '0') { + // changeSaleStatus(e.sku, e.skuName, 0) + // e.sku.autoSaleAt = autoSaleAt + // } else { + // if(res.code === '-105' && res.desc.includes('本地数据修改成功,但同步失败,请根据错误提示处理')) toast(res.desc) + // else toast('修改失败', 2) + // } + + if (res.code == 0) { + changeSaleStatus(e.sku, e.skuName, 0) + e.sku.autoSaleAt = autoSaleAt + } else { + let findIndex = res.desc.indexOf('[') + let str = '' + if(findIndex !== -1){ + JSON.parse(res.desc.substring(findIndex)).forEach((element:AnyObject) => { + str = str.length >0 ? str + ';\n' + element['平台名'] + ':【' + element['错误信息'] + '】': str + element['平台名'] +':【' + element['错误信息']+'】' + }); + } + if(res.code === '-105' && res.desc.includes('本地数据修改成功,但同步失败,请根据错误提示处理')) toast(`${str}`) + else toast('修改失败', 2) + } + }, + fail: (t: number) => { + toast(`操作太快`) + } + }) + + /************************************************* + * 计算自动可售时间 + */ + function computedAutoSaleAt() { + let now = +new Date() + let autoTime = +new Date(`${timeFormatD(+new Date())} ${autoSaleAt.value}`) + if (now < autoTime) { + return `${timeFormatD(+new Date())} ${autoSaleAt.value}` + } else { + return `${timeFormatD(+new Date() + 24 * 3600 * 1000)} ${autoSaleAt.value}` + } + } + + // 自动可售时间 + const autoSaleAt = computed(() => { + let { autoSaleAt = '' } = configCms.serveInfo + return autoSaleAt + }) + + /************************************************* + * 修改商品可售状态 + */ + async function changeSaleStatus(sku: AnyObject, skuName: AnyObject, status: number) { + if (props.isAudit) return false + sku.storeSkuStatus = +status + // 计算可售不可售图标 + if (skuName.skus.some((item: AnyObject) => item.storeSkuStatus)) { + skuName.skuAllnoSale = false + } else { + skuName.skuAllnoSale = true + } + } + + return { + isNewPriceDisplay, // 列表判断条件 + userType, // 获取userType + updateSaleStatus, // 修改商品售卖状态 + tmpSaleNo, // 临时不可售 + } +} + +export default goodsListFn \ No newline at end of file diff --git a/src/pages/goods-manager/childPages/right-main/right-main.vue b/src/pages/goods-manager/childPages/right-main/right-main.vue new file mode 100644 index 0000000..c2e476d --- /dev/null +++ b/src/pages/goods-manager/childPages/right-main/right-main.vue @@ -0,0 +1,264 @@ + + + + + \ No newline at end of file diff --git a/src/pages/goods-manager/childPages/shopping-filter/shopping-filter.vue b/src/pages/goods-manager/childPages/shopping-filter/shopping-filter.vue new file mode 100644 index 0000000..2667a4d --- /dev/null +++ b/src/pages/goods-manager/childPages/shopping-filter/shopping-filter.vue @@ -0,0 +1,218 @@ + + + + + \ No newline at end of file diff --git a/src/pages/goods-manager/childPages/shopping-search/shopping-search.vue b/src/pages/goods-manager/childPages/shopping-search/shopping-search.vue new file mode 100644 index 0000000..4a30ed7 --- /dev/null +++ b/src/pages/goods-manager/childPages/shopping-search/shopping-search.vue @@ -0,0 +1,128 @@ + + + + + \ No newline at end of file diff --git a/src/pages/goods-manager/component/left-bar/left-bar.scss b/src/pages/goods-manager/component/left-bar/left-bar.scss new file mode 100644 index 0000000..917801d --- /dev/null +++ b/src/pages/goods-manager/component/left-bar/left-bar.scss @@ -0,0 +1,45 @@ +// 一级 +.one-item { + background-color: #fff; + height: 90rpx; + overflow: hidden; + transition: all 0.4s; + border-bottom: 1rpx solid #f1f1f1; + + // 二级名字 + .one-item-name { + display: flex; + height: 90rpx; + line-height: 90rpx; + + .iconfont { + display: inline-block; + transform: rotate(0deg); + transition: all 0.2s; + } + + .noe-seat { + display: inline-block; + width: 30rpx; + height: 90rpx; + border-left: 7rpx solid transparent; + transition: none; + } + } + + // 二级内容 + .tow-item { + display: flex; + height: 90rpx; + line-height: 90rpx; + transition: none; + + // 二级左侧竖杠 + .tow-seat { + display: inline-block; + width: 30rpx; + height: 90rpx; + border-left: 7rpx solid transparent; + } + } +} \ No newline at end of file diff --git a/src/pages/goods-manager/component/left-bar/left-bar.ts b/src/pages/goods-manager/component/left-bar/left-bar.ts new file mode 100644 index 0000000..dea7f17 --- /dev/null +++ b/src/pages/goods-manager/component/left-bar/left-bar.ts @@ -0,0 +1,83 @@ +import shopping from "@/api/https/shopping" +import { getStorage } from "@/utils/storage" +import { onLoad } from "@dcloudio/uni-app" +import { ref } from "vue" + +/************************************************* + * 商品分类栏目 +*/ +function leftBarFn(props: AnyObject) { + + onLoad(async () => { + await GetStoreCategoryMap() + }) + + /************************************************* + * @info 左侧tab数据 + * 获取列表数据 + */ + const cat = ref>([]) + async function GetStoreCategoryMap() { + let data = { + storeID: getStorage('storeID'), + parentID: -1, + } + let res = await shopping.getStore_category_map(data) + if (res.code == 0) { + handledata(res.data, true) + } else { + cat.value = [] + handleOriginData() + } + } + + /************************************************* + * 处理列表数据 + */ + const _isMap = ref(false) + function handledata(curdeData: Array, isMap: boolean) { + let data = curdeData + let catData: Array = [] + data.forEach((item: AnyObject) => { + if (item.name !== '3件9.9') { + item.name = item.name.slice(0, 4) + } + catData.push(item) + }) + + //把sku分类过滤掉 + if (!isMap) catData = catData.filter((item) => item.type === 0) + let catLevel1 = catData.filter((item) => item.level === 1) + let catLevel2 = catData.filter((item) => item.level === 2) + + // 组合分类 + let catData2: Array = [] + let catData3: AnyObject + catLevel1.forEach((level1: AnyObject) => { + isMap + ? (catData3 = catLevel2.filter( + (level2) => level2.parentID === level1.categoryID + )) + : (catData3 = catLevel2.filter((level2) => level2.parentID === level1.id)) + level1.children = catData3 + _isMap.value = isMap + catData2.push(level1) + }) + let lastData = props.dafauleData.concat(catData2) + cat.value = lastData + } + + async function handleOriginData() { + let res = await shopping.get_categories() + if (res.code == 0) { + handledata(res.data, false) + } + } + + return { + cat, // 右侧菜单数据 + GetStoreCategoryMap, // 获取数据 + } +} + +export default leftBarFn \ No newline at end of file diff --git a/src/pages/goods-manager/component/left-bar/left-bar.vue b/src/pages/goods-manager/component/left-bar/left-bar.vue new file mode 100644 index 0000000..42b7264 --- /dev/null +++ b/src/pages/goods-manager/component/left-bar/left-bar.vue @@ -0,0 +1,139 @@ + + + + + \ No newline at end of file diff --git a/src/pages/goods-manager/main.scss b/src/pages/goods-manager/main.scss new file mode 100644 index 0000000..2f7027c --- /dev/null +++ b/src/pages/goods-manager/main.scss @@ -0,0 +1,124 @@ +.MountWrap { + display: flex; + z-index: 99; + box-sizing: border-box; + justify-content: space-between; + position: fixed; + width: 100%; + bottom: 0; + left: 0; + background-color: $jx-primary; + padding: 20rpx 25rpx; + + .onActive { + width: 44%; + background-color: #fff; + color: $jx-primary; + text-align: center; + border-radius: 10rpx; + padding: 10rpx 0; + } +} + +.createGoods { + padding: 10rpx 80rpx; + border-radius: 10rpx; + background-color: $jx-primary; + color: #fff; + text-align: center; + margin-top: 20rpx; +} + +.jx-popup-update { + box-sizing: border-box; + padding: 20rpx; + background-color: #fff; + border-radius: 0 0 15rpx 15rpx; + + .text { + display: block; + width: 100%; + text-align: center; + margin-bottom: 25rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid rgb(209, 209, 209); + } + + .tip-new{ + padding: 2rpx 0; + height: 66rpx; + line-height: 66rpx; + text-align: left; + border-bottom:1px dashed #999; + + .money { + color: $jx-primary; + } + } + + .ipt-box{ + margin: 10rpx 0; + // height: 86rpx; + // line-height: normal; + } + + .tip { + padding: 10rpx 0; + + .money { + color: $jx-primary; + } + } + + .ipt { + border: 2rpx solid rgb(209, 209, 209); + text-align: center; + border-radius: 5rpx; + height: 86rpx; + line-height: normal; + // -webkit-appearance: none; + // border-radius: 0 + } + + .title { + width: 100%; + text-align: center; + margin-bottom: 20rpx; + } + + .btn-root { + display: flex; + justify-content: space-between; + margin: 40rpx 0 0rpx 0; + + .btn-esc, + .btn-ok { + text-align: center; + width: 100%; + padding: 15rpx 0; + border-radius: 10rpx; + border: 2rpx solid $jx-primary; + color: $jx-primary; + } + + .btn-ok { + background-color: $jx-primary; + color: #fff; + margin-left: 10rpx; + } + + .btn-esc { + margin-right: 10rpx; + } + } + + .delete { + margin-top: 50rpx; + margin-bottom: 20rpx; + background-color: $jx-warring; + text-align: center; + color: #fff; + padding: 20rpx; + border-radius: 15rpx; + } +} \ No newline at end of file diff --git a/src/pages/goods-manager/main.ts b/src/pages/goods-manager/main.ts new file mode 100644 index 0000000..b0eaad7 --- /dev/null +++ b/src/pages/goods-manager/main.ts @@ -0,0 +1,710 @@ +import { onLoad, onShow } from '@dcloudio/uni-app' +import { getStorage } from '@/utils/storage' +import { computed, onBeforeUnmount, ref } from 'vue' +import { store } from '@/store' +import { timeFormatD, timeFormatHMS } from '@/utils/tools' +import toast from '@/utils/toast' +import shopping from '@/api/https/shopping' +import merchant from '@/api/https/merchant' +/************************************************* + * 商品管理 +*/ +function shoppingMangerFn() { + /************************************************* + * 数据归位,元神显现 + */ + function dataHoming() { + skuNames.value = [] + page.value = 1 + totalCount.value = 0 + } + + /************************************************* + * 下拉刷新数据重现 + */ + const leftBarRef = ref(null) + let onPullDownRefreshTimer: any = '' + const triggered = ref(false) + function refresherrefresh() { + triggered.value = true + clearTimeout(onPullDownRefreshTimer) + onPullDownRefreshTimer = setTimeout(() => { + triggered.value = false + dataHoming() + oneMenuClick(isFilter.value) + if (isFilter.value == 'hot') return + leftBarRef.value.GetStoreCategoryMap() + }, 500) + } + + /************************************************* + * 获取数据 + */ + let oldStoreID: any = 0 + onShow(() => { + if (oldStoreID != getStorage('storeID') && oldStoreID != 0) { + triggered.value = true + } + oldStoreID = getStorage('storeID') + }) + + /************************************************* + * 默认数据 + */ + const dafauleData: Array = [ + { + categoryID: 'all', + children: [], + level: 1, + name: '所有分类', + }, + { + categoryID: 'act', + children: [], + level: 1, + name: '活动商品', + }, + { + categoryID: 'hot', + children: [], + level: 1, + name: '畅销推荐', + }, + { + categoryID: 'audit', + children: [], + level: 1, + name: '待审商品', + }, + ] + + /************************************************* + * @info 右侧主体数据 + * 获取商品数据 + */ + onLoad(async () => { + if (!getStorage('token')) return + store.commit('storeInfo/jxLoadingFn', true) + await getSkuNames() + store.commit('storeInfo/jxLoadingFn', false) + }) + const keyword = ref('') + const categoryID = ref('') // 分类id + const isAct = ref(false) // 是否是活动商品 + const totalCount = ref(0) // 总条数 + const skuNames = ref>([]) // 商品数据 + const isAudit = ref(false) // 商品列表判断条件 + const isHot = ref(false) // 商品列表判断条件 + async function getSkuNames() { + isLoad.value = true + let data:AnyObject = { + categoryID: categoryID.value, + isFocus: true, + keyword: keyword.value, + offset: pageSize.value * (page.value - 1), + pageSize: pageSize.value, + isAct: isAct.value, + status: -1, + storeID: getStorage('storeID') + } + + if(allSaleStatus.value && allSaleStatus.value.name !== 'all') data[allSaleStatus.value.name] = allSaleStatus.value.status + + keyFilter(data) + + let res = await shopping.get_stores_skus_for_store(data) + + if (res.code == 0) { + totalCount.value = res.data.totalCount + let filterData = mapskuName(res.data.skuNames || []) + skuNames.value = skuNames.value.concat(filterData) + if (filterData.length == 0) return toast('该分类未找到商品') + } else { + dataHoming() + toast('分类查询错误') + } + isLoad.value = false + } + + /************************************************* + * 过滤对象空字段 + */ + function keyFilter(obj: AnyObject) { + for (let key in obj) { + if ('' + obj[key] == "" || '' + obj[key] == undefined) { + delete obj[key] + } + } + return obj + } + + /************************************************* + * 列表判断条件 + */ + const isNewPriceDisplay = ref( + store.getters['storeInfo/isNewPriceDisplay'] + ) + + /************************************************* + * 格式化数据 + */ + function mapskuName(skuNames: Array) { + let arr = skuNames.map((skuName) => { + skuName.auditUnitPrice = skuName.auditUnitPrice + // 是否全部不可售 + if (skuName.skus.some((item: AnyObject) => item.storeSkuStatus)) { + skuName.skuAllnoSale = false + } else { + skuName.skuAllnoSale = true + } + // skus + skuName.skus = skuName.skus.map((sku: AnyObject) => { + // 价格异常请参考老版本或者在git进行查看 + sku.comparePrice = sku.price + sku.autoSaleAt = + +new Date(sku.autoSaleAt) > 0 ? timeFormatHMS(sku.autoSaleAt) : 0 + return sku + }) + return skuName + }) + return arr + } + + /************************************************* + * 页面触底,加载更多数据 + */ + const page = ref(1) // 第几页 + const pageSize = ref(20) // 每页条数 + const isLoad = ref(false) // 加载图 + function scrolltolower() { + page.value++ + if (pageSize.value * (page.value - 1) > totalCount.value || totalCount.value < pageSize.value) { + isLoad.value = false + } else { + if (isLoad.value) return + if (isFilter.value == 'hot') return + if (isFilter.value == 'audit') return GetStoreSkuAudit() + getSkuNames() + } + } + + /************************************************* + * 点击菜单获取数据 + */ + const isCheckoutFilter = ref(false) + const isFilter = ref('') + function oneMenuClick(catID: string | number) { + isAct.value = false + isHot.value = false + isCheckoutFilter.value = false + categoryID.value = '' + keyword.value = '' + isFilter.value = catID + isAudit.value = false + dataHoming() + if (catID == 'all') { // 全部商品 + isAct.value = false + getSkuNames() + } else if (catID == 'act') { // 活动商品 + isAct.value = true + getSkuNames() + } else if (catID == 'hot') { // 畅销商品 + isHot.value = true + isCheckoutFilter.value = true + getTopSkus() + } else if (catID == 'audit') { // 待审核商品 + isCheckoutFilter.value = true + isAudit.value = true + GetStoreSkuAudit() + } else { + categoryID.value = catID as string + getSkuNames() + } + } + + /************************************************* + * 畅销推荐 + */ + async function getTopSkus() { + isLoad.value = true + let data = { + storeID: getStorage('storeID') + } + let res = await shopping.get_top_skus_by_city_code(data) + if (res.code == 0) { + let data = res.data || [] + if (data.length > 0) { + totalCount.value = data.length + skuNames.value = mapskuName(data) + } else { + dataHoming() + toast('暂无畅销商品') + } + + } else { + toast('分类查询错误') + dataHoming() + } + isLoad.value = false + } + + /************************************************* + * 待审核商品 + */ + async function GetStoreSkuAudit() { + isLoad.value = true + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + applyTimeStart: timeFormatD(+new Date() - 1000 * 60 * 60 * 24 * 30) + ' 00:00:00', + applyTimeEnd: timeFormatD(+new Date()) + ' 23:59:59', + statuss: JSON.stringify([0]), + types: JSON.stringify([1, 2]), + offset: pageSize.value * (page.value - 1), + pageSize: pageSize.value, + } + let res = await shopping.get_store_sku_audit(data) + if (res.code == 0) { + totalCount.value = res.data.totalCount + let newData = res.data.data || [] + let filterSkuName = mapAuditSkuName(newData) + skuNames.value = skuNames.value.concat(filterSkuName) + if (newData.length == 0) return toast('暂无待审核商品') + } else { + toast('分类查询错误') + dataHoming() + } + isLoad.value = false + } + + + /************************************************* + * 过滤待审核商品 + */ + function mapAuditSkuName(data: AnyObject) { + let arr = data.map((item: any) => ({ + auditUnitPrice: item.unitPrice, + unitPrice: item.originPrice, + skuAllnoSale: false, + nameID: item.nameID, + img: item.img, + unit: item.unit, + type: item.type, + prefix: item.prefix, + name: item.skuName, + })) + return arr + } + + + /************************************************* + * @info 过滤类数据 + */ + const showMountTab = ref(false) + + + /************************************************* + * 头部数据过滤 + */ + const allSaleStatus = ref() + async function updateIsSale(data: AnyObject) { + allSaleStatus.value = data + data.lable == 3 + ? (showMountTab.value = true) + : (showMountTab.value = false) + if (data.lable == 3) return + dataHoming() + await getSkuNames() + } + async function updateTowFilter(data: AnyObject) { + if (data.lable == 3) { + return showMountTab.value = true + } else { + showMountTab.value = false + } + if (isFilter.value == 'hot') { + oneMenuClick(isFilter.value) + } + + if (isFilter.value == 'audit') { + oneMenuClick(isFilter.value) + } + } + + /************************************************* + * @info 搜索框操作 + */ + async function serachShopping(text: string) { + dataHoming() + keyword.value = text + await getSkuNames() + } + async function clearInpu() { + dataHoming() + keyword.value = '' + await getSkuNames() + } + + /************************************************* + * 批量操作 + */ + let picked: Array = [] + function handleSale(skuName: AnyObject) { + if (picked && picked.some((item) => item.nameID == skuName.id)) { + picked = picked.filter((item) => { + return item.nameID != skuName.id + }) + } else { + picked.push({ nameID: Number(skuName.id) }) + picked = distinct(picked, 'nameID') + } + } + function distinct(arr: any, key: string) { + let set = new Set() + return arr.reduce( + (p: any, c: any) => (set.has(c[key]) ? p : (set.add(c[key]), [...p, c])), + [] + ) + } + + /************************************************* + * 批量可售与不可售 + */ + let handleChangeSaleTimer: any = null + const updateStateOk = ref(false) + async function handleChangeSale(type: number) { + if (picked.length == 0) return toast('未选择商品') + picked.forEach((item: AnyObject) => { + item['isSale'] = type + }) + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + payload: JSON.stringify(picked), + } + let res = await shopping.update_stores_skus(data) + if (res.code == 0) { + toast('修改成功') + let data = { + status: -1, + lable: 2, + } + updateStateOk.value = true + handleChangeSaleTimer = setTimeout(() => { + updateIsSale(data) + clearTimeout(handleChangeSaleTimer) + }, 1000) + } else { + toast('修改失败', 2) + updateStateOk.value = false + } + } + + /************************************************* + * 去创建商品 + */ + function createGoods() { + uni.navigateTo({ url: '/subPages/shoppingChild/createGoods/createGoods' }) + } + + /************************************************* + * 改价还是折扣(从vuex 里面读取) + */ + const isPointStore = computed(() => { + return store.getters['storeInfo/isPointStore'] + }) + // skuName + const skuName = ref({ + unit: '', + auditUnitPrice: '' + }) + function openPriceDialog(skuNames: AnyObject) { + skuName.value = skuNames + popup.value.open() + } + // 当前修改价格 + const currentValue = ref('') + // 审核价格 + const auditUnitPrice = computed(() => { + let price = skuName.value.auditUnitPrice + if (price) { + return +((price * 1) / 100).toFixed(2) + } else { + return +'0.00' + } + }) + // 弹窗实例 + const popup = ref(null) + // 确定修改价格 + function handleConfirm() { + if (isNaN(+currentValue.value)) return toast('请输入格式正确的价格') + if (+currentValue.value < 0.01) return toast('请输入大于等于1分钱的价格') + if ( + currentValue.value.toString().indexOf('.') > -1 && + currentValue.value.toString().split('.')[1].length > 2 + ) { + return toast('最多只能有两位小数') + } + let updatePrice = Math.round(+currentValue.value * 100) + if (updatePrice == skuName.value.unitPrice) { + return toast('没有修改价格') + } + if (updatePrice > skuName.value.unitPrice * 1.3 || + updatePrice < skuName.value.unitPrice * 0.7) { + uni.jxConfirm({ + title: '提示', + content: `修改幅度超过30%,新价格为¥${(updatePrice / 100).toFixed(2)},是否确定修改?`, + success: () => { + updatePriceFn(updatePrice, skuName.value.id, skuName.value.unitPrice) + } + }) + } else { + updatePriceFn(updatePrice, skuName.value.id, skuName.value.unitPrice) + } + } + /** + * 验证通过开始修改价格 + */ + let updatePriceFnTimer: any = null + async function updatePriceFn(price: string | number, id: number, originalUnitPrice: number) { + let data = { + storeIDs: JSON.stringify([+getStorage('storeID')]), + payload: JSON.stringify([ + { + nameID: skuName.value.id, + unitPrice: price, + }, + ]), + } + popup.value.close() // 关闭 popup + // 修改价格 + let updatePrice = await shopping.update_stores_skus(data) + + if (updatePrice.code == 0) { + // 获取单个门店serverSkuName + let storeData = { + storeIDs: JSON.stringify([+getStorage('storeID')]), + isFocus: true, + nameIDs: JSON.stringify([id]), + fromStatus: 0, + toStatus: 1, + } + const serverSkuName = await merchant.get_stores_skus(storeData) + if (serverSkuName.code == 0) { + let skuNameData = serverSkuName.data.skuNames || [] + if (skuNameData.length > 0) { + let index = skuNames.value.findIndex((item: any) => item.id == id) + if (index !== -1) skuNames.value[index] = mapskuName(skuNameData)[0] + } + } + // 判断提示 + if (isPointStore.value || store.state.storeInfo.allStoreInfo.storeLevel == 'E') { + toast('修改成功') + currentValue.value = '' + } else { + currentValue.value = '' + toast( + +price < originalUnitPrice ? '修改成功' : '提交成功, 请等待审核' + ) + } + } else { + toast('修改失败', 2) + } + } + + /************************************************* + * 修该库存或货架码 + */ + const popupDialog = ref(null) + const skuNameItem = ref({ + payload:{ + nameID:0, + Skus:[], + }, + name:'', + type:'price' + }) + const stockOrCode = ref('') + + // 打开dialog 修改库存以及货架码 + function openDialog(payload: AnyObject) { + skuNameItem.value = payload + const sku = payload.payload.Skus[0] + if(payload.type === 'stock') stockOrCode.value = sku.stock + '' + if(payload.type === 'locationCode') stockOrCode.value = sku.locationCode + popupDialog.value.open() + } + async function sureStockOrCode() { + const nameID = skuNameItem.value.payload.nameID + const skuID = skuNameItem.value.payload.Skus[0].skuID + let data:AnyObject = { + storeIDs: JSON.stringify([+getStorage('storeID')]) + } + if(skuNameItem.value.type === 'stock') { + data.payload = JSON.stringify([{ + nameID: nameID, + Skus:[ + { + skuID: skuID, + stock: +stockOrCode.value + } + ] + }]) + }else{ + data.payload = JSON.stringify([{ + nameID: nameID, + Skus:[ + { + skuID:skuID, + locationCode: ''+ stockOrCode.value ? '' + stockOrCode.value : 'EMPTY_VALUE' + } + ] + }]) + } + popupDialog.value.close() // 关闭 popupDialog + let res = await shopping.update_stores_skus(data) + if (res.code == 0) { + let storeData = { + storeIDs: JSON.stringify([+getStorage('storeID')]), + isFocus: true, + nameIDs: JSON.stringify([skuNameItem.value.payload.nameID]), + fromStatus: 0, + toStatus: 1, + } + const serverSkuName = await merchant.get_stores_skus(storeData) + if (serverSkuName.code == 0) { + let skuNameData = serverSkuName.data.skuNames || [] + if (skuNameData.length > 0) { + let index = skuNames.value.findIndex((item: any) => item.id == skuNameItem.value.payload.nameID) + if (index !== -1) { + skuNames.value[index] = mapskuName(skuNameData)[0] + } + } + } + toast('修改成功') + } + } + + /************************************************* + * 删除商品 + */ + function handleDelete() { + uni.jxConfirm({ + title: '提示', + content: `确认删除《${skuName.value.name}》吗?`, + confirmText: '确认', + success: async () => { + popup.value.close() // 关闭 popup + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + payload: JSON.stringify([{ nameID: skuName.value.id, isFocus: -1 }]), + } + let res = await shopping.update_stores_skus(data) + if (res.code == 0) { + toast('删除成功') + skuNames.value = skuNames.value.filter((item) => item.id != skuName.value.id) + if (skuNames.value.length == 0) return dataHoming() + } else { + toast('删除失败', 2) + } + } + }) + } + + + const toExamineData = ref({}) // 审核商品数据 + const toExaminePopup = ref(null) // 审核弹窗实例 + const toExamineValue = ref('') // 审核输入框 + /************************************************* + * 审核商品 + */ + function toExamine(res: AnyObject) { + toExamineData.value = res + if (res.status == 1) { + toExamineValue.value = res.auditPrice / 100 + } else { + toExamineValue.value = '' + } + toExaminePopup.value.open() + } + + /************************************************* + * 改价审核操作 + */ + async function toExamineConfirm() { + toExaminePopup.value.close() + let data = { + status: toExamineData.value.status, + isAsync: false, + isContinueWhenError: true, + payload: JSON.stringify([{ + storeID: toExamineData.value.storeID, + nameID: toExamineData.value.nameID, + ...(toExamineData.value.status == 1 + ? { auditPrice: Math.floor(+toExamineValue.value * 100) } + : { remark: toExamineValue.value }) + }]) + } + let res = await shopping.store_sku_price_audit(data) + if (res.code == 0) { + toast('操作成功') + skuNames.value = skuNames.value.filter((item) => item.nameID != toExamineData.value.nameID) + if (skuNames.value.length == 0) return dataHoming() + } else { + toast(res.desc || res.data) + } + } + + + /************************************************* + * 善后工作 + */ + onBeforeUnmount(() => { + clearTimeout(handleChangeSaleTimer) + clearTimeout(updatePriceFnTimer) + clearTimeout(onPullDownRefreshTimer) + }) + + return { + dafauleData, // 左侧tablist 数据 + totalCount, // 商品总条数 + skuNames, // 商品列表数据 + skuNameItem, // 商品数据2 + isAudit, // 商品列表判断条件 + isHot, // 商品列表判断条件 + showMountTab, // 批量操作判断 + scrolltolower, // 页面触底 + isLoad, // 加载动画 + updateIsSale, // 过滤筛选 + updateTowFilter, // 过滤筛选 + serachShopping, // 搜索框确定 + clearInpu, // 清空搜索框 + oneMenuClick, // 一级菜单点击事件 + isCheckoutFilter, // 切换过滤选项 + isFilter, // 判断条件 + handleSale, // 批量可售与不可售 + handleChangeSale, // 批量可售与不可售 + updateStateOk, // 批量操作成功 + createGoods, // 去创建商品 + isPointStore, // 判断扣点还是折扣 + skuName, // 当前修改的价格 + auditUnitPrice, // 正在审核的价格 + currentValue, // 当前修改价格 + popup, // 弹窗实例 + stockOrCode, // stock locationCode + popupDialog, // 弹窗 stock locationCode + handleConfirm, // 确定修改价格 + openPriceDialog, // 获取修改数据 + openDialog, // 获取修改数据2 + sureStockOrCode, // 确认框 stock locationCode + handleDelete, // 删除商品 + refresherrefresh, // 下拉刷新 + triggered, // 下拉刷新标识 + leftBarRef, // 右侧导航栏实例 + toExamine, // 审核商品 + toExamineData, // 审核商品数据 + toExaminePopup, // 改价审核实例 + toExamineConfirm, // 确定操作审核 + toExamineValue, // 审核输入内容 + } +} + +export default shoppingMangerFn \ No newline at end of file diff --git a/src/pages/goods-manager/main.vue b/src/pages/goods-manager/main.vue new file mode 100644 index 0000000..8fa0553 --- /dev/null +++ b/src/pages/goods-manager/main.vue @@ -0,0 +1,244 @@ + + + + + + + \ No newline at end of file diff --git a/src/pages/merchant/index.ts b/src/pages/merchant/index.ts new file mode 100644 index 0000000..0d87744 --- /dev/null +++ b/src/pages/merchant/index.ts @@ -0,0 +1,189 @@ + +import { computed, onBeforeUnmount, ref } from 'vue' +import { timeFormatD } from '@/utils/tools' +import { getStorage, setStorage } from '@/utils/storage' +import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app' +import merchant from '@/api/https/merchant' +import { store } from '@/store' +import useGlobalFunc from '@/composables/useGlobalFunc' +import log from '@/utils/log' + +/************************************************* + * 商家中心 +*/ +const merchantFn = function () { + const { getMtStoreIMStatus } = useGlobalFunc() + /************************************************* + * 下拉刷新 + */ + let onPullDownRefreshTimer: any = null + onPullDownRefresh(() => { + clearTimeout(onPullDownRefreshTimer) + onPullDownRefreshTimer = setTimeout(async () => { + if (!getStorage('token')) return + store.commit('storeInfo/jxLoadingFn', true) + await getSaleInfo() + await getStoreVendorMaps(-1) + await getMtStoreIMStatus() // 获取美团门店的IM状态 + uni.stopPullDownRefresh() + clearTimeout(onPullDownRefreshTimer) + store.commit('storeInfo/jxLoadingFn', false) + }, 500) + }) + + + /************************************************* + * 页面加载获取数据 + */ + const popup = ref(null) + onLoad(async (params) => { + // 订单管理-新订单通知 + let logData = { + '日志记录时间': Date(), + '启动类型': '订单管理', + '启动参数': params, + '用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN', + '用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号', + '店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID', + '店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字', + } + log.info(JSON.stringify(logData)) + + if (!getStorage('token')) return + store.commit('storeInfo/jxLoadingFn', true) + await getStoreVendorMaps(-1) + await getSaleInfo() + store.commit('storeInfo/jxLoadingFn', false) + if (getStorage('isDownApp') != 'true') { + setTimeout(() => { + popup.value.open() + }, 800) + } + }) + + + const saleInfo = ref({ + earningPrice: 0, + count: 0, + }) + + /************************************************* + * 获取今日营业数据 + */ + async function getSaleInfo() { + let fromTime = `${timeFormatD()} 00:00:00` + let toTime = `${timeFormatD()} 23:59:59` + let data = { + storeIDs: `[${parseInt(getStorage('storeID'))}]`, + fromTime, + toTime, + statuss:JSON.stringify([110]) // 只统计已完成的订单,不包含取消单 + } + await merchant.get_store_order_sale_info(data).then((res) => { + let json = { + earningPrice: 0, + shopPrice: 0, + realEarningPrice: 0, + count: 0, + actualPayPrice: 0, + actualFee: 0 + } + if (res.code == 0) { + let data = res.data || [] + + data.forEach((item: AnyObject) => { + if (item.status === 110) { + json.actualPayPrice += item.actualPayPrice + json.realEarningPrice += item.realEarningPrice + json.earningPrice += item.earningPrice + json.shopPrice += item.shopPrice + json.count += item.count + json.actualFee += item.actualFee + } + }) + json.actualFee = +(json.actualFee / 100).toFixed(2) + saleInfo.value = json + } else { + saleInfo.value = json + } + }) + } + + + /************************************************* + * 获取门店信息数据 + */ + const _vendorPayPercentage = ref(0) + const isNotQuote = ref(true) + const isZero = ref(true) + const isUpperfif = ref(false) + const isShowShop = ref(false) + async function getStoreVendorMaps(vendorID: number) { + let data = { + storeID: getStorage('storeID'), + vendorID: vendorID + } + let res = await merchant.get_store_vendor_maps(data) + if (res.code == 0) { + let data = res.data + _vendorPayPercentage.value = data[0].vendorPayPercentage + isNotQuote.value = true + isNotQuote.value = data.some((item: AnyObject) => { + return item.vendorPayPercentage != 0 && item.vendorPayPercentage <= 50 + }) + isZero.value = data.every((item: AnyObject) => { + return item.vendorPayPercentage == 0 + }) + isUpperfif.value = data.every((item: AnyObject) => { + return item.vendorPayPercentage > 50 + }) + if (isNotQuote.value) { + isShowShop.value = data.every((v: AnyObject) => { + return v.vendorPayPercentage > 50 + }) + } + } else { + _vendorPayPercentage.value = 0 + } + } + + function getMsg() { + uni.removeTabBarBadge({ index: 3 }) + store.commit('storeInfo/setIsNewMessage', false) + uni.navigateTo({ + url: '/subPages/merchantChild/message/message', + }) + } + + const isMsg = computed(() => { + return store.state.storeInfo.isNewMessage + }) + + function closeDownApp() { + setStorage('isDownApp', 'true') + popup.value.close() + } + + + /************************************************* + * 做收尾工作 + */ + onBeforeUnmount(() => { + clearTimeout(onPullDownRefreshTimer) + }) + + return { + saleInfo, // 今日订单数据 + _vendorPayPercentage, // 供应商百分比 + isShowShop, // 是否为出售金额 + isNotQuote, + isZero, + isUpperfif, + getMsg, + isMsg, + popup, + closeDownApp, + } +} + +export default merchantFn \ No newline at end of file diff --git a/src/pages/merchant/index.vue b/src/pages/merchant/index.vue new file mode 100644 index 0000000..ee39a39 --- /dev/null +++ b/src/pages/merchant/index.vue @@ -0,0 +1,156 @@ + + + + + \ No newline at end of file diff --git a/src/pages/merchant/options/options.scss b/src/pages/merchant/options/options.scss new file mode 100644 index 0000000..5f4e7c3 --- /dev/null +++ b/src/pages/merchant/options/options.scss @@ -0,0 +1,106 @@ +.options-root { + background-color: #fff; + margin-top: 20rpx; + box-sizing: border-box; + padding: 20rpx; + + :deep(.popupAnimation) { + z-index: 1000000; + } + + .grid-item-box { + position: relative; + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + .image { + width: 75rpx; + height: 75rpx; + margin-bottom: 10rpx; + } + + .text { + font-size: 26rpx; + } + + + // ************* 角标内容 ************ + // 我的账单 + .bill-new { + position: absolute; + top: 15rpx; + right: 15rpx; + background-color: $jx-warring; + color: #fff; + font-size: 24rpx; + padding: 0 15rpx 5rpx 15rpx; + border-radius: 20rpx; + animation: bill-new-animation 0.5s ease-in-out infinite alternate; + } + + // 消息通知 + .msg-count { + position: absolute; + top: 20rpx; + right: 35rpx; + color: #fff; + background-color: $jx-warring; + font-size: 24rpx; + min-width: 18rpx; + min-height: 20rpx; + line-height: 20rpx; + text-align: center; + line-height: 1; + padding: 4rpx 8rpx 5rpx 8rpx; + border-radius: 100rpx; + } + + // 差评管理 + .evaluate-number { + position: absolute; + top: 20rpx; + right: 30rpx; + color: #fff; + background-color: $jx-warring; + font-size: 24rpx; + line-height: 1; + padding: 4rpx 8rpx 5rpx 8rpx; + border-radius: 100rpx; + min-width: 30rpx; + text-align: center; + max-height: 35rpx; + } + + // 发现新版本 + .newVarsion { + position: absolute; + top: 15rpx; + right: 30rpx; + display: inline-block; + background-color: $jx-warring; + width: 30rpx; + height: 30rpx; + border-radius: 50%; + font-size: 24rpx; + line-height: 30rpx; + text-align: center; + color: #fff; + padding: 5rpx; + animation: bill-new-animation 0.5s ease-in-out infinite alternate; + } + } +} + + +@keyframes bill-new-animation { + 0% { + transform: scale(0.95); + } + + 100% { + transform: scale(1.05); + } +} \ No newline at end of file diff --git a/src/pages/merchant/options/options.ts b/src/pages/merchant/options/options.ts new file mode 100644 index 0000000..2f29b1c --- /dev/null +++ b/src/pages/merchant/options/options.ts @@ -0,0 +1,316 @@ +/** + * options 选项 + */ +import toast from "@/utils/toast" +import { store } from '@/store' +import { timeFormatD } from "@/utils/tools" +import { getStorage } from "@/utils/storage" +import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app" +import { Ref, ref, onBeforeUnmount,watch } from "vue" +import merchant from '@/api/https/merchant' +import order from "@/api/https/order" + +function options() { + /** + * 进入群聊 + */ + function getGroupChat() { + uni.navigateTo({ + url: '/subPages/merchantChild/enterGroupChat/enterGroupChat', + }) + } + + + /** + * 注册时间 + */ + async function getSelfInfo() { + let infoRes = await merchant.get_self_info() + if (infoRes.code == 0) { + let time1 = Math.floor((+new Date() - +new Date(infoRes.data.createdAt)) / 1000 / 24 / 3600) + let time2 = Math.floor((+new Date() - +new Date(store.state.storeInfo.createStoreTimer)) / 1000 / 24 / 3600) + uni.jxAlert({ + title: '回首过往', + content: `门店ID:${getStorage('storeID')}\r\n\r\n您注册于${timeFormatD(infoRes.data.createdAt)}\r\n来到京西${time1}天\r\n\r\n门店创建于${timeFormatD(store.state.storeInfo.createStoreTimer)}\r\n在平台经营${time2}天` + }) + } else toast('注册数据异常', 2) + } + + + /** + * 物料申请 + */ + function moveToWM() { + if (store.state.storeInfo.allStoreInfo.packageSwitch === 1) { + let tel = store.state.storeInfo.allStoreInfo.marketManPhone ? store.state.storeInfo.allStoreInfo.marketManPhone : "18048531223" + uni.jxAlert({ + title: '物料申请', + content: `非常抱歉,无法进入物料商城,请联系运营${tel}` + }) + return + } + + if (store.state.storeInfo.storeStatus === -2) { + uni.jxAlert({ + title: '物料申请', + content: '门店已被禁用,请联系运营' + }) + } + + uni.navigateToMiniProgram({ + appId: 'wx4b5930c13f8b1170', + path: `pages/index/index?storeID=666666&fromStoreID=${getStorage('storeID')}&storeType=c4`, + success: (res) => { + toast('即将进入京西菜市') + }, + fail: (err) => { + toast('取消申请') + }, + }) + } + + /** + * 查询是否有新账单 + */ + onLoad(async () => { + await handleMsg() + await tmpGetJxBadCommentsNo() + await getMessageData() + }) + // 处理新账单 + const billUrl: Ref = ref('') + const newBillShow: Ref = ref(false) // 是否有新帐单 + function handleMsg() { + getStoreBills((url: Array | string) => { + if (typeof (url) == 'string') { + billUrl.value = url + // 保存新账单url地址 (存vuex) + store.commit('serveInfo/setOrderUrl', url) + + // 查询本地账单地址 + if (getStorage('newBillUrl') !== billUrl.value) { + // 有新账单 + newBillShow.value = true + } else { + // 没有新帐单 + newBillShow.value = false + } + } + }) + } + // 查询新订单 + interface BillListType { + billName: string + billTitle: string + date: string + id: number + shopName: string + storeId: string + url: string + } + const billList = ref>([]) + async function getStoreBills(fn: Function) { + let data = { + storeID: getStorage('storeID') + } + let newOrderRes = await merchant.get_store_bills(data) + if (newOrderRes.code == 0) { + let newMsg: Array | string = [] + if (newOrderRes.data != null) { + billList.value = newOrderRes.data.slice(0, 5) + billList.value = billList.value.map((bill) => { + let time = bill.date + bill.date = timeFormatD(time) + return bill + }) + newMsg = newOrderRes.data[0].url.trim() + fn && fn(newMsg) + } else { + billList.value = [] + fn && fn(newMsg) + } + } else { + toast('账单数据异常', 2) + } + + } + + + /** + * 是否有新信息 + */ + const msgCount = ref(0) + async function getMessageData() { + let data = { + storeIDs: JSON.stringify([+getStorage('storeID')]), + fromReadCount: 0, + toReadCount: 0, + offset: 0, + pageSize: -1, + fromTime: + timeFormatD(+new Date() - 7 * 24 * 60 * 60 * 1000) + ' 00:00:00', + toTime: timeFormatD(+new Date()) + ' 23:59:59', + } + let msgRes = await merchant.Get_store_message_statuses(data) + if (msgRes.code == 0) { + msgCount.value = msgRes.data.totalCount + } else { + toast('消息数据异常') + } + } + + + /** + * 获取差评数量 + */ + let badCommentCount: Ref = ref(0) + async function tmpGetJxBadCommentsNo() { + let data = { + jxStoreId: getStorage('storeID') + } + let evaluateMRes = await merchant.tmp_get_jx_bad_comments_no(data) + if (evaluateMRes.code == 0) { + badCommentCount.value = evaluateMRes.data ? evaluateMRes.data : 0 + } else toast('差评数据异常', 2) + } + + watch(() => store.getters['storeInfo/imMtStatus'], + (val) => { + if(val && val.length>0) getInvoiceInfo('mt') + }) + + /** + * 发票数量 美团 + */ + const invoiceCount:Ref = ref(0) + async function getInvoiceInfo(type:string,ebStore?:any) { + if(type === 'mt'){ + // 美团们门店 + if(store.getters['storeInfo/imMtStatus'] && store.getters['storeInfo/imMtStatus'].length>0) { + let data:AnyObject = { + storeId: getStorage('storeID'), + startTime: `${timeFormatD(+new Date() - 7 * 24 * 60 * 60 * 1000)}` + ' 00:00:00', + endTime:`${timeFormatD()}` + ' 23:59:59', + pageSize: -1, + offset: 0 + } + let res = await order.query_mt_invoice(data) + if(res.code === '0') invoiceCount.value = res.data.totalCount + } + }else if(type === 'eb'){ + // console.log('get_invoice_info',ebStore) + // let res = await order.get_invoice_info({ + // vendorId:'3', + // vendorStoreID:'' + ebStore.vendorStoreID, + // storeID:+ebStore.storeID + // }) + // console.log('饿百数据列表信息',res.data) + // if(res.code === '0') invoiceCount.value = Number(invoiceCount.value) + res.total_count + } + } + + + /** + * 打开 app or 小程序 + */ + function openAppOrApplet() { + uni.jxAlert({ + title: '提示', + content: '下载链接复制成功,请到浏览器进行下载,或者到手机应用商店搜索【京西菜市】进行下载!', + success: () => { + uni.setClipboardData({ + data: 'https://www.jxc4.com/managerApp/downApp.html' + }) + } + }) + } + + + /************************************************* + * 下拉刷新 + */ + let onPullDownRefreshTimer: any = null + onPullDownRefresh(() => { + clearTimeout(onPullDownRefreshTimer) + onPullDownRefreshTimer = setTimeout(async () => { + await tmpGetJxBadCommentsNo() + await getMessageData() + await handleMsg() + await getInvoiceInfo('mt') + // await getInvoiceInfo('eb') + uni.stopPullDownRefresh() + }, 1000) + }) + + + /** + * 版本更新 + */ + const isVarsion = ref(false) + onBeforeUnmount(() => { + clearTimeout(onPullDownRefreshTimer) + }) + + + /************************************************* + * 微信小程序版本更新 + */ + function autoUpdate() { + // 获取小程序更新机制兼容 + if (uni.canIUse('getUpdateManager')) { + const updateManager = uni.getUpdateManager() + // 检查是否有新版本发布 + updateManager.onCheckForUpdate(function (res) { + if (res.hasUpdate) { + isVarsion.value = true + //小程序有新版本,则静默下载新版本,做好更新准备 + updateManager.onUpdateReady(function () { + uni.jxAlert({ + title: '更新提示', + content: '应用已经升级到新版本了请及时更新', + success: () => { + updateManager.applyUpdate() + } + }) + }) + // 新的版本下载失败 + updateManager.onUpdateFailed(function () { + uni.showModal({ + title: '温馨提示', + content: '新版本已经上线,请您删除当前小程序,重新搜索打开', + }) + }) + } else { + isVarsion.value = false + toast('已经是最新版') + } + }) + } else { + // 提示用户在最新版本的客户端上体验 + uni.showModal({ + title: '温馨提示', + content: '当前微信版本过低,可能无法使用该功能,请升级到最新版本后重试。' + }) + } + } + + + + return { + getGroupChat, // 跳转加入群聊 + getSelfInfo, // 获取门店来京西的时间 + moveToWM, // 物料申请 + newBillShow, // 是否有新订单 + billList, // 账单列表 + msgCount, // 是否有信息 + badCommentCount, // 获取差评数量 + invoiceCount, // 发票数量 + openAppOrApplet, // app or 小程序 + isVarsion, // 是否现实新版本 + autoUpdate, // 检查微信更新 + } + +} + + +export default options \ No newline at end of file diff --git a/src/pages/merchant/options/options.vue b/src/pages/merchant/options/options.vue new file mode 100644 index 0000000..a0e4bfa --- /dev/null +++ b/src/pages/merchant/options/options.vue @@ -0,0 +1,280 @@ + + + + + diff --git a/src/pages/merchant/orderData/orderData.scss b/src/pages/merchant/orderData/orderData.scss new file mode 100644 index 0000000..c993de9 --- /dev/null +++ b/src/pages/merchant/orderData/orderData.scss @@ -0,0 +1,49 @@ +.order-data-root { + box-sizing: border-box; + background-color: #fff; + padding: 20rpx; +} + +.title-root { + display: flex; + justify-content: space-between; + margin-bottom: 10rpx; + + .see-more { + color: #cfcccc; + } + + .text { + margin-right: 15rpx; + } +} + +.order-money { + display: flex; + justify-content: space-between; + + .money, + .order { + border-right: 1rpx solid #e0e0e0; + } + + .money, + .order, + .order1 { + width: 354rpx; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .number { + font-weight: bold; + font-size: 40rpx; + padding: 30rpx 0; + } + } + + .afterNumber::before{ + content: '-'; + } +} \ No newline at end of file diff --git a/src/pages/merchant/orderData/orderData.vue b/src/pages/merchant/orderData/orderData.vue new file mode 100644 index 0000000..9cf382c --- /dev/null +++ b/src/pages/merchant/orderData/orderData.vue @@ -0,0 +1,151 @@ + + + + + \ No newline at end of file diff --git a/src/pages/merchant/userInfo/userInfo.scss b/src/pages/merchant/userInfo/userInfo.scss new file mode 100644 index 0000000..7c1c1d5 --- /dev/null +++ b/src/pages/merchant/userInfo/userInfo.scss @@ -0,0 +1,127 @@ +.merchant-root { + box-sizing: border-box; + background-color: #4eb331; + position: sticky; + top: 0; + z-index: 1; + + .store-timer { + text-align: center; + color: #fcff06; + height: 0rpx; + line-height: 50rpx; + overflow: hidden; + transition: all 0.5s; + + .text { + margin-left: -60rpx; + } + } + + .store-active { + height: 50rpx; + } + + .info-root { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0rpx 20rpx 20rpx 20rpx; + + .user-infor-root { + display: flex; + align-items: center; + + image { + width: 140rpx; + height: 140rpx; + border-radius: 50%; + background-color: #fff; + border: 4rpx solid #fff; + } + + .isHeight { + height: 190rpx; + } + + .storeName-style-timer { + display: flex; + flex-direction: column; + color: #fff; + width: 380rpx; + margin-left: 25rpx; + + .timer-root { + margin-top: 5rpx; + line-height: 1; + padding: 10rpx 10rpx; + background-color: rgba(0, 0, 0, 0.15); + border-radius: 10rpx; + } + + .name, + .state, + .timer-root { + display: inline-block; + max-width: 380rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-bottom: 10rpx; + } + + .state, + .timer { + font-size: 28rpx; + } + + .state { + display: flex; + align-items: center; + + .tip{ + display: flex; + line-height: 46rpx; + .title{ + font-size: 24rpx; + } + } + + .do-business-root { + display: flex; + align-items: center; + justify-content: center; + background: #3e8f27; + border-radius: 80rpx; + color: #cccccc; + margin-right: 10rpx; + transition: all 0.4s; + + .text { + padding: 0 15rpx; + } + } + + .business-active { + background-color: #ffad49; + color: #fff; + } + } + } + } + + .esc-switchSoter { + width: 152rpx; + + button { + font-size: 24rpx; + color: #4eb331; + white-space: nowrap; + } + + .swithcStore-btn { + margin-top: 20rpx; + } + } + } +} \ No newline at end of file diff --git a/src/pages/merchant/userInfo/userInfo.ts b/src/pages/merchant/userInfo/userInfo.ts new file mode 100644 index 0000000..6f1b1e1 --- /dev/null +++ b/src/pages/merchant/userInfo/userInfo.ts @@ -0,0 +1,229 @@ +/** + * 用户信息类 + */ +import { getStorage, setStorage } from "@/utils/storage"; +import { onPullDownRefresh, onShow, onLoad } from "@dcloudio/uni-app"; +import { computed, onBeforeUnmount, ref } from "vue"; +import { timeFormatD } from "@/utils/tools"; +import useGlobalFunc from "@/composables/useGlobalFunc"; +import { listenOrder } from '@/utils/bluetoothPrinter/printerOrder' +import { store } from "@/store"; + + +function userInfo() { + const { newMessage, logOutFn, isTxd, getMtStoreIMStatus } = useGlobalFunc() + + + /** + * 门店自动营业时间 + */ + const newAutoEnableAt = ref('') + const switchOpenTime = computed(() => { + if (newAutoEnableAt.value) { + let now = +new Date(timeFormatD(+new Date())); + let time = +new Date(timeFormatD(newAutoEnableAt.value)); + let num = time - now; + if (num < 0) { + return "营业时间错误请联系运营"; + } else { + let day = num / 1000 / 3600 / 24; + if (day < 1) return "门店将在今天自动营业"; + else if (day >= 1 && day < 2) return "门店将在明天自动营业"; + else if (day >= 2 && day < 3) return "门店将在后天自动营业"; + else return `将在 ${timeFormatD(newAutoEnableAt.value)} 自动营业`; + } + } else { + return ""; + } + }) + + /** + * 下拉刷新 + */ + let onPullDownRefreshTimer: any = null + onPullDownRefresh(async () => { + await getStores() + clearTimeout(onPullDownRefreshTimer) + onPullDownRefreshTimer = setTimeout(() => { + uni.stopPullDownRefresh() + }, 1000) + }) + + /** + * 用户头像、门店名字 + */ + interface StoreInfoType { + avatar: string; + storeName: string; + } + const storeInfo = ref({ + avatar: "https://image.jxc4.com/image/70143fcf48aefe74537533f35a0a8153.jpg", + storeName: "", + }); + let oldStoreID: any = 0 + onShow(async () => { + getStores() + await listenOrder() + storeInfo.value.storeName = getStorage("storeName") + if (oldStoreID != getStorage('storeID') && oldStoreID != 0) { + uni.startPullDownRefresh({}) + } + oldStoreID = getStorage('storeID') + }); + onLoad(async () => { + await getStores() + await newMessage() // 商家中心有新信息了 + }) + + const businessHours = ref({}) + async function getStores() { + await store.dispatch('storeInfo/getOneStore',getStorage("storeID")) + businessHours.value = store.getters['storeInfo/businessHours'] // 营业时间 + newAutoEnableAt.value = store.getters['storeInfo/newAutoEnableAt'] // 手机门店休息时间 + + await getMtStoreIMStatus() // 获取门店的IM单聊开关状态 + + await newMessage() // 商家中心有新信息了 + await listenOrder() // 小程序监听新订单 + } + + /************************************************* + * 去修改营业时间 + */ + function setTime() { + uni.navigateTo({ url: `/subPages/merchantChild/setBusinessTime/setBusinessTime` }) + } + + /** + * 退出登录 + */ + let goLoginTime: any = null + function goLogin() { + uni.vibrateShort({}) + uni.showActionSheet({ + title: '退出后不会删除任何数据', + itemColor: '#e70808', + itemList: ['退出登录'], + popover: { + width: 5000, + }, + success: function (res) { + logOutFn() + // uni.navigateTo({ url: '/subPages/login/wxLogin/wxLogin' }) + uni.reLaunch({ url: '/subPages/login/wxLogin/wxLogin' }) + }, + fail: () => { + console.log('ZSW-取消退出'); + }, + complete: () => { + uni.vibrateShort({}) + } + }); + } + + function downApp() { + uni.jxAlert({ + title: '提示', + content: '下载链接复制成功,请到浏览器进行下载,或者到手机应用商店搜索【京西菜市】进行下载!', + success: () => { + uni.setClipboardData({ + data: 'https://www.jxc4.com/managerApp/downApp.html' + }) + } + }) + } + + /** + * 切换门店 + */ + function switchStore() { + uni.navigateTo({ url: "/subPages/switchStore/switchStore" }); + + // 图片转pdf https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=88093251_52_hao_pg&wd=uniapp%E5%B0%8F%E7%A8%8B%E5%BA%8F%20%E5%A6%82%E4%BD%95%E5%B0%86%E5%9B%BE%E7%89%87%E7%9A%84%E4%B8%B4%E6%97%B6%E6%96%87%E4%BB%B6%E8%BD%AC%E6%88%90pdf%E6%A0%BC%E5%BC%8F&oq=%25E9%2587%258D%25E6%25B8%25A9%25E6%2580%25BB%25E4%25B9%25A6%25E8%25AE%25B0%25E5%25AF%25B9%25E6%25B5%25B7%25E5%258D%2597%25E5%25AF%2584%25E4%25BA%2588%25E7%259A%2584%25E5%258E%259A%25E6%259C%259B&rsv_pq=cd144c82001083ca&rsv_t=4715G1mkyqJr%2FhraQB%2FDsJO62gnA57BCAmiAx1S%2Be4x%2FRVjoViQTJa15XVpww3QSg2jkH32EJe6s&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=25&rsv_n=2&rsv_sug1=18&rsv_sug7=100&rsv_btype=t&inputT=14749&rsv_sug4=14838 + // import jsPDF from 'jspdf'; + // const ctx = uni.createCanvasContext('myCanvas', this); + // // 假设你有一个图片的临时路径,例如从uni.chooseImage获取 + // const imagePath = '/path/to/your/image.jpg'; + // ctx.drawImage(imagePath, 0, 0, 300, 300); // 绘制图片到Canvas上 + // ctx.draw(false, () => { + // // 获取Canvas内容并转换为PDF + // const contentWidth = 300; // Canvas宽度 + // const contentHeight = 300; // Canvas高度 + // const pdf = new jsPDF('p', 'pt', [contentWidth, contentHeight]); // A4 size page format + // pdf.addImage(imagePath, 'JPEG', 0, 0, contentWidth, contentHeight); // 这里需要确保图片路径正确,或者在绘制后使用ctx.toTempFilePath获取图片路径 + // pdf.save('converted-image.pdf'); // 保存PDF文件 + // }); + // ctx.toTempFilePath({ + // success: (res) => { + // console.log('图片路径:', res.tempFilePath); + // }, + // fail: (err) => { + // console.error('导出失败:', err); + // } + // }); + // uni.chooseImage({ + // count: 1, // 默认9,设置图片的最大数量为1张 + // sizeType: ['original'], // 可以指定是原图还是压缩图,默认二者都有 + // sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 + // success: function(res) { + // // 获取到图片的本地文件路径列表 + // const tempFilePaths = res.tempFilePaths; + // // 获取文件管理器 + // console.log('获取临时文件路径',res) + // const fs = uni.getFileSystemManager(); + // // 读取文件内容并转换为Base64 + // fs.readFile({ + // filePath: tempFilePaths[0], // 选择图片返回的本地文件路径列表的第一个路径 + // encoding: 'base64', // 指定编码格式为base64 + // success: function(res) { + // const base64Data = res.data; // 读取到的Base64数据 + // console.log(base64Data,'二进制文件base64格式'); // 输出或使用base64Data + // }, + // fail: function(err) { + // console.error('读取文件失败', err); + // } + // }); + // // fs.readFile({ + // // filePath: tempFilePaths[0], // 第一个图片的路径 + // // encoding: 'binary', // 以二进制形式读取 + // // success: function(res) { + // // console.log(res,'图片的二进制数据:', res.data); // 这里的res.data就是图片的二进制数据 + // // } + // // }) + // } + // }) + } + + /** + * 跳转到设置营业状态页面 + */ + function jumpBusinessStatus() { + uni.navigateTo({ + url: '/subPages/merchantChild/setBusinessStatus/setBusinessStatus' + }) + } + + /************************************************* + * 做收尾工作 + */ + onBeforeUnmount(() => { + clearTimeout(onPullDownRefreshTimer) + clearTimeout(goLoginTime) + }) + + + return { + storeInfo, // 用户信息 + businessHours, // 营业时间段 + goLogin, // 退出登录 + switchStore, // 切换门店 + switchOpenTime, // 门店休息到那天 + setTime, // 去修改营业时间 + jumpBusinessStatus, // 跳转到营业状态页面 + downApp, + store + } +} + + +export default userInfo \ No newline at end of file diff --git a/src/pages/merchant/userInfo/userInfo.vue b/src/pages/merchant/userInfo/userInfo.vue new file mode 100644 index 0000000..3adfbef --- /dev/null +++ b/src/pages/merchant/userInfo/userInfo.vue @@ -0,0 +1,97 @@ + + + + + \ No newline at end of file diff --git a/src/pages/message/index.ts b/src/pages/message/index.ts new file mode 100644 index 0000000..932a93e --- /dev/null +++ b/src/pages/message/index.ts @@ -0,0 +1,209 @@ +import toast from '@/utils/toast' +import { onPullDownRefresh, onShow } from '@dcloudio/uni-app' +import { computed, ref } from 'vue' +import { store } from "@/store" +import { Decrypt, timeFormatDHM } from '@/utils/tools' +import message from '@/api/https/message' +import order from '@/api/https/order' +import useGlobalFunc from "@/composables/useGlobalFunc" +// import { msgInfo } from '@/api/mockData/index' +/************************************************* + * IM消息 +*/ +const messageFn = function () { + // vuex + const { getMtStoreIMStatus } = useGlobalFunc() + + // 用户列表 + const userListData = ref>([]) + + /************************************************* + * 获取用户列表 + */ + onShow(() => { + if (isFirstLogin.value) return + userListData.value = [] + getMTUserList() + }) + const isFirstLogin = computed(() => { + // 是否没有登陆的状态 + return store.state.serveInfo.isFirstLogin + }) + + /** + * 整理参数信息,避免请求出错 + */ + async function dataParams() { + let arr:any = [] + let brr = store.getters['storeInfo/platformInfo'] + if(brr && brr.length>0){ + let mtVendorIDInfo = brr.find((item:AnyObject) => item.vendorID === 1) + let ebVendorIDInfo = brr.find((item:AnyObject) => item.vendorID === 3) + if(mtVendorIDInfo){ + arr.push({ + vendorStoreID: mtVendorIDInfo.vendorStoreID, + vendorID: "1", + appID: mtVendorIDInfo.vendorOrgCode + }) + } + + if(ebVendorIDInfo){ + arr.push({ + vendorStoreID: ebVendorIDInfo.vendorStoreID, + vendorID: "3", + appID: ebVendorIDInfo.vendorOrgCode + }) + } + } + return arr + } + + // 获取美团IM + async function getMTUserList(time?:number) { + let arr = await dataParams() + if(!(arr && arr.length>0)) return + let data = { + payLoad:JSON.stringify(arr) + } + let venderIDInfo = arr.find((item:AnyObject) => item.vendorID === '1') + let ebStore = arr.find((item:AnyObject) => item.vendorID === '3') + + let res = await message.get_IM_user_list(data) + // res = msgInfo.userList // 模拟数据 + // console.log('获取用户列表', res) + if (res.code == 0) { + if (JSON.stringify(res.data) === '{}') return + let platformID = venderIDInfo.appID // 美团账号 + let newArr: any = [] + // let fmtUserList = res.data[`${venderIDInfo.appID}:${venderIDInfo.vendorStoreID}:1`] || [] // 美团 + let fmtUserList = venderIDInfo ? res.data[`${venderIDInfo.appID}:${venderIDInfo.vendorStoreID}:1`] || [] : [] // 美团 + let febUserList = ebStore && JSON.stringify(ebStore) !== '{}' ? res.data[`${ebStore.appID}:${ebStore.vendorStoreID}:3`] || [] : [] // 饿百 + + let reverseList = fmtUserList && fmtUserList.length > 0 ? fmtUserList.reverse() : [] + let reverseListEb = febUserList && febUserList.length > 0 ? febUserList.reverse() : [] + reverseList.map((element: any) => { + let resData = JSON.parse(element) + + // 判断是否需要显示列表 + if (Decrypt(resData.latestMsg, platformID).indexOf('[自动回复]') == -1) { + let latestMsgHandler = '' + try { + JSON.parse(Decrypt(resData.latestMsg, platformID)) + latestMsgHandler = typeof JSON.parse(Decrypt(resData.latestMsg, platformID)) === 'number' ? Decrypt(resData.latestMsg, platformID) : '【订单】' + } catch (error) { + let msg = Decrypt(resData.latestMsg, platformID) + if (msg == '') latestMsgHandler = '【商品】' + else { + if (!(msg.includes('https') || msg.includes('http'))) latestMsgHandler = msg + else latestMsgHandler = msg.indexOf('.amr') == -1 ? '【图片】' : '【语音】' + } + } + + // if (resData.userID != 0) { + // 只展示6个小时以内的消息 + let userList = { + ...resData, + latestMsg: latestMsgHandler, + latestTime: timeFormatDHM(+new Date(resData.latestTime * 1000)), + orderInfo: {}, + orderDesc: '' + } + newArr.push(userList) + + // 获取订单信息 + // if (userList.orderID) getOrderInfo(userList.orderID, index) + if (userList.orderID) getOrderInfo(userList.orderID, newArr.length - 1) + + // } + + } + }) + + // 饿百 + reverseListEb.map((element: any, index: number) => { + let resData = JSON.parse(element) + let latestMsgHandler = JSON.parse(resData.latestMsg).text ? JSON.parse(resData.latestMsg).text : JSON.parse(resData.latestMsg).duration ? '【语音】' : '【图片】' + // let isAddUserLiset = JSON.parse(resData.latestMsg).data && JSON.parse(JSON.parse(resData.latestMsg).data).title.includes('本次服务已经完成,会话暂停') ? false : true + if (JSON.parse(resData.latestMsg).elements && JSON.parse(resData.latestMsg).elements.length > 0) { + let findItem = JSON.parse(resData.latestMsg).elements.filter((item: { elementType: number }) => item.elementType === 1) + latestMsgHandler = findItem && findItem.length > 0 ? JSON.parse(findItem[0].elementContent).text.replace('@商家', '') : latestMsgHandler + } + // 饿百参考文档:https://open-retail.ele.me/#/apidoc/me.ele.retail:im.message.send-3?aopApiCategory=IM_all&type=api_menu resData.userID != 0 && isAddUserLiset + if ((new Date().getTime() - resData.latestTime * 1000) <= (3600 * 1000 * 12 * 1) ) { + let userList = { + ...resData, + latestMsg: latestMsgHandler, + latestTime: timeFormatDHM(+new Date(resData.latestTime * 1000)), + orderInfo: {}, + orderDesc: '' + } + newArr.push(userList) + + // 获取订单信息 + // if (userList.orderID) getOrderInfo(userList.orderID, index) + if (userList.orderID) getOrderInfo(userList.orderID, newArr.length - 1 ) + } + + }) + + userListData.value = newArr + } else { + toast('获取信息异常') + userListData.value.length == 0 + } + } + + /** + * 获取订单信息 + */ + async function getOrderInfo(orderId: string, index: number) { + let res = await order.get_orders({ vendorOrderID: orderId }) + if (res.code === '0') { + userListData.value[index].orderInfo = res.data.data[0] + userListData.value[index].orderDesc = ` #${res.data.data[0].orderSeq}` + } + } + + /** + * 下拉刷新 + */ + let onPullDownRefreshTimer: any = null + onPullDownRefresh(() => { + clearTimeout(onPullDownRefreshTimer) + onPullDownRefreshTimer = setTimeout(async () => { + getMtStoreIMStatus() // 刷新美团门店IM单聊状态 + // 获取用户列表 + getMTUserList() + clearTimeout(onPullDownRefreshTimer) + }, 500) + }) + + + /************************************************* + * 进入聊天页面 + */ + function charItem(item: AnyObject) { + item.latestMsg = "" + uni.navigateTo({ + url: `/subPages/messageChild/msgChat/msgChat?data=${JSON.stringify(item)}`, + }) + } + + /************************************************* + * 进入设置页面 + */ + function jumpToSetUp() { + uni.navigateTo({ + url: `/subPages/merchantChild/setUp/setUp`, + }) + } + + return { + charItem, // 进入聊天页面 + userListData, // 用户列表 + jumpToSetUp, // 跳到设置页面 + store + } +} + +export default messageFn \ No newline at end of file diff --git a/src/pages/message/index.vue b/src/pages/message/index.vue new file mode 100644 index 0000000..0259252 --- /dev/null +++ b/src/pages/message/index.vue @@ -0,0 +1,76 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/abnormal-order/abnormal-order.scss b/src/pages/order-manager/childPages/abnormal-order/abnormal-order.scss new file mode 100644 index 0000000..df5f445 --- /dev/null +++ b/src/pages/order-manager/childPages/abnormal-order/abnormal-order.scss @@ -0,0 +1,76 @@ +.position-relative { + position: relative; +} + +.abnormal-order { + background-color: #fff; + padding-bottom: 1rpx; + + .address { + display: flex; + justify-content: space-between; + padding: 15rpx; + font-size: 32rpx; + border-bottom: 2rpx dashed #e7e7e7; + color: #999999; + font-size: 28rpx; + } + + .abnormal-op { + height: 90rpx; + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: space-between; + font-size: 32rpx; + padding: 0 20rpx; + background: linear-gradient(to right, #e8edd8, white); + + .title { + color: #333; + font-weight: bold; + } + + .op { + display: flex; + align-items: center; + + .btn-cancel, + .btn-confirm { + color: #fff; + background-color: $jx-primary; + padding: 7rpx 30rpx; + border-radius: 7rpx; + } + + .btn-cancel { + margin-right: 40rpx; + background-color: #F60D58; + } + } + } + + .abnormal-dealed { + height: 90rpx; + display: flex; + align-items: center; + justify-content: center; + font-size: 32rpx; + background: white; + color: #333; + + text { + font-weight: bold; + display: inline-block; + margin-left: 10rpx; + } + + .agree { + color: green; + } + + .refuse { + color: red; + } + } +} \ No newline at end of file diff --git a/src/pages/order-manager/childPages/abnormal-order/abnormal-order.vue b/src/pages/order-manager/childPages/abnormal-order/abnormal-order.vue new file mode 100644 index 0000000..d000fbc --- /dev/null +++ b/src/pages/order-manager/childPages/abnormal-order/abnormal-order.vue @@ -0,0 +1,80 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/abnormal-order/abonmrmal-order.ts b/src/pages/order-manager/childPages/abnormal-order/abonmrmal-order.ts new file mode 100644 index 0000000..4fae39c --- /dev/null +++ b/src/pages/order-manager/childPages/abnormal-order/abonmrmal-order.ts @@ -0,0 +1,158 @@ +import { store } from "@/store" +import toast from "@/utils/toast" +import order from '@/api/https/order' +/************************************************* + * 异常订单处理 +*/ +function abonmrmalFn(props: { item: AnyObject }) { + + // 是否拒绝用户退款 + function fnCancelOrder(num: number) { + let data = { + vendorOrderID: props.item.vendorOrderID, + vendorID: props.item.vendorID, + acceptIt: Boolean(num), + reason: '理由暂无' + } + // let data = { + // afsOrderID: props.item.afsOrderID, + // vendorID: props.item.vendorID, + // approveType: num, + // reason: '理由暂无' + // } + // 拒绝退款 + if (num == 0) { + uni.jxConfirm({ + title: '提示', + content: '是否拒绝用户取消该订单', + success: async () => { + let res = await order.agree_or_refuse_cancel(data) + // let res = await order.agree_orRefuse_refund(data) + if (res.code == 0) { + toast('拒绝成功', 1) + store.commit('serveInfo/setUpdateOrder', Date.now()) + } else { + toast('决绝失败', 2) + } + } + }) + } + + // 同意退款 + if (num == 1) { + uni.jxConfirm({ + title: '提示', + content: '是否同意用户取消该订单', + success: async () => { + let res = await order.agree_or_refuse_cancel(data) + // let res = await order.agree_orRefuse_refund(data) + if (res.code == 0) { + toast('同意成功', 1) + store.commit('serveInfo/setUpdateOrder', Date.now()) + } else { + toast('同意失败', 2) + } + } + }) + } + } + + + /************************************************* + * 骑手申请取消 + */ + function fnCancelDeliver(num: number) { + let data = { + vendorOrderID: props.item.vendorOrderID, + vendorID: props.item.vendorID, + acceptIt: Boolean(num), + reason: '理由暂无' + } + // + if (num == 0) { + uni.jxConfirm({ + title: '提示', + content: '拒绝后只能由该配送员完成本订单', + success: async () => { + let res = await order.accept_or_refuse_failed_get_order(data) + if (res.code == 0) { + store.commit('serveInfo/setUpdateOrder', Date.now()) + fnCallNew() + } else { + toast('操作失败', 2) + } + } + }) + } + + if (num == 1) { + uni.jxConfirm({ + title: '提示', + content: '是否同意取消该订单配送', + success: async () => { + let res = await order.accept_or_refuse_failed_get_order(data) + if (res.code == 0) { + store.commit('serveInfo/setUpdateOrder', Date.now()) + fnCallNew() + } else { + toast('操作失败', 2) + } + } + }) + } + } + // 重新召唤骑手 + async function fnCallNew() { + let data = { + vendorOrderID: props.item.vendorOrderID, + vendorID: props.item.vendorID + } + uni.jxConfirm({ + title: '提示', + content: '是否重新召唤骑手进行配送', + success: async () => { + let res = await order.callP_m_courier(data) + if (res.code == 0) { + toast('操作成功') + store.commit('serveInfo/setUpdateOrder', Date.now()) + } else { + toast('操作失败') + } + } + }) + } + + + /************************************************* + * 是否收到退货 + */ + function fnGoodsReturn() { + let data = { + vendorOrderID: props.item.vendorOrderID, + vendorID: props.item.vendorID, + } + uni.jxConfirm({ + title: '提示', + content: '确认已经收到退回的货物', + success: async () => { + let res = await order.confirm_receive_goods(data) + if (res.code == 0) { + toast('操作成功') + store.commit('serveInfo/setUpdateOrder', Date.now()) + } else { + toast('操作失败') + } + } + }) + } + + + return { + fnCancelOrder, // 是否统一用户取消订单 + fnCancelDeliver, // 骑手申请取消 + fnCallNew, // 重新召唤骑手 + fnGoodsReturn, // 是否退回商品 + } +} + +export default abonmrmalFn \ No newline at end of file diff --git a/src/pages/order-manager/childPages/abnormal-order/bottom-component.vue b/src/pages/order-manager/childPages/abnormal-order/bottom-component.vue new file mode 100644 index 0000000..9887e9f --- /dev/null +++ b/src/pages/order-manager/childPages/abnormal-order/bottom-component.vue @@ -0,0 +1,124 @@ + + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/after-sales-order/after-sales-order.scss b/src/pages/order-manager/childPages/after-sales-order/after-sales-order.scss new file mode 100644 index 0000000..d25c458 --- /dev/null +++ b/src/pages/order-manager/childPages/after-sales-order/after-sales-order.scss @@ -0,0 +1,199 @@ +%globalStyle { + border-bottom: 2rpx dashed #e7e7e7; + padding: 15rpx; +} + +.position-relative { + position: relative; +} + +.after-sales-root { + background-color: #fff; + + .top-title { + @extend %globalStyle; + border-bottom: 6rpx dashed #e7e7e7; + display: flex; + justify-content: space-between; + font-size: 30rpx; + padding: 25rpx 15rpx; + + .order { + color: #000; + } + + .success { + color: $jx-primary; + } + + .warring { + color: $jx-warring; + } + } + + .platform { + display: flex; + align-items: center; + @extend %globalStyle; + + .brand { + display: inline-block; + width: 40rpx; + height: 40rpx; + flex-shrink: 0; + background-size: 100%; + background-repeat: no-repeat; + border-radius: 15rpx; + } + + .orderSeq{ + color: #999; + } + + .num { + font-size: 30rpx; + color: #999; + margin-left: 15rpx; + } + } + + .detaile-text { + @extend %globalStyle; + color: $jx-warring; + background-image: linear-gradient(90deg, #fffefd, #fceceb); + } + + .after-text { + @extend %globalStyle; + font-size: 34rpx; + color: #666; + + .mode { + font-weight: bold; + } + } + + .created-time { + @extend %globalStyle; + font-size: 32rpx; + color: #999; + } + + .shopping-count { + @extend %globalStyle; + font-size: 32rpx; + color: #999; + } + + .detail-btn { + box-sizing: border-box; + padding: 20rpx; + margin: 15rpx; + text-align: center; + color: #fff; + background-image: linear-gradient(135deg, #4eb331, #85c972); + border-radius: 10rpx; + } + + .tips-text { + text-align: center; + color: #f72a6c; + + text { + display: inline-block; + padding: 15rpx; + } + } + + .operation-btn { + @extend %globalStyle; + + .text { + color: #f72a6c; + font-size: 24rpx; + width: 100%; + } + + .btn-root { + display: flex; + justify-content: space-between; + box-sizing: border-box; + + .reject, + .resolve { + width: 100%; + padding: 20rpx; + text-align: center; + border-radius: 10rpx; + margin-top: 15rpx; + color: #fff; + } + + .reject { + margin-right: 15rpx; + background-image: linear-gradient(135deg, #85c972, $jx-primary); + } + + .resolve { + margin-left: 15rpx; + background-image: linear-gradient(135deg, #ff6a20, #ec903f); + } + } + } + + .confirm-goods { + @extend %globalStyle; + + .text { + padding: 20rpx; + text-align: center; + background-image: linear-gradient(135deg, #f72a6c, #f16692); + border-radius: 10rpx; + color: #fff; + } + } +} + +.reson-root { + padding: 15rpx; + background-color: #fff; + width: 600rpx; + border-radius: 10rpx; + + .title { + text-align: center; + } + + .textarea { + box-sizing: border-box; + margin: 15rpx 0; + width: 100%; + max-height: 200rpx; + background-color: rgb(243, 243, 243); + padding: 10rpx; + border-radius: 10rpx; + } + + .btn-root { + width: 100%; + display: flex; + justify-content: space-between; + border-top: 1rpx solid rgb(223, 223, 223); + + .cancal, + .confirm { + width: 100%; + padding: 20rpx 0 10rpx 0; + text-align: center; + + } + + .cancal { + color: #666; + } + + .confirm { + border-left: 1rpx solid rgb(223, 223, 223); + } + } +} \ No newline at end of file diff --git a/src/pages/order-manager/childPages/after-sales-order/after-sales-order.vue b/src/pages/order-manager/childPages/after-sales-order/after-sales-order.vue new file mode 100644 index 0000000..e348e4c --- /dev/null +++ b/src/pages/order-manager/childPages/after-sales-order/after-sales-order.vue @@ -0,0 +1,285 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/completed/completed.vue b/src/pages/order-manager/childPages/completed/completed.vue new file mode 100644 index 0000000..13039c8 --- /dev/null +++ b/src/pages/order-manager/childPages/completed/completed.vue @@ -0,0 +1,120 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/component/orderListTop.vue b/src/pages/order-manager/childPages/component/orderListTop.vue new file mode 100644 index 0000000..269a5e3 --- /dev/null +++ b/src/pages/order-manager/childPages/component/orderListTop.vue @@ -0,0 +1,514 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/component/orderMoney.vue b/src/pages/order-manager/childPages/component/orderMoney.vue new file mode 100644 index 0000000..ce1da99 --- /dev/null +++ b/src/pages/order-manager/childPages/component/orderMoney.vue @@ -0,0 +1,79 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/jx-tab/jx-tab.scss b/src/pages/order-manager/childPages/jx-tab/jx-tab.scss new file mode 100644 index 0000000..ffd5585 --- /dev/null +++ b/src/pages/order-manager/childPages/jx-tab/jx-tab.scss @@ -0,0 +1,45 @@ +.jx-tabs { + border-top: 1rpx solid #f8f8f8; + background-color: #fff; + border-bottom: 1rpx solid rgb(214, 214, 214); +} + +.tab-scroll { + white-space: nowrap; + width: 100%; + height: 95rpx; + line-height: 94rpx; +} + + +.scroll-item { + position: relative; + display: inline-block; + width: 150rpx; + text-align: center; + text-align: center; + font-size: 33rpx; + transition: all 0.2s; + + .badge { + position: absolute; + right: -5rpx; + top: 4rpx; + border-radius: 100rpx 100rpx 100rpx 0; + font-size: 28rpx; + min-width: 40rpx; + min-height: 40rpx; + padding: 3rpx; + box-sizing: border-box; + text-align: center; + line-height: 40rpx; + color: #fff; + background-color: #f60d58; + } +} + +.jxTabsActive { + color: #4eb331; + font-weight: bold; + font-size: 37rpx; +} \ No newline at end of file diff --git a/src/pages/order-manager/childPages/jx-tab/jx-tab.ts b/src/pages/order-manager/childPages/jx-tab/jx-tab.ts new file mode 100644 index 0000000..c6a4706 --- /dev/null +++ b/src/pages/order-manager/childPages/jx-tab/jx-tab.ts @@ -0,0 +1,161 @@ +/** + * 订单木块方法 + */ +import { Ref, ref } from "vue"; +import { getStorage } from '@/utils/storage' +import { onShow } from "@dcloudio/uni-app"; +import order from '@/api/https/order' + +function tabFn() { + onShow(async () => { + await getOrderCount() + }) + + + /** + * tab 菜单栏数据 + */ + const currentStatus: Ref = ref(2); + interface OrderStatusType { + id: number; + status: number | Array; + name: string; + count: number; + } + const orderStatus = ref([ + { + id: 1, + status: [3], + name: "待接单", + count: 0, + }, + { + id: 2, + status: [10], + name: "待拣货", + count: 0, + }, + { + id: 3, + status: [15], + name: "待配送", + count: 0, + }, + { + id: 4, + status: [20], + name: "配送中", + count: 0, + }, + { + id: 5, + status: [5, 10, 15, 20, 17, 18, 22], + name: "异常单", + count: 0, + }, + { + id: 6, + status: [155, 160, 165, 167, 180, 190], + name: "售后单", + count: 0, + }, + { + id: 7, + status: [110, 115, 120], + name: "已完成", + count: 0, + }, + ]); + + + /** + * tab 点击事件 + */ + const scrollLeft: Ref = ref(0); // 滚动到左边距离 + const record: Ref = ref(1); // 记录值 + function clickTab(id: number, recordID: number, e: AnyObject) { + currentStatus.value = id; + // 判断左右滑动 + let { offsetLeft } = e.target; + if (id > recordID) { + scrollLeft.value = offsetLeft - 75; + } else { + scrollLeft.value = offsetLeft - 75 * 3; + } + record.value = id; // 赋值记录纸 + // 更新条数 + getOrderCount() + } + + + /** + * 请求订单数量信息 + */ + async function getOrderCount() { + let orderData = { + storeID: getStorage('storeID'), + lastHours: new Date().getHours() * 1 + 48 + } + // 订单数量 + let orderCount = await order.Get_store_rder_count_info(orderData) + // 售后单量 + let afsCount = await order.Get_store_afs_order_countinfo(orderData) + if (orderCount.code == 0 && afsCount.code == 0) { + // 没有数据默认一个空数组 + let data = orderCount.data || [] + let data2 = afsCount.data || [] + + // 判断显示条数 + if (data.length > 0) { + // 3 待接单 + orderStatus.value[0].count = data.filter((item: any) => item.status === 3 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 3 && item.lockStatus === 0)[0].count : 0 + orderStatus.value[0].count += data.filter((item: any) => item.status === 3 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 3 && item.lockStatus === 0)[0].count : 0 + // 10 待拣货 + orderStatus.value[1].count = data.filter((item: any) => item.status === 10 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 10 && item.lockStatus === 0)[0].count : 0 + orderStatus.value[1].count += data.filter((item: any) => item.status === 10 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 10 && item.lockStatus === 0)[0].count : 0 + // 15 待配送 + orderStatus.value[2].count = data.filter((item: any) => item.status === 15 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 15 && item.lockStatus === 0)[0].count : 0 + orderStatus.value[2].count += data.filter((item: any) => item.status === 15 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 15 && item.lockStatus === -20)[0].count : 0 + // 20 配送中 + orderStatus.value[3].count = data.filter((item: any) => item.status === 20 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 20 && item.lockStatus === 0)[0].count : 0 + orderStatus.value[3].count += data.filter((item: any) => item.status === 20 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 20 && item.lockStatus === -20)[0].count : 0 + // 17 异常单 + orderStatus.value[4].count = data.filter((item: any) => item.status === 17 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 17 && item.lockStatus === 0)[0].count : 0 + // 18 已完成 + orderStatus.value[4].count += data.filter((item: any) => item.status === 18 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 18 && item.lockStatus === 0)[0].count : 0 + // 22 已完成 + orderStatus.value[4].count += data.filter((item: any) => item.status === 22 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 22 && item.lockStatus === 0)[0].count : 0 + orderStatus.value[4].count += data.filter((item: any) => item.lockStatus === -5 && item.status < 100).length > 0 ? data.filter((item: any) => item.lockStatus === -5 && item.status < 100)[0].count : 0 + } else { + orderStatus.value[0].count = 0 + orderStatus.value[1].count = 0 + orderStatus.value[2].count = 0 + orderStatus.value[3].count = 0 + orderStatus.value[4].count = 0 + } + // 售后单 + if (data2.length > 0) { + orderStatus.value[5].count = data2.find((item: any) => item.status === 155) ? data2.find((item: any) => item.status === 155).count : 0 + orderStatus.value[5].count += data2.find((item: any) => item.status === 165) ? data2.find((item: any) => item.status === 155).count : 0 + } else { + orderStatus.value[5].count = 0 + } + } + } + + + /** + * 导出数据 + */ + return { + currentStatus, // 高亮初始值 + orderStatus, // tab 菜单栏数据 + scrollLeft, // 滚动到左边距离 + record, // 记录值 + clickTab, // tab 点击事件 + getOrderCount, // 获取数据 + } +} + + +export default tabFn \ No newline at end of file diff --git a/src/pages/order-manager/childPages/jx-tab/jx-tab.vue b/src/pages/order-manager/childPages/jx-tab/jx-tab.vue new file mode 100644 index 0000000..c31389f --- /dev/null +++ b/src/pages/order-manager/childPages/jx-tab/jx-tab.vue @@ -0,0 +1,51 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/order-filter/order-filter.scss b/src/pages/order-manager/childPages/order-filter/order-filter.scss new file mode 100644 index 0000000..b91f9e9 --- /dev/null +++ b/src/pages/order-manager/childPages/order-filter/order-filter.scss @@ -0,0 +1,56 @@ +.switch-filter { + background-color: #fff; + + .condition { + text-align: center; + color: #999999; + } + + box-sizing: border-box; + border-radius: 10rpx; + padding: 20rpx 40rpx 10rpx 40rpx; + + .item { + display: flex; + margin-top: 35rpx; + + .root { + display: flex; + align-items: center; + + text { + padding: 0 10rpx; + } + } + + .title { + color: #999999; + } + + .value { + padding: 5rpx 15rpx; + border: 1rpx solid #bebebe; + border-radius: 10rpx; + } + } + + .btnRoot { + display: flex; + justify-content: space-between; + margin-top: 30rpx; + border-top: 1rpx solid #999999; + + .cancel, + .confirm { + color: #696969; + text-align: center; + width: 100%; + padding: 20rpx; + } + + .confirm { + color: #000; + border-left: 1rpx solid #999999; + } + } +} \ No newline at end of file diff --git a/src/pages/order-manager/childPages/order-filter/order-filter.vue b/src/pages/order-manager/childPages/order-filter/order-filter.vue new file mode 100644 index 0000000..e60d3fa --- /dev/null +++ b/src/pages/order-manager/childPages/order-filter/order-filter.vue @@ -0,0 +1,273 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/pending-distribution/pending-distribution.vue b/src/pages/order-manager/childPages/pending-distribution/pending-distribution.vue new file mode 100644 index 0000000..af6415b --- /dev/null +++ b/src/pages/order-manager/childPages/pending-distribution/pending-distribution.vue @@ -0,0 +1,325 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/pending-order/pending-order.vue b/src/pages/order-manager/childPages/pending-order/pending-order.vue new file mode 100644 index 0000000..fb8c5e2 --- /dev/null +++ b/src/pages/order-manager/childPages/pending-order/pending-order.vue @@ -0,0 +1,107 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/childPages/pending-picking/pending-picking.vue b/src/pages/order-manager/childPages/pending-picking/pending-picking.vue new file mode 100644 index 0000000..098223e --- /dev/null +++ b/src/pages/order-manager/childPages/pending-picking/pending-picking.vue @@ -0,0 +1,119 @@ + + + + + \ No newline at end of file diff --git a/src/pages/order-manager/main.ts b/src/pages/order-manager/main.ts new file mode 100644 index 0000000..de9145b --- /dev/null +++ b/src/pages/order-manager/main.ts @@ -0,0 +1,407 @@ +import useGlobalFunc from '@/composables/useGlobalFunc' +import { store } from '@/store' +import { getStorage } from '@/utils/storage' +import toast from '@/utils/toast' +import { timeFormatD, jx_trembling } from '@/utils/tools' +import { onLoad, onShow } from '@dcloudio/uni-app' +import { watch, ref, onBeforeUnmount } from 'vue' +import order from '@/api/https/order' +// import merchant from '@/api/https/merchant' +/** + * 订单管理方法 + * @author zhangshuwie <2966211270@qq.com> + * @param * + * @return 模板使用数据与方法,详情内容请查看return + */ +function orderInfoFn() { + const { isTrades } = useGlobalFunc() + /** + * 公共复位函数 + */ + function reset() { + orderDataList.value = [] + page.value = 1 + totalCount.value = 0 + } + + + + /** + * tab单击事件 + * @param target 点击对应tab获取到的信息 + */ + const status = ref>([10]) // 默认显示待拣货 + const orderState = ref(2) // 默认显示待拣货 + const orderStateInfo = ref() + async function jxTabClick(target: AnyObject) { + orderStateInfo.value = target + reset() + uni.removeTabBarBadge({ index: 0 }) + keyword.value = '' + // 列表展示判断条件 + orderState.value = target.id + // 请求数据订单状态 + status.value = target.status + // 请求数据 + if (target.id == 6) { + // 获取售后单 + if (orderStateInfo.value.count) { + allData.value.fromTime = timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 2)) + allData.value.afsStatus = '155' + } + await getAfsOrders() + } else { + await getOrderAllInfo() + } + } + + + /** + * 下拉刷新 + */ + let refresherrefreshTimer: any = null + const triggered = ref(false) + function refresherrefresh() { + uni.removeTabBarBadge({ index: 0 }) + triggered.value = true + clearTimeout(refresherrefreshTimer) + refresherrefreshTimer = setTimeout(async () => { + store.commit('storeInfo/jxLoadingFn', true) + reset() + refreshTab() + if (orderState.value == 5) { + totalCount.value = 0 + } + if (orderState.value == 6) { + await getAfsOrders() + } else { + await getOrderAllInfo() + } + triggered.value = false + store.commit('storeInfo/jxLoadingFn', false) + }, 500) + } + + /** + * 页面触底 + */ + const isLoad = ref(false) + async function scrolltolower() { + uni.removeTabBarBadge({ index: 0 }) + page.value++ + if (pageSize.value * (page.value - 1) > totalCount.value || totalCount.value < pageSize.value) { + isLoad.value = false + } else { + if (isLoad.value) return + if (orderState.value == 7) { + await getOrderAllInfo() + } else { + await getAfsOrders() + } + } + } + + + /** + * 获取订单详情数据 + */ + type emitType = { + fromTime: string + toTime: string + vendorID: number | string + waybillVendorID?: number | string + isDateFinish?: boolean + appealTypes?: number | string + afsStatus?: number | string + } + let oldStoreID: any = 0 + + + /************************************************* + * 门店休息情况 + */ + const isRest = ref(true) + const isStatu = ref(false) + onShow(async () => { + if (!store.state.storeInfo.allStoreInfo.id) { + // console.log('ZSW-没有门店信息开始获取门店信息'); + await store.dispatch('storeInfo/getOneStore',getStorage("storeID")) + } + if (oldStoreID != getStorage('storeID') && oldStoreID != 0) { + reset() + triggered.value = true + } + oldStoreID = getStorage('storeID') + isRest.value = isTrades(new Date()) // 门店是否接受预订单 + let storeInfo = store.state.storeInfo.allStoreInfo + isStatu.value = storeInfo.status == 1 ? true : false + uni.removeTabBarBadge({ index: 0 }) + }) + + onLoad(async (params) => { + store.commit('storeInfo/jxLoadingFn', true) + // 请求数据 + reset() + await getOrderAllInfo() + store.commit('storeInfo/jxLoadingFn', false) + }) + const pageSize = ref(33) // 每一页条数 + const page = ref(1) // 第多少条 + const orderDataList = ref([]) // 订单数据 + const totalCount = ref(0) // 订单条数 + const allData = ref({ + fromTime: timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 7)), + toTime: timeFormatD(+new Date()), + vendorID: '', + waybillVendorID: '', + isDateFinish: false, + appealTypes: '', + afsStatus: '' + }) // 已完成数据筛选 + async function getOrderAllInfo() { + isLoad.value = true + let time1 = timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 7)) + let time2 = timeFormatD(+new Date()) + // 待接单、待检货、待配送、配送中、异常单、已完成 + let data: any = { + fromDate: time1, + toDate: time2, + storeIDs: JSON.stringify([getStorage('storeID')]), + statuss: JSON.stringify(status.value), + offset: pageSize.value * (page.value - 1), + pageSize: pageSize.value, + isJxFirst: true + } + if (orderState.value == 7) { + data = { + fromDate: allData.value.fromTime ? allData.value.fromTime : time1, + toDate: allData.value.toTime ? allData.value.toTime : time2, + storeIDs: JSON.stringify([getStorage('storeID')]), + statuss: JSON.stringify(status.value), + offset: pageSize.value * (page.value - 1), + pageSize: pageSize.value, + isDateFinish: allData.value.isDateFinish, + vendorIDs: `[${allData.value.vendorID}]`, + waybillVendorIDs: `[${allData.value.waybillVendorID}]`, + isJxFirst: true, + keyword: keyword.value + } + } + + let res = await order.get_orders(keyFilter(data)) + if (res.code == 0) { + if (page.value <= 1) { + reset() + } + let data: Array = res.data.data || [] + if (data.length == 0) toast('暂无该类型订单') + orderDataList.value = orderDataList.value.concat(data) + totalCount.value = res.data.totalCount + } else { + reset() + totalCount.value = 0 + + } + isLoad.value = false + } + + + /************************************************* + * 过滤对象空字段 + */ + function keyFilter(obj: AnyObject) { + for (let key in obj) { + // if ((obj[key] == "" || obj[key] == [""] || obj[key] == '[-1]')) { + if ((obj[key] == "" || obj[key] == '[-1]')) { + delete obj[key] + } + } + return obj + } + + + /************************************************* + * 获取异常单 + */ + async function getAfsOrders() { + isLoad.value = true + // 待接单、待捡货、待配送、配送中、异常单、已完成 + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + fromTime: `${allData.value.fromTime} 00:00:00`, + toTime: `${allData.value.toTime} 23:59:59`, + pageSize: pageSize.value, + offset: pageSize.value * (page.value - 1), + vendorIDs: `[${allData.value.vendorID}]`, + appealTypes: `[${allData.value.appealTypes}]`, + statuss: `[${allData.value.afsStatus}]`, + isDetail: true, + keyword: keyword.value + } + let res = await order.get_afs_orders(keyFilter(data)) + if (res.code == 0) { + if (page.value <= 1) { + reset() + } + let data: Array = res.data.data || [] + if (data.length == 0) toast("暂无售后订单") + orderDataList.value = orderDataList.value.concat(res.data.data) + totalCount.value = res.data.totalCount + } else { + reset() + totalCount.value = 0 + } + isLoad.value = false + } + + + /** + * 刷新导航栏 + */ + const tabInfo = ref(null) + function refreshTab() { + tabInfo.value.getOrderCount() + } + + + /** + * 输入确认按钮 + */ + const keyword = ref('') + async function searchStore(keywords: string) { + keyword.value = keywords + reset() + if (orderState.value == 7) { + await getOrderAllInfo() + } else { + await getAfsOrders() + } + } + + + /** + * 输入框输入值变化 + */ + let trembling = jx_trembling(getOrderAllInfo, 800) + let trembling2 = jx_trembling(getAfsOrders, 800) + async function changeIpt(keywords: string) { + keyword.value = keywords + reset() + if (orderState.value == 7) { + trembling() + } else { + trembling2() + } + } + + + /** + * 清空输入框 + */ + async function clearIpt() { + keyword.value = '' + reset() + if (orderState.value == 7) { + await getOrderAllInfo() + } else { + await getAfsOrders() + } + } + + + /** + * 已完成和售后单筛选 + */ + const active = ref(0) + async function filterData(data: emitType) { + let ruler = (+new Date() - +new Date(data.fromTime)) / 1000 / 60 / 60 / 24 + if (orderState.value != 7 && ruler > 59) { + return toast('售后查询不能超过60天') + } + if (orderState.value == 7 && ruler > 180) { + return toast('最大查询天数为180天') + } + allData.value = data + reset() + if (orderState.value == 7) { + await getOrderAllInfo() + } else { + await getAfsOrders() + } + } + + /** + * 筛选条件实例对象 + */ + const orderFilterRef = ref(null) + + /** + * 监听新订单刷新页面 + */ + watch(() => store.state.serveInfo.updateOrder, async () => { + reset() + refreshTab() + if (orderState.value == 6) { + await getAfsOrders() + } else { + trembling() + } + }) + + + + /** + * 动态计算scorll-view 高度 + */ + const scorllHeight = ref('94rpx') + watch(() => orderState.value, (nweVal) => { + let arr: Array = [1, 2, 4, 5] + if (arr.includes(nweVal)) { + scorllHeight.value = '100rpx' + } else { + scorllHeight.value = '190rpx' + } + }) + + + /************************************************* + * 配送状态筛选 + */ + function distributionStatu(type: number) { + active.value = type + } + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + clearTimeout(refresherrefreshTimer) + }) + + + return { + jxTabClick, // 导航栏按钮 + orderDataList, // 订单数据 + totalCount, // 订单条数 + orderState, // 订单列表判断条件 + orderStateInfo, // 订单列表信息 + tabInfo, // 导航栏实例 + searchStore, // 输入库条件筛选 + keyword, // 输入库内容 + changeIpt, // 输入款输入变化 + clearIpt, // 清空输入框 + scorllHeight, // 动态计算scorll-view高度 + active, // 待配送筛选高亮 + orderFilterRef, // 筛选条件实例对象 + filterData, // 筛选条件数据 + refresherrefresh, // 下拉刷新 + triggered, // 下拉加载 + scrolltolower, // 页面触底 + isLoad, // 触底加载 + distributionStatu, // 配送筛选 + isRest, // 是否显示休息状态 + isStatu, // 门店是否在营业 + } +} + +export default orderInfoFn \ No newline at end of file diff --git a/src/pages/order-manager/main.vue b/src/pages/order-manager/main.vue new file mode 100644 index 0000000..6f7c294 --- /dev/null +++ b/src/pages/order-manager/main.vue @@ -0,0 +1,439 @@ + + + + + + \ No newline at end of file diff --git a/src/static/agreement/privacy.html b/src/static/agreement/privacy.html new file mode 100644 index 0000000..32f6aca --- /dev/null +++ b/src/static/agreement/privacy.html @@ -0,0 +1,103 @@ + + + + + + + 京西菜市用户隐私协议 + + + +
+ +
京西菜市用户隐私协议
+
+
+京西菜市尊重和保护用户的隐私。本隐私政策将告诉您我们如何收集和使用有关您的信息,以及我们如何保护这些信息的安全。您成为京西菜市用户前务必仔细阅读本隐私条款并同意所有隐私条款。本隐私政策条款在您注册成为京西菜市用户后立即生效,并对您及京西菜市产生约束力。
+
+一、我们可能收集的用户信息
+
+我们提供服务时,可能会收集、储存和使用下列与您有关的信息。如果您不提供相关信息,可能无法注册成为我们的用户或无法享受我们提供的某些服务。
+
+1、您提供的信息
+
+•  您在注册账户或使用我们的服务时,向我们提供的相关个人信息,例如电话号码,昵称。
+
+2、我们获取的您的信息。 您使用服务时我们可能收集如下信息:
+
+• 设备信息:移动设备的设备识别码、IP地址;
+
+• 位置信息:手机等设备返回的当前位置信息。
+
+• 地址信息,指您在微信,支付宝等平台存储的常用收件地址信息。
+
+• 行为信息,指您在APP不同页面停留时间,关注商品, 使用APP直到退出时的行为轨迹。
+
+
+二、我们可能如何使用用户信息
+
+1、登录验证和防作弊监测;
+
+2、推荐附近店铺;
+
+3、分析使用我们软件的手机类型,地域;
+
+4、协助选择收货信息;
+
+5、优化APP商品展示。
+
+为了让您有更好的体验、改善我们的服务或您同意的其他用途,在符合相关法律法规的前提下,我们可能将通过以上描述的某一项服务所收集的信息,以汇集信息或者个性化的方式,用于我们京西菜市的其他服务。
+
+三、我们可能与第三方共享的用户信息
+
+在下列情况下,我们可能会共享您的个人信息:
+
+1、我们店铺或骑手在完成定单过程中,无法通过您收件预留的信息与您联系,我们将您的注册电话或其他联系方式分享给店铺或骑手。
+
+2、您在京西菜市活动中的存在刷补贴等违约行为,被我们发现或店铺发起申诉时,我们会将您的注册信息分享给对应的负责人;
+
+3、应行政、司法部门的要求向该等机构提供您的用户信息;
+
+4、您通过京西菜市平台向第三方合作机构申请相关产品服务时,我们将根据您的授权向第三方提供您的用户信息;
+
+5、我们以及我们的关联公司,可能将您的个人信息与我们的关联公司、合作伙伴及第三方服务供应商、承包商及代理(例如代表我们发出短信或推送通知的通讯服务提供商、为我们提供位置数据的地图服务供应商)分享(他们可能并非位于您所在的法域),为了我们向您提供或改善我们的服务;
+
+• 随着我们业务的持续发展,我们以及我们的关联公司有可能进行合并、收购、资产转让或类似的交易,您的个人信息有可能作为此类交易的一部分而被转移; 
+• 依据法律要求必须向第三方提供您的用户信息的情形;
+
+四、我们如何保护用户信息
+
+我们使用各种安全技术和程序,以防信息的丢失、不当使用、未经授权阅览或披露。但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全。您需要了解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。
+
+五、账户注销
+
+当用户需要注销本账号时,可联系 京西菜市 客服人员进行验证注销。
+
+六、隐私政策的修改
+
+由于法律法规的变更,以及为了与互联网的新发展和可能的发展趋势保持同步,我们可能会不定时修改本政策。因此,我们保留自行决定实施此类修改的权利,如该等修订造成您在本《隐私政策》下权利的实质减少,我们将在修订生效前通过在主页上显著位置提示或向您推送通知或以其他方式通知您。在该种情况下,若您继续使用我们的服务,即表示同意受经修订的本《隐私政策》的约束。
+      
+		
+
+ + \ No newline at end of file diff --git a/src/static/agreement/service.html b/src/static/agreement/service.html new file mode 100644 index 0000000..f423632 --- /dev/null +++ b/src/static/agreement/service.html @@ -0,0 +1,211 @@ + + + + + + + 京西菜市用户协议 + + + +
+
京西菜市用户协议
+
+
+京西菜市帐号使用协议
+欢迎您注册、使用京西菜市帐号!
+
+本协议系您与成都若溪科技有限公司就京西菜市帐号的注册和使用而订立的。成都若溪科技有限公司(如下简称“京西菜市”)在此特别提醒您认真阅读、充分理解本协议各条款,特别是涉及服务费用条款,免除或者限制京西菜市责任的条款,对您的权利限制条款,争议解决和法律适用条款等,此类条款将以加粗的形式提示您注意。请您审慎阅读并选择接受或不接受本协议(限制民事行为能力人应在监护人或法定代理人陪同下阅读)。除非您接受本协议所有条款,否则您无权注册、使用京西菜市帐号。您的注册和使用京西菜市帐号行为将视为您已充分理解本协议(即本协议及后续更新版本或开通或使用某项服务的单项协议),并同意接受本协议各项条款的约束。
+
+一、 关于京西菜市帐号
+1.京西菜市帐号系由京西菜市所有的用于识别您身份的标识。帐号的所有权属于京西菜市,您作为初始申请注册人仅拥有您所注册帐号的使用权。
+
+2.您可通过京西菜市帐号享受京西菜市及关联公司提供的单项服务包括但不限于京西菜市小程序服务,您亦可通过京西菜市帐号向京西菜市购买品鉴券以便您享受京西菜市及关联公司的各种产品和增值服务。
+
+3. 本服务条款的效力范围及于京西菜市及关联公司的一切产品和服务,您在享受任何单项服务时,应当受本服务条款的约束。当您使用京西菜市各单项服务时,您同意以单项服务要求的方式同意该单项服务的服务条款以及京西菜市在该单项服务中发出的各类公告(下列简称为“单项条款”),在此情况下单项条款与本服务条款同时对您产生效力。若单项条款与本服务条款存在同类条款的冲突,则在单项条款约束范围内应以单项条款为准。
+
+二、帐号使用规则
+1.注册帐号
+
+1.1 您确认,在您开始注册程序使用京西菜市服务前,您应当具备中华人民共和国法律规定的与您行为相适应的民事行为能力。若您不具备前述与您行为相适应的民事行为能力,则您及您的监护人应依照法律规定承担因此而导致的一切后果。
+
+1.2 您应提供及时、详尽及准确的个人资料,并不断更新注册资料,符合及时、详尽、准确的要求。您保证在注册时所提交的所有资料(包括但不限于手机号码、生日等)真实、准确、合法、有效且系您本人的资料。如果因注册信息不真实或更新不及时而引发的相关问题, 京西菜市不负任何责任。您可以通过京西菜市帐号设置页面查询、更正您的信息,您应当通过真实身份信息认证注册帐号,且您提交的帐号名称、头像和简介等注册信息中不得出现违法和不良信息,经京西菜市审核,如存在上述情况,京西菜市将不予注册;同时,在注册后,如发现您以虚假信息骗取帐号名称注册,或您的帐号头像、简介等注册信息存在违法和不良信息的,京西菜市有权不经通知单方采取限期改正、暂停使用、终止帐号等措施。当您按照注册页面提示填写信息、阅读并同意本协议条款且完成全部注册程序后,您可获得京西菜市帐号并成为京西菜市用户。
+
+
+2.帐号使用
+
+2.1 您应对您帐号项下的所有行为结果负责。
+
+2.2 由于您的京西菜市帐号关联您的个人信息及京西菜市商业信息,您的京西菜市帐号仅限您本人使用。未经京西菜市同意,您直接或间接授权第三方使用您京西菜市帐号或获取您帐号项下信息的行为无效。如京西菜市根据京西菜市各平台规则中约定的违约认定程序及标准判断您京西菜市帐号的使用可能危及您的帐号安全及或京西菜市信息安全的,京西菜市可拒绝提供相应服务或终止本协议。
+
+2.3 若您选择第三方帐号登陆京西菜市的服务,第三方帐号将与您的京西菜市帐号相关联,京西菜市将根据您授权第三方提供的信息而使用您的信息(如头像)。您后续使用该京西菜市帐号的行为受本协议约束。
+
+
+3.帐号保管和找回
+
+3.1 京西菜市帐号包括帐号名称和手机号,您可使用设置的帐号名称(手机号)登录,您应妥善保管好您的帐号,因您个人原因导致的帐号信息遗失,如需找回京西菜市帐号信息,请按照京西菜市帐号找回流程提供相应的信息,并确保提供的信息合法真实有效,若提供的信息不符合要求,无法通过京西菜市安全验证,京西菜市有权拒绝提供帐号找回服务;
+
+3.2 如果您当前使用的京西菜市帐号并非您初始申请注册的或通过京西菜市提供的其他途径获得的,但您却知悉该京西菜市帐号当前的手机号,您不得用该京西菜市帐号登录或进行任何操作,并请您在第一时间通知京西菜市或者该京西菜市帐号的初始申请注册人。
+
+
+4.帐号转让
+
+4.1 您可在本协议约定的范围内使用京西菜市帐号,您不得恶意注册京西菜市帐号,不得赠与、借用、租用、有偿或无偿转让或售卖京西菜市帐号或者以其他方式许可非初始申请注册人使用京西菜市帐号,京西菜市有权对上述行为进行独立判断并处理,您应当自行承担由此产生的任何责任,同时京西菜市保留追究上述行为人法律责任的权利。且由此产生的一切责任均由您承担。
+
+4.2 京西菜市有权根据法律法规对您采取以下措施:
+
+4.2.1 如您违反法律法规、京西菜市各单项条款或业务规则的规定,京西菜市有权进行独立判断并随时采取限期改正、暂停使用、终止您对京西菜市帐号的使用,且根据实际情况决定是否恢复使用。
+
+4.2.2 如果京西菜市发现您并非该帐号初始申请注册人,京西菜市有权在未经通知的情况下终止您使用该帐号。
+
+4.2.3 京西菜市按照本规则或相关法律法规,限期改正、暂停使用或终止您对京西菜市帐号的使用,而由此给您带来的损失(包括但不限于通信中断,用户资料和相关数据等的清空等),由您自行承担。
+
+
+5.帐号回收
+
+5.1为了防止资源占用,如您连续24个月未使用您的京西菜市帐号或未通过京西菜市认可的其他方式登录过您的帐号,京西菜市有权对该帐号进行注销,您将不能再通过该帐号登录或使用相关服务。如该帐号有关联的待处理交易或余额等,京西菜市会在合理范围内协助您处理,请您按照京西菜市提示的方式进行操作。
+
+
+6. 帐号安全
+
+6.1 您的帐号为您自行设置并由您保管,京西菜市任何时候均不会主动要求您提供您的帐号手机号。建议您采取特定措施保护您的帐号安全,包括但不限于安装防病毒木马软件等措施。
+
+6.2 京西菜市帐号因您主动泄露或因您遭受他人攻击、诈骗等行为导致的损失及后果,京西菜市并不承担责任,您应通过司法、行政等救济途径向侵权行为人追偿。
+
+
+7.帐号注销
+
+7.1 在需要终止使用京西菜市帐号服务时,符合以下条件的,您可以申请注销您的京西菜市帐号。
+
+7.1.1 您仅能申请注销您本人的帐号,并依照京西菜市的流程进行注销;
+
+7.1.2 您仍应对您在注销帐号前且使用京西菜市服务期间的行为承担相应责任。
+
+7.1.3 您应当知晓您的帐号终止意味着您的用户内容将从我们的活动数据库中删除。
+
+
+三、用户权利和义务
+1.您在使用京西菜市服务时,必须遵守《网络安全法》、《互联网新闻信息服务管理规定》等中华人民共和国相关法律法规的规定,您应同意将不会利用本服务进行任何违法或不正当的活动,包括但不限于下列行为:
+
+1.1上载、展示、张贴、传播或以其他方式传送含有下列内容之一的信息:
+
+1.1.1 反对宪法所确定的基本原则的;
+1.1.2 危害 国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;
+1.1.3 损害国家荣誉和利益的;
+1.1.4 煽动民族仇恨、民族歧视、破坏民族团结的;
+1.1.5 破坏国家宗教政策,宣扬邪教和封建迷信的;
+1.1.6 散布谣言,扰乱社会秩序,破坏社会稳定的;
+1.1.7 散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;
+1.1.8 侮辱或者诽谤他人,侵害他人合法权利的;
+1.1.9 含有虚假、有害、胁迫、侵害他人隐私、骚扰、侵害、中伤、粗俗、猥亵、或其他道德上令人反感的内容;
+1.1.10 含有中国法律、法规、规章、条例以及任何具有法律效力之规范所限制或禁止的其他内容的;
+1.2 不利用京西菜市服务从事以下活动:
+
+1.2.1 未经允许,进入计算机信息网络或者使用计算机信息网络资源的;
+1.2.2 未经允许,对计算机信息网络功能进行删除、修改或者增加的;
+1.2.3 未经允许,对进入计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加的;
+1.2.4 故意制作、传播计算机病毒等破坏性程序的;
+1.2.5 进行任何诸如发布广告、销售商品的商业行为,或者进行任何非法的侵害京西菜市利益的行为,如贩卖可币、游戏币、外挂、道具等;
+1.2.6 其他危害计算机信息网络安全的行为。
+2.您违反本协议或相关的服务条款的规定,导致或产生的任何第三方向京西菜市与合作公司、关联公司主张的任何索赔、要求或损失,包括合理的律师费,您同意赔偿京西菜市与合作公司、关联公司,并使之免受损害。同时,京西菜市有权视您的行为性质,采取包括但不限于删除发布信息内容、暂停使用许可、终止服务、限制使用京西菜市帐号、追究法律责任等措施。同时,京西菜市会视司法部门的要求,协助调查。
+
+3.您不得对京西菜市服务任何部分或京西菜市服务之使用或获得,进行复制、拷贝、出售、转售或用于任何其他商业目的。
+
+4.您须对自己在使用京西菜市服务过程中的行为承担法律责任。您承担法律责任的形式包括但不限于:对受到侵害者进行赔偿,以及在京西菜市首先承担了因您的行为导致的行政处罚或侵权损害赔偿责任后,您应给予京西菜市等额的赔偿。
+
+5.在任何情况下,京西菜市都不对您或任何第三方因本协议产生的任何间接性、后果性、惩戒性的、偶然的、特殊或惩罚性的损害赔偿承担责任。
+
+
+四 免责声明
+1.如发生下述情形,京西菜市不承担任何法律责任:
+
+1.1 依据法律规定或相关政府部门的要求提供您的个人信息;
+
+1.2 由于您的使用不当或其他自身原因而导致任何个人信息的泄露;
+
+1.3 任何由于黑客攻击,电脑病毒的侵入,非法内容信息、骚扰信息的屏蔽,政府管制以及其他任何网络、技术、通信线路、信息安全管理措施等原因造成的服务中断、受阻等不能满足您要求的情形;
+
+1.4 因第三方如运营商的通讯线路故障、技术问题、网络、电脑故障、系统不稳定及其他因不可抗力造成的损失的情形;
+
+1.5 使用京西菜市产品、程序及服务可能存在的来自他人匿名或冒名的含有威胁、诽谤、令人反感或非法内容的信息而招致的风险;
+
+1.6 用户之间通过本网站或京西菜市产品、程序及服务与其他用户交往,因受误导或欺骗而导致或可能导致的任何心理、生理上的伤害以及经济上的损失;
+
+1.7 京西菜市服务明文声明,不以明示、默示或以任何形式对京西菜市及其合作公司服务之及时性、安全性、准确性做出担保。
+
+1.8 您在利用京西菜市帐号所发布的任何内容并不代表和反映京西菜市的任何观点或政策,京西菜市对此不承担任何责任。
+
+1.9 在任何情况下,京西菜市均不对任何间接性、后果性、惩罚性、偶然性、特殊性或刑罚性的损害,包括因您使用京西菜市服务而遭受的利润损失,承担责任。尽管本协议中可能含有相悖的规定,我们对您承担的全部责任,无论因何原因或何种行为方式,始终不超过您在注册期内因使用京西菜市服务而支付给京西菜市的费用(如有)。
+
+2. 您可以选择使用您已有的第三方帐号关联京西菜市帐号,京西菜市对于因第三方原因对您造成的损失不承担任何责任。
+
+
+五、知识产权
+1. 您在京西菜市发布的信息不得侵犯任何第三人的知识产权,未经具有相关所有权人之事先书面同意,您不得以任何方式上传、发布、修改、传播或复制任何受著作权保护的材料、商标或属于其他人的专有信息。如果收到任何著作权人或其合法代表发给京西菜市的适当通知后,我们将在审查的基础上移除该等侵犯他人著作权的内容。
+
+2. 您在使用京西菜市服务时利用京西菜市帐号发表上传的文字、图片、视频、软件以及表演等原创信息的知识产权归您所有,但是您确认您对该等信息的发表、上传行为视同为对京西菜市非独占地、永久地、不可撤销地授予该等信息相关全部知识产权的使用、复制等权利,并且您同意京西菜市可转授权上述权利。
+
+3. 除非经过京西菜市的在先书面同意,您未获得权利使用京西菜市的任何知识产权。您保证、陈述并承诺您尊重京西菜市的知识产权。您不会以自己名义或促使第三方,也不会同意或放任任何第三方,为了其任何营销、广告、促销或其他目的,在任何法域、以任何方式申请与京西菜市或京西菜市关联公司商标相似的商标、域名、无线网站、互联网搜索词或任何商号、服务标志。如出现上述情况,您须将所有相关权利转让给京西菜市,费用由您承担。如因您违反本条款约定而给京西菜市造成损失的,该损失全部由您承担。
+
+六、 修订
+1. 鉴于互联网相关技术、市场、业务模式等等的发展迅速,您同意,京西菜市有权随时根据中华人民共和国有关法律、法规的变化、互联网的发展以及公司经营状况和经营策略的调整等不定时地制定、修改本协议及各类规则。如有修订,京西菜市将通过法定程序通知。经修订的协议、规则一经公布,则立即自动生效,且成为本服务协议不可分割的一部分。如您不同意上述修订,则您必须立即停止使用本协议下各项服务。您继续登录或继续使用京西菜市服务,则表明您认可并接受经修订的协议、规则。
+
+
+七、 终止
+7.1 本协议自您接受之日起生效,在您使用京西菜市服务的过程中持续有效,直至依据本协议终止;
+
+7.2 尽管有上述规定,如果您使用京西菜市服务的时间早于您接受本协议的时间,您在此知晓或应当知晓并同意本协议于您第一次使用京西菜市服务时生效,除非依据本协议提前终止。
+
+7.3 我们可能会依据法律的规定,保留您使用京西菜市服务、或者京西菜市帐号的权利;无论是否通知,我们将在任何时间以任何原因终止本协议,包括出于善意地相信您违反了我们可接受使用政策或本协议的其他规定。
+
+7.4 不受前款规定所限,如果您侵犯第三人的著作权且京西菜市接到著作权人或著作权人的合法代理人的通知后,京西菜市保留终止本协议的权利。
+
+
+八、其他
+8.1 反馈
+
+8.1.1 您对京西菜市提出建议(或称“反馈”),即视为您向京西菜市转让“反馈”的全部权利并同意京西菜市有权利以任何合理方式使用此反馈及其相关信息。我们将视此类反馈信息为非保密且非专有;
+
+8.1.2 您已同意您不会向京西菜市提供任何您视为保密和专有的信息;
+
+8.2 隐私政策
+
+8.2.1 请查阅我们的《隐私政策》,《隐私政策》为与本协议效力等同且不可分割的一部分。
+
+8.3 通知
+
+8.3.1 在注册京西菜市帐号时,您应该向京西菜市提供真实有效的联系方式(包括您的手机号码等),对于联系方式发生变更的,您有义务及时更新有关信息,并保持可被联系的状态。京西菜市将向您的上述联系方式的其中之一或其中若干向您送达各类通知,而此类通知的内容可能对您的权利义务产生重大的有利或不利影响,请您务必及时关注。您所提供的手机号码无法使用或者因任何原因我们无法将通知送达给您而产生的风险,由您自行承担。
+
+8.4 适用法律
+
+8.4.1 本协议适用中华人民共和国法律。
+
+8.4.2 如果双方发生纠纷,应本着友好的原则协商解决;如协商不成,应向北京市海淀区人民法院提起诉讼。若单项条款与本服务条款在管辖约定内容上存在冲突,则在单项条款约束范围内应以单项条款为准。
+
+8.5 独立性
+
+8.5.1 若本协议中的某些条款因故无法适用,则本协议的其他条款继续适用且无法适用的条款将会被修改,以便能够依法适用。
+		
+
+ + \ No newline at end of file diff --git a/src/static/font/iconfont.css b/src/static/font/iconfont.css new file mode 100644 index 0000000..b8f89ff --- /dev/null +++ b/src/static/font/iconfont.css @@ -0,0 +1,343 @@ +@font-face { + font-family: "iconfont"; + src: url('/static/font/iconfont.ttf') format('truetype'); +} + + +/* 自定义图标 */ +.icon-0 { + background-image: url(https://image.jxc4.com/image/884664b80ffd2eda64a4aab9f4dc402e.png); +} + +.icon-1 { + background-image: url(http://image.jxc4.com/image/c4d4a4bf342e301733d16262e0cec2dc.png) +} + +.icon-3 { + background-image: url(https://image.jxc4.com/image/9b6dc6f925111cf1d72175df9669c738.png) +} + +.icon-4 { + background-image: url(https://image.jxc4.com/image/a8914f97edd3e8efa8aef4122fb86f78.png) +} + +.icon-5 { + background-image: url(https://image.jxc4.com/image/e3d7c79e4fe65a687bafbccbad5c2c57.png) +} + +.icon-9 { + background-image: url(http://image.jxc4.com/image/02a72aff88e6fb688472d3d34c275ea2.png) +} + +.icon-16 { + background-image: url(https://image.jxc4.com/image/db9c805c2747a9f8cced29ef8ea7be75.jpg) +} + +.icon-14 { + background-image: url(https://image.jxc4.com/image/32ff8463b62a4195e0a5d979eb0f46f3.png) +} + +.icon-6 { + background-image: url(https://image.jxc4.com/image/57ed88f5b1c2122655dada08de40ed61.png); +} + +.icon-103 { + background-image: url(http://image.jxc4.com/image/35cb1b9bbf9d78b6bb4b48fdae20d88f.png); +} + +.icon-101 { + background-image: url(http://image.jxc4.com/image/223fccabb90ffeb8854e534c6ec1a43c.jpg) +} + +.icon-105 { + background-image: url(http://image.jxc4.com/image/f4ef8fd49fc3d07f456c5fe19dc2ac44.jpg) +} + +.icon-106 { + background-image: url(http://image.jxc4.com/image/938b1fc6aa3428f95182e30c87b887ab.png) +} + + +.promtion-sku-icon, +.promtion-sku-icon2, +.promotion-earning-icon { + position: absolute; + left: 0; + top: 20rpx; + width: 30rpx; + height: 30rpx; + background-color: white; + background-repeat: no-repeat; + background-position: center center; + background-size: 100%; + animation: bounce .5s infinite alternate; +} + +.promotion-earning-icon { + height: 60rpx; +} + +.promtion-sku-icon { + background-image: url(http://image.jxc4.com/image/21a32b90b1de684d70fa16a24b033be7.png); +} + +.promtion-sku-icon2 { + background-image: url(http://image.jxc4.com/image/0be36cc81c28da0be8d1152dc3a2f9b5.png); +} + +.promotion-earning-icon { + background-image: url(http://image.jxc4.com/image/194cd17fcce1c86e589251e9c9e4d87b.png); +} + +/* 订单管理item样式 */ +.position-relative { + font-size: 30rpx; + box-sizing: border-box; + position: relative; + border-radius: 10rpx !important; + overflow: hidden; + padding: 0rpx 15rpx; + margin: 35rpx 25rpx 0rpx 25rpx; +} + +.promtion-sku-icon2 { + background-image: url(https://image.jxc4.com/image/b593ed3cb0b2bc4f012ad81eeacaf4f6.png); +} + +.promtion-sku-icon { + background-image: url(https://image.jxc4.com/image/61daa3ff4294cd271fef44088c94d38c.png); +} + + +/* 兼容ios样式 */ +.rest-time { + display: block; + box-sizing: border-box; + width: 186rpx; + height: 58rpx; + background-size: 100%; + text-align: right; + font-size: 36rpx; + font-weight: bold; + color: #fff; + line-height: 56rpx; + padding-right: 10rpx; +} + +/* 已超时 */ +.order-bg-cs { + display: block; + width: 186rpx; + height: 58rpx; + background: url(https://image.jxc4.com/image/28c4ddde0d2d427e7dd8ec852cd7984f.tem.png) center center no-repeat; + background-size: 100%; + font-size: 0; +} + +/* 预订单 */ +.order-bg-dsd { + display: block; + width: 186rpx; + height: 58rpx; + background: url(https://image.jxc4.com/image/96d3ae7a7b3748a9ad2fc4678c528a61.tem.png) center center no-repeat; + background-size: 100%; + font-size: 0; +} + +/* time */ +.picktime1 { + background: url(https://image.jxc4.com/image/9de64fdcd36aa43cf85c20f5361a486a.tem.png) center center no-repeat; + background-size: 100% 100%; +} + +.canceltime { + background: url(https://image.jxc4.com/image/1ba2acde27582db3bcc801fab44729db.tem.png) center center no-repeat; + background-size: 100% 100%; +} + +/* time < 10 */ +.picktime2 { + background: url(https://image.jxc4.com/image/20b8cfeba3fa10114b7292ee53bde792.tem.png) center center no-repeat; + background-size: 100% 100%; +} + +/* time < 5 */ +.picktime3 { + background: url(https://image.jxc4.com/image/cd1e46e18fa2b7eeea72c4b5b4828b5b.tem.png) center center no-repeat; + background-size: 100% 100%; +} + +/* time */ +.arrived1 { + background: url(https://image.jxc4.com/image/68d5fbc3b1d925cb58a6dad714c45adb.tem.png) center center no-repeat; + background-size: 100% 100%; +} + +/* time < 20 */ +.arrived2 { + background: url(https://image.jxc4.com/image/628846b61f5a0a67aa15b1c6c0ab838f.tem.png) center center no-repeat; + background-size: 100% 100%; +} + +/* time < 5 */ +.arrived3 { + background: url(https://image.jxc4.com/image/47a56698feaf90e5b8376a4824f98475.tem.png) center center no-repeat; + background-size: 100% 100%; +} + +/* 已送达 */ +.order-delivered { + display: block; + box-sizing: border-box; + width: 186rpx; + height: 58rpx; + font-size: 36rpx; + font-weight: 500; + color: #4eb331; + text-align: right; + line-height: 58rpx; +} + +/* 配送管理 */ +.small { + font-size: 24rpx !important; +} + +.red { + color: #D34B3B !important; +} + +.green { + color: #4EB331 !important; +} + + + +/* 系统图标 */ +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-yijianshouquan:before { + content: "\e68f"; +} + +.icon-yuyin:before { + content: "\e69f"; +} + +.icon-jiantou_yemian_xiangxia:before { + content: "\eb0a"; +} + +.icon-erweima:before { + content: "\e60c"; +} + +.icon-xiangce:before { + content: "\e7f1"; +} + +.icon-qiehuan:before { + content: "\e607"; +} + +.icon-zhengque:before { + content: "\e628"; +} + +.icon-ziyuan:before { + content: "\e60f"; +} + +.icon-jiantou1:before { + content: "\e605"; +} + +.icon-jiahao:before { + content: "\eaf3"; +} + +.icon-24gf-telephone:before { + content: "\e96c"; +} + +.icon-zhuanfa:before { + content: "\e627"; +} + +.icon-cangpeitubiao_xiazaipandiandanxiazaidayinmoban:before { + content: "\e623"; +} + +.icon-shengyin:before { + content: "\e87c"; +} + +.icon-shijian:before { + content: "\e8a9"; +} + +.icon-xinxi:before { + content: "\e64e"; +} + +.icon-fuzhi:before { + content: "\e604"; +} + +.icon-shanchu:before { + content: "\e603"; +} + +.icon-xiangyoujiantou:before { + content: "\e65f"; +} + +.icon-xiangzuojiantou:before { + content: "\e660"; +} + +.icon-gengduo:before { + content: "\e602"; +} + +.icon-wenhaoxiao:before { + content: "\e8c8"; +} + +.icon-duihao:before { + content: "\e684"; +} + +.icon-shuxie:before { + content: "\e60e"; +} + +.icon-kongzhuangtai:before { + content: "\e6fe"; +} + +.icon-sousuo:before { + content: "\e62f"; +} + +.icon-weixin:before { + content: "\e601"; +} + +.icon-mima:before { + content: "\e600"; +} + +.icon-yanzhengma2:before { + content: "\e656"; +} + +.icon-shoujihao:before { + content: "\e62b"; +} \ No newline at end of file diff --git a/src/static/font/iconfont.ttf b/src/static/font/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4ecc3230885f128c8445af17b858d70567400364 GIT binary patch literal 8312 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 literal 0 HcmV?d00001 diff --git a/src/static/image/global/empty.png b/src/static/image/global/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..1bfefa097d8db99be70e4e6da6feafa6b4dada8e GIT binary patch literal 69022 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

MDzgy2CxH?)>mTcHq3hkmI6 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 literal 0 HcmV?d00001 diff --git a/src/static/image/global/error.png b/src/static/image/global/error.png new file mode 100644 index 0000000000000000000000000000000000000000..27f699c8b8dcb3be50c5237ec814fb636329f3bd GIT binary patch literal 13556 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 literal 0 HcmV?d00001 diff --git a/src/static/image/global/order-divider.png b/src/static/image/global/order-divider.png new file mode 100644 index 0000000000000000000000000000000000000000..b2609f59a7bf0edeef4a029903cefe2d01fc445f GIT binary patch literal 1088 zcmXX^3rtgI6mGi**rv=Ph}fWGqOSD;lcK0u4T1=)bcDiSq^UsUtiTbQu^B zoIC;ybu7@OGRiHLXM3U4f}$BBU}Qk0EkpzvL~xe&-uCWqSaNc59^X0N_dl*hu+Ni; zyNNg)jvN{i6p6zTRzd9G_#W_FH~(L8I6NtW6?G1zm{f|YRP6=?cscNWefGeJLIxCt zVXI1I9T-sPP}v*;=@GL=1M0H5&9-?HHZ}&3z#t<6ijcvAfY^Y_4XAwzhHWr>6~h2v zE0r4&P_*ydGCQ5+|E@{}!18$;XmuD71ctG}!FD5x4Ge7d_9}GdtwAsggn|7)C#cAc zRtN}ID*x%~0u=Ij6w;&6JR+a7VlWI^z&e08qE@9+HfOc=_XC!8y%{oC0R^PD$X?h5 z02nxa>&{GY8@R7>BH0`q-iE$25s`JJ%Ocg8Nd55CE;7NqzVd1TlBFjl(g=pWGVA)< zsG`24Bv+6g&+u?2*ZaFWOigM!?-Umcl21F`EX(B_{CH||R3i~)aUy+HE#6v{pB%hI zMQBh!RP6n>=luMoi0x{jXNaR`SJ=wkNm*x9^pXt8UK=uDUfq@N#I_BMiuq)u(H#EL z>vn?HQsWm46)p=a(|r|9Q@rdwr9~dv6xDUg%1w0q#IBMbw}nZ>!!1&=^jJlusD5ZE z1WC%9B~7%_xt8C2$vlFjH+00si*-vkJ%OG~yEI9rtyY%Dr%;}mCcjXdW610S(H=u; zhRt}MgMC6sJ9W~@;VC0NYYiG#zsaPzV;Kd6<`}|(PKBG~@MpBv;ORqL;`XWv78TRb z@f@m@F?c*Mn zx-j9-4*qoFenbE2=Oi97_S1>nS#rL-yr#fW_Bw75C)&d;D)fDWBkib4dg&F&=TkV! z;TR}9ke0pXSa-CPR_*5VEbg@A!r-+2o|vE$z}uLEZ*!~r*{!sIZYnYU7kH&M4e>df zTJU9)H1CpYk-+W7_fBZw!@5Tg)XhOJ-akX}*1GKQX^Wl-ah|Bk+{@DK!*gtlrsaf$ z1>`@qX5k ryDTGH-F%rc5u$dvXVO&v?LBc>o>W7)Hp9GS|NNon*g>+h+$;Y9<>Oxa literal 0 HcmV?d00001 diff --git a/src/static/image/global/success.png b/src/static/image/global/success.png new file mode 100644 index 0000000000000000000000000000000000000000..bb2c86a635ca07ad6adcbf9a3e48ff613da1dfad GIT binary patch literal 5962 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 S@h>n889ZJ6T-G@yGywqS!qSca literal 0 HcmV?d00001 diff --git a/src/static/image/tabBarIcon/merchant.png b/src/static/image/tabBarIcon/merchant.png new file mode 100644 index 0000000000000000000000000000000000000000..11a5f6ef8d5a5d1a9bc2215852c14dd660aa11eb GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sMFBn`u0VRmj2TOpE(MYhFn#*; z*qgrA-ZPGngtY@H*X$XF+>f}B%lb84dDXG zj}_TRfwroa1o;Isyl4G=wfDG&+ zXam(VI(oV|hIkx*JNaZ@vw?`~d|tU=g%-sLI}iWtj?U&o+9?n)R?rgfTW;t80%=1~Sp3lE*Po#mt)AN5r_Ln2RT9h6>uU zJ-w)8S|-YLN|R-Ep3C*Vo|iQ_Q_kFaYIAXN^qIH-!`Fub?W_NN{+5?@MRs3UXIl21 z`F)*Qh8ea`?^X(a|4=26-y8aKo6!1gJ2x#8l^6Iqqd(?Q-ua2)4?`lO;k=-yoz zYoPz~P@nLRJz7UTSge>JJP}22WQ%mvv4FO#r7Y B{9gb7 literal 0 HcmV?d00001 diff --git a/src/static/image/tabBarIcon/msg-active.png b/src/static/image/tabBarIcon/msg-active.png new file mode 100644 index 0000000000000000000000000000000000000000..a07e4cd599e5563e6a4b2c4268f6ba9944f9cf93 GIT binary patch literal 2546 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 ALI3~& literal 0 HcmV?d00001 diff --git a/src/static/image/tabBarIcon/shopping.png b/src/static/image/tabBarIcon/shopping.png new file mode 100644 index 0000000000000000000000000000000000000000..2ff64801d20521cf8dc182d4280448d616482d81 GIT binary patch literal 549 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 literal 0 HcmV?d00001 diff --git a/src/static/merchant-icon/14.png b/src/static/merchant-icon/14.png new file mode 100644 index 0000000000000000000000000000000000000000..6f191b5297dba1a523d69a2c9f089526115ab20f GIT binary patch literal 2636 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 u*=Z{KQZs1R_95f}O?&A1Fcy|fLoJ7 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%0AT4?bCu57 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 literal 0 HcmV?d00001 diff --git a/src/static/merchant-icon/18.png b/src/static/merchant-icon/18.png new file mode 100644 index 0000000000000000000000000000000000000000..9ceb103d8a28b574847525c9c83b985cf0e5e5c0 GIT binary patch literal 4364 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 + + + + + + + \ No newline at end of file diff --git a/src/subPages/login/paswordLogin/paswordLogin.vue b/src/subPages/login/paswordLogin/paswordLogin.vue new file mode 100644 index 0000000..a1d88fb --- /dev/null +++ b/src/subPages/login/paswordLogin/paswordLogin.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/login/weixin.ts b/src/subPages/login/weixin.ts new file mode 100644 index 0000000..2863245 --- /dev/null +++ b/src/subPages/login/weixin.ts @@ -0,0 +1,137 @@ +import { onBeforeUnmount, ref, Ref } from "vue"; +import useGlobalFunc from "@/composables/useGlobalFunc"; +import { store } from "@/store"; +import { setStorage } from "@/utils/storage"; +import login from '@/api/https/login' +import { onShow } from "@dcloudio/uni-app"; + +/** + *@description: 微信登录功能模块 + *@return {*} + *@param {}- +*/ +function weixinFn() { + + const { + setUserInfo, + } = useGlobalFunc() + /** + * 定义切换标题数据 + */ + interface LoginType { + title: string; + } + const loginTypeList: Ref = ref([ + { title: "验证码登录" }, + { title: "密码登录" }, + ]); + const activeItem: Ref = ref(0); + + onShow(() => { + store.commit('serveInfo/setIsAgreement', false) + store.commit('serveInfo/setIsAgreementIf', false) + }) + + /************************************************* + * 存储用户信息 + */ + async function saveUserType() { + let res = await login.get_self_info() + if (res.code == 0) { + setStorage('userType', res.data.type) + } else { + setStorage('userType', 0) + } + } + + + /** + * 验证码登录 + */ + function codeLogin(data: AnyObject) { + setUserInfo(data) + saveUserType() + } + + + /** + * 密码登录 + */ + function pwdLogin(data: AnyObject) { + setUserInfo(data) + saveUserType() + } + + + + /** + * 微信登录 + */ + let appWxLoginFnTimer: any = null + let appWxLoginFnTimer2: any = null + + + /** + * 用户协议 + */ + function user() { + uni.navigateTo({ url: '/subPages/agreement/user' }) + } + + + /** + * 隐私协议 + */ + function privacy() { + uni.navigateTo({ url: '/subPages/agreement/privacy' }) + } + + /************************************************* + * 是否同意协议 + */ + const isAgreement = ref(false) + function agreement(e: AnyObject) { + if (e.detail.value.length) { + // 同意 + isAgreement.value = true + store.commit('serveInfo/setIsAgreement', true) + store.commit('serveInfo/setIsAgreementIf', false) + } else { + // 不同意 + store.commit('serveInfo/setIsAgreement', false) + isAgreement.value = false + } + } + + /************************************************* + * 切换登录信息 + */ + function change(res: AnyObject) { + activeItem.value = res.detail.current + } + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + store.commit('serveInfo/setIsAgreement', false) + clearTimeout(appWxLoginFnTimer) + clearTimeout(appWxLoginFnTimer2) + }) + + + return { + loginTypeList, // 切换tab + activeItem, // 切换高亮 + codeLogin, // 验证码登录 + pwdLogin, // 密码登录 + user, // 用户协议 + privacy, // 隐私协议 + change, // 切换 + agreement, // 是否同意协议 + isAgreement, // 是否同意协议 + } +} + + +export default weixinFn \ No newline at end of file diff --git a/src/subPages/login/wxLogin/wxLogin.scss b/src/subPages/login/wxLogin/wxLogin.scss new file mode 100644 index 0000000..6db2e0e --- /dev/null +++ b/src/subPages/login/wxLogin/wxLogin.scss @@ -0,0 +1,126 @@ +.title { + display: flex; + justify-content: center; + align-items: center; + margin-top: 80rpx; + + image { + width: 60rpx; + height: 60rpx; + } + + text { + font-weight: bold; + font-size: 36rpx; + } +} + +.logo { + width: 350rpx; + height: 350rpx; + margin-top: 100rpx; +} + +.login { + position: absolute; + top: 45%; + margin-top: 100rpx; + text-align: center; + + .btn { + position: relative; + display: flex; + align-items: center; + justify-content: center; + background-color: $jx-login; + color: #fff; + padding: 20rpx 0; + border-radius: 100rpx; + width: 640rpx; + text-align: center; + height: 86rpx; + + text { + margin-left: 20rpx; + } + + // image { + // position: absolute; + // width: 130rpx; + // right: 0; + // top: -16rpx; + // } + } + image { + position: absolute; + width: 130rpx; + right: 0; + top: -16rpx; + z-index:99; + } + .phone { + margin-top: 35rpx; + background-color: #3fc2f6; + } +} + +.info { + position: absolute; + width: 100%; + text-align: center; + bottom: 60rpx; + color: rgb(126, 126, 126); + font-size: 28rpx; +} + +.wxPopup-root { + background-color: #fff; + border-radius: 35rpx 35rpx 0 0; + padding: 40rpx; + + .text { + .agreement-title { + font-weight: bold; + font-size: 36rpx; + margin-bottom: 25rpx; + } + + .content { + font-size: 28rpx; + color: rgb(69, 69, 69); + } + + .agreement { + margin: 30rpx 0; + font-weight: bold; + font-size: 28rpx; + + .text { + color: $jx-login; + font-weight: 400; + } + } + } + + .btn { + display: flex; + justify-content: space-between; + margin-bottom: 20rpx; + + view, + button { + width: 46%; + height: 90rpx; + line-height: 90rpx; + border: 1rpx solid $jx-login; + text-align: center; + color: $jx-login; + border-radius: 100rpx; + } + + .resolve { + background-color: $jx-login; + color: #fff; + } + } +} \ No newline at end of file diff --git a/src/subPages/login/wxLogin/wxLogin.ts b/src/subPages/login/wxLogin/wxLogin.ts new file mode 100644 index 0000000..50071bf --- /dev/null +++ b/src/subPages/login/wxLogin/wxLogin.ts @@ -0,0 +1,193 @@ +import toast from "@/utils/toast"; +import { ref } from "vue"; +import useGlobalFunc from "@/composables/useGlobalFunc"; +import { getStorage, setStorage } from "@/utils/storage"; +import { onLoad, onShow } from "@dcloudio/uni-app"; +import login from '@/api/https/login' + +import { store } from '@/store' +import weixinFn from '../weixin' + +const { + agreement, // 是否同意协议 + isAgreement, // 是否同意协议 +} = weixinFn() + +const { setUserInfo, isUserAgreementFn } = useGlobalFunc() +export default { + setup() { + + onShow(() => { + store.commit('serveInfo/setIsAgreement', false) + store.commit('serveInfo/setIsAgreementIf', false) + }) + + // 微信公众号绑定后获取到信息登录 + onLoad(async (position) => { + if (position?.data == 1) { + // 公众号授权成功调用登录 + await silenceLogin() + } + setStorage('isDownApp', 'false') + }) + + // 跳转手机号登录 + function phoneLogin() { + uni.navigateTo({ + url: '/subPages/login/index', + }) + } + + // 用户协议 + function user() { + uni.navigateTo({ url: '/subPages/agreement/user' }) + } + + // 隐私协议 + function privacy() { + uni.navigateTo({ url: '/subPages/agreement/privacy' }) + } + + // 微信登录弹窗实例 + const wxPopup = ref(null) + + // 非首次登录 不需要绑定手机号 + function noNeedBind (){ + if(store.getters['serveInfo/isBindMobile'].need) return // 不需要绑定 + silenceLogin() + } + + // ******************** wx登录类 ***************************** + //#region + function clickLogin() { + if (!store.state.serveInfo.isAgreement) { + isUserAgreementFn() + return false + } + } + + // 微信登录 + async function weixiniLogin(e: AnyObject) { + wxPopup.value.close() + if (e.detail.errMsg == "getPhoneNumber:ok") { + silenceLogin(e) + } + } + async function silenceLogin(e?: AnyObject) { + let getCode = await login.get_jx_code(); + if (getCode) { + let data = { + authType: "weixinmini", + authSecret: getCode.code, + }; + let userInfo = await login.applets_login(data); + if (userInfo.code == 0) { + // 登录成功 + if (userInfo.data.tokenType == 1) { + setUserInfo(userInfo.data); + saveUserType() + } + + // 首次登录绑定用户手机号 + if (userInfo.data.tokenType != 1) { + setStorage('token', userInfo.data.token) + bangdingMobile(e!, userInfo.data.token) + } + } else { + toast("登录失败", 2); + } + } + } + // 绑定手机号码 + async function bangdingMobile(e: AnyObject, token: AnyObject) { + let data = { + "data": e.detail.encryptedData, + "iv": e.detail.iv, + "appID": 'wx08a5c2a8581414ff' + } + let resData = await login.getUser_by_mini_info(data) + if (resData.code == 0) { + // 有手机号码,绑定 + if (resData.data.isExist) { + let data = { + authToken: token, + mobile: resData.data.mobile, + } + let ress = await login.add_auth_bind(data) + if (ress.code == 0) { + setStorage('token', '85e60d6a-f1f8-4837-9c7d-d7072b0ba1c6') + let infoData = await login.get_token_info() + setStorage('token', infoData.data.token) + setStorage('userID', infoData.data.userID) + bindsns(resData.data.mobile) + } else { + toast('登录失败', 2) + } + } + + // 没手机号码 + if (!resData.data.isExist) { + let oldData = { + "userID2": resData.data.mobile, + "name": resData.data.mobile, + "avatar": 'https://image.jxc4.com/jxwhite.png', + "mobile": resData.data.mobile + } + let data = { + authToken: getStorage('token'), + payload: JSON.stringify(oldData) + } + let res = await login.register_user(data) + if (res.code == 0) { + setStorage('token', res.data.token) + setStorage('token', '85e60d6a-f1f8-4837-9c7d-d7072b0ba1c6') + let infoData = await login.get_token_info() + setStorage('token', infoData.data.token) + setStorage('userID', infoData.data.userID) + bindsns(false) + } else { + toast('登录失败', 2) + } + } + } else { + toast('登录失败', 2) + } + } + // 存储用户信息 + async function saveUserType() { + let res = await login.get_self_info() + if (res.code == 0) { + setStorage('userType', res.data.type) + } else { + setStorage('userType', 0) + } + } + // 获取新信息 + function bindsns(mobile: string | boolean) { + if (mobile) { + uni.navigateTo({ + url: `/subPages/login/bindSNS/bindSNS?mobile=${mobile}` + }) + } else { + uni.navigateTo({ + url: '/subPages/login/bindSNS/bindSNS' + }) + } + + } + //#endregion + + return { + phoneLogin, + user, + privacy, + wxPopup, + weixiniLogin, + agreement, + isAgreement, + store, + clickLogin, + noNeedBind // 不需要绑定 + } + } +} \ No newline at end of file diff --git a/src/subPages/login/wxLogin/wxLogin.vue b/src/subPages/login/wxLogin/wxLogin.vue new file mode 100644 index 0000000..c99944b --- /dev/null +++ b/src/subPages/login/wxLogin/wxLogin.vue @@ -0,0 +1,169 @@ + + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/accountBalance/accountBalance.vue b/src/subPages/merchantChild/accountBalance/accountBalance.vue new file mode 100644 index 0000000..33bcc1d --- /dev/null +++ b/src/subPages/merchantChild/accountBalance/accountBalance.vue @@ -0,0 +1,171 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/activity/activity.vue b/src/subPages/merchantChild/activity/activity.vue new file mode 100644 index 0000000..517c2fc --- /dev/null +++ b/src/subPages/merchantChild/activity/activity.vue @@ -0,0 +1,49 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/bill/bill.scss b/src/subPages/merchantChild/bill/bill.scss new file mode 100644 index 0000000..b7f3045 --- /dev/null +++ b/src/subPages/merchantChild/bill/bill.scss @@ -0,0 +1,85 @@ +.bill-list { + + .list-cell { + position: relative; + margin: 20rpx 20rpx 0; + background: white; + border-radius: 10rpx; + height: 144rpx; + border: 1rpx solid #ddd; + box-shadow: 0 0 10rpx rgba(79, 180, 52, 0.12); + display: flex; + align-items: center; + padding: 0 20rpx; + } + + .right { + margin-left: 20rpx; + flex: 1; + + .bill-name { + font-size: 36rpx; + color: #373c40; + line-height: 1; + } + + .bottom { + margin-top: 20rpx; + display: flex; + justify-content: space-between; + align-items: center; + + .timer { + color: #999; + font-size: 28rpx; + line-height: 1; + } + + .detail { + color: $jx-primary + } + } + } + + .icon { + width: 80rpx; + height: 80rpx; + background-repeat: no-repeat; + background-size: 100%; + flex-shrink: 0; + } +} + +.new { + position: absolute; + right: -10rpx; + top: -10rpx; + background-color: rgb(219, 0, 0); + font-size: 20rpx; + width: 30rpx; + height: 30rpx; + text-align: center; + line-height: 30rpx; + color: #fff; + border-radius: 100rpx; + animation: bill-new-animation 0.5s ease-in-out infinite alternate; +} + + +.icon-normal { + background-image: url(https://image.jxc4.com/image/d25167c85897406090cb345edc57b70f.png); +} + +.icon-new { + background-image: url(https://image.jxc4.com/image/afafe57e72dfbf221cca0f481b2a41a9.png); +} + +@keyframes bill-new-animation { + 0% { + transform: scale(0.95); + } + + 100% { + transform: scale(1.05); + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/bill/bill.vue b/src/subPages/merchantChild/bill/bill.vue new file mode 100644 index 0000000..3c6706e --- /dev/null +++ b/src/subPages/merchantChild/bill/bill.vue @@ -0,0 +1,80 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/billDetaile/billDetaile.vue b/src/subPages/merchantChild/billDetaile/billDetaile.vue new file mode 100644 index 0000000..da3ff1c --- /dev/null +++ b/src/subPages/merchantChild/billDetaile/billDetaile.vue @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/businessLicense/businessLicense.scss b/src/subPages/merchantChild/businessLicense/businessLicense.scss new file mode 100644 index 0000000..08bced0 --- /dev/null +++ b/src/subPages/merchantChild/businessLicense/businessLicense.scss @@ -0,0 +1,60 @@ +// 营业执照 +.business-license { + .title { + color: #999; + font-size: 28rpx; + padding: 20rpx; + font-weight: 400; + } + + .cell { + padding: 20rpx; + background: white; + border-top: 1rpx solid #e5e5e5; + + display: flex; + align-items: center; + + text { + white-space: nowrap; + } + + input, + .licence-type { + + font-size: 30rpx; + padding: 10rpx 20rpx; + width: 100%; + + } + + .range-date { + font-size: 30rpx; + display: flex; + justify-content: space-around; + align-items: center; + flex: 1; + + .time { + width: 200rpx; + text-align: center; + background: #efefef; + border-radius: 8rpx; + padding: 10rpx 0; + } + } + } + + .submit-btn { + background: $jx-primary; + height: 100rpx; + line-height: 100rpx; + font-size: 30rpx; + font-weight: 500; + color: white; + text-align: center; + position: fixed; + width: 100%; + bottom: 0; + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/businessLicense/businessLicense.ts b/src/subPages/merchantChild/businessLicense/businessLicense.ts new file mode 100644 index 0000000..15e4fb2 --- /dev/null +++ b/src/subPages/merchantChild/businessLicense/businessLicense.ts @@ -0,0 +1,220 @@ +/** + * @desc 营业资质 + */ + +import toast from "@/utils/toast" +import { computed, ref } from "vue" +import { qiniuyun } from '@/utils/qiniuUploader' +import { onLoad } from "@dcloudio/uni-app" +import { store } from "@/store" +import { getStorage } from "@/utils/storage" +import merchant from '@/api/https/merchant' + + +function businessLicense() { + const qiniuyunUploadImg = qiniuyun() // 七牛云sdk + + + /** + * 获取营业执照信息 + */ + onLoad(async () => { + await getStoreBusiness() + }) + function getStoreBusiness() { + let business = store.state.storeInfo.allStoreInfo + businessData.value.licenceCode = business.licenceCode + businessData.value.licenceType = business.licenceType + businessData.value.licenceCorpName = business.licenceCorpName + businessData.value.licenceOwnerName = business.licenceOwnerName + businessData.value.licenceAddress = business.licenceAddress + businessData.value.licenceValid = business.licenceValid + businessData.value.licence2Code = business.licence2Code + businessData.value.licenceExpire = business.licenceExpire + businessData.value.licence2Valid = business.licence2Valid + businessData.value.licence2Expire = business.licence2Expire + imgUrls.value.licence = business.licence + imgUrls.value.licence2Image = business.licence2Image + } + + + /** + * 营业资质信息 + */ + const businessData = ref({ + licenceCode: '', // 营业编号18 + typeArr: ['个人', '公司'], // 类型 + licenceType: 0, // 0个人 1公司 + licenceCorpName: '', // 公司名称 + licenceOwnerName: '', // 法人醒姓名 + licenceAddress: '', // 营业执照地址 + licenceValid: '', // 营业执照有效期开始 + licence2Code: '', // 经营许可证编号 + licenceExpire: '', // 营业执照有效期结束 + licence2Valid: '', // 经营许可证开始时间 + licence2Expire: '', // 经营许可证结束时间 + }) + + /** + * 切换营业执照类型 + */ + function typeChange(e: AnyObject) { + businessData.value.licenceType = e.target.value + } + + + /** + * 营业执照类型 + */ + const licenceTypeText = computed(() => { + if (parseInt('' + businessData.value.licenceType, 10) === 0) { + return '个人' + } else if (parseInt('' + businessData.value.licenceType, 10) === 1) { + return '公司' + } else { + return '' + } + }) + + + /** + * 修改时间 + * @param {type}-1:营业执照开始时间 2:营业执照结束时间 3:经营许可证开始时间 4:经营许可证结束时间 + */ + function fnDateChange(e: AnyObject, type: number) { + if (type == 1) { + businessData.value.licenceValid = e.detail.value + } + if (type == 2) { + businessData.value.licenceExpire = e.detail.value + } + if (type == 3) { + businessData.value.licence2Valid = e.detail.value + } + if (type == 4) { + businessData.value.licence2Expire = e.detail.value + } + } + + + /** + * 上传营业执照 + */ + function imgChangeLicence(data: AnyObject) { + // 删除 + if (data.type == 'delet') { + imgUrls.value.licence = '' + } + // 上传 + if (data.type == 'upload') { + uploadImg(data, 'licence') + } + } + + + /** + * 上传经营执照 + */ + function imgChangeLicence2Image(data: AnyObject) { + // 删除 + if (data.type == 'delet') { + imgUrls.value.licence2Image = '' + } + // 上传 + if (data.type == 'upload') { + uploadImg(data, 'licence2Image') + } + } + + + /** + * 上传图片到七牛云 + */ + const uploadUrl = ref('https://image.jxc4.com/') + const imgUrls = ref({ + licence: '', // 营业执照 + licence2Image: '', // 经营执照 + }) + async function uploadImg(data: AnyObject, img: string) { + let suffix = data.img.indexOf('.png') === -1 ? '.jpg' : '.png' + let params = { + suffix + } + let res = await merchant.get_qiniu_upload_token(params) + if (res.code == 0) { + let filePath = data.img + qiniuyunUploadImg.upload( + filePath, + (res: any) => { + // 得到图片网址 + let imgUrl = uploadUrl.value + res.key + imgUrls.value[img] = imgUrl + }, + (err: AnyObject) => { + toast('上传失败,请重试', 2) + }, + { + uploadURL: 'https://up-z2.qiniup.com/', + key: res.data.fileName, + uptoken: res.data.token, + } + ) + } else { + toast('上传失败', 2) + } + } + + + /** + * 提交修改 + */ + function confirmSubmit() { + uni.jxConfirm({ + title: '提示', + content: '您确定要修改信息吗?', + success: async () => { + let data = { + storeID: getStorage('storeID'), + payload: JSON.stringify({ + licenceCode: businessData.value.licenceCode, + licenceType: businessData.value.licenceType, + licenceCorpName: businessData.value.licenceCorpName, + licenceOwnerName: businessData.value.licenceOwnerName, + licenceAddress: businessData.value.licenceAddress, + licenceValid: businessData.value.licenceValid, + licenceExpire: businessData.value.licenceExpire, + licence2Code: businessData.value.licence2Code, + licence2Valid: businessData.value.licence2Valid, + licence2Expire: businessData.value.licence2Expire, + licence: imgUrls.value.licence, + licence2Image: imgUrls.value.licence2Image + }) + } + let res = await merchant.update_store(data) + if (res.code == 0) { + toast('修改成功', 1) + setTimeout(() => { + uni.navigateBack() + }, 1500) + } else { + toast('修改失败', 2) + } + }, + }) + } + + + return { + businessData, // 营业资质信息 + typeChange, // 修改营业执照类型 + licenceTypeText, // 营业执照类型 + fnDateChange, // 修改时间 + imgChangeLicence, // 上传图片 + imgChangeLicence2Image, // 上传图片 + confirmSubmit, // 提交修改 + imgUrls, // 上传的图片 + } +} + + +export default businessLicense \ No newline at end of file diff --git a/src/subPages/merchantChild/businessLicense/businessLicense.vue b/src/subPages/merchantChild/businessLicense/businessLicense.vue new file mode 100644 index 0000000..031884c --- /dev/null +++ b/src/subPages/merchantChild/businessLicense/businessLicense.vue @@ -0,0 +1,145 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/enterGroupChat/enterGroupChat.vue b/src/subPages/merchantChild/enterGroupChat/enterGroupChat.vue new file mode 100644 index 0000000..1f6c66b --- /dev/null +++ b/src/subPages/merchantChild/enterGroupChat/enterGroupChat.vue @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/evaluateM/commentList/commentList.scss b/src/subPages/merchantChild/evaluateM/commentList/commentList.scss new file mode 100644 index 0000000..a90f3d3 --- /dev/null +++ b/src/subPages/merchantChild/evaluateM/commentList/commentList.scss @@ -0,0 +1,134 @@ +.comment-cell { + margin-bottom: 25rpx; + + .pd20 { + padding: 0 20rpx; + } + + .order-id { + background: rgba(207, 228, 125, 0.2); + display: flex; + align-items: center; + justify-content: space-between; + height: 80rpx; + + .id { + font-size: 30rpx; + color: #333; + font-weight: 400; + } + + .time { + font-size: 24rpx; + color: #999; + font-weight: 400; + } + } + + // 评分 + .score { + background: white; + height: 80rpx; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + display: flex; + align-items: center; + + .text { + font-size: 28rpx; + color: #666; + font-weight: 400; + margin-right: 20rpx; + } + + .rank { + display: flex; + + .star { + display: block; + width: 32rpx; + height: 32rpx; + background: url(https://image.jxc4.com/image/8d59f1ead093cae2d699b5be71026534.png) center center no-repeat; + background-size: cover; + margin: 0 4rpx; + } + + .star2 { + background: url(https://image.jxc4.com/image/b253e76ed05d02b5c3ff502692e88e56.png) center center no-repeat; + background-size: cover; + } + } + } + + // 评论 + .comment-text { + font-size: 30rpx; + font-weight: 400; + color: #333; + padding: 30rpx 20rpx 40rpx; + background: white; + text-indent: 2em; + text-align: justify; + } + + // tag + .tag { + padding: 20rpx; + background: white; + + .span { + display: inline-block; + border-radius: 17rpx; + font-size: 26rpx; + color: #999; + border: 1rpx solid #999; + margin-right: 20rpx; + padding: 0 20rpx; + } + } + + // 剩余时间 + .rest-time { + border-top: 2rpx dashed rgba(204, 204, 204, 0.4); + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + width: 100% !important; + text-align: right; + font-size: 28rpx; + color: #e9007a; + background: white; + } + + // 联系客户 + .contact { + padding: 20rpx; + display: flex; + justify-content: space-between; + align-items: center; + background: white; + + .tel { + font-size: 28rpx; + } + + .btn { + width: 280rpx; + height: 76rpx; + text-align: center; + line-height: 76rpx; + color: white; + border-radius: 10rpx; + background: #4eb331; + font-size: 36rpx; + font-weight: 400; + } + } + + // 商家图标 + .vendor-icon { + display: inline-block; + width: 40rpx; + height: 40rpx; + background-size: 100%; + background-repeat: no-repeat; + margin-right: 20rpx; + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/evaluateM/commentList/commentList.vue b/src/subPages/merchantChild/evaluateM/commentList/commentList.vue new file mode 100644 index 0000000..10c97d7 --- /dev/null +++ b/src/subPages/merchantChild/evaluateM/commentList/commentList.vue @@ -0,0 +1,284 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/evaluateM/evaluateM.vue b/src/subPages/merchantChild/evaluateM/evaluateM.vue new file mode 100644 index 0000000..8cfc264 --- /dev/null +++ b/src/subPages/merchantChild/evaluateM/evaluateM.vue @@ -0,0 +1,139 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/evaluateM/tabs/tabs.vue b/src/subPages/merchantChild/evaluateM/tabs/tabs.vue new file mode 100644 index 0000000..4850508 --- /dev/null +++ b/src/subPages/merchantChild/evaluateM/tabs/tabs.vue @@ -0,0 +1,87 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/helpCenter/helpCenter.vue b/src/subPages/merchantChild/helpCenter/helpCenter.vue new file mode 100644 index 0000000..3ef164a --- /dev/null +++ b/src/subPages/merchantChild/helpCenter/helpCenter.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/subPages/merchantChild/invoice/invoice.vue b/src/subPages/merchantChild/invoice/invoice.vue new file mode 100644 index 0000000..afd4dc2 --- /dev/null +++ b/src/subPages/merchantChild/invoice/invoice.vue @@ -0,0 +1,495 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/message/message.scss b/src/subPages/merchantChild/message/message.scss new file mode 100644 index 0000000..c423dd8 --- /dev/null +++ b/src/subPages/merchantChild/message/message.scss @@ -0,0 +1,84 @@ +// 消息清单样式 + +.list { + padding: 20rpx; + font-size: 26rpx; +} + +.list-title { + color: #999; + margin-bottom: 20rpx; + padding-left: 50rpx; + background: url(https://image.jxc4.com/image/8c8763df4642d3eddfd9ff0b5ac562ac.png) left center no-repeat; + background-size: contain; +} + +.list-item { + background: white; + padding: 20rpx; + border-radius: 10rpx; + margin-top: 40rpx; + box-shadow: 0 1rpx 1rpx rgba(black, .2), + 0 8rpx 0 -3rpx white, + 0 9rpx 1rpx -3rpx rgba(black, .2), + 0 16rpx 0 -6rpx white, + 0 17rpx 2rpx -6rpx rgba(black, .2); +} + +.new-icon, +.old-icon { + width: 90rpx; + font-size: 20rpx; + flex-shrink: 0; + background: #d81e06; + border-radius: 80rpx; + color: white; + text-align: center; + padding: 10rpx; +} + +.new-icon { + animation: bigSmall 1s infinite; + animation-fill-mode: both; +} + +.old-icon { + background: #ccc; + color: white; +} + +.content { + display: flex; + align-items: center; + + .title { + margin-left: 20rpx; + width: 560rpx; + font-size: 36rpx; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + color: #333; + font-weight: 500; + } +} + +.create-time { + text-align: right; + color: #999; +} + + +@keyframes bigSmall { + 0% { + transform: scale3d(1, 1, 1); + } + + 50% { + transform: scale3d(1.1, 1.1, 1.1); + } + + 100% { + transform: scale3d(1, 1, 1); + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/message/message.vue b/src/subPages/merchantChild/message/message.vue new file mode 100644 index 0000000..ec9b4d1 --- /dev/null +++ b/src/subPages/merchantChild/message/message.vue @@ -0,0 +1,88 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/messageDetail/messageDetail.scss b/src/subPages/merchantChild/messageDetail/messageDetail.scss new file mode 100644 index 0000000..7532d9a --- /dev/null +++ b/src/subPages/merchantChild/messageDetail/messageDetail.scss @@ -0,0 +1,42 @@ +.cell { + box-sizing: border-box; + border-bottom: 1rpx solid rgb(233, 233, 233); + padding: 10rpx 0; + margin: 0 20rpx; + + .text { + margin-left: 15rpx; + } +} + +.content { + padding: 10rpx 20rpx 96rpx 20rpx; +} + +.imgWrap { + display: flex; + + .imgInnerWrap { + width: 100%; + height: 550rpx; + margin: 10rpx; + + .img { + width: 100%; + height: 100%; + } + } +} + +.return { + position: fixed; + width: 100%; + height: 94rpx; + bottom: 0; + line-height: 94rpx; + text-align: center; + font-size: 36rpx; + color: white; + font-weight: 400; + background-color: $jx-primary; +} \ No newline at end of file diff --git a/src/subPages/merchantChild/messageDetail/messageDetail.vue b/src/subPages/merchantChild/messageDetail/messageDetail.vue new file mode 100644 index 0000000..3b6c572 --- /dev/null +++ b/src/subPages/merchantChild/messageDetail/messageDetail.vue @@ -0,0 +1,103 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/modifyPrice/modifyPrice.scss b/src/subPages/merchantChild/modifyPrice/modifyPrice.scss new file mode 100644 index 0000000..548e643 --- /dev/null +++ b/src/subPages/merchantChild/modifyPrice/modifyPrice.scss @@ -0,0 +1,148 @@ +.price-value { + + .price-item { + display: flex; + width: 100%; + position: relative; + + .s1 { + flex: 120rpx; + } + + .s2, + .s3 { + flex: 1; + } + + .common { + font-size: 28rpx; + color: #999; + margin-bottom: 10rpx; + border-top: 1rpx solid #e5e5e5; + border-bottom: 1rpx solid #e5e5e5; + background: white; + height: 60rpx; + display: flex; + justify-content: center; + align-items: center; + + .num { + color: $jx-primary; + } + } + } +} + +.btn { + box-sizing: border-box; + margin: 20rpx 10rpx 20rpx 10rpx; + background-color: $jx-primary; + color: #fff; +} + + +.modal { + width: 100%; + height: 100%; + background-color: #fff; + + .price-item { + display: flex; + width: 100%; + position: relative; + + .icon-x { + flex: 0 0 60rpx; + } + + .news1 { + flex: 0 0 290rpx; + } + + .news2 { + flex: 0 0 200rpx; + } + + .news3 { + flex: 0 0 190rpx; + } + + .common { + font-size: 28rpx; + color: #999; + margin-bottom: 10rpx; + border-top: 1rpx solid #e5e5e5; + border-bottom: 1rpx solid #e5e5e5; + background: white; + height: 60rpx; + display: flex; + justify-content: center; + align-items: center; + + text { + white-space: nowrap; + } + + .num-ipt { + margin-left: 6rpx; + width: 60rpx; + } + + .num { + color: $jx-primary; + } + } + } + + .btn-group { + display: flex; + justify-content: space-evenly; + + .btn2 { + width: 30%; + } + + .btn-update { + background-color: $jx-primary; + color: #fff; + } + } +} + + +/* 元素进入之前的动画 */ +.fade-enter-from { + opacity: 0; +} + +/* 进入中 */ +.fade-enter-active { + transition: all 0.7s ease-in-out; +} + +/* 进入之后 */ +.fade-enter-to { + opacity: 1; +} + +/* 元素离开之前 */ +.fade-leave-from { + opacity: 1; + transform: rotate(0); +} + +/* 离开中 */ +.fade-leave-active { + transition: all 0.3s ease-in; +} + +/* 离开之后 */ +.fade-leave-to { + opacity: 0; + transform: rotate(360deg); +} + +/* 移动元素的动画 */ +.fade-move { + transition: transform 0.3s ease-out; +} \ No newline at end of file diff --git a/src/subPages/merchantChild/modifyPrice/modifyPrice.vue b/src/subPages/merchantChild/modifyPrice/modifyPrice.vue new file mode 100644 index 0000000..2cdd721 --- /dev/null +++ b/src/subPages/merchantChild/modifyPrice/modifyPrice.vue @@ -0,0 +1,212 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/orderRealTime/orderRealTime.scss b/src/subPages/merchantChild/orderRealTime/orderRealTime.scss new file mode 100644 index 0000000..79dd597 --- /dev/null +++ b/src/subPages/merchantChild/orderRealTime/orderRealTime.scss @@ -0,0 +1,149 @@ +.select-root { + display: flex; + justify-content: space-between; + background-color: #fff; + padding: 10rpx 20rpx; + margin-bottom: 20rpx; + + .all-text { + font-weight: bold; + } + + .slect-text { + color: $jx-primary; + text-decoration: underline; + } +} + + +.today-root { + background-color: #fff; + padding: 20rpx; + margin-top: 20rpx; + + .order-money { + display: flex; + justify-content: space-between; + + .money { + border-right: 1rpx solid #e0e0e0; + } + + .money, + .order { + width: 354rpx; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .number { + font-weight: bold; + font-size: 40rpx; + padding: 30rpx 0; + } + } + } +} + + +.business-status { + background-color: #fff; + margin-top: 20rpx; + + .business-text { + padding: 20rpx; + } + + .slect-item-root { + display: flex; + justify-content: space-around; + width: 100%; + + .item { + display: block; + width: 100%; + text-align: center; + padding: 15rpx 0; + } + + .item-active { + background-color: $jx-primary; + color: #fff; + } + } + + .time-root { + display: flex; + align-items: center; + justify-content: center; + padding: 15rpx 0; + background-color: #fafafa; + border-top: 1rpx solid #e2e2e2; + border-bottom: 1rpx solid #e2e2e2; + font-size: 28rpx; + color: #919191; + + .slect-edit { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 20rpx; + width: 100%; + + + .time-item { + display: flex; + align-items: center; + background-color: #e6e6e6; + padding: 10rpx 20rpx; + border-radius: 10rpx; + } + + button { + background-color: $jx-primary; + color: #fff; + margin: 0; + } + } + } + + .money-data-root { + padding: 20rpx; + + .row { + border-bottom: 1rpx solid #e0e0e0; + } + + .row, + .row-last { + display: flex; + justify-content: space-between; + width: 100%; + + .money-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + margin-top: 25rpx; + margin-bottom: 25rpx; + + .number { + font-weight: bold; + font-size: 40rpx; + padding: 20rpx; + } + } + + .active { + border-right: 1rpx solid #e0e0e0; + } + } + + .afterNumber::before{ + content: '-'; + } + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/orderRealTime/orderRealTime.ts b/src/subPages/merchantChild/orderRealTime/orderRealTime.ts new file mode 100644 index 0000000..162c16e --- /dev/null +++ b/src/subPages/merchantChild/orderRealTime/orderRealTime.ts @@ -0,0 +1,455 @@ +/** + * 营业数据 + */ + +import { onLoad } from "@dcloudio/uni-app"; +import { getStorage } from "@/utils/storage"; +import toast from "@/utils/toast"; +import { computed, onBeforeUnmount, ref } from "vue"; +import { store } from '@/store' +import useGlobalFunc from "@/composables/useGlobalFunc"; +import { clearList, timeFormatD } from "@/utils/tools"; +import configCms from "@/utils/configCms" +import merchant from '@/api/https/merchant' + + +export default function orderRealTime() { + const { globGetToDay } = useGlobalFunc() + const { singleCalcPrice } = useGlobalFunc() + + /************************************************* + * 接收参数 + */ + const isNotQuote = ref(true) + const isZero = ref(true) + const isUpperfif = ref(true) + onLoad((options) => { + _vendorPayPercentage.value = options!._vendorPayPercentage + isNotQuote.value = JSON.parse(options!.isNotQuote) + isZero.value = JSON.parse(options!.isZero) + isUpperfif.value = JSON.parse(options!.isUpperfif) + }) + + /** + * 获取平台数据-平台名称 + */ + onLoad(async () => { + await getPlatformList() + await tabClick(0) + await getFromTime() // 获取营业概况数据 + await getToDay() // 获取今日数据 + }) + + + /************************************************* + * 平台列表数据 + */ + const vendorArr = ref>([ + { + vendorID: -1, + vendorStoreName: '全部' + } + ]) + + /************************************************* + * 切换平台更新数据 + */ + const pickValue = ref('0') // 代码高亮 + async function handleVendorChange(e: AnyObject) { + pickValue.value = e.detail.value + await changeStatus(active.value) + await getFromTime() // 获取营业概况数据 + await getToDay() // 获取今日数据 + } + + + /************************************************* + * 获取今日数据 + */ + const toDaySaleInfo = ref({}) + async function getToDay() { + let fromTime = `${timeFormatD()} 00:00:00`; + let toTime = `${timeFormatD()} 23:59:59`; + let data = { + storeIDs: `[${parseInt(getStorage("storeID"))}]`, + fromTime, + toTime, + statuss:JSON.stringify([110]) + }; + let toDay = await globGetToDay(data) + if (!toDay) toDay = [] + toDaySaleInfo.value = filterSaleInfo(toDay) + } + + + /************************************************* + * 分时间段获取营业数据-营业概况 + */ + const saleInfo = ref({}) + async function getFromTime() { + uni.vibrateShort({}) + let data = { + storeIDs: `[${parseInt(getStorage("storeID"))}]`, + fromTime: `${fromTime.value} 00:00:00`, + toTime: `${toTime.value} 23:59:59`, + statuss:JSON.stringify([110]) // 只统计已完成的订单,不包含取消单 + } + let toDay = await globGetToDay(data) + if (!toDay) toDay = [] + saleInfo.value = filterSaleInfo(toDay) + } + + + /************************************************* + * 过滤今日营业数据 + */ + const isAllplatfrom = ref(true) + const checkVendorID = ref(0) + function filterSaleInfo(arr: Array) { + let vendorID = vendorArr.value[+pickValue.value].vendorID + checkVendorID.value = vendorID + let actualPayPrice = 0 + let realEarningPrice = 0 + let earningPrice = 0 + let shopPrice = 0 + let count = 0 + let cancelCount = 0 + let afsPrice = 0 + let afsCount = 0 + let waybillTipMoney = 0 + let distanceFreightMoney = 0 + let actualFee = 0 + let serverFee = 0 // 报价门店,管理费 + + // 全部 + if (vendorID === -1) { + arr.forEach((item) => { + waybillTipMoney += item.waybillTipMoney + serverFee += item.serverFee + if (item.status === 110) { + distanceFreightMoney += item.distanceFreightMoney + realEarningPrice += item.platformSettlement + earningPrice += item.earningPrice + shopPrice += item.shopPrice + count += item.count + actualPayPrice += item.actualPayPrice + actualFee += item.actualFee + } else if (item.status === 115) { + cancelCount += item.count + } else if (item.status < 0) { + afsPrice += item.earningPrice + afsCount += item.count + } + }) + isAllplatfrom.value = true + } else { + // 走平台过滤 + arr.forEach((item) => { + waybillTipMoney += item.waybillTipMoney + serverFee += item.serverFee + if (item.status === 110 && item.vendorID === vendorID) { + distanceFreightMoney += item.distanceFreightMoney + realEarningPrice += item.platformSettlement + earningPrice += item.earningPrice + shopPrice += item.shopPrice + count += item.count + actualPayPrice += item.actualPayPrice + actualFee += +item.actualFee + } + if (item.status === 115 && item.vendorID === vendorID) { + cancelCount += item.count + } + if (item.status < 0 && item.vendorID === vendorID) { + afsPrice += item.earningPrice + afsCount += item.count + } + }) + isAllplatfrom.value = false + } + + actualFee = +(actualFee / 100).toFixed(2) + + return { + actualPayPrice, + earningPrice, + shopPrice, + count, + cancelCount, + afsPrice, + afsCount, + waybillTipMoney, + distanceFreightMoney, + realEarningPrice, + actualFee, + serverFee + } + } + + + /************************************************* + * 获取门店信息 + */ + const _vendorPayPercentage = ref(0) + async function getStoreVendorMaps(vendorID: number) { + let data = { + storeID: getStorage('storeID'), + vendorID: vendorID + } + let res = await merchant.get_store_vendor_maps(data) + if (res.code == 0) { + let data = res.data + _vendorPayPercentage.value = data[0].vendorPayPercentage + } else { + _vendorPayPercentage.value = 0 + } + } + + + /************************************************* + * 平台名称 + */ + async function getPlatformList() { + let data = { + storeID: getStorage('storeID') + } + let platformRes = await merchant.get_stores(data) + if (platformRes.code == 0) { + let serveInfo:AnyObject = configCms.serveInfo + let storeData = platformRes.data.stores[0] + storeData.StoreMaps.forEach((element: AnyObject) => { + vendorArr.value.push({ + vendorID: element.vendorID, + vendorStoreName: `${serveInfo.vendorName[element.vendorID] ? serveInfo.vendorName[element.vendorID] : '未知平台'}`, + vendorPayPercentage: element.vendorPayPercentage + }) + }); + } else { + toast('平台数据异常', 2) + } + } + + + /** + * 打开说明窗口 + */ + function explain() { + uni.jxAlert({ + title: '说明', + content: `实际收入: 从当日0时到当前时间的实际获得,不再扣点,已扣除售后退款\r\n 有效订单: 统计时间内,已支付订单中未被取消的订单数量。\r\n取消订单: 统计时间内,取消订单的数量。\r\n订单取消率: 取消订单/(有效订单 + 取消订单)`, + }) + } + + + /************************************************* + * 营业状况筛选列表 + */ + const tabArr = ref>(["昨日", "近7日", "近30日", "自定义"]) + + + /************************************************* + * 营业概况筛选 + */ + const active = ref(0) + const fromTime = ref('') + const toTime = ref('') + async function tabClick(index: number) { + switch (index) { + case 0: + fromTime.value = `${timeFormatD(+new Date().getTime() - 1000 * 60 * 60 * 24)}` + toTime.value = `${timeFormatD(+new Date().getTime() - 1000 * 60 * 60 * 24)}` + break + case 1: + fromTime.value = `${timeFormatD(+new Date().getTime() - 1000 * 60 * 60 * 24 * 6)}` + toTime.value = timeFormatD() + break + case 2: + fromTime.value = `${timeFormatD(+new Date().getTime() - 1000 * 60 * 60 * 24 * 29)}` + toTime.value = timeFormatD() + break + case 3: + fromTime.value = `${timeFormatD(+new Date().getTime() - 1000 * 60 * 60 * 24 * 6)}` + toTime.value = timeFormatD() + break + + } + if (active.value == index) return + active.value = index + await changeStatus(active.value) + await getFromTime() // 营业概况数据 + } + + + /************************************************* + * 自定义开始日期 + */ + function fnChangeFrom(e: AnyObject) { + fromTime.value = e.detail.value + } + // 自定义结束时间 + function fnChangeTo(e: AnyObject) { + toTime.value = e.detail.value + } + + + /************************************************* + * 实际收益 + */ + const isPointStore = computed(() => { + return store.getters['storeInfo/isPointStore'] + }) + const price = computed(() => { + if (isYesterday.value) { + if (saleInfo.value.count) { + //订单量不为0 + //单平台 + let calcData = { + vendorPayPercentage: _vendorPayPercentage.value, + actualPayPrice: saleInfo.value.actualPayPrice, + shopPrice: saleInfo.value.shopPrice, + isPointStore: isPointStore.value, + earningPrice: saleInfo.value.earningPrice, + } + return singleCalcPrice(calcData) + } else { + //订单量为0 + return 0 + } + } else if (!isYesterday.value) { + if (isPointStore.value) { + //扣点 + return saleInfo.value.realEarningPrice + ? (saleInfo.value.realEarningPrice / 100).toFixed(2) + : 0 + } else { + //报价 + return saleInfo.value.shopPrice + ? (saleInfo.value.shopPrice / 100).toFixed(2) + : 0 + // console.log(saleInfo.value.earningPrice,'11111111',saleInfo.value) + // console.log('eeeeeeee') + + // return saleInfo.value.earningPrice + // ? (saleInfo.value.earningPrice / 100).toFixed(2) + // : 0 + } + } + }) + + + /************************************************* + * 结算类型 + */ + const vendortitle = computed(() => { + if (isYesterday.value) { + if (isPointStore.value) { + return '实际支付' + } else { + if ( + _vendorPayPercentage.value != 0 && + _vendorPayPercentage.value < 50 + ) { + //扣点 + return '实际支付' + } else { + //报价 + return '实际收入' + } + } + } else { + if (isPointStore.value) { + //扣点 + return '平台结算' + } else { + //报价 + return '实际收入' + } + } + }) + + + /************************************************* + * 获取判断条件 + */ + const isYesterday = ref(true) + async function changeStatus(index: number) { + await getStoreVendorMaps(checkVendorID.value) + index == 0 ? (isYesterday.value = true) : (isYesterday.value = false) + } + + + /************************************************* + * 配送小费 + */ + const waybillTipMoney = computed(() => { + return saleInfo.value.waybillTipMoney + ? (saleInfo.value.waybillTipMoney / 100).toFixed(2) + : '0.00' + }) + + + /************************************************* + * 扣点:远距离配送费 + * 报价:服务费 + */ + const distanceFreightMoney = computed(() => { + if(isPointStore.value){ + // 扣点 + return saleInfo.value.distanceFreightMoney + ? (saleInfo.value.distanceFreightMoney / 100).toFixed(2) + : '0.00' + }else{ + // 报价 + return saleInfo.value.serverFee + ? (saleInfo.value.serverFee / 100).toFixed(2) + : '0.00' + } + + }) + + + /************************************************* + * 售后退款 + */ + const afsPrice = computed(() => { + return saleInfo.value.afsPrice + ? (saleInfo.value.afsPrice / 100).toFixed(2) + : '0.00' + }) + + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + clearList() + }) + + + return { + vendorArr, // 平台列表 + handleVendorChange, // 切换平台 + explain, // 今日订单说明窗口 + tabArr, // 营业概况选择列表 + active, // 列表高亮 + tabClick, // 营业概况筛选 + fromTime, // 开始时间 + toTime, // 结束时间 + saleInfo, // 今日概况数据 + fnChangeFrom, // 自定义开始时间 + fnChangeTo, // 自定义结束时间 + pickValue, // 平台内容 + getFromTime, // 查询订单 + toDaySaleInfo, // 今日订单数据 + isAllplatfrom, + isNotQuote, + _vendorPayPercentage, + isZero, + isUpperfif, + price, + vendortitle, + waybillTipMoney, + distanceFreightMoney, + afsPrice, + isPointStore + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/orderRealTime/orderRealTime.vue b/src/subPages/merchantChild/orderRealTime/orderRealTime.vue new file mode 100644 index 0000000..8fdfd6c --- /dev/null +++ b/src/subPages/merchantChild/orderRealTime/orderRealTime.vue @@ -0,0 +1,182 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/payeeInfo/payeeInfo.vue b/src/subPages/merchantChild/payeeInfo/payeeInfo.vue new file mode 100644 index 0000000..51ecb87 --- /dev/null +++ b/src/subPages/merchantChild/payeeInfo/payeeInfo.vue @@ -0,0 +1,207 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/platformDetail/index.scss b/src/subPages/merchantChild/platformDetail/index.scss new file mode 100644 index 0000000..724e9af --- /dev/null +++ b/src/subPages/merchantChild/platformDetail/index.scss @@ -0,0 +1,84 @@ +.info{ + text-align: center; + + .logo{ + display: flex; + align-items: center; + justify-content: center; + margin-top:20px; + + .vendor { + display: flex; + flex-shrink: 0; + width: 150rpx; + height: 150rpx; + + .icon { + width: 150rpx; + height: 150rpx; + flex-shrink: 0; + background-size: 100%; + background-repeat: no-repeat; + border: 1rpx solid #efefef; + border-radius: 10rpx; + opacity: 1; + transition: all 0.5s; + } + } + } + + // /.sync, + .vendorName,.onlineStatus{ + margin-top: 10rpx; + text-align: center; + } + // .sync, + .onlineStatus{ + margin: 20rpx; + height: 120rpx; + background:linear-gradient(180deg, #a4e8f5, #fff); + border-top-right-radius: 20rpx; + border-top-left-radius: 20rpx; + padding: 20rpx; + } + + .time{ + background: #fff; + height: 220rpx; + margin:-40rpx 20rpx 20rpx 20rpx; + border-radius: 20rpx; + border: 1rpx solid #eee; + padding: 20rpx; + display: flex; + flex-direction: column; + justify-content: space-around; + text-align: center; + } + + .timeItem{ + background-color: #cccccc; + border-radius: 20rpx; + padding: 10rpx; + color:#fff; + } + + .disabledColor{ + opacity: 0.6; + background-color: #ffad49; + } + + .notice{ + border: 1rpx solid #eee; + text-align: left; + margin:20rpx; + padding: 20rpx; + color:rgb(241, 167, 114); + font-size: 28rpx; + border-radius: 20rpx; + + .text::before{ + content: "*"; + } + } +} + diff --git a/src/subPages/merchantChild/platformDetail/index.vue b/src/subPages/merchantChild/platformDetail/index.vue new file mode 100644 index 0000000..d4fd1f1 --- /dev/null +++ b/src/subPages/merchantChild/platformDetail/index.vue @@ -0,0 +1,106 @@ + + + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/platformM/platformM.scss b/src/subPages/merchantChild/platformM/platformM.scss new file mode 100644 index 0000000..ff0da9e --- /dev/null +++ b/src/subPages/merchantChild/platformM/platformM.scss @@ -0,0 +1,80 @@ +.cell { + min-height: 90rpx; + background: white; + border-top: 1rpx solid #e5e5e5; + border-bottom: 1rpx solid #e5e5e5; + display: flex; + align-items: center; + justify-content: space-between; + padding: 10rpx 20rpx; + margin-bottom: 20rpx; + + .left { + flex: 1; + + .vendor { + display: flex; + align-items: center; + flex-shrink: 0; + + .icon { + width: 40rpx; + height: 40rpx; + flex-shrink: 0; + background-size: 100%; + background-repeat: no-repeat; + border: 1rpx solid #efefef; + border-radius: 10rpx; + opacity: 1; + transition: all 0.5s; + } + + .vendor-name { + margin-left: 10rpx; + font-size: 34rpx; + display: flex; + } + } + + .name-active { + color: #4eb331; + font-size: 11px; + margin-top: 5px; + margin-left: 20rpx; + transition: all 0.5s; + } + + .packname { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + font-size: 20rpx; + color: #999; + } + } + + .do-business-root { + display: flex; + align-items: center; + justify-content: center; + background: #3e8f27; + border-radius: 80rpx; + color: #cccccc; + margin-right: 10rpx; + transition: all 0.4s; + font-size: 24rpx; + + .text { + padding: 0 15rpx; + } + } + + .business-active { + background-color: #ffad49; + color: #fff; + } + + .btn2 { + width: 200rpx; + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/platformM/platformM.vue b/src/subPages/merchantChild/platformM/platformM.vue new file mode 100644 index 0000000..62268c7 --- /dev/null +++ b/src/subPages/merchantChild/platformM/platformM.vue @@ -0,0 +1,120 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/printerSetUp/printerSetUp.scss b/src/subPages/merchantChild/printerSetUp/printerSetUp.scss new file mode 100644 index 0000000..66bdf61 --- /dev/null +++ b/src/subPages/merchantChild/printerSetUp/printerSetUp.scss @@ -0,0 +1,224 @@ +.Tips { + box-sizing: border-box; + padding: 0 20rpx; + margin-top: 20rpx; + width: 100%; + text-align: center; +} + +.Tipss { + box-sizing: border-box; + padding: 0 20rpx; + margin-top: 20rpx; + width: 100%; +} + +.printer-root { + display: flex; + justify-content: space-between; + box-sizing: border-box; + padding: 20rpx; + + .left { + box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + height: 170rpx; + margin-right: 20rpx; + border-radius: 5rpx; + background-color: $jx-primary; + color: #fff; + } + + .right { + box-sizing: border-box; + display: flex; + flex-direction: column; + justify-content: space-between; + width: 100%; + height: 170rpx; + margin-left: 20rpx; + + .active1 { + background-color: #24810b !important; + } + + .btn { + border-radius: 5rpx; + width: 100%; + height: 70rpx; + line-height: 70rpx; + background-color: $jx-primary; + font-size: 25rpx; + color: #fff; + } + + .setState { + background-color: #f09a2a; + } + + .active2 { + background-color: #24810b !important; + } + + } +} + +.btn-root { + display: flex; + + button { + width: 100%; + height: 70rpx; + line-height: 70rpx; + } +} + +.text-printer { + background-color: $jx-primary; + margin: 20rpx; + font-size: 25rpx; + color: #fff; + border-radius: 5rpx; +} + +.active3 { + background-color: #24810b !important; +} + +.text-printer1 { + background-color: rgba($color: $jx-warring, $alpha: 0.6); + margin: 20rpx; + font-size: 25rpx; + color: #fff; + border-radius: 5rpx; +} + +.active4 { + background-color: $jx-warring !important; +} + + +.printer-list { + position: relative; + padding: 0 20rpx; + box-sizing: border-box; + height: 60vh; + + .fjsb { + box-sizing: border-box; + padding-left: 20rpx; + border-left: 5rpx solid $jx-primary; + } +} + + +.bt-list { + box-sizing: border-box; + margin-bottom: 4rpx; + + .cgreen { + width: 4rpx; + background: $jx-primary !important; + margin-left: 4rpx; + } + + .van-cell { + font-size: 32rpx; + align-items: center; + } + + .bt-item { + padding: 20rpx; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1rpx solid #dfdfdf; + border-top: 1rpx solid #dfdfdf; + } + + .link-btn { + font-size: 26rpx; + background: #fafafa; + border: 1rpx solid $jx-primary; + color: $jx-primary; + width: 120rpx; + height: 54rpx; + border-radius: 6rpx; + text-align: center; + line-height: 54rpx; + padding: 0; + margin: 0; + } + + .active { + background-color: $jx-primary; + } + + // 断开按钮 + .activelink { + background: $jx-primary; + color: white; + } + + .dev-single-name { + width: 500rpx; + white-space: nowrap; + overflow: hidden; + } + + .dev-name { + display: inline-block; + vertical-align: middle; + + div:nth-of-type(1) { + font-size: 26rpx; + margin: 0; + padding: 0; + } + + div:nth-of-type(2) { + font-size: 20rpx; + padding: 0; + } + } + + .single { + box-sizing: border-box; + display: inline-flex; + justify-content: space-between; + align-items: baseline; + height: 22rpx; + margin-right: 16rpx; + + &>span { + width: 4rpx; + height: 22rpx; + background: rgba(0, 0, 0, 0.1); + margin: 0 1rpx; + + &:nth-of-type(1) { + height: 5rpx; + } + + &:nth-of-type(2) { + height: 12rpx; + } + + &:nth-of-type(3) { + height: 5rpx; + } + + &:nth-of-type(4) { + height: 19rpx; + } + + &:nth-of-type(5) { + height: 22rpx; + } + } + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/printerSetUp/printerSetUp.ts b/src/subPages/merchantChild/printerSetUp/printerSetUp.ts new file mode 100644 index 0000000..0dcdbd3 --- /dev/null +++ b/src/subPages/merchantChild/printerSetUp/printerSetUp.ts @@ -0,0 +1,386 @@ +/** + * 蓝牙打印机 + */ +import { store } from '@/store' +import { cleatStorage, getStorage, setStorage } from '@/utils/storage' +import toast from '@/utils/toast' +import { versionCompare, jx_throttles } from '@/utils/tools' +import { onLoad } from '@dcloudio/uni-app' +import { ref, onBeforeUnmount } from 'vue' +import Bluetooth from '@/utils/bluetoothPrinter/bluetooth' +import util from '@/utils/bluetoothPrinter/util' +import useOrderInfo from '@/composables/useOrderInfo' +import useGlobalFunc from '@/composables/useGlobalFunc' +import { jx_trembling } from '@/utils/tools' + +function printerSetUp() { + // const bluetooth = new Bluetooth() + const bluetooth: any = ref() // 方便通过微信审核,切勿直接赋值 + const { bluetoothPrinter } = useOrderInfo() + const { setPrinterStatus } = useGlobalFunc() + + /** + * 查看版本是否支持 + */ + onLoad(() => { + // 获取本机信息 + let sysInfo = JSON.parse(store.state.serveInfo.sysInfo) + + if (versionCompare('6.5.7', sysInfo.version)) { + uni.jxAlert({ + title: '温馨提示', + content: '当前微信版本过低,请升级', + success: () => { + uni.navigateBack() + } + }) + } + + + // 当前设备名称 打印机id + printerName.value = newPrinterName() + printerVID.value = getStorage('deviceId') + + // 检查当前蓝牙状态 + if (bluetooth.value) bluetooth.value.openBluetoothAdapter() + }) + function newPrinterName(): string { + let name = getStorage('deviceName') + if (name) { + return name + } else { + return '请选择设备' + } + } + + /** + * @desc 检查蓝牙当前状态 + */ + function bluetoothAdapter() { + if (!bluetooth.value) bluetooth.value = new Bluetooth() + bluetooth.value.openBluetoothAdapter() + } + + /** + * @desc 搜索蓝牙 + */ + const blueToothChecked = ref(false) + function initBlue() { + if (!bluetooth.value) { + uni.jxConfirm({ + title: '提示', + content: '是否授权蓝牙连接功能', + success: () => { + bluetoothAdapter() + initBlueThrottles() + } + }) + } + + } + const initBlueThrottles = jx_throttles({ + time: 5000, + success: () => { + bluetooth.value.openBluetoothAdapter(). + then(() => { + setupTwo() // 进入第二步 + }) + .catch((error: string | undefined) => { + toast(error) + }) + }, fail: (t: number) => { + toast(`请${t}秒后再试`) + } + }) + + + /** + * @desdc 第二步初判断本机蓝牙是否可用 + */ + function setupTwo() { + util.getBTAdapterState() + .then((res: any) => { + if (res.available) { + if (res.discovering) { + bluetooth.value.stopBluetoothDevicesDiscovery() // 停止搜索蓝牙 + } else { + setupTherr(); + } + } else { + toast('本机蓝牙不可用') + } + }) + .catch((error) => { + toast(error) + }) + } + + + /** + * @desdc 第三步开始获取附近蓝牙 + */ + function setupTherr() { + bluetooth.value.startBluetoothDevicesDiscovery() + ?.then(() => { + setupFour() + }). + catch((error: string | undefined) => { + toast(error,) + }) + } + + + /** + * @desdc 第四步获取附近连接或者没有连接过的蓝牙 + */ + interface SetDataType { + list: Array, + services: Array, + serviceId: number, + writeCharacter?: boolean, + readCharacter?: boolean, + notifyCharacter?: boolean, + } + const setData = ref({ + list: [], + services: [], + serviceId: 0, + writeCharacter: false, + readCharacter: false, + notifyCharacter: false, + }) + const isScanning = ref(false) + let setupFourTimer: any = null + function setupFour() { + isScanning.value = true // 正在搜索 + uni.showLoading({ + title: '正在搜索蓝牙...', + mask: true + }) + clearTimeout(setupFourTimer) + setupFourTimer = setTimeout(() => { + bluetooth.value.getBluetoothDevices() + .then((res: any) => { + var devices = []; + var num = 0; + for (var i = 0; i < res.devices.length; ++i) { + if (res.devices[i].name != "" && res.devices[i].localName != "") { + devices[num] = res.devices[i]; + devices[num].RSSI = Math.floor(max(0, devices[num].RSSI + 100) / 10) + num++; + } + } + + setData.value.list = devices + bluetooth.value.stopBluetoothDevicesDiscovery() // 停止搜索 + }) + .catch((error: string | undefined) => { + toast(error) + }) + .finally(() => { + isScanning.value = false // 搜索完成 + uni.hideLoading() + }) + }, 2000) + } + // 信号大小 + function max(n1: number, n2: number) { + return Math.max(n1, n2) + } + + /** + * @desc 第五步 + * 开始链接蓝牙 + */ + const printerName = ref('') // 打印机名字 + const printerVID = ref('') // 打印机ID + const serviceList = ref>([]) + + const linkBLENew = jx_trembling(async (deviceId: string, deviceName: string) => { + bluetooth.value.deviceId = deviceId + serviceList.value = [] + + try { + //1.链接设备 + await bluetooth.value.createBLEConnection() + + uni.showLoading({ + title: '正在获取蓝牙设备服务', + }) + //2.寻找服务 + await bluetooth.value.getBLEDeviceServices().then((res: AnyObject[]) => { + uni.hideLoading() + serviceList.value = res + res.forEach((item: AnyObject) => { + getBLEDevCharact(deviceId, item.uuid, deviceName) + }) + }) + } catch (e) { + uni.hideLoading() + uni.jxAlert({ + title: '提示', + content: '连接失败,请重试,或者先断开其他已经连接的设备' + }) + } + },800) + + function linkBLE(deviceId: string, deviceName: string) { + linkBLENew(deviceId, deviceName) + } + + // 获取特征值 + let timer: any = null + function getBLEDevCharact(deviceId: string, serviceId: string, deviceName: string) { + let json = { + deviceId, + serviceId, + deviceName, + uuid: '' + } + uni.getBLEDeviceCharacteristics({ + deviceId, + serviceId, + success: res => { + res.characteristics.forEach(item => { + // 同时要有读写监听的权限 + if (item.properties.read && item.properties.write && item.properties.notify) { + // 找到需要的特征 + json.uuid = item.uuid + setStorage('commitBTDevCharact', json) + toast('连接成功') + setPrinterStatus() + store.commit('storeInfo/setIsConnectPrinter', true) + printerName.value = deviceName + printerVID.value = deviceId + setStorage('deviceId', deviceId) + setStorage('deviceName', deviceName) + clearTimeout(timer) + timer = setTimeout(() => { + setState() + clearTimeout(timer) + }, 2500) + } + }) + }, + fail: error => { + printerName.value = '请选择设备' + printerVID.value = '' + toast('获取打印机权限失败请重试') + } + }) + } + + + /** + * 设备状态 + */ + function setState() { + let data: any = getStorage('commitBTDevCharact') + util.notifyBLEState(data.deviceId, data.serviceId, data.uuid) + .then((res) => { + switch (res) { + case 12: + toast('打印机正常') + break + case 32: + toast('打印机缺纸') + break + case 36: + toast('开盖、缺纸') + break + case 16: + toast('打印机开盖') + break + case 40: + toast('打印机未启动') + break + default: + toast('设备断开') + } + }) + .catch((error) => { + toast(error) + // 清除缓存 + cleatStorage('deviceId') + cleatStorage('deviceName') + cleatStorage('commitBTDevCharact') + printerName.value = '请选择设备' + printerVID.value = '' + }) + } + + /************************************************* + * 清除打印机缓存 + */ + function clearPrinter() { + cleatStorage('deviceId') + cleatStorage('deviceName') + cleatStorage('commitBTDevCharact') + uni.jxAlert({ + title: '提示', + content: '清除缓存成功,请重新启动软件!', + success: () => { + plus.runtime.restart() + } + }) + } + + /** + * 测试打印 + */ + let timer1: any = null + function testPrint() { + util.getBTAdapterState() + .then(async () => { + bluetoothPrinter('901234567890123') + }) + .catch(() => { + uni.jxAlert({ + title: '提示', + content: '打开系统蓝牙,如果系统蓝牙已打卡请点右上角胶囊的《三个点点》->《设置》->《设置蓝牙为允许》' + }) + }) + } + + + /************************************************* + * 断开蓝牙连接 + */ + function closeBLE(deviceId: string) { + printerName.value = '请选择设备' + printerVID.value = '' + cleatStorage('deviceId') + cleatStorage('deviceName') + cleatStorage('commitBTDevCharact') + bluetooth.value.deviceId = deviceId + bluetooth.value.closeBLEConnection() + } + + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + clearTimeout(setupFourTimer) + clearTimeout(timer) + clearTimeout(timer1) + }) + + + return { + printerName, // 当前打印机名字 + blueToothChecked, // 动态监听蓝牙开关 + initBlue, // 初始化蓝牙 + setData, // 蓝牙列表 + setState, // 设备状态 + linkBLE, // 选择蓝牙 + closeBLE, // 断开蓝牙 + testPrint, // 测试打印 + printerVID, // 打印机ID + isScanning, // 是否正在搜索打印机 + clearPrinter, // 清除缓存 + } +} + + +export default printerSetUp \ No newline at end of file diff --git a/src/subPages/merchantChild/printerSetUp/printerSetUp.vue b/src/subPages/merchantChild/printerSetUp/printerSetUp.vue new file mode 100644 index 0000000..801eac1 --- /dev/null +++ b/src/subPages/merchantChild/printerSetUp/printerSetUp.vue @@ -0,0 +1,150 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.scss b/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.scss new file mode 100644 index 0000000..018590e --- /dev/null +++ b/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.scss @@ -0,0 +1,129 @@ +.info{ + text-align: center; + .logo { + width: 300rpx; + height: 300rpx; + margin-top: 40rpx; + } + + .storeStatus{ + margin: 20rpx; + height: 220rpx; + background:linear-gradient(180deg, #a4e8f5, #fff); + border-top-right-radius: 20rpx; + border-top-left-radius: 20rpx; + padding: 20rpx; + + .status,.timeInfo{ + display: flex; + justify-content: center; + margin-top: 10rpx; + } + + .status,.timeInfo{ + font-size: 28rpx; + } + + .title1,.title2{ + font-weight: bold; + } + + .title2{ + margin-top: 20rpx; + } + + .timeInfo{ + .timRange2{ + margin-left: 20rpx; + } + } + } + + .time{ + background: #fff; + height: 220rpx; + margin:-40rpx 20rpx 20rpx 20rpx; + border-radius: 20rpx; + border: 1rpx solid #eee; + padding: 20rpx; + display: flex; + flex-direction: column; + justify-content: space-around; + } + + .timeItem{ + background-color: #cccccc; + border-radius: 20rpx; + padding: 10rpx; + color:#fff; + } + .disabledColor{ + opacity: 0.6; + background-color: #ffad49; + } + + .notice{ + border: 1rpx solid #eee; + text-align: left; + margin:20rpx; + padding: 20rpx; + color:rgb(241, 167, 114); + font-size: 28rpx; + border-radius: 20rpx; + } +} + +.jx-popup-update { + box-sizing: border-box; + padding: 20rpx; + background-color: #fff; + border-radius: 0 0 15rpx 15rpx; + width: 94vw; + + .text { + display: block; + width: 100%; + text-align: center; + margin-bottom: 25rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid rgb(209, 209, 209); + } + + .ipt { + border: 2rpx solid rgb(209, 209, 209); + text-align: center; + height: 140rpx; + border-radius: 5rpx; + padding-bottom: 20rpx; + } + + .item{ + margin-top: 20rpx; + } + + .btn-root { + display: flex; + justify-content: space-between; + margin: 40rpx 0 0rpx 0; + + .btn-esc, + .btn-ok { + text-align: center; + width: 100%; + padding: 15rpx 0; + border-radius: 10rpx; + border: 2rpx solid $jx-primary; + color: $jx-primary; + } + + .btn-ok { + background-color: $jx-primary; + color: #fff; + margin-left: 10rpx; + } + + .btn-esc { + margin-right: 10rpx; + } + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.ts b/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.ts new file mode 100644 index 0000000..7754588 --- /dev/null +++ b/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.ts @@ -0,0 +1,203 @@ +import { computed, ref } from 'vue' +import { onLoad } from "@dcloudio/uni-app"; +import { getStorage } from '@/utils/storage'; +import merchant from '@/api/https/merchant'; +import { timeFormatD } from "@/utils/tools"; +import useGlobalFunc from '@/composables/useGlobalFunc'; +import { store } from '@/store' +import toast from "@/utils/toast"; +export default { + setup() { + const businessStatusList = ref([ + { id: 1, name: '营业' }, + { id: 0, name: '临时休息' }, + { id: -1, name: '休息' } + // { id: -2, name: '禁用' }, + ]) + const businessHours = ref({}) // 营业时间段 + const businessStatus = ref(1) // 营业状态,默认营业 + const newAutoEnableAt = ref('') + const popupTime = ref() + const dayList = ref(["休息到明天", "休息到后天"]); + const currentTime = ref(0) + const storeName = ref('') // 门店名称 + + const { isTxd } = useGlobalFunc() + + onLoad(async () => { + store.commit('storeInfo/jxLoadingFn', true) + await getStores() + store.commit('storeInfo/jxLoadingFn', false) + }) + + + const switchOpenTime = computed(() => { + if (newAutoEnableAt.value) { + let now = +new Date(timeFormatD(+new Date())); + let time = +new Date(timeFormatD(newAutoEnableAt.value)); + let num = time - now; + if (num < 0) { + return "营业时间错误请联系运营"; + } else { + let day = num / 1000 / 3600 / 24; + if (day < 1) return "门店将在今天自动营业"; + else if (day >= 1 && day < 2) return "门店将在明天自动营业"; + else if (day >= 2 && day < 3) return "门店将在后天自动营业"; + else return `将在 ${timeFormatD(newAutoEnableAt.value)} 自动营业`; + } + } else { + return ""; + } + }) + + /** + * 获取门店数据 + */ + async function getStores() { + await store.dispatch('storeInfo/getOneStore',getStorage("storeID")) + const stateData = store.state.storeInfo.allStoreInfo + storeName.value = stateData.name // 门店名 + businessStatus.value = stateData.status // 营业状态 + newAutoEnableAt.value = stateData.autoEnableAt // 手机门店休息时间 + businessHours.value = store.getters['storeInfo/businessHours'] // 营业时间 + } + + + /************************************************* + * 去修改营业时间 + */ + function setTime() { + uni.navigateTo({ url: `/subPages/merchantChild/setBusinessTime/setBusinessTime` }) + } + + /************************************************* + * 修改营业状态 + */ + function setStatus(item: AnyObject) { + if (item.id === businessStatus.value) return + // console.log('修改营业状态', item) + + if (item.id === 1) { + uni.jxConfirm({ + title: '提示', + content: '确定要将此门店设置为营业吗?', + success: async () => { + let data = { + storeID: getStorage("storeID"), + payload: JSON.stringify({ + status: 1, + }), + }; + await merchant.update_store(data); + setTxdIngState(1) + newAutoEnableAt.value = '' + toast("操作成功", 1) + // state.value = 1; + // businessStatus.value = item.id + await getStores() + // uni.navigateBack() + }, + }) + } else if (item.id === 0) { + // console.log('设置门店为临时休息') + popupTime.value.open() + // businessStatus.value = item.id + } else if (item.id === -1) { + uni.jxConfirm({ + title: '提示', + content: '确定要将此门店设置为休息吗?', + success: async () => { + let data = { + storeID: getStorage("storeID"), + payload: JSON.stringify({ + status: -1, + }), + }; + await merchant.update_store(data); + setTxdIngState(-1) + newAutoEnableAt.value = '' + // businessStatus.value = item.id + toast("操作成功", 1) + await getStores() + // uni.navigateBack() + }, + }) + } else { + // 禁用 + } + } + + /** + * 设置第三方平台 + */ + async function setTxdIngState(type: number) { + if (isTxd()) { + let data = { + vendorOrgCode: 34402634, + txdStores: JSON.stringify({ + flag: [1], + txdStoreID: `JX${getStorage('storeID')}`, + status: type + }) + } + await merchant.update_txd_store(data) + } + + // 更新线上平台的营业状态 + let arr = store.state.storeInfo.allStoreInfo.StoreMaps.map((item: AnyObject) => { + if (item.isSync) return item.vendorID + '' + }) + + arr = arr.filter((item: string) => item !== '9') + if (arr.length > 0) { + let data = { + storeID: getStorage('storeID'), + vendorIDs: arr.join(','), + status: type + } + await merchant.update_vendors_store_states(data); + } + // uni.navigateBack() + } + + async function storeRest() { + let autoEnableAt = currentTime.value + ? timeFormatD(+new Date() + 2 * 24 * 3600 * 1000) + : timeFormatD(+new Date() + 1 * 24 * 3600 * 1000) + let data = { + storeID: getStorage("storeID"), + payload: JSON.stringify({ + status: 0, + autoEnableAt, + }), + }; + await merchant.update_store(data); + setTxdIngState(0) + toast("操作成功", 1); + popupTime.value.close() + businessStatus.value = 0; + newAutoEnableAt.value = autoEnableAt + getStores() + } + + function radioChange(e: any) { + let findIndex = dayList.value.findIndex(item => item === e.detail.value) + if (findIndex !== -1) currentTime.value = findIndex + } + + return { + businessStatusList, // 营业时间列表 + businessHours, // 营业时间段 + businessStatus, // 营业状态 + switchOpenTime, // 临时休息 多久后自动回复营业 + setTime, // 去修改营业时间 + setStatus, // 修改营业状态 + popupTime, // 临时休息的时间弹框 + dayList, // 临时休息时间段 + currentTime, // 临时休息时间 动态index + storeRest, // 临时休息的时间弹框 确认 + radioChange, // 临时休息的时间弹框 change事件 + storeName // 门店名 + } + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.vue b/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.vue new file mode 100644 index 0000000..03ad3d4 --- /dev/null +++ b/src/subPages/merchantChild/setBusinessStatus/setBusinessStatus.vue @@ -0,0 +1,81 @@ + + + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/setBusinessTime/setBusinessTime.scss b/src/subPages/merchantChild/setBusinessTime/setBusinessTime.scss new file mode 100644 index 0000000..195f71f --- /dev/null +++ b/src/subPages/merchantChild/setBusinessTime/setBusinessTime.scss @@ -0,0 +1,68 @@ +.info { + padding: 30rpx 30rpx 60rpx 30rpx; + box-sizing: border-box; + background: linear-gradient(0deg, #ffe2d2, #fdf6f0); + font-size: 28rpx; +} + +.time-root { + padding: 30rpx; + box-sizing: border-box; + margin-top: -35rpx; + border-radius: 30rpx 30rpx 0 0; + background-color: #fff; + + .time { + display: flex; + justify-content: space-between; + align-items: center; + background-color: #f6f7fb; + border-radius: 15rpx; + + text { + display: inline-block; + padding: 0 20rpx; + box-sizing: border-box; + } + + view { + width: 100%; + text-align: center; + padding: 20rpx; + box-sizing: border-box; + } + + .time-active { + box-sizing: border-box; + padding: 18rpx; + border: 2rpx solid $jx-primary; + border-radius: 15rpx; + } + } +} + +.tip { + font-size: 26rpx; + margin-bottom: 15rpx; + color: red; +} + +.button { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + background-color: #fff; + padding: 30rpx; + box-sizing: border-box; + box-shadow: -10rpx 0rpx 10rpx rgb(166, 166, 166); + + + view { + background: linear-gradient(90deg, #ffe14f, #fdc450); + border-radius: 50rpx; + padding: 20rpx 0; + text-align: center; + box-sizing: border-box; + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/setBusinessTime/setBusinessTime.ts b/src/subPages/merchantChild/setBusinessTime/setBusinessTime.ts new file mode 100644 index 0000000..48ebc86 --- /dev/null +++ b/src/subPages/merchantChild/setBusinessTime/setBusinessTime.ts @@ -0,0 +1,175 @@ +import { computed, ref } from 'vue' +import { onLoad } from "@dcloudio/uni-app"; +import { getStorage } from '@/utils/storage'; +import merchant from '@/api/https/merchant'; +import useGlobalFunc from '@/composables/useGlobalFunc'; +import { store } from "@/store"; + +export default { + setup() { + const { isTxd } = useGlobalFunc() + + // ******************** 时间选择组件操作 ***************************** + //#region + const dateTimePicker = ref(null) // 时间组件实例 + const timeActive = ref(0) // 时间选择高亮 + const timeIng = ref('00:00') // 选择器的当前时间 + // 确认选择时间 + function confirm(e: AnyObject): void { + switch (timeActive.value) { + case 1: + businessTime.value.timer1 = e.value + break + case 2: + businessTime.value.timer2 = e.value + break + case 3: + businessTime.value.timer3 = e.value + break + case 4: + businessTime.value.timer4 = e.value + break + } + } + // 打开时间设置 + function setTime(type: number): void { + timeActive.value = type + let time = businessTime.value + switch (type) { + case 1: + timeIng.value = time.timer1 + break + case 2: + timeIng.value = time.timer2 + break + case 3: + timeIng.value = time.timer3 + break + case 4: + timeIng.value = time.timer4 + break + } + dateTimePicker.value.open() + } + // 时间标题 + const timeTitle = computed(() => { + let type = timeActive.value + if (type == 1 || type == 3) { + return '选择开始时间' + } else { + return '选择结束时间' + } + }) + //#endregion + + + // ******************** 获取门店营业时间 ***************************** + //#region + const businessTime = ref({}) + onLoad(async() => { + store.commit('storeInfo/jxLoadingFn', true) + if(!store.getters['storeInfo/businessHours']) await store.dispatch('storeInfo/getOneStore',getStorage("storeID")) + businessTime.value = store.getters['storeInfo/businessHours'] + store.commit('storeInfo/jxLoadingFn', false) + }) + //#endregion + + + // ******************** 保存营业时间 ***************************** + //#region + async function saveBusinessTime() { + let time = businessTime.value + // 一开始时间大于结束时间 + if (formatTime(time.timer1) >= formatTime(time.timer2)) { + return uni.jxAlert({ + title: '营业时间一', + content: `开始时间不能大于结束时间,您可以修改为【${time.timer2}至${time.timer1}】` + }) + } + // 第二段时间小于第一段时间 + if (time.timer3 != '00:00' && time.timer4 != '00:00') { + if (formatTime(time.timer3) < formatTime(time.timer2)) { + return uni.jxAlert({ + title: '提示', + content: `第二段营业时间不能小于第一段营业时间,您可以修改到【${time.timer2}】点之后` + }) + } + } + // 二开始时间大于结束时间 + if (formatTime(time.timer3) > formatTime(time.timer4)) { + return uni.jxAlert({ + title: '营业时间二', + content: `开始时间不能大于结束时间,您可以修改为【${time.timer3}至${time.timer4}】` + }) + } + + // 校验通过 + let data = { + storeID: getStorage("storeID"), + payload: JSON.stringify({ + openTime1: formatTime(time.timer1), + closeTime1: formatTime(time.timer2), + openTime2: formatTime(time.timer3), + closeTime2: formatTime(time.timer4), + }), + } + let updateTimerRes = await merchant.update_store(data); + if (updateTimerRes.code == 0) { + uni.jxAlert({ + title: '提示', + content: '修改成功,请返回下拉刷新', + success: () => { + uni.navigateBack() + } + }) + } else { + uni.jxAlert({ + title: '操作提示', + content: `提示:${updateTimerRes.desc}`, + success: () => { + uni.navigateBack() + } + }) + } + } + // 格式化数据 + function formatTime(time: string): number { + let newTime = time.slice(0, 2) + time.slice(-2) + return +newTime + } + //#endregion + + + // ******************** 修改淘鲜达线上时间 ***************************** + //#region + async function setTxdIngTime(time: AnyObject) { + if (isTxd()) { + let data = { + vendorOrgCode: 34402634, + txdStores: JSON.stringify({ + flag: [2], + txdStoreID: `JX${getStorage('storeID')}`, + startTime: time.timer1, + endTime: time.timer2 + }) + } + let res = await merchant.update_txd_store(data) + console.log('ZSW-res', res); + } else { + console.log('此店铺暂无淘鲜达店铺') + } + } + //#endregion + + return { + dateTimePicker, // 时间组件实例 + confirm, // 选择时间val + businessTime, // 营业时间 + timeActive, // 时间选择高亮 + setTime, // 打开时间设置 + timeTitle, // 选择器标题 + saveBusinessTime, // 确定修改时间 + timeIng, // 选择器的当前时间 + } + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/setBusinessTime/setBusinessTime.vue b/src/subPages/merchantChild/setBusinessTime/setBusinessTime.vue new file mode 100644 index 0000000..8e11f70 --- /dev/null +++ b/src/subPages/merchantChild/setBusinessTime/setBusinessTime.vue @@ -0,0 +1,75 @@ + + + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.scss b/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.scss new file mode 100644 index 0000000..865894c --- /dev/null +++ b/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.scss @@ -0,0 +1,54 @@ +.info{ + text-align: center; + .logo { + width: 300rpx; + height: 300rpx; + margin-top: 40rpx; + } + + .storeStatus{ + margin: 20rpx; + // height: 220rpx; + background:linear-gradient(180deg, #d6f7d0, #fff); + border-top-right-radius: 20rpx; + border-top-left-radius: 20rpx; + padding: 20rpx; + + box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 12px 0px; + + .title1{ + font-weight: bold; + } + } + + + + .item{ + display: flex; + justify-content: center; + margin-bottom: 20rpx; + } + + .uni-input{ + border: 1px solid #bfbaba; + width: 350rpx; + margin-left: 10rpx; + padding: 10rpx; + border-radius: 20rpx; + } + + .save_button{ + background-color: #4eb331; + color:#fff; + border-radius: 20rpx; + height: 92rpx; + border-radius: 20rpx; + line-height: 92rpx; + font-size: 40rpx; + } + + .disabledColor{ + opacity: 0.6; + background-color: #ffad49; + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.ts b/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.ts new file mode 100644 index 0000000..d2c8971 --- /dev/null +++ b/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.ts @@ -0,0 +1,159 @@ +import { ref, watch } from 'vue' +import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app"; +import { getStorage } from '@/utils/storage'; +import { store } from '@/store' +import toast from "@/utils/toast"; +import order from '@/api/https/order'; +export default { + setup() { + const invoiceInfo = ref({ + invoice_contact:{ + person:"", + phone:"" + }, + invoice_mode:"", // 开具方式 + invoice_material:"", // 发票材质 + invoice_class:"", // 发票种类 + }) + const invoice_mode_array = ref([{value:'empty',label:'无'},{value:'SYS_MANUAL',label:'人工开具'},{value:'OPEN_API',label:'开放平台'},{value:'FLASH_INVOICE',label:'闪电开票'},{value:'CODE_INVOICE',label:'扫码开票'},{value:'H5_REDIRECT',label:'H5植入'},{value:'OTHER',label:'其他形式'}]) + const invoice_mode_index = ref(0) + + const invoice_material_array = ref([{value:'empty',label:'无'},{value:'PAPER',label:'纸质'},{value:'ELECTRONIC',label:'电子'}]) + const invoice_material_index = ref(0) + + const invoice_class_array = ref([{value:'empty',label:'无'},{value:'VAT_COMMON',label:'普通发票'},{value:'VAT_SPECIAL',label:'专用发票'},{value:'QUOTA',label:'定额发票'}]) + const invoice_class_index = ref(0) + + const invoice_contact_name = ref('') + const invoice_contact_phone = ref('') + const storeName = ref('') // 门店名称 + const ebaiStore = ref({}) + + + onLoad(async () => { + store.commit('storeInfo/jxLoadingFn', true) + await getStores() + store.commit('storeInfo/jxLoadingFn', false) + }) + + + watch(() => store.getters['storeInfo/platformInfo'], + (val) => { + if(val && val.length>0){ + let findItem = val.filter((item:AnyObject) => item.vendorID === 3) + if(findItem && findItem.length>0) { + ebaiStore.value = findItem[0] + console.log('findItem[0]',findItem[0]) + queryEbStoreInvoice() + } + } + }) + + /** + * 下拉刷新 + */ + onPullDownRefresh(async () => { + store.commit('storeInfo/jxLoadingFn', true) + await getStores() + await queryEbStoreInvoice() + store.commit('storeInfo/jxLoadingFn', false) + }) + + + /** + * 获取门店数据 + */ + async function getStores() { + await store.dispatch('storeInfo/getOneStore',getStorage("storeID")) + const stateData = store.state.storeInfo.allStoreInfo + storeName.value = stateData.name // 门店名 + + + } + + + /** + * 查询门店发票设置 + */ + async function queryEbStoreInvoice() { + let res = await order.query_invoice_setting({ + vendorId:'3', + vendorStoreID:ebaiStore.value.vendorStoreID + + }) + if(res.code === '0'){ + invoiceInfo.value = res.data[0].settings + if(invoiceInfo.value.invoice_mode){ + let findIndex = invoice_mode_array.value.findIndex(item => item.value === invoiceInfo.value.invoice_mode) + if(findIndex !== -1 ) invoice_mode_index.value = findIndex + } + + if(invoiceInfo.value.invoice_material){ + let findIndex = invoice_material_array.value.findIndex(item => item.value === invoiceInfo.value.invoice_material) + if(findIndex !== -1 ) invoice_material_index.value = findIndex + } + + if(invoiceInfo.value.invoice_class){ + let findIndex = invoice_class_array.value.findIndex(item => item.value === invoiceInfo.value.invoice_class) + if(findIndex !== -1 ) invoice_class_index.value = findIndex + } + } + } + + + + + + /** + * 选择确认框 + */ + function bindPickerChange(e:any,type:string) { + if(type === 'invoice_mode') invoice_mode_index.value = e.target.value + if(type === 'invoice_material') invoice_material_index.value = e.target.value + if(type === 'invoice_class') invoice_class_index.value = e.target.value + } + + + /** + * 保存发票信息 + */ + async function saveInvoiceInfo() { + try { + let findItem = store.getters['storeInfo/platformInfo'].filter((item:AnyObject) => item.vendorID === 3) + if(findItem.length === 0) return toast('未绑定饿百门店',2) + // if(!ebStoreInfo || JSON.stringify(ebStoreInfo) === '{}') return toast('未绑定饿百门店') + if(+invoice_mode_index.value) invoiceInfo.value.invoice_mode = invoice_mode_array.value[invoice_mode_index.value].value + if(+invoice_material_index.value) invoiceInfo.value.invoice_material = invoice_material_array.value[invoice_material_index.value].value + if(+invoice_class_index.value) invoiceInfo.value.invoice_class = invoice_class_array.value[invoice_class_index.value].value + // console.log(store,'保存发票的信息数据,9999',invoiceInfo.value,'invoice_contact_name',invoice_contact_name.value,'invoice_contact_phone*********',invoice_contact_phone.value) + let res = await order.bath_update_invoice_setting({ + vendorId:'3', + vendorStoreID:findItem[0].vendorStoreID, + payload:JSON.stringify(invoiceInfo.value) + }) + if(res.success.length>0 && !res.success[0].msg){ + toast('修改成功',1) + }else toast('修改失败',2) + uni.hideLoading() + } catch (error) { + uni.hideLoading() + throw error + } + } + + return { + invoiceInfo, // 发票信息 + invoice_contact_name, + invoice_contact_phone, + invoice_mode_array, // 开具方式 + invoice_mode_index, // 开具方式索引 + invoice_material_array, // 发票材质 + invoice_material_index, // 发票材质索引 + invoice_class_array, // 发票种类 + invoice_class_index, // 发票种类索引 + bindPickerChange, // 选择确认框 + saveInvoiceInfo, // 保存发票信息 + storeName // 门店名 + } + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.vue b/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.vue new file mode 100644 index 0000000..a9f588c --- /dev/null +++ b/src/subPages/merchantChild/setInvoiceEB/setInvoiceEB.vue @@ -0,0 +1,59 @@ + + + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/setUp/setUp.scss b/src/subPages/merchantChild/setUp/setUp.scss new file mode 100644 index 0000000..2311fab --- /dev/null +++ b/src/subPages/merchantChild/setUp/setUp.scss @@ -0,0 +1,186 @@ +// 公共样式 +%item { + box-sizing: border-box; + display: flex; + justify-content: space-between; + align-items: center; + padding: 25rpx; + border-bottom: 1rpx solid rgb(220, 220, 220); +} + +// 来单提示 +.tips-root { + background-color: #fff; + margin-top: 20rpx; + + .item { + @extend %item; + } +} + +// 未拣货提示 +.picking-root { + background-color: #fff; + + .item { + @extend %item; + + .text { + font-size: 28rpx; + color: $jx-primary; + } + } +} + +// 网络打印机 +.inter-printer { + margin-top: 20rpx; + background-color: #fff; + + .item { + @extend %item; + + .printer-name { + font-size: 28rpx; + color: rgb(139, 139, 139); + } + } +} + +// 蓝牙打印机 +.bluetooth-printer { + margin-top: 20rpx; + background-color: #fff; + + .item { + @extend %item; + + .printer-name { + font-size: 28rpx; + color: rgb(139, 139, 139); + } + + .text { + font-size: 28rpx; + color: $jx-primary; + } + } +} + +// 版权信息 +.copyRight-root { + margin-top: 20rpx; + background-color: #fff; + + .item { + @extend %item; + } +} + +.title-tip { + background-color: rgb(245, 245, 245); + padding: 0 0 20rpx 25rpx; + font-size: 30rpx; + color: #616161; + border-bottom: 1rpx solid rgb(220, 220, 220); +} + +.outLogin-root { + padding: 30rpx 60rpx; + box-sizing: border-box; + + .outLogin { + display: block; + padding: 20rpx; + background-color: $jx-primary; + color: #fff; + border-radius: 200rpx; + text-align: center; + } + + .accoutCancellation { + display: block; + padding: 20rpx; + background-color: $jx-warring; + color: #fff; + border-radius: 200rpx; + text-align: center; + margin-bottom: 20rpx; + } +} + +.jx-popup-update { + box-sizing: border-box; + padding: 20rpx; + background-color: #fff; + border-radius: 0 0 15rpx 15rpx; + + .text { + display: block; + width: 100%; + text-align: center; + margin-bottom: 25rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid rgb(209, 209, 209); + } + + // .tip { + // padding: 10rpx 0; + + // .money { + // color: $jx-primary; + // } + // } + + .ipt { + border: 2rpx solid rgb(209, 209, 209); + text-align: center; + height: 80rpx; + border-radius: 5rpx; + } + .scan-code{ + margin-top:20rpx; + width: 100%; + text-align: center; + border: 2rpx solid $jx-primary; + color: #fff; + border-radius: 10rpx; + padding: 15rpx 0; + background-color: $jx-primary; + } + .btn-root { + display: flex; + justify-content: space-between; + margin: 40rpx 0 0rpx 0; + + .btn-esc, + .btn-ok { + text-align: center; + width: 100%; + padding: 15rpx 0; + border-radius: 10rpx; + border: 2rpx solid $jx-primary; + color: $jx-primary; + } + + .btn-ok { + background-color: $jx-primary; + color: #fff; + margin-left: 10rpx; + } + + .btn-esc { + margin-right: 10rpx; + } + } + + // .delete { + // margin-top: 50rpx; + // margin-bottom: 20rpx; + // background-color: $jx-warring; + // text-align: center; + // color: #fff; + // padding: 20rpx; + // border-radius: 15rpx; + // } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/setUp/setUp.ts b/src/subPages/merchantChild/setUp/setUp.ts new file mode 100644 index 0000000..022647e --- /dev/null +++ b/src/subPages/merchantChild/setUp/setUp.ts @@ -0,0 +1,559 @@ +/** + * 系统设置 + */ + +import { store } from '@/store' +import { getStorage, setStorage } from '@/utils/storage' +import toast from '@/utils/toast' +import { onShow } from '@dcloudio/uni-app' +import { computed, nextTick, ref } from 'vue' +import useGlobalFunc from '@/composables/useGlobalFunc' +import merchant from '@/api/https/merchant' + +function setUp() { + const { logOutFn } = useGlobalFunc() + + /** + * 获取页面初始化信息 + */ + onShow(async () => { + await getStoreMsg() + }) + // 打印机品牌 + const printerData = ref({ + 0: '未绑定', + 201: '飞鹅打印机', + 202: '外卖管家打印机', + 203: '易联云打印机', + 204: '中午云打印机', + 205: '京西云打印机', + }) + const netPrinterData = ref>(['无', '外卖管家打印机', '易联云打印机', '中午云打印机', '京西云打印机']) + const defultNetPrinterValue = ref('') + const netPrinter = ref() + const recordIndex = ref('') // 记录打印机最初的序列号 + const popup = ref(null) // 弹窗实例 + + const currentNetPrinter = ref(['', '', '']) + const bindNetPrinter = ref({ + printerSN: '', + printerKey: '' + }) + async function getStoreMsg() { + // 读取vuex 中的 store 数据 + smsNotify.value = store.state.storeInfo.allStoreInfo.smsNotify + printerDisabled.value = store.state.storeInfo.allStoreInfo.printerDisabled + // 获取第三方美团门店 + if (JSON.stringify(store.state.storeInfo.allStoreInfo) !== '{}') { + let mtStore = store.state.storeInfo.allStoreInfo.StoreMaps.find((item: { vendorID: number }) => item.vendorID === 1) + if (mtStore) { + mtStoreInfo.value = mtStore + isExistMtStore.value = true + let mtStatus = store.state.storeInfo.imOnlineStatus.filter(item => item.vendorID === 1) + imMtStoreStatus.value = mtStatus[0].imStatus + } + + let ebStore = store.state.storeInfo.allStoreInfo.StoreMaps.find((item: { vendorID: number }) => item.vendorID === 3) + if (ebStore && JSON.stringify(ebStore) !== '{}') { + ebStoreInfo.value = ebStore + isExistEbStore.value = true + let ebStataus = store.state.storeInfo.imOnlineStatus.filter(item => item.vendorID === 3) + imEbStoreStatus.value = ebStataus[0].imStatus + } + } + // 网络打印机 + netPrinter.value = (store.state.serveInfo.serviceInfo as any).printerVendorInfo + for (let i in netPrinter.value) { + if (!printerData.value[i]) { + let printerName = netPrinter.value[i][0] + '打印机' + printerData.value[i] = printerName + netPrinterData.value.push(printerName) + } + } + + if (store.state.storeInfo.allStoreInfo.printerVendorID) { + for (let key in printerData.value) { + if (key == store.state.storeInfo.allStoreInfo.printerVendorID) { + let findIndex = netPrinterData.value.findIndex(item => item === printerData.value[key]) + if (findIndex !== -1) { + defultNetPrinterValue.value = findIndex + '' + recordIndex.value = defultNetPrinterValue.value + } + } + } + } + retryActive.value = (+getStorage('printerRetrySize')) + '' + defaultPrinterValue.value = getStorage('defaultPrinter') || '2' + + } + // // 打印机名字 + // const printerName = computed(() => { + // for (let key in printerData.value) { + // if (key == store.state.storeInfo.allStoreInfo.printerVendorID) { + // return printerData.value[key] + // } + // } + // }) + // 是否禁用打印机 + const printerDisabled = ref(0) + + // IM单聊状态是否开启 + const imMtStoreStatus = ref(0) + + // IM单聊状态是否开启-饿百 + const imEbStoreStatus = ref(0) + + // 美团门店信息 + const mtStoreInfo = ref({}) + + // 饿百门店信息 + const ebStoreInfo = ref({}) + + // 是否含有美团门店 + const isExistMtStore = ref(false) + + // 是否含有饿百门店 + const isExistEbStore = ref(false) + + + /** + * 京西版权信息 + */ + interface CopyRightType { + id: number + title: string + url: string + } + const copyRight = ref>([ + { + id: 1, + title: '用户协议', + url: '/subPages/agreement/user', + }, + { + id: 2, + title: '隐私协议', + url: '/subPages/agreement/privacy', + }, + { + id: 3, + title: '关于京西', + url: '/subPages/agreement/about', + }, + ]) + + // 未拣货提醒 + const smsNotifyData = ref>(['不提醒', '拣货超时短信提醒', '拣货超时电话提示']) + const smsNotify = ref('0') + function bindMultiPickerChange(item: AnyObject) { + if (store.state.storeInfo.allStoreInfo.packageSwitch === 1) { + let tel = store.state.storeInfo.allStoreInfo.marketManPhone ? store.state.storeInfo.allStoreInfo.marketManPhone : "18048531223" + uni.jxAlert({ + title: '设置失败', + content: `非常抱歉,无法设置拣货提醒,请联系运营${tel}` + }) + return + } + smsNotify.value = item.detail.value + switchSmsNotify() + } + // 切换未拣货提示方式 + async function switchSmsNotify() { + let data = { + storeID: getStorage('storeID'), + payload: JSON.stringify({ 'smsNotify': smsNotify.value }) + } + let res = await merchant.update_store(data) + if (res.code != 0) return toast('切换失败') + } + + + /************************************************* + * 默认打印机设备 + */ + const defaultPrinterValue = ref('0') + const defaultPrinter = ref>(['蓝牙打印机', '网络打印机', '手动选择打印机']) + // 切换打印设备 + function defaultPrinterChange(e: AnyObject) { + defaultPrinterValue.value = e.detail.value + setStorage('defaultPrinter', e.detail.value) + } + + + /** + * 选择网络打印机 + */ + async function updateNetPrinter(item: AnyObject) { + if (item.detail.value !== '0') { + defultNetPrinterValue.value = item.detail.value + for (let i in netPrinter.value) { + // if (netPrinter.value[i][0] + '打印机' === netPrinterData.value[item.detail.value]) { + if (netPrinterData.value[item.detail.value].includes(netPrinter.value[i][0])) { + currentNetPrinter.value = netPrinter.value[i] + popup.value.open() + } + } + } else { + defultNetPrinterValue.value = '' + let res = await merchant.update_store({ + storeID: store.state.storeInfo.allStoreInfo.id, + payload: JSON.stringify({ + printerVendorID: 0, + printerSN: '', + printerKey: '' + }) + }) + if (res.code == '0') { + toast("删除成功", 1); + getStores() + } else { + toast("删除失败", 2); + } + + } + } + + /** + * 绑定网络打印机 + */ + async function handleConfirm() { + if (!bindNetPrinter.value.printerSN) return toast(`请输入${currentNetPrinter.value[1]}`, 2) + if (currentNetPrinter.value[2] !== '不填' && !bindNetPrinter.value.printerKey) return toast(`请输入${currentNetPrinter.value[2]}`, 2) + // if (this.storeInfo.printerSN) { + // json.isPrintCancelOrder = this.storeInfo.isPrintCancelOrder + // json.isPrintRefundOrder = this.storeInfo.isPrintRefundOrder + // } + let printerVendorID = '' + for (let i in printerData.value) { + if (netPrinterData.value[+defultNetPrinterValue.value] === printerData.value[i]) printerVendorID = i + } + let res = await merchant.update_store({ + storeID: store.state.storeInfo.allStoreInfo.id, + payload: JSON.stringify({ + printerVendorID, + printerSN: bindNetPrinter.value.printerSN, + printerKey: bindNetPrinter.value.printerKey + }) + }) + if (res.code == '0') { + toast("绑定成功", 1) + getStores() + } else { + toast("绑定失败", 2) + } + bindNetPrinter.value.printerSN = '' + bindNetPrinter.value.printerKey = '' + popup.value.close() + + } + + /** + * 扫码绑定打印机 易联云 + */ + function scanCode() { + uni.scanCode({ + success: async ({ result }) => { + let res = await merchant.bind_net_printer({ + storeID: store.state.storeInfo.allStoreInfo.id, + data: result + }) + if (res.code == 0) { + toast('绑定成功', 1) + defultNetPrinterValue.value = '2' + defultNetPrinterValue.value = recordIndex.value + getStores() + cancelPopup() + } else { + toast('绑定失败', 2) + defultNetPrinterValue.value = recordIndex.value + cancelPopup() + } + }, + fail: () => { + toast('取消扫码', 2) + cancelPopup() + }, + }) + } + + /** + * 获取门店信息 + */ + async function getStores() { + await store.dispatch('storeInfo/getOneStore',getStorage("storeID")) + // let stateRes = await merchant.get_stores({ + // storeID: getStorage("storeID") + // }); + // if (stateRes.code == 0) { + // let stateData = stateRes.data.stores[0]; + // store.commit('storeInfo/setAllStoreInfo', stateData) + + // } else { + // toast("系统异常", 2); + // } + } + + // /** + // * 绑定打印机 + // * 没有打印机跳转到物料商城购买打印机 + // * 有打印机切是京西云的打印机跳转到京西云打印机小程序 + // */ + // function bindPrinter(type = '未绑定') { + // if (type == '未绑定') { + // if (store.state.storeInfo.storeStatus === -2) { + // uni.jxAlert({ + // title: '物料申请', + // content: '门店已被禁用,请联系运营', + // }) + // } + // uni.navigateToMiniProgram({ + // appId: 'wx4b5930c13f8b1170', + // path: `pages/index/index?storeID=666666&fromStoreID=${getStorage('storeID')}&storeType=c4`, + // success: (res) => { + // toast('即将进入京西菜市') + // }, + // fail: (err) => { + // toast('取消申请') + // }, + // }) + + // } else if (type == '京西云打印机') { + // uni.navigateToMiniProgram({ + // appId: 'wx2bfbc02e6251b71b', + // path: 'pages/home/home', + // success: (res) => { + // toast('即将进入京西云打印机') + // }, + // fail: (err) => { + // toast('取消操作') + // }, + // }) + // } else { + // uni.jxAlert({ + // title: type, + // content: `您当前使用的是【${type}】,如有问题请联系运营`, + // }) + // } + // } + + /** + * 取消绑定打印机弹框 + */ + function cancelPopup() { + defultNetPrinterValue.value = recordIndex.value + bindNetPrinter.value.printerSN = '' + bindNetPrinter.value.printerKey = '' + popup.value.close() + } + + /** + * 清空打印队列 + */ + async function DeletePrinterSeq() { + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]) + } + let res = await merchant.delete_printer_seq(data) + if (res.code == 0) { + toast('清空队列成功', 1) + } else { + toast('清空队列失败', 2) + } + } + + + /** + * 网络打印机禁用开关 + */ + async function switchprinterDisabled(e: AnyObject) { + let data = { + storeID: getStorage('storeID'), + payload: JSON.stringify({ + printerDisabled: e.detail.value ? 1 : 0 + }) + } + let res = await merchant.update_store(data) + } + + /** + * IM单聊状态设置 + */ + async function switchImMtStoreStatus(e: AnyObject, vendorID: number) { + let data = [ + { + vendorID: vendorID, + vendorStoreID: vendorID === 1 ? mtStoreInfo.value.vendorStoreID + '' : ebStoreInfo.value.vendorStoreID + '', + vendorOrgCode: vendorID === 1 ? mtStoreInfo.value.vendorOrgCode + '' : ebStoreInfo.value.vendorOrgCode + '', + imStatus: e.detail.value ? 1 : 0 + } + ] + let res = await merchant.set_mt_store_im_status({ data: JSON.stringify(data) }) + if (res.code == 0) { + let brr: any = [] + store.state.storeInfo.imOnlineStatus.forEach(item => { + if (item.vendorID === vendorID) brr.push({ + ...item, + imStatus: e.detail.value ? 1 : 0 + }) + else brr.push({ ...item }) + }) + store.commit('storeInfo/setImOnlineStatus', brr) + } else { + uni.jxAlert({ + title: '提示', + content: `修改失败:${res.desc || res.data}`, + success: () => { + // chatData.value.pop() + } + }) + } + } + + /** + * 是否打印Upc + */ + function switchUpc(e: AnyObject) { + setStorage('isPrinterUpc', e.detail.value) + } + + + /************************************************* + * 是否开启打印机兼容模式 + */ + function switchCompatible(e: AnyObject) { + console.log('ZSW-e.detail.value', e.detail.value); + setStorage('printerCompatible', e.detail.value) + } + + + /** + * 蓝牙打印机字体大小 + */ + const printerFontSize = ref>(['小号', '中号', '大号', '开发者模板']) + const retryActive = ref('0') + function changeRetry(e: AnyObject) { + retryActive.value = e.detail.value + setStorage('printerRetrySize', +e.detail.value) + } + + + /** + * 蓝牙打印机设置 + */ + function bluetoothPrinterSetUp() { + uni.navigateTo({ url: '/subPages/merchantChild/printerSetUp/printerSetUp' }) + } + + + /** + * 京西协议信息 + */ + function copyRightFn(url: string) { + uni.navigateTo({ url: url }) + } + + + /** + * 当前打印机名字 + */ + const newPrinterName = ref('') + onShow(() => { + newPrinterName.value = getStorage('deviceName') || '未连接' + }) + + /************************************************* + * 后台运行能力 + */ + + + /************************************************* + * 退出登录 + */ + function outLogin() { + uni.vibrateShort({}) + logOutFn() + uni.navigateTo({ + url: '/subPages/login/wxLogin/wxLogin', + animationType: 'zoom-out', + }) + } + + /************************************************* + * 是否打印机商品价格 + */ + function switchgoodsMoney(e: AnyObject) { + setStorage('printerGoodsMoney', e.detail.value) + + } + + /** + * 跳转到设置营业状态页面 + */ + function jumpBusinessStatus() { + uni.navigateTo({url: '/subPages/merchantChild/setBusinessStatus/setBusinessStatus'}) + } + + + /** + * 跳转到发票设置页面 (饿百) + */ + function jumpInvoiceSet() { + uni.navigateTo({url: '/subPages/merchantChild/setInvoiceEB/setInvoiceEB'}) + } + + + /************************************************* + * 去修改营业时间 + */ + async function setTime() { + uni.navigateTo({ url: `/subPages/merchantChild/setBusinessTime/setBusinessTime` }) + + } + + + return { + copyRight, // 京西版权信息 + smsNotifyData, // 未拣货选项 + defaultPrinter, // 选择默认打印设备 + defaultPrinterChange, // 切换打印设备 + defaultPrinterValue, // 默认选中设备 + smsNotify, // 选中提醒方式 + bindMultiPickerChange, // 未拣货选择提醒方式 + copyRightFn, // 京西协议 + // printerName, // 绑定的打印机品牌 + // bindPrinter, // 绑定打印机 + bluetoothPrinterSetUp, // 蓝牙打印机设置 + switchUpc, // 是否打印Upc + newPrinterName, // 当前绑定打印机设备 + DeletePrinterSeq, // 清空打印队列 + printerDisabled, // 是否禁用网络打印机 + switchprinterDisabled, // 网络打印机禁用开关 + imMtStoreStatus, // IM单聊状态是否开启 + imEbStoreStatus, // IM单聊状态是否开启 饿百 + switchImMtStoreStatus, // 更改IM单聊门店状态 + isExistMtStore, // 是否绑定美团门店 + isExistEbStore, // 是否绑定饿百门店 + printerFontSize, // 蓝牙打印机字体大小 + retryActive, // 默认选中重试次数 + changeRetry, // 选择重试次数 + switchCompatible, // 打印机兼容模式 + outLogin, // 退出登录 + switchgoodsMoney, // 是否打印商品价格 + netPrinterData, // 网络打印机 + defultNetPrinterValue, // 默认选中的网络打印机 + updateNetPrinter, // 选择网络打印机 + popup, // 弹框实例 + scanCode, // 易联云 扫码绑定打印机 + cancelPopup, // 取消绑定打印机弹框 + currentNetPrinter, // 当前选中的网络打印机需填写的数据 + bindNetPrinter, // 绑定的网络打印机的值 v-model + handleConfirm, // 绑定网络打印机 + setTime, // 去修改营业时间 + jumpBusinessStatus, // 跳转到营业状态页面 + jumpInvoiceSet, // 跳转到发票设置页面 + store + } +} + + +export default setUp \ No newline at end of file diff --git a/src/subPages/merchantChild/setUp/setUp.vue b/src/subPages/merchantChild/setUp/setUp.vue new file mode 100644 index 0000000..7dbbfaa --- /dev/null +++ b/src/subPages/merchantChild/setUp/setUp.vue @@ -0,0 +1,268 @@ + + + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/shareStore/shareStore.scss b/src/subPages/merchantChild/shareStore/shareStore.scss new file mode 100644 index 0000000..59de6f9 --- /dev/null +++ b/src/subPages/merchantChild/shareStore/shareStore.scss @@ -0,0 +1,104 @@ +.store-vender { + min-height: 90rpx; + background: white; + border-top: 1rpx solid #e5e5e5; + border-bottom: 1rpx solid #e5e5e5; + display: flex; + align-items: center; + justify-content: space-between; + padding: 10rpx 20rpx; + margin-bottom: 20rpx; + + .left { + display: flex; + align-items: center; + flex-shrink: 0; + + .icon { + width: 60rpx; + height: 60rpx; + flex-shrink: 0; + background-size: 100%; + background-repeat: no-repeat; + border: 1rpx solid #efefef; + border-radius: 10rpx; + opacity: 1; + transition: all 0.5s; + } + + .vendor-name { + margin-left: 20rpx; + font-size: 34rpx; + display: flex; + } + } + + .right { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .code-text { + font-size: 26rpx; + color: rgb(71, 71, 71); + } + } +} + +.share-root { + display: flex; + flex-direction: column; + align-items: center; + width: 658rpx; + background-color: #fff; + border-radius: 20rpx; + overflow: hidden; + + .qrCode { + position: relative; + width: 658rpx; + height: 892rpx; + background-image: url('https://image.jxc4.com/image/713906375700d61ad84314a58e6ff240.png'); + background-size: 658rpx 892rpx; + + .title { + position: absolute; + width: 658rpx; + text-align: center; + top: 40rpx; + font-weight: bold; + color: #fff; + } + + .canvas { + position: absolute; + width: 658rpx; + display: flex; + justify-content: center; + text-align: center; + top: 350rpx; + + .canvas-img { + width: 0px; + height: 0px; + } + + .canvas-img-active { + width: 120px; + height: 120px; + } + } + } + + .closeQrCode { + margin-top: 100rpx; + margin-bottom: 70rpx; + background-image: linear-gradient(90deg, #ff7868, #fa9b57); + width: 550rpx; + border-radius: 100rpx; + text-align: center; + padding: 20rpx; + color: #fff; + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/shareStore/shareStore.vue b/src/subPages/merchantChild/shareStore/shareStore.vue new file mode 100644 index 0000000..84cb7ab --- /dev/null +++ b/src/subPages/merchantChild/shareStore/shareStore.vue @@ -0,0 +1,163 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/storeScore/storeScore.scss b/src/subPages/merchantChild/storeScore/storeScore.scss new file mode 100644 index 0000000..975dc2f --- /dev/null +++ b/src/subPages/merchantChild/storeScore/storeScore.scss @@ -0,0 +1,72 @@ +@import '@/static/style/mixin-svg.scss'; + +.score-root { + box-sizing: border-box; + padding: 20rpx; +} + +.score-item { + display: flex; + border-radius: 10rpx; + box-shadow: 0 5rpx 5rpx rgba(black, .3); + margin-bottom: 20rpx; + align-items: center; + padding: 20rpx; + background: white; + box-sizing: border-box; + border: 1rpx solid #eee; +} + +.score-icon { + background-position: center center; + background-repeat: no-repeat; + background-size: 100%; + width: 50rpx; + height: 50rpx; + margin-right: 10rpx; + flex: none; +} + +.level1 { + @include svg_icon(star, f4d522); +} + +.level2 { + @include svg_icon(star, c9c7c7); +} + +.level3 { + @include svg_icon(star, d28751); +} + +.level0 { + @include svg_icon(star, dddddd); +} + +.left { + flex: 1; + + .storeName { + color: black; + font-size: 36rpx; + } + + .date { + color: #539941; + font-size: 30rpx; + } +} + +.right { + flex: none; + text-align: right; + font-size: 50rpx; + font-weight: bold; + color: #4EB331; +} + +.no-list { + color: #666; + text-align: center; + font-size: 32rpx; +} \ No newline at end of file diff --git a/src/subPages/merchantChild/storeScore/storeScore.vue b/src/subPages/merchantChild/storeScore/storeScore.vue new file mode 100644 index 0000000..55cc0ad --- /dev/null +++ b/src/subPages/merchantChild/storeScore/storeScore.vue @@ -0,0 +1,85 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/storeScoreDetaile/storeScoreDetaile.vue b/src/subPages/merchantChild/storeScoreDetaile/storeScoreDetaile.vue new file mode 100644 index 0000000..b66bf93 --- /dev/null +++ b/src/subPages/merchantChild/storeScoreDetaile/storeScoreDetaile.vue @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/useInfo/useInfo.vue b/src/subPages/merchantChild/useInfo/useInfo.vue new file mode 100644 index 0000000..9ef6bed --- /dev/null +++ b/src/subPages/merchantChild/useInfo/useInfo.vue @@ -0,0 +1,157 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoods/waitGoods.scss b/src/subPages/merchantChild/waitGoods/waitGoods.scss new file mode 100644 index 0000000..59414c7 --- /dev/null +++ b/src/subPages/merchantChild/waitGoods/waitGoods.scss @@ -0,0 +1,68 @@ +.good-list { + padding: 20rpx; +} + +.good-item { + margin-bottom: 20rpx; + background-color: white; + border-radius: 10rpx; + border: 1rpx solid #dfdfdf; + font-size: 30rpx; + color: #333; + padding: 20rpx; + box-shadow: 0 2rpx 5rpx rgba(black, .4); + display: flex; + align-items: center; +} + +.left { + flex: none; + font-size: 40rpx; + color: #ccc; + font-weight: 500; + width: 50rpx; + padding-right: 10rpx; +} + +.right { + flex: 1; +} + +.good-name { + border-bottom: 1rpx solid #efefef; + margin-bottom: 5rpx; + padding-bottom: 5rpx; + display: flex; + align-items: center; + + .img { + width: 180rpx; + height: 180rpx; + border-radius: 15rpx; + } + + .name { + padding-left: 20rpx; + } +} + +.good-info { + font-size: 34rpx; + font-weight: 500; + display: flex; + align-items: center; + justify-content: space-between; +} + +.good-count {} + +.good-weight {} + +.no { + height: 100rpx; + display: flex; + justify-content: center; + align-items: center; + color: #666; + font-size: 30rpx; +} \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoods/waitGoods.vue b/src/subPages/merchantChild/waitGoods/waitGoods.vue new file mode 100644 index 0000000..cc75f7a --- /dev/null +++ b/src/subPages/merchantChild/waitGoods/waitGoods.vue @@ -0,0 +1,112 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.scss b/src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.scss new file mode 100644 index 0000000..8d4427f --- /dev/null +++ b/src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.scss @@ -0,0 +1,233 @@ +@import '@/static/style/mixin-svg.scss'; + +.new-skuName-cell { + box-sizing: border-box; + padding: 30rpx; + display: flex; + align-items: center; + background-color: rgb(255, 255, 255); + + #{&}-left { + flex: none; + margin-right: 20rpx; + @include svg_icon(loading, 4EB331); + background-repeat: no-repeat; + background-position: center; + background-size: 40rpx; + + .img { + border-radius: 10rpx; + width: 280rpx; + height: 280rpx; + border: 2rpx solid #efefef; + // background: white; + } + } + + #{&}-right { + flex: auto; + height:280rpx; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + .skuNameId{ + color:#818181; + font-size: 28rpx; + } + + .name { + font-size: 36rpx; + color: #333; + } + + .update-price { + display: flex; + align-items: center; + justify-content: space-between; + } + + .price { + font-size: 38rpx; + font-weight: 500; + color: $jx-primary; + } + + .btn-updatePrice { + @include svg_icon(modify, 999); + width: 60rpx; + height: 60rpx; + background-repeat: no-repeat; + background-position: center; + background-size: 40rpx; + background-color: white; + } + + .tips { + font-size: 28rpx; + color: #999; + } + + .check-display { + color: #f44; + font-size: 24rpx; + font-weight: bold; + animation: rubberBand 1s infinite alternate; + } + + .update-price-input { + box-sizing: border-box; + padding: 20rpx; + + .top { + font-size: 24rpx; + color: #666; + } + + .audit { + color: red; + } + + input { + border: 1rpx solid #cdcdcd; + border-radius: 10rpx; + font-size: 36rpx; + padding: 10rpx; + text-align: center; + color: #333; + } + } +} + +.new-sku-cell { + padding: 20rpx 0; + border-bottom: 1rpx solid #cdcdcd; + + .flex-wrapper { + display: flex; + align-items: center; + justify-content: space-between; + } + + #{&}-left { + position: relative; + // display: flex; + text-align: center; + // background: red; + width: 200rpx; + } + + #{&}-right { + display: flex; + font-size: 30rpx; + color: #333; + text-align: center; + } + + .btn-status { + // margin: 10rpx; + background: #cdcdcd; + border-radius: 10rpx; + padding: 20rpx 30rpx; + color: #333; + font-size: 28rpx; + + &:nth-of-type(2) { + border-left: 1rpx solid white; + border-right: 1rpx solid white; + } + } + + .active { + background: $jx-primary; + color: white; + } + + .promotion-price { + color: $jx-primary; + } + + .cell-bottom, + .auto-at { + text-align: center; + font-size: 26rpx; + color: #ccc; + } + + .flex-wrapper-2 { + display: flex; + align-items: center; + justify-content: center; + } + + .cell-bottom { + flex: auto; + } + + .auto-at { + flex: none; + width: 460rpx; + color: $jx-primary; + } +} + +// mask + + +.jx-popup-update { + box-sizing: border-box; + padding: 20rpx; + background-color: #fff; + border-radius: 0 0 15rpx 15rpx; + + .text { + display: block; + width: 100%; + text-align: center; + margin-bottom: 25rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid rgb(209, 209, 209); + } + + .tip { + padding: 10rpx 0; + + .money { + color: $jx-primary; + } + } + + .ipt { + border: 2rpx solid rgb(209, 209, 209); + text-align: center; + height: 80rpx; + border-radius: 5rpx; + } + + .btn-root { + display: flex; + justify-content: space-between; + margin: 40rpx 0 0rpx 0; + + .btn-esc, + .btn-ok { + text-align: center; + width: 100%; + padding: 15rpx 0; + border-radius: 10rpx; + border: 2rpx solid $jx-primary; + color: $jx-primary; + } + + .btn-ok { + background-color: $jx-primary; + color: #fff; + margin-left: 10rpx; + } + + .btn-esc { + margin-right: 10rpx; + } + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.vue b/src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.vue new file mode 100644 index 0000000..853138a --- /dev/null +++ b/src/subPages/merchantChild/waitGoodsDetaile/skuName/skuName.vue @@ -0,0 +1,193 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.scss b/src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.scss new file mode 100644 index 0000000..0f2a7f9 --- /dev/null +++ b/src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.scss @@ -0,0 +1,172 @@ +@import '@/static/style/mixin-svg.scss'; + +.new-skuName-cell { + display: flex; + align-items: center; + + #{&}-left { + flex: none; + margin-right: 20rpx; + @include svg_icon(loading, 4EB331); + background-repeat: no-repeat; + background-position: center; + background-size: 40rpx; + + img { + border-radius: 10rpx; + width: 280rpx; + height: 280rpx; + border: 2rpx solid #efefef; + // background: white; + } + } + + #{&}-right { + flex: auto; + } + + .name { + font-size: 36rpx; + color: #333; + } + + .update-price { + display: flex; + align-items: center; + justify-content: space-between; + } + + .price { + font-size: 38rpx; + font-weight: 500; + color: $jx-primary; + } + + .btn-updatePrice { + @include svg_icon(modify, 999); + width: 60rpx; + height: 60rpx; + background-repeat: no-repeat; + background-position: center; + background-size: 40rpx; + background-color: white; + } + + .tips { + font-size: 28rpx; + color: #999; + } + + .check-display { + color: #f44; + font-size: 24rpx; + font-weight: bold; + animation: rubberBand 1s infinite alternate; + } + + .update-price-input { + padding: 20rpx; + + .top { + font-size: 24rpx; + color: #666; + } + + .audit { + color: red; + } + + input { + border: 1rpx solid #cdcdcd; + border-radius: 10rpx; + font-size: 36rpx; + padding: 10rpx; + text-align: center; + color: #333; + } + } +} + +.new-sku-cell { + padding: 20rpx 0; + border-bottom: 1rpx solid #cdcdcd; + + .flex-wrapper { + display: flex; + align-items: center; + justify-content: space-between; + + } + + #{&}-left { + position: relative; + // display: flex; + text-align: center; + // background: red; + width: 190rpx; + } + + #{&}-right { + display: flex; + justify-content: space-between; + width: 500rpx; + font-size: 30rpx; + color: #333; + text-align: center; + } + + .btn-status { + color: $jx-primary; + border-radius: 10rpx; + padding: 20rpx 30rpx; + border: 2rpx solid $jx-primary; + font-size: 28rpx; + } + + .active { + background: $jx-primary; + color: white; + } + + .price { + color: $jx-primary + } + + .promotion-price { + color: $jx-primary; + } + + .cell-bottom, + .auto-at { + text-align: center; + font-size: 26rpx; + color: #ccc; + } + + .flex-wrapper-3{ + display: flex; + justify-content: center; + color:#666; + margin-top:20rpx; + } + + .locationCode{ + margin-left: 20rpx; + } + + .flex-wrapper-2 { + display: flex; + align-items: center; + justify-content: center; + } + + .cell-bottom { + flex: auto; + } + + .auto-at { + flex: none; + width: 460rpx; + color: $jx-primary; + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.vue b/src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.vue new file mode 100644 index 0000000..de45a93 --- /dev/null +++ b/src/subPages/merchantChild/waitGoodsDetaile/skuNameID/skuNameID.vue @@ -0,0 +1,245 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.ts b/src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.ts new file mode 100644 index 0000000..ac93fd0 --- /dev/null +++ b/src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.ts @@ -0,0 +1,158 @@ +import { setStorage,getStorage } from '@/utils/storage' +import toast from '@/utils/toast' +import { onLoad, onShow } from '@dcloudio/uni-app' +import { Ref, ref } from 'vue' +import merchant from '@/api/https/merchant' +import useGlobalFunc from '@/composables/useGlobalFunc' +import shopping from '@/api/https/shopping' + +export default function waitGoodsDetaile() { + const { copyInfo } = useGlobalFunc() + /** + * 接收数据 + */ + interface GoodsInfoType { + nameID: number + skuID: number + goodsName: string + + } + const goodsInfo = ref({ + nameID: 0, + skuID: 0, + goodsName: '商品名字' + }) + const goodsTotalCount = ref(0) + onLoad(async (options) => { + goodsInfo.value.nameID = options?.nameID + goodsInfo.value.skuID = options?.skuID + goodsInfo.value.goodsName = options?.goodsName + }) + + onShow(async () => { + await GetStoresSkus() + }) + + /** + * 通过nameID获取商品 + */ + interface SkuNameType { + img: string + prefix: string + unit: string + name: string + unitPrice: number + auditUnitPrice: number + } + const skuName: Ref = ref({ + img: '', + prefix: '', + unit: '', + name: '', + unitPrice: 0, + auditUnitPrice: 0, + }) + async function GetStoresSkus() { + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + isFocus: true, + nameIDs: JSON.stringify([+goodsInfo.value.nameID]), + fromStatus: 0, + toStatus: 1, + } + let goodsDetailRes = await merchant.get_stores_skus(data) + if (goodsDetailRes.code == 0) { + goodsTotalCount.value = goodsDetailRes.data.totalCount + if (goodsDetailRes.data.totalCount == 0) { + uni.jxConfirm({ + title: '提示', + content: `未创建该商品,请先创建该商品,商品名字:【${goodsInfo.value.goodsName}】`, + // confirmText: '新建', + // cancelText: '强制下降', + success: () => { + uni.navigateTo({ + url: '/subPages/shoppingChild/createGoods/createGoods', + success: () => { + copyInfo(goodsInfo.value.goodsName, '商品名字复制成功') + } + }) + }, + fail: () => { + uni.navigateBack() + } + }) + } else { + skuName.value = goodsDetailRes.data.skuNames[0] + } + } else { + toast('商品数据异常', 2) + } + } + + + const popupDialog = ref(null) + const skuNameItem = ref({ + payload:{ + nameID:0, + Skus:[], + }, + name:'', + type:'price' + }) + const stockOrCode = ref('') + // 修改库存确认 + async function sureStockOrCode() { + const nameID = skuNameItem.value.payload.nameID + const skuID = skuNameItem.value.payload.Skus[0].skuID + let data:AnyObject = { + storeIDs: JSON.stringify([+getStorage('storeID')]) + } + if(skuNameItem.value.type === 'stock') { + data.payload = JSON.stringify([{ + nameID: nameID, + Skus:[{skuID: skuID,stock: +stockOrCode.value}] + }]) + }else{ + data.payload = JSON.stringify([{ + nameID: nameID, + Skus:[{skuID:skuID,locationCode: ''+ stockOrCode.value ? '' + stockOrCode.value : 'EMPTY_VALUE'}] + }]) + } + let res = await shopping.update_stores_skus(data) + if (res.code == 0) { + refresh(skuName.value.id) + setStorage("reLoadOrderDetail", true ) + toast('修改成功') + } + popupDialog.value.close() // 关闭 popupDialog + } + + // 打开dialog 修改库存以及货架码 + function openDialog(payload: AnyObject) { + skuNameItem.value = payload + const sku = payload.payload.Skus[0] + if(payload.type === 'stock') stockOrCode.value = sku.stock + '' + if(payload.type === 'locationCode') stockOrCode.value = sku.locationCode + popupDialog.value.open() + } + + /** + * 刷新状态 + */ + function refresh(id: number) { + goodsInfo.value.nameID = id + GetStoresSkus() + } + + return { + skuName, // 商品skuName + goodsInfo, // nameID and skuID + refresh, // 刷新状态 + goodsTotalCount, // 商品数量 + skuNameItem, // 修改商品当前的数据 + popupDialog, // 弹窗 stock locationCode + sureStockOrCode, // 弹窗确认 sure + stockOrCode, // 库存 或 货架码 + openDialog // 打开弹框 + } +} \ No newline at end of file diff --git a/src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.vue b/src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.vue new file mode 100644 index 0000000..b931bbe --- /dev/null +++ b/src/subPages/merchantChild/waitGoodsDetaile/waitGoodsDetaile.vue @@ -0,0 +1,154 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/messageChild/appPlay/appPlay.vue b/src/subPages/messageChild/appPlay/appPlay.vue new file mode 100644 index 0000000..7cddcfb --- /dev/null +++ b/src/subPages/messageChild/appPlay/appPlay.vue @@ -0,0 +1,246 @@ + + + + \ No newline at end of file diff --git a/src/subPages/messageChild/msgChat/msgChat.ts b/src/subPages/messageChild/msgChat/msgChat.ts new file mode 100644 index 0000000..f4b1b5c --- /dev/null +++ b/src/subPages/messageChild/msgChat/msgChat.ts @@ -0,0 +1,573 @@ +import { onLoad, onShow } from '@dcloudio/uni-app' +import { nextTick, onBeforeUnmount, ref } from 'vue' +import { store } from "@/store" +import message from '@/api/https/message' +import toast from '@/utils/toast' +import { Decrypt, Encrypt, jxParse } from '@/utils/tools' +// import { msgInfo } from '@/api/mockData/index' +import useGlobalFunc from '@/composables/useGlobalFunc' +import merchant from '@/api/https/merchant' +import { qiniuyun } from '@/utils/qiniuUploader' +import { getStorage } from "@/utils/storage"; +const { analyEmoji } = useGlobalFunc() +const qiniuyunUploadImg = qiniuyun() // 七牛云sdk + +/************************************************* + * 聊天详情 +*/ +const msgChatFn = function () { + /************************************************* + * 数据 + */ + const chatData = ref>([]) + + const scrollToView = ref() + + const platformID = ref('589') + + const isShowEmoji = ref(false) // 是否显示emoji + + const editorCtx = ref() // editor编辑器初始化 + + const readOnly = ref(false) // edotor编辑器的可读性 + + /************************************************* + * 接收数据 + */ + let useData: AnyObject = {} + let ebStore: AnyObject = {} + let detailTime: any = null // 计时器 + onLoad((potion: any) => { + let res:any = getStorage('vendorUserInfo') + if(JSON.stringify(potion) === '{}') { + useData = { + userID:res.userID, + NewMessageNum:0, + orderDesc:` #${res.orderSeq}`, + vendorID:res.vendorID, + orderID:res.venderOrderID + } + }else{ + let useInfo: AnyObject = JSON.parse(potion.data) + useData = useInfo + } + + if (store.state.storeInfo.allStoreInfo.StoreMaps && store.state.storeInfo.allStoreInfo.StoreMaps.length > 0) ebStore = store.state.storeInfo.allStoreInfo.StoreMaps.find((item: { vendorID: number }) => item.vendorID === 3) // 饿百 + + // 修改标题 + uni.setNavigationBarTitle({ + title: + useData.vendorID == 1 + ? `【美团${useData.orderDesc}】${useData.userID === '0' ? '群发消息' : useData.userID}` + : `【饿了么】${useData.userID}`, + }) + + // 获取聊天数据 + getChatDetail(0) + detailTime = setInterval(() => { + getChatDetail(1) + }, 4000) + }) + onShow(async () => { + if (useData.NewMessageNum == 0) return + await SetMsgRead() + }) + + /************************************************* + * 设置消息为已读 + */ + async function SetMsgRead() { + let venderIDInfo = store.state.storeInfo.vendorStoreIDS + let data = { + appID: useData.vendorID === 1 ? venderIDInfo.appID : ebStore.vendorOrgCode, + vendorStoreID: useData.vendorID === 1 ? venderIDInfo.MT : ebStore.vendorStoreID, + vendorID: "" + useData.vendorID, + orderID: "" + useData.orderID ? useData.orderID : '0', + userID: useData.userID + } + await message.set_IM_msg_read(data) + } + + + /************************************************* + * 获取聊天详情 + */ + const isItem = ref(false) + async function getChatDetail(num: number) { + let venderIDInfo = store.state.storeInfo.vendorStoreIDS + let data = { + payLoad: JSON.stringify([{ + vendorStoreID: useData.vendorID === 1 ? venderIDInfo.MT : ebStore.vendorStoreID, + vendorID: "" + useData.vendorID, + appID: useData.vendorID === 1 ? venderIDInfo.appID : ebStore.vendorOrgCode, + userID: useData.userID + }]) + } + let res = await message.get_IM_chat_detail(data) + // res = msgInfo.chatDetail // 模拟数据 + // console.log('res1111111111', res) + if (res.code == 0) { + let newArr: any = [] + if (useData.vendorID === 1) { + platformID.value = venderIDInfo.appID // 获取平台数据 + let newMsg = res.data[`${venderIDInfo.appID}:${venderIDInfo.MT}:${useData.vendorID}:${useData.userID}`] || [] + if (newMsg.length > chatData.value && num != 0) { + (newMsg.splice(chatData.value.length - 1)).forEach((element: any) => { + let resData = jxParse(element) + if (resData.msgContent != undefined) { + let msg_content = resData.msgContent.msg_type == 1 ? analyEmoji(Decrypt(resData.msgContent.msg_content, platformID.value)) : Decrypt(resData.msgContent.msg_content, platformID.value) + if (resData.msgContent.msg_type == 4) msg_content = resData.msgContent.app_spu_codes // 商品skuid + let msgList = { + sendType: resData.sendType, + ...resData.msgContent, + msg_content, + // msg_type: resData.msgContent.msg_type == 1 ? (!isCloudEmoji(Decrypt(resData.msgContent.msg_content, platformID.value)) ? resData.msgContent.msg_type : 'emoji') : resData.msgContent.msg_type + } + newArr.push(msgList) + } + }) + } else { + newMsg.forEach((element: any) => { + let resData = jxParse(element) + if (resData.msgContent != undefined) { + let msg_content = resData.msgContent.msg_type == 1 ? analyEmoji(Decrypt(resData.msgContent.msg_content, platformID.value)) : Decrypt(resData.msgContent.msg_content, platformID.value) + if (resData.msgContent.msg_type == 4) msg_content = resData.msgContent.app_spu_codes // 商品skuid + let msgList = { + sendType: resData.sendType, + ...resData.msgContent, + msg_content, + // msg_type: resData.msgContent.msg_type == 1 ? (!isCloudEmoji(Decrypt(resData.msgContent.msg_content, platformID.value)) ? resData.msgContent.msg_type : 'emoji') : resData.msgContent.msg_type + } + // msg_type 1:文字,2:图片,3:语音,注意b2c不支持语音,4:商品卡片,发送商品卡片类型则不关注msg_content,5:订单卡片类型商家只能接收消息,不支持给用户发送消息,只支持单聊 11:群文字,12:群图片,13:群语音,注意b2c不支持语音,14:群商品卡片 https://tscc.meituan.com/home/docDetail/10090 + newArr.push(msgList) + } + }) + } + } else { + // 饿百 + let newMsg = res.data[`${ebStore.vendorOrgCode}:${ebStore.vendorStoreID}:${useData.vendorID}:${useData.userID}`] || [] + if (num === 1) newArr = chatData.value + if (newMsg.length !== 0 && newMsg.length === chatData.value.length) return + + if (newMsg.length > chatData.value.length && num != 0) { + let arr = newMsg + arr.map((element: any, index: number) => { + let resData = JSON.parse(element) + if (resData.msgContent) { + if (resData.msgContent.payload) resData.msgContent.payLoad = resData.msgContent.payload + let findIndex = newArr.findIndex((item: { payLoad: { msgId: any } }) => item.payLoad.msgId === resData.msgContent.payLoad.msgId) // 消息id,唯一性 + if (findIndex === -1) { + let msg = JSON.parse(resData.msgContent.payLoad.content) + if (msg.text) { + msg.text = msg.text.replace(/^["']|["']$/g, '') //正则 去掉字符串中的首尾双引号 + resData.msgContent.payLoad.contentType = 1 + } + let str = '' + if (resData.msgContent.payLoad.contentType == 1) { + str = msg.text + } else if (resData.msgContent.payLoad.contentType == 2 || resData.msgContent.payLoad.contentType == 3 || resData.msgContent.payLoad.contentType == 4) { + analyUrl({ + mediaID: msg.mediaId, + platformShopID: '' + ebStore.vendorStoreID + }, index) + str = '' + } else { + if(resData.msgContent.payLoad.contentType == 101 && msg.type == 7){ + // 101、自定义消息-商品卡片 + analyUrl({ + mediaID: msg.data.item.id, + platformShopID: '' + ebStore.vendorStoreID + }, index) + }else if(resData.msgContent.payLoad.contentType == 101 && msg.type == 10052){ + let json = JSON.parse(msg.data) + let json1 = JSON.parse(resData.msgContent['payLoad'].content) + str = json.shortTitle + resData.msgContent['payLoad'] = { + ...resData.msgContent['payLoad'], + content:{ + ...json1, + data:JSON.parse(json1.data) + } + } + }else{ + if (msg.elements && msg.elements.length) { + // contentType 为'8' + let findItem = msg.elements.filter((item: { elementType: number }) => item.elementType === 1) + str = findItem && findItem.length > 0 ? JSON.parse(findItem[0].elementContent).text.replace('@商家', '') : '' + } + } + } + let msgList = { + sendType: resData.sendType, + ...resData.msgContent, + msg_content: resData.msgContent.payLoad.contentType === 1 || resData.msgContent.payLoad.contentType === '8' ? analyEmoji(str) : str, + // msg_source: 2, + msg_source: resData.sendType === 'jx' ? 1 : 2, + msg_type: resData.msgContent.payLoad.contentType === '8' ? 1 : resData.msgContent.payLoad.contentType + // msg_type: element.sendType === 'jx' ? 1 : 2 + } + newArr.push(msgList) + } + } + + }) + } else { + newMsg.map((element: any, index: number) => { + let resData = JSON.parse(element) + + if (resData.msgContent) { + if (resData.msgContent.payload) resData.msgContent.payLoad = resData.msgContent.payload + let msg = JSON.parse(resData.msgContent.payLoad.content) + if (msg.text) { + msg.text = msg.text.replace(/^["']|["']$/g, '') //正则 去掉字符串中的首尾双引号 + resData.msgContent.payLoad.contentType = 1 + } + let str = '' + if (resData.msgContent.payLoad.contentType == 1) { + str = msg.text + } else if (resData.msgContent.payLoad.contentType == 2 || resData.msgContent.payLoad.contentType == 3 || resData.msgContent.payLoad.contentType == 4) { + // contentType为2图片、3语音、4视频时 + analyUrl({ + mediaID: msg.mediaId, + platformShopID: '' + ebStore.vendorStoreID + }, index) + str = '' + } else { + if(resData.msgContent.payLoad.contentType == 101 && msg.type == 7){ + // 101、自定义消息-商品卡片 + analyUrl({ + mediaID: msg.data.item.id, + platformShopID: '' + ebStore.vendorStoreID + }, index) + }else if(resData.msgContent.payLoad.contentType == 101 && msg.type == 10052){ + let json = JSON.parse(msg.data) + let json1 = JSON.parse(resData.msgContent['payLoad'].content) + str = json.shortTitle + resData.msgContent['payLoad'] = { + ...resData.msgContent['payLoad'], + content:{ + ...json1, + data:JSON.parse(json1.data) + } + } + }else{ + if (msg.elements && msg.elements.length) { + let findItem = msg.elements.filter((item: { elementType: number }) => item.elementType === 1) + str = findItem && findItem.length > 0 ? JSON.parse(findItem[0].elementContent).text.replace('@商家', '') : '' + } + } + + } + let msgList = { + sendType: resData.sendType, + ...resData.msgContent, + msg_content: resData.msgContent.payLoad.contentType === 1 || resData.msgContent.payLoad.contentType === '8' ? analyEmoji(str) : str, + msg_source: resData.sendType === 'jx' ? 1 : 2, + msg_type: resData.msgContent.payLoad.contentType === '8' ? 1 : resData.msgContent.payLoad.contentType + } + newArr.push(msgList) + } + + }) + } + } + + chatData.value = newArr + isItem.value = true + scrollToView.value = 'msg' + (chatData.value.length - 1) + } else { + toast('获取聊天信息异常') + } + } + + /************************************************* + * 获取url by mediaId + */ + async function analyUrl(params: AnyObject, index: number) { + if (chatData.value[index] && !chatData.value[index].msg_content) return + let res = await message.get_url_by_mediaID(params) + if (chatData.value[index].msg_content.length === 0) chatData.value[index].msg_content = res.code === '0' ? res.data : '' + } + + /************************************************* + * 选择图片 + */ + function selectImg() { + if (useData.vendorID === 3) return toast('暂不支持该功能') + uni.chooseImage({ + success: (res: any) => { + res.tempFiles.forEach((item: AnyObject) => { + uploadImg(item.path) + }) + }, + }) + } + + /************************************************* + * 图片上传 + * @param {Object} 图片内容 + */ + async function uploadImg(img: string) { + let suffix = img.indexOf('.png') === -1 ? '.jpg' : '.png' + let params = { + suffix, + } + let res = await merchant.get_qiniu_upload_token(params) + if (res.code == 0) { + let filePath = img + qiniuyunUploadImg.upload( + filePath, + (res: any) => { + // 得到图片网址 + let url = 'https://image.jxc4.com/' + let imgUrl = url + res.key + sendClick({ msg: imgUrl, type: 2 }) + }, + (err: AnyObject) => { + toast('上传失败,请重试', 2) + }, + { + uploadURL: 'https://up-z2.qiniup.com/', + key: res.data.fileName, + uptoken: res.data.token, + } + ) + } else { + toast('上传失败', 2) + } + } + + /************************************************* + * 编辑器初始化完成时触发 + */ + function onEditorReady() { + uni.createSelectorQuery().select('#editor').context((res: any) => { + editorCtx.value = res.context + }).exec() + } + + /************************************************* + * 编辑器的内容(实时) + */ + function onInput(params: any) { + // console.log('params', params) + } + + /************************************************* + * 失去焦点 + */ + function onBlur(e: any) { + console.log('失去焦点', e.detail.delta.ops) + // isShowEmoji.value = false + + } + + /** + * 编辑器聚焦时 + */ + function onFocus(e: any) { + isShowEmoji.value = false + } + + /************************************************* + * 打开emoji + */ + function openEmoji() { + // uni.hideKeyboard() + readOnly.value = true + isShowEmoji.value = true + } + function closeEmoji() { + isShowEmoji.value = false + closeReadOnly() + } + + /************************************************* + * 选择emoji + */ + function selectEmoji(emoji: AnyObject) { + editorCtx.value.insertImage({ + src: `https://www.jxc4.com/emoji/${emoji.symbol}.png`, + alt: emoji.text, + width: '20px', + height: '20px', + nowrap: true + }) + + const timer = setTimeout(() => { + closeReadOnly() + clearTimeout(timer) + }, 2000) + } + + /************************************************* + * 发送消息 + */ + function sendMessage() { + editorCtx.value.getContents({ + complete(res: any) { + + if (res.errMsg === 'ok') { + let str = '' + res.delta.ops.forEach((item: any) => { + let type = typeof item.insert + if (type === 'string') { + str = str + item.insert + } else { + str = str + item.attributes.alt + } + }) + str = str.replace(/\n/g, '') // 除去回车符 + if (str.length > 0) { + // console.log('str', str) + sendClick({ msg: str, type: 1 }) + editorCtx.value.clear() + closeReadOnly() + } + } + } + }) + + // sendClick({ msg: initValue.value, type: 1 }) + // initValue.value = '' + // editorCtx.value.clear() + } + + /************************************************* + * 发送数据 + */ + async function sendClick(msgData: AnyObject) { + let venderIDInfo = useData.vendorID === 1 ? store.state.storeInfo.vendorStoreIDS : ebStore.vendorOrgCode + let data = { + sendType: useData.vendorID === 1 ? "mt" : "elm", + app_id: useData.vendorID === 1 ? venderIDInfo.appID : ebStore.vendorOrgCode, + app_poi_code: useData.vendorID === 1 ? venderIDInfo.MT : ebStore.vendorStoreID, + cts: Math.round(new Date().getTime() / 1000).toString(), + msg_content: msgData.type === 1 ? analyEmoji(msgData.msg) : msgData.msg, + msg_id: Math.round(new Date().getTime()).toString(), + msg_source: 1, + msg_type: msgData.type, + open_user_id: useData.userID, + order_id: useData.orderID, + app_spu_codes: "" + } + + chatData.value.push(data) + + nextTick(() => { + // 滚动信息到底部 + scrollToView.value = 'msg' + (chatData.value.length - 1) + }) + + let sendMsg = {} + if (useData.vendorID === 1) { + sendMsg = { + vendorOrgCode: platformID.value, + sendData: JSON.stringify({ + vendorID: useData.vendorID, + data: { + msg_content: Encrypt(msgData.msg, platformID.value), + msg_type: +Number(msgData.type), + app_poi_code: "" + venderIDInfo.MT, + msg_id: +Math.round(new Date().getTime()).toString() + 184572, + app_id: useData.vendorID === 1 ? +venderIDInfo.appID : +ebStore.vendorOrgCode, + msg_source: 1, + order_id: useData.orderID, + cts: +Math.round(new Date().getTime() / 1000).toString(), + open_user_id: +useData.userID, + } + }) + } + } else { + let chatDataItem = chatData.value.filter(item => item.msg_source === 2) + // vendorOrgCode + console.log('chatDataItem', chatDataItem) + sendMsg = { + // platformShopId: ebStore.vendorStoreID, + platformShopId: chatDataItem[0].platformShopId, + subBizType: 'SEND_MESSAGE', + bizType: 'IM', + payload: { + receiverIds: chatDataItem[0].payLoad.receiverIds, + groupId: chatDataItem[0].payLoad.groupId, + msgId: '' + Math.round(new Date().getTime()).toString() + 184572, + contentType: '' + msgData.type, // 1-普通文本 2-图片 3-语音 4-视频 101-自定义 + // contentType: '2', // 1-普通文本 2-图片 3-语音 4-视频 101-自定义 + content: msgData.type == 1 ? + JSON.stringify({ + text: msgData.msg + }) + : + JSON.stringify({ + mediaId: msgData.msg, + fileType: 0, // 必传 int类型 0-jpg图片, 2-png图片 + size: 1 // 必传 int类型 图片大小, 单位字节, 不超过3*1024*1024 + }) + // content: JSON.stringify({ + // mediaId: '3XLsJLhrcwmB0amFxycl3M8V1FWno0Fq_S6rKTRupMI48Wnr5wVjHqWM0b4zjG34', + // fileType: 0, + // size: 87668 + // }) + } + } + sendMsg = { + vendorOrgCode: ebStore.vendorOrgCode, + sendData: JSON.stringify({ + vendorID: useData.vendorID, + data: { ...sendMsg } + }) + } + + } + + let res = await message.send_to_vendor(sendMsg) + if (res.code == 0) { + } else { + uni.jxAlert({ + title: '提示', + content: `发送失败:${res.desc || res.data}`, + success: () => { + chatData.value.pop() + } + }) + } + SetMsgRead() + } + + /************************************************* + * 关闭editor的只读属性 + */ + function closeReadOnly() { + readOnly.value = false + } + + /** + * 收尾 工作 + */ + onBeforeUnmount(async () => { + clearInterval(detailTime) + if (useData.NewMessageNum == 0) return + await SetMsgRead() + }) + + + return { + scrollToView, // 滚动到底部 + chatData, // 聊天信息 + isItem, // 聊天界面的数据是否请求完毕 + isShowEmoji, // emoji是否发生偏移 + onEditorReady, // 编辑器初始化 + onInput, // 编辑器的内容(实时) + onBlur, // 编辑器失去焦点 + onFocus, // 编辑器聚焦时 + selectImg, // 选择图片 + openEmoji, // 打开emoji + closeEmoji, // 关闭emoji + selectEmoji, // 选择emoji + sendMessage, // 发送消息 + readOnly, // 是否为只读 + closeReadOnly // 关闭editor的只读属性 + } +} + +export default msgChatFn \ No newline at end of file diff --git a/src/subPages/messageChild/msgChat/msgChat.vue b/src/subPages/messageChild/msgChat/msgChat.vue new file mode 100644 index 0000000..2e31912 --- /dev/null +++ b/src/subPages/messageChild/msgChat/msgChat.vue @@ -0,0 +1,99 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/messageChild/msgChat/msgChatChild/chat-item.vue b/src/subPages/messageChild/msgChat/msgChatChild/chat-item.vue new file mode 100644 index 0000000..a876a3b --- /dev/null +++ b/src/subPages/messageChild/msgChat/msgChatChild/chat-item.vue @@ -0,0 +1,379 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/messageChild/msgChat/msgChatChild/index.scss b/src/subPages/messageChild/msgChat/msgChatChild/index.scss new file mode 100644 index 0000000..53550f9 --- /dev/null +++ b/src/subPages/messageChild/msgChat/msgChatChild/index.scss @@ -0,0 +1,599 @@ +.chat-input-bar { + display: flex; + flex-direction: row; + align-items: center; + background-color: #f8f8f8; + padding: 0 15rpx; + height: 110rpx; + border-top: 2rpx solid rgb(221, 221, 221); + box-sizing: border-box; + + justify-content: space-between; + width: 750rpx; +} + +.good_card{ + color:rgb(64, 158, 255); + text-decoration: underline; +} + +.xc-icon { + width: 70rpx; + margin-right: 10rpx; +} +.chat-input-root { + padding: 10rpx; + background-color: rgb(255, 255, 255); + box-sizing: border-box; + border-radius: 10rpx; +} +.chat-input { + width: 416rpx; + // max-height: 300rpx; + box-sizing: border-box; +} +.chat-emoji-border, +.chat-input-send { + margin: 10rpx 10rpx 10rpx 20rpx; + border-radius: 10rpx; + padding: 10rpx 0rpx; + width: 60rpx; +} +.chat-emoji-border { + display: flex; +} +.chat-input-send { + background-color: #05c160; + padding: 10rpx 30rpx; + width: 100rpx; + text-align: center; +} + +.chat-emoji { + width: 50rpx; + height: 50rpx; +} +.chat-input-send-text { + color: white; + font-size: 26rpx; +} + +.jx-popup-update { + box-sizing: border-box; + padding: 20rpx; + background-color: #fff; + border-radius:15rpx; + width: 94vw; + + .text { + display: block; + width: 100%; + text-align: center; + margin-bottom: 25rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid rgb(209, 209, 209); + } + + .goodCard_name{ + margin:20rpx 0 + } + + .btn-root { + text-align: center; + margin: 40rpx 0 0rpx 0; + .btn-ok { + text-align: center; + width: 100%; + padding: 15rpx 0; + border-radius: 10rpx; + border: 2rpx solid $jx-primary; + color: $jx-primary; + } + + .btn-ok { + background-color: $jx-primary; + color: #fff; + } + } +} + + +/************************************************* + * emoji表情配置 + */ + .emoji-select,.emoji-box{ + display: flex; + flex-wrap: wrap; + } + + .emoji-select{ + justify-content: space-around; + overflow: hidden; + height:400rpx; + overflow-y: auto; + background-color: #f8f8f8; + } + + .emoji-select::after{ + content: ''; + width: 100rpx; + border:2rpx solid transparent; + } + + .emoji-border{ + width: 100rpx; + height: 100rpx; + display: flex; + justify-content: center; + align-items: center; + } + + // .emoji-display{ + // width:50px; + // height:50px; + // background-size: 490px 730px; //设置背景图片的大小,相当于图片实际宽高等比例饿缩放的 + // } + .emoji-display,.emoji-img{ + width:30px; + height:30px; + background-size: 245px 365px; //设置背景图片的大小,相当于图片实际宽高等比例饿缩放的 + } + + .emoji-display,.emoji-img{ + // background-image: url(https://image.jxc4.com/image/2321c0f65268145cef711cf3b8195b9b.jpg); + background-image: url(https://image.jxc4.com/image/2aa6a9355bbb5c9fd60418d7b53e4227.tem.png); + background-repeat: no-repeat; + background-color: transparent; + } + + + + // 微笑 + .emoji-smile{ + background-position: 0px 0px; + } + + // 撇嘴 + .emoji-pieMouth{ + background-position: -30px 0px; + } + + // 色 + .emoji-tity{ + background-position: -60px 0px; + } + + // 发呆 + .emoji-asleep{ + background-position: -90px 0px; + } + + // 得意 + .emoji-complacent{ + background-position: -120px 0px; + } + + // 流泪 + .emoji-shedTears{ + background-position: -150px 0px; + } + + // 害羞 + .emoji-shy{ + background-position: -180px 0px; + } + + // 闭嘴 + .emoji-shutUp{ + background-position: -210px 0px; + } + + // 睡 + .emoji-sleep{ + background-position: 0px -30px; + } + + // 大哭 + .emoji-bigCry{ + background-position: -30px -30px; + } + + // 尴尬 + .emoji-awkward{ + background-position: -60px -30px; + } + + // 发怒 + .emoji-flareUp{ + background-position: -90px -30px; + } + + // 调皮 + .emoji-naughty{ + background-position: -120px -30px; + } + + // 呲牙 + .emoji-bareTeeth{ + background-position: -150px -30px; + } + + // 惊讶 + .emoji-amazed{ + background-position: -180px -30px; + } + + // 难过 + .emoji-feelSorry{ + background-position: -210px -30px; + } + + // 酷 + .emoji-cool{ + background-position: 0px -60px; + } + + // 囧 + .emoji-orz{ + background-position: -30px -60px; + } + + // 抓狂 + .emoji-crazy{ + background-position: -60px -60px; + } + + // 吐 + .emoji-vomit{ + background-position: -90px -60px; + } + + // 偷笑 + .emoji-titter{ + background-position: -120px -60px; + } + + // 愉快 + .emoji-happy{ + background-position: -150px -60px; + } + + // 白眼 + .emoji-whiteEye{ + background-position: -180px -60px; + } + + // 傲慢 + .emoji-arrogance{ + background-position: -210px -60px; + } + + // 饥饿 + .emoji-hunger{ + background-position: -0px -90px; + } + + // 困 + .emoji-tired{ + background-position: -30px -90px; + } + + // 惊恐 + .emoji-terrified{ + background-position: -60px -90px; + } + + // 流汗 + .emoji-sweat{ + background-position: -90px -90px; + } + + // 憨笑 + .emoji-smileFatuously{ + background-position: -120px -90px; + } + + // 悠闲 + .emoji-easy{ + background-position: -150px -90px; + } + + // 奋斗 + .emoji-struggle{ + background-position: -180px -90px; + } + + // 咒骂 + .emoji-swear{ + background-position: -210px -90px; + } + + // 疑问 + .emoji-query{ + background-position: -0px -120px; + } + + // 嘘 + .emoji-hiss{ + background-position: -30px -120px; + } + + // 晕 + .emoji-giddy{ + background-position: -60px -120px; + } + + // 疯了 + .emoji-insane{ + background-position: -90px -120px; + } + + // 衰 + .emoji-decline{ + background-position: -120px -120px; + } + + // 骷髅 + .emoji-skull{ + background-position: -150px -120px; + } + + // 敲打 + .emoji-beat{ + background-position: -180px -120px; + } + + // 再见 + .emoji-goodbye{ + background-position: -210px -120px; + } + + // 擦汗 + .emoji-wipePerspiration{ + background-position: -0px -150px; + } + + // 抠鼻 + .emoji-pickNose{ + background-position: -30px -150px; + } + + // 鼓掌 + .emoji-applaud{ + background-position: -60px -150px; + } + + // 糗大了 + .emoji-embarrassed{ + background-position: -90px -150px; + } + + // 坏笑 + .emoji-snicker{ + background-position: -120px -150px; + } + + // 左哼哼 + .emoji-leftHum{ + background-position: -150px -150px; + } + + // 右哼哼 + .emoji-rightHum{ + background-position: -180px -150px; + } + + // 哈欠 + .emoji-yawn{ + background-position: -210px -150px; + } + + // 鄙视 + .emoji-disdain{ + background-position: 0px -180px; + } + + // 委屈 + .emoji-grievance{ + background-position: -30px -180px; + } + + // 快哭了 + .emoji-cring{ + background-position: -60px -180px; + } + + // 阴险 + .emoji-cattiness{ + background-position: -90px -180px; + } + + // 亲亲 + .emoji-kiss{ + background-position: -120px -180px; + } + + // 吓 + .emoji-threaten{ + background-position: -150px -180px; + } + + // 可怜 + .emoji-pitiful{ + background-position: -180px -180px; + } + + // 菜刀 + .emoji-kitchenKnife{ + background-position: -210px -180px; + } + + // 西瓜 + .emoji-watermelon{ + background-position: 0px -210px; + } + + // 啤酒 + .emoji-beer{ + background-position: -30px -210px; + } + + // 篮球 + .emoji-basketball{ + background-position: -60px -210px; + } + + // 乒乓 + .emoji-ping-pong{ + background-position: -90px -210px; + } + + // 咖啡 + .emoji-coffee{ + background-position: -120px -210px; + } + + // 饭 + .emoji-rice{ + background-position: -150px -210px; + } + + // 猪头 + .emoji-pigHead{ + background-position: -180px -210px; + } + + // 玫瑰 + .emoji-rose{ + background-position: -210px -210px; + } + + // 凋谢 + .emoji-fade{ + background-position: 0px -240px; + } + + // 嘴唇 + .emoji-lip{ + background-position: -30px -240px; + } + + // 爱心 + .emoji-love{ + background-position: -60px -240px; + } + + // 心碎 + .emoji-heartbreak{ + background-position: -90px -240px; + } + + // 蛋糕 + .emoji-cake{ + background-position: -120px -240px; + } + + // 闪电 + .emoji-lightning{ + background-position: -150px -240px; + } + + // 炸弹 + .emoji-bombs{ + background-position: -180px -240px; + } + + // 刀 + .emoji-knife{ + background-position: -210px -240px; + } + + // 足球 + .emoji-soccer{ + background-position: 0px -270px; + } + + // 瓢虫 + .emoji-ladybird{ + background-position: -30px -270px; + } + + // 便便 + .emoji-excrement{ + background-position: -60px -270px; + } + + // 月亮 + .emoji-moon{ + background-position: -90px -270px; + } + + // 太阳 + .emoji-sun{ + background-position: -120px -270px; + } + + // 礼物 + .emoji-gift{ + background-position: -150px -270px; + } + + // 拥抱 + .emoji-embrace{ + background-position: -180px -270px; + } + + // 强 + .emoji-strong{ + background-position: -210px -270px; + } + + // 弱 + .emoji-weak{ + background-position: 0px -300px; + } + + // 握手 + .emoji-handshake{ + background-position: -30px -300px; + } + + // 胜利 + .emoji-victory{ + background-position: -60px -300px; + } + + // 抱拳 + .emoji-holdFist{ + background-position: -90px -300px; + } + + // 勾引 + .emoji-seduce{ + background-position: -120px -300px; + } + + // 拳头 + .emoji-fist{ + background-position: -150px -300px; + } + + // 差劲 + .emoji-bad{ + background-position: -180px -300px; + } + + // 爱你 + .emoji-loveYou{ + background-position: -210px -300px; + } + + // NO + .emoji-no{ + background-position: 0px -330px; + } + + // OK + .emoji-ok{ + background-position: -30px -330px; + } \ No newline at end of file diff --git a/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.scss b/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.scss new file mode 100644 index 0000000..54e2c5d --- /dev/null +++ b/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.scss @@ -0,0 +1,205 @@ +.skuList { + padding: 0 20rpx; + background-color: #fff; + + .sku-item-for-orderdetail { + padding: 20rpx 0; + display: flex; + align-items: center; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + + .img { + position: relative; + + image { + width: 180rpx; + height: 180rpx; + border: 2rpx solid #efefef; + } + } + + .right { + margin-left: 20rpx; + + .sku-name { + font-size: 30rpx; + font-weight: 500; + color: #333; + margin-right: 40rpx; + } + + .sku-spec { + margin-top: 10rpx; + display: flex; + width: 510rpx; + justify-content: space-between; + align-items: center; + position: relative; + + .sku-count { + font-size: 28rpx; + color: #999999; + font-weight: 400; + } + } + } + } +} + + +.cell { + background-color: #ffffff; + padding: 30rpx 20rpx; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + color: #333; +} + +.afsWhy { + background: #fcf1f0; + color: #F25340; + font-size: 32rpx; + padding: 30rpx 20rpx; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); +} + +.imgdesc { + background: white; + padding: 10rpx 20rpx; + font-size: 32rpx; + color: #333; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + + .img-wrapper { + margin-top: 10rpx; + display: flex; + flex-flow: row wrap; + + // justify-content: space-around; + .img-item { + width: 160rpx; + height: 160rpx; + margin: 8rpx; + + image { + max-width: 100%; + max-height: 100%; + } + } + } +} + +.userName { + display: flex; + align-items: center; + justify-content: space-between; + background: #fff; + padding: 30rpx 20rpx; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); +} + +.loss { + background: #ffffff; + color: #F25340; + font-size: 26rpx; + padding: 30rpx 20rpx; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); +} + +.btn-group { + display: flex; + justify-content: space-between; + background-color: #fff; + padding: 20rpx; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + + .refuse, + .agree { + width: 42%; + padding: 20rpx; + text-align: center; + background: #fcf1f0; + color: #F25340; + border-radius: 10rpx; + border: 1rpx solid #F25340; + + } + + .agree { + background-color: $jx-primary; + color: #fff; + border: none; + } +} + +.afsOrder-flag { + padding: 30rpx 20rpx; + text-align: center; + font-weight: bold; + color: #F25340; + background-color: #fff; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); +} + +.refuseReason { + padding: 30rpx 20rpx; + color: #F25340; + background-color: #fff; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); +} + +.status-165 { + padding: 20rpx; + background-color: #fff; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + + text { + display: block; + background-color: $jx-primary; + text-align: center; + padding: 20rpx; + border-radius: 10rpx; + color: #fff; + } +} + + +.popup { + padding: 20rpx; + background-color: #fff; + border-radius: 0 0 30rpx 30rpx; + + .title { + text-align: center; + margin-bottom: 20rpx; + } + + .textarea { + box-sizing: border-box; + background-color: #f1f1f1; + border-radius: 10rpx; + padding: 20rpx; + width: 100%; + height: 200rpx; + } + + .btn-root { + display: flex; + justify-content: space-between; + margin-top: 20rpx; + + .cancel, + .confirm { + width: 42%; + border-radius: 10rpx; + border: 1rpx solid $jx-primary; + color: $jx-primary; + padding: 20rpx; + text-align: center; + } + + .confirm { + background-color: $jx-primary; + color: #fff; + } + } +} \ No newline at end of file diff --git a/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.ts b/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.ts new file mode 100644 index 0000000..45b0ef1 --- /dev/null +++ b/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.ts @@ -0,0 +1,293 @@ +import order from '@/api/https/order' +import toast from "@/utils/toast" +import { timeFormatHMS } from "@/utils/tools" +import { onLoad } from "@dcloudio/uni-app" +import { computed, ref, Ref } from "vue" +import configData from "@/utils/configCms" + +/************************************************* + * 售后详情 + *@author zhang-shu-wei <2966211270@qq.com> + *@date 2023-02-06 09:10:52 + *@param {}- + *@return {*} +*/ +function afterSalesOrderDetailFn() { + + /************************************************* + * 获取售后商品数据 + */ + let afsOrderID = '' // 售后单号 + onLoad(async (options) => { + afsOrderID = options!.afsOrderID + // 查询售后单 + await GetAfsOrders() + await GetAfsOrderSkuInfo() + await GetOrders() + }) + + /************************************************* + * 查询售后单 + */ + const afsOrder: Ref = ref({ vendorOrderID: 99 }) + async function GetAfsOrders() { + let data = { + afsOrderID: afsOrderID + } + let res = await order.get_afs_orders(data) + if (res.code == 0 && res.data.totalCount >= 1) { + afsOrder.value = res.data.data[0] + } else { + uni.jxAlert({ + title: '提示', + content: '售后单数据异常', + success: () => { + uni.navigateBack() + } + }) + } + } + + /************************************************* + * 查询售后单商品 + */ + const afsOrderSku = ref>([]) // 售后商品 + async function GetAfsOrderSkuInfo() { + let data = { + afsOrderID: afsOrderID, + vendorID: afsOrder.value.vendorID + } + let res = await order.get_afs_order_sku_info(data) + if (res.code == 0) { + afsOrderSku.value = res.data + } else { + uni.jxAlert({ + title: '提示', + content: '售后单数据异常', + success: () => { + uni.navigateBack() + } + }) + } + } + + /************************************************* + * 查询订单 + */ + const orderData = ref({}) + async function GetOrders() { + let data = { + vendorOrderID: afsOrder.value.vendorOrderID + } + let res = await order.get_orders(data) + if (res.code == 0 && res.data.totalCount >= 1) { + orderData.value = res.data.data[0] + } else { + uni.jxAlert({ + title: '提示', + content: '售后单数据异常', + success: () => { + uni.navigateBack() + } + }) + } + } + + /************************************************* + * 售后方式 + */ + const configCms:AnyObject = configData.serveInfo + const afsAppealTypeName = computed(() => { + if (afsOrder.value.appealType !== undefined) { + return configCms.afsAppealTypeName[afsOrder.value.appealType] + } else { + return '未知' + } + }) + + /************************************************* + * 订单创建时间 + */ + const createTime = computed(() => { + if (afsOrder.value.afsCreatedAt !== undefined) { + return timeFormatHMS(afsOrder.value.afsCreatedAt) + } else { + return '' + } + }) + + /************************************************* + * 售后单状态 + */ + const afsStatus = computed(() => { + if (afsOrder.value.status !== undefined) { + return configCms.orderStatus[afsOrder.value.status] + } else { + return '未知' + } + }) + + /************************************************* + * 配送方式 + */ + const waybillVendorName = computed(() => { + if (orderData.value.waybillVendorID !== undefined) { + return configCms.vendorName[orderData.value.waybillVendorID] + } else { + return '门店自送' + } + }) + + /************************************************* + * 售后原因 + */ + const afsReason = computed(() => { + if (afsOrder.value.reasonType !== undefined) { + return configCms.afsReasonTypeName[afsOrder.value.reasonType] + } else { + return '未知' + } + }) + + /************************************************* + * 图片列表 + */ + const imgList = computed(() => { + if (afsOrder.value.reasonImgList !== undefined) { + return afsOrder.value.reasonImgList.split(',') + } else { + return [] + } + }) + + /************************************************* + * 同意退款 + */ + function handleAgree() { + uni.jxConfirm({ + title: '提示', + content: '是否同意处理该售后单', + success: () => { + agreeOrRefuse(1) + }, + }) + } + + /************************************************* + * 同意退款 + */ + async function agreeOrRefuse(type: number) { + // if (afsOrder.value.vendorID == 3) { + // if (type == 1) { + // let data = { + // vendorOrderID: afsOrder.value.vendorOrderID, + // vendorID: afsOrder.value.vendorID, + // acceptIt: Boolean(1), // 拒绝为0,同意为1 + // reason: type === 1 ? '同意退款' : reason.value, + // } + // let res = await order.agree_or_refuse_cancel(data) + // if (res.code == 0) { + // toast('操作成功', 1) + // afsOrder.value.flag = 1 + // } else { + // toast(res.desc || res.data) + // } + // } else { + // let data = { + // vendorOrderID: afsOrder.value.vendorOrderID, + // vendorID: afsOrder.value.vendorID, + // acceptIt: Boolean(0), // 拒绝为0,同意为1 + // reason: type === 1 ? '同意退款' : reason.value, + // } + // let res = await order.agree_or_refuse_cancel(data) + // if (res.code == 0) { + // toast('操作成功', 1) + // afsOrder.value.flag = 3 + // } else { + // toast(res.desc || res.data) + // } + // } + // } else { + let data = { + afsOrderID: afsOrder.value.afsOrderID, + vendorID: afsOrder.value.vendorID, + approveType: type, + reason: type === 1 ? '同意退款' : reason.value + } + let res = await order.agree_orRefuse_refund(data) + if (res.code == 0) { + toast('操作成功', 1) + } else { + toast(res.desc || res.data) + } + // } + } + + /************************************************* + * 退货待确认 + */ + function confirmGoods() { + uni.jxConfirm({ + title: '提示', + content: '是否已收到货', + success: async () => { + let data = { + afsOrderID: afsOrder.value.afsOrderID, + vendorID: afsOrder.value.vendorID + } + let res = await order.confirm_received_return_goods(data) + if (res.code == 0) { + toast('操作成功', 1) + afsOrder.value.flag = 4 + } else { + toast(res.desc || res.data) + } + }, + }) + } + + /************************************************* + * 取消驳回 + */ + const popup = ref(null) + const reason = ref() // 输入内容 + function cancelFn() { + reason.value = '' + popup.value.close() + } + + /************************************************* + * 同意驳回 + */ + function diaConfirm() { + if (reason.value) { + agreeOrRefuse(3) + reason.value = '' + popup.value.close() + } else { + toast('请输入驳回原因') + } + } + + return { + afsOrder, // 售后订单 + afsOrderSku, // 售后商品数据 + orderData, // 订单数据 + afsAppealTypeName, // 售后方式 + createTime, // 订单创建时间 + afsStatus, // 售后单状态 + waybillVendorName, // 配送方式 + afsReason, // 售后原因 + imgList, // 图片列表 + popup, // 售后dialog 实例 + handleAgree, // 同意退款 + confirmGoods, // 退货待确认 + reason, // 驳回原因 + cancelFn, // 取下驳回 + diaConfirm, // 同意驳回 + } +} + + +export default afterSalesOrderDetailFn + diff --git a/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.vue b/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.vue new file mode 100644 index 0000000..8765aac --- /dev/null +++ b/src/subPages/orderChild/afterSalesOrderDetail/afterSalesOrderDetail.vue @@ -0,0 +1,206 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/complaint/complaint.vue b/src/subPages/orderChild/complaint/complaint.vue new file mode 100644 index 0000000..38f163f --- /dev/null +++ b/src/subPages/orderChild/complaint/complaint.vue @@ -0,0 +1,225 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/createAfterSales/createAfterSales.scss b/src/subPages/orderChild/createAfterSales/createAfterSales.scss new file mode 100644 index 0000000..053da55 --- /dev/null +++ b/src/subPages/orderChild/createAfterSales/createAfterSales.scss @@ -0,0 +1,274 @@ +.header { + height: 100rpx; + display: flex; + justify-content: space-between; + align-items: center; + padding: 20rpx; + box-sizing: border-box; + font-weight: 500; + font-size: 32rpx; + border-bottom: 1rpx solid rgba(204, 204, 204, 0.4); + background: white; + + .title { + color: #333; + border-left: 8rpx solid $jx-primary; + padding-left: 10rpx; + } + + .btn-cancel, + .btn-confirm { + padding: 8rpx 45rpx; + background: rgba(78, 179, 49, 0.3); + border: 2rpx solid rgba(78, 179, 49, 0.3); + color: $jx-primary; + border: 2rpx solid rgba(78, 179, 49, 0.3); + border-radius: 6rpx; + } + + .btn-cancel { + margin-right: 30rpx; + } +} + +.sku-list { + max-height: calc(100vh - 120rpx); + overflow-y: auto; + + .adjust-sku-cell { + padding: 20rpx; + display: flex; + border-bottom: 1px solid rgba(#ccc, .4); + margin-top: 20rpx; + background: white; + position: relative; + + image { + width: 180rpx; + height: 180rpx; + flex-shrink: 0; + } + + .list-right { + margin-left: 20rpx; + width: 100%; + } + + .sku-name { + color: #333; + font-size: 30rpx; + font-weight: 500; + // margin-bottom: 35rpx; + min-height: 60rpx; + text-align: justify; + line-height: 1.2; + } + + .delete { + text-decoration: line-through; + color: #999; + } + + .adjust-count { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1rpx dashed #ccc; + padding-bottom: 10rpx; + + .price { + font-size: 30rpx; + font-weight: 400; + color: rgb(0, 0, 0); + } + + .earning-price { + .price1 { + font-size: 30rpx; + text-decoration: line-through; + color: #999; + } + + .price2 { + font-size: 30rpx; + color: #999; + margin-left: 10rpx; + } + } + } + + :deep(.adjust-op) { + display: flex; + justify-content: space-between; + align-items: center; + + .disabled { + opacity: .2; + } + + .uni-numbox { + + .uni-numbox-btns { + padding: 0rpx !important; + border-radius: 7rpx; + overflow: hidden; + background-color: transparent; + } + + .uni-numbox--text { + color: #fff !important; + width: 80rpx !important; + height: 51rpx !important; + text-align: center; + line-height: 50rpx !important; + background-color: $jx-primary; + } + + .uni-numbox--disabled { + background-color: #ccc !important; + } + + } + } + + .sku-count { + color: #333; + font-size: 32rpx; + padding: 0 20rpx; + } + + .btn-minus, + .btn-plus { + width: 60rpx; + height: 60rpx; + background-size: 48rpx; + background-repeat: no-repeat; + background-position: center center; + background-color: white; + } + + + .count-to-0 { + margin-top: 10rpx; + + span { + font-weight: bold; + } + + .count-to-0-wrapper { + display: flex; + align-items: center; + } + + .circle { + width: 30rpx; + height: 30rpx; + box-sizing: border-box; + border: 1rpx solid #ccc; + border-radius: 50%; + margin-right: 10rpx; + } + + .text { + font-size: 28rpx; + color: $jx-warring; + } + + .active { + .circle { + border: 1rpx solid $jx-primary; + position: relative; + + &:after { + content: ""; + width: 14rpx; + height: 14rpx; + background: $jx-primary; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + border-radius: 50%; + } + } + + .text { + color: $jx-primary; + font-weight: bold; + } + } + } + } +} + +.refundMoney { + color: red; + font-weight: bold; +} + +.jx-popup-update { + box-sizing: border-box; + padding: 20rpx; + background-color: #fff; + border-radius: 0 0 15rpx 15rpx; + + .text { + display: block; + width: 100%; + text-align: center; + margin-bottom: 25rpx; + padding-bottom: 10rpx; + border-bottom: 2rpx solid rgb(209, 209, 209); + } + + // .tip { + // padding: 10rpx 0; + + // .money { + // color: $jx-primary; + // } + // } + + .ipt { + border: 2rpx solid rgb(209, 209, 209); + text-align: center; + height: 80rpx; + border-radius: 5rpx; + } + + .btn-root { + display: flex; + justify-content: space-between; + margin: 40rpx 0 0rpx 0; + + .btn-esc, + .btn-ok { + text-align: center; + width: 100%; + padding: 15rpx 0; + border-radius: 10rpx; + border: 2rpx solid $jx-primary; + color: $jx-primary; + } + + .btn-ok { + background-color: $jx-primary; + color: #fff; + margin-left: 10rpx; + } + + .btn-esc { + margin-right: 10rpx; + } + } + + // .delete { + // margin-top: 50rpx; + // margin-bottom: 20rpx; + // background-color: $jx-warring; + // text-align: center; + // color: #fff; + // padding: 20rpx; + // border-radius: 15rpx; + // } +} \ No newline at end of file diff --git a/src/subPages/orderChild/createAfterSales/createAfterSales.ts b/src/subPages/orderChild/createAfterSales/createAfterSales.ts new file mode 100644 index 0000000..8ca93e9 --- /dev/null +++ b/src/subPages/orderChild/createAfterSales/createAfterSales.ts @@ -0,0 +1,346 @@ +import order from '@/api/https/order' +import { store } from '@/store' +import toast from '@/utils/toast' +import { onLoad } from '@dcloudio/uni-app' +import { computed, ref, onBeforeUnmount } from 'vue' + +/************************************************* + * 售后-退款 + *@author zhang-shu-wei <2966211270@qq.com> + *@date 2023-02-02 10:07:00 +*/ +function createAfterSales() { + const storeInfo = ref(store.state.storeInfo.allStoreInfo) + /************************************************* + * 接收optios 参数 + * @type {number} 1:部分退款 2:发起售后 + * @data {anyObject} 数据 + */ + const vendorOrderID = ref('') + const vendorID = ref(0) + const buyerComment = ref('') + const skuList = ref>([]) + const type = ref(1) + onLoad(async (options) => { + let data = JSON.parse(options!.data) + vendorOrderID.value = data.vendorOrderID + vendorID.value = +data.vendorID + buyerComment.value = data.buyerComment + type.value = +options!.type + // 部分退款 + if (options!.type == 1) { + let orderSkuInfo = await getSkuList() + skuList.value = reduceSku(orderSkuInfo, []) + } + + // 发起售后 + if (options!.type == 2) { + let orderSkuInfo = await getSkuList() + let orderAfsSkuInfo = await getAfsOrderSkuInfo() + skuList.value = reduceSku(orderSkuInfo, orderAfsSkuInfo) + } + console.log('创建售后单的商品信息',skuList.value) + }) + + + /************************************************* + * 获取商品数据 + */ + async function getSkuList() { + let data = { + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + } + let res = await order.get_order_sku_info(data) + if (res.code == 0 && res.data != null) { + return res.data + } else { + return [] + } + } + + + /************************************************* + * 获取售后单商品 + */ + async function getAfsOrderSkuInfo() { + let data = { + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + } + let res = await order.get_afs_order_sku_info(data) + if (res.code == 0 && res.data != null) { + return res.data + } else { + return [] + } + } + + + /************************************************* + * 筛选已售后商品 + */ + // 减掉已经售后的商品 + function reduceSku(skuList: Array, afsSkuList: Array) { + if (afsSkuList) { + afsSkuList.forEach((item) => { + let findItem: any = skuList.find( + (sku) => + sku.jxSkuID === item.jxSkuID && sku.storeSubID === item.storeSubID + ) + findItem.count = findItem.count - item.count + }) + return mapData(skuList) + } else { + return mapData(skuList) + } + } + // 过滤数据 + const isNewPriceDisplay: any = computed(() => { + store.getters['storeInfo/isNewPriceDisplay'] + }) + function mapData(dataList: Array) { + let data = JSON.parse(JSON.stringify(dataList)) + data.forEach((item: AnyObject) => { + item.comparePrice = isNewPriceDisplay.value + ? item.salePrice > item.shopPrice + ? (item.shopPrice / 100).toFixed(2) + : (item.salePrice / 100).toFixed(2) + : (item.shopPrice / 100).toFixed(2) + item.afsCount = 0 + }) + return data + } + + + + /************************************************* + * 退款 + */ + let arrSelectGood: Array = [] + async function partRefundOrder() { + skuList.value.forEach((item: AnyObject) => { + if (item.afsCount) { + arrSelectGood.push(item) + } + }) + if (arrSelectGood.length === 0) { + uni.jxAlert({ + title: '提示', + content: '请选择退款商品', + }) + return + } + if(buyerComment.value === '支付方式:扫码枪'){ + let myMap = new Map() + arrSelectGood.forEach((i => { + myMap.set(i.jxSkuID,i.afsCount) + })) + let objNew = Object.fromEntries(myMap); + await order.refund_online_order({vendorOrderID:vendorOrderID.value,skuIds:JSON.stringify(objNew),reason:'协商一致'}) + toast('创建成功', 1) + }else{ + if (type.value == 1) { + partialRefund(arrSelectGood) + } + if (type.value == 2) { + createServe(arrSelectGood) + } + } + } + + + /************************************************* + * 部分退款 + */ + let partRefundReason = '商品缺货' + const popup = ref() + let partialRefundTimer: any = null + function partialRefund(arr: AnyObject) { + uni.jxConfirm({ + title: '退款', + content: '是否对该订单进行调整', + success: async () => { + popup.value.open() + // return + // arr = arr.map((item: AnyObject) => ({ + // skuID: item.skuID, + // count: item.afsCount, + // storeSubID: item.storeSubID + // })) + // let data = { + // vendorOrderID: vendorOrderID.value, + // vendorID: vendorID.value, + // removedSkuInfo: JSON.stringify(arr), + // // reason: '商品缺货' + // reason: '买多或者买少' + // } + // console.log('是否对订单进行调整',data) + // let res = await order.adjust_order(data) + // if (res.code == 0) { + // toast('部分退款成功', 1) + // clearTimeout(partialRefundTimer) + // partialRefundTimer = setTimeout(() => { + // uni.navigateBack() + // }, 800) + // } else { + // uni.jxAlert({ + // title: '退款失败', + // content: res.desc || res.data, + // }) + // } + }, + }) + } + + + /** + * 获取输入框的值 + */ + function onKeyInput(event:AnyObject) { + partRefundReason = event.target.value + } + + + /** + * 弹框确认数据 + */ + async function handleConfirm() { + if(partRefundReason.length===0) return toast('请填写退款理由', 2) + let arr = arrSelectGood.map((item: AnyObject) => ({ + skuID: item.skuID, + count: item.afsCount, + storeSubID: item.storeSubID + })) + let data = { + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + removedSkuInfo: JSON.stringify(arr), + // reason: '商品缺货' + reason: partRefundReason + } + let res = await order.adjust_order(data) + if (res.code == 0) { + toast('部分退款成功', 1) + clearTimeout(partialRefundTimer) + partialRefundTimer = setTimeout(() => { + uni.navigateBack() + }, 800) + } else { + uni.jxAlert({ + title: '退款失败', + content: res.desc || res.data, + }) + } + popup.value.close() + } + + /************************************************* + * 发起售后 + */ + function createServe(arr: AnyObject) { + uni.jxConfirm({ + title: '退款', + content: '是否对该订单创建售后单\r\n进行【退款】处理', + success: async () => { + // 全额退款 + if (totalCount.value == 0) { + let data = { + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + reason: '商家同意退款', + } + let res = await order.refund_order(data) + if (res.code == 0) { + toast('退款成功', 1) + setTimeout(() => { + uni.navigateBack() + }, 800) + } else { + uni.jxAlert({ + title: '退款失败', + content: res.desc || res.data, + }) + } + } + + // 部分退款 + if (totalCount.value != 0) { + arr = arr.map((item: AnyObject) => ({ + skuID: item.skuID, + count: item.afsCount, + storeSubID: item.storeSubID, + })) + let data = { + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + refundSkuList: JSON.stringify(arr), + reason: '商家同意退款', + } + let res = await order.part_refund_order(data) + if (res.code == 0) { + toast('售后单创建成功', 1) + setTimeout(() => { + uni.navigateBack() + }, 800) + } else { + uni.jxAlert({ + title: '退款失败', + content: res.desc || res.data, + }) + } + } + }, + }) + } + + + /************************************************* + * 总数量 + */ + const totalCount = computed(() => { + let count = 0 + skuList.value.forEach((item: AnyObject) => { + count += parseInt(item.count, 10) + }) + return count + }) + + + const refundMoney = ref(0) + let obj:AnyObject = {} + /************************************************* + // * 获取当前将要退款金额 + */ + function numChange(e: number, sku: AnyObject) { + obj[sku.id] = sku.shopPrice * e + let sum = 0 + for (const key in obj) { + sum += obj[key] + refundMoney.value = sum + } + } + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + clearTimeout(partialRefundTimer) + }) + + + return { + skuList, // 商品数据 + partRefundOrder, // 退款处理 + isNewPriceDisplay, // 是否显示新价格 + storeInfo, // 商户数据 + numChange, // 获取当前退款金额 + refundMoney, // 总共退款金额 + partRefundReason, // 部分退款理由 + handleConfirm, // 弹框确认 + onKeyInput, + popup + } +} + +export default createAfterSales \ No newline at end of file diff --git a/src/subPages/orderChild/createAfterSales/createAfterSales.vue b/src/subPages/orderChild/createAfterSales/createAfterSales.vue new file mode 100644 index 0000000..4815285 --- /dev/null +++ b/src/subPages/orderChild/createAfterSales/createAfterSales.vue @@ -0,0 +1,156 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/deliverManager/deliverManager.scss b/src/subPages/orderChild/deliverManager/deliverManager.scss new file mode 100644 index 0000000..c4748ac --- /dev/null +++ b/src/subPages/orderChild/deliverManager/deliverManager.scss @@ -0,0 +1,318 @@ +.icon-tel { + display: inline-block; + width: 28rpx; + height: 28rpx; + background: url(http://image.jxc4.com/image/cb1ecb5937d8e6b87d0b0b27c1117fc3.png) center center no-repeat; + background-size: 100%; +} + +// 顶部系统信息 +.top-system-root { + padding: 30rpx 25rpx 0 25rpx; + box-sizing: border-box; + + .stop-delivery { + border-radius: 10rpx; + margin-bottom: 20rpx; + box-shadow: 0rpx 0rpx 10rpx 5rpx rgb(220, 220, 220); + } + + .vender-store-money { + background-color: #fff; + padding: 0 20rpx; + border-radius: 10rpx; + box-shadow: 0rpx 0rpx 10rpx 5rpx rgb(220, 220, 220); + + .vender, + .store { + display: flex; + justify-content: space-between; + align-items: center; + padding: 26rpx 0; + } + + .vender { + border-bottom: 1rpx solid rgb(220, 220, 220); + } + + .btn { + background-color: #ffa652; + padding: 10rpx 20rpx; + border-radius: 50rpx; + font-size: 27rpx; + color: #fff; + } + + .right { + display: flex; + align-items: center; + } + } + + .address-tip { + display: flex; + justify-content: space-between; + margin-top: 50rpx; + + .addres, + .tip { + border-radius: 10rpx; + width: 48%; + background-color: #fff; + box-shadow: 0rpx 0rpx 10rpx 5rpx rgb(220, 220, 220); + text-align: center; + padding: 20rpx 30rpx 30rpx 30rpx; + box-sizing: border-box; + } + + .icon { + .banner { + width: 220rpx; + height: 220rpx; + } + + .address-icon { + width: 30rpx; + height: 42rpx; + } + + .text { + display: flex; + align-items: center; + font-weight: bold; + justify-content: center; + + .distance { + color: $jx-primary; + text-decoration: underline; + } + } + } + + .sd-btn, + .tip-btn { + padding: 10rpx 15rpx; + background-color: $jx-primary; + color: #fff; + border-radius: 10rpx; + margin-top: 25rpx; + } + + .sd-ing-btn { + background-image: linear-gradient(135deg, #ec903f, #ff6a20); + } + + .waybill-price { + font-size: 28rpx; + color: $jx-warring; + margin-top: 15rpx; + margin-bottom: -15rpx; + } + } + + .delivery-info { + position: relative; + margin-top: 50rpx; + height: 210rpx; + width: 100%; + + image { + position: absolute; + width: 100%; + height: 230rpx; + z-index: -1; + } + + .delivery-status, + .delivery-person { + display: flex; + margin-top: 17rpx; + padding: 0 45rpx; + box-sizing: border-box; + font-weight: bold; + justify-content: space-between; + } + + .deliver-name>text { + color: $jx-primary; + } + + .complain{ + text-decoration:underline ; + margin-right: 40rpx; + margin-top: 17rpx; + padding: 0 45rpx; + box-sizing: border-box; + } + + .status { + color: $jx-warring; + } + + .delivery-status { + padding-top: 20rpx; + } + + .delivery-person, + .money { + font-size: 31rpx; + } + + .money { + margin-top: 17rpx; + padding: 0 45rpx; + box-sizing: border-box; + } + + .number { + color: #666; + } + } +} + +.bottom-info { + position: relative; + background-color: #fff; + margin-top: 18rpx; + + .bg { + position: absolute; + background-color: rgb(255, 255, 255); + height: 180rpx; + width: 100%; + z-index: -2; + top: -70rpx; + } + + .thead { + padding: 20rpx; + display: flex; + justify-content: space-between; + + .right { + display: flex; + justify-content: space-between; + + .de-money { + margin-right: 90rpx; + } + } + } + + .dleivery-list { + padding: 0 15rpx; + box-sizing: border-box; + } + + .ther-btn { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + padding: 22rpx 0; + color: #2a89ec; + border-top: 1rpx solid rgb(225, 225, 225); + } + + .icon-jiantou_yemian_xiangxia { + font-size: 40rpx; + } + + .info { + padding: 0 15rpx 15rpx 20rpx; + box-sizing: border-box; + } + + .info>view { + box-sizing: border-box; + background-color: #f5f7ed; + padding: 20rpx 0; + } +} + +.dy-root { + background-color: #fff; + border-radius: 0 0 20rpx 20rpx; + padding: 30rpx; + box-sizing: border-box; + + .delivering-title { + width: 100%; + text-align: center; + margin-bottom: 30rpx; + } + + .ipt { + margin-bottom: 20rpx; + background-color: #f5f5f5; + line-height: 70rpx; + border-radius: 7rpx; + + text { + white-space: nowrap; + } + + input { + width: 100%; + padding: 10rpx 0rpx; + border-bottom: 1rpx solid rgb(209, 209, 209); + } + } + + .btn-root { + display: flex; + justify-content: space-between; + + .cancel, + .confirm { + width: 42%; + padding: 20rpx; + text-align: center; + border: 3rpx solid $jx-primary; + color: $jx-primary; + border-radius: 7rpx; + } + + .confirm { + border: none; + background-color: $jx-primary; + color: #fff; + } + } +} + +.delivery-flex { + max-height: 110rpx; + overflow: hidden; + transition: all 0.5s; +} + +.active { + max-height: 550rpx !important; + overflow: auto !important; +} + +.iconfont { + display: inline-block; + transition: all 0.5s; +} + +.rotate { + transform: rotateZ(180deg); +} + +.stop-schedule ,.cancel-all { + text-align: center; + color: #fff; + margin: 15rpx 20rpx; + border-radius: 6rpx; + padding: 10rpx 0; +} + +.stop-schedule{ + background-color:#f56c6c; +} + +.cancel-all{ + background-color: #000; +} \ No newline at end of file diff --git a/src/subPages/orderChild/deliverManager/deliverManager.ts b/src/subPages/orderChild/deliverManager/deliverManager.ts new file mode 100644 index 0000000..c0092a1 --- /dev/null +++ b/src/subPages/orderChild/deliverManager/deliverManager.ts @@ -0,0 +1,589 @@ +import order from '@/api/https/order' +import merchant from '@/api/https/merchant' +import { onLoad, onShow, onPullDownRefresh } from "@dcloudio/uni-app" +import { computed, ref, onBeforeUnmount } from "vue" +import { store } from "@/store" +import toast from "@/utils/toast"; +import configData from "@/utils/configCms" +import { getStorage } from '@/utils/storage' +import { clearList } from "@/utils/tools"; + + +/************************************************* + * 配送管理 + * @author zhang-shu-wei <2966211270@qq.com> + * @date 2023-02-06 17:49:16 + * @param {}- + * @return {*} +*/ +function deliverMangetFn() { + + /************************************************* + * 接收数据 + */ + const vendorOrderID = ref('') + onLoad(async (options) => { + store.commit('storeInfo/jxLoadingFn', true) + vendorOrderID.value = options?.orderId + await getOrder() + await getWaybillFee() + // await getDeliverMoney() + // await getStoreMoney() + store.commit('storeInfo/jxLoadingFn', false) + }) + + onShow(async () => { + await getDeliverMoney() + await getStoreMoney() + }) + + /************************************************* + * 下拉刷新 + */ + let onPullDownRefreshTimer: any = null + onPullDownRefresh(() => { + clearTimeout(onPullDownRefreshTimer) + onPullDownRefreshTimer = setTimeout(async () => { + allFn() + clearTimeout(onPullDownRefreshTimer) + }, 1000) + }) + + /************************************************* + * 获取订单信息 + */ + const orderData = ref({}) // 订单数据 + const courierMaps = ref>([]) // 快递地图 + const createDeliveryType = ref(0) + async function getOrder() { + let data = { + vendorOrderID: vendorOrderID.value + } + let res = await order.get_orders(data) + if (res.code == 0 && res.data.totalCount >= 1) { + orderData.value = res.data.data[0] + let store = await getStoreInfo(orderData.value.jxStoreID) + courierMaps.value = store.CourierMaps + createDeliveryType.value = orderData.value.createDeliveryType + } else { + uni.jxAlert({ + title: '提示', + content: '未查询到订单信息', + success: () => { + uni.navigateBack() + } + }) + } + } + + /************************************************* + * 获取门店信息 + */ + async function getStoreInfo(storeID: string) { + let data = { + storeIDs: JSON.stringify([storeID]), + pageSize: 1 + } + let res = await merchant.get_stores(data) + if (res.code == 0) { + return res.data.stores[0] + } + } + + /************************************************* + * 配送状态 + */ + const waitingStatus = computed(() => { + if (orderData.value.waybillVendorID === -1 && orderData.value.status === 15 && (orderData.value.deliveryFlag & 16) === 0 && (orderData.value.deliveryFlag & 32) === 0) { + if (orderData.value.businessType === 1) { + // 立即达 + return '待配送' + } else { + // 预订单 + let keys = Object.keys(deliverList.value) + if (keys.length > 0) { + if (deliverList.value[keys[0]].timeoutSecond) { + return '待配送' + } else { + return '预订单' + } + } else { + return '预订单' + } + } + } else if (orderData.value.waybillVendorID === -1 && orderData.value.status === 15 && ((orderData.value.deliveryFlag & 16) === 16 || (orderData.value.deliveryFlag & 32) === 32)) { + return '正在召唤三方配送' + } else { + if (orderData.value.waybillVendorID >= 0) { + return configCms.vendorName[orderData.value.waybillVendorID] + } else { + return '商家自送' + } + } + }) + + /************************************************* + * 订单状态 + */ + const configCms:AnyObject = configData.serveInfo + const orderStatus = computed(() => { + let status = orderData.value.status + if (status === 15) { + return '待配送' + } else if (status === 20) { + return '配送中' + } else { + if (status) { + return configCms.orderStatus[status] + } else { + return '未知状态' + } + } + }) + + /************************************************* + * 获取配送费用 + */ + const deliverList = ref({}) + async function getWaybillFee() { + let data = { + vendorOrderID: orderData.value.vendorOrderID, + vendorID: orderData.value.vendorID + } + let res = await order.query_order_waybill_fee_info(data) + if (res.code == 0) { + let info = res.data + courierMaps.value && courierMaps.value.forEach((element: AnyObject) => { + if (info[element.vendorID]) info[element.vendorID].status = element.status + }) + deliverList.value = info + isShouldCharge(deliverList.value) + } else { + uni.jxAlert({ + title: '提示', + content: '未获取到配送费用', + success: () => { + uni.navigateBack() + } + }) + } + } + + /************************************************* + * + */ + const isCharge = ref(false) + function isShouldCharge(item: AnyObject) { + for (let key in item) { + var currentNum = + (orderData.value.baseFreightMoney || 400) * 0.9 - + (item[key].waybill + ? item[key].waybill.actualFee + : item[key].deliveryFee) + Math.abs(currentNum) > accountBalance.value + ? (isCharge.value = true) + : null + } + } + + const accountBalance = ref(0) // 品牌账号余额 + /************************************************* + * 获取品牌账户余额 + */ + async function getDeliverMoney() { + let res = await order.get_brands() + if (res.code == 0) { + let brandID = store.state.storeInfo.allStoreInfo.brandID + const resAll = res.data.find((item: any) => item.id === brandID) + accountBalance.value = resAll && resAll.balance ? resAll.balance : 0 + } else { + toast('账户余额信息异常') + } + } + + const StoreMoneyBalance = ref(0) // 门店账号余额 + /************************************************* + * 门店账号余额 + */ + async function getStoreMoney() { + let data = { + storeID: getStorage('storeID'), + } + let res = await order.get_store_acct_balance(data) + if (res.code == 0) { + StoreMoneyBalance.value = res.data.accountBalance + } else { + toast('门店账号余额异常') + StoreMoneyBalance.value = 0 + } + } + + + + /************************************************* + * 召唤骑手费用 + */ + const feeCall = computed(() => { + // 拿到平台 + const waybillFee = deliverList.value[orderData.value.waybillVendorID] + // 拿到费用 + let fee = 0 + if (waybillFee) { + fee = waybillFee.waybill + ? waybillFee.waybill.desiredFee + : waybillFee.deliveryFee + } + return (fee / 100).toFixed(2) + }) + + /************************************************* + * 平台补贴 + */ + const selfDeliveryPrice = computed(() => { + return (((orderData.value.baseFreightMoney || 400) * 0.9) / 100).toFixed(1) + }) + + /************************************************* + * 立即召唤 + */ + const isSelfDeliver = computed(() => { + let order = orderData.value + if ('deliveryFlag' in order) { + return ( + (order.deliveryFlag & 3) === 3 && + order.lockStatus === 0 && + order.deliveryType !== 'self' && + !order.vendorWaybillID + ) + } else { + return false + } + }) + + /************************************************* + * 立即充值金额 + */ + async function handleChargeNow(type: number) { + uni.vibrateShort({}) + let data = JSON.stringify({ + type: type, + storeName: getStorage('storeName'), + storeID: getStorage('storeID'), + token: getStorage('token'), + platform: 0 + }) + uni.navigateTo({ + url: `/subPages/messageChild/appPlay/appPlay?playData=${data}`, + }) + } + + /************************************************* + * 立即自送 + */ + const dyPopup = ref(null) + function selfDelivery() { + uni.jxConfirm({ + title: '提示', + content: '是否将该订单转为自送', + success: () => { + // 抖音小时购和饿佰新零售转自送 + if (orderData.value.vendorID == 14 || orderData.value.vendorID == 3 || orderData.value.vendorID == 1 || orderData.value.vendorID == 16) { + uni.jxConfirm({ + title: '提示', + content: '是否填写骑手信息', + confirmText: '填写', + cancelText: '不填写', + success: () => { + dyPopup.value.open() + }, + fail: () => { + selfDelivering() + } + }) + } else { + // 非抖店订单自送 + selfDelivering() + } + }, + }) + } + async function selfDelivering() { + let data = { + vendorOrderID: orderData.value.vendorOrderID, + vendorID: orderData.value.vendorID, + } + let res = await order.self_delivering(data) + if (res.code == 0) { + allFn() + uni.jxAlert({ + title: '提示', + content: '转自送成功,请尽快安排给客户送货', + }) + } else { + uni.jxAlert({ + title: '提示', + content: `转自送失败:${res.desc || res.data}`, + }) + } + dyCancel() + } + + /************************************************* + * 抖音自送 + */ + const deliveryRider = ref<{ + name: string + tel: string + }>({ + name: '', + tel: '' + }) + async function handleConfirm() { + if (deliveryRider.value.name == '') return toast('请填写骑手姓名') + let ruler = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/ + if (!ruler.test(deliveryRider.value.tel)) return toast('请填写正确的骑手电话') + let data = { + vendorOrderID: orderData.value.vendorOrderID, + vendorID: orderData.value.vendorID, + courierName: deliveryRider.value.name, + courierMobile: deliveryRider.value.tel + } + dyCancel() + let res = await order.self_delivering(data) + if (res.code == 0) { + allFn() + uni.jxAlert({ + title: '提示', + content: '转自送成功,请尽快安排给客户送货', + }) + } else { + uni.jxAlert({ + title: '提示', + content: `转自送失败:${res.desc || res.data}`, + }) + } + } + let allFnTimer: any = null + // 重新请求数据 + function allFn() { + clearTimeout(allFnTimer) + allFnTimer = setTimeout(async () => { + store.commit('storeInfo/jxLoadingFn', true) + await getOrder() + await getWaybillFee() + await getDeliverMoney() + await getStoreMoney() + store.commit('storeInfo/jxLoadingFn', false) + }, 1000) + } + + /************************************************* + * 取消抖音自送 + */ + function dyCancel() { + dyPopup.value.close() + deliveryRider.value = { + name: '', + tel: '' + } + } + + /************************************************* + * 添加小费 + */ + function addTipMoney() { + uni.jxConfirm({ + title: '添加小费', + content: `当前已加小费:${(orderData.value.waybillTipMoney / 100).toFixed( + 2 + )}\r\n是否再添加 1元`, + confirmText: '加1元', + cancelText: '不了', + success: async () => { + let data = { + vendorOrderID: orderData.value.vendorOrderID, + vendorID: orderData.value.vendorID, + tipFee: +orderData.value.waybillTipMoney + 100, + isPay: 0, + } + let res = await order.update_order_waybill_tip(data) + if (res.code == 0) { + toast('添加成功', 1) + allFn() + } else { + uni.jxConfirm({ + title: '提示', + // content: `添加失败:${res.desc || res.data}`, + content: `${res.desc || res.data}`, + confirmText: '确认添加', + cancelText: '取消', + success: async () => { + let data = { + vendorOrderID: orderData.value.vendorOrderID, + vendorID: orderData.value.vendorID, + tipFee: +orderData.value.waybillTipMoney + 100, + isPay: 1, + } + let res = await order.update_order_waybill_tip(data) + if (res.code == 0) { + toast('添加成功', 1) + allFn() + } else { + uni.jxAlert({ + title: '提示', + content: `添加失败:${res.desc || res.data}`, + }) + } + } + }) + } + }, + }) + } + + /************************************************* + * 自动发单 + */ + interface switchStatusType { + vendorID: number | string, + status: number, + waybillFee: AnyObject, + } + async function switchStatus(sendData: switchStatusType) { + let courier: any = courierMaps.value.find( + (item: AnyObject) => +item.vendorID === +sendData.vendorID + ) + let data = { + storeID: orderData.value.jxStoreID, + vendorID: sendData.vendorID, + payload: JSON.stringify({ + status: sendData.status, + vendorStoreID: courier.vendorStoreID, + }) + } + let res = await order.update_store_courier_map(data) + if (res.code == 0) { + if (sendData.status == 0) { + toast('关闭成功', 1) + } else { + toast('打开成功', 1) + } + await getOrder() + await getWaybillFee() + } else { + uni.jxAlert({ + title: '提示', + content: `操作失败${res.desc || res.data}` + }) + } + } + // 刷新 + async function refresh() { + if (orderData.value.status > 20) { + uni.jxAlert({ + title: '警告', + content: '订单状态已改变', + success: () => { + uni.navigateBack() + } + }) + } else { + // 获取运单费用信息 + await getWaybillFee() + } + } + + const switchActive = ref(false) // 配送列表默认关闭 + + /************************************************* + * 取消所有配送 + */ + function cancelAll(isStopSchedule?:Boolean) { + let data:AnyObject = { + vendorOrderID: vendorOrderID.value, + vendorID: orderData.value.vendorID + } + if(isStopSchedule) data['isStopSchedule'] = isStopSchedule // 停止运单调度 + uni.jxConfirm({ + title: '提示', + content: '是否取消该订单的所有三方配送', + success: async () => { + let res = await order.cancel_all_3rd_waybills(data) + if (res.code == 0) { + uni.jxAlert({ + title: "提示", + content: "取消成功", + success: () => { + allFn() + } + }) + } else { + uni.jxAlert({ + title: '提示', + content: res.desc || res.data + }) + } + } + }) + } + + /************************************************* + * 投诉骑手 + */ + async function complainRider() { + uni.navigateTo({ + url: `/subPages/orderChild/complaint/complaint?vendorOrderID=${orderData.value.vendorOrderID}&orderData=${JSON.stringify(orderData.value)}&type=current` + }) + } + + /************************************************* + * 查看地图 + */ + function seeMap() { + uni.openLocation({ + latitude: orderData.value.consigneeLat / 1000000, + longitude: orderData.value.consigneeLng / 1000000, + name: orderData.value.consigneeAddress, + address: '客户地址', + scale: 16, + }) + } + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + clearTimeout(allFnTimer) + clearList() + }) + + return { + waitingStatus, // 配送状态 + orderData, // 订单数据 + createDeliveryType, // 创建交货类型 + orderStatus, // 待配送状态 + deliverList, // 获取配送费用 + // isCharge, // 判断 + accountBalance, // 品牌账户余额 + StoreMoneyBalance, // 门店账户余额 + feeCall, // 召唤骑手费用 + selfDeliveryPrice, // 平台补贴 + isSelfDeliver, // 立即召唤 + handleChargeNow, // 立即充值金额 + selfDelivery, // 立即自送 + deliveryRider, // 抖音自送骑手信息 + dyPopup, // 抖音自送 popup 实例 + // dyCancel, // 取消抖音自送 + selfDelivering, // 取消填写骑手信息 还是进行转自配送 + handleConfirm, // 确定骑手信息 + addTipMoney, // 加小费 + switchStatus, // 自动发单 + refresh, // 刷新状态 + switchActive, // 切换状态 + seeMap, // 查看地图 + cancelAll, // 一键取消所有配送 + complainRider // 投诉骑手 + } +} + +export default deliverMangetFn \ No newline at end of file diff --git a/src/subPages/orderChild/deliverManager/deliverManager.vue b/src/subPages/orderChild/deliverManager/deliverManager.vue new file mode 100644 index 0000000..24e27b4 --- /dev/null +++ b/src/subPages/orderChild/deliverManager/deliverManager.vue @@ -0,0 +1,273 @@ + + + + + + diff --git a/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.scss b/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.scss new file mode 100644 index 0000000..53ff345 --- /dev/null +++ b/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.scss @@ -0,0 +1,159 @@ +.deliver-cell { + padding: 20rpx 10rpx; + display: flex; + align-items: center; + background: #f5f7ed; + border-bottom: 1rpx solid rgba(#ccc, .4); + + // 左边快递 + .vendor-name { + font-size: 30rpx; + color: #666; + width: 50%; + + .map-op { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + + .switch-group { + width: 190rpx; + display: flex; + margin-right: 15rpx; + align-items: center; + font-size: 22rpx; + border: 1rpx solid rgb(235, 235, 235); + border-radius: 10rpx; + overflow: hidden; + + .left-check, + .right-check { + flex: 0.5; + background-color: white; + color: #000000; + display: flex; + align-items: center; + justify-content: center; + padding: 16rpx 0; + transition: all 0.5s; + } + + .left-check { + flex: 0.5; + } + + .active { + background-color: $jx-primary; + color: white; + } + + .activeWarring { + background-color: $jx-warring; + color: white; + } + } + + .group-active { + .left-check { + background-color: #d0d0d0; + color: #fff; + } + + .active { + background-color: #a6a6a6; + color: white; + } + } + } + } + + // 右边状态 + .right-handler { + width: 50%; + display: flex; + align-items: center; + justify-content: space-between; + + .waybill-price { + font-size: 26rpx; + color: #666; + text-align: center; + margin-left: 20rpx; + } + + .operation { + text-align: right; + display: flex; + flex-wrap: wrap; + + .text { + color: #4EB331; + font-size: 30rpx; + text-align: center; + font-weight: bold; + } + + .text-ing { + color: $jx-warring; + font-weight: bold; + } + } + + .operation-text { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .text { + color: #9a9a9a; + font-size: 27rpx; + text-align: center; + } + } + } + + .btn { + width: 150rpx; + height: 50rpx; + background: #4EB331; + border-radius: 6rpx; + border: 1rpx solid rgba(0, 0, 0, 0.08); + color: white; + font-size: 27rpx; + line-height: 50rpx; + text-align: center; + } + + .cancel { + background: #D34B3B; + } + + .errStr { + color: #D34B3B; + font-size: 30rpx; + } + + .delivering101 { + color: #0073EA; + } + + .delivering102 { + color: #ff6a20; + } +} + +.deActive { + position: relative; + background-color: #f5f5f5; + + .deActive-mak { + position: absolute; + left: 0; + top: 0; + background-color: transparent; + height: 100rpx; + width: 100%; + } +} \ No newline at end of file diff --git a/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.ts b/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.ts new file mode 100644 index 0000000..cbfa260 --- /dev/null +++ b/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.ts @@ -0,0 +1,251 @@ +import order from '@/api/https/order' +import toast from "@/utils/toast" +import { computed, ref } from "vue" +import configData from "@/utils/configCms" +import { jx_throttles } from "@/utils/tools" + +/************************************************* + * 三方配送 +*/ +interface propType { + vendor: string | number + waybillFee: AnyObject + orderData: AnyObject + accountBalance: number + sotreID: number + createDeliveryType: number +} +function threeDeliverFn(props: Readonly, emit: any) { + const waybillFeeStatus = ref(props.waybillFee) + + /************************************************* + * 动态class + */ + const vendorClass = computed(() => { + if (props.waybillFee.waybill && props.waybillFee.waybill.status > 10) { + return 'delivering' + props.vendor + } else { + return '' + } + }) + + /************************************************* + * 配送名称 + */ + const configCms:AnyObject = configData.serveInfo + const vendorName = computed(() => { + return props.vendor ? configCms.vendorName[props.vendor] : '' + }) + + /************************************************* + * 等待发单 + */ + const countDown = computed(() => { + // 计算分 + let minites = Math.floor(props.waybillFee.timeoutSecond / 60) + // 计算秒 + let seconds = props.waybillFee.timeoutSecond % 60 + return `${minites < 10 ? '0' + minites : minites}分${seconds < 10 ? '0' + seconds : seconds}秒` + }) + + /************************************************* + * 新的计算方式 + */ + const newPrice = computed(() => { + if (waybillFeeStatus.value.status) { + const fee = props.waybillFee.waybill ? props.waybillFee.waybill.desiredFee : props.waybillFee.deliveryFee + return `¥${(fee / 100).toFixed(2)}
(预估支出)
` + } else { + return '--
(预估支出)
' + } + }) + + + /************************************************* + * 判断是否展示无骑手文字 + */ + const tipText = computed(() => { + if (waybillFeeStatus.value.status) { + const fee = props.waybillFee.waybill ? props.waybillFee.waybill.desiredFee : props.waybillFee.deliveryFee + if (fee == 0) { + return true + } else { + return false + } + } + }) + + /************************************************* + * 切换发单状态 + */ + const switchStatus = jx_throttles({ + time: 1000, + success: (status: number) => { + uni.vibrateShort({}) + if (status === waybillFeeStatus.value.status && status == 0) { + return toast('已经是关闭状态') + } + if (status === waybillFeeStatus.value.status && status == 1) { + return toast('已经是打开状态') + } + waybillFeeStatus.value.status = status + emit('switchStatus', { + vendorID: props.vendor, + status, + waybillFee: props.waybillFee, + }) + console.log(props, '切换发单状态', waybillFeeStatus.value) + }, + fail: (t: number) => { + toast('操作过快') + } + }) + + + /************************************************* + * 立即召唤 + */ + const maskMap = ref({ + '101': 16, + '102': 32 + }) + + /************************************************* + * 立即发单 + */ + const createWaybill = jx_throttles({ + time: 3000, + success: () => { + uni.vibrateShort({}) + let data = + (props.orderData.baseFreightMoney || 400) * 0.9 - + (props.waybillFee.waybill + ? props.waybillFee.waybill.desiredFee + : props.waybillFee.deliveryFee) + let tempdata = Math.abs(data / 100) + if (props.createDeliveryType == 0) { + //系统发单 + if (tempdata > 10) { + uni.jxConfirm({ + title: '提示', + content: `配送费超过10元,是否继续发单`, + success: () => { + hireRider() + } + }) + } else { + hireRider() + } + } else { + //门店发单 + if (props.accountBalance < 10) { + uni.jxAlert({ + title: '提示', + content: '余额不足10元,请充值后发单' + }) + } else { + orderCreate(tempdata) + } + } + }, + fail: (t: number) => { + toast(`${t}秒后在试`) + } + }) + async function hireRider() { + uni.showLoading({ title: '召唤中...' }) + let data = { + vendorOrderID: props.orderData.vendorOrderID, + vendorID: props.orderData.vendorID, + courierVendorIDs: JSON.stringify([Number(props.vendor)]), + forceCreate: false, + maxAddFee: 0, + maxDiffFee2Mtps: 0, + } + if (props.waybillFee && props.waybillFee.deliveryFee) data.maxAddFee = props.waybillFee.deliveryFee + let res = await order.create_waybill_on_providers(data) + uni.hideLoading() + if (res.code == 0) { + uni.jxAlert({ + title: '提示', + content: '召唤成功', + success: () => { + emit('refresh') + } + }) + } else { + uni.jxAlert({ + title: '提示', + content: `召唤失败${res.desc || res.data}` + }) + } + } + function orderCreate(tempdata: number) { + if (props.accountBalance > tempdata) { + uni.jxConfirm({ + title: '提示', + content: `是否手动召唤${vendorName.value}`, + confirmText: '召唤', + success: () => { + hireRider() + } + }) + } else { + uni.jxConfirm({ + title: '提示', + content: '配送余额不足,点击确定对账号充值' + }) + } + } + + /************************************************* + * 取消三方配送 + */ + function cancelWaybill() { + uni.jxConfirm({ + title: '提示', + content: `是否取消${vendorName.value}`, + success: async () => { + uni.showLoading({ title: '取消中...' }) + let data = { + vendorWaybillID: props.waybillFee.waybill.vendorWaybillID, + waybillVendorID: props.waybillFee.waybill.waybillVendorID, + reasonID: 0, + reason: '不想发了', + } + let res = await order.cancel_waybill(data) + uni.hideLoading() + if (res.code == 0) { + uni.jxAlert({ + title: '提示', + content: '取消成功', + success: () => { + emit('refresh') + } + + }) + } else { + uni.jxAlert({ + title: '提示', + content: `取消失败${res.desc || res.data}` + }) + } + } + }) + } + + return { + vendorClass, // 动态class + vendorName, // 配送名字 + countDown, // 等待发单 + newPrice, // 新的计算方式 + maskMap, // 立即召唤 + createWaybill, // 立即发单 + switchStatus, // 切换发单 + cancelWaybill, // 取消三方配送 + waybillFeeStatus, // 是否打开自动发单 + tipText, // 是否展示当前范围无骑手问题 + } +} + +export default threeDeliverFn \ No newline at end of file diff --git a/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.vue b/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.vue new file mode 100644 index 0000000..9753695 --- /dev/null +++ b/src/subPages/orderChild/deliverManager/threeDeliver/threeDeliver.vue @@ -0,0 +1,154 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/getPhone/getPhone.vue b/src/subPages/orderChild/getPhone/getPhone.vue new file mode 100644 index 0000000..b1be322 --- /dev/null +++ b/src/subPages/orderChild/getPhone/getPhone.vue @@ -0,0 +1,94 @@ + + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/orderDetail/detailChild/goodsList.vue b/src/subPages/orderChild/orderDetail/detailChild/goodsList.vue new file mode 100644 index 0000000..04064d4 --- /dev/null +++ b/src/subPages/orderChild/orderDetail/detailChild/goodsList.vue @@ -0,0 +1,607 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/orderDetail/detailChild/goodsRefund.vue b/src/subPages/orderChild/orderDetail/detailChild/goodsRefund.vue new file mode 100644 index 0000000..f01f3ba --- /dev/null +++ b/src/subPages/orderChild/orderDetail/detailChild/goodsRefund.vue @@ -0,0 +1,122 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/orderDetail/orderDetail.scss b/src/subPages/orderChild/orderDetail/orderDetail.scss new file mode 100644 index 0000000..9004797 --- /dev/null +++ b/src/subPages/orderChild/orderDetail/orderDetail.scss @@ -0,0 +1,485 @@ +%globalStyle { + padding: 20rpx 15rpx; + border-bottom: 1rpx solid #e7e7e7; + background-color: #fff; + font-size: 30rpx; +} + +%flex { + display: flex; + justify-content: space-between; + align-items: center; +} + +// 品牌 +.brandStatus { + @extend %globalStyle; + @extend %flex; + background-color: #f1f3e9; + + .left { + @extend %flex; + + .index-0 { + color: $jx-primary !important; + } + + .index-5 { + color: $jx-primary !important; + } + + .index-1 { + color: #000000 !important; + } + + .index-2 { + color: #008de1 !important; + } + + .index-3 { + color: #008de1 !important; + } + + .index-9 { + color: $jx-primary !important; + } + + .index-11 { + color: #0065fa !important; + } + + .h-number { + font-size: 28rpx; + display: flex; + align-items: center; + + .brand { + display: inline-block; + width: 40rpx; + height: 40rpx; + flex-shrink: 0; + background-size: 100%; + border-radius: 15rpx; + background-repeat: no-repeat; + } + + .num-root { + font-size: 24rpx; + margin-left: 10rpx; + } + + .num { + font-size: 38rpx; + font-weight: bold; + } + } + + .type { + display: inline-block; + color: white; + background: $jx-primary; + border-radius: 8rpx; + width: 120rpx; + height: 48rpx; + line-height: 48rpx; + text-align: center; + font-size: 26rpx; + margin-left: 15rpx + } + + .type-active { + background-color: $jx-warring !important; + animation: enlarge 1.5s linear infinite; + } + + @keyframes enlarge { + 0% { + transform: scale(0.9); + } + + 50% { + transform: scale(1.1); + } + + 100% { + transform: scale(0.9); + } + } + } + + + .right { + @extend %flex; + + .btn-print { + display: inline-block; + margin-right: 15rpx; + width: 50rpx; + height: 50rpx; + background: url(https://image.jxc4.com/image/dcd4683420297286a61bc6fb2fbe56d7.png) center center no-repeat; + background-size: 100%; + z-index: 100; + } + + .order-status { + color: $jx-primary; + background-color: rgba($color: #000000, $alpha: 0) + } + } +} + +// 订单编号 +.order-number { + @extend %globalStyle; + @extend %flex; + + .cancel { + padding: 7rpx 15rpx; + background: rgba(78, 179, 49, 0.3); + border: 2rpx solid rgba(78, 179, 49, 0.3); + font-size: 24rpx; + color: $jx-primary; + border-radius: 6rpx; + text-align: center; + } + + .order-num { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +// 下单时间 +.create-order-timer { + display: flex; + position: relative; + @extend %globalStyle; + + image { + position: absolute; + right: 15rpx; + width: 60rpx; + height: 60rpx; + top: 5rpx; + } +} + +// 预计送达 +.estimate-service { + @extend %globalStyle; +} + +.dsd-expectTime { + color: $jx-warring !important; + font-weight: bold +} + +// 订单状态 +.order-status { + @extend %globalStyle; + color: $jx-warring; +} + +// 条形码 +.barcode { + @extend %globalStyle; + text-align: center; + + image { + width: 600rpx; + height: 200rpx; + } +} + +// 用户信息 +.user-name { + @extend %globalStyle; + display: flex; + justify-content: space-between; + padding: 15rpx; + + // .user-info{ + // @extend %flex; + // width: 100%; + // } + + .see-map { + padding: 7rpx 15rpx; + background: rgba(78, 179, 49, 0.3); + border: 2rpx solid rgba(78, 179, 49, 0.3); + font-size: 24rpx; + color: $jx-primary; + border-radius: 6rpx; + text-align: center; + } + + + // .user-operation{ + // // display: flex; + // // justify-content: space-between; + + // // @extend %globalStyle; + // @extend %flex; + // margin-top: 10rpx; + // } + + .mobile { + color: $jx-primary + } + + .auxiliary { + color: #969696; + } + + .connectUser{ + width: 38rpx; + height: 38rpx; + } +} + +.user-name-self { + color: #ff0000; + font-weight: bold; + justify-content: center; +} + +// 备注 +.remarks { + color: $jx-primary; + font-weight: bold; + font-size: 38rpx; +} + +// 地址分割 +.divider { + width: 100%; + height: 7rpx; + background: white url('../../../static/image/global/order-divider.png') 0 0 no-repeat; + background-size: 100%; +} + +// 物流 +.logistics { + margin-top: 25rpx; + + .waybill { + @extend %globalStyle; + @extend %flex; + + .auxiliary { + color: #969696; + } + } + + .waybiller { + @extend %globalStyle; + font-size: 32rpx; + display: flex; + align-items: center; + + .brand { + display: inline-block; + width: 40rpx; + height: 40rpx; + flex-shrink: 0; + background-size: 100%; + background-repeat: no-repeat; + border-radius: 15rpx; + } + + .courierName { + margin-right: 20rpx; + margin-left: 20rpx; + } + + .courierMobile { + color: $jx-primary; + } + } + +} + + +// 运单状态 +.waybill-status-root { + @extend %globalStyle; + + .waybill-status { + color: #666666; + height: 60rpx; + line-height: 60rpx; + + .timer { + position: relative; + display: inline-block; + width: 210rpx; + } + + .timer::after { + position: absolute; + content: ""; + width: 20rpx; + height: 20rpx; + background-color: #d2d2d2; + border-radius: 50%; + right: -10rpx; + top: 25rpx; + + } + + .timer::before { + position: absolute; + content: ""; + right: -1rpx; + height: 60rpx; + width: 2rpx; + background-color: #d2d2d2; + + } + + .timer1::before { + position: absolute; + content: ""; + right: -1rpx; + bottom: 0; + height: 30rpx !important; + width: 2rpx; + background-color: #d2d2d2 !important; + } + + .statues { + display: inline-block; + padding-left: 40rpx + } + } + + .waybill-status-active { + color: $jx-primary; + font-weight: bold; + + .timer::after { + position: absolute; + content: ""; + width: 20rpx; + height: 20rpx; + background-color: $jx-primary; + border-radius: 50%; + right: -10rpx; + top: 25rpx; + + } + } +} + +// 售后单 +.afsOrder { + @extend %globalStyle; + + .order-num { + color: $jx-primary; + text-decoration: underline; + + } +} + +// 商品列表 +.goods-list { + @extend %globalStyle; + @extend %flex; + margin-top: 25rpx; + + .left { + display: flex; + + .goods-num { + margin-left: 20rpx; + color: #969696; + } + } + + .to-adjustpage { + padding: 8rpx 15rpx; + background: rgba(78, 179, 49, 0.3); + border: 2rpx solid rgba(78, 179, 49, 0.3); + color: $jx-primary; + border: 2rpx solid rgba(78, 179, 49, 0.3); + border-radius: 6rpx; + } +} + +// 拣货完成 +.finish-pick { + background-color: $jx-primary; + text-align: center; + padding: 40rpx; + color: #fff; + font-weight: bold; + border-top: 2rpx solid #fff; +} + +.finish-pick-fail { + background-image: linear-gradient(135deg, #ff6a20, #ec903f); + text-align: center; + padding: 20rpx 0; + color: #fff; + font-weight: bold; +} + +.elemIDSuf { + color: #008DE1; + font-weight: bold; +} + + +.icon { + width: 48rpx; + height: 48rpx; +} + +.icon-dd { + background: url(http://image.jxc4.com/image/0e1077eb63d075a39a813aaacd0fbe7d.png) 0 0 no-repeat; + background-size: 100%; +} + +.icon-fn { + background: url(http://image.jxc4.com/image/a432bb1ae686329faafb1e027aa3fe43.png) 0 0 no-repeat; + background-size: 100%; +} + +.icon-mt { + background: url(http://image.jxc4.com/image/ef68485f57c874b192f18aaf243f9277.png) 0 0 no-repeat; + background-size: 100%; +} + +.tip { + display: flex; + justify-content: center; + align-items: center; + background-color: #fbcf53; + color: #fff; +} + +.map { + width: 100%; + height: 10vh; + background-color: transparent; +} + + +.store-name { + background-color: #f73d7a; + border: 2rpx solid #fff; + color: #fff; + width: 200rpx; + text-align: center; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + border-radius: 5rpx; +} + +.no-status { + color: $jx-primary; + font-weight: bold; +} \ No newline at end of file diff --git a/src/subPages/orderChild/orderDetail/orderDetail.ts b/src/subPages/orderChild/orderDetail/orderDetail.ts new file mode 100644 index 0000000..66f05c7 --- /dev/null +++ b/src/subPages/orderChild/orderDetail/orderDetail.ts @@ -0,0 +1,629 @@ +import order from '@/api/https/order' +import toast from '@/utils/toast' +import { store } from '@/store' +import { timeFormatHMS, timeFormatDHM, clearList } from '@/utils/tools' +import { onLoad, onUnload,onShow } from '@dcloudio/uni-app' +import { computed, onBeforeUnmount, ref } from 'vue' +import useOrderInfo from '@/composables/useOrderInfo' +import configCms from "@/utils/configCms" +import { setStorage, getStorage, cleatStorage } from '@/utils/storage' +// import log from '@/utils/log' + +/** + * 订单详情 + * @param * + * @return 模板使用数据与方法,详情内容请查看return + */ +function orderDetailFn() { + const { phoneCall, afterSalesDetaile } = useOrderInfo() + onUnload(() => { + cleatStorage("templateMessage") + }) + + /*************************************************************** + * 收集传递信息 + */ + const vendorID = ref(0) + const vendorOrderID = ref(0) + onLoad(async (options: any) => { + // // 订单管理-新订单通知 + // let logData = { + // '日志记录时间': Date(), + // '启动类型': '订单详情', + // '启动参数': options, + // '用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN', + // '用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号', + // '店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID', + // '店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字', + // } + // log.info(JSON.stringify(logData)) + + vendorID.value = options.vendorID + vendorOrderID.value = options.vendorOrderID + store.commit('storeInfo/jxLoadingFn', true) + await getOrderInfo(options.vendorOrderID) // 获取订单详情 + await getBarCode() // 获取条形码 + await getWayBill(2) // 获取运单状态 + await GetAfsOrders() // 售后单 + await getSkuList() // 获取商品列表 + await getComplaintList() // 是否可以投诉骑手 + store.commit('storeInfo/jxLoadingFn', false) + }) + + onShow(() => { + if(getStorage('reLoadOrderDetail')) getSkuList() + }) + + /*************************************************************** + * 获取订单详情 + * @vendorOrderID {number} 订单号 + */ + const invoiceTitle = ref('') // 发票抬头 + const invoiceTaxerID = ref('') // 纳税人ID + const orderData = ref({ + vendorID: -99 // 默认值判断,防止页面渲染报错 + }) // 订单信息1 + async function getOrderInfo(vendorOrderID: number) { + let res = await order.get_orders({ vendorOrderID }) + if (res.code == 0 && res.data.totalCount) { + // 公众号模板消息-新订单通知 + let templateMessage: any = getStorage("templateMessage") + let newData = res.data.data[0] + if (templateMessage && templateMessage.scene === 1043) { + setStorage("storeID", +newData.jxStoreID) + await store.dispatch('storeInfo/getOneStore', newData.jxStoreID) + } + if (getStorage('storeID') != newData.jxStoreID) { + setStorage('storeID', +newData.jxStoreID) + await store.dispatch('storeInfo/getOneStore', +newData.jxStoreID) + } + invoiceTitle.value = newData.invoiceTitle + invoiceTaxerID.value = newData.invoiceTaxerID + orderData.value = newData + GetOrderInfo(newData, vendorOrderID) + } else { + uni.jxAlert({ + title: '提示', + content: '获取订单号信息失败', + success: () => { + uni.navigateBack() + } + }) + } + } + const orderInfo = ref({ + vendorID: -99 // 默认值判断,防止页面渲染报错 + }) // 订单信息2 + async function GetOrderInfo(orderData: AnyObject, vendorOrderID: number) { + let data = { + vendorOrderID, + vendorID: orderData.vendorID, + refresh: false + } + let res = await order.get_order_info(data) + if (res.code == 0) { + orderInfo.value = res.data + // 是否是京西新用户 + if (res.data.vendorID == 9) getOrderUserBuyFirst(res.data.vendorOrderID) + } else { + uni.jxAlert({ + title: '提示', + content: '获取订单号信息失败', + success: () => { + uni.navigateBack() + } + }) + } + } + // 获取条形码 + const barCodeImg = ref('https://image.jxc4.com/image/34e6c3b22b914d7102c99bebfc95f9dd.png') + async function getBarCode() { + let data = { + width: 600, + height: 200, + codetype: 'bar', + srcData: vendorOrderID.value, + } + let res = await order.create_qrOr_bar_code(data) + if (res.code == 0) barCodeImg.value = res.data + } + // 查询京西是否是新用户 + const isNewUser = ref(false) + async function getOrderUserBuyFirst(vendorOrderID: number) { + let res = await order.get_order_user_buy_first({ vendorOrderID }) + if (res.code == 0) isNewUser.value = res.data + } + + + /*************************************************************** + * 订单状态 + */ + const orderType:AnyObject = configCms.serveInfo + const orderStatus = computed(() => { + if (orderData.value.status != '') { + return orderType.orderStatus[orderData.value.status] + } else { + return '未知' + } + + }) + + + /*************************************************************** + * 取消订单 + */ + function cancelOrder(vendorOrderID: string) { + uni.jxConfirm({ + title: '提示', + content: '是否取消该订单', + success: async () => { + let data = { + vendorOrderID: vendorOrderID, + isDetail: true + } + let res = await order.getafs_orders(data) + if (res.code == 0) { + handleResData(res.data) + if (cancelOrderFail.value) { + uni.jxAlert({ + title: '提示', + content: '有待审核的售后单,请先审核售后单再取消订单', + success: () => { + afterSalesDetaile(res.data.data[0].afsOrderID || 123) + } + }) + } else { + let data = { + vendorOrderID: vendorOrderID, + vendorID: vendorID.value, + // %E5%8D%8F%E5%95%86%E4%B8%80%E8%87%B4 这一串是啥密文,没搞清从哪编译来的 + // reason: '%E5%8D%8F%E5%95%86%E4%B8%80%E8%87%B4' + reason: '协商一致' + } + let res = await order.cancel_order(data) + if (res.code == 0) { + toast('取消成功', 1) + uni.jxAlert({ + title: '提示', + content: '取消成功' + }) + } else { + uni.jxAlert({ + title: '提示', + content: `取消失败:${res.desc || res.data}` + }) + } + } + } else { + uni.jxAlert({ + title: '提示', + content: `取消失败:${res.desc || res.data}` + }) + } + } + }) + } + const afsCount = ref(0) // 取消订单标识 + const cancelOrderFail = ref(false) + function handleResData(res: AnyObject) { + res.data && res.data.forEach((item: AnyObject) => { + item.skus.forEach((item: AnyObject) => { + afsCount.value += item.count + if (afsCount.value == orderData.value.goodsCount) cancelOrderFail.value = true + }) + afsCount.value = 0 + }) + } + + + /** + * 拨打电话 + */ + function callPhone(item:AnyObject) { + let itemList:string[] = [] + if(item.consigneeMobile) itemList.push('临1:' + item.consigneeMobile.split(',')[0] +'转' + item.consigneeMobile.split(',')[1]) + if(item.consigneeMobile2) itemList.push('临2:' + item.consigneeMobile2.split(',')[0] +'转' + item.consigneeMobile2.split(',')[1]) + if(itemList.length === 0) return toast('该订单暂无联系方式', 2) + uni.showActionSheet({ + // title: '退出后不会删除任何数据', + itemColor: '#4eb331', + itemList, + popover: { + width: 5000, + }, + success: function (res) { + if(res.tapIndex === 0) phoneCall(item.consigneeMobile) + if(res.tapIndex === 1) phoneCall(item.consigneeMobile2) + } + }); + } + + + /*************************************************************** + * 联系用户 + */ + function realMobile() { + if(orderData.value.vendorID === 1){ + if(store.getters['storeInfo/imMtStatus'][0].imStatus !== 1) return toast('美团IM状态已关闭', 1) + setStorage('vendorUserInfo',{ + venderOrderID:orderData.value.vendorOrderID, + orderSeq:orderData.value.orderSeq, + vendorOrgCode:orderData.value.vendorOrgCode, + vendorStoreID:orderData.value.vendorStoreID, + userID:orderData.value.vendorUserID, + vendorID:orderData.value.vendorID + }) + uni.navigateTo({ url: '/subPages/messageChild/msgChat/msgChat' }) + }else{ + // 饿百 + toast('暂不支持聊天', 2) + } + } + + + /*************************************************************** + * 饿佰订单号 + */ + const elemIDPre = computed(() => { + return orderData.value.vendorOrderID2 ? orderData.value.vendorOrderID2.slice(0, orderData.value.vendorOrderID2.length - 4) : '' + }) + const elemIDSuf = computed(() => { + return orderData.value.vendorOrderID2 ? orderData.value.vendorOrderID2.slice(orderData.value.vendorOrderID2.length - 4) : '' + }) + + + /*************************************************************** + * 格式化预计送达时间 + */ + const expectTime = computed(() => { + if ( + !orderData.value.expectedDeliveredTime || + orderData.value.expectedDeliveredTime.indexOf('1970') !== -1 + ) { + // 处理预计送达数据为空 + return timeFormatHMS() + } else { + return timeFormatHMS(orderData.value.expectedDeliveredTime) + } + }) + + + /** + * 是否隐藏订单信息 + */ + const isHiddenOrderInfo = computed(() => { + return !(orderData.value.buyerComment && orderData.value.buyerComment.includes('支付方式')) + }) + + + /*************************************************************** + * 收益异常处理 + */ + const isPointStore = computed(() => { + return store.getters['storeInfo/isPointStore'] + }) + const earningTooSmall = computed(() => { + const { payPercentage } = storeInfo.value + const { + totalShopMoney, + desiredFee, + shopPrice, + distanceFreightMoney, + waybillTipMoney, + } = orderData.value + let jxEarning = 0 + if (isPointStore.value) { + // 扣点 + jxEarning = (totalShopMoney * payPercentage) / 200 / 100 + } else { + // 报价 + jxEarning = + (totalShopMoney - + desiredFee - + shopPrice - + distanceFreightMoney - + waybillTipMoney) / + 100 + } + if ( + (jxEarning < -10 || totalShopMoney < 0) && + orderData.value.buyerComment.indexOf('【JD】') == -1 + ) { + return true + } else { + return false + } + }) + + + /*************************************************************** + * 获取门店信息 + */ + const storeInfo = computed(() => { + return store.state.storeInfo.allStoreInfo + }) + + + /*************************************************************** + * 均价 + */ + const avgPriceInfo = computed(() => { + const avgPrice = orderInfo.value.avgPrice || 0 + if (avgPrice <= 2000) { + return '超低' + } else if (avgPrice > 2000 && avgPrice <= 4000) { + return '较低' + } else if (avgPrice > 4000 && avgPrice <= 10000) { + return '中等' + } else if (avgPrice > 10000 && avgPrice <= 20000) { + return '较高' + } else if (avgPrice > 20000) { + return '超高' + } + }) + + + /*************************************************************** + * 运单状态 + */ + const finallyWaybillStatus = ref([]) // 最终运单状态 + const waybillStatus = computed(() => { + let orderStatus:AnyObject = configCms.serveInfo.waybillStatus + let newArr: Array = [] + let delivery: any = {} + finallyWaybillStatus.value.forEach((element: AnyObject) => { + delivery[element.vendorID] = (configCms as AnyObject).serveInfo.vendorName[element.vendorID] + if (element.vendorOrderID == orderData.value.vendorWaybillID) { + let obj = { + ...element, + status: orderStatus[element.status], + statusTime: timeFormatDHM(element.statusTime) + } + newArr.push(obj) + } + }) + return newArr + }) + async function getWayBill(orderType: number) { + let data = { + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + orderType + } + let res = await order.get_order_status_list(data) + if (res.code == 0 && res.data != null) { + finallyWaybillStatus.value = res.data + } + } + + + /*************************************************************** + * 查询售后单 + */ + const afsOrder = ref>([]) + async function GetAfsOrders() { + let data = { + vendorOrderID: vendorOrderID.value + } + let res = await order.get_afs_orders(data) + if (res.code == 0) { + afsOrder.value = res.data.data || [] + } + } + + + /*************************************************************** + * 获取商品列表 + */ + const skuList = ref>([]) + const totalCount = ref(0) + async function getSkuList() { + let data = { + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value + } + let res = await order.get_order_sku_info(data) + if (res.code == 0) { + skuList.value = res.data + skuList.value.forEach((item: AnyObject) => { + totalCount.value += item.count + item.comparePrice = (item.shopPrice / 100).toFixed(2) + item.earnPrice = (item.earningPrice / 100).toFixed(2) + item.saleSalePrice = (item.salePrice / 100).toFixed(2) + }) + setStorage('reLoadOrderDetail',false) + } + } + + + /*************************************************************** + * 跳转创建售后单 + * @param {type} 1部分退款 2发起售后 + * @param {skuList} 部分退款数据 + * @param {tel} 用户手机号 + */ + function toCreateAfsOrderPage(type: number, tel?: string) { + if (type == 1) { + uni.jxConfirm({ + title: '提示', + content: '修改订单比例大于10%您的门店将被下线。请联系客户\r\n1.请联系客户更换其他等价商品\r\n2.联系客户说明可做售后退款', + confirmText: '继续退款', + cancelText: '联系客服', + success: () => { + let data = JSON.stringify({ + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + buyerComment:orderData.value.buyerComment + }) + uni.navigateTo({ + url: `/subPages/orderChild/createAfterSales/createAfterSales?type=${type}&data=${data}` + }) + }, + fail: () => { + phoneCall(tel!) + } + }) + } else { + let data = JSON.stringify({ + vendorOrderID: vendorOrderID.value, + vendorID: vendorID.value, + buyerComment:orderData.value.buyerComment + }) + uni.navigateTo({ + url: `/subPages/orderChild/createAfterSales/createAfterSales?type=${type}&data=${data}` + }) + } + } + + + /*************************************************************** + * 平台补贴筛选 + */ + const realPointStore = computed(() => { + if (orderData.value.vendorPayPercentage != 0) { + if (orderData.value.vendorPayPercentage < 50) {//扣点 + return true + } else {//报价 + return false + } + } else { + if (isPointStore.value) {//扣点 + return true + } else {//报价 + return false + } + } + }) + + + /*************************************************************** + * 运营负责人 + */ + const yunyingInfo = computed(() => { + if (typeof vendorID.value === 'undefined') return { name: '', mobile: '' } + const obj:AnyObject = { + 0: ['operatorName', 'operatorPhone'], + 1: ['operatorName2', 'operatorPhone2'], + 3: ['operatorName3', 'operatorPhone3'], + 9: ['operatorName', 'operatorPhone'], + 4: ['operatorName', 'operatorPhone'], + 5: ['operatorName', 'operatorPhone'], + 6: ['operatorName', 'operatorPhone'], + 7: ['operatorName', 'operatorPhone'], + 8: ['operatorName', 'operatorPhone'], + 14: ['operatorName', 'operatorPhone'], + 16: ['operatorName', 'operatorPhone'], + } + return { + name: storeInfo.value[obj[vendorID.value][0]], + mobile: storeInfo.value[obj[vendorID.value][1]], + } + }) + + const waybillType = computed(() => { + switch (orderData.value.waybillVendorID) { + case 0: + return 'dd' + case 1: + return 'mt' + case 2: + return 'fn' + case 3: + return 'fn' + case 101: + return 'dd' + case 102: + return 'mt' + default: + return orderData.value.waybillVendorID + } + }) + + + /** + * 拣货完成 + */ + async function pickingComplete(vendorOrderID: string, vendorID: string) { + let data = { + vendorOrderID, + vendorID, + } + let res = await order.finished_pickup(data) + if (res.code == 0) { + toast('拣货成功', 1) + // 刷新订单 + } else { + toast('拣货异常', 2) + } + } + + + /************************************************* + * 投诉骑手 + */ + function complaintHandler(vendorOrderID: string) { + uni.navigateTo({ + url: `/subPages/orderChild/complaint/complaint?vendorOrderID=${vendorOrderID}` + }) + } + + const isComplaint = ref(false) + /************************************************* + * 查看是否能投诉骑手 + */ + async function getComplaintList() { + const res = await order.complaint_rider_list({ vendorOrderID: orderData.value.vendorOrderID }) + if (res.code == 0 && res.data != null) { + // 可以投诉 + isComplaint.value = true + } else { + // 只能投诉三方配送,不能投诉官方配送 + isComplaint.value = false + } + } + + + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + clearList() + }) + + + return { + invoiceTitle, // 抬头发票 + invoiceTaxerID, // 纳税 + orderData, // 信息1 + orderInfo, // 信息2 + orderStatus, // 订单状态 + cancelOrder, // 取消订单 + elemIDPre, // 饿了么订单编号 + elemIDSuf, // 饿了么订单编号 + expectTime, // 预计送达 + barCodeImg, // 条形码 + earningTooSmall, // 收益异常 + isNewUser, // 新用户 + realMobile, // 真实手机号 + avgPriceInfo, // 均价 + waybillStatus, // 运单状态 + afsOrder, // 售后单 + skuList, // 商品列表 + totalCount, // 商品数量 + toCreateAfsOrderPage, // 跳转到售后单页面 + isPointStore, // 扣点信息 + realPointStore, // 平台补贴筛选 + storeInfo, // 门店收款人 + yunyingInfo, // 运营负责人 + waybillType, // 快递类型 + pickingComplete, // 拣货完成 + complaintHandler, // 投诉骑手 + isComplaint, // 是否可以投诉骑手 + isHiddenOrderInfo, // 是否隐藏订单信息 + callPhone // 拨打电话 + } +} + + +export default orderDetailFn diff --git a/src/subPages/orderChild/orderDetail/orderDetail.vue b/src/subPages/orderChild/orderDetail/orderDetail.vue new file mode 100644 index 0000000..f48a622 --- /dev/null +++ b/src/subPages/orderChild/orderDetail/orderDetail.vue @@ -0,0 +1,504 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/orderChild/seeMap/seeMap.vue b/src/subPages/orderChild/seeMap/seeMap.vue new file mode 100644 index 0000000..2009aee --- /dev/null +++ b/src/subPages/orderChild/seeMap/seeMap.vue @@ -0,0 +1,480 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoods.scss b/src/subPages/shoppingChild/createGoods/createGoods.scss new file mode 100644 index 0000000..7e42ccf --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoods.scss @@ -0,0 +1,11 @@ +.bottom-filter { + + .item { + width: 100%; + background-color: $jx-primary; + height: 90rpx; + line-height: 90rpx; + text-align: center; + color: #fff; + } +} \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoods.ts b/src/subPages/shoppingChild/createGoods/createGoods.ts new file mode 100644 index 0000000..f517fb6 --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoods.ts @@ -0,0 +1,364 @@ +import { getStorage } from "@/utils/storage"; +import toast from "@/utils/toast"; +import { clearList } from "@/utils/tools"; +import { onLoad } from "@dcloudio/uni-app"; +import { onBeforeUnmount, ref } from "vue"; +import shopping from '@/api/https/shopping' + +/************************************************* + * 创建商品 +*/ +function createGoodsFn() { + + /************************************************* + * 默认数据 + */ + const dafauleData: Array = [ + { + categoryID: 'all', + children: [], + level: 1, + name: '所有分类', + } + ] + + /************************************************* + * 过滤对象空字段 + */ + function keyFilter(obj: AnyObject) { + for (let key in obj) { + if ('' + obj[key] == "" || '' + obj[key] == undefined) { + delete obj[key] + } + } + return obj + } + + /************************************************* + * 数据归位,empty显现 + */ + function dataHoming() { + offset.value = 0 + totalCount.value = 0 + skuNames.value = [] + } + + /************************************************* + * 点击列表 + */ + const isCategoryID = ref(false) + function oneMenuClick(catID: string | number) { + if (catID == 'all') { + isCategoryID.value = false + categoryID.value = '' + dataHoming() + getSkuNames() + } else { + isCategoryID.value = true + categoryID.value = catID + dataHoming() + getSkuNames() + } + } + + onLoad(async () => { + await getSkuNames() + }) + + /************************************************* + * 获取商品数据 + */ + const skuNames = ref>([]) // 商品数据 + const isFocus = ref(false) // 是否关注 + const keyword = ref('') // 关键字搜索 + const fromStatus = ref(0) + const toStatus = ref(1) + const offset = ref(0) + const pageSize = ref(30) + const totalCount = ref(0) + const focusArr = ref>([]) + const categoryID = ref('') + async function getSkuNames() { + isLoad.value = true + let data = { + storeID: getStorage('storeID'), + isFocus: isFocus.value, + keyword: keyword.value, + fromStatus: fromStatus.value, + toStatus: toStatus.value, + offset: offset.value, + pageSize: pageSize.value, + status: -1, + categoryID: categoryID.value + } + keyFilter(data) + let res = await shopping.get_stores_skus_for_store(data) + if (res.code == 0) { + let oldSkuNames: Array = [] + totalCount.value = res.data.totalCount + oldSkuNames = mapskuName(res.data.skuNames || []) + focusArr.value.forEach((item: AnyObject) => { + let arr = oldSkuNames.filter((skuName: AnyObject) => skuName.id === item.nameID) + if (arr.length > 0) { + arr[0].skuNameCheckedStatus = true + } + }) + skuNames.value = skuNames.value.concat(oldSkuNames) + } else { + dataHoming() + } + isLoad.value = false + } + + /************************************************* + * 格式化数据 + */ + function mapskuName(skuNames: Array) { + let arr = skuNames.map(skuName => { + skuName.price = (skuName.unitPrice / 100).toFixed(2) + skuName.skuNameCheckedStatus = false + skuName.skus = skuName.skus.map((sku: any) => { + return { + ...sku, + price: skuName.unit === '份' ? (computedPrice(skuName.price, sku) / 100).toFixed(2) : skuName.price + } + }) + return skuName + }) + return arr + } + + /************************************************* + * 计算sku价格 + */ + function computedPrice(price: any, item: any) { + let skuNamePrice = Math.round(price * 100) // 一斤的价格 + let specQuality = item.specQuality // 质量 + let specUnit = item.specUnit.toLowerCase() // 单位 + if (specUnit === 'kg' || specUnit === 'l') { + specQuality = specQuality * 1000 + } + let temPrice = Math.round(skuNamePrice * specQuality / 500) + return temPrice + } + + /************************************************* + * 更新条件筛选 + */ + function updateTowFilter(type: number) { + if (type == 0) { + isFocus.value = false + } else { + isFocus.value = true + } + keyword.value = '' + rightMainRef.value.createSuccess() + dataHoming() + getSkuNames() + } + + /************************************************* + * 搜索商品 + */ + function serachShopping(text: string) { + dataHoming() + keyword.value = text + getSkuNames() + } + function clearInpu() { + dataHoming() + keyword.value = '' + getSkuNames() + } + + const isSearchGoods = ref(false) + const scanData = ref({}) + /************************************************* + * 扫描二维码 + */ + async function scanCode(text: string) { + let data = { + keyword: text, + status:-1 + } + // 先从京西商品库查询 + let res = await shopping.get_sku_names_new(data) + let obj: AnyObject = {} + if (res.data.skuNames) { + const skuName = res.data.skuNames[0] + const sku = skuName.skus[0] + // _this.keyword = skuName.name 商品名字 + obj.originalName = computedName(skuName, sku) + obj.name = skuName.name + obj.imgList = [skuName.img] + obj.upcCode = skuName.Upc + obj.specQuality = sku.specQuality + obj.specUnit = sku.specUnit + obj.unit = skuName.unit + obj.weight = sku.weight + obj.isJx = true + isSearchGoods.value = true + } else { + // 请求京东仓库 + let data = { + upcCode: text + } + const res = await shopping.get_jd_upc_code_by_name(data) + if (res.data != null) { + obj = res.data[0] + obj.isJx = false + isSearchGoods.value = true + } else { + uni.jxAlert({ + title: '提示', + content: '未查询到商品,请联系运营创建' + }) + } + } + scanData.value = obj + } + + /************************************************* + * 扫码创建商品 + */ + async function scanGoodConfirm(obj: AnyObject) { + isSearchGoods.value = false + let data = { + ...obj, + storeID: getStorage('storeID') + } + const res = await shopping.create_skus_and_focus_from_wx(data) + if (res.code == 0) { + uni.jxAlert({ + title: '提示', + content: "创建成功" + }) + } else { + uni.jxAlert({ + title: '提示', + content: "创建失败,请联系运营进行创建" + }) + } + } + + /************************************************* + * 格式化商品单位 + */ + function computedName(skuName: any, sku: any) { + let name = '' + if (skuName.prefix) name += `[${skuName.prefix}]` + name += skuName.name + if (skuName.unit === '份') name += '约' + name += +sku.specQuality + name += sku.specUnit + name += '/' + skuName.unit + if (sku.comment) name += `(${sku.comment})` + return name + } + + /************************************************* + * 下拉刷新 + */ + const leftBarRef = ref(null) + let onPullDownRefreshTimer: any = null + const triggered = ref(false) + function refresherrefresh() { + triggered.value = true + clearTimeout(onPullDownRefreshTimer) + onPullDownRefreshTimer = setTimeout(() => { + triggered.value = false + leftBarRef.value.GetStoreCategoryMap() + dataHoming() + getSkuNames() + }, 1000) + } + + /************************************************* + * 页面触底加载更多 + */ + const isLoad = ref(false) // 加载图 + function scrolltolower() { + offset.value++ + if (pageSize.value * (offset.value - 1) > totalCount.value || totalCount.value < pageSize.value) { + isLoad.value = false + } else { + if (isLoad.value) return + getSkuNames() + } + } + + /************************************************* + * 新建可售商品 + */ + let newFocusArr: Array = [] + const newGoodsNum = ref(0) + function newCreateGoods(data: Array) { + newGoodsNum.value = data.length + newFocusArr = data + } + + /************************************************* + * 创建商品(关注商品) + */ + const rightMainRef = ref(null) + async function handleFocus(type: number) { + if (newGoodsNum.value == 0) return toast('未选择商品') + uni.jxConfirm({ + title: '提示', + content: `本次操作一共${isFocus.value ? '删除' : '创建'}《${newGoodsNum.value}》个商品,确定操作吗`, + success: async () => { + if (type == 1) { + let data = { + storeIDs: JSON.stringify([getStorage('storeID')]), + payload: JSON.stringify(newFocusArr) + } + let res = await shopping.update_stores_skus(data) + if (res.code == 0) { + isFocus.value ? toast('删除成功', 1) : toast('创建成功,请等待审核', 1) + newFocusArr = [] + rightMainRef.value.createSuccess() + newGoodsNum.value = 0 + dataHoming() + getSkuNames() + } else { + isFocus.value ? toast('删除失败', 2) : toast('创建失败', 2) + } + } + } + }) + } + + + /************************************************* + * 收尾工作 + */ + onBeforeUnmount(() => { + clearList() + }) + + return { + dafauleData, // 列表默认数 + oneMenuClick, // 点击列表项 + skuNames, // 商品数据 + isFocus, // 是否关注 + totalCount, // 未关注条数 + updateTowFilter, // 更新筛选条件 + serachShopping, // 输入框搜索 + clearInpu, // 清空输入框 + scanCode, // 扫码 + refresherrefresh, // 下拉刷新 + triggered, // 动态显示加载 + leftBarRef, // 右侧tab实例 + scrolltolower, // 页面触底 + isLoad, // 加载动画 + newCreateGoods, // 新建可售商品 + newGoodsNum, // 新建商品数量 + handleFocus, // 创建和移除商品 + rightMainRef, // 主体内容实例 + isSearchGoods, // 是否查询到了商品 + scanData, // 查询到的商品详情 + scanGoodConfirm, // 创建商品 + } +} + +export default createGoodsFn \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoods.vue b/src/subPages/shoppingChild/createGoods/createGoods.vue new file mode 100644 index 0000000..cdae5f1 --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoods.vue @@ -0,0 +1,140 @@ + + + + + + \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-filter/create-goods-filter.vue b/src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-filter/create-goods-filter.vue new file mode 100644 index 0000000..f448ffc --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-filter/create-goods-filter.vue @@ -0,0 +1,89 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-search/create-goods-search.vue b/src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-search/create-goods-search.vue new file mode 100644 index 0000000..5fecbb9 --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoodsChild/create-goods-search/create-goods-search.vue @@ -0,0 +1,93 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.scss b/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.scss new file mode 100644 index 0000000..26a7280 --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.scss @@ -0,0 +1,196 @@ +.skuName-cell-focus { + box-sizing: border-box; + background: white; + padding: 19rpx; + border-radius: 10rpx; + margin: 15rpx 15rpx; + box-shadow: 0rpx 2rpx 10rpx rgb(207, 207, 207); + + .skuName { + display: flex; + align-items: flex-start; + position: relative; + + .skuName-img { + image { + width: 180rpx; + height: 180rpx; + border-radius: 10rpx; + border: 1rpx solid rgb(218, 218, 218); + } + } + + .skuName-info { + margin-left: 17rpx; + position: relative; + width: 100%; + + .skuName-name { + color: #333; + font-size: 32rpx; + line-height: 1; + } + + .skuName-monthsale { + font-size: 28rpx; + color: #999; + line-height: 1; + margin-top: 7rpx; + } + + .skuName-checkStatus { + width: 40rpx; + height: 40rpx; + border-radius: 6rpx; + position: absolute; + border: 2rpx solid #ccc; + top: 70rpx; + right: 30rpx; + } + + .skuName-price { + color: $jx-primary; + margin-top: 33rpx; + margin-bottom: 14rpx; + line-height: 1; + position: absolute; + width: 100%; + top: 90rpx; + display: flex; + align-items: center; + + .icon-money { + font-size: 20rpx; + } + + .num { + display: inline-block; + font-size: 38rpx; + font-weight: 500; + } + + .num-input { + border: 1rpx solid $jx-primary; + width: 160rpx; + padding: 5rpx 10rpx; + border-radius: 8rpx; + margin: 0 10rpx; + color: $jx-primary; + } + + .unit { + font-size: 30rpx; + } + } + } + } + + // sku + .skus2 { + text-align: left; + font-size: 30rpx; + border-top: 1rpx solid rgb(219, 219, 219); + + .sku-cell-forfocus+.sku-cell-forfocus { + border-bottom: 1rpx solid rgb(219, 219, 219); + padding: 10rpx 0; + } + + .sku-cell-forfocus { + border-bottom: 1rpx solid rgb(219, 219, 219); + color: rgb(189, 189, 189); + padding: 10rpx 0; + } + + .sku-cell-forfocus-green { + color: $jx-primary; + } + } + + + // sku + .skus { + border-top: 1rpx solid rgb(219, 219, 219); + display: flex; + justify-content: space-between; + flex-wrap: wrap; + margin-top: 10rpx; + + .sku-cell { + width: 48%; + border: 1rpx solid $jx-primary; + border-radius: 10rpx; + margin-top: 20rpx; + align-items: center; + overflow: hidden; + + .sku-root-active { + height: 100%; + } + + .sku-root { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; + } + + .sku-left { + color: $jx-primary; + width: 50%; + line-height: 1.15; + text-align: center; + padding: 5rpx 0; + + .sku-spec { + font-size: 26rpx; + } + + .sku-price { + font-size: 26rpx; + + text { + font-size: 15rpx; + } + } + } + + .sku-right { + position: absolute; + width: 50%; + height: 100%; + background: #ecfce9; + color: $jx-primary; + border-left: 1rpx solid $jx-primary; + transition: all 0.3s; + display: flex; + align-items: center; + justify-content: center; + right: 0; + border-radius: 0 10rpx 10rpx 0; + } + + .isSale { + background-color: $jx-primary; + color: #fff; + } + + .sku-bottom { + min-height: 36rpx; + border-top: 1rpx solid $jx-primary; + font-size: 26rpx; + text-align: center; + color: #f60d58; + width: 100%; + padding: 5rpx 0; + } + } + } +} + +.checkbox { + width: 100%; + display: flex; + justify-content: flex-end; + margin-top: 15rpx; +} \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.ts b/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.ts new file mode 100644 index 0000000..6956ec6 --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.ts @@ -0,0 +1,142 @@ +import { jx_trembling } from "@/utils/tools" +import { ref } from "vue" + +/************************************************* + * 未新建商品 +*/ +function rightMainFn(props: any, emit: any) { + + /************************************************* + * 计算sku价格 + */ + function computedPrice(price: any, item: any) { + let skuNamePrice = Math.round(price * 100) // 一斤的价格 + let specQuality = item.specQuality // 质量 + let specUnit = item.specUnit.toLowerCase() // 单位 + if (specUnit === 'kg' || specUnit === 'l') { + specQuality = specQuality * 1000 + } + let temPrice = Math.round(skuNamePrice * specQuality / 500) + return temPrice + } + + /************************************************* + * 修改商品价格 + */ + const focusArr = ref>([]) + function updateSaleStatus(skuName: AnyObject, sku?: AnyObject) { + if (!props.isFocus) { + addFocus(skuName) + // 修改sku的可售 + sku!.storeSkuStatus = sku!.storeSkuStatus ? 0 : 1 + // 修改 focusArr 的可售 + // 判断修改列表中是否有这个sku + let focus = focusArr.value.find((item: AnyObject) => item.nameID === skuName.id) + if (focus) { + if (sku!.storeSkuStatus) { + // 添加sku + focus.skus.push({ + skuID: sku!.id, + isSale: 1 + }) + } else { + // 删除sku + focus.skus = focus.skus.filter((item: AnyObject) => item.skuID !== sku!.id) + } + focus.skus.length == 0 && removeFocus(skuName) + } + } + } + + /************************************************* + * 添加认领商品 + */ + function addFocus(skuName: AnyObject) { + if (!focusArr.value.find((item: AnyObject) => item.nameID === skuName.id)) { + let skus: Array = [] + skuName.skus.forEach((item: AnyObject) => { + if (item.storeSkuStatus) { + skus.push({ + skuID: item.id, + isSale: 1 + }) + } + }) + if (!props.isFocus) { + focusArr.value.push({ + nameID: skuName.id, + unitPrice: Math.round(skuName.price * 100), + isFocus: props.isFocus ? -1 : 1, + skus + }) + } else { + focusArr.value.push({ + nameID: skuName.id, + isFocus: props.isFocus ? -1 : 1, + }) + } + emit('newCreateGoods', focusArr.value) + } + } + + /************************************************* + * 删除认领商品 + */ + function removeFocus(skuName: AnyObject) { + if (focusArr.value.find((item: AnyObject) => item.nameID === skuName.id)) { + focusArr.value = focusArr.value.filter((item: AnyObject) => item.nameID !== skuName.id) + emit('newCreateGoods', focusArr.value) + } + } + + /************************************************* + * 输入框失焦事件 + */ + function priceBlur(skuName: AnyObject) { + if (skuName.price <= 0) { + skuName.price = 0.01 + skuName.skus = skuName.skus.map((sku: AnyObject) => ({ + ...sku, + price: 0.01 + })) + } + } + + function priceChange(e: AnyObject, skuName: AnyObject) { + priceChangeTrembling(e, skuName) + } + const priceChangeTrembling = jx_trembling((e: AnyObject, skuName: AnyObject) => { + // 计算其他规格价格 + skuName.skus = skuName.skus.map((sku: AnyObject) => ({ + ...sku, + price: skuName.unit === '份' ? (computedPrice(e.detail.value, sku) / 100).toFixed(2) : Number(e.detail.value).toFixed(2) + })) + let focus = focusArr.value.find((item: AnyObject) => item.nameID === skuName.id) + if (focus) { + if (e.detail.value) { + focus.unitPrice = Math.round(e.detail.value * 100) + } else { + focus.unitPrice = 1 + } + } + }, 500) + + function removeGoods(e: AnyObject, skuName: AnyObject) { + if (e.detail.value.length == 0) { + removeFocus(skuName) + } else { + addFocus(skuName) + } + } + + + return { + updateSaleStatus, // 修改商品价格 + priceBlur, // 失去焦点事件 + priceChange, // 输入框改变事件 + focusArr, // 创建商品数据 + removeGoods, // 移除商品 + } +} + +export default rightMainFn \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.vue b/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.vue new file mode 100644 index 0000000..9f09ece --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoodsChild/right-main/right-main.vue @@ -0,0 +1,149 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.scss b/src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.scss new file mode 100644 index 0000000..fa7e8c1 --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.scss @@ -0,0 +1,86 @@ +.big-modal { + position: fixed; + left: 0; + top: 0; + background-color: rgba(black, 0.4); + width: 100vw; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + + .have-goods { + text-align: center; + color: red; + } + + .modal-bg { + background-color: white; + border-radius: 20rpx; + margin: 40rpx; + width: 90vw; + // height: 90vh; + box-sizing: border-box; + padding: 20rpx; + } + + .big-modal-btn-group { + display: flex; + justify-content: space-between; + } + + .btn { + width: 300rpx; + text-align: center; + padding: 20rpx 0; + border-radius: 10rpx; + } + + .btn-cancel { + background: #ccc; + } + + .btn-correct { + background: #ccc; + } + + .btn-create { + background-color: $jx-primary; + color: #fff; + } + + .modal-content { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding-bottom: 50rpx; + } + + .original-name { + color: #666; + font-size: 34rpx; + text-align: center; + } + + .upc-code { + color: #999; + font-size: 30rpx; + margin: 10rpx 0; + } + + .img { + width: 500rpx; + height: 500rpx; + } + + .input { + font-size: 32rpx; + border: 1rpx solid #ccc; + border-radius: 10rpx; + padding: 10rpx 20rpx; + text-align: center; + color: #666; + } +} \ No newline at end of file diff --git a/src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.vue b/src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.vue new file mode 100644 index 0000000..06e10f3 --- /dev/null +++ b/src/subPages/shoppingChild/createGoods/createGoodsChild/searchGoods/searchGoods.vue @@ -0,0 +1,105 @@ + + + + + \ No newline at end of file diff --git a/src/subPages/switchStore/switchStore.scss b/src/subPages/switchStore/switchStore.scss new file mode 100644 index 0000000..50af0f7 --- /dev/null +++ b/src/subPages/switchStore/switchStore.scss @@ -0,0 +1,79 @@ +.fillert-search-root { + position: sticky; + top: 0; + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: space-between; + width: 750rpx; + padding: 10rpx 20rpx; + background-color: #4eb331; + + .fillter-btn { + box-sizing: border-box; + width: 200rpx; + height: 60rpx; + text-align: center; + line-height: 60rpx; + border: 1rpx solid #fff; + color: #fff; + border-radius: 10rpx; + } + + .search-root { + box-sizing: border-box; + width: 490rpx; + background-color: #fff; + // line-height: 45rpx; + border-radius: 10rpx; + + input { + width: 100%; + } + } +} + +.store-item-list { + .item { + box-sizing: border-box; + display: flex; + justify-content: space-between; + align-items: center; + padding: 20rpx; + border-bottom: 1rpx solid rgb(218, 218, 218); + + .city-name { + display: flex; + align-items: center; + + .city { + box-sizing: border-box; + white-space: nowrap; + font-size: 24rpx; + color: rgb(133, 133, 133); + margin-right: 25rpx; + } + + .name { + width: 500rpx; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + + .status { + white-space: nowrap; + font-size: 24rpx; + color: #4eb331; + } + + .status-waring { + color: red !important; + } + } +} + +:deep(.uni-searchbar) { + padding: 0; +} \ No newline at end of file diff --git a/src/subPages/switchStore/switchStore.ts b/src/subPages/switchStore/switchStore.ts new file mode 100644 index 0000000..5854516 --- /dev/null +++ b/src/subPages/switchStore/switchStore.ts @@ -0,0 +1,166 @@ +/** + *@description: 切换门店 + *@return {*} + *@param {}- +*/ +import { Ref, ref } from "vue"; +import toast from "@/utils/toast"; +import configCms1 from "@/utils/configCms"; +import { setStorage } from "@/utils/storage"; +import { onShow } from '@dcloudio/uni-app' +import useGlobalFunc from "@/composables/useGlobalFunc"; +import login from '@/api/https/login' + +const configCms:AnyObject = configCms1 +function switchStoreFn() { + const { logOutFn } = useGlobalFunc() + + onShow(async () => { + await getStore() + await objTarrau() + }) + + /** + * 获取门店信息 + */ + const storeDataList = ref(); + async function getStore() { + let data = { + version: '1.3.5' + } + let storeRes = await login.get_my_store_list(data); + if (storeRes.code == 0) { + let data: Array = storeRes.data || [] + if (data.length > 0) { + storeDataList.value = data; + filterStoreDataList.value = data + } else { + uni.jxAlert({ + title: '提示', + content: '您还没有绑定门店,请联系运营!', + success: () => { + logOutFn() + uni.reLaunch({ + url: '/subPages/login/wxLogin/wxLogin', + }) + } + }) + } + } else { + storeDataList.value = [] + toast("获取门店信息失败"); + uni.jxAlert({ + title: '警告', + content: '获取门店信息失败,重新登录试试!', + success: () => { + logOutFn() + uni.reLaunch({ + url: '/subPages/login/wxLogin/wxLogin', + }) + } + }) + } + } + + /** + * 进入店铺 + */ + function switchStore(id: string, name: string) { + uni.jxConfirm({ + title: '提示', + content: `是否进入【${name}】`, + success: () => { + setStorage("storeID", id); + setStorage('storeName', name) + uni.switchTab({ url: '/pages/merchant/index' }) + }, + }) + } + + /** + * 筛选方法 + */ + const status: Ref = ref("0"); + function changeStatus(e: AnyObject) { + keyword.value = ""; + status.value = e.detail.value; + if (e.detail.value == 0) { + getStore(); + } + if (e.detail.value == 1) { + // 临时休息 + storeDataList.value = storeDataList.value?.filter((item) => { + return item.status == "0"; + }); + } + if (e.detail.value == 2) { + getStore(); + // 营业中 + storeDataList.value = storeDataList.value?.filter((item) => { + return item.status == "1"; + }); + } + if (e.detail.value == 3) { + // 休息 + storeDataList.value = storeDataList.value?.filter((item) => { + return item.status == "-1"; + }); + } + if (e.detail.value == 4) { + // 禁用 + storeDataList.value = storeDataList.value?.filter((item) => { + return item.status == "-2"; + }); + } + } + + /** + * 通过搜索筛选 + */ + const keyword: Ref = ref(""); + const filterStoreDataList = ref() + function searchStore(keyword: string) { + if (keyword == "") { + status.value = "0"; + return getStore(); + } + filterStoreDataList.value = storeDataList.value?.filter((item) => { + if (JSON.stringify(item).indexOf(keyword) > -1) { + return true; + } + }); + } + + /** + * 清空搜索框 + */ + function clearInput() { + keyword.value = ""; + status.value = "0"; + getStore(); + } + + /** + * 获取筛选数据列表 + */ + const pickerDataList: Ref = ref([]); + function objTarrau() { + pickerDataList.value.push("全部"); + for (let key in configCms.storeStatus) { + pickerDataList.value.push(configCms.storeStatus[key]); + } + } + + return { + switchStore, // 进入门店 + status, // 门店状态 + changeStatus, // 选择框过滤门店 + keyword, // 搜索框关键词 + searchStore, // 搜索框搜索门店 + clearInput, // 清空文本框操作 + pickerDataList, // 筛选框 存储 + filterStoreDataList, // 过滤过后的门店 + } +} + +export default switchStoreFn \ No newline at end of file diff --git a/src/subPages/switchStore/switchStore.vue b/src/subPages/switchStore/switchStore.vue new file mode 100644 index 0000000..1e24581 --- /dev/null +++ b/src/subPages/switchStore/switchStore.vue @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/src/uni.scss b/src/uni.scss new file mode 100644 index 0000000..5aa0cf9 --- /dev/null +++ b/src/uni.scss @@ -0,0 +1,64 @@ +$jx-primary: #4eb331; +$jx-warring: #e70808; +$jx-login: #2dd091; + +/* 行为相关颜色 */ +$uni-color-primary: #007aff; +$uni-color-success: #4cd964; +$uni-color-warning: #f0ad4e; +$uni-color-error: #dd524d; + +/* 文字基本颜色 */ +$uni-text-color: #333; // 基本色 +$uni-text-color-inverse: #fff; // 反色 +$uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息 +$uni-text-color-placeholder: #808080; +$uni-text-color-disable: #c0c0c0; + +/* 背景颜色 */ +$uni-bg-color: #fff; +$uni-bg-color-grey: #f8f8f8; +$uni-bg-color-hover: #f1f1f1; // 点击状态颜色 +$uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色 + +/* 边框颜色 */ +$uni-border-color: #c8c7cc; + +/* 尺寸变量 */ + +/* 文字尺寸 */ +$uni-font-size-sm: 12px; +$uni-font-size-base: 14px; +$uni-font-size-lg: 16; + +/* 图片尺寸 */ +$uni-img-size-sm: 20px; +$uni-img-size-base: 26px; +$uni-img-size-lg: 40px; + +/* Border Radius */ +$uni-border-radius-sm: 2px; +$uni-border-radius-base: 3px; +$uni-border-radius-lg: 6px; +$uni-border-radius-circle: 50%; + +/* 水平间距 */ +$uni-spacing-row-sm: 5px; +$uni-spacing-row-base: 10px; +$uni-spacing-row-lg: 15px; + +/* 垂直间距 */ +$uni-spacing-col-sm: 4px; +$uni-spacing-col-base: 8px; +$uni-spacing-col-lg: 12px; + +/* 透明度 */ +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 + +/* 文章场景相关 */ +$uni-color-title: #2c405a; // 文章标题颜色 +$uni-font-size-title: 20px; +$uni-color-subtitle: #555; // 二级标题颜色 +$uni-font-size-subtitle: 18px; +$uni-color-paragraph: #3f536e; // 文章段落颜色 +$uni-font-size-paragraph: 15px; \ No newline at end of file diff --git a/src/uni_modules/uv-datetime-picker/changelog.md b/src/uni_modules/uv-datetime-picker/changelog.md new file mode 100644 index 0000000..b122900 --- /dev/null +++ b/src/uni_modules/uv-datetime-picker/changelog.md @@ -0,0 +1,15 @@ +## 1.0.6(2023-07-05) +修复vue3模式下,动态修改v-model绑定的值无效的BUG +## 1.0.5(2023-07-02) +uv-datetime-picker 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/datetimePicker.html +## 1.0.4(2023-06-29) +1. 修复抖音小程序报错的BUG +## 1.0.3(2023-06-07) +1. 取消defaultIndex参数,传该值没实际意义,后续更新文档 +## 1.0.2(2023-06-02) +1. 修复v-model重新赋值不更新的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-datetime-picker 时间选择器 diff --git a/src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js b/src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js new file mode 100644 index 0000000..99ebc7c --- /dev/null +++ b/src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/props.js @@ -0,0 +1,125 @@ +export default { + props: { + // 是否打开组件 + show: { + type: Boolean, + default: false + }, + // 是否展示顶部的操作栏 + showToolbar: { + type: Boolean, + default: true + }, + // 绑定值 + // #ifdef VUE2 + value: { + type: [String, Number], + default: '' + }, + // #endif + // #ifdef VUE3 + modelValue: { + type: [String, Number], + default: '' + }, + // #endif + // 顶部标题 + title: { + type: String, + default: '' + }, + // 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择 + mode: { + type: String, + default: 'datetime' + }, + // 可选的最大时间 + maxDate: { + type: Number, + // 最大默认值为后10年 + default: new Date(new Date().getFullYear() + 10, 0, 1).getTime() + }, + // 可选的最小时间 + minDate: { + type: Number, + // 最小默认值为前10年 + default: new Date(new Date().getFullYear() - 10, 0, 1).getTime() + }, + // 可选的最小小时,仅mode=time有效 + minHour: { + type: Number, + default: 0 + }, + // 可选的最大小时,仅mode=time有效 + maxHour: { + type: Number, + default: 23 + }, + // 可选的最小分钟,仅mode=time有效 + minMinute: { + type: Number, + default: 0 + }, + // 可选的最大分钟,仅mode=time有效 + maxMinute: { + type: Number, + default: 59 + }, + // 选项过滤函数 + filter: { + type: [Function, null], + default: null + }, + // 选项格式化函数 + formatter: { + type: [Function, null], + default: null + }, + // 是否显示加载中状态 + loading: { + type: Boolean, + default: false + }, + // 各列中,单个选项的高度 + itemHeight: { + type: [String, Number], + default: 44 + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: '取消' + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: '确认' + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: '#909193' + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: '#3c9cff' + }, + // 每列中可见选项的数量 + visibleItemCount: { + type: [String, Number], + default: 5 + }, + // 是否允许点击遮罩关闭选择器 + closeOnClickOverlay: { + type: Boolean, + default: true + }, + // 是否允许点击确认关闭选择器 + closeOnClickConfirm: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.datetimePicker + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue b/src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue new file mode 100644 index 0000000..6f12064 --- /dev/null +++ b/src/uni_modules/uv-datetime-picker/components/uv-datetime-picker/uv-datetime-picker.vue @@ -0,0 +1,369 @@ + + + + diff --git a/src/uni_modules/uv-datetime-picker/package.json b/src/uni_modules/uv-datetime-picker/package.json new file mode 100644 index 0000000..782a318 --- /dev/null +++ b/src/uni_modules/uv-datetime-picker/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-datetime-picker", + "displayName": "uv-datetime-picker 时间选择器 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.6", + "description": "时间选择器组件用于时间日期,主要用于年月日时分秒的选择,具体选择的精确度由参数控制。", + "keywords": [ + "datetime-picker", + "uvui", + "uv-ui", + "datetime", + "时间选择" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-picker" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-datetime-picker/readme.md b/src/uni_modules/uv-datetime-picker/readme.md new file mode 100644 index 0000000..6b78f0d --- /dev/null +++ b/src/uni_modules/uv-datetime-picker/readme.md @@ -0,0 +1,11 @@ +## DatetimePicker 时间选择器 + +> **组件名:uv-datetime-picker** + +此选择器用于时间日期,主要用于年月日时分秒的选择,具体选择的精确度由参数控制。 + +###
查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-icon/changelog.md b/src/uni_modules/uv-icon/changelog.md new file mode 100644 index 0000000..97717c5 --- /dev/null +++ b/src/uni_modules/uv-icon/changelog.md @@ -0,0 +1,15 @@ +## 1.0.5(2023-07-04) +1. 更新图标,删除一些不常用的图标 +2. 删除base64,修改成ttf文件引入读取图标 +3. 自定义图标文档说明:https://www.uvui.cn/guide/customIcon.html +## 1.0.4(2023-07-03) +1. 修复主题颜色在APP不生效的BUG +## 1.0.3(2023-05-24) +1. 将线上ttf字体包替换成base64,避免加载时或者网络差时候显示白色方块 +## 1.0.2(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.1(2023-05-10) +1. 修复小程序中异常显示 +## 1.0.0(2023-05-04) +新发版 diff --git a/src/uni_modules/uv-icon/components/uv-icon/icons.js b/src/uni_modules/uv-icon/components/uv-icon/icons.js new file mode 100644 index 0000000..b261a95 --- /dev/null +++ b/src/uni_modules/uv-icon/components/uv-icon/icons.js @@ -0,0 +1,157 @@ +export default { + 'uvicon-level': 'e68e', + 'uvicon-checkbox-mark': 'e659', + 'uvicon-folder': 'e694', + 'uvicon-movie': 'e67c', + 'uvicon-star-fill': 'e61e', + 'uvicon-star': 'e618', + 'uvicon-phone-fill': 'e6ac', + 'uvicon-phone': 'e6ba', + 'uvicon-apple-fill': 'e635', + 'uvicon-backspace': 'e64d', + 'uvicon-attach': 'e640', + 'uvicon-cut': 'e65e', + 'uvicon-empty-address': 'e68a', + 'uvicon-empty-favor': 'e662', + 'uvicon-reload': 'e627', + 'uvicon-order': 'e695', + 'uvicon-server-man': 'e601', + 'uvicon-search': 'e632', + 'uvicon-fingerprint': 'e6aa', + 'uvicon-more-dot-fill': 'e66f', + 'uvicon-scan': 'e631', + 'uvicon-map': 'e61d', + 'uvicon-map-fill': 'e6a8', + 'uvicon-tags': 'e621', + 'uvicon-tags-fill': 'e613', + 'uvicon-eye': 'e664', + 'uvicon-eye-fill': 'e697', + 'uvicon-eye-off': 'e69c', + 'uvicon-eye-off-outline': 'e688', + 'uvicon-mic': 'e66d', + 'uvicon-mic-off': 'e691', + 'uvicon-calendar': 'e65c', + 'uvicon-trash': 'e623', + 'uvicon-trash-fill': 'e6ce', + 'uvicon-play-left': 'e6bf', + 'uvicon-play-right': 'e6b3', + 'uvicon-minus': 'e614', + 'uvicon-plus': 'e625', + 'uvicon-info-circle': 'e69f', + 'uvicon-info-circle-fill': 'e6a7', + 'uvicon-question-circle': 'e622', + 'uvicon-question-circle-fill': 'e6bc', + 'uvicon-close': 'e65a', + 'uvicon-checkmark': 'e64a', + 'uvicon-checkmark-circle': 'e643', + 'uvicon-checkmark-circle-fill': 'e668', + 'uvicon-setting': 'e602', + 'uvicon-setting-fill': 'e6d0', + 'uvicon-heart': 'e6a2', + 'uvicon-heart-fill': 'e68b', + 'uvicon-camera': 'e642', + 'uvicon-camera-fill': 'e650', + 'uvicon-more-circle': 'e69e', + 'uvicon-more-circle-fill': 'e684', + 'uvicon-chat': 'e656', + 'uvicon-chat-fill': 'e63f', + 'uvicon-bag': 'e647', + 'uvicon-error-circle': 'e66e', + 'uvicon-error-circle-fill': 'e655', + 'uvicon-close-circle': 'e64e', + 'uvicon-close-circle-fill': 'e666', + 'uvicon-share': 'e629', + 'uvicon-share-fill': 'e6bb', + 'uvicon-share-square': 'e6c4', + 'uvicon-shopping-cart': 'e6cb', + 'uvicon-shopping-cart-fill': 'e630', + 'uvicon-bell': 'e651', + 'uvicon-bell-fill': 'e604', + 'uvicon-list': 'e690', + 'uvicon-list-dot': 'e6a9', + 'uvicon-zhifubao-circle-fill': 'e617', + 'uvicon-weixin-circle-fill': 'e6cd', + 'uvicon-weixin-fill': 'e620', + 'uvicon-qq-fill': 'e608', + 'uvicon-qq-circle-fill': 'e6b9', + 'uvicon-moments-circel-fill': 'e6c2', + 'uvicon-moments': 'e6a0', + 'uvicon-facebook-circle-fill': 'e661', + 'uvicon-facebook': 'e674', + 'uvicon-car': 'e64f', + 'uvicon-car-fill': 'e648', + 'uvicon-warning-fill': 'e6c7', + 'uvicon-warning': 'e6c1', + 'uvicon-clock-fill': 'e64b', + 'uvicon-clock': 'e66c', + 'uvicon-edit-pen': 'e65d', + 'uvicon-edit-pen-fill': 'e679', + 'uvicon-email': 'e673', + 'uvicon-email-fill': 'e683', + 'uvicon-minus-circle': 'e6a5', + 'uvicon-plus-circle': 'e603', + 'uvicon-plus-circle-fill': 'e611', + 'uvicon-file-text': 'e687', + 'uvicon-file-text-fill': 'e67f', + 'uvicon-pushpin': 'e6d1', + 'uvicon-pushpin-fill': 'e6b6', + 'uvicon-grid': 'e68c', + 'uvicon-grid-fill': 'e698', + 'uvicon-play-circle': 'e6af', + 'uvicon-play-circle-fill': 'e62a', + 'uvicon-pause-circle-fill': 'e60c', + 'uvicon-pause': 'e61c', + 'uvicon-pause-circle': 'e696', + 'uvicon-gift-fill': 'e6b0', + 'uvicon-gift': 'e680', + 'uvicon-kefu-ermai': 'e660', + 'uvicon-server-fill': 'e610', + 'uvicon-coupon-fill': 'e64c', + 'uvicon-coupon': 'e65f', + 'uvicon-integral': 'e693', + 'uvicon-integral-fill': 'e6b1', + 'uvicon-home-fill': 'e68e', + 'uvicon-home': 'e67b', + 'uvicon-account': 'e63a', + 'uvicon-account-fill': 'e653', + 'uvicon-thumb-down-fill': 'e628', + 'uvicon-thumb-down': 'e60a', + 'uvicon-thumb-up': 'e612', + 'uvicon-thumb-up-fill': 'e62c', + 'uvicon-lock-fill': 'e6a6', + 'uvicon-lock-open': 'e68d', + 'uvicon-lock-opened-fill': 'e6a1', + 'uvicon-lock': 'e69d', + 'uvicon-red-packet': 'e6c3', + 'uvicon-photo-fill': 'e6b4', + 'uvicon-photo': 'e60d', + 'uvicon-volume-off-fill': 'e6c8', + 'uvicon-volume-off': 'e6bd', + 'uvicon-volume-fill': 'e624', + 'uvicon-volume': 'e605', + 'uvicon-download': 'e670', + 'uvicon-arrow-up-fill': 'e636', + 'uvicon-arrow-down-fill': 'e638', + 'uvicon-play-left-fill': 'e6ae', + 'uvicon-play-right-fill': 'e6ad', + 'uvicon-arrow-downward': 'e634', + 'uvicon-arrow-leftward': 'e63b', + 'uvicon-arrow-rightward': 'e644', + 'uvicon-arrow-upward': 'e641', + 'uvicon-arrow-down': 'e63e', + 'uvicon-arrow-right': 'e63c', + 'uvicon-arrow-left': 'e646', + 'uvicon-arrow-up': 'e633', + 'uvicon-skip-back-left': 'e6c5', + 'uvicon-skip-forward-right': 'e61f', + 'uvicon-rewind-left': 'e62f', + 'uvicon-arrow-right-double': 'e639', + 'uvicon-arrow-left-double': 'e637', + 'uvicon-empty-data': 'e671', + 'uvicon-man': 'e675', + 'uvicon-woman': 'e626', + 'uvicon-zh': 'e6d3', + 'uvicon-en': 'e6b8', + 'uvicon-twitte': 'e607', + 'uvicon-twitter-circle-fill': 'e6cf' +} \ No newline at end of file diff --git a/src/uni_modules/uv-icon/components/uv-icon/props.js b/src/uni_modules/uv-icon/components/uv-icon/props.js new file mode 100644 index 0000000..71ae061 --- /dev/null +++ b/src/uni_modules/uv-icon/components/uv-icon/props.js @@ -0,0 +1,90 @@ +export default { + props: { + // 图标类名 + name: { + type: String, + default: '' + }, + // 图标颜色,可接受主题色 + color: { + type: String, + default: '#606266' + }, + // 字体大小,单位px + size: { + type: [String, Number], + default: '16px' + }, + // 是否显示粗体 + bold: { + type: Boolean, + default: false + }, + // 点击图标的时候传递事件出去的index(用于区分点击了哪一个) + index: { + type: [String, Number], + default: null + }, + // 触摸图标时的类名 + hoverClass: { + type: String, + default: '' + }, + // 自定义扩展前缀,方便用户扩展自己的图标库 + customPrefix: { + type: String, + default: 'uvicon' + }, + // 图标右边或者下面的文字 + label: { + type: [String, Number], + default: '' + }, + // label的位置,只能右边或者下边 + labelPos: { + type: String, + default: 'right' + }, + // label的大小 + labelSize: { + type: [String, Number], + default: '15px' + }, + // label的颜色 + labelColor: { + type: String, + default: '#606266' + }, + // label与图标的距离 + space: { + type: [String, Number], + default: '3px' + }, + // 图片的mode + imgMode: { + type: String, + default: '' + }, + // 用于显示图片小图标时,图片的宽度 + width: { + type: [String, Number], + default: '' + }, + // 用于显示图片小图标时,图片的高度 + height: { + type: [String, Number], + default: '' + }, + // 用于解决某些情况下,让图标垂直居中的用途 + top: { + type: [String, Number], + default: 0 + }, + // 是否阻止事件传播 + stop: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.icon + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-icon/components/uv-icon/uniicons.css b/src/uni_modules/uv-icon/components/uv-icon/uniicons.css new file mode 100644 index 0000000..2f56eab --- /dev/null +++ b/src/uni_modules/uv-icon/components/uv-icon/uniicons.css @@ -0,0 +1,663 @@ +.uniui-color:before { + content: "\e6cf"; +} + +.uniui-wallet:before { + content: "\e6b1"; +} + +.uniui-settings-filled:before { + content: "\e6ce"; +} + +.uniui-auth-filled:before { + content: "\e6cc"; +} + +.uniui-shop-filled:before { + content: "\e6cd"; +} + +.uniui-staff-filled:before { + content: "\e6cb"; +} + +.uniui-vip-filled:before { + content: "\e6c6"; +} + +.uniui-plus-filled:before { + content: "\e6c7"; +} + +.uniui-folder-add-filled:before { + content: "\e6c8"; +} + +.uniui-color-filled:before { + content: "\e6c9"; +} + +.uniui-tune-filled:before { + content: "\e6ca"; +} + +.uniui-calendar-filled:before { + content: "\e6c0"; +} + +.uniui-notification-filled:before { + content: "\e6c1"; +} + +.uniui-wallet-filled:before { + content: "\e6c2"; +} + +.uniui-medal-filled:before { + content: "\e6c3"; +} + +.uniui-gift-filled:before { + content: "\e6c4"; +} + +.uniui-fire-filled:before { + content: "\e6c5"; +} + +.uniui-refreshempty:before { + content: "\e6bf"; +} + +.uniui-location-filled:before { + content: "\e6af"; +} + +.uniui-person-filled:before { + content: "\e69d"; +} + +.uniui-personadd-filled:before { + content: "\e698"; +} + +.uniui-back:before { + content: "\e6b9"; +} + +.uniui-forward:before { + content: "\e6ba"; +} + +.uniui-arrow-right:before { + content: "\e6bb"; +} + +.uniui-arrowthinright:before { + content: "\e6bb"; +} + +.uniui-arrow-left:before { + content: "\e6bc"; +} + +.uniui-arrowthinleft:before { + content: "\e6bc"; +} + +.uniui-arrow-up:before { + content: "\e6bd"; +} + +.uniui-arrowthinup:before { + content: "\e6bd"; +} + +.uniui-arrow-down:before { + content: "\e6be"; +} + +.uniui-arrowthindown:before { + content: "\e6be"; +} + +.uniui-bottom:before { + content: "\e6b8"; +} + +.uniui-arrowdown:before { + content: "\e6b8"; +} + +.uniui-right:before { + content: "\e6b5"; +} + +.uniui-arrowright:before { + content: "\e6b5"; +} + +.uniui-top:before { + content: "\e6b6"; +} + +.uniui-arrowup:before { + content: "\e6b6"; +} + +.uniui-left:before { + content: "\e6b7"; +} + +.uniui-arrowleft:before { + content: "\e6b7"; +} + +.uniui-eye:before { + content: "\e651"; +} + +.uniui-eye-filled:before { + content: "\e66a"; +} + +.uniui-eye-slash:before { + content: "\e6b3"; +} + +.uniui-eye-slash-filled:before { + content: "\e6b4"; +} + +.uniui-info-filled:before { + content: "\e649"; +} + +.uniui-reload:before { + content: "\e6b2"; +} + +.uniui-micoff-filled:before { + content: "\e6b0"; +} + +.uniui-map-pin-ellipse:before { + content: "\e6ac"; +} + +.uniui-map-pin:before { + content: "\e6ad"; +} + +.uniui-location:before { + content: "\e6ae"; +} + +.uniui-starhalf:before { + content: "\e683"; +} + +.uniui-star:before { + content: "\e688"; +} + +.uniui-star-filled:before { + content: "\e68f"; +} + +.uniui-calendar:before { + content: "\e6a0"; +} + +.uniui-fire:before { + content: "\e6a1"; +} + +.uniui-medal:before { + content: "\e6a2"; +} + +.uniui-font:before { + content: "\e6a3"; +} + +.uniui-gift:before { + content: "\e6a4"; +} + +.uniui-link:before { + content: "\e6a5"; +} + +.uniui-notification:before { + content: "\e6a6"; +} + +.uniui-staff:before { + content: "\e6a7"; +} + +.uniui-vip:before { + content: "\e6a8"; +} + +.uniui-folder-add:before { + content: "\e6a9"; +} + +.uniui-tune:before { + content: "\e6aa"; +} + +.uniui-auth:before { + content: "\e6ab"; +} + +.uniui-person:before { + content: "\e699"; +} + +.uniui-email-filled:before { + content: "\e69a"; +} + +.uniui-phone-filled:before { + content: "\e69b"; +} + +.uniui-phone:before { + content: "\e69c"; +} + +.uniui-email:before { + content: "\e69e"; +} + +.uniui-personadd:before { + content: "\e69f"; +} + +.uniui-chatboxes-filled:before { + content: "\e692"; +} + +.uniui-contact:before { + content: "\e693"; +} + +.uniui-chatbubble-filled:before { + content: "\e694"; +} + +.uniui-contact-filled:before { + content: "\e695"; +} + +.uniui-chatboxes:before { + content: "\e696"; +} + +.uniui-chatbubble:before { + content: "\e697"; +} + +.uniui-upload-filled:before { + content: "\e68e"; +} + +.uniui-upload:before { + content: "\e690"; +} + +.uniui-weixin:before { + content: "\e691"; +} + +.uniui-compose:before { + content: "\e67f"; +} + +.uniui-qq:before { + content: "\e680"; +} + +.uniui-download-filled:before { + content: "\e681"; +} + +.uniui-pyq:before { + content: "\e682"; +} + +.uniui-sound:before { + content: "\e684"; +} + +.uniui-trash-filled:before { + content: "\e685"; +} + +.uniui-sound-filled:before { + content: "\e686"; +} + +.uniui-trash:before { + content: "\e687"; +} + +.uniui-videocam-filled:before { + content: "\e689"; +} + +.uniui-spinner-cycle:before { + content: "\e68a"; +} + +.uniui-weibo:before { + content: "\e68b"; +} + +.uniui-videocam:before { + content: "\e68c"; +} + +.uniui-download:before { + content: "\e68d"; +} + +.uniui-help:before { + content: "\e679"; +} + +.uniui-navigate-filled:before { + content: "\e67a"; +} + +.uniui-plusempty:before { + content: "\e67b"; +} + +.uniui-smallcircle:before { + content: "\e67c"; +} + +.uniui-minus-filled:before { + content: "\e67d"; +} + +.uniui-micoff:before { + content: "\e67e"; +} + +.uniui-closeempty:before { + content: "\e66c"; +} + +.uniui-clear:before { + content: "\e66d"; +} + +.uniui-navigate:before { + content: "\e66e"; +} + +.uniui-minus:before { + content: "\e66f"; +} + +.uniui-image:before { + content: "\e670"; +} + +.uniui-mic:before { + content: "\e671"; +} + +.uniui-paperplane:before { + content: "\e672"; +} + +.uniui-close:before { + content: "\e673"; +} + +.uniui-help-filled:before { + content: "\e674"; +} + +.uniui-paperplane-filled:before { + content: "\e675"; +} + +.uniui-plus:before { + content: "\e676"; +} + +.uniui-mic-filled:before { + content: "\e677"; +} + +.uniui-image-filled:before { + content: "\e678"; +} + +.uniui-locked-filled:before { + content: "\e668"; +} + +.uniui-info:before { + content: "\e669"; +} + +.uniui-locked:before { + content: "\e66b"; +} + +.uniui-camera-filled:before { + content: "\e658"; +} + +.uniui-chat-filled:before { + content: "\e659"; +} + +.uniui-camera:before { + content: "\e65a"; +} + +.uniui-circle:before { + content: "\e65b"; +} + +.uniui-checkmarkempty:before { + content: "\e65c"; +} + +.uniui-chat:before { + content: "\e65d"; +} + +.uniui-circle-filled:before { + content: "\e65e"; +} + +.uniui-flag:before { + content: "\e65f"; +} + +.uniui-flag-filled:before { + content: "\e660"; +} + +.uniui-gear-filled:before { + content: "\e661"; +} + +.uniui-home:before { + content: "\e662"; +} + +.uniui-home-filled:before { + content: "\e663"; +} + +.uniui-gear:before { + content: "\e664"; +} + +.uniui-smallcircle-filled:before { + content: "\e665"; +} + +.uniui-map-filled:before { + content: "\e666"; +} + +.uniui-map:before { + content: "\e667"; +} + +.uniui-refresh-filled:before { + content: "\e656"; +} + +.uniui-refresh:before { + content: "\e657"; +} + +.uniui-cloud-upload:before { + content: "\e645"; +} + +.uniui-cloud-download-filled:before { + content: "\e646"; +} + +.uniui-cloud-download:before { + content: "\e647"; +} + +.uniui-cloud-upload-filled:before { + content: "\e648"; +} + +.uniui-redo:before { + content: "\e64a"; +} + +.uniui-images-filled:before { + content: "\e64b"; +} + +.uniui-undo-filled:before { + content: "\e64c"; +} + +.uniui-more:before { + content: "\e64d"; +} + +.uniui-more-filled:before { + content: "\e64e"; +} + +.uniui-undo:before { + content: "\e64f"; +} + +.uniui-images:before { + content: "\e650"; +} + +.uniui-paperclip:before { + content: "\e652"; +} + +.uniui-settings:before { + content: "\e653"; +} + +.uniui-search:before { + content: "\e654"; +} + +.uniui-redo-filled:before { + content: "\e655"; +} + +.uniui-list:before { + content: "\e644"; +} + +.uniui-mail-open-filled:before { + content: "\e63a"; +} + +.uniui-hand-down-filled:before { + content: "\e63c"; +} + +.uniui-hand-down:before { + content: "\e63d"; +} + +.uniui-hand-up-filled:before { + content: "\e63e"; +} + +.uniui-hand-up:before { + content: "\e63f"; +} + +.uniui-heart-filled:before { + content: "\e641"; +} + +.uniui-mail-open:before { + content: "\e643"; +} + +.uniui-heart:before { + content: "\e639"; +} + +.uniui-loop:before { + content: "\e633"; +} + +.uniui-pulldown:before { + content: "\e632"; +} + +.uniui-scan:before { + content: "\e62a"; +} + +.uniui-bars:before { + content: "\e627"; +} + +.uniui-cart-filled:before { + content: "\e629"; +} + +.uniui-checkbox:before { + content: "\e62b"; +} + +.uniui-checkbox-filled:before { + content: "\e62c"; +} + +.uniui-shop:before { + content: "\e62f"; +} + +.uniui-headphones:before { + content: "\e630"; +} + +.uniui-cart:before { + content: "\e631"; +} diff --git a/src/uni_modules/uv-icon/components/uv-icon/uv-icon.vue b/src/uni_modules/uv-icon/components/uv-icon/uv-icon.vue new file mode 100644 index 0000000..6c1a66a --- /dev/null +++ b/src/uni_modules/uv-icon/components/uv-icon/uv-icon.vue @@ -0,0 +1,220 @@ + + + + + \ No newline at end of file diff --git a/src/uni_modules/uv-icon/components/uv-icon/uvicons.ttf b/src/uni_modules/uv-icon/components/uv-icon/uvicons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3be2cad722b6db621b5246165d86a9c06125d4d1 GIT binary patch literal 39500 zcmeFacbpv6nKoMIRO(9IU7f>p&-C)P~N+Oz|T14v=cUc_g{YUaX|>3k9#9KHl4GRJ;JWQbqbkUPTjO) z%ceKCKPw1VU5NY->^$wGXWTGjUbi4zGgA-(nt-~CyASLZ)=5;TfFrf$(0@02cW`&w z)I?=NXylKA;pctjiO)}^jQ;t+1Ck)l#n*tq8;?^-H?loKllPtO>i83c1KxN4O}a2e z7!~;3`Ad!zf~Rac<5VF-mGJ)2^M_uuQ?{MB3FZ4wGW%7gv!wz$v_xeK+Ulw*F+u^;z>4pC%{hvPg|8fps z%3(f(x(EW+Elof1et%x_yK$FhXgAJSS-3CpPvZLuVJ4mlJF*jSbjNaHPRi+Yx}6bc zt~2f&;jD7jILA82J6oNToR2tXI_Em)JG-3=oliQSc0TXi;@s(c$GO|N*Lld<=RD^8 z$a%{7iSzsctXr%P6(yQZ*hxA~D6!8Ob>=&ZP~vLm7-yZc86}?Ld=w>q%-Q99!nwq` z%(>RN!MV-(hVwm?cppmqf%7;@e8w*kwf%qZA4AKJ7LLW=I$^W0Rk#3uHwbqK-w^J{ z--E(l;Ys0H{JkK&jK5!j#=a`NF8p5D&jKvMnphrx?f9F*`tdh}inRy{At|JUH0V+m zlq@IYg|J`?5g{tXggAPiqwgj3wj!vYL>k7y5KO@mfD=L+Wu9}~_O{z>?_uuIr2>_HnpAzUb2BwQ?9B79P~RJcs|lyJFlg>a>C zm2kE2Y2g~-TH!k3Gs0(u&k3Iwz93vL6ogixD6|PBp)6E{cA-P)6uK~rdW2q~4-|Q- z&@WVlnlK;?3Uy(cFkKiDhJ_Jf259vd=GH7>wlGJSE6fw-3k!sCVWF@{SS&0NmI}*+ zjVcYpAzPu z;HZAWOcWgOGD?_}f`gS$iTJF8H&Vhp6&%Y?n6ZKr_7mo=;Mjh`EEb%IpD>>VC+a86 zY{7~733FUPFIOBc-9TJ>HegZ`j zoW*_uZ4#U%egc&eoTYvOy%L;degfqZoaKH34HKLdegZWU9O`Q%&^5uK{zU?X6CCPO zB+xp+p*}?d)e{`*J0#FQ!J)oG0wok2>MtbFM8To{LIQOZ9O^G5&`H6e{z3x96r7EI z0__wW>MtZvQNf}9LIOP%9O@$^P*%aAK0*SG6&&g#Bv4zyp?*OUcH>NKMgj#E9BMNX zXtCf>n~^}31&7*<1o|vE)Mg}5YQdp4BY|cM4z&{r)LU?0`CzV zDi;Y{NN}iJB=94_p>mPHnFNQ*MFNi!94Z$H+)8k$TqN)*yzUn9NM!~tmPvDY* z^EE$#Ukc8hegfwdoNxFEJXCPL=_hbg!MV#%;H!f3EkA+73eLCv1YRpR-|-W;uHbyn zPvF0TbGM(si3R6gKY=F;&V7CYcNU!Q`w4tnaPIdLIJV$C;3r`w&JX$tTwHJ-@)P*E z;Oz4gIJ@Bdz)#@ug7ZT^f!hntBYpzk7o11^1Oy;BkNF8$KyV)S6HtNR{K!wh2ZHmI zpMVqu=NUf%GYHPJegb+Boag)m93ePA_7f0=;QYi-z!rk@yq^eVc>hiUHQ&#su?P7e zzf8PF;?jlEU9uprmp`w}Rc=*v^(6HU_2Iy5ZKigO_M|?jU#P!g3>i0>x_N=Q-&$s! zXSu-@!D~YQ72X_v)Xvyj?fW81IzGQVu*2!hcYeI{S6zc$ zFLbZ({$cmqJ#9U=_B`1u^q${)XJ2H>=cmS|)~ZKW@2I-9*|l?O4-X^;&KS6L;FZBM z2JanwyFOAsw*KTaW!f3jGt-w%zj{a?x?yj%=!oGb}uXZ&3AT$)Y8dV zXN!MgqlbMJ?XKpDkG6DmweTyNyAHi3>~r8f@rz=ZRv!y8HP4cX!ODPAuJocm&>Qu^ zI<9K_ctWAf@mQid%8-Q}xa&=cf9|}H#E$6|Lv3ou)Y!CGAi41< z)@@p1=Nzf`j9zVKS+dL?cJ#(@gh|@@Ul8Rt#IXFvU6(%BErzrO%6KRq(-Mm_l2S-U zwlA1h>zbjkl44nbR<4Y6*5-|Gi-fzCiAoh)`!IUF zY>atL7~`mLqM4(viuehPVj`}Z<|B_pD-jXH$3kZ4#f^F?8q_wu7)gnYed7x+CYmK> z>sG^T4Zrw>V0*~qEssTlnr1%MA{AmGTBtG|`0M<3pwL!Oy)jzZCG=Ja-BhlW%0U*l zVw$*PqJ zJSB>n^JUlk1|mWitfv{ z#azp_EmsWM)CCG1#LM}kK>p3(SkpmqLHk&L5-SkXDV9j8b##4yy*x0=DtQ)DTFawM zZ7tUZ`x7xm_Onrr!FsYX%1ZPLo`@;cgIE0WpcT7e`&l=M!vjsnr~A^F4*a4i;b^pw zX6d`b>2ymp$`^{4ZrXa0C|6Yd*^PN7t-5od@L3`7J9~+KDh@;efbLhabm+oz>M<&_khkFvuTgHnI=c&qf)GvRRSruVR^ryBL2) z6xpn&CE0zL9YOhLb!`d7@koedkOL2kKM-d@(nx~yj{}XLCEO-}Z&SBp3ZmPC-o?RD zXvLbTlxy`--j7wDOvF?Sq9V3>r%rXo!}C(ZXAs?`C0QRF z=w%>kbhA;FI0&_>gop~^m0vdH&_R@u}dMV%`jy>2OT7*@9CSFgp`weA|i@+c;~n zqE=K3+p@{#vqWn$*_s$TSh>9u(@?F+D$c@-k61-jn_n!VX7_s46?b{{LDdeg<^G38 zPQLP{EB(58)jWAbR8hHk<2U_nJzZ|vwi)lq7y$)@K#f#tbLS4wz2#dt-?EI&D2DVv zKvFeXkDXyBsGgXz9?cR@5e3ZJ3g*KIp&C}iI8=)0^Eh})42%(MCRxA$*;N{VQmtN1 zB;!S!GgVQnLuH;nW}T=oE~vu_`{xTTU++LKeo=B;r`{CFEIHn zEp7BnsrMV{FxM+x<)Y34^+c+W`DFJAjVT#%dyodt6Na|mSnxTZ8RC+@wCQ*ZSl4y zEfdYSPceg~CvLfu%p`;x9>AKP;jMXr6^PbU3q*C8O(Yjw2`f&#e*e>1n~V@+LE|Q7>9QWY$q3_%dxm({vB#Vx zif0{j>{&lr9=v7eX%_}?+_1-3ZW-JN-H3;R#*Ii4uGSoLHs@y_;~fbHfF_^M9g-+K z`k@dG=tUKp2@JLdc`VNfsf>cM5H%x4+)ERJ{!mNr2k~Q_k}kH1bVkus!?@1MDF?yUaW;9#wP*4%}gzgmrm@wCZL_>v`qcy~(iv?b)-8cjwTN&*%`8#Y*x$lXtBM%L7%wkI=fOg>%=>uj|Z!2{<-EcdZs zq~i%qjcb|URc+bXrunXBM1t;h7Il@+!{+hd0=X=MHs(}}D^dPdkl@N7x~2}W3`!3O z4Khvrr6g4#7mRff9Z0`{Un?{L65!mJ5F+{!umu2&D0&&$h?n4(e!|`H*au&|{ugHi z3hBb)LM*%|W{UEja13A4g^(JI&0btc76QTGMW$6)GAkAggj$iaC1hS?8Qw#)V?kB@ zSFI`9T{7&5e|pX+bw_h{*erELbDGGqiD*;ArkmdB(QJ1p5;5&Xy;F33am0*7gWc2W z=|U-LwP(7!ml}a+xsa~cDObQ)+TPLB9rW&G+1)L+k%)pW>G5dJjV26xRxTRXBQ3fS zcVE*ZGjo&o(65B29|oT87G~m09R22fFo2k8=pIZ!Z!mGL65++K@hUozau$1uv|{P_ z%LZ#oyq>k^tsUnEa&}X(*km_pM=dwv&4l!uTf|$=Ip=1vB~Rb-tD8HEP12*+UHhoi zRAm2jM{@_Cal9V3i}fP2LxGWUXY<$aoPN&Dl63PqI-dWU|KQh}+9mV4MbKx%3Vaw zi)ElSB_3iP*UQtI8mvbLCppA0V+Gq2eMq<&W|+My+A1#1ciyy=MMG_I&UY-YOlNFb zJA0wEuJouAFE0qk|rD=mUgV?e`F7tt`@{q8_d! zMnNWmEa8L7eK8h&wgD=$UnCUS*;z4c*@z=GaAYm=Y$Vb^k?sK>H&(eGk5Ddjn@>-F zz;3`i5Dw)chjETcj^Xo&hsB36Zz7~q_Ap$+qYgwIFmn`{*(6bMKAf~|9!jFw1c!%6(?A_FY+C&@=1 z9Ce-C^1fWXUP&83;G9XpP+?)JbxXe$QQSXV_SLV-`mB5I`E<6hVl^9AK@dveXpr%2 zOwFg_1?l1=);A{Wgv?G@^QpqLpr)9~OiW~9Nb-6r7s`WirR?0acy1^+qy)xuL*mA< zTnqZlUpv$X%b{<)QGm`3xC7!K5%CZ%(SA(15GSn!dZ-yU(F>Sl&0HnnArHz;$0YdF z7>68A6u%EQ33E{qcnsr<81N?rm;nzYJBz?NX>7L|r0lqAAAGv7_voSLJdTRhIlJ zhbxQ12df-Q``OSkw8GDpODu`!&afL58k9w`pxPTY*lM$^4|Xh5y&BuYwiF%@2bXmq zgOpe8jT>z>ulO01MYd?KWpg*r>*Hg+;B@-d509cPyF9=qWfp+phGS~S1DLcMB8Gd_J9-xqK1J@0)tj?3WBxJc`#BR7!=R# z>`N83o`J+rVfIm6+H~vmc&WME!siY~sSUX+>W-&@rg$ z%_%8po_x6|UVgF}lv2&Q3Il@A?>2*1XVI&uJ1Z9pSSBL0wqOD=LYZUSlP+qas(95# zjnS{=I_6Hb;OWeOqPm#4AXjnQi-Sr}AeZa9X=${O*Tqx8uwVO#EQgv&X7qS-FOP=U z>X8MZIAih90=_rf+v>j5UT)bu+@sqe<&VUx-R~1~Zi-w0VH3=mm94PHwy~T@o(9(2 z3wlrbl_Df+l080T-5-jUkcY4mVWehHAx5wdxSk!DRCSQT!$(Tq@usi8DoL+?{m$1U z={5H+EYcJ~hvV>DfM4KSaZKJ17U*e7_V51@aMI+nqAb69XXD{lU5Q}QD*#qFOkVlz zzyPd8--ls$p8_4;?8*LzsF5IAFkqL(0;^TQLkOxC2*Z*Nvw-}5H|J|VNy!vOE>eLTmaLHCK{pu zZXxPI$_3T_t1SO@@810~hT$tONYV>mx#a~}eqoQ*6g)K?GbGW7*{7NX{p4`e5=Be1 ztdrNPqNE;I-=K-IL8JE&J^aw#{lnhFDB_l{yuhb~3?np6G@{{82BU_&&Ip>pwUQMH zelip_86S|e6AWqBZbd&KK)M~G@2`kwh~x_cn-d$r^7h0xpk45P8aNM;fe3)*07gP$ zE32M{uMFZvqvr|3gLTYd2qVA|Xf;MS&tVcdlJ)iV%v6pz`v_&Mx37;`mMUYIlBv(U za9x_`;!T=rA1@V88#go2RH~R1dpn1_RVBM;Ej#ln#`x4_k?^AFovRmTIa`@pdCAn? zbkFc`Pr7&N#Vd1GITLGA%q{1fv&9YQU7d>lnZG+;C_7 z_+n~qG8ArVMT331aWVfD=58C&V~vx*>zye#n(owxv_KHL*=f+YhE(@AZ$LZ@y@AEU{=?nHc1t1Y zN>NqCE2Uuf6^UFfab>(e>V7PdU>8UF!z`AM$MZ277gY2_z7O6UP|u6Y}sf7pv-*}rqgv_G~@VQfm<9~<)<ga z84Pv#*$1p9Azg&g>Y!=}U%Eh$2yOQ#qKE!60NjnTAd_OD zi>vrZk6Z7V!PtzR0VFQbpOz6zSXt5rgJ{MoBh6P2pBhMyTM2@8DYN%;+zo<<=ta~HWqY*-5<2=ELQqg zQ4VI^sUF10kOI)h-5=25Hcub_AygRF1)uKHVt|3cC%jnj%7@Zk_w`_d+Oo)N82Kj1 zr5{RfUyEA*Hc4L(UU|ds9Ug@ruK^B6@?4&gas^N@Rx0y~0tq0Qh!8{=l!-kMIbu(R z%9SR=2qs5*xGKN)FVDZO;NNRM`zml&rYv?E@xori4nv8qYsdSHelJ0qytiQPj!<^UO|J}0$ zOz2s0QkU4Et&{KbfD48UzayKsbUoTDV?L{RpV~N=h%p`VUgEk0eIQU#{>le3KB*@> z9R`(m@b|whuYwg+@+46I%x-@ol1fFMh$Iecp0rcQ5KZ>q_x7P*ev6tv*=RsK!;casRGbi( zOxy!>uPyC6vPD!BR_mWWw(Q80w;T~@vfYV7_uxVZlq|2aY8l!<*3FB}vZWZB`wh`h zLuPaSpC47U)A(XY8QQYq@xu}<`O>Pvp+d*Jm4Qg|n`t&)?=J9sG*PZHJ-1AqUSg8W z6n2ypNJm8_{8lFTfnN3

CYEZ%F?JiLsYMft~XdRtL>9y{tqCl58_R%?5$@2z4AP z1rNFq4dL%rv(=dkW>&Ma%l(Y?m)Q&6+1<_NZko&9VQ1T>+fMcr_JV1@6G=tzVLv~y zb*w*==^rhgh)3K%pvq`Bv&#J^_068$ccS|RGO0ol4+;#G>pG(D>&!^R!^96k4>aas zt`=Af;7#T}q`&>2LWbb{xZ(R5>M% z9?ZRWV*ld+P#y-uk(~!TQck6!hn+ByNMG~tL0xAH`AmIiO(!du^a+qpo`C#ZNpc&N z^mUqERi8{@narN&sT!d_~xvD*8gSO_2X;+Ec7jCB+(LrYnMvoV{CTUf2#{aqt- zxKexB2nLOHFqG>=AN;yq&EN5?faD8A@DH^Db5UXdfr9{nysV-#Vd(aRums$KaFyp^ zLCXtAtXo+K+AS;Bt}4u)&8F*VolS2ku$IN{%kIllrX+`FjU-EYI#5at&l>Ja#rW+l zZEY>KO~?87EpUIJag~h~RvowMPwvlIXYG<&GLufVYg#+bQ)bMAa~p6g^hKmA^kv7x zEb_#)Fr4VoUKTA77HC-T4){9seY7<8`Sb0T7iIaypnEfE&e;YWXG!ipf3od!#Sxiw z?Z|;C=We0Nn2pjJMFr;aH{pq0!1^5Y06~WAap@-pTRA$ql5;vBdJKlb*lf=k6~}RW(`h=Qlj>ob_CO{dW_>4-xB{}-}oLVa#4u; zM(U7rOAC9~dk$Uz6TbxmNk=08MJEr`Yt$(56h490R3W(^4TO5FaIf$);cf8y7&(f- zf=e!HSiyM)sRa@)DaP^DlY5J>WcthH(4LL+Y2pJ8Tq~H!Fz&=sgMLp zel3l9Q$ExI)lCxofX0DJ@ZL^Ms0~8k8fR8Wiv(0dRSZK)B+WL>;I^SyL9S~&H@x(s zxpgyX1k5=rzr3NXGbT^Gswp$t8MjTz3Ng(pjH-Gnx+5Ae6*I~()zWd1yjMKLuw z2Tl5*7RhMiuxRX*l4eVL&-`=}ovZigVJ%?DN+qDEsix+h>a1#~X=vt@6n@ZjNey=g zH5D{59S)>pQlNDj8!hG~CjU^Cpq!26i@L3;2E5*;+3-&i15(^%rgegrp5Cv8j3^Iu zR}E8(X6y?jsXG&5vXU~RCD_BmOlm!G*nsn!7_+8rYKdJm_lS%fNF|k)&F!m})PG}X z%J`Kkz!lK5#rxY&n5}BjiQgnN*-q<8T?}X1HC>dG=A!HSjvUl75pDd`?mO7$OhYou zrM8tltwZxevYIkSdRnJ!=z7-B;?Kocxv$5g6m0Z>+XPUPr zeLX{K#h>F0xFaFfSw~AO;`SG#aWl@I%?^bPe%HipEgkSrNhX(;;ucGWL%wd#r<;?y z({A!hCxSG|^$6j36cbA}isk2dQ&RVk`z{oUWqBa^p%Q!hZ!Ig;3>U|AHuzgWbVYLC z{qcv(?Cj1IF#v>Ofb+FiU1Q&=8U}NfqPCqGK$MrsRF9P^prpj^;o!_sb)o zRq9)FSV7z2)A>`Mjaxs&VKo&^ zopDAwl2V7pGcgvlt#bkS&2ue#4-;8HHpN_Q(i(gAbO$7L7u zUjXv}%aSbaH!%h+9mICXX{4!Bi*X{82eozlqi+&6eiPhx|Bxhevlw+Fk)p{JahSAo zb4WWkJEXFoMoAkU9ls(F;H0PHs&+*J`ndC;kGmw&-*~^j4vHR@#=KH(@@j-d-P48A z;;4WMV=yrmFsQ3;zfBGohCMyYo{d}a=u{)%R-wa|L^$NKXCN!FB(0o@+v0XM7-mT; z-nMK^kI3#@poFr-*NOqo-8apKu5uOs3FcFZqC03Nk#^44u-D4+D8ML*ZVldyT46dQ z;$mXr#Y`(>tr=cP7mKdNDnk`~*sE}#a!-dNIvWhcReqGhe^N{zn)lgUr7~QpxYrXw z%~>p=vH(9vrYLj#6Yl^gh4zVv4$BNrK%b1Jk8-=DVnXT}Kb0IE^=g0MQFk z7|;OTbkNH+c+kl;&-+J-R+T-47pex*gf|mBp;s3h6)F>}_ZBm%iIV)wMxBclGH=1p z1aysj4e5_+9|8*S+M$AOkbfNjWo4jThc1hr$C$u$T7i?>VNLUzl&q2)mfy;l8iz^_ zO|PL;vNMCQ&NGW|m{EWpJn;a_uu~~S^m@gM=V^hBj4Pd-?3of&2*U`-g(vX<>T|V z=kp`muejmz9Ybtn`@Heb!(<`_7?`1K8$lUP9ukmK5V${%TR4=ODd)5iAW~B7+;yh0!HZf zhRsDIVz6V-Kw~SeME509CwRuDy%XX`&~cNUxc^b=yhUF=*pG|8eAUh&(e%8CZ@6;% z$k3^uy77vWbNPuEC0P$`iKoMw5zfUInISD2{-$awObvio8$2F~MGZ3)KFtbhmuxWu z&{LV(PRQ4~9niwDR7EvpNz=b&TC%AvO6H>}ge7E?pAa=>+P^oWq6EqP2sIE@6=-OJ zF_6^&v|W~VnubeJIzcyekq7nP14R;Dh92f&$WR8wVjYSDqJS!%KLTNMSTFn&7BU&E z2t;934%F&c6}SMAfHn*(3>SIEg?-dV@E?O+v^S76wSok1(0BBE3{xSyP%s% z6<#eylc_UVK5~5Fk)p(OGiwAzU;1lkp(gH^Y`c_IVn!^J2!|7ym>E^FB|9vtgN1BS zQe$xXRp+l`Z0-Dj#^E|H6|=2_4W8p;K(fwYZDV0Wa|1PrXMBe%ns1i#Dh*-=G6w;M zRCvCb8`OmeOoMizVIE*?nDU51`>-+J*+IDPxamIbllzP7yE3N5JbXAj^XjFl-JA_E z-fhZ?5t?_=(BQgaxev1p-_{4CT!b5`q;{xWZrd^z33aGZeM%qjz-k|M4y_~DS?O-= z0v`#s#g<+@HsZlkD^-lHFILyAS3{D{)V^|Y-Qe(r^VE=H*k)=4NV6pz;ERWoWT-m5?un} z3ou|L+8S<)z<;wfVA@{@+T=;v8d5{iIg1On^@T`CYe}{)hS#X)NxGzvv_AunzSL*z zWMK*A42-u%H9Z>YZtCeeI;g|E+*6;Hf{sA9j_#Y1?y#bz)^vSZcL+L`_!=u%o3bWu zdAShoIH_~+=Woo@rT84n=O2?iz3wSxD+8$Yhr~a4Qmq%R258$@-=L9BBhFwRg&`m^ zAq)rexPr)p9Sb-~%YI}+OE6+Z^`xd4htJ!SY>H7xTofTd=!XpG0aLZx4+|Msj)(yx z5D*Pn);%5Wzl+z38AQzIAbpQhWH_9V2decXnNvN-NzZJ;)My1USMZ)B1w00eSS$Gl zW9;DOR4)_srC1(}@8nIA7%*$$1dQRV?5|#M>0j6g6KA!&c{=&?u!l#)yDHyknJu2I zLmQuFb{KTnPU)Fkaxr{)m{w?OFKJ>prT5i(C)OEU<7qvc5cP>S^{n~y$nRddY5paXB#})WK3L&chETd__glIKdqR;y=Vd^D*;vTt@G4d%Jn z9UjWM{g8&DMfPkY21#g!tV?cxgqY5=QUJ2@&oZH~`<4|iEls*_8IYj(+E{GjHc5rp zoHXNb+hj??k$693CQP=|_|G866%YlC$yY)pfOD7<16?SL@)`wc0IWc{fm#9jlqMC| zbzkc6We{42D5ctkGN04dJP+Pn-L0u<~_*X zPNY%^H<76Jk`=4BI>u}*sj>T4mj4$H}IsjyYwm;O+vB!lLL}v~{ zFSP{w3mktqrB?~iz_$_Ji_obwvpD?H231-tELkq9gKC)^;HyMD$zv402|!q7^00#c z8Xi>OgM}X}iE3S`t3^Bp8WBhIkgqKDjw@SoiL@QKh_Q=8At-D^%a3WfLNn62&_(gn zK5n%D$UYcec8s;ac!$XLs5p-{094lX~oaJhyV7`iBN>aJi$dN8#7=%56LUUE>L ze8D5ZWDLrLOX457j%o6~@QP!tjVQ?0J_%Q-JMhBRaA?Ka!c}--K72{yBfEn|FW>UD z)`o-m=7obR))h*jFkrbq-oyMq;MpKT3O#G6qwOd4+HOb?$(Dm zu6W|rq)WD^(P}0Tn}9OR%UY}-bQU1RXuRPlfSHVM{7rW%`Zfr?Bg;X2=nekmfT6MH zG=u%BkBCVh4DtSjcg$5ul~f<1RXdQU4DYhuqB|8*9W3~)@hG0*|H1lNmjTz*YEWh^ zYwf$Jx3?BRK&^Xj7&-e$xl3h-k*ZjyTD?vs_v5#py1P&uie-B|74R<2G&S#TCs_bWPZ$A7oS=XO%q^4*U;(*6oWn}li9cma z4CfzHOMWcNT$7lun@roU!X&7@2G0iD+6NZ7E8AK@Tn6Nw5~)~{6+f7QhV6qN zqPG8#h`OVF3NXFroyG4)_^A7~0)IK3B@TvRzqO=i#qm$92{AA#^ClNlH4Lm7{@RhmOT@=gu!J~nvbj>!r;L)({E<*6A{#0~! zo`Of+2)pGGE<)?T+Tb_pdL^=n4}9D&;ctVUGe_>|2Gki%?SH?XqoCBO< zknz45M!@f#l%a(}n@GoVz~^-`_HW6-8ZwjO@=Fvk21Zx^NBJ691LhOyaJ+!CB!b3f zw|s*Iry6(uBW#U*qvYPReA3@l?1l&H^=!tFdDK75(D;&W_k32!kQ40F=^V5X4gJIl z_$gVi3@t=2V1ba%lA6(bn|2+J*ZjttT=rKsDIL znqmx25A8YkOROo%;69M;$gwMVLhZ@9U(I!^o!kgarP($$->r0VQ)S1hCQpc#;od>F z+0oI08TlxO`#>hfqq(M-ciGVdm*S6T+P~yWr5xL+Y9Jb=ocm=})75{$+C(sCI0UCF z731v3wUB*;Pz}W?9|bBwL60N}BLJC9(J``x9MnTHP(T%0fQB-X6p`@pm6HIe2XDgT zg&s>{x{{rsamCg`jhG3AuCYR)Y%G@W-7`Ir#C<&;ZC{?~>SN;WO{;g=hOz1t7z~H( z(PAsE_$jNF@8sQUG%Q9ud|Bhn`$Jh26`Jm!*n&gs-4j2R)b@G#Wqqr6aCXcB#!ppP;Ze^1iwI}1UwzXyatx7(%^!?CUGhcR+YqIjt9fD*MbZV&sxSZ z*-X1+rx*`*^_;)@s4Xm)t);Wl%s6J|Olejm7+_OjQWiDNdpvW0LvG}~%_f(QFJ<}_ z&FGVqa6;a*V9qj4E{UQT3)?IeA*r-InJBOrA1k)BGB`2%?b?Sp&Y9TJ={U?%>`KAm zEKkuPAwNb0eI7!L2rv)PDms#bRUgbq07s;|^Wse~R%3`a0UV-0NY7|hjf-CYV8WvD zyzGT>jE730=@ejL9~Dh=1Xxf^2)CyDF(Fb@{0_qIkjN8@eCWlaxCjkj_4ekz&D zulCRN`v^qqYn~2sD*6cH7~;OCCx9dtBH~bi9--Kxc8~GF8l$K$^g=(PYs4=;3Z12| zuSD-%bdMI*WmCHQqF_8?*SO5gCoK0bidAu6Dy>o^@i%w#6f~UXQK+Vy(cFLZc@kR0aY6_0c$-VGIH7}t4R5Bmq4!Y@mIyX$az#x$33VblM> z+F$qRHGUxG?qgoBnARMq2zWaA@}L;@IorAzVd)-h6)!d;>~7YU#W`YLEcsa2oVbmc zGhgdjj?%W||C()cmm-ts177c$6_n%P(XI=!Yh1;=ngY={$i%VBn+x45wtaN4x}qEB=~LHr zTpq|mbY||AoAz*i!NyH{L~+ly%ge`AhfZ42ok*_Ob_UKZEtdzNZBB0Cdp3DFaKz%J ziip?pb!1Z||3egn`1k(01|Rdmn)pfgD!oZ}uf}FASslvTWAtqNRkl;t-D`C_7{e|1 zt9m>`MH8xFR%gAtf;KmC1qke=C+P@cg`ry-5OclvboI=Tj%zr z#kQGj+vfUWm9-(nPvqyGH@?_3gCqGvCVr(G8W^P_|J@yN z0Al82n#P7TgoSDDFIiFJ5%-6%={=_Fhu@taV0jH2E##0R6>$IT{y6}G|93aFBn6xJ z^WhwRAGHY)NANcF^jmN_Ce`ipo*A9#WJfQ>P4`V|6aVMGHJICn_^+*+Y*%y;!%rG? za%a)7Vh0OMvHh--sYBani3 z$lu-sdz-|E8~Mx7&BxKp#Agp(RgJI__^A>11^LLa0yKXr4&c2$V2N{a(FvSwUbOfG z&QDl8b=IuoXK_Aj;+V}ZZ$2i~#J`^`PduE8EnIc)%0;kTGvY&s1@0k5zB__{W=SpI&OW2C~?rEE{M+hkN~xb#y7#5xm@^o-PtI0P~m?JX~I2 z@XAqXm7WLoC9zd{8e{4H`rv9QXgp@Xn)*$NU8-W~0`#D-n zv}WJqFNz5oYpiz~o1%iLM-GL9{cOYEuXE7=J;)k|&;uhAZ`9kPBggq=LA&j#5BrlE z`6tExTROsvC`@NN3@CIV9kHX0IEcsOSnc7jdeU^Crvrg{Fv#PiI`ATlVP+)F81OG* z09D`ETpPr0Km_SwhM!bci{Zgf-FW$q>8#K^kcEAW>meSs*Ug#tl^3O<&p^U1VB3&~ z=p2uq&f@r1i1Ukk`uf(MHD}@Mk*iQEZyJFrfFbc zjWIp&XYndgBbrXG=~T}=wBFFKfjQX>%AE?lT+2Kpn>s&qqQNzCs-B5}P<&3p9KCeP~E!r!t3{b!Zn{M}#XRh&8ek;3N0b5Nt;d@+8# zsy|>~jIZvKi#Kz=dGTV}foO5hFz3U^j*Re)i-W<%c-p<*FNJL__q(&nWs_~iQ^AFc zgD5CW5BiU9cHdwlJqRW~78}xGYIyP;$wA~NOPmY*>hRk7{5=Z!4Z=5+$TS;j5N!CQ z2RX$>-a=t{zTb7h-M`yN$Mnw|;LJ^WBHJ*Sc;S=eIu4iFMs9Y%eSZ&j?J+)&^_Im$ z9+{{0Pqaq$#&@s=O%d(BkR;_S`S&mdgH5#%FX3FB9KpiGx!wp~;{MtvH5fs5mSVz` zz0IRE?lVMb+~%MCIR2A&`?pvSU@(3wQW zU`MlK8g#}pV2B<3ztE!@p#?FXM_`|ZW3b=uiRe?YAVQx^9SPW%jDib8wKEXKtzk5+ zRbh>6$5O8%j`r8Ho6;^R*jCXl9q-OtPl^2ZUIW@ zmXN`jf&Dc?#xZ>983;w+<6_M3a%ZxikF{Xy)E5ri{}%{m4LCq9+1xe|{1PPg&!#02Df#^(o(iNDhBM79CTdr%!(zI;fX zc!&KSg}pFE?HV5LQri09uhzih=VRyk4rp*k5J^QAUeC7z%LtRfTYcpJN%WS^h)JO< zB#59l#2W8LCK61@d?8abJryiO;B)#V zcK?c8$uG>kyK9)W#ghT0+|(A2GNnDoO1Y~N9qxfh(2Bs6pGrqmHe$~Cqa6z3dnC<5 zmKy9<^D)EJ5pUYSKp(@d{osopBtC3OiaV@U(>?LoU~9^H*D6@-UW~l2 zfq@wfT0T;VVi2L7Cv_jjlOiiWxE2GQ(^=S{{lT!Y)%4DZ_qwJ*?M&a{w>qtho%NC# z3YjmF)B3?HzK>1s+J)cS21{XMH=aOF?|Z!s5AW)l&fIImNleU8GJMVC1@)I-{~dfc z`n`pA&c$+tx{GLG73jyK{V|Y!cnYD@l7;@bT1JM(;E^AXBftXgS24dkre}5pH2vqyEL^v?m4=0*k@rR@Rv4`WV zoMpS3O757%9~SXp;1kuzc0C=}w{O?uS!3HaBOBLG-KLAPDEk3fKCpM+f&D*3{;zmX zedQNCt!dl0Yasl{oR0a|`bl_@`WrR_bULkjvcWC}CEY~(g#Z1@$29U6JhbA6uKda& zOFtQ_V>*#u652cRAtjA@JW14G0GeoW1_O!sfF2w|4RRf=paP%<*s*B1JE{*Bb)$*M zLA?lS&>hfnC0NhhsUMJopWSH9?r7=^#1M8AVM`+E;~M0_j)GvM4-yDtp!j#>0b~N; zl!H99c78w|Lhf(v5RnHeQ7u*4RkfT2v|dc#H=1*nyARo6C2%OcD71rG_0-VD){O^H{wa5cD zH+w*4GGv*#U*LWDp z6!&&3p~O04O2Ue_1kTqA?sM8Slb?C?(PwfK5Vq;omAhNIhlaXacCWm3_BPAz9vtkp zt?e9^7>S97HL)xniNuee*`Wo$i)ZlUcY|8TOtiz-%N)u76<7^EK8MonDAkN&#Ms2b zjht^>I8Mj$YaW&+R!a}_pVOU96#27oqk9y-tX{ovqemAWZt#H^tfYt21z%!;lMWfK z$!V7CyoYTT`W899v?kl3q4FZd55svA4aXQ>iIYI397JKHRs0>KJ%_H^D5up5s}NO+YKg`DHy2`X@Uj~&I|brZejuxQ z(p4{KwwjremPWWZR>dHu8A! z_gp$Geio#*jD6mSFAk8(f;O3f<_?=zB1+gh_s4zy4rg2N{DQ~d{cF+O#=o?bFqK8P6x(6M^TD&;GfA+@Knw} zq6{~aEizWjGAGmK{?UB{zBsF{mHS9m>hq7X`%^nm9bD-3B}fu#;ZH$PycCHHMpg0ElZ|m?D(Dc535ii&!FG@&v;$()5K86E{1`4EzGD$2 zt59Z)wI18P6We}AlDfO!{VPRVGkNFKlUj1AzK*qXwbag?DXq}4y@Qnz&@p=;_ z$vD)f!#zmkcaBEwQ}|CNFq5`V17oUQRG`4=*|Ti=A)Y1! zbRDXBDio6uRK&xeo~(_Jgs=g#aSrbY1Ab5A{BS&e=#813WBQ4)OeS`s zKDL@Jz1`>V#k~$~+XaEMwT6v2tzEvb<=q%)^>6ThV)f2lXk&R=2@T%WS!azKC2SGk z-Y+F1#`9t5|3fA zz^H_oB!6%j7uQOUUW*Mzn~I&ytNlGkTg02sIp-F!1#vZ`);E?PrD1PV+Tb)7ICqBy zN6q5IXZ6)OK75&fW{(`)q_n+ha_dq&f9Qs$&7I|uK*&b?RnZRX$Isv$&39xgbHAqR zU(>%w2QUioqyzuSe=2&klF=r7*z-v(+W7M}oUHcqpDgZdx;%RBHRqjo!m9bA_VHrt z+AG}8vh7!%boBAW6+uIGib~@XQ z*U^4b^nVY)p%EdTm4ZT>N!4p)js{MUNn=h%`#9lQSog{4X`n7*nTABdx5SDt0K;U= z=S2kZ`mPpa(@XY~D}e91HdunZkN_1S8E=${#SdP?Mn%wogOy025(H*K9K(o#&hvVK zi1z^041FTr5iNL|O7`(8XgTe18st3m})2 zBxEA0w0hfF!dV_2Q|3={F@rs}S5hw`~?56LQdja zm0Sih3sUdB8K-2?9P@k@HJunweSn_m5_fNba zhivfz6LGfIC2CVzMR%iFm)K@LDxPg>A?Y_v>gez9kk}=Ne8c~@fC@+q&LFaSZqR71 zRGN+8nE^=_iFF#+5Ei<|2re|^fpIMqRmU~1jcYMeUx35JEes|e`4Zb|j*91q(Xb?k zBjWCmp3<#P267l*_RnI-=I5AN&J15HWwHMSQ&MU55=%>J<{m?{WcOnjZ6-;|m;Cp0|AICZi8Uk3@*(yL6JbwPK&aMPHuIfDNfA7scqZ!R; z7D;1kmu$%+AzQL+%LdCbw!lk}R|uFe8a+v4&E{Do+rfYx7MmS68xGi<1d|g?+H;Co zdP=BEOkC2Ol0Z1ksa+@uO>@!^2YM*!qDQ~~zBkfH*$&k*bKiY;U;q0r-!)kep{48F z;($?tUYV;RWf6TO<601}^EmG!$DQ6+5#~56t{%5JzFQHpZFIOp_Cecz%b>~QAnQhp z$G+b&Xb(XrAD>psLA%GY(Ta~ji=lUQUiy1bZHxy6>=A~6f@Pbx7cfvz-IlOV2eGtb zqc7*gFf})x|b{4 z+q=C~j#`AN-0RamfU8>j4_ev#eTU=wz03Kth$ZzFaquhK#hLUR?h05da1B}*S&bL| zQd|QROy3$HT*s?oX|XxzMYYg>KmH@d&u#0o)C!D)$NJxODQE7u{fy#zcdgEM)w#3v zkw||eQZKJn-hBM6BHY1SkH7i9ueW{l#NlUT`I*BfKbHIwgCmdtN_d-=tcyg}Ey04$ z{K6vtXr6?CAeMtEBU7L=s?T7onpv%nb;D;lM%uY@ok3J(-^)B7dpu<@i{`M2roTyZ zxI$njjTsywQ4YRugJl(vLUMZ*8wLDSUcy8%XgLV5Ins&c+ItWVew76ccaY+MF@vr` zrb{HW6WYJpA+11}4uj}L{=5aD&VK`*nJyPuJU2JFq-%VwSfz#5KeGd2LfFDt>nSt9 zP6@P*|55S+A>`ZO2s#v-Q3ehp0Ch^FA{#co!xp(8R@%2ql}?b&dLLYrLvk~8M`4#B zQ0Pz!R=q|WaQC&9}^UyGeFof^OUI!5E0USw51O)qre>P+mdm4rCayhbP!}A z=(+n6`&bQx!mQqqnYdr_NRMgnt=b||%EP0bJ!z_zU$lV&EBP||5$SKo z8Oh0(!O(-onSoD0;7US|d}a^}6M0>*b5%Ti#um1I%jT`JO#r#*wbwq@PrJ z@qicD{1(Z8v)$_W8ze~JB!wjP_3YftaWwY10Qg@8@xCtfSPF61(0 z)Yu84l{*dnhsDFl6srehK?d`tQ{t_tI6tAsB%A*lW~`2VM;mr`C6CMU@nq@|xw=Z0 z@A8D8o1nZbWq0kwg-=<&@aZ*BEQA?+Y+-}^NJ!xkSnFUufMfwASn%+r}ir>|N)_|DVsKPm0PllH?kYkvHzr{BRE zX~aD$6Zk7z5Era|>=8`&@+l1UWbj=u3v`|oyL$Leo?h6QF++>3VZqW8sGepJ&iJd9 zmickL8QNVwYhY5IpXV2>2w5qkbd_cSKmxed>Ar8q3 z;wZ|A{oIP!|BCgK_F=3xpnmn>6=AmGpdjwBGqs?meAeWRDbNdi(iSPIMU^!Q{^*qW zrjXro4C-yi6pI84VkspDuF%eO;RXhO7j0h}XqHVAX7kgsMcNDIGz?I00}7N-qLQz} zR3Y>V+jUe4l(IF@`DgtIe~N1@l?IHEnI#Y^GQ617 zQjff#?WoPA?GG_BQiwjrx3*Yk?qRmlO6?71F;EA8mbfLDPbDh=<){A)-D|B2PCscR z@+(&}U-jj8!$<<3aDPSr`iaweLvk5N9Yde^TIkETAvvjqwdqz^XWq>B*V3HIbgE2uyutt_x19h9b@i@w$meMtd<=0y5 z3!EmoWxGjnO2>X`Hve?fyBzP`0gNG&bAeBGD5mXnTfnVd5~+Kr$sJhtOEZ1^F`0h} z0^Mq^*?gs?+FNtWEj8Y1%axmJ%zjTnl*p6!_!AD8Cz*$8CB?SzJu>xi;(aFiIfPe= zT@Eg=DH4{g;`qEx`Z`7oYw9#Jt<76X&}0GQvXh!yF#`n$O)8^p?WTs%^gUG#$|C7? zmv+kRwn*9&uI8{b#Vh8ax57a&Ng#oH2V+rs$D&Pzo0~BanBFL2BCfh@HTdUqHWbT8K`;ky;4iT{FV>P1|%rp{{l58SI?rcTvf>BGXov8meE1iOh0E2 z`hYOHyTX3-X7GSZIhkQ5_12^=OvQpepj}ALZB!EW&?NPA{8qAI7Ki4uCsN1u6S3_6T zl16XcP!F0%mz&%mx8j610GexrZ=@FX_!tM!yEBkhgyBpjz!g|Qh;NO+A2%Ji&fGpY zaDb;IR&rr$0a$GdPawR6TaoX)9sPS&LdUc zsw3+g`*-fyv977{Mt|?>&ueDDcn9!a(0=u;%o3HQO zKG4{(ZpY_#yzLJJ+IqrkckWyp?)g$pjjPVvg6ycL$y;a8YDFB%wHSS91n|JPEx^S3 zlSq`!t-x?Wcu327Vb>#ndSFWJI}h&KX5no>g&d} zzok8oZEgvH%qatY5q@w7=4;r8J{^`c=r~?tF!#9YnF}Z|q;F|4y8|ISt@NNNq_3vUxm*$I=kEs+sD+rEwF+DDqNN@H% zr`I|^J^JyXE=zmQoqPV7XI>DWQVU-G|Dw{jibdp-E`9zNb04SAgeqnV8p7+jkME0O zA!nF+R?igpg4?hC{13hP1&aMV{_iT5SJb!~V9|)CCxOUDGyLwmVsvBPZ4%hDJpzw| zH4m60Ei}SA(1E`POxXlU94iv=5tH}5xk$gi7I3w#eJ)e5+G%3A+WwvyxY|nsiFSIL zF4;XEyT*74|HVl0P-g$9k z&OIz@+ryj+EE!^+-6eg(x4UD(6$b%wT+_wS4JT|KPwolt0;Rf+v{xWStMQ#iAn)nQ z8VQQ;S2b0$@sVDR+o5L+KtUfYpZt7p1Or#;Y!N<>G=R#)EWw<>$pmkCm2YX4Kz;Uh zFS~~Z6;i^1)|RWWb8YMmFT|-s0VAquX?-NM($nW&xcuB|1%A?BDU}H7tqk9I{TF2U z)WhLmKv619rb-J|j2}I|b_LEXRVuOF^gT90MVo=qaUI z)PE!9-U_vjD)R%S60F)dvS^OTOc6RGk0yP_VE_*+AO`=e-@EZYMj&eI=KD0{^w?} zjM*lObr4Ynj8Q>ifjpRH6@zkU1utgiCCDR|Vlh3y+(MS{1OxPm4i9F)e>3p6u9W=~ z*JsCH?>~FlWV(D-d@i)Oe&Y&P0ZIiJjxN`4Dq#(E6@bNxAY-@=2YTPE&y55~v2?GR zqzEEEcUe&`KX>-Bw!vjNW^tFB%5h6`5O$--TtTQ&=;!(yV1r|0KA3M=1*kq|XYwf< zlMe_Qyn6{dcphS{72Un(Z@yUo6rX*~?f_b--1Hh0I!sZ(t!ih=VR}HXXm>MXw9h3j z=B%{Uls^c)j{&}!6MP|9XD3}kPa9IkxAhr^)`by{;U=-yikXP=SwPk5ZW;cI4L4&| zt}xst@Mks}ZZrJ18E!jJSfYm8f%NakEP_@B@@c`{54xMm7M8tgxFyH{erC93_#*muY>tj2MF~)9%m!sq(r>=waB5=V^HPE<98IP zjUw$dR9EX@O3LYTofG&?!zUx&?S)Sa{vBoGB31@hb9LgkSkq$o4$(eIW8PpS2_6i- z=l?v;;#WZ1@x=!)Jj0~0105FFkXSF=`4(0x=1WuE{PmqNI40TefdL1?iIy$<$Z z4Zx#mBA8r4&1VsglWjPCE};mP%1*k1x@ajZwz{c@mSgE$0crdy?24U z?8j(?R2ro*8mBnzr3p$wyA~TNGzU>CDh1hJdv>RTjBENCgPdMXgWI;&5lH}@v-r|V@i$hkEg_I zB_AEjx%U;+TplyXNWzrQMswqi$#kNS)YDTki9*gal}<)e=B%1XM@QVqGC3R>Nl)ns znR4UNtm??A*-2H;*~4*43uV=#6f!o>RAg^T##4n{<-zgzXkj>-E)8wTsrh_7HRdQu z#x{(psaMb_Tp?r5PsQ_j)v|A&cwwI{SA}Su(lkw(@pL{d9UQkCsU5EBC@ftS9)|*Nu*;Fj$}Hk8u>WlSjG&uC7DjDseI1E zfgOX9UYN^E0s!`D@;zX)TWO@b57r-iRGQ^<{Hj3Fbb zsd6-S$!OzdO{sP<0z~-Ac>_vM+UPR0nr)_F77WW2D&sSnN+hf5eQeL7xiZn%gqnBi zY3KG8Fv!ZqkRHa12-nSNBq1_!&t@W?UAgge1|=Vh#L(hiW8{~V-7dzu2Vrv)S}iq>w4s9XwxnCfcK!j4@YT z#ULVbh5jTuZ6sY7PN?qLm?DH%e-=|2gMousqOn-IkjfjGaAeNJQ4-QVn~E(q9@R&L zIhxN$W8+T!T_MAf%&}+^d!{EguEr*k(d>lL97Zujwt5Xj%{VW4I67uU`-3}WfJ4t)1XFmfJB^A7p9&Q@&gmV6YvK|a4yX4= zxU?pbCQ6e~QzOx=RUL`vBba$|tdKYBrLa$^qlJi?O-AF^Q50i1ot|*0$xQx0WHdUN z&dQkEGUi-GY4Jn}{4;ec9V47&Y(h@PW6shNy2Pr0*(#!1x#xM|wCg#IMDtOTiXtQ` zi)AQH6ZxlH#j@+|F^?)p9hW8p*5s^`sS^%SaY!iIAR>e34n9T~~0xtv`rOL}g+(&=jwuUj_GT)Z$P)JZj=@JeJsjd=~kLO-*vh%m0= KLNA`guK$0As(IT0 literal 0 HcmV?d00001 diff --git a/src/uni_modules/uv-icon/package.json b/src/uni_modules/uv-icon/package.json new file mode 100644 index 0000000..907d179 --- /dev/null +++ b/src/uni_modules/uv-icon/package.json @@ -0,0 +1,83 @@ +{ + "id": "uv-icon", + "displayName": "uv-icon 图标 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.5", + "description": "基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。可自定义颜色、大小。", + "keywords": [ + "uv-ui,uvui,uv-icon,icon,图标,字体图标" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-icon/readme.md b/src/uni_modules/uv-icon/readme.md new file mode 100644 index 0000000..188175d --- /dev/null +++ b/src/uni_modules/uv-icon/readme.md @@ -0,0 +1,11 @@ +## uv-icon 图标库 + +> **组件名:uv-icon** + +基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:549833913 或 官方QQ群 \ No newline at end of file diff --git a/src/uni_modules/uv-loading-icon/changelog.md b/src/uni_modules/uv-loading-icon/changelog.md new file mode 100644 index 0000000..710c0f9 --- /dev/null +++ b/src/uni_modules/uv-loading-icon/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-06-27) +优化 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增uv-loading-icon组件 diff --git a/src/uni_modules/uv-loading-icon/components/uv-loading-icon/props.js b/src/uni_modules/uv-loading-icon/components/uv-loading-icon/props.js new file mode 100644 index 0000000..c0c953a --- /dev/null +++ b/src/uni_modules/uv-loading-icon/components/uv-loading-icon/props.js @@ -0,0 +1,60 @@ +export default { + props: { + // 是否显示组件 + show: { + type: Boolean, + default: true + }, + // 颜色 + color: { + type: String, + default: '#909193' + }, + // 提示文字颜色 + textColor: { + type: String, + default: '#909193' + }, + // 文字和图标是否垂直排列 + vertical: { + type: Boolean, + default: false + }, + // 模式选择,circle-圆形,spinner-花朵形,semicircle-半圆形 + mode: { + type: String, + default: 'spinner' + }, + // 图标大小,单位默认px + size: { + type: [String, Number], + default: 24 + }, + // 文字大小 + textSize: { + type: [String, Number], + default: 15 + }, + // 文字内容 + text: { + type: [String, Number], + default: '' + }, + // 动画模式 https://www.runoob.com/cssref/css3-pr-animation-timing-function.html + timingFunction: { + type: String, + default: 'linear' + }, + // 动画执行周期时间 + duration: { + type: [String, Number], + default: 1200 + }, + // mode=circle时的暗边颜色 + inactiveColor: { + type: String, + default: '' + }, + ...uni.$uv?.props?.loadingIcon + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue b/src/uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue new file mode 100644 index 0000000..054e6d4 --- /dev/null +++ b/src/uni_modules/uv-loading-icon/components/uv-loading-icon/uv-loading-icon.vue @@ -0,0 +1,346 @@ + + + + + diff --git a/src/uni_modules/uv-loading-icon/package.json b/src/uni_modules/uv-loading-icon/package.json new file mode 100644 index 0000000..e245405 --- /dev/null +++ b/src/uni_modules/uv-loading-icon/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-loading-icon", + "displayName": "uv-loading-icon 加载动画 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "uv-loading-icon 此组件为一个小动画,目前用在uv-ui的loadMore加载更多等组件的正在加载状态场景。", + "keywords": [ + "uv-loading-icon", + "uvui", + "uv-ui", + "loading", + "加载动画" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-loading-icon/readme.md b/src/uni_modules/uv-loading-icon/readme.md new file mode 100644 index 0000000..63de21a --- /dev/null +++ b/src/uni_modules/uv-loading-icon/readme.md @@ -0,0 +1,11 @@ +## LoadingIcon 加载动画 + +> **组件名:uv-loading-icon** + +此组件为一个小动画,目前用在uv-ui的loadMore加载更多等组件的正在加载状态场景。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-overlay/changelog.md b/src/uni_modules/uv-overlay/changelog.md new file mode 100644 index 0000000..ff14713 --- /dev/null +++ b/src/uni_modules/uv-overlay/changelog.md @@ -0,0 +1,9 @@ +## 1.0.3(2023-07-02) +uv-overlay 由于弹出层uv-transition的修改,组件内部做了相应的修改,参数不变。 +## 1.0.2(2023-06-29) +1. 优化,H5端禁止穿透滚动 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增uv-overlay组件 diff --git a/src/uni_modules/uv-overlay/components/uv-overlay/props.js b/src/uni_modules/uv-overlay/components/uv-overlay/props.js new file mode 100644 index 0000000..267c613 --- /dev/null +++ b/src/uni_modules/uv-overlay/components/uv-overlay/props.js @@ -0,0 +1,25 @@ +export default { + props: { + // 是否显示遮罩 + show: { + type: Boolean, + default: false + }, + // 层级z-index + zIndex: { + type: [String, Number], + default: 10070 + }, + // 遮罩的过渡时间,单位为ms + duration: { + type: [String, Number], + default: 300 + }, + // 不透明度值,当做rgba的第四个参数 + opacity: { + type: [String, Number], + default: 0.5 + }, + ...uni.$uv?.props?.overlay + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue b/src/uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue new file mode 100644 index 0000000..53568c0 --- /dev/null +++ b/src/uni_modules/uv-overlay/components/uv-overlay/uv-overlay.vue @@ -0,0 +1,85 @@ + + + + diff --git a/src/uni_modules/uv-overlay/package.json b/src/uni_modules/uv-overlay/package.json new file mode 100644 index 0000000..a664f3a --- /dev/null +++ b/src/uni_modules/uv-overlay/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-overlay", + "displayName": "uv-overlay 遮罩层 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.3", + "description": "uv-overlay 创建一个遮罩层,用于强调特定的页面元素,并阻止用户对遮罩下层的内容进行操作,一般用于弹窗场景,uv-popup、uv-toast、uv-tooltip等组件就是用了该组件。", + "keywords": [ + "uv-overlay", + "uvui", + "uv-ui", + "overlay", + "遮罩层" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-transition" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-overlay/readme.md b/src/uni_modules/uv-overlay/readme.md new file mode 100644 index 0000000..4e8af4b --- /dev/null +++ b/src/uni_modules/uv-overlay/readme.md @@ -0,0 +1,11 @@ +## Overlay 遮罩层 + +> **组件名:uv-overlay** + +创建一个遮罩层,用于强调特定的页面元素,并阻止用户对遮罩下层的内容进行操作,一般用于弹窗场景,uv-popup、uv-toast、uv-tooltip等组件就是用了该组件。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-picker/changelog.md b/src/uni_modules/uv-picker/changelog.md new file mode 100644 index 0000000..c58742b --- /dev/null +++ b/src/uni_modules/uv-picker/changelog.md @@ -0,0 +1,17 @@ +## 1.0.6(2023-07-02) +uv-picker 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/picker.html +## 1.0.5(2023-06-26) +1. 增加color参数 +2. 增加activeColor参数 +## 1.0.4(2023-06-15) +1. 修改支付宝报错的BUG +## 1.0.3(2023-06-12) +1. setColumnValues的使用统一化,避免某些平台报错 +2. 取消change回调回传的组件实例,直接统一通过ref的方式调取setColumnValues方法 +## 1.0.2(2023-05-23) +1. uv-toolbar组件新增下边框属性 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-picker 选择器 diff --git a/src/uni_modules/uv-picker/components/uv-picker/props.js b/src/uni_modules/uv-picker/components/uv-picker/props.js new file mode 100644 index 0000000..8bcb18f --- /dev/null +++ b/src/uni_modules/uv-picker/components/uv-picker/props.js @@ -0,0 +1,90 @@ +export default { + props: { + // 是否展示顶部的操作栏 + showToolbar: { + type: Boolean, + default: true + }, + // 顶部标题 + title: { + type: String, + default: '' + }, + // 对象数组,设置每一列的数据 + columns: { + type: Array, + default: () => [] + }, + // 是否显示加载中状态 + loading: { + type: Boolean, + default: false + }, + // 各列中,单个选项的高度 + itemHeight: { + type: [String, Number], + default: 44 + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: '取消' + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: '确定' + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: '#909193' + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: '#3c9cff' + }, + // 文字颜色 + color: { + type: String, + default: '' + }, + // 选中文字的颜色 + activeColor: { + type: String, + default: '' + }, + // 每列中可见选项的数量 + visibleItemCount: { + type: [String, Number], + default: 5 + }, + // 选项对象中,需要展示的属性键名 + keyName: { + type: String, + default: 'text' + }, + // 是否允许点击遮罩关闭选择器 + closeOnClickOverlay: { + type: Boolean, + default: true + }, + // 是否允许点击确认关闭选择器 + closeOnClickConfirm: { + type: Boolean, + default: true + }, + // 各列的默认索引 + defaultIndex: { + type: Array, + default: () => [], + }, + // 是否在手指松开时立即触发 change 事件。若不开启则会在滚动动画结束后触发 change 事件,只在微信2.21.1及以上有效 + immediateChange: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.picker + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-picker/components/uv-picker/uv-picker.vue b/src/uni_modules/uv-picker/components/uv-picker/uv-picker.vue new file mode 100644 index 0000000..c047834 --- /dev/null +++ b/src/uni_modules/uv-picker/components/uv-picker/uv-picker.vue @@ -0,0 +1,312 @@ + + + + + diff --git a/src/uni_modules/uv-picker/components/uv-toolbar/props.js b/src/uni_modules/uv-picker/components/uv-toolbar/props.js new file mode 100644 index 0000000..ac162da --- /dev/null +++ b/src/uni_modules/uv-picker/components/uv-toolbar/props.js @@ -0,0 +1,39 @@ +export default { + props: { + // 是否展示工具条 + show: { + type: Boolean, + default: true + }, + // 是否显示下边框 + showBorder: { + type: Boolean, + default: false + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: '取消' + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: '确认' + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: '#909193' + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: '#3c9cff' + }, + // 标题文字 + title: { + type: String, + default: '' + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-picker/components/uv-toolbar/uv-toolbar.vue b/src/uni_modules/uv-picker/components/uv-toolbar/uv-toolbar.vue new file mode 100644 index 0000000..40a4b4a --- /dev/null +++ b/src/uni_modules/uv-picker/components/uv-toolbar/uv-toolbar.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/src/uni_modules/uv-picker/package.json b/src/uni_modules/uv-picker/package.json new file mode 100644 index 0000000..20909cc --- /dev/null +++ b/src/uni_modules/uv-picker/package.json @@ -0,0 +1,89 @@ +{ + "id": "uv-picker", + "displayName": "uv-picker 选择器 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.6", + "description": "uv-picker 此选择器用于单列,多列,多列联动的选择场景。", + "keywords": [ + "uv-picker", + "uvui", + "uv-ui", + "picker", + "联动选择" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-popup", + "uv-loading-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-picker/readme.md b/src/uni_modules/uv-picker/readme.md new file mode 100644 index 0000000..9926939 --- /dev/null +++ b/src/uni_modules/uv-picker/readme.md @@ -0,0 +1,11 @@ +## Picker 选择器 + +> **组件名:uv-picker** + +此选择器用于单列,多列,多列联动的选择场景。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-popup/changelog.md b/src/uni_modules/uv-popup/changelog.md new file mode 100644 index 0000000..44bc961 --- /dev/null +++ b/src/uni_modules/uv-popup/changelog.md @@ -0,0 +1,9 @@ +## 1.0.3(2023-07-02) +uv-popup 弹出层,代码重构优化,性能翻倍,小程序体验性能更加,避免卡顿。打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/popup.html +## 1.0.2(2023-06-11) +1. 修复zIndex层级问题 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增uv-popup组件 diff --git a/src/uni_modules/uv-popup/components/uv-popup/keypress.js b/src/uni_modules/uv-popup/components/uv-popup/keypress.js new file mode 100644 index 0000000..62dda46 --- /dev/null +++ b/src/uni_modules/uv-popup/components/uv-popup/keypress.js @@ -0,0 +1,45 @@ +// #ifdef H5 +export default { + name: 'Keypress', + props: { + disable: { + type: Boolean, + default: false + } + }, + mounted () { + const keyNames = { + esc: ['Esc', 'Escape'], + tab: 'Tab', + enter: 'Enter', + space: [' ', 'Spacebar'], + up: ['Up', 'ArrowUp'], + left: ['Left', 'ArrowLeft'], + right: ['Right', 'ArrowRight'], + down: ['Down', 'ArrowDown'], + delete: ['Backspace', 'Delete', 'Del'] + } + const listener = ($event) => { + if (this.disable) { + return + } + const keyName = Object.keys(keyNames).find(key => { + const keyName = $event.key + const value = keyNames[key] + return value === keyName || (Array.isArray(value) && value.includes(keyName)) + }) + if (keyName) { + // 避免和其他按键事件冲突 + setTimeout(() => { + this.$emit(keyName, {}) + }, 0) + } + } + document.addEventListener('keyup', listener) + // this.$once('hook:beforeDestroy', () => { + // document.removeEventListener('keyup', listener) + // }) + }, + render: () => {} +} +// #endif diff --git a/src/uni_modules/uv-popup/components/uv-popup/props.js b/src/uni_modules/uv-popup/components/uv-popup/props.js new file mode 100644 index 0000000..02a88bd --- /dev/null +++ b/src/uni_modules/uv-popup/components/uv-popup/props.js @@ -0,0 +1,80 @@ +export default { + props: { + // 是否展示弹窗 + show: { + type: Boolean, + default: false + }, + // 是否显示遮罩 + overlay: { + type: Boolean, + default: true + }, + // 弹出的方向,可选值为 top bottom right left center + mode: { + type: String, + default: 'bottom' + }, + // 动画时长,单位ms + duration: { + type: [String, Number], + default: 300 + }, + // 是否显示关闭图标 + closeable: { + type: Boolean, + default: false + }, + // 自定义遮罩的样式 + overlayStyle: { + type: [Object, String], + default: '' + }, + // 点击遮罩是否关闭弹窗 + closeOnClickOverlay: { + type: Boolean, + default: true + }, + // 层级 + zIndex: { + type: [String, Number], + default: 10075 + }, + // 是否为iPhoneX留出底部安全距离 + safeAreaInsetBottom: { + type: Boolean, + default: true + }, + // 是否留出顶部安全距离(状态栏高度) + safeAreaInsetTop: { + type: Boolean, + default: false + }, + // 自定义关闭图标位置,top-left为左上角,top-right为右上角,bottom-left为左下角,bottom-right为右下角 + closeIconPos: { + type: String, + default: 'top-right' + }, + // 圆角值 + round: { + type: [Boolean, String, Number], + default: 0 + }, + // mode=center,也即中部弹出时,是否使用缩放模式 + zoom: { + type: Boolean, + default: true + }, + // 弹窗背景色,设置为transparent可去除白色背景 + bgColor: { + type: String, + default: '' + }, + // 遮罩的透明度,0-1之间 + overlayOpacity: { + type: [Number, String], + default: 0.5 + }, + ...uni.$uv?.props?.popup + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-popup/components/uv-popup/uv-popup.vue b/src/uni_modules/uv-popup/components/uv-popup/uv-popup.vue new file mode 100644 index 0000000..c9d06ea --- /dev/null +++ b/src/uni_modules/uv-popup/components/uv-popup/uv-popup.vue @@ -0,0 +1,527 @@ + + + + diff --git a/src/uni_modules/uv-popup/package.json b/src/uni_modules/uv-popup/package.json new file mode 100644 index 0000000..c46619d --- /dev/null +++ b/src/uni_modules/uv-popup/package.json @@ -0,0 +1,92 @@ +{ + "id": "uv-popup", + "displayName": "uv-popup 弹出层 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.3", + "description": "uv-popup 弹出层容器,用于展示弹窗、信息提示等内容,支持上、下、左、右和中部弹出。组件只提供容器,内部内容由用户自定义。", + "keywords": [ + "uv-popup", + "uvui", + "uv-ui", + "popup", + "弹出层" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-overlay", + "uv-transition", + "uv-icon", + "uv-status-bar", + "uv-safe-bottom" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-popup/readme.md b/src/uni_modules/uv-popup/readme.md new file mode 100644 index 0000000..2d7f96f --- /dev/null +++ b/src/uni_modules/uv-popup/readme.md @@ -0,0 +1,11 @@ +## Popup 弹出层 + +> **组件名:uv-popup** + +弹出层容器,用于展示弹窗、信息提示等内容,支持上、下、左、右和中部弹出。组件只提供容器,内部内容由用户自定义。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-safe-bottom/changelog.md b/src/uni_modules/uv-safe-bottom/changelog.md new file mode 100644 index 0000000..f0e1a92 --- /dev/null +++ b/src/uni_modules/uv-safe-bottom/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-07-02) +uv-safe-bottom 修复,在百度程序,抖音小程序不生效的BUG +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-safe-bottom 底部安全区组件 diff --git a/src/uni_modules/uv-safe-bottom/components/uv-safe-bottom/uv-safe-bottom.vue b/src/uni_modules/uv-safe-bottom/components/uv-safe-bottom/uv-safe-bottom.vue new file mode 100644 index 0000000..9f796bd --- /dev/null +++ b/src/uni_modules/uv-safe-bottom/components/uv-safe-bottom/uv-safe-bottom.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/src/uni_modules/uv-safe-bottom/package.json b/src/uni_modules/uv-safe-bottom/package.json new file mode 100644 index 0000000..9ebb43b --- /dev/null +++ b/src/uni_modules/uv-safe-bottom/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-safe-bottom", + "displayName": "uv-safe-bottom 底部安全区 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.2", + "description": "这个适配,主要是针对IPhone X等一些底部带指示条的机型,指示条的操作区域与页面底部存在重合,容易导致用户误操作,因此我们需要针对这些机型进行底部安全区适配。", + "keywords": [ + "uv-safe-bottom", + "uvui", + "uv-ui", + "bottom", + "底部安全区" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-safe-bottom/readme.md b/src/uni_modules/uv-safe-bottom/readme.md new file mode 100644 index 0000000..8c78882 --- /dev/null +++ b/src/uni_modules/uv-safe-bottom/readme.md @@ -0,0 +1,11 @@ +## SafeBottom 底部安全区 + +> **组件名:uv-safe-bottom** + +这个适配,主要是针对IPhone X等一些底部带指示条的机型,指示条的操作区域与页面底部存在重合,容易导致用户误操作,因此我们需要针对这些机型进行底部安全区适配。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-status-bar/changelog.md b/src/uni_modules/uv-status-bar/changelog.md new file mode 100644 index 0000000..fc04088 --- /dev/null +++ b/src/uni_modules/uv-status-bar/changelog.md @@ -0,0 +1,7 @@ +## 1.0.2(2023-06-05) +1. 兼容渐变背景色 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增uv-status-bar组件 diff --git a/src/uni_modules/uv-status-bar/components/uv-status-bar/props.js b/src/uni_modules/uv-status-bar/components/uv-status-bar/props.js new file mode 100644 index 0000000..f42e525 --- /dev/null +++ b/src/uni_modules/uv-status-bar/components/uv-status-bar/props.js @@ -0,0 +1,8 @@ +export default { + props: { + bgColor: { + type: String, + default: 'transparent' + } + } +} diff --git a/src/uni_modules/uv-status-bar/components/uv-status-bar/uv-status-bar.vue b/src/uni_modules/uv-status-bar/components/uv-status-bar/uv-status-bar.vue new file mode 100644 index 0000000..ee887c7 --- /dev/null +++ b/src/uni_modules/uv-status-bar/components/uv-status-bar/uv-status-bar.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/uni_modules/uv-status-bar/package.json b/src/uni_modules/uv-status-bar/package.json new file mode 100644 index 0000000..dd4311e --- /dev/null +++ b/src/uni_modules/uv-status-bar/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-status-bar", + "displayName": "uv-status-bar 状态栏占位", + "version": "1.0.2", + "description": "状态栏占位组件主要用于状态填充,比如在自定导航栏的时候,它会自动适配一个恰当的状态栏高度。", + "keywords": [ + "uv-status-bar", + "uvui", + "uv-ui", + "status-bar", + "状态栏" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-status-bar/readme.md b/src/uni_modules/uv-status-bar/readme.md new file mode 100644 index 0000000..fc61e0b --- /dev/null +++ b/src/uni_modules/uv-status-bar/readme.md @@ -0,0 +1,10 @@ +## StatbusBar 状态栏占位 + +> **组件名:uv-status-bar** + +本组件主要用于状态填充,比如在自定导航栏的时候,它会自动适配一个恰当的状态栏高度。 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 + diff --git a/src/uni_modules/uv-transition/changelog.md b/src/uni_modules/uv-transition/changelog.md new file mode 100644 index 0000000..f143e9c --- /dev/null +++ b/src/uni_modules/uv-transition/changelog.md @@ -0,0 +1,13 @@ +## 1.0.5(2023-07-02) +修改VUE3模式下可能存在的BUG +## 1.0.4(2023-07-02) +uv-transition 动画组件,代码重构优化,性能更加友好,增加自定义动画功能。详情参考文档:https://www.uvui.cn/components/transition.html +## 1.0.3(2023-06-12) +1. 恢复this.$nextTick的使用,经过测试百度等平台无问题 +## 1.0.2(2023-05-23) +1. 百度小程序等平台不支持this.$nextick,修改成延时 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +1. 新增动画组件 diff --git a/src/uni_modules/uv-transition/components/uv-transition/createAnimation.js b/src/uni_modules/uv-transition/components/uv-transition/createAnimation.js new file mode 100644 index 0000000..8f89b18 --- /dev/null +++ b/src/uni_modules/uv-transition/components/uv-transition/createAnimation.js @@ -0,0 +1,131 @@ +// const defaultOption = { +// duration: 300, +// timingFunction: 'linear', +// delay: 0, +// transformOrigin: '50% 50% 0' +// } +// #ifdef APP-NVUE +const nvueAnimation = uni.requireNativePlugin('animation') +// #endif +class MPAnimation { + constructor(options, _this) { + this.options = options + // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误 + this.animation = uni.createAnimation({ + ...options + }) + this.currentStepAnimates = {} + this.next = 0 + this.$ = _this + + } + + _nvuePushAnimates(type, args) { + let aniObj = this.currentStepAnimates[this.next] + let styles = {} + if (!aniObj) { + styles = { + styles: {}, + config: {} + } + } else { + styles = aniObj + } + if (animateTypes1.includes(type)) { + if (!styles.styles.transform) { + styles.styles.transform = '' + } + let unit = '' + if(type === 'rotate'){ + unit = 'deg' + } + styles.styles.transform += `${type}(${args+unit}) ` + } else { + styles.styles[type] = `${args}` + } + this.currentStepAnimates[this.next] = styles + } + _animateRun(styles = {}, config = {}) { + let ref = this.$.$refs['ani'].ref + if (!ref) return + return new Promise((resolve, reject) => { + nvueAnimation.transition(ref, { + styles, + ...config + }, res => { + resolve() + }) + }) + } + + _nvueNextAnimate(animates, step = 0, fn) { + let obj = animates[step] + if (obj) { + let { + styles, + config + } = obj + this._animateRun(styles, config).then(() => { + step += 1 + this._nvueNextAnimate(animates, step, fn) + }) + } else { + this.currentStepAnimates = {} + typeof fn === 'function' && fn() + this.isEnd = true + } + } + + step(config = {}) { + // #ifndef APP-NVUE + this.animation.step(config) + // #endif + // #ifdef APP-NVUE + this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config) + this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin + this.next++ + // #endif + return this + } + + run(fn) { + // #ifndef APP-NVUE + this.$.animationData = this.animation.export() + this.$.timer = setTimeout(() => { + typeof fn === 'function' && fn() + }, this.$.durationTime) + // #endif + // #ifdef APP-NVUE + this.isEnd = false + let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref + if(!ref) return + this._nvueNextAnimate(this.currentStepAnimates, 0, fn) + this.next = 0 + // #endif + } +} + + +const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d', + 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY', + 'translateZ' +] +const animateTypes2 = ['opacity', 'backgroundColor'] +const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom'] +animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => { + MPAnimation.prototype[type] = function(...args) { + // #ifndef APP-NVUE + this.animation[type](...args) + // #endif + // #ifdef APP-NVUE + this._nvuePushAnimates(type, args) + // #endif + return this + } +}) + +export function createAnimation(option, _this) { + if(!_this) return + clearTimeout(_this.timer) + return new MPAnimation(option, _this) +} diff --git a/src/uni_modules/uv-transition/components/uv-transition/uv-transition.vue b/src/uni_modules/uv-transition/components/uv-transition/uv-transition.vue new file mode 100644 index 0000000..95e499f --- /dev/null +++ b/src/uni_modules/uv-transition/components/uv-transition/uv-transition.vue @@ -0,0 +1,301 @@ + + diff --git a/src/uni_modules/uv-transition/package.json b/src/uni_modules/uv-transition/package.json new file mode 100644 index 0000000..9164f57 --- /dev/null +++ b/src/uni_modules/uv-transition/package.json @@ -0,0 +1,87 @@ +{ + "id": "uv-transition", + "displayName": "uv-transition 动画 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.5", + "description": "transition 该组件用于组件的动画过渡效果。", + "keywords": [ + "uv-transition", + "uvui", + "uv-ui", + "transition", + "动画" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-transition/readme.md b/src/uni_modules/uv-transition/readme.md new file mode 100644 index 0000000..b3e79f6 --- /dev/null +++ b/src/uni_modules/uv-transition/readme.md @@ -0,0 +1,11 @@ +## Transition 动画 + +> **组件名:uv-transition** + +该组件用于组件的动画过渡效果。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-ui-tools/changelog.md b/src/uni_modules/uv-ui-tools/changelog.md new file mode 100644 index 0000000..4c986e1 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/changelog.md @@ -0,0 +1,24 @@ +## 1.0.9(2023-06-28) +优化openType.js +## 1.0.8(2023-06-15) +1. 修改支付宝报错的BUG +## 1.0.7(2023-06-07) +1. 解决微信小程序使用uvui提示 Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors +2. 解决上述提示,需要在uni.scss配置$uvui-nvue-style: false; 然后在APP.vue下面引入uvui内置的基础样式:@import '@/uni_modules/uv-ui-tools/index.scss'; +## 1.0.6(2023-06-04) +1. uv-ui-tools 优化工具组件,兼容更多功能 +2. 小程序分享功能优化等 +## 1.0.5(2023-06-02) +1. 修改扩展使用mixin中方法的问题 +## 1.0.4(2023-05-23) +1. 兼容百度小程序修改bem函数 +## 1.0.3(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.2(2023-05-10) +1. 增加Http请求封装 +2. 优化 +## 1.0.1(2023-05-04) +1. 修改名称及备注 +## 1.0.0(2023-05-04) +1. uv-ui工具集首次发布 diff --git a/src/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue b/src/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue new file mode 100644 index 0000000..baf45e9 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue @@ -0,0 +1,6 @@ + + + diff --git a/src/uni_modules/uv-ui-tools/index.js b/src/uni_modules/uv-ui-tools/index.js new file mode 100644 index 0000000..b3a24cd --- /dev/null +++ b/src/uni_modules/uv-ui-tools/index.js @@ -0,0 +1,77 @@ +// 全局挂载引入http相关请求拦截插件 +import Request from './libs/luch-request' + +// 引入全局mixin +import mixin from './libs/mixin/mixin.js' +// 小程序特有的mixin +import mpMixin from './libs/mixin/mpMixin.js' +// #ifdef MP +import mpShare from '@/uni_modules/uv-ui-tools/libs/mixin/mpShare.js' +// #endif + +// 路由封装 +import route from './libs/util/route.js' +// 公共工具函数 +import * as index from './libs/function/index.js' +// 防抖方法 +import debounce from './libs/function/debounce.js' +// 节流方法 +import throttle from './libs/function/throttle.js' +// 规则检验 +import * as test from './libs/function/test.js' + +// 颜色渐变相关,colorGradient-颜色渐变,hexToRgb-十六进制颜色转rgb颜色,rgbToHex-rgb转十六进制 +import * as colorGradient from './libs/function/colorGradient.js' + +// 配置信息 +import config from './libs/config/config.js' +// 平台 +import platform from './libs/function/platform' + +const $uv = { + route, + config, + test, + throttle, + date: index.timeFormat, // 另名date + ...index, + colorGradient: colorGradient.colorGradient, + hexToRgb: colorGradient.hexToRgb, + rgbToHex: colorGradient.rgbToHex, + colorToRgba: colorGradient.colorToRgba, + http: new Request(), + debounce, + throttle, + platform, + mixin, + mpMixin +} +uni.$uv = $uv; +const install = (Vue,options={}) => { + // #ifndef APP-NVUE + Vue.mixin(mixin); + // #ifdef MP + if(options.mpShare){ + Vue.mixin(mpShare); + } + // #endif + // #endif + // #ifdef VUE2 + // 时间格式化,同时两个名称,date和timeFormat + Vue.filter('timeFormat', (timestamp, format) => uni.$uv.timeFormat(timestamp, format)); + Vue.filter('date', (timestamp, format) => uni.$uv.timeFormat(timestamp, format)); + // 将多久以前的方法,注入到全局过滤器 + Vue.filter('timeFrom', (timestamp, format) => uni.$uv.timeFrom(timestamp, format)); + // 同时挂载到uni和Vue.prototype中 + // #ifndef APP-NVUE + // 只有vue,挂载到Vue.prototype才有意义,因为nvue中全局Vue.prototype和Vue.mixin是无效的 + Vue.prototype.$uv = $uv; + // #endif + // #endif + // #ifdef VUE3 + Vue.config.globalProperties.$uv = $uv; + // #endif +} +export default { + install +} \ No newline at end of file diff --git a/src/uni_modules/uv-ui-tools/index.scss b/src/uni_modules/uv-ui-tools/index.scss new file mode 100644 index 0000000..8d05b8d --- /dev/null +++ b/src/uni_modules/uv-ui-tools/index.scss @@ -0,0 +1,7 @@ +// 引入公共基础类 +@import "./libs/css/common.scss"; + +// 非nvue的样式 +/* #ifndef APP-NVUE */ +@import "./libs/css/vue.scss"; +/* #endif */ \ No newline at end of file diff --git a/src/uni_modules/uv-ui-tools/libs/config/config.js b/src/uni_modules/uv-ui-tools/libs/config/config.js new file mode 100644 index 0000000..cca97eb --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/config/config.js @@ -0,0 +1,34 @@ +// 此版本发布于2023-05-23 +const version = '1.0.2' + +// 开发环境才提示,生产环境不会提示 +if (process.env.NODE_ENV === 'development') { + console.log(`\n %c uvui V${version} https://www.uvui.cn/ \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0; border-radius: 5px;'); +} + +export default { + v: version, + version, + // 主题名称 + type: [ + 'primary', + 'success', + 'info', + 'error', + 'warning' + ], + // 颜色部分,本来可以通过scss的:export导出供js使用,但是奈何nvue不支持 + color: { + 'uv-primary': '#2979ff', + 'uv-warning': '#ff9900', + 'uv-success': '#19be6b', + 'uv-error': '#fa3534', + 'uv-info': '#909399', + 'uv-main-color': '#303133', + 'uv-content-color': '#606266', + 'uv-tips-color': '#909399', + 'uv-light-color': '#c0c4cc' + }, + // 默认单位,可以通过配置为rpx,那么在用于传入组件大小参数为数值时,就默认为rpx + unit: 'px' +} diff --git a/src/uni_modules/uv-ui-tools/libs/css/color.scss b/src/uni_modules/uv-ui-tools/libs/css/color.scss new file mode 100644 index 0000000..ce65743 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/css/color.scss @@ -0,0 +1,32 @@ +$uv-main-color: #303133 !default; +$uv-content-color: #606266 !default; +$uv-tips-color: #909193 !default; +$uv-light-color: #c0c4cc !default; +$uv-border-color: #dadbde !default; +$uv-bg-color: #f3f4f6 !default; +$uv-disabled-color: #c8c9cc !default; + +$uv-primary: #3c9cff !default; +$uv-primary-dark: #398ade !default; +$uv-primary-disabled: #9acafc !default; +$uv-primary-light: #ecf5ff !default; + +$uv-warning: #f9ae3d !default; +$uv-warning-dark: #f1a532 !default; +$uv-warning-disabled: #f9d39b !default; +$uv-warning-light: #fdf6ec !default; + +$uv-success: #5ac725 !default; +$uv-success-dark: #53c21d !default; +$uv-success-disabled: #a9e08f !default; +$uv-success-light: #f5fff0; + +$uv-error: #f56c6c !default; +$uv-error-dark: #e45656 !default; +$uv-error-disabled: #f7b2b2 !default; +$uv-error-light: #fef0f0 !default; + +$uv-info: #909399 !default; +$uv-info-dark: #767a82 !default; +$uv-info-disabled: #c4c6c9 !default; +$uv-info-light: #f4f4f5 !default; diff --git a/src/uni_modules/uv-ui-tools/libs/css/common.scss b/src/uni_modules/uv-ui-tools/libs/css/common.scss new file mode 100644 index 0000000..7ab99f8 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/css/common.scss @@ -0,0 +1,100 @@ +// 超出行数,自动显示行尾省略号,最多5行 +// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】 +@for $i from 1 through 5 { + .uv-line-#{$i} { + /* #ifdef APP-NVUE */ + // nvue下,可以直接使用lines属性,这是weex特有样式 + lines: $i; + text-overflow: ellipsis; + overflow: hidden; + flex: 1; + /* #endif */ + + /* #ifndef APP-NVUE */ + // vue下,单行和多行显示省略号需要单独处理 + @if $i == '1' { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } @else { + display: -webkit-box!important; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + -webkit-line-clamp: $i; + -webkit-box-orient: vertical!important; + } + /* #endif */ + } +} +$uv-bordercolor: #dadbde; +@if variable-exists(uv-border-color) { + $uv-bordercolor: $uv-border-color; +} + +// 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时, +// App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效 +// 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important +// 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现 +.uv-border { + border-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-style: solid; +} + +.uv-border-top { + border-top-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; +} + +.uv-border-left { + border-left-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-left-style: solid; +} + +.uv-border-right { + border-right-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-right-style: solid; +} + +.uv-border-bottom { + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-bottom-style: solid; +} + +.uv-border-top-bottom { + border-top-width: 0.5px!important; + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + border-bottom-style: solid; +} + +// 去除button的所有默认样式,让其表现跟普通的view、text元素一样 +.uv-reset-button { + padding: 0; + background-color: transparent; + /* #ifndef APP-PLUS */ + font-size: inherit; + line-height: inherit; + color: inherit; + /* #endif */ + /* #ifdef APP-NVUE */ + border-width: 0; + /* #endif */ +} + +/* #ifndef APP-NVUE */ +.uv-reset-button::after { + border: none; +} +/* #endif */ + +.uv-hover-class { + opacity: 0.7; +} + diff --git a/src/uni_modules/uv-ui-tools/libs/css/components.scss b/src/uni_modules/uv-ui-tools/libs/css/components.scss new file mode 100644 index 0000000..81ce15d --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/css/components.scss @@ -0,0 +1,23 @@ +@mixin flex($direction: row) { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: $direction; +} + +/* #ifndef APP-NVUE */ +// 由于uvui是基于nvue环境进行开发的,此环境中普通元素默认为flex-direction: column; +// 所以在非nvue中,需要对元素进行重置为flex-direction: column; 否则可能会表现异常 +$uvui-nvue-style: true !default; +@if $uvui-nvue-style == true { + view, scroll-view, swiper-item { + display: flex; + flex-direction: column; + flex-shrink: 0; + flex-grow: 0; + flex-basis: auto; + align-items: stretch; + align-content: flex-start; + } +} +/* #endif */ diff --git a/src/uni_modules/uv-ui-tools/libs/css/variable.scss b/src/uni_modules/uv-ui-tools/libs/css/variable.scss new file mode 100644 index 0000000..63903c9 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/css/variable.scss @@ -0,0 +1,111 @@ +// 超出行数,自动显示行尾省略号,最多5行 +// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】 +@if variable-exists(show-lines) { + @for $i from 1 through 5 { + .uv-line-#{$i} { + /* #ifdef APP-NVUE */ + // nvue下,可以直接使用lines属性,这是weex特有样式 + lines: $i; + text-overflow: ellipsis; + overflow: hidden; + flex: 1; + /* #endif */ + + /* #ifndef APP-NVUE */ + // vue下,单行和多行显示省略号需要单独处理 + @if $i == '1' { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } @else { + display: -webkit-box!important; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + -webkit-line-clamp: $i; + -webkit-box-orient: vertical!important; + } + /* #endif */ + } + } +} +@if variable-exists(show-border) { + $uv-bordercolor: #dadbde; + @if variable-exists(uv-border-color) { + $uv-bordercolor: $uv-border-color; + } + // 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时, + // App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效 + // 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important + // 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现 + @if variable-exists(show-border-surround) { + .uv-border { + border-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-style: solid; + } + } + @if variable-exists(show-border-top) { + .uv-border-top { + border-top-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + } + } + @if variable-exists(show-border-left) { + .uv-border-left { + border-left-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-left-style: solid; + } + } + @if variable-exists(show-border-right) { + .uv-border-right { + border-right-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-right-style: solid; + } + } + @if variable-exists(show-border-bottom) { + .uv-border-bottom { + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-bottom-style: solid; + } + } + @if variable-exists(show-border-top-bottom) { + .uv-border-top-bottom { + border-top-width: 0.5px!important; + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + border-bottom-style: solid; + } + } +} +@if variable-exists(show-reset-button) { + // 去除button的所有默认样式,让其表现跟普通的view、text元素一样 + .uv-reset-button { + padding: 0; + background-color: transparent; + /* #ifndef APP-PLUS */ + font-size: inherit; + line-height: inherit; + color: inherit; + /* #endif */ + /* #ifdef APP-NVUE */ + border-width: 0; + /* #endif */ + } + + /* #ifndef APP-NVUE */ + .uv-reset-button::after { + border: none; + } + /* #endif */ +} +@if variable-exists(show-hover) { + .uv-hover-class { + opacity: 0.7; + } +} diff --git a/src/uni_modules/uv-ui-tools/libs/css/vue.scss b/src/uni_modules/uv-ui-tools/libs/css/vue.scss new file mode 100644 index 0000000..bdbefdd --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/css/vue.scss @@ -0,0 +1,40 @@ +// 历遍生成4个方向的底部安全区 +@each $d in top, right, bottom, left { + .uv-safe-area-inset-#{$d} { + padding-#{$d}: 0; + padding-#{$d}: constant(safe-area-inset-#{$d}); + padding-#{$d}: env(safe-area-inset-#{$d}); + } +} + +//提升H5端uni.toast()的层级,避免被uvui的modal等遮盖 +/* #ifdef H5 */ +uni-toast { + z-index: 10090; +} +uni-toast .uni-toast { + z-index: 10090; +} +/* #endif */ + +// 隐藏scroll-view的滚动条 +::-webkit-scrollbar { + display: none; + width: 0 !important; + height: 0 !important; + -webkit-appearance: none; + background: transparent; +} + +$uvui-nvue-style: true !default; +@if $uvui-nvue-style == false { + view, scroll-view, swiper-item { + display: flex; + flex-direction: column; + flex-shrink: 0; + flex-grow: 0; + flex-basis: auto; + align-items: stretch; + align-content: flex-start; + } +} diff --git a/src/uni_modules/uv-ui-tools/libs/function/colorGradient.js b/src/uni_modules/uv-ui-tools/libs/function/colorGradient.js new file mode 100644 index 0000000..55c188f --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/function/colorGradient.js @@ -0,0 +1,134 @@ +/** + * 求两个颜色之间的渐变值 + * @param {string} startColor 开始的颜色 + * @param {string} endColor 结束的颜色 + * @param {number} step 颜色等分的份额 + * */ +function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) { + const startRGB = hexToRgb(startColor, false) // 转换为rgb数组模式 + const startR = startRGB[0] + const startG = startRGB[1] + const startB = startRGB[2] + + const endRGB = hexToRgb(endColor, false) + const endR = endRGB[0] + const endG = endRGB[1] + const endB = endRGB[2] + + const sR = (endR - startR) / step // 总差值 + const sG = (endG - startG) / step + const sB = (endB - startB) / step + const colorArr = [] + for (let i = 0; i < step; i++) { + // 计算每一步的hex值 + let hex = rgbToHex(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB + * i + startB))})`) + // 确保第一个颜色值为startColor的值 + if (i === 0) hex = rgbToHex(startColor) + // 确保最后一个颜色值为endColor的值 + if (i === step - 1) hex = rgbToHex(endColor) + colorArr.push(hex) + } + return colorArr +} + +// 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式) +function hexToRgb(sColor, str = true) { + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + sColor = String(sColor).toLowerCase() + if (sColor && reg.test(sColor)) { + if (sColor.length === 4) { + let sColorNew = '#' + for (let i = 1; i < 4; i += 1) { + sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)) + } + sColor = sColorNew + } + // 处理六位的颜色值 + const sColorChange = [] + for (let i = 1; i < 7; i += 2) { + sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`)) + } + if (!str) { + return sColorChange + } + return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})` + } if (/^(rgb|RGB)/.test(sColor)) { + const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',') + return arr.map((val) => Number(val)) + } + return sColor +} + +// 将rgb表示方式转换为hex表示方式 +function rgbToHex(rgb) { + const _this = rgb + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + if (/^(rgb|RGB)/.test(_this)) { + const aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',') + let strHex = '#' + for (let i = 0; i < aColor.length; i++) { + let hex = Number(aColor[i]).toString(16) + hex = String(hex).length == 1 ? `${0}${hex}` : hex // 保证每个rgb的值为2位 + if (hex === '0') { + hex += hex + } + strHex += hex + } + if (strHex.length !== 7) { + strHex = _this + } + return strHex + } if (reg.test(_this)) { + const aNum = _this.replace(/#/, '').split('') + if (aNum.length === 6) { + return _this + } if (aNum.length === 3) { + let numHex = '#' + for (let i = 0; i < aNum.length; i += 1) { + numHex += (aNum[i] + aNum[i]) + } + return numHex + } + } else { + return _this + } +} + +/** +* JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba(255,255,255,0.5)字符串 +* sHex为传入的十六进制的色值 +* alpha为rgba的透明度 +*/ +function colorToRgba(color, alpha) { + color = rgbToHex(color) + // 十六进制颜色值的正则表达式 + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + /* 16进制颜色转为RGB格式 */ + let sColor = String(color).toLowerCase() + if (sColor && reg.test(sColor)) { + if (sColor.length === 4) { + let sColorNew = '#' + for (let i = 1; i < 4; i += 1) { + sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)) + } + sColor = sColorNew + } + // 处理六位的颜色值 + const sColorChange = [] + for (let i = 1; i < 7; i += 2) { + sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`)) + } + // return sColorChange.join(',') + return `rgba(${sColorChange.join(',')},${alpha})` + } + + return sColor +} + +export { + colorGradient, + hexToRgb, + rgbToHex, + colorToRgba +} diff --git a/src/uni_modules/uv-ui-tools/libs/function/debounce.js b/src/uni_modules/uv-ui-tools/libs/function/debounce.js new file mode 100644 index 0000000..ad3996b --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/function/debounce.js @@ -0,0 +1,29 @@ +let timeout = null + +/** + * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数 + * + * @param {Function} func 要执行的回调函数 + * @param {Number} wait 延时的时间 + * @param {Boolean} immediate 是否立即执行 + * @return null + */ +function debounce(func, wait = 500, immediate = false) { + // 清除定时器 + if (timeout !== null) clearTimeout(timeout) + // 立即执行,此类情况一般用不到 + if (immediate) { + const callNow = !timeout + timeout = setTimeout(() => { + timeout = null + }, wait) + if (callNow) typeof func === 'function' && func() + } else { + // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法 + timeout = setTimeout(() => { + typeof func === 'function' && func() + }, wait) + } +} + +export default debounce diff --git a/src/uni_modules/uv-ui-tools/libs/function/digit.js b/src/uni_modules/uv-ui-tools/libs/function/digit.js new file mode 100644 index 0000000..c8260a0 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/function/digit.js @@ -0,0 +1,167 @@ +let _boundaryCheckingState = true; // 是否进行越界检查的全局开关 + +/** + * 把错误的数据转正 + * @private + * @example strip(0.09999999999999998)=0.1 + */ +function strip(num, precision = 15) { + return +parseFloat(Number(num).toPrecision(precision)); +} + +/** + * Return digits length of a number + * @private + * @param {*number} num Input number + */ +function digitLength(num) { + // Get digit length of e + const eSplit = num.toString().split(/[eE]/); + const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0); + return len > 0 ? len : 0; +} + +/** + * 把小数转成整数,如果是小数则放大成整数 + * @private + * @param {*number} num 输入数 + */ +function float2Fixed(num) { + if (num.toString().indexOf('e') === -1) { + return Number(num.toString().replace('.', '')); + } + const dLen = digitLength(num); + return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num); +} + +/** + * 检测数字是否越界,如果越界给出提示 + * @private + * @param {*number} num 输入数 + */ +function checkBoundary(num) { + if (_boundaryCheckingState) { + if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { + console.warn(`${num} 超出了精度限制,结果可能不正确`); + } + } +} + +/** + * 把递归操作扁平迭代化 + * @param {number[]} arr 要操作的数字数组 + * @param {function} operation 迭代操作 + * @private + */ +function iteratorOperation(arr, operation) { + const [num1, num2, ...others] = arr; + let res = operation(num1, num2); + + others.forEach((num) => { + res = operation(res, num); + }); + + return res; +} + +/** + * 高精度乘法 + * @export + */ +export function times(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, times); + } + + const [num1, num2] = nums; + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + const baseNum = digitLength(num1) + digitLength(num2); + const leftValue = num1Changed * num2Changed; + + checkBoundary(leftValue); + + return leftValue / Math.pow(10, baseNum); +} + +/** + * 高精度加法 + * @export + */ +export function plus(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, plus); + } + + const [num1, num2] = nums; + // 取最大的小数位 + const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + // 把小数都转为整数然后再计算 + return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; +} + +/** + * 高精度减法 + * @export + */ +export function minus(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, minus); + } + + const [num1, num2] = nums; + const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; +} + +/** + * 高精度除法 + * @export + */ +export function divide(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, divide); + } + + const [num1, num2] = nums; + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + checkBoundary(num1Changed); + checkBoundary(num2Changed); + // 重要,这里必须用strip进行修正 + return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1)))); +} + +/** + * 四舍五入 + * @export + */ +export function round(num, ratio) { + const base = Math.pow(10, ratio); + let result = divide(Math.round(Math.abs(times(num, base))), base); + if (num < 0 && result !== 0) { + result = times(result, -1); + } + // 位数不足则补0 + return result; +} + +/** + * 是否进行边界检查,默认开启 + * @param flag 标记开关,true 为开启,false 为关闭,默认为 true + * @export + */ +export function enableBoundaryChecking(flag = true) { + _boundaryCheckingState = flag; +} + + +export default { + times, + plus, + minus, + divide, + round, + enableBoundaryChecking, +}; + diff --git a/src/uni_modules/uv-ui-tools/libs/function/index.js b/src/uni_modules/uv-ui-tools/libs/function/index.js new file mode 100644 index 0000000..b35e0ab --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/function/index.js @@ -0,0 +1,734 @@ +import { number, empty } from './test.js' +import { round } from './digit.js' +/** + * @description 如果value小于min,取min;如果value大于max,取max + * @param {number} min + * @param {number} max + * @param {number} value + */ +function range(min = 0, max = 0, value = 0) { + return Math.max(min, Math.min(max, Number(value))) +} + +/** + * @description 用于获取用户传递值的px值 如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.upx2px进行转换 + * @param {number|string} value 用户传递值的px值 + * @param {boolean} unit + * @returns {number|string} + */ +function getPx(value, unit = false) { + if (number(value)) { + return unit ? `${value}px` : Number(value) + } + // 如果带有rpx,先取出其数值部分,再转为px值 + if (/(rpx|upx)$/.test(value)) { + return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value))) + } + return unit ? `${parseInt(value)}px` : parseInt(value) +} + +/** + * @description 进行延时,以达到可以简写代码的目的 比如: await uni.$uv.sleep(20)将会阻塞20ms + * @param {number} value 堵塞时间 单位ms 毫秒 + * @returns {Promise} 返回promise + */ +function sleep(value = 30) { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, value) + }) +} +/** + * @description 运行期判断平台 + * @returns {string} 返回所在平台(小写) + * @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台 + */ +function os() { + return uni.getSystemInfoSync().platform.toLowerCase() +} +/** + * @description 获取系统信息同步接口 + * @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync + */ +function sys() { + return uni.getSystemInfoSync() +} + +/** + * @description 取一个区间数 + * @param {Number} min 最小值 + * @param {Number} max 最大值 + */ +function random(min, max) { + if (min >= 0 && max > 0 && max >= min) { + const gab = max - min + 1 + return Math.floor(Math.random() * gab + min) + } + return 0 +} + +/** + * @param {Number} len uuid的长度 + * @param {Boolean} firstU 将返回的首字母置为"u" + * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制 + */ +function guid(len = 32, firstU = true, radix = null) { + const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('') + const uuid = [] + radix = radix || chars.length + + if (len) { + // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 + for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] + } else { + let r + // rfc4122标准要求返回的uuid中,某些位为固定的字符 + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-' + uuid[14] = '4' + + for (let i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | Math.random() * 16 + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r] + } + } + } + // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class + if (firstU) { + uuid.shift() + return `u${uuid.join('')}` + } + return uuid.join('') +} + +/** +* @description 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法 + this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx + 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name + 值(默认为undefined),就是查找最顶层的$parent +* @param {string|undefined} name 父组件的参数名 +*/ +function $parent(name = undefined) { + let parent = this.$parent + // 通过while历遍,这里主要是为了H5需要多层解析的问题 + while (parent) { + // 父组件 + if (parent.$options && parent.$options.name !== name) { + // 如果组件的name不相等,继续上一级寻找 + parent = parent.$parent + } else { + return parent + } + } + return false +} + +/** + * @description 样式转换 + * 对象转字符串,或者字符串转对象 + * @param {object | string} customStyle 需要转换的目标 + * @param {String} target 转换的目的,object-转为对象,string-转为字符串 + * @returns {object|string} + */ +function addStyle(customStyle, target = 'object') { + // 字符串转字符串,对象转对象情形,直接返回 + if (empty(customStyle) || typeof(customStyle) === 'object' && target === 'object' || target === 'string' && + typeof(customStyle) === 'string') { + return customStyle + } + // 字符串转对象 + if (target === 'object') { + // 去除字符串样式中的两端空格(中间的空格不能去掉,比如padding: 20px 0如果去掉了就错了),空格是无用的 + customStyle = trim(customStyle) + // 根据";"将字符串转为数组形式 + const styleArray = customStyle.split(';') + const style = {} + // 历遍数组,拼接成对象 + for (let i = 0; i < styleArray.length; i++) { + // 'font-size:20px;color:red;',如此最后字符串有";"的话,会导致styleArray最后一个元素为空字符串,这里需要过滤 + if (styleArray[i]) { + const item = styleArray[i].split(':') + style[trim(item[0])] = trim(item[1]) + } + } + return style + } + // 这里为对象转字符串形式 + let string = '' + for (const i in customStyle) { + // 驼峰转为中划线的形式,否则css内联样式,无法识别驼峰样式属性名 + const key = i.replace(/([A-Z])/g, '-$1').toLowerCase() + string += `${key}:${customStyle[i]};` + } + // 去除两端空格 + return trim(string) +} + +/** + * @description 添加单位,如果有rpx,upx,%,px等单位结尾或者值为auto,直接返回,否则加上px单位结尾 + * @param {string|number} value 需要添加单位的值 + * @param {string} unit 添加的单位名 比如px + */ +function addUnit(value = 'auto', unit = uni?.$uv?.config?.unit ? uni?.$uv?.config?.unit : 'px') { + value = String(value) + // 用uvui内置验证规则中的number判断是否为数值 + return number(value) ? `${value}${unit}` : value +} + +/** + * @description 深度克隆 + * @param {object} obj 需要深度克隆的对象 + * @param cache 缓存 + * @returns {*} 克隆后的对象或者原值(不是对象) + */ +function deepClone(obj, cache = new WeakMap()) { + if (obj === null || typeof obj !== 'object') return obj; + if (cache.has(obj)) return cache.get(obj); + let clone; + if (obj instanceof Date) { + clone = new Date(obj.getTime()); + } else if (obj instanceof RegExp) { + clone = new RegExp(obj); + } else if (obj instanceof Map) { + clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)])); + } else if (obj instanceof Set) { + clone = new Set(Array.from(obj, value => deepClone(value, cache))); + } else if (Array.isArray(obj)) { + clone = obj.map(value => deepClone(value, cache)); + } else if (Object.prototype.toString.call(obj) === '[object Object]') { + clone = Object.create(Object.getPrototypeOf(obj)); + cache.set(obj, clone); + for (const [key, value] of Object.entries(obj)) { + clone[key] = deepClone(value, cache); + } + } else { + clone = Object.assign({}, obj); + } + cache.set(obj, clone); + return clone; +} + +/** + * @description JS对象深度合并 + * @param {object} target 需要拷贝的对象 + * @param {object} source 拷贝的来源对象 + * @returns {object|boolean} 深度合并后的对象或者false(入参有不是对象) + */ +function deepMerge(target = {}, source = {}) { + target = deepClone(target) + if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target; + const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target); + for (const prop in source) { + if (!source.hasOwnProperty(prop)) continue; + const sourceValue = source[prop]; + const targetValue = merged[prop]; + if (sourceValue instanceof Date) { + merged[prop] = new Date(sourceValue); + } else if (sourceValue instanceof RegExp) { + merged[prop] = new RegExp(sourceValue); + } else if (sourceValue instanceof Map) { + merged[prop] = new Map(sourceValue); + } else if (sourceValue instanceof Set) { + merged[prop] = new Set(sourceValue); + } else if (typeof sourceValue === 'object' && sourceValue !== null) { + merged[prop] = deepMerge(targetValue, sourceValue); + } else { + merged[prop] = sourceValue; + } + } + return merged; +} + +/** + * @description error提示 + * @param {*} err 错误内容 + */ +function error(err) { + // 开发环境才提示,生产环境不会提示 + if (process.env.NODE_ENV === 'development') { + console.error(`uvui提示:${err}`) + } +} + +/** + * @description 打乱数组 + * @param {array} array 需要打乱的数组 + * @returns {array} 打乱后的数组 + */ +function randomArray(array = []) { + // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0 + return array.sort(() => Math.random() - 0.5) +} + +// padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序 +// 所以这里做一个兼容polyfill的兼容处理 +if (!String.prototype.padStart) { + // 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解 + String.prototype.padStart = function(maxLength, fillString = ' ') { + if (Object.prototype.toString.call(fillString) !== '[object String]') { + throw new TypeError( + 'fillString must be String' + ) + } + const str = this + // 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉 + if (str.length >= maxLength) return String(str) + + const fillLength = maxLength - str.length + let times = Math.ceil(fillLength / fillString.length) + while (times >>= 1) { + fillString += fillString + if (times === 1) { + fillString += fillString + } + } + return fillString.slice(0, fillLength) + str + } +} + +/** + * @description 格式化时间 + * @param {String|Number} dateTime 需要格式化的时间戳 + * @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd + * @returns {string} 返回格式化后的字符串 + */ +function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') { + let date + // 若传入时间为假值,则取当前时间 + if (!dateTime) { + date = new Date() + } + // 若为unix秒时间戳,则转为毫秒时间戳(逻辑有点奇怪,但不敢改,以保证历史兼容) + else if (/^\d{10}$/.test(dateTime?.toString().trim())) { + date = new Date(dateTime * 1000) + } + // 若用户传入字符串格式时间戳,new Date无法解析,需做兼容 + else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) { + date = new Date(Number(dateTime)) + } + // 处理平台性差异,在Safari/Webkit中,new Date仅支持/作为分割符的字符串时间 + // 处理 '2022-07-10 01:02:03',跳过 '2022-07-10T01:02:03' + else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) { + date = new Date(dateTime.replace(/-/g, '/')) + } + // 其他都认为符合 RFC 2822 规范 + else { + date = new Date(dateTime) + } + + const timeSource = { + 'y': date.getFullYear().toString(), // 年 + 'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月 + 'd': date.getDate().toString().padStart(2, '0'), // 日 + 'h': date.getHours().toString().padStart(2, '0'), // 时 + 'M': date.getMinutes().toString().padStart(2, '0'), // 分 + 's': date.getSeconds().toString().padStart(2, '0') // 秒 + // 有其他格式化字符需求可以继续添加,必须转化成字符串 + } + + for (const key in timeSource) { + const [ret] = new RegExp(`${key}+`).exec(formatStr) || [] + if (ret) { + // 年可能只需展示两位 + const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0 + formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex)) + } + } + + return formatStr +} + +/** + * @description 时间戳转为多久之前 + * @param {String|Number} timestamp 时间戳 + * @param {String|Boolean} format + * 格式化规则如果为时间格式字符串,超出一定时间范围,返回固定的时间格式; + * 如果为布尔值false,无论什么时间,都返回多久以前的格式 + * @returns {string} 转化后的内容 + */ +function timeFrom(timestamp = null, format = 'yyyy-mm-dd') { + if (timestamp == null) timestamp = Number(new Date()) + timestamp = parseInt(timestamp) + // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位) + if (timestamp.toString().length == 10) timestamp *= 1000 + let timer = (new Date()).getTime() - timestamp + timer = parseInt(timer / 1000) + // 如果小于5分钟,则返回"刚刚",其他以此类推 + let tips = '' + switch (true) { + case timer < 300: + tips = '刚刚' + break + case timer >= 300 && timer < 3600: + tips = `${parseInt(timer / 60)}分钟前` + break + case timer >= 3600 && timer < 86400: + tips = `${parseInt(timer / 3600)}小时前` + break + case timer >= 86400 && timer < 2592000: + tips = `${parseInt(timer / 86400)}天前` + break + default: + // 如果format为false,则无论什么时间戳,都显示xx之前 + if (format === false) { + if (timer >= 2592000 && timer < 365 * 86400) { + tips = `${parseInt(timer / (86400 * 30))}个月前` + } else { + tips = `${parseInt(timer / (86400 * 365))}年前` + } + } else { + tips = timeFormat(timestamp, format) + } + } + return tips +} + +/** + * @description 去除空格 + * @param String str 需要去除空格的字符串 + * @param String pos both(左右)|left|right|all 默认both + */ +function trim(str, pos = 'both') { + str = String(str) + if (pos == 'both') { + return str.replace(/^\s+|\s+$/g, '') + } + if (pos == 'left') { + return str.replace(/^\s*/, '') + } + if (pos == 'right') { + return str.replace(/(\s*$)/g, '') + } + if (pos == 'all') { + return str.replace(/\s+/g, '') + } + return str +} + +/** + * @description 对象转url参数 + * @param {object} data,对象 + * @param {Boolean} isPrefix,是否自动加上"?" + * @param {string} arrayFormat 规则 indices|brackets|repeat|comma + */ +function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') { + const prefix = isPrefix ? '?' : '' + const _result = [] + if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets' + for (const key in data) { + const value = data[key] + // 去掉为空的参数 + if (['', undefined, null].indexOf(value) >= 0) { + continue + } + // 如果值为数组,另行处理 + if (value.constructor === Array) { + // e.g. {ids: [1, 2, 3]} + switch (arrayFormat) { + case 'indices': + // 结果: ids[0]=1&ids[1]=2&ids[2]=3 + for (let i = 0; i < value.length; i++) { + _result.push(`${key}[${i}]=${value[i]}`) + } + break + case 'brackets': + // 结果: ids[]=1&ids[]=2&ids[]=3 + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + break + case 'repeat': + // 结果: ids=1&ids=2&ids=3 + value.forEach((_value) => { + _result.push(`${key}=${_value}`) + }) + break + case 'comma': + // 结果: ids=1,2,3 + let commaStr = '' + value.forEach((_value) => { + commaStr += (commaStr ? ',' : '') + _value + }) + _result.push(`${key}=${commaStr}`) + break + default: + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + } + } else { + _result.push(`${key}=${value}`) + } + } + return _result.length ? prefix + _result.join('&') : '' +} + +/** + * 显示消息提示框 + * @param {String} title 提示的内容,长度与 icon 取值有关。 + * @param {Number} duration 提示的延迟时间,单位毫秒,默认:2000 + */ +function toast(title, duration = 2000) { + uni.showToast({ + title: String(title), + icon: 'none', + duration + }) +} + +/** + * @description 根据主题type值,获取对应的图标 + * @param {String} type 主题名称,primary|info|error|warning|success + * @param {boolean} fill 是否使用fill填充实体的图标 + */ +function type2icon(type = 'success', fill = false) { + // 如果非预置值,默认为success + if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success' + let iconName = '' + // 目前(2019-12-12),info和primary使用同一个图标 + switch (type) { + case 'primary': + iconName = 'info-circle' + break + case 'info': + iconName = 'info-circle' + break + case 'error': + iconName = 'close-circle' + break + case 'warning': + iconName = 'error-circle' + break + case 'success': + iconName = 'checkmark-circle' + break + default: + iconName = 'checkmark-circle' + } + // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的 + if (fill) iconName += '-fill' + return iconName +} + +/** + * @description 数字格式化 + * @param {number|string} number 要格式化的数字 + * @param {number} decimals 保留几位小数 + * @param {string} decimalPoint 小数点符号 + * @param {string} thousandsSeparator 千分位符号 + * @returns {string} 格式化后的数字 + */ +function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') { + number = (`${number}`).replace(/[^0-9+-Ee.]/g, '') + const n = !isFinite(+number) ? 0 : +number + const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) + const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator + const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint + let s = '' + + s = (prec ? round(n, prec) + '' : `${Math.round(n)}`).split('.') + const re = /(-?\d+)(\d{3})/ + while (re.test(s[0])) { + s[0] = s[0].replace(re, `$1${sep}$2`) + } + + if ((s[1] || '').length < prec) { + s[1] = s[1] || '' + s[1] += new Array(prec - s[1].length + 1).join('0') + } + return s.join(dec) +} + +/** + * @description 获取duration值 + * 如果带有ms或者s直接返回,如果大于一定值,认为是ms单位,小于一定值,认为是s单位 + * 比如以30位阈值,那么300大于30,可以理解为用户想要的是300ms,而不是想花300s去执行一个动画 + * @param {String|number} value 比如: "1s"|"100ms"|1|100 + * @param {boolean} unit 提示: 如果是false 默认返回number + * @return {string|number} + */ +function getDuration(value, unit = true) { + const valueNum = parseInt(value) + if (unit) { + if (/s$/.test(value)) return value + return value > 30 ? `${value}ms` : `${value}s` + } + if (/ms$/.test(value)) return valueNum + if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000 + return valueNum +} + +/** + * @description 日期的月或日补零操作 + * @param {String} value 需要补零的值 + */ +function padZero(value) { + return `00${value}`.slice(-2) +} + +/** + * @description 在uv-form的子组件内容发生变化,或者失去焦点时,尝试通知uv-form执行校验方法 + * @param {*} instance + * @param {*} event + */ +function formValidate(instance, event) { + const formItem = $parent.call(instance, 'uv-form-item') + const form = $parent.call(instance, 'uv-form') + // 如果发生变化的input或者textarea等,其父组件中有uv-form-item或者uv-form等,就执行form的validate方法 + // 同时将form-item的pros传递给form,让其进行精确对象验证 + if (formItem && form) { + form.validateField(formItem.prop, () => {}, event) + } +} + +/** + * @description 获取某个对象下的属性,用于通过类似'a.b.c'的形式去获取一个对象的的属性的形式 + * @param {object} obj 对象 + * @param {string} key 需要获取的属性字段 + * @returns {*} + */ +function getProperty(obj, key) { + if (!obj) { + return + } + if (typeof key !== 'string' || key === '') { + return '' + } + if (key.indexOf('.') !== -1) { + const keys = key.split('.') + let firstObj = obj[keys[0]] || {} + + for (let i = 1; i < keys.length; i++) { + if (firstObj) { + firstObj = firstObj[keys[i]] + } + } + return firstObj + } + return obj[key] +} + +/** + * @description 设置对象的属性值,如果'a.b.c'的形式进行设置 + * @param {object} obj 对象 + * @param {string} key 需要设置的属性 + * @param {string} value 设置的值 + */ +function setProperty(obj, key, value) { + if (!obj) { + return + } + // 递归赋值 + const inFn = function(_obj, keys, v) { + // 最后一个属性key + if (keys.length === 1) { + _obj[keys[0]] = v + return + } + // 0~length-1个key + while (keys.length > 1) { + const k = keys[0] + if (!_obj[k] || (typeof _obj[k] !== 'object')) { + _obj[k] = {} + } + const key = keys.shift() + // 自调用判断是否存在属性,不存在则自动创建对象 + inFn(_obj[k], keys, v) + } + } + + if (typeof key !== 'string' || key === '') { + + } else if (key.indexOf('.') !== -1) { // 支持多层级赋值操作 + const keys = key.split('.') + inFn(obj, keys, value) + } else { + obj[key] = value + } +} + +/** + * @description 获取当前页面路径 + */ +function page() { + const pages = getCurrentPages(); + const route = pages[pages.length - 1]?.route; + // 某些特殊情况下(比如页面进行redirectTo时的一些时机),pages可能为空数组 + return `/${route ? route : ''}` +} + +/** + * @description 获取当前路由栈实例数组 + */ +function pages() { + const pages = getCurrentPages() + return pages +} + +/** + * 获取页面历史栈指定层实例 + * @param back {number} [0] - 0或者负数,表示获取历史栈的哪一层,0表示获取当前页面实例,-1 表示获取上一个页面实例。默认0。 + */ +function getHistoryPage(back = 0) { + const pages = getCurrentPages() + const len = pages.length + return pages[len - 1 + back] +} + + + +/** + * @description 修改uvui内置属性值 + * @param {object} props 修改内置props属性 + * @param {object} config 修改内置config属性 + * @param {object} color 修改内置color属性 + * @param {object} zIndex 修改内置zIndex属性 + */ +function setConfig({ + props = {}, + config = {}, + color = {}, + zIndex = {} +}) { + const { + deepMerge, + } = uni.$uv + uni.$uv.config = deepMerge(uni.$uv.config, config) + uni.$uv.props = deepMerge(uni.$uv.props, props) + uni.$uv.color = deepMerge(uni.$uv.color, color) + uni.$uv.zIndex = deepMerge(uni.$uv.zIndex, zIndex) +} + +export { + range, + getPx, + sleep, + os, + sys, + random, + guid, + $parent, + addStyle, + addUnit, + deepClone, + deepMerge, + error, + randomArray, + timeFormat, + timeFrom, + trim, + queryParams, + toast, + type2icon, + priceFormat, + getDuration, + padZero, + formValidate, + getProperty, + setProperty, + page, + pages, + getHistoryPage, + setConfig +} \ No newline at end of file diff --git a/src/uni_modules/uv-ui-tools/libs/function/platform.js b/src/uni_modules/uv-ui-tools/libs/function/platform.js new file mode 100644 index 0000000..d6b926e --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/function/platform.js @@ -0,0 +1,75 @@ +/** + * 注意: + * 此部分内容,在vue-cli模式下,需要在vue.config.js加入如下内容才有效: + * module.exports = { + * transpileDependencies: ['uview-v2'] + * } + */ + +let platform = 'none' + +// #ifdef VUE3 +platform = 'vue3' +// #endif + +// #ifdef VUE2 +platform = 'vue2' +// #endif + +// #ifdef APP-PLUS +platform = 'plus' +// #endif + +// #ifdef APP-NVUE +platform = 'nvue' +// #endif + +// #ifdef H5 +platform = 'h5' +// #endif + +// #ifdef MP-WEIXIN +platform = 'weixin' +// #endif + +// #ifdef MP-ALIPAY +platform = 'alipay' +// #endif + +// #ifdef MP-BAIDU +platform = 'baidu' +// #endif + +// #ifdef MP-TOUTIAO +platform = 'toutiao' +// #endif + +// #ifdef MP-QQ +platform = 'qq' +// #endif + +// #ifdef MP-KUAISHOU +platform = 'kuaishou' +// #endif + +// #ifdef MP-360 +platform = '360' +// #endif + +// #ifdef MP +platform = 'mp' +// #endif + +// #ifdef QUICKAPP-WEBVIEW +platform = 'quickapp-webview' +// #endif + +// #ifdef QUICKAPP-WEBVIEW-HUAWEI +platform = 'quickapp-webview-huawei' +// #endif + +// #ifdef QUICKAPP-WEBVIEW-UNION +platform = 'quckapp-webview-union' +// #endif + +export default platform diff --git a/src/uni_modules/uv-ui-tools/libs/function/test.js b/src/uni_modules/uv-ui-tools/libs/function/test.js new file mode 100644 index 0000000..7c8b747 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/function/test.js @@ -0,0 +1,287 @@ +/** + * 验证电子邮箱格式 + */ +function email(value) { + return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value) +} + +/** + * 验证手机格式 + */ +function mobile(value) { + return /^1([3589]\d|4[5-9]|6[1-2,4-7]|7[0-8])\d{8}$/.test(value) +} + +/** + * 验证URL格式 + */ +function url(value) { + return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/ + .test(value) +} + +/** + * 验证日期格式 + */ +function date(value) { + if (!value) return false + // 判断是否数值或者字符串数值(意味着为时间戳),转为数值,否则new Date无法识别字符串时间戳 + if (number(value)) value = +value + return !/Invalid|NaN/.test(new Date(value).toString()) +} + +/** + * 验证ISO类型的日期格式 + */ +function dateISO(value) { + return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value) +} + +/** + * 验证十进制数字 + */ +function number(value) { + return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value) +} + +/** + * 验证字符串 + */ +function string(value) { + return typeof value === 'string' +} + +/** + * 验证整数 + */ +function digits(value) { + return /^\d+$/.test(value) +} + +/** + * 验证身份证号码 + */ +function idCard(value) { + return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test( + value + ) +} + +/** + * 是否车牌号 + */ +function carNo(value) { + // 新能源车牌 + const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/ + // 旧车牌 + const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/ + if (value.length === 7) { + return creg.test(value) + } if (value.length === 8) { + return xreg.test(value) + } + return false +} + +/** + * 金额,只允许2位小数 + */ +function amount(value) { + // 金额,只允许保留两位小数 + return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value) +} + +/** + * 中文 + */ +function chinese(value) { + const reg = /^[\u4e00-\u9fa5]+$/gi + return reg.test(value) +} + +/** + * 只能输入字母 + */ +function letter(value) { + return /^[a-zA-Z]*$/.test(value) +} + +/** + * 只能是字母或者数字 + */ +function enOrNum(value) { + // 英文或者数字 + const reg = /^[0-9a-zA-Z]*$/g + return reg.test(value) +} + +/** + * 验证是否包含某个值 + */ +function contains(value, param) { + return value.indexOf(param) >= 0 +} + +/** + * 验证一个值范围[min, max] + */ +function range(value, param) { + return value >= param[0] && value <= param[1] +} + +/** + * 验证一个长度范围[min, max] + */ +function rangeLength(value, param) { + return value.length >= param[0] && value.length <= param[1] +} + +/** + * 是否固定电话 + */ +function landline(value) { + const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/ + return reg.test(value) +} + +/** + * 判断是否为空 + */ +function empty(value) { + switch (typeof value) { + case 'undefined': + return true + case 'string': + if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true + break + case 'boolean': + if (!value) return true + break + case 'number': + if (value === 0 || isNaN(value)) return true + break + case 'object': + if (value === null || value.length === 0) return true + for (const i in value) { + return false + } + return true + } + return false +} + +/** + * 是否json字符串 + */ +function jsonString(value) { + if (typeof value === 'string') { + try { + const obj = JSON.parse(value) + if (typeof obj === 'object' && obj) { + return true + } + return false + } catch (e) { + return false + } + } + return false +} + +/** + * 是否数组 + */ +function array(value) { + if (typeof Array.isArray === 'function') { + return Array.isArray(value) + } + return Object.prototype.toString.call(value) === '[object Array]' +} + +/** + * 是否对象 + */ +function object(value) { + return Object.prototype.toString.call(value) === '[object Object]' +} + +/** + * 是否短信验证码 + */ +function code(value, len = 6) { + return new RegExp(`^\\d{${len}}$`).test(value) +} + +/** + * 是否函数方法 + * @param {Object} value + */ +function func(value) { + return typeof value === 'function' +} + +/** + * 是否promise对象 + * @param {Object} value + */ +function promise(value) { + return object(value) && func(value.then) && func(value.catch) +} + +/** 是否图片格式 + * @param {Object} value + */ +function image(value) { + const newValue = value.split('?')[0] + const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i + return IMAGE_REGEXP.test(newValue) +} + +/** + * 是否视频格式 + * @param {Object} value + */ +function video(value) { + const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i + return VIDEO_REGEXP.test(value) +} + +/** + * 是否为正则对象 + * @param {Object} + * @return {Boolean} + */ +function regExp(o) { + return o && Object.prototype.toString.call(o) === '[object RegExp]' +} + +export { + email, + mobile, + url, + date, + dateISO, + number, + digits, + idCard, + carNo, + amount, + chinese, + letter, + enOrNum, + contains, + range, + rangeLength, + empty, + jsonString, + landline, + object, + array, + code, + func, + promise, + video, + image, + regExp, + string +} diff --git a/src/uni_modules/uv-ui-tools/libs/function/throttle.js b/src/uni_modules/uv-ui-tools/libs/function/throttle.js new file mode 100644 index 0000000..2f33611 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/function/throttle.js @@ -0,0 +1,30 @@ +let timer; let + flag +/** + * 节流原理:在一定时间内,只能触发一次 + * + * @param {Function} func 要执行的回调函数 + * @param {Number} wait 延时的时间 + * @param {Boolean} immediate 是否立即执行 + * @return null + */ +function throttle(func, wait = 500, immediate = true) { + if (immediate) { + if (!flag) { + flag = true + // 如果是立即执行,则在wait毫秒内开始时执行 + typeof func === 'function' && func() + timer = setTimeout(() => { + flag = false + }, wait) + } + } else if (!flag) { + flag = true + // 如果是非立即执行,则在wait毫秒内的结束处执行 + timer = setTimeout(() => { + flag = false + typeof func === 'function' && func() + }, wait) + } +} +export default throttle diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js b/src/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js new file mode 100644 index 0000000..e03cf5f --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js @@ -0,0 +1,97 @@ +import buildURL from '../helpers/buildURL' +import buildFullPath from '../core/buildFullPath' +import settle from '../core/settle' +import { isUndefined } from '../utils' + +/** + * 返回可选值存在的配置 + * @param {Array} keys - 可选值数组 + * @param {Object} config2 - 配置 + * @return {{}} - 存在的配置项 + */ +const mergeKeys = (keys, config2) => { + const config = {} + keys.forEach((prop) => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } + }) + return config +} +export default (config) => new Promise((resolve, reject) => { + const fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params) + const _config = { + url: fullPath, + header: config.header, + complete: (response) => { + config.fullPath = fullPath + response.config = config + try { + // 对可能字符串不是json 的情况容错 + if (typeof response.data === 'string') { + response.data = JSON.parse(response.data) + } + // eslint-disable-next-line no-empty + } catch (e) { + } + settle(resolve, reject, response) + } + } + let requestTask + if (config.method === 'UPLOAD') { + delete _config.header['content-type'] + delete _config.header['Content-Type'] + const otherConfig = { + // #ifdef MP-ALIPAY + fileType: config.fileType, + // #endif + filePath: config.filePath, + name: config.name + } + const optionalKeys = [ + // #ifdef APP-PLUS || H5 + 'files', + // #endif + // #ifdef H5 + 'file', + // #endif + // #ifdef H5 || APP-PLUS + 'timeout', + // #endif + 'formData' + ] + requestTask = uni.uploadFile({ ..._config, ...otherConfig, ...mergeKeys(optionalKeys, config) }) + } else if (config.method === 'DOWNLOAD') { + // #ifdef H5 || APP-PLUS + if (!isUndefined(config.timeout)) { + _config.timeout = config.timeout + } + // #endif + requestTask = uni.downloadFile(_config) + } else { + const optionalKeys = [ + 'data', + 'method', + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + 'timeout', + // #endif + 'dataType', + // #ifndef MP-ALIPAY + 'responseType', + // #endif + // #ifdef APP-PLUS + 'sslVerify', + // #endif + // #ifdef H5 + 'withCredentials', + // #endif + // #ifdef APP-PLUS + 'firstIpv4' + // #endif + ] + requestTask = uni.request({ ..._config, ...mergeKeys(optionalKeys, config) }) + } + if (config.getTask) { + config.getTask(requestTask, config) + } +}) diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js b/src/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js new file mode 100644 index 0000000..3e8728d --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js @@ -0,0 +1,50 @@ +'use strict' + +function InterceptorManager() { + this.handlers = [] +} + +/** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ +InterceptorManager.prototype.use = function use(fulfilled, rejected) { + this.handlers.push({ + fulfilled, + rejected + }) + return this.handlers.length - 1 +} + +/** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + */ +InterceptorManager.prototype.eject = function eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null + } +} + +/** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + */ +InterceptorManager.prototype.forEach = function forEach(fn) { + this.handlers.forEach((h) => { + if (h !== null) { + fn(h) + } + }) +} + +export default InterceptorManager diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js b/src/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js new file mode 100644 index 0000000..cc48566 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js @@ -0,0 +1,198 @@ +/** + * @Class Request + * @description luch-request http请求插件 + * @version 3.0.7 + * @Author lu-ch + * @Date 2021-09-04 + * @Email webwork.s@qq.com + * 文档: https://www.quanzhan.co/luch-request/ + * github: https://github.com/lei-mu/luch-request + * DCloud: http://ext.dcloud.net.cn/plugin?id=392 + * HBuilderX: beat-3.0.4 alpha-3.0.4 + */ + +import dispatchRequest from './dispatchRequest' +import InterceptorManager from './InterceptorManager' +import mergeConfig from './mergeConfig' +import defaults from './defaults' +import { isPlainObject } from '../utils' +import clone from '../utils/clone' + +export default class Request { + /** + * @param {Object} arg - 全局配置 + * @param {String} arg.baseURL - 全局根路径 + * @param {Object} arg.header - 全局header + * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式 + * @param {String} arg.dataType = [json] - 全局默认的dataType + * @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持 + * @param {Object} arg.custom - 全局默认的自定义参数 + * @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序 + * @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+) + * @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+) + * @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+) + * @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300 + */ + constructor(arg = {}) { + if (!isPlainObject(arg)) { + arg = {} + console.warn('设置全局参数必须接收一个Object') + } + this.config = clone({ ...defaults, ...arg }) + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + } + } + + /** + * @Function + * @param {Request~setConfigCallback} f - 设置全局默认配置 + */ + setConfig(f) { + this.config = f(this.config) + } + + middleware(config) { + config = mergeConfig(this.config, config) + const chain = [dispatchRequest, undefined] + let promise = Promise.resolve(config) + + this.interceptors.request.forEach((interceptor) => { + chain.unshift(interceptor.fulfilled, interceptor.rejected) + }) + + this.interceptors.response.forEach((interceptor) => { + chain.push(interceptor.fulfilled, interceptor.rejected) + }) + + while (chain.length) { + promise = promise.then(chain.shift(), chain.shift()) + } + + return promise + } + + /** + * @Function + * @param {Object} config - 请求配置项 + * @prop {String} options.url - 请求路径 + * @prop {Object} options.data - 请求参数 + * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型 + * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse + * @prop {Object} [options.header = config.header] - 请求header + * @prop {Object} [options.method = config.method] - 请求方法 + * @returns {Promise} + */ + request(config = {}) { + return this.middleware(config) + } + + get(url, options = {}) { + return this.middleware({ + url, + method: 'GET', + ...options + }) + } + + post(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'POST', + ...options + }) + } + + // #ifndef MP-ALIPAY + put(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'PUT', + ...options + }) + } + + // #endif + + // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU + delete(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'DELETE', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN + connect(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'CONNECT', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN || MP-BAIDU + head(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'HEAD', + ...options + }) + } + + // #endif + + // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU + options(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'OPTIONS', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN + trace(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'TRACE', + ...options + }) + } + + // #endif + + upload(url, config = {}) { + config.url = url + config.method = 'UPLOAD' + return this.middleware(config) + } + + download(url, config = {}) { + config.url = url + config.method = 'DOWNLOAD' + return this.middleware(config) + } +} + +/** + * setConfig回调 + * @return {Object} - 返回操作后的config + * @callback Request~setConfigCallback + * @param {Object} config - 全局默认config + */ diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js b/src/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js new file mode 100644 index 0000000..5eb8a17 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js @@ -0,0 +1,20 @@ +'use strict' + +import isAbsoluteURL from '../helpers/isAbsoluteURL' +import combineURLs from '../helpers/combineURLs' + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * @returns {string} The combined full path + */ +export default function buildFullPath(baseURL, requestedURL) { + if (baseURL && !isAbsoluteURL(requestedURL)) { + return combineURLs(baseURL, requestedURL) + } + return requestedURL +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js b/src/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js new file mode 100644 index 0000000..be375a9 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js @@ -0,0 +1,29 @@ +/** + * 默认的全局配置 + */ + +export default { + baseURL: '', + header: {}, + method: 'GET', + dataType: 'json', + // #ifndef MP-ALIPAY + responseType: 'text', + // #endif + custom: {}, + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + timeout: 60000, + // #endif + // #ifdef APP-PLUS + sslVerify: true, + // #endif + // #ifdef H5 + withCredentials: false, + // #endif + // #ifdef APP-PLUS + firstIpv4: false, + // #endif + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300 + } +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js b/src/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js new file mode 100644 index 0000000..724545c --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js @@ -0,0 +1,3 @@ +import adapter from '../adapters/index' + +export default (config) => adapter(config) diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js b/src/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js new file mode 100644 index 0000000..08f8b9b --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js @@ -0,0 +1,103 @@ +import { deepMerge, isUndefined } from '../utils' + +/** + * 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局 + * @param {Array} keys - 配置项 + * @param {Object} globalsConfig - 当前的全局配置 + * @param {Object} config2 - 局部配置 + * @return {{}} + */ +const mergeKeys = (keys, globalsConfig, config2) => { + const config = {} + keys.forEach((prop) => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } else if (!isUndefined(globalsConfig[prop])) { + config[prop] = globalsConfig[prop] + } + }) + return config +} +/** + * + * @param globalsConfig - 当前实例的全局配置 + * @param config2 - 当前的局部配置 + * @return - 合并后的配置 + */ +export default (globalsConfig, config2 = {}) => { + const method = config2.method || globalsConfig.method || 'GET' + let config = { + baseURL: globalsConfig.baseURL || '', + method, + url: config2.url || '', + params: config2.params || {}, + custom: { ...(globalsConfig.custom || {}), ...(config2.custom || {}) }, + header: deepMerge(globalsConfig.header || {}, config2.header || {}) + } + const defaultToConfig2Keys = ['getTask', 'validateStatus'] + config = { ...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2) } + + // eslint-disable-next-line no-empty + if (method === 'DOWNLOAD') { + // #ifdef H5 || APP-PLUS + if (!isUndefined(config2.timeout)) { + config.timeout = config2.timeout + } else if (!isUndefined(globalsConfig.timeout)) { + config.timeout = globalsConfig.timeout + } + // #endif + } else if (method === 'UPLOAD') { + delete config.header['content-type'] + delete config.header['Content-Type'] + const uploadKeys = [ + // #ifdef APP-PLUS || H5 + 'files', + // #endif + // #ifdef MP-ALIPAY + 'fileType', + // #endif + // #ifdef H5 + 'file', + // #endif + 'filePath', + 'name', + // #ifdef H5 || APP-PLUS + 'timeout', + // #endif + 'formData' + ] + uploadKeys.forEach((prop) => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } + }) + // #ifdef H5 || APP-PLUS + if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) { + config.timeout = globalsConfig.timeout + } + // #endif + } else { + const defaultsKeys = [ + 'data', + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + 'timeout', + // #endif + 'dataType', + // #ifndef MP-ALIPAY + 'responseType', + // #endif + // #ifdef APP-PLUS + 'sslVerify', + // #endif + // #ifdef H5 + 'withCredentials', + // #endif + // #ifdef APP-PLUS + 'firstIpv4' + // #endif + ] + config = { ...config, ...mergeKeys(defaultsKeys, globalsConfig, config2) } + } + + return config +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js b/src/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js new file mode 100644 index 0000000..8d3638f --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js @@ -0,0 +1,16 @@ +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + */ +export default function settle(resolve, reject, response) { + const { validateStatus } = response.config + const status = response.statusCode + if (status && (!validateStatus || validateStatus(status))) { + resolve(response) + } else { + reject(response) + } +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js b/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js new file mode 100644 index 0000000..472ad6a --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js @@ -0,0 +1,69 @@ +'use strict' + +import * as utils from '../utils' + +function encode(val) { + return encodeURIComponent(val) + .replace(/%40/gi, '@') + .replace(/%3A/gi, ':') + .replace(/%24/g, '$') + .replace(/%2C/gi, ',') + .replace(/%20/g, '+') + .replace(/%5B/gi, '[') + .replace(/%5D/gi, ']') +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @returns {string} The formatted url + */ +export default function buildURL(url, params) { + /* eslint no-param-reassign:0 */ + if (!params) { + return url + } + + let serializedParams + if (utils.isURLSearchParams(params)) { + serializedParams = params.toString() + } else { + const parts = [] + + utils.forEach(params, (val, key) => { + if (val === null || typeof val === 'undefined') { + return + } + + if (utils.isArray(val)) { + key = `${key}[]` + } else { + val = [val] + } + + utils.forEach(val, (v) => { + if (utils.isDate(v)) { + v = v.toISOString() + } else if (utils.isObject(v)) { + v = JSON.stringify(v) + } + parts.push(`${encode(key)}=${encode(v)}`) + }) + }) + + serializedParams = parts.join('&') + } + + if (serializedParams) { + const hashmarkIndex = url.indexOf('#') + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex) + } + + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams + } + + return url +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js b/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js new file mode 100644 index 0000000..ac7c124 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js @@ -0,0 +1,14 @@ +'use strict' + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * @returns {string} The combined URL + */ +export default function combineURLs(baseURL, relativeURL) { + return relativeURL + ? `${baseURL.replace(/\/+$/, '')}/${relativeURL.replace(/^\/+/, '')}` + : baseURL +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js b/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js new file mode 100644 index 0000000..63c6647 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js @@ -0,0 +1,14 @@ +'use strict' + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +export default function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url) +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts b/src/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts new file mode 100644 index 0000000..e939ce1 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts @@ -0,0 +1,116 @@ +type AnyObject = Record +type HttpPromise = Promise>; +type Tasks = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask +export interface RequestTask { + abort: () => void; + offHeadersReceived: () => void; + onHeadersReceived: () => void; +} +export interface HttpRequestConfig { + /** 请求基地址 */ + baseURL?: string; + /** 请求服务器接口地址 */ + url?: string; + + /** 请求查询参数,自动拼接为查询字符串 */ + params?: AnyObject; + /** 请求体参数 */ + data?: AnyObject; + + /** 文件对应的 key */ + name?: string; + /** HTTP 请求中其他额外的 form data */ + formData?: AnyObject; + /** 要上传文件资源的路径。 */ + filePath?: string; + /** 需要上传的文件列表。使用 files 时,filePath 和 name 不生效,App、H5( 2.6.15+) */ + files?: Array<{ + name?: string; + file?: File; + uri: string; + }>; + /** 要上传的文件对象,仅H5(2.6.15+)支持 */ + file?: File; + + /** 请求头信息 */ + header?: AnyObject; + /** 请求方式 */ + method?: "GET" | "POST" | "PUT" | "DELETE" | "CONNECT" | "HEAD" | "OPTIONS" | "TRACE" | "UPLOAD" | "DOWNLOAD"; + /** 如果设为 json,会尝试对返回的数据做一次 JSON.parse */ + dataType?: string; + /** 设置响应的数据类型,支付宝小程序不支持 */ + responseType?: "text" | "arraybuffer"; + /** 自定义参数 */ + custom?: AnyObject; + /** 超时时间,仅微信小程序(2.10.0)、支付宝小程序支持 */ + timeout?: number; + /** DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+) */ + firstIpv4?: boolean; + /** 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+) */ + sslVerify?: boolean; + /** 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+) */ + withCredentials?: boolean; + + /** 返回当前请求的task, options。请勿在此处修改options。 */ + getTask?: (task: T, options: HttpRequestConfig) => void; + /** 全局自定义验证器 */ + validateStatus?: (statusCode: number) => boolean | void; +} +export interface HttpResponse { + config: HttpRequestConfig; + statusCode: number; + cookies: Array; + data: T; + errMsg: string; + header: AnyObject; +} +export interface HttpUploadResponse { + config: HttpRequestConfig; + statusCode: number; + data: T; + errMsg: string; +} +export interface HttpDownloadResponse extends HttpResponse { + tempFilePath: string; +} +export interface HttpError { + config: HttpRequestConfig; + statusCode?: number; + cookies?: Array; + data?: any; + errMsg: string; + header?: AnyObject; +} +export interface HttpInterceptorManager { + use( + onFulfilled?: (config: V) => Promise | V, + onRejected?: (config: E) => Promise | E + ): void; + eject(id: number): void; +} +export abstract class HttpRequestAbstract { + constructor(config?: HttpRequestConfig); + config: HttpRequestConfig; + interceptors: { + request: HttpInterceptorManager; + response: HttpInterceptorManager; + } + middleware(config: HttpRequestConfig): HttpPromise; + request(config: HttpRequestConfig): HttpPromise; + get(url: string, config?: HttpRequestConfig): HttpPromise; + upload(url: string, config?: HttpRequestConfig): HttpPromise; + delete(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + head(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + post(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + put(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + connect(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + options(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + trace(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + + download(url: string, config?: HttpRequestConfig): Promise; + + setConfig(onSend: (config: HttpRequestConfig) => HttpRequestConfig): void; +} + +declare class HttpRequest extends HttpRequestAbstract { } +export default HttpRequest; diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/index.js b/src/uni_modules/uv-ui-tools/libs/luch-request/index.js new file mode 100644 index 0000000..8fb2b44 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/index.js @@ -0,0 +1,3 @@ +import Request from './core/Request' + +export default Request diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/utils.js b/src/uni_modules/uv-ui-tools/libs/luch-request/utils.js new file mode 100644 index 0000000..847283d --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/utils.js @@ -0,0 +1,131 @@ +'use strict' + +// utils is a library of generic helper functions non-specific to axios + +const { toString } = Object.prototype + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Array, otherwise false + */ +export function isArray(val) { + return toString.call(val) === '[object Array]' +} + +/** + * Determine if a value is an Object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Object, otherwise false + */ +export function isObject(val) { + return val !== null && typeof val === 'object' +} + +/** + * Determine if a value is a Date + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Date, otherwise false + */ +export function isDate(val) { + return toString.call(val) === '[object Date]' +} + +/** + * Determine if a value is a URLSearchParams object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +export function isURLSearchParams(val) { + return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams +} + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + */ +export function forEach(obj, fn) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return + } + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /* eslint no-param-reassign:0 */ + obj = [obj] + } + + if (isArray(obj)) { + // Iterate over array values + for (let i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj) + } + } else { + // Iterate over object keys + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + fn.call(null, obj[key], key, obj) + } + } + } +} + +/** + * 是否为boolean 值 + * @param val + * @returns {boolean} + */ +export function isBoolean(val) { + return typeof val === 'boolean' +} + +/** + * 是否为真正的对象{} new Object + * @param {any} obj - 检测的对象 + * @returns {boolean} + */ +export function isPlainObject(obj) { + return Object.prototype.toString.call(obj) === '[object Object]' +} + +/** + * Function equal to merge with the difference being that no reference + * to original objects is kept. + * + * @see merge + * @param {Object} obj1 Object to merge + * @returns {Object} Result of all merge properties + */ +export function deepMerge(/* obj1, obj2, obj3, ... */) { + const result = {} + function assignValue(val, key) { + if (typeof result[key] === 'object' && typeof val === 'object') { + result[key] = deepMerge(result[key], val) + } else if (typeof val === 'object') { + result[key] = deepMerge({}, val) + } else { + result[key] = val + } + } + for (let i = 0, l = arguments.length; i < l; i++) { + forEach(arguments[i], assignValue) + } + return result +} + +export function isUndefined(val) { + return typeof val === 'undefined' +} diff --git a/src/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js b/src/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js new file mode 100644 index 0000000..2fee704 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js @@ -0,0 +1,264 @@ +/* eslint-disable */ +var clone = (function() { + 'use strict'; + + function _instanceof(obj, type) { + return type != null && obj instanceof type; + } + + var nativeMap; + try { + nativeMap = Map; + } catch(_) { + // maybe a reference error because no `Map`. Give it a dummy value that no + // value will ever be an instanceof. + nativeMap = function() {}; + } + + var nativeSet; + try { + nativeSet = Set; + } catch(_) { + nativeSet = function() {}; + } + + var nativePromise; + try { + nativePromise = Promise; + } catch(_) { + nativePromise = function() {}; + } + + /** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). + * @param `includeNonEnumerable` - set to true if the non-enumerable properties + * should be cloned as well. Non-enumerable properties on the prototype + * chain will be ignored. (optional - false by default) + */ + function clone(parent, circular, depth, prototype, includeNonEnumerable) { + if (typeof circular === 'object') { + depth = circular.depth; + prototype = circular.prototype; + includeNonEnumerable = circular.includeNonEnumerable; + circular = circular.circular; + } + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular == 'undefined') + circular = true; + + if (typeof depth == 'undefined') + depth = Infinity; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + + if (depth === 0) + return parent; + + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + + if (_instanceof(parent, nativeMap)) { + child = new nativeMap(); + } else if (_instanceof(parent, nativeSet)) { + child = new nativeSet(); + } else if (_instanceof(parent, nativePromise)) { + child = new nativePromise(function (resolve, reject) { + parent.then(function(value) { + resolve(_clone(value, depth - 1)); + }, function(err) { + reject(_clone(err, depth - 1)); + }); + }); + } else if (clone.__isArray(parent)) { + child = []; + } else if (clone.__isRegExp(parent)) { + child = new RegExp(parent.source, __getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (clone.__isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + if (Buffer.from) { + // Node.js >= 5.10.0 + child = Buffer.from(parent); + } else { + // Older Node.js versions + child = new Buffer(parent.length); + parent.copy(child); + } + return child; + } else if (_instanceof(parent, Error)) { + child = Object.create(parent); + } else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + if (_instanceof(parent, nativeMap)) { + parent.forEach(function(value, key) { + var keyChild = _clone(key, depth - 1); + var valueChild = _clone(value, depth - 1); + child.set(keyChild, valueChild); + }); + } + if (_instanceof(parent, nativeSet)) { + parent.forEach(function(value) { + var entryChild = _clone(value, depth - 1); + child.add(entryChild); + }); + } + + for (var i in parent) { + var attrs = Object.getOwnPropertyDescriptor(parent, i); + if (attrs) { + child[i] = _clone(parent[i], depth - 1); + } + + try { + var objProperty = Object.getOwnPropertyDescriptor(parent, i); + if (objProperty.set === 'undefined') { + // no setter defined. Skip cloning this property + continue; + } + child[i] = _clone(parent[i], depth - 1); + } catch(e){ + if (e instanceof TypeError) { + // when in strict mode, TypeError will be thrown if child[i] property only has a getter + // we can't do anything about this, other than inform the user that this property cannot be set. + continue + } else if (e instanceof ReferenceError) { + //this may happen in non strict mode + continue + } + } + + } + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(parent); + for (var i = 0; i < symbols.length; i++) { + // Don't need to worry about cloning a symbol because it is a primitive, + // like a number or string. + var symbol = symbols[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); + if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { + continue; + } + child[symbol] = _clone(parent[symbol], depth - 1); + Object.defineProperty(child, symbol, descriptor); + } + } + + if (includeNonEnumerable) { + var allPropertyNames = Object.getOwnPropertyNames(parent); + for (var i = 0; i < allPropertyNames.length; i++) { + var propertyName = allPropertyNames[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); + if (descriptor && descriptor.enumerable) { + continue; + } + child[propertyName] = _clone(parent[propertyName], depth - 1); + Object.defineProperty(child, propertyName, descriptor); + } + } + + return child; + } + + return _clone(parent, depth); + } + + /** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ + clone.clonePrototype = function clonePrototype(parent) { + if (parent === null) + return null; + + var c = function () {}; + c.prototype = parent; + return new c(); + }; + +// private utility functions + + function __objToStr(o) { + return Object.prototype.toString.call(o); + } + clone.__objToStr = __objToStr; + + function __isDate(o) { + return typeof o === 'object' && __objToStr(o) === '[object Date]'; + } + clone.__isDate = __isDate; + + function __isArray(o) { + return typeof o === 'object' && __objToStr(o) === '[object Array]'; + } + clone.__isArray = __isArray; + + function __isRegExp(o) { + return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; + } + clone.__isRegExp = __isRegExp; + + function __getRegExpFlags(re) { + var flags = ''; + if (re.global) flags += 'g'; + if (re.ignoreCase) flags += 'i'; + if (re.multiline) flags += 'm'; + return flags; + } + clone.__getRegExpFlags = __getRegExpFlags; + + return clone; +})(); + +export default clone diff --git a/src/uni_modules/uv-ui-tools/libs/mixin/button.js b/src/uni_modules/uv-ui-tools/libs/mixin/button.js new file mode 100644 index 0000000..0c019c2 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/mixin/button.js @@ -0,0 +1,13 @@ +export default { + props: { + lang: String, + sessionFrom: String, + sendMessageTitle: String, + sendMessagePath: String, + sendMessageImg: String, + showMessageCard: Boolean, + appParameter: String, + formType: String, + openType: String + } +} diff --git a/src/uni_modules/uv-ui-tools/libs/mixin/mixin.js b/src/uni_modules/uv-ui-tools/libs/mixin/mixin.js new file mode 100644 index 0000000..6ec3c9e --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/mixin/mixin.js @@ -0,0 +1,152 @@ +import * as index from '../function/index.js'; +import * as test from '../function/test.js'; +export default { + // 定义每个组件都可能需要用到的外部样式以及类名 + props: { + // 每个组件都有的父组件传递的样式,可以为字符串或者对象形式 + customStyle: { + type: [Object, String], + default: () => ({}) + }, + customClass: { + type: String, + default: '' + }, + // 跳转的页面路径 + url: { + type: String, + default: '' + }, + // 页面跳转的类型 + linkType: { + type: String, + default: 'navigateTo' + } + }, + data() { + return {} + }, + onLoad() { + // getRect挂载到$uv上,因为这方法需要使用in(this),所以无法把它独立成一个单独的文件导出 + this.$uv.getRect = this.$uvGetRect + }, + created() { + // 组件当中,只有created声明周期,为了能在组件使用,故也在created中将方法挂载到$uv + this.$uv.getRect = this.$uvGetRect + }, + computed: { + $uv() { + return { + ...index, + test + } + }, + /** + * 生成bem规则类名 + * 由于微信小程序,H5,nvue之间绑定class的差异,无法通过:class="[bem()]"的形式进行同用 + * 故采用如下折中做法,最后返回的是数组(一般平台)或字符串(支付宝和字节跳动平台),类似['a', 'b', 'c']或'a b c'的形式 + * @param {String} name 组件名称 + * @param {Array} fixed 一直会存在的类名 + * @param {Array} change 会根据变量值为true或者false而出现或者隐藏的类名 + * @returns {Array|string} + */ + bem() { + return function(name, fixed, change) { + // 类名前缀 + const prefix = `uv-${name}--` + const classes = {} + if (fixed) { + fixed.map((item) => { + // 这里的类名,会一直存在 + classes[prefix + this[item]] = true + }) + } + if (change) { + change.map((item) => { + // 这里的类名,会根据this[item]的值为true或者false,而进行添加或者移除某一个类 + this[item] ? (classes[prefix + item] = this[item]) : (delete classes[prefix + item]) + }) + } + return Object.keys(classes) + // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效 + // #ifdef MP-ALIPAY || MP-TOUTIAO || MP-LARK || MP-BAIDU + .join(' ') + // #endif + } + } + }, + methods: { + // 跳转某一个页面 + openPage(urlKey = 'url') { + const url = this[urlKey] + if (url) { + // 执行类似uni.navigateTo的方法 + uni[this.linkType]({ + url + }) + } + }, + // 查询节点信息 + // 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21) + // 解决办法为在组件根部再套一个没有任何作用的view元素 + $uvGetRect(selector, all) { + return new Promise((resolve) => { + uni.createSelectorQuery() + .in(this)[all ? 'selectAll' : 'select'](selector) + .boundingClientRect((rect) => { + if (all && Array.isArray(rect) && rect.length) { + resolve(rect) + } + if (!all && rect) { + resolve(rect) + } + }) + .exec() + }) + }, + getParentData(parentName = '') { + // 避免在created中去定义parent变量 + if (!this.parent) this.parent = {} + // 这里的本质原理是,通过获取父组件实例(也即类似uv-radio的父组件uv-radio-group的this) + // 将父组件this中对应的参数,赋值给本组件(uv-radio的this)的parentData对象中对应的属性 + // 之所以需要这么做,是因为所有端中,头条小程序不支持通过this.parent.xxx去监听父组件参数的变化 + // 此处并不会自动更新子组件的数据,而是依赖父组件uv-radio-group去监听data的变化,手动调用更新子组件的方法去重新获取 + this.parent = this.$uv.$parent.call(this, parentName) + if (this.parent.children) { + // 如果父组件的children不存在本组件的实例,才将本实例添加到父组件的children中 + this.parent.children.indexOf(this) === -1 && this.parent.children.push(this) + } + if (this.parent && this.parentData) { + // 历遍parentData中的属性,将parent中的同名属性赋值给parentData + Object.keys(this.parentData).map((key) => { + this.parentData[key] = this.parent[key] + }) + } + }, + // 阻止事件冒泡 + preventEvent(e) { + e && typeof(e.stopPropagation) === 'function' && e.stopPropagation() + }, + // 空操作 + noop(e) { + this.preventEvent(e) + } + }, + onReachBottom() { + uni.$emit('uvOnReachBottom') + }, + beforeDestroy() { + // 判断当前页面是否存在parent和chldren,一般在checkbox和checkbox-group父子联动的场景会有此情况 + // 组件销毁时,移除子组件在父组件children数组中的实例,释放资源,避免数据混乱 + if (this.parent && test.array(this.parent.children)) { + // 组件销毁时,移除父组件中的children数组中对应的实例 + const childrenList = this.parent.children + childrenList.map((child, index) => { + // 如果相等,则移除 + if (child === this) { + childrenList.splice(index, 1) + } + }) + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js b/src/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js new file mode 100644 index 0000000..90b6903 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js @@ -0,0 +1,8 @@ +export default { + // #ifdef MP-WEIXIN + // 将自定义节点设置成虚拟的(去掉自定义组件包裹层),更加接近Vue组件的表现,能更好的使用flex属性 + options: { + virtualHost: true + } + // #endif +} \ No newline at end of file diff --git a/src/uni_modules/uv-ui-tools/libs/mixin/mpShare.js b/src/uni_modules/uv-ui-tools/libs/mixin/mpShare.js new file mode 100644 index 0000000..c9695a0 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/mixin/mpShare.js @@ -0,0 +1,13 @@ +export default { + onLoad() { + // 设置默认的转发参数 + uni.$uv.mpShare = { + title: '', // 默认为小程序名称 + path: '', // 默认为当前页面路径 + imageUrl: '' // 默认为当前页面的截图 + } + }, + onShareAppMessage() { + return uni.$uv.mpShare + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-ui-tools/libs/mixin/openType.js b/src/uni_modules/uv-ui-tools/libs/mixin/openType.js new file mode 100644 index 0000000..e6ffe3d --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/mixin/openType.js @@ -0,0 +1,44 @@ +export default { + props: { + openType: String + }, + emits: ['getphonenumber','getuserinfo','error','opensetting','launchapp','contact','chooseavatar','addgroupapp','chooseaddress','subscribe','login','im'], + methods: { + onGetPhoneNumber(event) { + this.$emit('getphonenumber', event.detail) + }, + onGetUserInfo(event) { + this.$emit('getuserinfo', event.detail) + }, + onError(event) { + this.$emit('error', event.detail) + }, + onOpenSetting(event) { + this.$emit('opensetting', event.detail) + }, + onLaunchApp(event) { + this.$emit('launchapp', event.detail) + }, + onContact(event) { + this.$emit('contact', event.detail) + }, + onChooseavatar(event) { + this.$emit('chooseavatar', event.detail) + }, + onAddgroupapp(event) { + this.$emit('addgroupapp', event.detail) + }, + onChooseaddress(event) { + this.$emit('chooseaddress', event.detail) + }, + onSubscribe(event) { + this.$emit('subscribe', event.detail) + }, + onLogin(event) { + this.$emit('login', event.detail) + }, + onIm(event) { + this.$emit('im', event.detail) + } + } +} diff --git a/src/uni_modules/uv-ui-tools/libs/mixin/touch.js b/src/uni_modules/uv-ui-tools/libs/mixin/touch.js new file mode 100644 index 0000000..0ecbd88 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/mixin/touch.js @@ -0,0 +1,59 @@ +const MIN_DISTANCE = 10 + +function getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal' + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical' + } + return '' +} + +export default { + methods: { + getTouchPoint(e) { + if (!e) { + return { + x: 0, + y: 0 + } + } if (e.touches && e.touches[0]) { + return { + x: e.touches[0].pageX, + y: e.touches[0].pageY + } + } if (e.changedTouches && e.changedTouches[0]) { + return { + x: e.changedTouches[0].pageX, + y: e.changedTouches[0].pageY + } + } + return { + x: e.clientX || 0, + y: e.clientY || 0 + } + }, + resetTouchStatus() { + this.direction = '' + this.deltaX = 0 + this.deltaY = 0 + this.offsetX = 0 + this.offsetY = 0 + }, + touchStart(event) { + this.resetTouchStatus() + const touch = this.getTouchPoint(event) + this.startX = touch.x + this.startY = touch.y + }, + touchMove(event) { + const touch = this.getTouchPoint(event) + this.deltaX = touch.x - this.startX + this.deltaY = touch.y - this.startY + this.offsetX = Math.abs(this.deltaX) + this.offsetY = Math.abs(this.deltaY) + this.direction = this.direction || getDirection(this.offsetX, this.offsetY) + } + } +} diff --git a/src/uni_modules/uv-ui-tools/libs/util/dayjs.js b/src/uni_modules/uv-ui-tools/libs/util/dayjs.js new file mode 100644 index 0000000..76ab4e8 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/util/dayjs.js @@ -0,0 +1,218 @@ +var __getOwnPropNames = Object.getOwnPropertyNames; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; + +// C:/Users/LP/Downloads/uvui-plus_3.1.27_example/node_modules/dayjs/dayjs.min.js +var require_dayjs_min = __commonJS({ + "C:/Users/LP/Downloads/uvui-plus_3.1.27_example/node_modules/dayjs/dayjs.min.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", f = "month", h = "quarter", c = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, f), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), f); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: f, y: c, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: h }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = function(t2) { + return t2 instanceof _; + }, S = function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, w = function(t2, e2) { + if (p(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, O = v; + O.l = S, O.i = p, O.w = function(t2, e2) { + return w(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = S(t2.locale, null, true), this.parse(t2); + } + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return new Date(NaN); + if (O.u(e2)) + return new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.$x = t2.x || {}, this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return O; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = w(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return w(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < w(t2); + }, m2.$g = function(t2, e2, n2) { + return O.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!O.u(e2) || e2, h2 = O.p(t2), l2 = function(t3, e3) { + var i2 = O.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, $2 = function(t3, e3) { + return O.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (h2) { + case c: + return r2 ? l2(1, 0) : l2(31, 11); + case f: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = O.p(t2), h2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = h2 + "Date", n2[d] = h2 + "Date", n2[f] = h2 + "Month", n2[c] = h2 + "FullYear", n2[u] = h2 + "Hours", n2[s] = h2 + "Minutes", n2[i] = h2 + "Seconds", n2[r] = h2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === f || o2 === c) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[O.p(t2)](); + }, m2.add = function(r2, h2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = O.p(h2), y2 = function(t2) { + var e2 = w(l2); + return O.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }; + if ($2 === f) + return this.set(f, this.$M + r2); + if ($2 === c) + return this.set(c, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return O.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = O.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, f2 = n2.months, h2 = function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, c2 = function(t3) { + return O.s(s2 % 12 || 12, t3, "0"); + }, d2 = n2.meridiem || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }, $2 = { YY: String(this.$y).slice(-2), YYYY: this.$y, M: a2 + 1, MM: O.s(a2 + 1, 2, "0"), MMM: h2(n2.monthsShort, a2, f2, 3), MMMM: h2(f2, a2), D: this.$D, DD: O.s(this.$D, 2, "0"), d: String(this.$W), dd: h2(n2.weekdaysMin, this.$W, o2, 2), ddd: h2(n2.weekdaysShort, this.$W, o2, 3), dddd: o2[this.$W], H: String(s2), HH: O.s(s2, 2, "0"), h: c2(1), hh: c2(2), a: d2(s2, u2, true), A: d2(s2, u2, false), m: String(u2), mm: O.s(u2, 2, "0"), s: String(this.$s), ss: O.s(this.$s, 2, "0"), SSS: O.s(this.$ms, 3, "0"), Z: i2 }; + return r2.replace(y, function(t3, e3) { + return e3 || $2[t3] || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = O.p(d2), M3 = w(r2), m3 = (M3.utcOffset() - this.utcOffset()) * e, v2 = this - M3, g2 = O.m(this, M3); + return g2 = ($2 = {}, $2[c] = g2 / 12, $2[f] = g2, $2[h] = g2 / 3, $2[o] = (v2 - m3) / 6048e5, $2[a] = (v2 - m3) / 864e5, $2[u] = v2 / n, $2[s] = v2 / e, $2[i] = v2 / t, $2)[y2] || v2, l2 ? g2 : O.a(g2); + }, m2.daysInMonth = function() { + return this.endOf(f).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = S(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return O.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), T = _.prototype; + return w.prototype = T, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", f], ["$y", c], ["$D", d]].forEach(function(t2) { + T[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), w.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, w), t2.$i = true), w; + }, w.locale = S, w.isDayjs = p, w.unix = function(t2) { + return w(1e3 * t2); + }, w.en = D[g], w.Ls = D, w.p = {}, w; + }); + } +}); +export default require_dayjs_min(); +//# sourceMappingURL=dayjs.js.map diff --git a/src/uni_modules/uv-ui-tools/libs/util/route.js b/src/uni_modules/uv-ui-tools/libs/util/route.js new file mode 100644 index 0000000..2d0c9c1 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/libs/util/route.js @@ -0,0 +1,124 @@ +/** + * 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷 + * 并且带有路由拦截功能 + */ + import { queryParams, deepMerge,page } from '@/uni_modules/uv-ui-tools/libs/function/index.js' +class Router { + constructor() { + // 原始属性定义 + this.config = { + type: 'navigateTo', + url: '', + delta: 1, // navigateBack页面后退时,回退的层数 + params: {}, // 传递的参数 + animationType: 'pop-in', // 窗口动画,只在APP有效 + animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效 + intercept: false // 是否需要拦截 + } + // 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文 + // 这里在构造函数中进行this绑定 + this.route = this.route.bind(this) + } + + // 判断url前面是否有"/",如果没有则加上,否则无法跳转 + addRootPath(url) { + return url[0] === '/' ? url : `/${url}` + } + + // 整合路由参数 + mixinParam(url, params) { + url = url && this.addRootPath(url) + + // 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary" + // 如果有url中有get参数,转换后无需带上"?" + let query = '' + if (/.*\/.*\?.*=.*/.test(url)) { + // object对象转为get类型的参数 + query = queryParams(params, false) + // 因为已有get参数,所以后面拼接的参数需要带上"&"隔开 + return url += `&${query}` + } + // 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号 + query = queryParams(params) + return url += query + } + + // 对外的方法名称 + async route(options = {}, params = {}) { + // 合并用户的配置和内部的默认配置 + let mergeConfig = {} + + if (typeof options === 'string') { + // 如果options为字符串,则为route(url, params)的形式 + mergeConfig.url = this.mixinParam(options, params) + mergeConfig.type = 'navigateTo' + } else { + mergeConfig = deepMerge(this.config, options) + // 否则正常使用mergeConfig中的url和params进行拼接 + mergeConfig.url = this.mixinParam(options.url, options.params) + } + + // 如果本次跳转的路径和本页面路径一致,不执行跳转,防止用户快速点击跳转按钮,造成多次跳转同一个页面的问题 + if (mergeConfig.url === page()) return + + if (params.intercept) { + this.config.intercept = params.intercept + } + // params参数也带给拦截器 + mergeConfig.params = params + // 合并内外部参数 + mergeConfig = deepMerge(this.config, mergeConfig) + // 判断用户是否定义了拦截器 + if (typeof routeIntercept === 'function') { + // 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转 + const isNext = await new Promise((resolve, reject) => { + routeIntercept(mergeConfig, resolve) + }) + // 如果isNext为true,则执行路由跳转 + isNext && this.openPage(mergeConfig) + } else { + this.openPage(mergeConfig) + } + } + + // 执行路由跳转 + openPage(config) { + // 解构参数 + const { + url, + type, + delta, + animationType, + animationDuration + } = config + if (config.type == 'navigateTo' || config.type == 'to') { + uni.navigateTo({ + url, + animationType, + animationDuration + }) + } + if (config.type == 'redirectTo' || config.type == 'redirect') { + uni.redirectTo({ + url + }) + } + if (config.type == 'switchTab' || config.type == 'tab') { + uni.switchTab({ + url + }) + } + if (config.type == 'reLaunch' || config.type == 'launch') { + uni.reLaunch({ + url + }) + } + if (config.type == 'navigateBack' || config.type == 'back') { + uni.navigateBack({ + delta + }) + } + } +} + +export default (new Router()).route diff --git a/src/uni_modules/uv-ui-tools/package.json b/src/uni_modules/uv-ui-tools/package.json new file mode 100644 index 0000000..65644b3 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/package.json @@ -0,0 +1,81 @@ +{ + "id": "uv-ui-tools", + "displayName": "uv-ui-tools 工具集 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.9", + "description": "uv-ui-tools,集成工具库,强大的Http请求封装,清晰的文档说明,开箱即用。方便使用,可以全局使用", + "keywords": [ + "uv-ui-tools,uv-ui,uv,ui,uview" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y", + "钉钉": "y", + "快手": "y", + "飞书": "y", + "京东": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + } + } + } + } +} \ No newline at end of file diff --git a/src/uni_modules/uv-ui-tools/readme.md b/src/uni_modules/uv-ui-tools/readme.md new file mode 100644 index 0000000..9307df4 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/readme.md @@ -0,0 +1,13 @@ +## uv-ui-tools 工具集 + +> **组件名:uv-ui-tools** + +uv-ui 工具集成,包括网络Http请求、便捷工具、节流防抖、对象操作、时间格式化、路由跳转、全局唯一标识符、规则校验等等。 + +需要在自己的项目中使用请参考[扩展配置](https://www.uvui.cn/components/setting.html)。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/src/uni_modules/uv-ui-tools/theme.scss b/src/uni_modules/uv-ui-tools/theme.scss new file mode 100644 index 0000000..cfaae92 --- /dev/null +++ b/src/uni_modules/uv-ui-tools/theme.scss @@ -0,0 +1,43 @@ +// 此文件为uvUI的主题变量,这些变量目前只能通过uni.scss引入才有效,另外由于 +// uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中,造成微信程序包太大, +// 故uni.scss只建议放scss变量名相关样式,其他的样式可以通过main.js或者App.vue引入 + +$uv-main-color: #303133; +$uv-content-color: #606266; +$uv-tips-color: #909193; +$uv-light-color: #c0c4cc; +$uv-border-color: #dadbde; +$uv-bg-color: #f3f4f6; +$uv-disabled-color: #c8c9cc; + +$uv-primary: #3c9cff; +$uv-primary-dark: #398ade; +$uv-primary-disabled: #9acafc; +$uv-primary-light: #ecf5ff; + +$uv-warning: #f9ae3d; +$uv-warning-dark: #f1a532; +$uv-warning-disabled: #f9d39b; +$uv-warning-light: #fdf6ec; + +$uv-success: #5ac725; +$uv-success-dark: #53c21d; +$uv-success-disabled: #a9e08f; +$uv-success-light: #f5fff0; + +$uv-error: #f56c6c; +$uv-error-dark: #e45656; +$uv-error-disabled: #f7b2b2; +$uv-error-light: #fef0f0; + +$uv-info: #909399; +$uv-info-dark: #767a82; +$uv-info-disabled: #c4c6c9; +$uv-info-light: #f4f4f5; + +@mixin flex($direction: row) { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: $direction; +} \ No newline at end of file diff --git a/src/utils/bluetoothPrinter/bluetooth.js b/src/utils/bluetoothPrinter/bluetooth.js new file mode 100644 index 0000000..cbc63a4 --- /dev/null +++ b/src/utils/bluetoothPrinter/bluetooth.js @@ -0,0 +1,281 @@ +import { store } from "@/store" +import { getStorage } from "../storage" +import toast from "../toast" + +const connectVoid = uni.createInnerAudioContext() +class Bluetooth { + + constructor() { + this.isOpenBle = false + this.deviceId = "" + this.serviceId = "" + this.writeId = "" + this.notifyId = "" + this.openBluetoothAdapter() + } + //初始化蓝牙模块,检查蓝牙是否已打开 + openBluetoothAdapter() { + return new Promise((resolve, reject) => { + uni.openBluetoothAdapter({ + success: res => { + this.isOpenBle = true + resolve(res) + }, + fail: err => { + // reject('请打开蓝牙和定位功能') + console.log('蓝牙错误-请打开蓝牙-bluetooth.js') + }, + }) + }) + } + //搜索周边蓝牙设备 + startBluetoothDevicesDiscovery() { + if (!this.isOpenBle) { + toast('请打开蓝牙和定位功能') + return + } + + let self = this + return new Promise((resolve, reject) => { + setTimeout(() => { + uni.startBluetoothDevicesDiscovery({ + success: res => { + resolve(res) + }, + fail: res => { + reject('搜索设备失败') + } + }) + }, 300) + }) + } + // 搜索附近连接上或没有连接上的设备 + getBluetoothDevices() { + return new Promise((resolve, reject) => { + uni.getBluetoothDevices({ + success(res) { + resolve(res) + }, + fail(error) { + reject('搜索失败') + } + }) + }) + } + //停止搜索周报蓝牙设备 + stopBluetoothDevicesDiscovery() { + let self = this + return new Promise((resolve, reject) => { + uni.stopBluetoothDevicesDiscovery({ + success: e => { + uni.hideLoading() + }, + fail: e => { + uni.hideLoading() + toast('停止搜索失败,请重试') + } + }) + }) + } + //连接设备 + createBLEConnection() { + let deviceId = this.deviceId + let self = this + + return new Promise((resolve, reject) => { + uni.createBLEConnection({ + deviceId, + success: (res) => { + resolve(res) + }, + fail: err => { + reject(err) + } + }) + }); + } + + //获取蓝牙设备所有服务(service) + getBLEDeviceServices() { + let _serviceList = [] + let deviceId = this.deviceId + let self = this + + return new Promise((resolve, reject) => { + setTimeout(() => { + uni.getBLEDeviceServices({ + deviceId, + success: res => { + for (let service of res.services) { + if (service.isPrimary) { + _serviceList.push(service) + } + } + if (res.services.length <= 0) { + showToast('成功获取服务,但没有可用服务') + } + + resolve(_serviceList) + }, + fail: err => { + //设备已连接,但未能获取设备服务,也有可能连接处于断开状态 + toast('未获取蓝牙设备相关服务') + reject(err) + }, + }) + }, 2000) + }); + } + + //获取蓝牙设备某个服务中所有特征值(characteristic) + getBLEDeviceCharacteristics() { + let deviceId = this.deviceId + let serviceId = this.serviceId + + let self = this + return new Promise((resolve, reject) => { + uni.getBLEDeviceCharacteristics({ + deviceId, + serviceId, + success: res => { + for (let _obj of res.characteristics) { + //获取notify + if (_obj.properties.notify) { + self.notifyId = _obj.uuid + uni.setStorageSync('notifyId', self.notifyId) + } + //获取writeId + if (_obj.properties.write) { + self.writeId = _obj.uuid + uni.setStorageSync('writeId', self.writeId) + } + } + + let result = { + 'notifyId': self.notifyId, + 'writeId': self.writeId + } + //成功获取到设备的服务特征值,可以测试设备功能了 + //self.showToast('已获取打印机服务,请测试打印功能') + resolve(result) + }, + fail: err => { + //已连接设备,但未能获取设备服务 + toast('未能获取设备相关服务,请重试') + reject(err) + } + }) + }); + } + + //断开蓝牙链接 + closeBLEConnection() { + let deviceId = this.deviceId + uni.closeBLEConnection({ + deviceId, + success(res) { + console.log('蓝牙连接已断开') + } + }) + } + //启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值 + notifyBLECharacteristicValue() { + let deviceId = this.deviceId + let serviceId = this.serviceId + let characteristicId = this.notifyId + //特征值变化时,异步通知提示 + uni.notifyBLECharacteristicValueChange({ + state: true, // 启用 notify 功能 + deviceId, + serviceId, + characteristicId, + success(res) { + //监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification + uni.onBLECharacteristicValueChange(function (res) { + + }) + }, + fail(res) { + console.log('notifyBLECharacteristicValueChange failed:' + res.errMsg) + + } + }) + } + //向低功耗蓝牙设备特征值中写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用 + writeBLECharacteristicValue(buffer) { + let deviceId = this.deviceId + let serviceId = this.serviceId + let characteristicId = this.writeId + + + return new Promise((resolve, reject) => { + uni.writeBLECharacteristicValue({ + deviceId, + serviceId, + characteristicId, + value: buffer, + success(res) { + resolve(res) + }, + fail(err) { + reject(err) + } + }) + }) + } + + //关闭蓝牙连接,想要连接要重新启动 + closeBluetoothAdapter() { + uni.closeBluetoothAdapter({ + success: res => { + console.log('断开蓝牙') + } + }) + } + + //若APP在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。 + reconnect() { + (async () => { + try { + let data = getStorage('commitBTDevCharact') + this.deviceId = this.deviceId || data.deviceId //设备id + this.serviceId = this.serviceId || data.serviceId //服务id + this.notifyId = this.notifyId || data.uuid // + this.writeId = this.writeId || data.uuid //写入二进制数据 特征值id + //连接蓝牙设备 + await this.createBLEConnection() + //获取蓝牙设备服务 + //await this.getBLEDeviceServices() + + uni.hideLoading() + if (!this.serviceId || this.serviceId == '') { + //this.showToast('打印服务已断开,请到开发设置重新搜索蓝牙设备') + uni.showModal({ + title: '打印机断开提示', + content: '打印服务已断开,请到设置重新搜索蓝牙设备' + }); + } else if (!this.writeId || this.writeId == '') { + //重新获取蓝牙设备服务特征值 + await this.getBLEDeviceCharacteristics() + connectVoid.src = 'https://image.jxc4.com/image/d1c9c6066f0c63516b8af513d46849f2.jpg' + connectVoid.stop() + connectVoid.play() + toast('蓝牙设备连接成功') + store.commit('storeInfo/setIsConnectPrinter', true) + } else { + connectVoid.src = 'https://image.jxc4.com/image/d1c9c6066f0c63516b8af513d46849f2.jpg' + connectVoid.stop() + connectVoid.play() + toast('蓝牙设备连接成功') + store.commit('storeInfo/setIsConnectPrinter', true) + } + + } catch (err) { + uni.hideLoading() + } + + })(); + } +} + +export default Bluetooth diff --git a/src/utils/bluetoothPrinter/commands.js b/src/utils/bluetoothPrinter/commands.js new file mode 100644 index 0000000..a1a900c --- /dev/null +++ b/src/utils/bluetoothPrinter/commands.js @@ -0,0 +1,193 @@ +/** + * 修改自https://github.com/song940/node-escpos/blob/master/commands.js + * ESC/POS _ (Constants) + */ +var _ = { + LF: [0x0a], + FS: [0x1c], + FF: [0x0c], + GS: [0x1d], + DLE: [0x10], + EOT: [0x04], + NUL: [0x00], + ESC: [0x1b], + EOL: '\n', +}; + +/** + * [FEED_CONTROL_SEQUENCES Feed control sequences] + * @type {Object} + */ +_.FEED_CONTROL_SEQUENCES = { + CTL_LF: [0x0a], // Print and line feed + CTL_GLF: [0x4a, 0x00], // Print and feed paper (without spaces between lines) + CTL_FF: [0x0c], // Form feed + CTL_CR: [0x0d], // Carriage return + CTL_HT: [0x09], // Horizontal tab + CTL_VT: [0x0b], // Vertical tab +}; + +_.CHARACTER_SPACING = { + CS_DEFAULT: [0x1b, 0x20, 0x00], + CS_SET: [0x1b, 0x20] +}; + +_.LINE_SPACING = { + LS_DEFAULT: [0x1b, 0x32], + LS_SET: [0x1b, 0x33] +}; + +/** + * [HARDWARE Printer hardware] + * @type {Object} + */ +_.HARDWARE = { + HW_INIT: [0x1b, 0x40], // Clear data in buffer and reset modes + HW_SELECT: [0x1b, 0x3d, 0x01], // Printer select + HW_RESET: [0x1b, 0x3f, 0x0a, 0x00], // Reset printer hardware +}; + +/** + * [CASH_DRAWER Cash Drawer] + * @type {Object} + */ +_.CASH_DRAWER = { + CD_KICK_2: [0x1b, 0x70, 0x00], // Sends a pulse to pin 2 [] + CD_KICK_5: [0x1b, 0x70, 0x01], // Sends a pulse to pin 5 [] +}; + +/** + * [MARGINS Margins sizes] + * @type {Object} + */ +_.MARGINS = { + BOTTOM: [0x1b, 0x4f], // Fix bottom size + LEFT: [0x1b, 0x6c], // Fix left size + RIGHT: [0x1b, 0x51], // Fix right size +}; + +/** + * [PAPER Paper] + * @type {Object} + */ +_.PAPER = { + PAPER_FULL_CUT: [0x1d, 0x56, 0x00], // Full cut paper + PAPER_PART_CUT: [0x1d, 0x56, 0x01], // Partial cut paper + PAPER_CUT_A: [0x1d, 0x56, 0x41], // Partial cut paper + PAPER_CUT_B: [0x1d, 0x56, 0x42], // Partial cut paper +}; + +/** + * [TEXT_FORMAT Text format] + * @type {Object} + */ +_.TEXT_FORMAT = { + TXT_NORMAL: [0x1b, 0x21, 0x00], // Normal text + TXT_2HEIGHT: [0x1b, 0x21, 0x10], // Double height text + TXT_2WIDTH: [0x1b, 0x21, 0x20], // Double width text + TXT_4SQUARE: [0x1b, 0x21, 0x30], // Double width & height text + + TXT_UNDERL_OFF: [0x1b, 0x2d, 0x00], // Underline font OFF + TXT_UNDERL_ON: [0x1b, 0x2d, 0x01], // Underline font 1-dot ON + TXT_UNDERL2_ON: [0x1b, 0x2d, 0x02], // Underline font 2-dot ON + TXT_BOLD_OFF: [0x1b, 0x45, 0x00], // Bold font OFF + TXT_BOLD_ON: [0x1b, 0x45, 0x01], // Bold font ON + TXT_ITALIC_OFF: [0x1b, 0x35], // Italic font ON + TXT_ITALIC_ON: [0x1b, 0x34], // Italic font ON + + TXT_FONT_A: [0x1b, 0x4d, 0x00], // Font type A + TXT_FONT_B: [0x1b, 0x4d, 0x01], // Font type B + TXT_FONT_C: [0x1b, 0x4d, 0x02], // Font type C + + TXT_ALIGN_LT: [0x1b, 0x61, 0x00], // Left justification + TXT_ALIGN_CT: [0x1b, 0x61, 0x01], // Centering + TXT_ALIGN_RT: [0x1b, 0x61, 0x02], // Right justification +}; + +/** + * [BARCODE_FORMAT Barcode format] + * @type {Object} + */ +_.BARCODE_FORMAT = { + BARCODE_TXT_OFF: [0x1d, 0x48, 0x00], // HRI barcode chars OFF + BARCODE_TXT_ABV: [0x1d, 0x48, 0x01], // HRI barcode chars above + BARCODE_TXT_BLW: [0x1d, 0x48, 0x02], // HRI barcode chars below + BARCODE_TXT_BTH: [0x1d, 0x48, 0x03], // HRI barcode chars both above and below + + BARCODE_FONT_A: [0x1d, 0x66, 0x00], // Font type A for HRI barcode chars + BARCODE_FONT_B: [0x1d, 0x66, 0x01], // Font type B for HRI barcode chars + + BARCODE_HEIGHT: function (height) { // Barcode Height [1-255] + return [0x1d, 0x68, height]; + }, + BARCODE_WIDTH: function (width) { // Barcode Width [2-6] + return [0x1d, 0x77, width]; + }, + BARCODE_HEIGHT_DEFAULT: [0x1d, 0x68, 0x64], // Barcode height default:100 + BARCODE_WIDTH_DEFAULT: [0x1d, 0x77, 0x01], // Barcode width default:1 + + BARCODE_UPC_A: [0x1d, 0x6b, 0x00], // Barcode type UPC-A + BARCODE_UPC_E: [0x1d, 0x6b, 0x01], // Barcode type UPC-E + BARCODE_EAN13: [0x1d, 0x6b, 0x02], // Barcode type EAN13 + BARCODE_EAN8: [0x1d, 0x6b, 0x03], // Barcode type EAN8 + BARCODE_CODE39: [0x1d, 0x6b, 0x04], // Barcode type CODE39 + BARCODE_ITF: [0x1d, 0x6b, 0x05], // Barcode type ITF + BARCODE_NW7: [0x1d, 0x6b, 0x06], // Barcode type NW7 + BARCODE_CODE93: [0x1d, 0x6b, 0x48], // Barcode type CODE93 + BARCODE_CODE128: [0x1d, 0x6b, 0x49], // Barcode type CODE128 +}; + +/** + * [IMAGE_FORMAT Image format] + * @type {Object} + */ +_.IMAGE_FORMAT = { + S_RASTER_N: [0x1d, 0x76, 0x30, 0x00], // Set raster image normal size + S_RASTER_2W: [0x1d, 0x76, 0x30, 0x01], // Set raster image double width + S_RASTER_2H: [0x1d, 0x76, 0x30, 0x02], // Set raster image double height + S_RASTER_Q: [0x1d, 0x76, 0x30, 0x03], // Set raster image quadruple +}; + +/** + * [BITMAP_FORMAT description] + * @type {Object} + */ +_.BITMAP_FORMAT = { + BITMAP_S8: [0x1b, 0x2a, 0x00], + BITMAP_D8: [0x1b, 0x2a, 0x01], + BITMAP_S24: [0x1b, 0x2a, 0x20], + BITMAP_D24: [0x1b, 0x2a, 0x21] +}; + +/** + * [GSV0_FORMAT description] + * @type {Object} + */ +_.GSV0_FORMAT = { + GSV0_NORMAL: [0x1d, 0x76, 0x30, 0x00], + GSV0_DW: [0x1d, 0x76, 0x30, 0x01], + GSV0_DH: [0x1d, 0x76, 0x30, 0x02], + GSV0_DWDH: [0x1d, 0x76, 0x30, 0x03] +}; + +/** + * [BEEP description] + * @type {string} + */ +_.BEEP = [0x1b, 0x42]; // Printer Buzzer pre hex + +/** + * [COLOR description] + * @type {Object} + */ + +_.COLOR = { + 0: [0x1b, 0x72, 0x00], // black + 1: [0x1b, 0x72, 0x01] // red +}; + +/** + * [exports description] + * @type {[type]} + */ +export default _ \ No newline at end of file diff --git a/src/utils/bluetoothPrinter/gbk.js b/src/utils/bluetoothPrinter/gbk.js new file mode 100644 index 0000000..14843fd --- /dev/null +++ b/src/utils/bluetoothPrinter/gbk.js @@ -0,0 +1,192 @@ +/*! + * gbk.js v0.3.0 + * Homepage https://github.com/cnwhy/GBK.js + * License MIT + */ +var GBK = function (gbk_us) { + var arr_index = 0x8140; //33088; + var gbk = { + decode: function (arr) { + var str = ""; + for (var n = 0, max = arr.length; n < max; n++) { + var code = arr[n] & 0xff; + if (code > 0x80 && n + 1 < max) { + var code1 = arr[n + 1] & 0xff; + if(code1 >= 0x40){ + code = gbk_us[(code << 8 | code1) - arr_index]; + n++; + } + } + str += String.fromCharCode(code); + } + return str; + }, + encode: function (str) { + str += ''; + var gbk = []; + var wh = '?'.charCodeAt(0); //gbk中没有的字符的替换符 + for (var i = 0; i < str.length; i++) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) gbk.push(charcode); + else { + var gcode = gbk_us.indexOf(charcode); + if (~gcode) { + gcode += arr_index; + gbk.push(0xFF & (gcode >> 8), 0xFF & gcode); + } else { + gbk.push(wh); + } + } + } + return gbk; + } + }; + return gbk; +}; +var gbk = GBK; + +var URI = function(GBK){ + var passChars = '!\'()*-._~'; + var otherPassChars = '#$&+,/:;=?@'; + function getModue(passChars){ + var passBits = passChars.split('').sort(); + var isPass = function (s){ + return ~passChars.indexOf(s) || /[0-9a-zA-Z]/.test(s) + }; + return { + encode:function(str){ + return (str+'').replace(/./g,function(v){ + if(isPass(v)) return v; + var bitArr = GBK.encode(v); + for(var i=0; i 0x80){ + var code2; + if(enstr.charAt(_i+1) === '%'){ + code2 = parseInt(enstr.substr(_i+2,2),16); + _i += 3; + }else{ + code2 = enstr.charCodeAt(_i+1); + _i += 1; + } + if(code2 >= 0x40){ + i = _i; + outStr += GBK.decode([code1,code2]); + continue; + } + }else{ + i += 2; + outStr += String.fromCharCode(code1); + continue; + } + } + } + outStr += char; + } + return outStr; + + } + } + } + + var URIComponent = getModue(passChars); + var URI = getModue(passChars + otherPassChars); + + return { + encodeURI:URI.encode, + decodeURI:URI.decode, + encodeURIComponent:URIComponent.encode, + decodeURIComponent:URIComponent.decode + } +}; + +var src = function (gbk_us){ + var gbk$$1 = gbk(gbk_us); + gbk$$1.URI = URI(gbk$$1); + return gbk$$1; +}; + +// 多进制转换后的数字还原函数 构建时会替换占位符 +var Fn_Hex_decode = function decode(){ + var n = 0, str = arguments[0]; + for (var i = 0,w = str.length; i < w; i++) { + var code = str.charCodeAt(i); + if(code < 38 || code > 126) return NaN; + n += (code - 38) * Math.pow(89, w - i - 1); + } + return n; + }; + +// 解压Unicode编码字符串函数 构建时会替换占位符 +var Fn_unzip = function unZip() { + return arguments[0].replace(/\x23(\d+)\x24/g, function (a, b) { + return Array(+b + 4).join("#"); + }) + .replace(/[\x26-\x7e]\x25[\x26-\x7e]/g,function(a){ + var b = a.substr(0,1).charCodeAt(0) + ,e = a.substr(2).charCodeAt(0) + ,str = String.fromCharCode(b); + while(b++ 0) { + data.length += 0x40 + 1; + } + for (var j = 0x40; j <= 0xfe; j++) { + if ( + (j == 0x7f) || + ((0xa1 <= i && i <= 0xa7) && j <= 0xa0) || + ((0xaa <= i && i <= 0xaf) && j >= 0xa1) || + (0xf8 <= i && j >= 0xa1) + ) { + data.push(undefined); + continue; + } + var hex = gbkArr[k++]; + var key = Fn_Hex_decode(hex); + data.push(key ? key : undefined); + } + } + return data; +} +var GBK$1 = function () { + // 生成按GBk编码顺数排列的编码映射数组 构建时会替换 zipData 的占位符 + var gbk_us = gbkArray(Fn_unzip("(T!HJ%LUX]e%gilotuwy{} (U!)-%/137>BDGHO%RTUW%\\_a%jl%rtw} (V!*+-0%27>C%EHJ%MP%R\\`cdfn%ptvz{} (W!()*,/3%579;=%CFGM%QWX\\^cdg%ilnprtvy%} (X!&')%.468CDHJLMOPSTWY%\\_b%dg%ilnprtuwxz%|~ (Y!'(*+-469%=?%GI%KO%RT%V[%_bdikmnptuy{}~ (Z!&')+%-/%;>@ACE%GKMNPR%TW[_%ikmo%rt%vy%{} ([!'(%+-%024%;=%BD%LO%QSTX%[]^`%ce%y{} (\\!()+%/1%7:%LN%SU%WY%cf%im%prt%xz%~ (]!&'%*-%/1%68%EG%cgloqs%uwx|%~ (^!')%-/02356;>FJKOPRSVWZ%]_`dfi%kmor%vyz (_!'+%-124%68;=@ACE%MOQRUVX%]_adegjqwx|~ (`!&)*-%/689;%=?%ADFIKLNOVX^%cehilmoq%uwyz|%~ (a!'),%/124%=?AD%HJ%PRSU%[]e%ho%qu%~ (b!()*,%.024%79;%=?A%FH%KM%WY%`c%ei%loq%tvy%| (c!'*+-.1346%8:%<>%GKLOQSUZ%\\_cghjltwy{| (d!(,/1%4679=>@D%JLMOQRTVWZ]`%ce%km%pr%tvy%} (e!+,-/0279%;>?DQW[%]_bdhqu%wy (f!&().47:;>ACEFHIKMP%SU^a%egikm%tx}~ (g!)*,.02%58<>BCGI%MPY[]`%bdeginpuv (h!(*-2%6=>A%CF%KMPRT%WZ\\%`deg%ln%qswxz{} (i!&+-%/1%469;>@AD%HJ%MP%TV%Y[\\abdh%mrsvx~ (j!&,%.0235%7:;>@%FH%PRTVXZ\\_%cf%hjkn%puw%{~ (k!').04578;=?%CFI%NQRTW%^`acdg%ilmo%ru%wz|~ (l!&(*%,.%9=%ACDHIK%OQS%U[%^`%ce%hk%ru%{~ (m!&')%79%CE%KM%PR%^`%hjkmnqxz%~ (n!&(*+./2%478<%>ACG%WYZ\\%^`%cgmnp%txy{} (o!&'%)+,.5%9;%BE%UWZ\\^%`b%il%ps%ux%~ (s!&)%:<%?A%CE%OQ%SU%bd%ilnpqstvwy%~ (t!&')+,.%246%9=>ACDF%ILNRVXY[\\ac%fiklprsvxy (u!&(%,.013%?BDG%IK%MRVXY[%^abeg%jl%ostyz}~ (v!'(%,.013%9;%=@%CIJMOR%VXZ[]%_a%lnp%rtv~ (w!&(%+-/%24%689<=?A%CE%KNPR%VX%Z\\%`bcf%oq%tv%|~ (x!&'(*+-%5:;=%@B%SU%[^%km%svxy{%~ (y!&(),%1346%:<>@B%DF%HKMNPQSU%Y[%qs%~ (z!()%ACEFH%OQ%_bfnpqwx{}~ ({!&)+-%023569=ADEG%IKMV^%`c%fhinq%swxz (|!&'%)+%-/2%:>@ADEG%KMO%U[\\^`acefi%lnpquwy|%~ (}!&(+-%02%578:%?AI%MP%TVZ%\\^`be%hjlnoq%vx%} )&!&'%+-%356:<>?ABD%MO%TWX[%`b%fhj%mopr%vx{}~ )'!&)%-/%69%@BCG%QSTVX%bdghj%mo%{}~ )(!&'%9;%=?%WY%eg%mo%{} ))!'(+,2458=>@%DGHLOQ%SUVZ[_f%mp%twxz%~ )*!()-%025%:<%BE%IKLNOR%`dfhmp%rtwx{%} )+!(.137%:>%BD%HJP%SU%^a%fjkm%pr%} ),!&(%02568%:B%DFI%KMOQSVWY%[^%aehikmo%uxz%|~ )-!&'%358=%@B%DGIKLORSVX%Z\\^a%cgjq%suwxz~ ).!&(%+-%2467:%?AC%FI%MRSUVY^%`e%gijmnpqstwz{}~ )/!&()+,.9%;=>BCEIJLPQT%V^%`b%fh%loprv%|~ )0!'(*,-/%1457%:>?GJKMNPWY%[^%acdg%jlnp%ruwz{}~ )1!')*.035%79:=%DG%IL%PR%TVWY[^a%ejqruwx{%~ )2!&)%,.1%37%;=%@B%EHILO%QS%eg%nprtvwy%{}~ )3!&'%*,%/1%47%=?%BDF%XZ[]%ac%jl%txy{%~ )4!&'%+-%24%68%<>A%EHJ%Z\\%ik%su%z|~ )5!/058%:@D%FH%KN%SW\\_%afijlmp%su%wy%{} )7!(*+-59;?GHJKNTUZ\\_b%ejm%pt%wyz|%~ )8!&(%*-78:=%?ABD%ILMO%RUXY[b%eg%nqu%wy{%} )9!'(*%-014%79;%>CEIK%MOQ%WY\\^cgijmnqsuw%{} ):!&')%+02%46%<>AC%GJKM%PRTVX%[]bce%ilmpqt%y|~ );!()%+-%/14%9;%?ABDFHIOQ%WY[%]_%ce%lnp%rt%} )!'(+%.2578;%?ABEFHIKM%ORSUWZ%\\_`b%eh%jlnpqs%~ )?!&'(*%,/%146%8:ABD%HJMNP%RTVY%[_%ac%egj%mor%uwy{| )A!'(%+-/024%:=>@AHIK%NPRSUWY%]a%cehik%mo%qsuvx%{}~ )B!&')%,/%35%=@%DF%JL%OQ%TV%oqu%|~ )C!&(%-/34689;?%EJLMO%QTV%XZ\\^%ceglnpqt%wyz|} )D!&)*,/0279:<%@BG%IKLPQSVY[]%`beghjkmoq%tv%y{~ )E!'+%-0258:=>@E%LNQ%Za%cgkmopr%tvwyz~ )F!()%/14%79@CEGHK%OQ%SU%[^%dg%imnrz~ )G!'),0%9DF%MOR%Z\\^a%hj%ln%pr%{}~ )H!&*%-/2357%@BD%IKMO%RTUWXZ\\%`bce%nps%uw%y|~ )I!&'(*%,.%2479;%FI%KM%TVWY%[]%`b%dfhik%{}~ )J!'(*+.01346%9;<>?A%EIJL%NPRTY%[]%befhil%uxy{}~ )K!&()+,.%02%68%?ACEG%IK%PR%TW%bd%gi%rtv%~ )L!&(%36%;=?%DFH%KMO%QS%Y\\%`bce%ln%twy%} )M!&'(*%46%<>?A%CE%GI%QSV%Z\\%ce%lnq%~ )N!&'%~ )O!&'%178:%CE%HJM%OQ%TVWZ\\]_%jl%sz{}~ )P!&'%136%9>AEG%JMNP%RU%Y[%bd%koq%wy|} )Q!&'%*,.018:<%@B%IL%NP%RTV%XZ%\\^%dh%lnrw|%~ )R!'*,2%48:=>@%CEFJ%LOR%VX%Z]_%aijl%nr%vxz|~ )S!&(%*-.2589;ABGINTUWXZ[]%_bd%fh%kmqrt%y{}~ )U!()+,02%46;<>@EHLQ%TWY[]^`acdg%il%oqru%wy%} )V!&')*-.02359%=?EHOPSTVWYZ\\%ad%fk%mp%su%xz}~ )W!&),-/1%479:<>%@BDG%NP%SUY\\]_bcefhilp%rtvxz{} )X!&'(*,%36%=@%CFHJKM%OQ%[]^`%nq%suxy{%~ )Y!&)%/1%35689;<>@AC%FHKMPQTV%X[%^`%bd%fhjnpqs%u{ )Z!&)%24%79%@B%DFGI%MO%QU%^`%bd%gkmoqstv%|~ )[!&'%+.%024%=?%ACE%GI%KM%RU%WY[%]_ac%ik%mpqu%~ )\\!&'(*%-/%35%?ABDEG%LNP%UW%]`%jlo%z}~ )]!&'%DF%MP%VX%hj%ln%~ )^!&()+%8:%EIL%ORT%VX\\%_a%cf%hj%lnrsuvy%~ )_!&'%,246%8<@AF%IKM%Y\\^%`b%eglpr%xz|%~ )`!'(%14%8:;=@D%NP%W[%^`%mo%rtvx%~ )a!&'%+-/%359%=?%AD%GIKLN%SU%Y[%^`%ce%gj%nq%wy%{}~ )b!&'%)+-%/1%9;%DF%JM%VX%[]_%df%oq%|~ )c!&'%:<%EGIK%MP%RXZ\\^%dg%il%oq%suvxz|~ )d!()*-/%25689;%=@%BGHJ%NQSUVX%ce%psv%xz )e!&'%,1%35%8;=?%BDFG 'W!,-. &(+&.'&-~&'u'W!/1 ')>.= '.u'/!K. '0`'/!94 '1t'0T'/!?Bu`\\Q1t '0!)* '/!xy2IH ';!*( &'}')!\\] '+{.;U&'q.>!&' ')Z&'t',5':!GF '9!eiha`;:ML ')e'-!XVWY 'W?'-!67%?#3$ '6!-.%@ '5!rs%~ '6!&'%, '5!^_%g## ']!67%?## '-!&'%1## .;!RST .>+.;!VW%~ .)'W!mn%~ 'X!&'%f#8$t%~ 'Y!&'%p#5$ &0!=>%MO%U#5$]%mo%u#4$ .9!89<=BC@AD%G##>?:;4#67#6$ &1!cd%hTi%~ &2!&'%)#12$*%/K0%I#10$ &.!()7 ')!=?O_ '+}',('-!\\]%_ '/!)37fz{ '0z'8!CD%ft%~ '9!&'%)-%/VW|%~ ':!&J '0P'W!>IJ#8$ &(!uU &+7&(T&).&(]&)6&(\\&)F&(a&+9&(`&)h&(g&+;&(f&*-&(n&+=&(m&+!?ACE &(!p^ &,a-Qc&)!_c -Qd&,q#1$'Z!&'%J#18$ 'W!MN%U '^`'a!@AN%PSv 'b!'*+. .93.>!(*# ',@']G#'):#0$'Yv'X!no 'Y!wx 'W2'X!pq .9!LM%UW%Z\\%ik%n -R!*+%6 'W3#10$'7!LM%~ '8!&'%>#12$ )e!HIKN%SVWabei%lnp%uw%y{%~ )f!'+%-23679%;@BCEFHIM%PS%_abdf%ik%rt%~ )g!(*%79%=?@BDFGIJL%OQ%TV%XZ[]%bdfgkn%prsv%y{}~ )h!&'(,-/3%9;%>@B%EGIK%MO%RT%cehil%or%z}~ )i!&'%)+,/13579:?%CE%HJ%\\^`eh%tvwy%} )j!'(%,.13%57%9;<>@%JLN%UY%hj%~ )k!&')%1357;=%CF%IKN%TV%Y[%bdfhj%mqstv%z|} )l!'+1369:<>%ACDFGJM%PR%UZ%ad%fh%npr%tw%{}~ )m!&()+%.0%2479@%CEFHIMOQ%TVX%Z\\%_aeg%ilnrswyz|} )o!()+%-/346%=@%EGI%MOQ%TV%\\^%`b%iklnq%suw{|~ )p!&()+-.013%<>%FHILN%WYZ\\ (iC*r5(pM)89(gy(h[(gk)p*)o>*A;)s|*9E)ui)cO*s5*ux)R/({@(Z*)7s)B.(~d*4~)F{*42)@K)pg(_l)>Q)a|*2'*Jb(\\0(u2)4?)\\@*9t)8])5n(eJ(f+)|s(^7)mH))<)7>*Yr*ua)6M*2O(o@*t|*0J)cV)oo)E[)op);L(XR*W~)7F)z6)?3)hN);2)66*8L*xa)Dd)cf)61)76(Wo)k9(cY(a_*.d*b,))v)G`)Jk*6R*.k)HS)vH*E'*oR([d*U/*:L*4b(bm*L>(a&)p!]`bdelnrsu%wy%} )q!&'%-035%7:;=?@BCEFJLN%X[%^ac%egj%lnp%ty{}~ )r!&)+%-/%69%@C *B**t=(Yf(qR*{F({T)6!th )BK*V+++A)b})DT)um)12(c!`& *^r*4P*Wv*mT(Z=)e4(t-)1k)`B*K0(tz*:])Cj)}<)&|*/8)l*)TJ*[[*`!0t +3')Q4*cF)}()-`)v**@.*A<)Q!596 ))I)*v)nD*q<)>X),G).P*_0(s@*7;*a^*rQ*v?*_J*/W*X,)5](YH(e5(cm*_!9:< *a,)F:)-N*6j*JF+,1)3Y(`E)nu)-P)?.)\\_)Z'({u);N(^!A| )EP(T_)yA*{Q)_5)r!DE%GKNPQT%_a%ch%jm%rvwz%~ )s!&'%,/12469;%=?@BD%HJLN%Z\\%df%hk%or )mi)*e)gu*=C)(dx*E0)PD)1!mh )^Z*:;*8Q(Vg)SU*Bu)Y)lB(i*(ZQ*Y,)6G*mQ)C[(ky)[T))*(f9)^m*^P)62)*Y(*JJ)<>)yh(pX)Lv)5,(fL(UE)z*)1i)[j*T>)6B*`V*~U)y\\(e`)n?)7k(c()Rg*_p),X*~:*2q+3k(Xj(}?*Xd*1T)?G)_?(]j(^~*D_)&Z({W)7'*d@)lq*ZZ)z?)2()~4(V[*/9)rl(TW*7f(`7(_m)M5(d^*[|*n^*sl)YY*rZ)J))u!`abdfgklnp%ruyz|~ )v!')+%28%;=%@BCE%GI%KO%RT%VY%[]%jl%np%tvxy{|~ )w!&'%*,%.0%6 )tu(\\&)se):o*N`(t*):B)(~){E)Ie(W[*8Y(j8(Tx)mR){])*!Qy *q>(`5(f=)^e)9.*n~(oe)@n)Ig*d[(hY)W=*.I*IY)5O*/1)mY*;=)vD*si*_/)2o)kM*T1)Ov(`T*XP)O3*3G*>{(n-(bn(Vb(Ta(_D*(G*d_*&i(YL*[t*&C){b);m)&g(\\**51)nL*(i)W6*1o)D6(zh(|V)vN)<[):r)9b)8<*ns);3*_O)}h)nt)5o(tM(fJ)P2([z)5P))n)P?(Vw*X7*Ji)-i*`f)w!78%<>%GI%MO%]_%cgil%oqt%|~ )x!&)*2457:%=?A%GJL%PSTW%Z\\%_a%c )/R*2s)7/(U&(cd*b~)9p*4J)@/)R5(X()1n)W+*TB),v*Ef)-7)82(^&*;v)G=(_s)8t*[=(ZB(~G)xH(|Z(`J)zZ)1<*a2)pp).B)-{)ov*[a)^J)om)}])s8(_f*ar(qU(X0)Z3*_{)>G)}/)e0)VG*1n(yJ)6x)++(nl*?3)}@))e),\\*`J*/U*y')9:)Y_)ut)_;(^D*uF(p5)l2(W~)l5)+-)1f(u-)Vc)Px)ue(eY*sr(_!>t )9A(eg*mF*Tg*Ys)cW)u{*G_*_~*Tq(e=)x!de%jl%wy%~ )y!&'%*,%047:<=?@BDF%HKLNOQ%VX%Z]`bdfi%oqrtvwy|} )z!&'%)+.%24578:; (TG)q/(eK*m<*xV+2S*o.({Q*S_(T!hb (^x*>m)47(ai)F>(Xy)0D(_.)Ts(^()6Y)?9*rW*UQ*`O)m|*c*)rJ)Q2)dO)eX*T_(qf)r`*XL)DA*oA*3w)+<)Wk(u_)|\\)s{*o<)Pn)?O*/O(q7(]v*qn(|W(s((f,*[g)>a*x_(my*mP)q>*`y)9?(gq(t!@` (o~*\\N)Cs*ZH*8U(`[)1p(qF*F@)&;+0<(YM*x}*Sv(w@)0O(d:)6?*a.*c/*{T)0B*2B(]d*2i(|r*{J)U-(Uy)z!<>@AC%QS%UWY]_%df%oq%uw%~ ){!&'%57%9;A%DHKMO%RT%VYZ_%adgh *X0(e.*0B)}c(WK(U<*qO)T*)h1*C6))N)lg*21)L')t3*mE*-4(_T)_h(e**_e*:q*X))dt*{B)T0(o-*9z)?[*4.)5[*r((uu(W:*S|*.T)>9*=U*uI(iZ*ye*4)(c9*Ta(e}*4>)+5)Sf*X9*9s*d.(f-)Q{(_y*.Q(oB)`C)S,*(9(tq(W8)/1)2K*(Z(Tv(|_)E7*FD)&C*ne*yU)mS)`&*`Z(^{*/^*Sz(to(_W(X=(f*(tQ)>r*4(({,)69)7,*^z)*4)R&)}:(WJ(Ya)CK){!ijmo%qt%xz%~ )|!&'%+-%79%BDEG%JNOQT%Y[]%ehikm%ortvy%{} )}!&'*%,.0135%7;=A )Uj)VM)x`*K6),T)l()6]*^o(Yx*eW)?I*5!Z| )+2*5{*Xt(a0*MY*XK(t3([\\(Vl*qk)cT*6K*Wx(|**S`*r:(uT*/[(g;(ld(kU*TI)>4)JQ*mL)po)Xz)*a)kn)D+)E])|l*3z*Xv)2F)y>)>]*Xc(^T(`4*mU*/y*3x*.L(~C)Wy)DE*&;)o}+&I*6a*0|*),):}*oQ)z^(fN(h7)O^):`)4}+04*4w)m=(a3*uT*>e)Fo*F&*qP*s1*nF(Tp(ea*.s)Fl*Z-*2K)C2)+0*1H)}!CDFH%KMOQS%XZ\\^abgikmprsuw%~ )~!&'(*+./13578:<%?A%GIJL%NQS%VY%[^%`i%kmnp%rt%{}~ *&&(pL*2u)Gq))-)>6(a`)0F+4-(X}*\\H(^8({b),P))1)Re)7[*Wz(^=*m\\(bf)SM*:M)eC(p,)Di*X-(tE*_-*=*(g@)~H(Wk)Sk(zt(vE+2X(eA*Ee*~r*UB*3~)>@*x^(n6*sd(`H)k2(`j(|?)7l*L.(UC)7:)/\\)H{(^?({O(^l*N<)~\\*{[*08)1o)^'*X/(]n)*n*`S)ix*N>(ni)tz)-6+42*qI*^R+'T*TE)oj)Fu)Eh*Z8*X5(`W*^t)Yr)HN*n_*bs(n9)E(*K~*_X(gs*&!'*%-/%246%:=>@%BD%FI%KM%OQRT%XZ%]_a%hj%lopr%wy%~ *'!&')%.124%@B%GK +&)(zy)Us)R-(V9({j*~Q*d7)3v*b5*v{(f/)VX(|0(_p(j**0=*2&)u*4e*G])e<*(z)XG*'!LM%UW%{~ *(!&'%*.%8:%@CDFI%KPQSV%Y[%]_`d%hjk ),d*DB(h~)6g(V&)SX)5S*9x(h)(c])fQ)Yi)l8(`,(b~*TA)KF)-n)/2)W8(o2)O4)gi)G-*_i*/T)8s)0|(hv)n5*Um)`>)VF({])*j*;g)2s+1b)v}*G@*'0)oy(_c)1v)`u)A3)*;)0&*Tr)^K)86*^s).H)0;*Eo(ms)Pz)0m)35(cX)1`)AV*X?)yu(WU)_k)RN*Sp*TV*.r*;y)@X(wu+'Z)UM)WA*UL)U7(WT)^F*@%EG%NPQS%`b%vxz%} **!&'(*%,.%4 *3i*{:*`1)\\M*Sb+/q(v`*/!*J (ef)Df)HY*^{*'V*sc(e')/W)mb)Ry(d)(y2*.A)85(_S*55))9*@7)6C(^L(zs(WI)x>(`\\)18)UJ({!{y *S!^m )@+).W*r;(u`*/(*.D(kP)EC(t_(XU({m(aa*;o*xj*X>)l/*mq(Zw)z[(W2)EB*~H(y*)P5)pj(o=(|t)}N*qC)`w(^H*4-*97(uE*/E*;<)HA)Ex)v4)uS)7M)8r)~;(Yv(a+(_B*;e)KQ*g=*ZC*X1*N;*o/)~h(W1**!56%km%tv%~ *+!&'%= ([<*8P(`k*{D)WZ)Xv)VJ),7(\\s(vP(|d)UB)Rf)m**?<)GB(t|*So(c/*dE*rC*AH)I:)w+)`O*4z(V8*bP)UC*~N(v{(mQ):d*nJ)sy(Y.*5E)eM*NL*{O*/u*.x(a@)>T*dI*^!im (eH){\\):L)9])ox)yp*J5*r,)5F(al*9I)G.)DU)9/)rR)|Z)TV*.m*N](vD)5.*Bo*9l)lI(ZO(V_)mI*TO(}O))F)}_)?F*eL(V^)Tz*M2*)~*o'(VY*U3*_l*u^)A;)xR*_b)_n)Ut*+!>?%JL%RT%~ *,!&'%F (}B(as*;[(^.*:|)rB)Af++l(V@)1J*(!nc *.i(V)*R|)A_*xh*uD(r[)>g*o])-h)mm*uA)|!LK (_3)_1){^):I){<*.:)gP*w&(U2)^S(UJ*d&(d_)>L)@0*7!u~ (g9(}6)m>*v2)7B)eE)ma(}J*~C*=-(}E(g+)sw(U+)S\\*37)7<)9&))0(^C*Z!+l *o0(Yz(eB)1g)_.(a()8a+0:(w:(ZV)qw(d-*.|)<2)>&)6L)9P(ZD)cS*NC(_&*S}*.w(o**=/*mZ(^g(ex)&N*,!GH%~ *-!&'%-/%35%9;%P (YS)|P)UV*bg*~Y(iy(gA(cp(gZ),=):H)JF(_b)36(_}(q[(b@(o1)tB)qK)+M)3E*)7)5w)6Z(V6)^p*29)7a)_f*uK(oZ*:I)E{)Hv)vX*xw)yI(sr(g^(eL)W~(]p(`U({Y*Tb*43(i<(p0)0L(o4(f1){@)0)(zd)9_)6c(e@)6&({~)E;(h?){e*:T*dK)+)*Ki(t^(p8)7x*Z6*4s(o:)~2(Y2).v({t)OP(c0)}d)e.)Fy)t4)qv)@@(_((U|)pm(~k){k*?&(tt+'Y([W*-!QR%tv%~ *.!&'%46%8HNUVp~ */!-:KQ_xz|%~ *0!&'%)+.%7:; *{])2N)Xt(oG)@O)8W(n,)7V)6,)+i*qc(of)73(j'*Fc*5u*_4(i_*)_[)V@(b:(U=*t;*on*A})vM**-(]F(ou)AC%FHK%OS%UWX[]%`b%eghj%qsuw%{}~ *1!&'(*+/12457%=@B%FIJMOQ%SU%XZ\\^%befh%mqr )n-)|8*(B)SS*sS(a\\)j2(h;(Yr*31*V*5c*nX)/})_>*.]*(^(_<)G[*(a*96(Tj*^p*eJ)An(VB*Ti)(er*n7(Y,)?g(}!jf */V*DE)R6)-o)gA)Y|*/@)&9)8,(zz)Y~(d+(U^)9X)lb)6d*^X(Wa(Ve)ST*.P*Sw*>'*HJ*0?*`s*n})~d*~k*K}*>G)Tp*~P*.v(uU+1Y)gU)t6*Dv*~!6L (kb(et(pU(U]+1D(ce*_Y*54)ry*{g*F0)Yy*@k)C:)30)Zj*3![^_begj%oqrtv{ *4!'*%,0479:<=?IK%OS%Y\\cdfgjry{} *5!&)%,.%02367@BDF%HJ%VXY[^%`bd%hj *U4*9Y*;@)q2)Qs).d**:s*nt)Q;)si*my(c~*:p(^^)*,*V>*X8(U5)ge)E&)G_*dJ*tM)a4)SO)qI(xT*oB)Q/*0v)@p(|.(v-(x\\*q!7F (W'*=o*?J)Mp)px*o1)f.)H'(zo)qo*dn*uL*)3*`/*U'),b*'|)yP*N?)Sz*F^({})*1)HJ)q`*/6(^a(]r(b1(wD*/F*uM*:E):.)rk*Bv)yJ)X+)+/(uf*@i)^H)Qq)7))pX)>J)1/*qL)@W*H/+/s*nG(ej(g(*U7);~*5!kl%prtx%z} *6!()*-%13%68:<%>ADEG%JSU%Y[]%`bd%iklp%tvwy{}~ *7!&'%+-%25%8=>@%BDF%L )<&*C^)L>*6n)vk);o+'l)6|)Ci*)YR*A*)72)*c)vA))UO(^h),A(uA(ak)/D(u@)B-*DD)mC)8;)4[*)F*T^(h8)O9+/u)Pm*B{(fY([M)SR(ic*Y[)cJ))])/G)i>)77)9J)cj)-|)X4)U:)=T)[>)pq)vS)q<)lQ(`>(e8(U@)+4)?c*2`*4Z)6^(g1(`B)_0*Jk*Yx)T6(f|*4^(q**Ky*XT*r`*cz(XK)SI(jW)p_)te)6k)_{)[t)-Q*@D)H[)uX*&Y*6z)CI+0F)8x)v3(oR)tG*t})6!DGHKPU%XZ%\\^`acdfhj%nxy{~ *;!'(+-.2%;>?CEGLPR (i]*5i)mV)pG(cH)n)(\\y(}F*S)*&)([&)ce*~a*y_)ZA)k8)x9)<4)s3)7f*xq*X+(gl*35(U?(oM*:g*=p)*b(_`)kL*T((}T(oD)TQ*xg(wa)ti+'\\*_|*(E(`p)5m*nT(VZ*k*=L*?c(p^)Cr(n?)A^)Ub*U<)Bt)]E)C])OL)FI)56(v/(TI(_7)ZE)E^)S=(^B)HL(tm)Oy)lc)&a*5;+3<)?y)w!rk *~[*Xw(~.(UK(W<(f3(tw)tA(lV)Qt*_U),@)S+)T8*Sh)9H*;!STVWYZ]_%chj%nrw *AE%GI%KN%P )0I)U9)d:)6)*m!Ax (cR*_R)~9(Vs*U1(Uk+1r*m!df (`g)[B*aB)UA*U?(qB)'F)O!2[ )E6(f_*6&*0t(rq*A6),w)6e)Ld*o:)>m)0])G?)s5(UA(Y1))/*v*)(VF)y^)i<(bL*:')=&)y5(|;)S/*u=*^e)R)(Zn(d5)WO)<{)Ad)R7)1E*xW*T[)*u)iD){=)yC(T^*b7)hd)RI(mo*cx)Ss*Y2(cI*Ea)C0*\\K(}M*~;)Wj*=!QRV%Z]%_a%cehj%msu%z|%~ *>!()%-3%:<%AC%EH%OQ%Z\\%`bg%jln%rtx%z|~ *?!(*,- (e3(wQ+3w*YJ(dq(nD*y.)D(*do)Sw(^4)mn)7])dq(`R(a^*/{)^o)o*(d*+0A)K-)uJ*s]*K^*13)`_)b:(^U)E_)k:(sc)=l(mL*Sf*{K)63*.o)1y)_o(sk(V!UN ).X*vy(W6*Sa(_v(uW*.E)5p(Va)@.)5**;M*?z*;x*Gv)ad)YN({p*.l(^c):()E`*3f*;N*IL(]7({1(uO*_B(U`)Rd(^1*LQ*^Y*q}*AI)if*nj*q?)VI*:S),n)2*6@++w(r6*X[(TO(dw*?!./%24%7;>@%GIKLN%QS%_abdf%hlmoqstv%y|} *@!&'*,-/%469:^)G+(js(Tm):s*~d)6.(y+)ig*99)VL)Ho(\\e*1)5g*{k({?(|])9@(i'(e4)nq(^I*A+)E.)H4)PC)6U*^}(e1*82)Vt)m3(US*XN({')ao*BU)B!(p *0Z*FB+1k+2e(}c)Cm*`()FD)DD)5))|C(r])+L)>k)Zp*B!(),.%46%@C%IK%MOQ%SW%\\^`%fh%np%twxz|%~ *C!&'(*%02%57%E )0.(`Q*2C);Z*JN)l&))M)FF)7^*t`(e))c[*Te)R;)rH)z-(f2)s:*xZ*8<*TX)u1)CR)_C)?Q))MD)n;)[S*U8*Tl(oI)QO*Jp)v6)9Z(eV)_/)Rk(r0);0(q3)Ha*6m(hb*)-(ZH*\\V)Vo*YF)_m)9G)V>)Yl*/'*=g)Fv*`;)V{*rl*Se(t})d>*C1*6P)m`*PR)H0(`n*Zp*nk):/*xx*[9(iu(X5)C=(l})1U)V8(`](}N(tO)WE(rC)l-)kr)0E*84*5q)7{)DF*_s)qz*ZA*X4*mt))^(d;(f0)_E*D!acdf%lw%} *E!)*%-/1%69%=@AFHIMNR%TV%Z\\%^`cghmnp%ruwx{%~ *F!'(%*,%.17%9<%?ACF%HMNP%SVX )RG),4([3(VA)+C)8K*8g*`R)G**dB)sA(ei*n6)-H)|R)GP)8V)}f*.y)n&([N)6X(tZ*`G(_k)y;){G(n:)-v*`L)U~(}e(n[(em(]y)X>(mw)9`*xs*6Q*FW*LV*`8(e{(}t*79)7@)5t*5\\+0,*r6*~!8F )IU(ur)7=(i7)8'(gr*Et)U8(vw)k<*Jz)O|(t<*UW),l)Xo)gc*x](T~)_y({C)us)8N)AJ)p/)1K({R(wd(TM*6')Rq)gE(V5)Dn*09)-d)@C)CY).c(uQ(vu*F![]_abfh%jl%oqrtuwxz%|~ *G!&)%/3468%;=%?AC%HJKO%VXZ%\\^`%ch%jmoprsuw%{}~ *H!&(%.0%4 )(n).9(d'*vx*_n)Fx(n0(i()1_(U')[3*/5*:5*=q(vH(W!Ze (}C*.F)Ch*@r(fw)lL*4G(i{+'g(X/)Ww*Tw(|g)3>(cz)nj)Ws*D~)?)*qJ*.S(f?)zR*)a*q=(k(*1P)kD)8.*FY)VD){c)5-)?C(cv):@)S1))3(f`*m[(U9)Rh*TP(}P)@)*9c)H((f!B8 )Q+)Ox(V()8S(cW*8>(WH(Y7(oA)5&*tB)AT)d.(bg(ab)0x*TS)@])ai)Du*MR)u.)t2)A`(l)(f<*n{)d?*H!5679:>@%BDF%IKLNOQ%UW%Y\\%`d%jl%oq%tv%y{%} *I!&'%/1%46%9;%@B%IKN%QS%WZ )yx)0H))T)0b*6o(t;)1\\)aT)_q)YB)RW)dE)MH*K2))u(UM(xu(j<*n=)Tl*)R*s6)5+*.`)ru*Dr(c2*tb*_')Aw)&4(Y))eY(TQ(d\\(t5(ep)98*o)(]m(Vm++P*.>(gc*W}*J2*8W*qA)V1),c(y5)A.*r_)gj)fA(du*6L*{Z*10({a*r!mF *.Y)q8(dX*ow*{n)~l*Lp)XI(UN*1c)x6*TJ)1s(gx(V?*xY))?)L~(\\M(en*Ul*>1)u9*tH(`d(h@(m8*nZ)V+({l)Vi)AC*I![\\%hj%oqrt%vx%z}~ *J!&'%),%13468%>DEHKMOQ%TV%Z^adeghjl%oq%su%y{%~ *K!&(*%/ (|m(zm)FT*3s(iq)|~)>C)I|(V/)OY*G7*uv(c^)80);@*b0)?>*4E*Tt(^e)H1(d.*I0)4=)Sr)TP*U-(}V*BP*9v*nf)O5*_,)?R)/-).N(Yj*I|)@h*67)f<)1z(^@(`+(on)-F*b(*J**df)*g)D4)/Y(vG(]i(_i*4|(bp)S'*sa)aZ(WL(Yw*1-)C{(je*nb)y8*Jt*.}(rw)5(*tD*DN(k_*x[)-t*Su*?u*d+(e6)@6)*~)lY)0=**l(xA*/!+. *^S(jG({Z)1,)?m)g>*K!13%57%;=%@B%EHILMO%RT%VX[\\_%cefkln%twz%| *L!&')+%-/%57%;=@%DH%LN%PR%UX%[]%_ac *`A)oU)qi*.t*u_*BA(zv){:*t.*Iw(b3)a_).5)@5*TF(|Y*~9))))PB)Rb*S!jl *`B*_V(dA)7&+/!v} (fD(Tq*:+)cw*E7)&i*J7)VR*sb(g|(V.*Ss)`2(gh*qX)_a)WC)pi(Tk)tI*FT(~U),3*Nz*x|*q])^i)Sm(tj)9a)q|*J+)ZS*9:(qa)bL(dB)tO*s^(hS)-J)`Y({k*T~*~V)P<(tT+0&)y_)DM)6/(XQ)mE*0r)T`*r))R.(W+)mv(^G)Fj)Z}*a_*6B(uc)i~*L!de%lnoq%~ *M!&'%03%8:%MO%QSUWXZ%t );M(},*aD){W*U.(vN(gW*7y*<+*MT*26)IX(l<*2l)cU*eI(_)(UL*xU)9N(T`(eS)C1*5v(tB)VU(TF(sx(cJ):5*nK(Y&(WE*JA*xp(t]*a6)ys(V~*4t)m5)S0({S(v\\)-A)I-*Du(ZJ)):(UF)sq(Vy*9A)6T)@\\*ap(}~(VS)-]*7?*`p*3a)mO(V:*KY)26)P~).Q(U6)pc)Y:*TG*Sk*T!n5 ),?*22*1[*.h*;J*<'(mu)Pp*w,*r*(vo(e|*nP)W5({|*{C(}>),R*s-*M!uv%~ *N!&'%:=GM%OQ%SUWY%\\^a%df%hj%ln%y{%~ *O!&')%> (d&*:_)LN(x6+0g)+**/i*!./ *;|*G0*__*Xb)pa)-U*xv)uH)@i(h1)7O(XE*7<)ml)+N*sj*ZX*F;(g:)TH)V/)R?)0X(b/)k~)*l(WS)0y).r(}))l.*b4*ms)d~)Sg)X)*cv)CG(e!(P (X3*eD*TU(d~)*k*_S)W.(U{)p[)JU*DR)2A*8&(X;(Yg*`v++0)20)W!g^ *r{(Uu(wL*t,(TT(~+)y1({>*TQ*1L)gC(pi*9R*bG(e^*a&(j[)&=).,)2/)OD)e]*46*PQ*O!?@%^`%hj%~ *P!&'%@B%H )Up(|1*KZ*xd*Uv*~7+0*)WT(^p(]h(p-*J_(dU):S*_&(n)(f\\(nB)fR)Y(*/Y*_m*:?)2f)/Z*rX)C.*.@*Y!1j *mX(~_*(T)CF)1&*qT*2N(U~*bm(bh*r^(]f*_a*As*d1)AE*w.(ze(c,)tm)D')Fp(gt)^Y({g*^g(^Y(nd(g\\)=f)Ar*X!^C *5:*>v*aL*)6(_r*CH)E/)@2)\\.*E?*[v(lX*`X)ot)^Q)b\\*W|)7S(`3)TR*X<)/@(rv)3\\)C<*X`)5j(jS)Wm)Ck*^Q*P!IJ%PS%Z\\%~ *Q!&'%R *n;*qG)qh)F8)Jw(g6(U:)_:*T,);^)?-({<){J(Zj(|F)sI)QA*PA*(H)Sl)ph)?K*_()''(}Z*D,)F;(co)54)|F)XL*/>)L<)|M)-T)Zr),])9D)VK)D;(TN))X*X&(Vk*4D)o&*s9)7E)@v)6A)Sj*Xu)a7*0Q(]k*3d(eI*aM)6[(hD*F2*_**2;*nq*@o*_j)UU)h.)?A)q_)kZ)t\\*7t*Ww*m;(Y/)Dz)m]*T.*tK)8@*oH*r+*?i)84)r()-e)e\\(Uv)/F)>o)7Y)Ou)>:*Q!ST%uw%~ *R!&'%;=%[ ))o)mk*bW*S~*9d)E))>*(f5*FZ)ss*4&*5-)RH(U8*.a*3))q4)I5)PO)6*(Zl(Xf(n|)7q)Ot*Ye(eG)@1*.R).b)8+)9o*7!lm *0V))d)&,(`P)Aj)ya)z9*X()^t)mx)Yv)Si){X(Ts)p^).k*mR*JU*.b)yE*4C*eH(W!-R *8?(fl))&)U.*T0*(U*^^*3u))b(g=)pJ({P)A,*~n)hA)F]*Ev)Co)f=*T!\\? *`H)|f)_])a>)7.)s7(kx(U(*>a)E}(aj*E[*X.*nR)}e*R!\\]%{}~ *S!&'(*%\\inx *T!+4Nm *U)(X1)T=)x.*~E)6V)cH)7g(TY)tK*^V)<]*XZ*&()GC)*s*KJ(uS)*0R(|h*aT)@q)).(X2)Ej([1(X>(o3)+=#2$*U!CD%KM%PSUVX%_a%df%kn%tw%} *V!&'%)-%3568%:=?%EG%IK%_ (Uz(TR(]e(TV),<(cT(T[(V,(Td+'J(z|(lW(Tn)y2(U,(b}(U4(tS)cY(c})Qp(mt*4h*{l)Q3)re+2\\(T|(V3+2U(U!IV (V'*9O(zk(ie(kV(VX(d!CSY[d *uP*X](c)(eR(c!5=M *X\\(c!ur (_!u{ (`!(GMYZfx{v *?`(a!>CBQT (^N*0<(V!OW]V|u (W&(Vr(W!V.] (XF(W!0`bDf (X!@I )>3(X!@A (cx(d0*q!lqp *r'*qy*r!328?JU]bhj~ *s!*4M *a!vz|x *b!2':9<@ *Y|*Z!&'*.%03%57;<>%@BDJL%RT%VY[\\^%ac%jnor%vy{~ *[!'()+%-01348:;A%EH%MO%Z\\]_`cf *b!>6UKDVJMYlhb]aqu *c!+1OKP^\\fps (`'(th(a!cmn (b&(hQ(b!8>X (e<)be)s[),1(_!ho +'G(dl),>)lW))7(o/(p!3+ (rV(s!;DP (n!ehfoujk (o?(n!w~ (o!LhNi_^KPYV (p!7. (oo(p! (ov(p!*_bdc\\B~y (q)(p!ng *[!hjl%prsuw%y{}~ *\\!&'%*-%/1%79;%FIJLMO%UW%ik%~ *]!&' (q!<>. (pw(q!1OJuQ (r!=DYarX *{}+2^)4t*9!@DFVQoKUX^`r *:!&, *9w*:!68Q *9!_~u *:!9:/ *9!p{hqf *:!2< *9k*:!OweR}uJb@FziA *;!&/ *:t*;!)* *:!NC *;!1fpq *:v*!&B *=!ti7Brf[\\M( *<|*>0*=!SD *>!f[dc} *?!89+:) *>!FPs *?!'=? *>!;w *?!r~ *@!(> *?n*@+*?!{pk *@8*?!RjeH *@!=;d )kc*A7*@H*A8*@w*A9*^!/0%OTjv| *_!.1%35%8;=%@C%FHIK%MPQTWZ%^`cghkqrtx} *`!')*,%.2%467?@DFKMP *A!U: *@!WT *A!XGgc]y )s0*A!Bqz *B!JN-5 *Ax*B!TB+_]Vyg *C!)LtRvc *D0),!;E (t!bg *2m(t{(u'(t~(bw(}!'*19 )5h)6!-b~ )7!4DAX )83)7`)8!J\\T )9e):U)9!)2Fl )8~)9!dB )8z)9!ft ):!QW?^ )9|):!=- );X)9!~v );!KG ):!jz );&):k);!,'d )<1);s))),H).])ko),N(cn(e!NZFEXosc (f!OV%XZG (e~(f![]'6 (g!-? (f!{uh (g!EF/ (f!zj (g!H{Xm_}RQ~ (h&(fv(gN(h'(g!fjw (h!+,. (g!TUO (h/(gz(h!0m9rOfEtuacy| (i`(j!/U (i!Bf:N8I5 *b!HILNOQ%SXZ%\\^%`d%fi%koprtv%y{%} *c!&'%),%.02%EG%JL%NQ%[]_%eg%oq (i!0On%p,)U (j!+r (i|(j!QY( (iz(j?(iw(j!v1 (it(k&(j!]^49 (k!1> (ji(kf(jq(k!23 (jt(k-(j!}d (k!6,9: (j!lm (k!/<+ *^~(k!eOSHkjEGnt (l!F'E (ks(l!;PGJ:BtR_Yijs (m!(Dilrv (n!1'5;@FEX ))!Wa\\Yy )*!*+ *c!rtu~ *d!'(%*,-/034:% *U~)(!Xf )-!W[fkmpy} ).!'38@G *J@)-E)d!ruy|} )e!/-:9>T[U^`cm_of *e!ab%~ *f!&'%g )eg)f!*&4 )ev)f!10(5L8?KDc`js )g!&)8 *8;(tK*yn(t!J( *{!8<%AILRUY\\_befh%j )*o)+')*z)+!,;6OKTI *XS)+!hgq~ ),'*73).!OTaZ )/5).y)/6).!lo )/!078 ).!ux )/!*KgXMA?[]%VX%p )0!CVos )1-)0!v\\ket )1!l;1]XFZ4 )2!GMB: )R!op{} )S!4W~ )T))S[)T!LMF, )S`)T!5+O@C )S_)T!(DS *g!qr%vx%~ *h!&'%79%y )U5)T!|a )U!?D )T!\\Ync )U!'I*1 )To)U!KNP/ )V4)Uk)V!AC )UZ)V!67 )U!X\\x_ )Wd)V!jh )W!(X )Vb)W!*[0' )V|)W`)VN)WV)VQ)Wu)X!_?\\ )YJ)X!PwDE )W!|o )X5)Y!wI0x )Zl)Y!z=?USOoLg'Z7 )[!H,- )Z!cT8nu )[!1Z )Z!iHh )[!osr^Xb` )\\^*h!z{%~ *i!&'%TV%~ *j!&') )\\!V4FCOn{km| )]!NWOmi )^!*9 ({!7;LJ\\o )l,*~h);:(|!BL *L\\(|N*[<*Qv*_!Gdfv *`&*_!uzw *`+*_y*`!=(u!xkq (v!F& (u|(v!K2yzQ|WLm (w'(v}(w!MO,>.[ (x)(w!epW} (x7*4p(x!l]9< (y!'T (xt(y!;= (xz(y!ILZ?OAEr (z!'&BGP (|!sz (z!ju ({*(z!acr *~!?ABDIGJKORTZ\\]`be%gijlmoq *.!9;=?BC *k!34%:<%~ *l!&'%: *.!GJXZ%\\cefjnquz{ */!),/023N7;] )FP)G!/@ )Ft)GA)F!sq}|\\ )H6)G!iNQmE )HC)J=)H})I!GH )Hz*o!(4>DILV[aouvx%~ *p!&(%s )IL)Hq)I!3) )J&)Hd)I8)J@)Ia)J/)Ij)J!,S:OgG )I\\)KB)J!VW )KD)J!X52Hjv )K1)J!z| )K!J'7@U )Jd)KV)J\\)Ku)LL)Kc)L!45 )M))Kh)L!a[ )Md)L!mxR )M!R= )L!ZEu )M!@UTm[o )f!Je )P!:;@=KLFSTZc *^!UW[%]_`bacdfhklnqu *p!tu%~ *q!&'%6;NVbgjmor%xz%|~ *r!&-%0479@DEG%IL%PR%TVY[\\ac%gin%z} *s!&' *^!wxy *_!)+ *\\j)5!'37;>=A@H *7`)k!EJUegi )>/)@!789Sb )DW)@!L^I )^`)C5)@!f}z )A&)@~*2<)A!OD1?FQGgt| )B!>4Urs} )C'*X!236;=@EFHIGMUY *N!AD%FH%K )d!3d )c{)d!+4CDIPRTW )7r)8C)9h*s!)+.%02378:%CE%LNOQRTUWX\\_`eghmnpqs%|~ *t!&'%+/%24%689<>%ACFGIN%PT%VXY[%_acd );E)=,*2:)Q!JS]UYegfmux%z )R!(0+19 )>!0Pf )c!kptN *DV(`0*3!|yp *4@)CH*4!A5/18;k%n_FH]Q[ )CN*4!aouxq *5!89 *4v*5')CS*5=*Ue*5!aIWC]sw~ *6!F+,C2;NO?9 (q~(xw*6!ZTc )Ym*6!u| *7E)Cd*7!C4 *t!ef%moprsuw%{~ *u!&'(*%@BCEG%wz *w!'(%+-0%G )/n)0!63@ )/s)0!2< )1+)2!-4 )3!+wk )4!@F{ *3!]\\ )SA)TK)WF)t!+-5>LMF )?M)t!bQRn%pTqZaX^ )u!*I23 )t[)u,)t|)u!(Fwovcx} )v!&5<(W\\Lou )w/)vw)w!=NH^ +4.+2!>@A )q!1DM9GHZbYmfux )r!78.*AO *w!HI%~ *x!&'%N )r!ILftdgsx )s!-.>CK )l!7=KHEXov )m'*0!@IG *Oi*0!P\\Yaif )p!f~ *Ii*m!89:>=?@BCGJHM%OVW^]`_bcegi%moprw{%~ *n!&'(*%,/%13258%:<>?ABD *x!OP%Tknruy *y!*/%TVW[]^b%dg%mp%~ *z!&'%5 *n!CEHIM%OQSVWY]\\`acdg%il%pruw%y| *o!+,*-2357%9=?@C6E%GJMOPS%UW%Z\\_`^bce%mpr%t; )s!uz *sf)y!Me[c~ )'A)y!{z )z!=3 *z!67%:<=?%[]%~ *{!&'(+%79;HMNPSWX^ )z!XVp +1m*{z){6)oz)p!',2= )k!46 )l)+/!prx%| +0!)(-/.01589;=%@BCEHLNQ%SUZ]%chdj )m!68:DAPGWX\\hUTgfzq )n!.31/62N?FLN[lfrnsy *J!BGP[]` *K!'KE.DQ_PiKULJdjO *F!+34/5 *Ek*FU*Ey*F6*E!zsl *F!EI:JLOKe}`gp\\ *G!'1 *F!vsky *G!(k *Fd*G!fgdIY5Wt%ACE%HJ%OQS%VX%[]_a%ikm%su%w *HV*G!qn *H!=' *Gl*H!;u-BE498GR2lnY )~0)}!`qt )~!)6 )}v)~!-,KabsgXc@eW]fo *&3)~|*&!.??A *(,)>D*(!AMLNRblmqw|}xu *)!.? *95)B?*1!N]dtpux} *2)*)O**u*+!KS *-:*.5+1!VR *Xs*Y!+;8X *X!gm *U!RT *c!w}{| *d8+(!;<%~ +)!&'%A *d!65D=CQRFHM`Ydaevw~ *e!()*0/5 *U`+0u*Y_*Z!9S *[!N^ *Y!\\fcak}~ *Z!(, *Y!uv *Z)*Ym*Z!:EF1GI2WKbkmz|q} *[!/5.*2&>67FG?ekqdiz *\\!+0,8: *V!*4<7JF )?=*N!PXTV +)!BC%~ +*!&'%H *N!_ei *O_*R<*u>*t!-73JELSRnqt *u)+3!loq%vx +2!CPR *s!VYZko )sM*s}*g!Ww *h8*iU*j(*k/*jM*l!Jw ++!369%< )zB++!?BD%FHINOR%WY%]_abd%kn%qx%{~ +,&+*!IJ%~ ++!&'%/12478=>@CGJ%MQ^`cmr%v|} +,!,-56;<'%+.%02%478:= *u!gp|} *v!&A=5DF *~!{z +&(+0O+&!'+-2163<=B +'!][_a`ei *yo*z!;\\ *{!*) +&!PRW`\\l^jy +'!'+7; +1![\\ *-.+0!y~ +1!&)0 *k;+1!;=y%{~} +2!'.,*/4gqt~| +3!)*0 +,!>?%~ +-!&'%~ +.!&'%~ +/!&'%ntw~ +0!'+237DGI%KMPTV%Y\\efik%twxz%} +1!'(*%/2%:<>%CE%QS%UWXZ]%ac%fh%jnpqs%uwx| +2!&()+-0%35%=?BD%OQTVWY%[]_%dfh%prsu%{} +3!&(+%/1%;>%jmny%~ +4!&'%+/%14%8 .*f.+!Zv .,!oy .-!;<%>@BCGN%PRSV%X -R!XY%~ -S!&'%N")); + var gbk = src(gbk_us); + return gbk; +}(); + +var gbk_build = GBK$1; + +export default gbk_build \ No newline at end of file diff --git a/src/utils/bluetoothPrinter/printerOrder.ts b/src/utils/bluetoothPrinter/printerOrder.ts new file mode 100644 index 0000000..e60a2d9 --- /dev/null +++ b/src/utils/bluetoothPrinter/printerOrder.ts @@ -0,0 +1,179 @@ +/** + * 蓝牙打印订单 + */ +import { getStorage } from '../storage' +import toast from '../toast' +import { store } from '@/store' +import { jx_trembling, timeFormatD, timeFormatHMS } from '../tools' +import urlConfig from "@/api/config"; +import useGlobalFunc from '@/composables/useGlobalFunc' +import useOrderInfo from '@/composables/useOrderInfo' +const { isTrades } = useGlobalFunc() +const { bluetoothPrinter } = useOrderInfo() + + +/*********************************************新订单提示******************************************** + * @desc 使用递归形式,或者使用定时器的方式来写,循环去请求接口,如果没有新数据立马结束本次请求 + */ +// 准备来新订单播放的音频 +const newOrderMp3 = uni.createInnerAudioContext() + + +// abort() 需要使用这个方法来中断请求 +let listen: any = null + + + +/************************************************************************* + * 监听新订单,使用递归的方式监听 + */ +export let listenOrder: any = async () => { + // 定义变量判断门店是否在印业状态 + + // 判断店铺是否在线 + let storeInfo = store.state.storeInfo.allStoreInfo + let currentFlag: boolean = isTrades(new Date()) + + // 判断如果没有登录或者是没有 storeID 就停止递归监听 + if (!getStorage('storeID') || !getStorage('token')) return false + + // 无网络不监听 + if (!store.state.serveInfo.isNetWork) return false + + try { + // 定义一个变量来保存数据 + interface NewOrderDataType { + storeID: string + waitingSecond: number + lastOrderTime?: string + lastOrderSeqID?: number + } + let newOrderData: NewOrderDataType = { + storeID: getStorage('storeID'), + waitingSecond: 86400 + } + newOrderData.lastOrderTime = timeFormatHMS(+new Date()) + // 开始进入递归监听 + if (listen) listen.abort() // 中断请求 + listen = uni.request({ + url: urlConfig + '/v2/cms/GetNewOrderMsg', + data: newOrderData, + header: { + token: getStorage('token') + }, + success: ({ data }) => { + let { code, data: res } = (data as AnyObject) + if (code == 0) { + // 刷新订单页面 + store.commit('serveInfo/setUpdateOrder', Date.now()) + res = JSON.parse(res) + // 判断是否是tabBar页面 + if (getCurrentPages().length == 1) { + uni.setTabBarBadge({ index: 0, text: '新' }) + } + console.log('订单状态发生改变', res) + shake() + // 新订单,语音播报提醒,其他处理操作 + if (res.Type === 'newOrder') { + getPrintOrders() + // 判断门店是否处于营业状态,设置是否禁用了语音播报,当前门店是不是在休息 + if (storeInfo.status == 1 && currentFlag && getStorage('isPlayShound')) { + newOrderMp3.src = 'https://image.jxc4.com/image/e640abe4c40032490264674da03434af.jpg' + newOrderMp3.stop() + newOrderMp3.play() + } + } else if (res.Type === "newWait4ApproveAfsOrder") { + // 售后单待处理 + if (storeInfo.status == 1 && currentFlag && getStorage('isPlayShound')) { + newOrderMp3.src = 'https://image.jxc4.com/image/0a6fe4e82f2905e42012074f66f81698.jpg' + newOrderMp3.stop() + newOrderMp3.play() + } + } else { + // 订单状态发生改变 + if (storeInfo.status == 1 && currentFlag && getStorage('isPlayShound')) { + newOrderMp3.src = 'https://image.jxc4.com/image/dafc928fa23d688ce71aa645f9b77c90.jpg' + newOrderMp3.stop() + newOrderMp3.play() + } + } + listenOrderThrottles() + } else { + // 发生错误继续监听 + listenOrderThrottles() + } + }, + fail: (error) => { + // 如果不是主动中断请求就继续监听 + if (!error.errMsg.includes('abort')) { + listenOrderThrottles() + } + } + }) + + } catch (error) { + toast('系统发生错误请重启应用') + } +} + + +// 节流防止重复播报 +let newListFun: any = null +let listenOrderThrottles = jx_trembling(() => { + newListFun = listenOrder + listenOrder() + listenOrder = null + listenOrder = newListFun +}, 5000) + + + + + +/**********************使用蓝牙打印机进行打印************************ + * + */ +// 获取订单数据 +let getOrderJson = { + storeIDs: JSON.stringify([getStorage('storeID')]), + fromDate: timeFormatD(+new Date()), + toDate: timeFormatD(+new Date()), + statuss: JSON.stringify([5, 10, 15, 17, 18, 20, 22]), + offset: 0, + pageSize: -1 +} + + +/************************************************* + * 连续震动提醒 +*/ +function shake() { + let timer: any = null + let timer1: any = null + uni.vibrateLong({ + success: () => { + clearTimeout(timer) + timer = setTimeout(() => { + uni.vibrateLong({ + success: () => { + clearTimeout(timer1) + timer1 = setTimeout(() => { + uni.vibrateLong({}) + clearTimeout(timer1) + }, 700) + } + }) + clearTimeout(timer) + }, 700) + } + }) +} + + +/************************************************* + * 打印订单 +*/ +async function getPrintOrders() { + if (!getStorage('deviceName')) return + bluetoothPrinter(getOrderJson, 2) +} \ No newline at end of file diff --git a/src/utils/bluetoothPrinter/printerTemplate.ts b/src/utils/bluetoothPrinter/printerTemplate.ts new file mode 100644 index 0000000..6f45e79 --- /dev/null +++ b/src/utils/bluetoothPrinter/printerTemplate.ts @@ -0,0 +1,632 @@ + +import { store } from '@/store'; +import PrinterJobs from '@/utils/bluetoothPrinter/printerjobs' +import printerUtil from '@/utils/bluetoothPrinter/printerutil.js' +import util from '@/utils/bluetoothPrinter/util.js' +import { getStorage } from '../storage'; +import { timeFormatHMS } from '../tools'; +/************************************************* + * 打印机模板 + * @param {string} size 模板大小 0:小号 1:中号 2:大号 + * @return {} 蓝牙打印订单 +*/ +const printerTemplate = async function (data: AnyObject) { + let tmpOrder = data.orderInfo + let tmpSkus = data.skus + let storeName = store.state.storeInfo.allStoreInfo.name ? store.state.storeInfo.allStoreInfo.name : '京西菜市' + let storeTel = store.state.storeInfo.allStoreInfo.tel1 ? store.state.storeInfo.allStoreInfo.tel1 : '18048531223' + let p = new PrinterJobs() + let size = +getStorage('printerRetrySize') || 0 + switch (size) { + // 小号 + case 0: + // 平台名称 + p + .clear() + .setSize(2, 2) + .setAlign('ct') + .print(`${vendorID2(tmpOrder.vendorID)}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 下单时间 + .setSize(1, 1) + .setAlign('lt') + .print(`下单时间:${timeFormatHMS(tmpOrder.orderCreatedAt)}`) + + // 预计送达时间 + .setSize(1, 1) + .setAlign('lt') + .print(`预计送达:${expectTime(tmpOrder)}`) + + // 客户姓名 + .setSize(1, 1) + .setAlign('lt') + .print(`客户姓名:${tmpOrder.consigneeName}`) + + // 客户电话 + .setSize(1, 1) + .setAlign('lt') + .print(`客户电话:${tmpOrder.consigneeMobile}`) + + // 订单编号 + .setSize(1, 2) + .setAlign('lt') + .printArrayP(30) + .print(`订单编号:${tmpOrder.vendorOrderID}`) + + // 订单序号 + .setSize(2, 2) + .setBold(true) + .setAlign('ct') + .printArrayP(30) + .print(`${vendorID2(tmpOrder.vendorID)}#${tmpOrder.orderSeq}`) + + // 条形码 + if (tmpOrder.vendorOrderID.length < 18 && !getStorage('printerCompatible')) { + p + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + } + + // 饿佰取货码 + if (tmpOrder.vendorID === 3) { + p + .setSize(1, 2) + .setAlign('ct') + .printArrayP(30) + .print(`饿百取货码: ${tmpOrder.vendorOrderID2.slice(tmpOrder.vendorOrderID2.length - 4)}`) + } + + // 分割线 + p + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 客户地址 + .setSize(1, 2) + .setAlign('lt') + .print(`客户地址:${tmpOrder.consigneeAddress}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 客户备注 + .setSize(1, 2) + .setAlign('lt') + .print(`客户备注:${tmpOrder.buyerComment}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 商品列表 + .setSize(1, 1) + .setAlign('lt') + .print('商品列表') + if (!getStorage('printerGoodsMoney')) { + // 打印 + p + .print('品名 数量 单价') + .print(printerUtil.fillLine()) + tmpSkus.forEach((item: any, index: number) => { + console.log('ZSW-item', item); + // let comparePrice = item.salePrice / 100 + // 老赵要求改为平台价,不要优惠后的价格 + let comparePrice = item.vendorPrice / 100 + p.print(`${index + 1}.${item.skuName}`) + p.print(util.goodsGandle('', `x${item.count}`, `¥${(comparePrice * 1).toFixed(2)}`)) + + // 蓝牙打印机地方设置打印 upc + if (getStorage('isPrinterUpc') && item.upc) { + p.print(`UPC: ${item.upc}`) + } + + p.print(printerUtil.fillLine()) + }) + } else { + // 不打印 + p + .print('品名 数量') + .print(printerUtil.fillLine()) + tmpSkus.forEach((item: any, index: number) => { + p.print(`${index + 1}.${item.skuName}`) + p.print(util.goodsGandle('', '', `x${item.count}`)) + + // 蓝牙打印机地方设置打印 upc + if (getStorage('isPrinterUpc') && item.upc) { + p.print(`UPC: ${item.upc}`) + } + + p.print(printerUtil.fillLine()) + }) + } + + p + .print(`共${tmpOrder.skuCount}种${tmpOrder.goodsCount}件商品`) + if (!getStorage('printerGoodsMoney')) { + p + .print(`实付金额: ¥${(tmpOrder.actualPayPrice / 100).toFixed(2)}`) + } + + // 分割线 + p + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 商品质量问题 + .setSize(1, 2) + .setAlign('ct') + .print('商品质量问题') + .print(storeTel) + .println(storeName) + + // 兼容模式条形码 + if (tmpOrder.vendorOrderID.length < 18 && getStorage('printerCompatible')) { + p + .setSize(1, 1) + .setAlign('ct') + .print(`#${tmpOrder.orderSeq}号兼容模式条形码`) + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + .println() + .println() + } else { + p + // 结束 + .setSize(1, 1) + .print(printerUtil.fillAround(`#${tmpOrder.orderSeq}完`)) + .println() + .println() + } + break + // 中号 + case 1: + // 平台名称 + p + .clear() + .setSize(2, 2) + .setAlign('ct') + .print(`${vendorID2(tmpOrder.vendorID)}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 下单时间 + .setSize(1, 1) + .setAlign('lt') + .print(`下单时间:${timeFormatHMS(tmpOrder.orderCreatedAt)}`) + + // 预计送达时间 + .setSize(1, 1) + .setAlign('lt') + .print(`预计送达:${expectTime(tmpOrder)}`) + + // 客户姓名 + .setSize(1, 1) + .setAlign('lt') + .print(`客户姓名:${tmpOrder.consigneeName}`) + + // 客户电话 + .setSize(1, 1) + .setAlign('lt') + .print(`客户电话:${tmpOrder.consigneeMobile}`) + + // 订单编号 + .setSize(1, 2) + .setAlign('lt') + .printArrayP(30) + .print(`订单编号:${tmpOrder.vendorOrderID}`) + + // 订单序号 + .setSize(2, 2) + .setBold(true) + .setAlign('ct') + .printArrayP(30) + .print(`${vendorID2(tmpOrder.vendorID)}#${tmpOrder.orderSeq}`) + + // 条形码 + if (tmpOrder.vendorOrderID.length < 18 && !getStorage('printerCompatible')) { + p + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + } + + // 饿佰取货码 + if (tmpOrder.vendorID === 3) { + p + .setSize(1, 2) + .setAlign('ct') + .printArrayP(30) + .print(`饿百取货码: ${tmpOrder.vendorOrderID2.slice(tmpOrder.vendorOrderID2.length - 4)}`) + } + + // 分割线 + p + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 客户地址 + .setSize(1, 2) + .setAlign('lt') + .setBold(true) + .print(`客户地址:${tmpOrder.consigneeAddress}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 客户备注 + .setSize(1, 2) + .setAlign('lt') + .setBold(true) + .print(`客户备注:${tmpOrder.buyerComment}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 商品列表 + .setSize(1, 1) + .setAlign('lt') + .setBold(true) + .print('商品列表') + if (!getStorage('printerGoodsMoney')) { + p + .print('品名 数量 单价') + .setSize(1, 1) + .print(printerUtil.fillLine()) + .setSize(1, 1) + .setBold(true) + tmpSkus.forEach((item: any, index: number) => { + // let comparePrice = item.salePrice / 100 + let comparePrice = item.vendorPrice / 100 + p.print(`${index + 1}.${item.skuName}`) + p.print(util.goodsGandle('', `x${item.count}`, `¥${(comparePrice * 1).toFixed(2)}`)) + + // 蓝牙打印机地方设置打印 upc + if (getStorage('isPrinterUpc') && item.upc) { + p.print(`UPC: ${item.upc}`) + } + + p.print(printerUtil.fillLine()) + }) + } else { + p + .print('品名 数量') + .setSize(1, 1) + .print(printerUtil.fillLine()) + .setSize(1, 1) + .setBold(true) + tmpSkus.forEach((item: any, index: number) => { + p.print(`${index + 1}.${item.skuName}`) + p.print(util.goodsGandle('', '', `x${item.count}`)) + + // 蓝牙打印机地方设置打印 upc + if (getStorage('isPrinterUpc') && item.upc) { + p.print(`UPC: ${item.upc}`) + } + + p.print(printerUtil.fillLine()) + }) + } + + + p + .setSize(1, 1) + .setBold(true) + .print(`共${tmpOrder.skuCount}种${tmpOrder.goodsCount}件商品`) + if (!getStorage('printerGoodsMoney')) { + p + .print(`实付金额: ¥${(tmpOrder.actualPayPrice / 100).toFixed(2)}`) + } + + // 分割线 + p + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 商品质量问题 + .setSize(1, 2) + .setAlign('ct') + .setBold(true) + .print('商品质量问题') + .print(storeTel) + .println(storeName) + + // 兼容模式条形码 + if (tmpOrder.vendorOrderID.length < 18 && getStorage('printerCompatible')) { + p + .setSize(1, 1) + .setAlign('ct') + .print(`#${tmpOrder.orderSeq}号兼容模式条形码`) + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + .println() + .println() + } else { + p + // 结束 + .setSize(1, 1) + .print(printerUtil.fillAround(`#${tmpOrder.orderSeq}完`)) + .println() + .println() + } + break + // 大号 + case 2: + // 平台名称 + p + .clear() + .setSize(2, 2) + .setAlign('ct') + .print(`${vendorID2(tmpOrder.vendorID)}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 下单时间 + .setSize(1, 1) + .setAlign('lt') + .setBold(true) + .print(`下单时间:${timeFormatHMS(tmpOrder.orderCreatedAt)}`) + + // 预计送达时间 + .setSize(1, 1) + .setAlign('lt') + .setBold(true) + .print(`预计送达:${expectTime(tmpOrder)}`) + + // 预计送达时间 + .setSize(1, 1) + .setAlign('lt') + .setBold(true) + .print(`客户姓名:${tmpOrder.consigneeName}`) + + // 预计送达时间 + .setSize(1, 1) + .setAlign('lt') + .setBold(true) + .print(`客户电话:${tmpOrder.consigneeMobile}`) + + // 订单编号 + .setSize(1, 2) + .setAlign('lt') + .setBold(true) + .printArrayP(30) + .print(`订单编号:${tmpOrder.vendorOrderID}`) + + // 订单序号 + .setSize(2, 2) + .setBold(true) + .setAlign('ct') + .printArrayP(30) + .print(`${vendorID2(tmpOrder.vendorID)}#${tmpOrder.orderSeq}`) + + // 条形码 + if (tmpOrder.vendorOrderID.length < 18 && !getStorage('printerCompatible')) { + p + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + } + + // 饿佰取货码 + if (tmpOrder.vendorID === 3) { + p + .setSize(1, 2) + .setAlign('ct') + .setBold(true) + .printArrayP(30) + .print(`饿百取货码: ${tmpOrder.vendorOrderID2.slice(tmpOrder.vendorOrderID2.length - 4)}`) + } + + // 分割线 + p + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 客户地址 + .setSize(2, 2) + .setAlign('lt') + .setBold(true) + .print(`客户地址:${tmpOrder.consigneeAddress}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 客户备注 + .setSize(2, 2) + .setAlign('lt') + .setBold(true) + .print(`客户备注:${tmpOrder.buyerComment}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 商品列表 + .setSize(1, 2) + .setAlign('lt') + .setBold(true) + .print('商品列表') + if (!getStorage('printerGoodsMoney')) { + p + .print('品名 数量 单价') + .setSize(1, 2) + .print(printerUtil.fillLine()) + .setSize(1, 2) + .setBold(true) + tmpSkus.forEach((item: any, index: number) => { + // let comparePrice = item.salePrice / 100 + let comparePrice = item.vendorPrice / 100 + p.print(`${index + 1}.${item.skuName}`) + p.print(util.goodsGandle('', `x${item.count}`, `¥${(comparePrice * 1).toFixed(2)}`)) + + // 蓝牙打印机地方设置打印 upc + if (getStorage('isPrinterUpc') && item.upc) { + p.print(`UPC: ${item.upc}`) + } + + p.print(printerUtil.fillLine()) + }) + } else { + p + .print('品名 数量') + .setSize(1, 2) + .print(printerUtil.fillLine()) + .setSize(1, 2) + .setBold(true) + tmpSkus.forEach((item: any, index: number) => { + p.print(`${index + 1}.${item.skuName}`) + p.print(util.goodsGandle('', '', `x${item.count}`)) + + // 蓝牙打印机地方设置打印 upc + if (getStorage('isPrinterUpc') && item.upc) { + p.print(`UPC: ${item.upc}`) + } + + p.print(printerUtil.fillLine()) + }) + } + + p + .setSize(2, 2) + .setBold(true) + .print(`共${tmpOrder.skuCount}种${tmpOrder.goodsCount}件商品`) + if (!getStorage('printerGoodsMoney')) { + p + .print(`实付:¥${(tmpOrder.actualPayPrice / 100).toFixed(2)}`) + } + + // 分割线 + p + .setSize(1, 1) + .print(printerUtil.fillLine()) + + // 商品质量问题 + .setSize(2, 2) + .setAlign('ct') + .setBold(true) + .print('商品质量问题') + .print(storeTel) + .println(storeName) + + // 兼容模式条形码 + if (tmpOrder.vendorOrderID.length < 18 && getStorage('printerCompatible')) { + p + .setSize(1, 1) + .setAlign('ct') + .print(`#${tmpOrder.orderSeq}号兼容模式条形码`) + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + .println() + .println() + } else { + p + // 结束 + .setSize(1, 1) + .print(printerUtil.fillAround(`#${tmpOrder.orderSeq}完`)) + .println() + .println() + } + break + // 开发者模板 + case 3: + p + .clear() + // 开始 + .setSize(2, 2) + .setAlign('ct') + .print(`${vendorID2(tmpOrder.vendorID)}`) + + // 分割线 + .setSize(1, 1) + .print(printerUtil.fillAround(`#${tmpOrder.orderSeq}`)) + .println() + + // 订单序号 + .setSize(2, 2) + .setBold(true) + .setAlign('ct') + .print(`${vendorID2(tmpOrder.vendorID)}#${tmpOrder.orderSeq}`) + + // 条形码 + if (tmpOrder.vendorOrderID.length < 18 && !getStorage('printerCompatible')) { + p + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + } + + // 兼容模式条形码 + if (tmpOrder.vendorOrderID.length < 18 && getStorage('printerCompatible')) { + p + .setSize(1, 1) + .setAlign('ct') + .print(`#${tmpOrder.orderSeq}号兼容模式条形码`) + .printQrFormat(tmpOrder.vendorOrderID) + .print(tmpOrder.vendorOrderID) + .println() + .println() + } else { + p + // 结束 + .setSize(1, 1) + .print(printerUtil.fillAround(`#${tmpOrder.orderSeq}完`)) + .println() + .println() + } + break + } + + let buffer = await p.buffer() + return buffer +} + +// 处理平台名字 +function vendorID2(vendorID: number) { + switch (vendorID) { + case 0: + return '京东到家' + case 1: + return '美团外卖' + case 2: + return '饿了么' + case 3: + return '饿百新零售' + case 5: + return '京东商城' + case 9: + return '京西菜市' + case 11: + return '微盟' + case 14: + return '抖音小时购' + case 16: + return '淘鲜达' + default: + return '未知平台' + } +} + +// 无预计送达时间的情况 +function expectTime(tmpOrder: AnyObject) { + let timer + try { + if (!tmpOrder.expectedDeliveredTime || tmpOrder.expectedDeliveredTime.indexOf('1970') !== -1) { + timer = new Date(new Date(tmpOrder.orderCreatedAt).getTime() + 60 * 60 * 1000) + } else { + timer = new Date(tmpOrder.expectedDeliveredTime) + } + return timeFormatHMS(+timer) + } catch (e) { + return 'YYYY-MM-DD hh:mm:ss' + } +} + +export default printerTemplate \ No newline at end of file diff --git a/src/utils/bluetoothPrinter/printerjobs.js b/src/utils/bluetoothPrinter/printerjobs.js new file mode 100644 index 0000000..c5b432c --- /dev/null +++ b/src/utils/bluetoothPrinter/printerjobs.js @@ -0,0 +1,190 @@ +import _ from './commands' +import gbk_build from './gbk' + +const PrinterJobs = function () { + this._queue = Array.from(_.HARDWARE.HW_INIT); + this._enqueue = function (cmd) { + this._queue.push.apply(this._queue, cmd); + } +} + +/** + * 增加打印内容 + * @param {string} content 文字内容 + */ +PrinterJobs.prototype.text = function (content) { + if (content) { + let uint8Array = gbk_build.encode(content); + let encoded = Array.from(uint8Array); + this._enqueue(encoded); + } + return this; +} + +/** + * 打印文字 + * @param {string} content 文字内容 + */ +PrinterJobs.prototype.print = function (content) { + this.text(content); + this._enqueue(_.LF); + return this; +} + + +/** + * 打印条形码 + * @param {string} content 打印条形码 + */ +PrinterJobs.prototype.printQrFormat = function (code) { + // 段前40点高度 + this._enqueue([27,74,40]) + // 居中 + this._enqueue([27,97,1]) + // 在一维码下面添加编号 + this._enqueue([29, 72, 2]) + // 条形码高度 + this._enqueue([29, 104, 140]) + // 条形码宽度 + this._enqueue([29, 119, 2]) + // 打印类型 + this._enqueue([29, 107, 72, code.length]) + return this; +} + + +PrinterJobs.prototype.printArrayP = function (num) { + this._enqueue([27,74,num]) + return this +} + + + +/** + * 打印文字并换行 + * @param {string} content 文字内容 + */ +PrinterJobs.prototype.println = function (content = '') { + return this.print(content + _.EOL) +} + +/** + * 设置对齐方式 + * @param {string} align 对齐方式 LT/CT/RT + */ +PrinterJobs.prototype.setAlign = function (align) { + this._enqueue(_.TEXT_FORMAT['TXT_ALIGN_' + align.toUpperCase()]) + return this +} + +/** + * 设置字体 + * @param {string} family A/B/C + */ +PrinterJobs.prototype.setFont = function (family) { + this._enqueue(_.TEXT_FORMAT['TXT_FONT_' + family.toUpperCase()]) + return this +} + +/** + * 设定字体尺寸 + * @param {number} width 字体宽度 1~2 + * @param {number} height 字体高度 1~2 + */ +PrinterJobs.prototype.setSize = function (width, height) { + if (2 >= width && 2 >= height) { + this._enqueue(_.TEXT_FORMAT.TXT_NORMAL) + if (2 === width && 2 === height) { + this._enqueue(_.TEXT_FORMAT.TXT_4SQUARE) + } else if (1 === width && 2 === height) { + this._enqueue(_.TEXT_FORMAT.TXT_2HEIGHT) + } else if (2 === width && 1 === height) { + this._enqueue(_.TEXT_FORMAT.TXT_2WIDTH) + } + } + return this +} + +/** + * 设定字体是否加粗 + * @param {boolean} bold + */ +PrinterJobs.prototype.setBold = function (bold) { + if (typeof bold !== 'boolean') { + bold = true; + } + this._enqueue(bold ? _.TEXT_FORMAT.TXT_BOLD_ON : _.TEXT_FORMAT.TXT_BOLD_OFF) + return this +} + +/** + * 设定是否开启下划线 + * @param {boolean} underline + */ +PrinterJobs.prototype.setUnderline = function (underline) { + if (typeof underline !== 'boolean') { + underline = true + } + this._enqueue(underline ? _.TEXT_FORMAT.TXT_UNDERL_ON : _.TEXT_FORMAT.TXT_UNDERL_OFF) + return this +} + +/** + * 设置行间距为 n 点行,默认值行间距是 30 点 + * @param {number} n 0≤n≤255 + */ +PrinterJobs.prototype.setLineSpacing = function (n) { + if (n === undefined || n === null) { + this._enqueue(_.LINE_SPACING.LS_DEFAULT) + } else { + this._enqueue(_.LINE_SPACING.LS_SET) + this._enqueue([n]) + } + return this +} + +/** + * 打印空行 + * @param {number} n + */ +PrinterJobs.prototype.lineFeed = function (n = 1) { + return this.print(new Array(n).fill(_.EOL).join('')) +} + +/** + * 设置字体颜色,需要打印机支持 + * @param {number} color - 0 默认颜色黑色 1 红色 + */ +PrinterJobs.prototype.setColor = function (color) { + this._enqueue(_.COLOR[color === 1 ? 1 : 0]) + return this +} + +/** + * https://support.loyverse.com/hardware/printers/use-the-beeper-in-a-escpos-printers + * 蜂鸣警报,需要打印机支持 + * @param {number} n 蜂鸣次数,1-9 + * @param {number} t 蜂鸣长短,1-9 + */ +PrinterJobs.prototype.beep = function (n, t) { + this._enqueue(_.BEEP) + this._enqueue([n, t]) + return this +} + +/** + * 清空任务 + */ +PrinterJobs.prototype.clear = function () { + this._queue = Array.from(_.HARDWARE.HW_INIT); + return this +} + +/** + * 返回ArrayBuffer + */ +PrinterJobs.prototype.buffer = function () { + return new Uint8Array(this._queue).buffer +} + +export default PrinterJobs diff --git a/src/utils/bluetoothPrinter/printerutil.js b/src/utils/bluetoothPrinter/printerutil.js new file mode 100644 index 0000000..f529b18 --- /dev/null +++ b/src/utils/bluetoothPrinter/printerutil.js @@ -0,0 +1,93 @@ +// 打印机纸宽58mm,页的宽度384,字符宽度为1,每行最多盛放32个字符 +const PAGE_WIDTH = 384; +const MAX_CHAR_COUNT_EACH_LINE = 32; + +/** + * @param str + * @returns {boolean} str是否全是中文 + */ +function isChinese(str) { + return /^[\u4e00-\u9fa5]$/.test(str); +} + +/** + * 返回字符串宽度(1个中文=2个英文字符) + * @param str + * @returns {number} + */ +function getStringWidth(str) { + let width = 0; + for (let i = 0, len = str.length; i < len; i++) { + width += isChinese(str.charAt(i)) ? 2 : 1; + } + return width; +} + +/** + * 同一行输出str1, str2,str1居左, str2居右 + * @param {string} str1 内容1 + * @param {string} str2 内容2 + * @param {number} fontWidth 字符宽度 1/2 + * @param {string} fillWith str1 str2之间的填充字符 + * + */ +function inline(str1, str2, fillWith = ' ', fontWidth = 1) { + const lineWidth = MAX_CHAR_COUNT_EACH_LINE / fontWidth; + // 需要填充的字符数量 + let fillCount = lineWidth - (getStringWidth(str1) + getStringWidth(str2)) % lineWidth; + let fillStr = new Array(fillCount).fill(fillWith.charAt(0)).join(''); + return str1 + fillStr + str2; +} + +/** + * 用字符填充一整行 + * @param {string} fillWith 填充字符 + * @param {number} fontWidth 字符宽度 1/2 + */ +function fillLine(fillWith = '-', fontWidth = 1) { + const lineWidth = MAX_CHAR_COUNT_EACH_LINE / fontWidth; + return new Array(lineWidth).fill(fillWith.charAt(0)).join(''); +} + +/** + * 文字内容居中,左右用字符填充 + * @param {string} str 文字内容 + * @param {number} fontWidth 字符宽度 1/2 + * @param {string} fillWith str1 str2之间的填充字符 + */ +function fillAround(str, fillWith = '-', fontWidth = 1) { + const lineWidth = MAX_CHAR_COUNT_EACH_LINE / fontWidth; + let strWidth = getStringWidth(str); + // 内容已经超过一行了,没必要填充 + if (strWidth >= lineWidth) { + return str; + } + // 需要填充的字符数量 + let fillCount = lineWidth - strWidth; + // 左侧填充的字符数量 + let leftCount = Math.round(fillCount / 2); + // 两侧的填充字符,需要考虑左边需要填充,右边不需要填充的情况 + let fillStr = new Array(leftCount).fill(fillWith.charAt(0)).join(''); + return fillStr + str + fillStr.substr(0, fillCount - leftCount); +} + +// ArrayBuffer转16进度字符串示例 +function ab2hex(buffer) { + const hexArr = Array.prototype.map.call( + new Uint8Array(buffer), + function (bit) { + return ('00' + bit.toString(16)).slice(-2) + } + ) + return hexArr.join(',') +} + + +const printerUtil = { + inline: inline, + fillLine: fillLine, + fillAround: fillAround, + ab2hex: ab2hex, +} + +export default printerUtil \ No newline at end of file diff --git a/src/utils/bluetoothPrinter/util.js b/src/utils/bluetoothPrinter/util.js new file mode 100644 index 0000000..241efe7 --- /dev/null +++ b/src/utils/bluetoothPrinter/util.js @@ -0,0 +1,242 @@ +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 +} + + +//4合1 +function convert4to1(res) { + let arr = []; + for (let i = 0; i < res.length; i++) { + if (i % 4 == 0) { + let rule = 0.29900 * res[i] + 0.58700 * res[i + 1] + 0.11400 * res[i + 2]; + if (rule > 200) { + res[i] = 0; + } else { + res[i] = 1; + } + arr.push(res[i]); + } + } + return arr; +} + +//8合1 +function convert8to1(arr) { + let data = []; + for (let k = 0; k < arr.length; k += 8) { + let temp = arr[k] * 128 + arr[k + 1] * 64 + arr[k + 2] * 32 + arr[k + 3] * 16 + arr[k + 4] * 8 + arr[k + 5] * 4 + + arr[k + 6] * 2 + arr[k + 7] * 1 + data.push(temp); + } + return data; +} + +//我的图片宽度是240,那么拼接的指令就是[29, 118, 48, 0, 30, 0, 240, 0] +//我的图片宽度是160,那么拼接的指令就是[29, 118, 48, 0, 20, 0, 160, 0] +//补充一点,打印非二维码的图片,宽度一定要是24的倍数,不然打印也会出现乱码 +function toArrayBuffer(res) { + let arr = convert4to1(res.data); + let data = convert8to1(arr); + let cmds = [].concat([27, 97, 1], [29, 118, 48, 0, 30, 0, 240, 0], data, [27, 74, 3], [27, 64]); + return new Uint8Array(cmds); +} + +function zip_image(res) { + let arr = convert4to1(res.data); + let data = convert8to1(arr); + return data; +} + +/** + * 商品列表处理,防止数据过多超出标线 + */ +function goodsGandle(a, b, c) { + var name = addName(a) + var SL = addSL(b) + var DJ = addDJ(c) + return name + SL + DJ +} +function addName(str) { + str = ' ' + str + var l = len(str) + var zl = 14 + var bl = zl - l + for (var i = 0; i < bl; i++) { + str += ' ' + } + return str +} +function addSL(str) { + var l = len(str) + var zl = 11 + var bl = zl - l + for (var i = 0; i < bl; i++) { + str += ' ' + } + return str +} +function addDJ(str) { + var l = len(str) + var zl = 5 + var bl = zl - l + for (var i = 0; i < bl; i++) { + str = ' ' + str + } + return str +} +function len(s) { + var l = 0 + var a = s.split('') + for (var i = 0; i < a.length; i++) { + if (a[i].charCodeAt(0) < 299) { + l++ + } else { + l += 2 + } + } + return l +} + +/************************************************* +* 打印机工具 +*/ + +/** + * 蓝牙错误状态信息 + */ +function BTStatus(code) { + switch (code) { + case 10000: + return '未初始化蓝牙适配器' + break + case 10001: + return '当前蓝牙适配器不可用' + break + case 10002: + return '没有找到指定设备' + break + case 10003: + return '连接失败请重试' + break + case 10004: + return '没有找到指定服务请重试' + break + case 10005: + return '没有找到指定特征值请重试' + break + case 10006: + return '当前连接已断开' + break + case 10007: + return '当前设备不支持' + break + case 10008: + return '系统发生异常' + break + case 10009: + return '系统版本低于 4.3 不支持 BLE' + break + default: + return '打印机未启动' + } +} + +/** + * @desdc 第二步初判断本机蓝牙是否可用 + * 获取本机蓝牙适配器状态 + */ +function getBTAdapterState() { + return new Promise((resolve, reject) => { + uni.getBluetoothAdapterState({ + success(res) { + resolve(res) + }, + fail(error) { + reject(BTStatus(error.errMsg)) + } + }) + }) +} + + + +/** + * @desc 第八步 + * 查询打印机状态 + */ +function notifyBLEState(deviceId, serviceId, characteristicId) { + // 发送给蓝牙打印机判断的状态 + let buf + let dateView + buf = new ArrayBuffer(3) + dateView = new DataView(buf) + dateView.setUint8(0, 16) + dateView.setUint8(1, 4) + dateView.setUint8(2, 2) + + return new Promise((resolve, reject) => { + // 发送信息给蓝牙打印机 + uni.writeBLECharacteristicValue({ + deviceId: deviceId, + serviceId: serviceId, + characteristicId: characteristicId, + value: buf, + fail(error) { + reject(BTStatus(error.errMsg)) + }, + }); + + // 收到蓝牙发回的信息 + uni.notifyBLECharacteristicValueChange({ + deviceId: deviceId, + serviceId: serviceId, + characteristicId: characteristicId, + state: true, + success(res) { + resolve(12) + // 不知为何这个api调用不起来,导致蓝牙打印机打不出任何信息,以前是可以用的 + // 监听蓝牙特征变化 + // uni.onBLECharacteristicValueChange(function (r) { + // let result = +ab2hex(r.value); + // resolve(result) + // }) + }, + fail(error) { + // reject(BTStatus(error.errMsg)) + reject(BTStatus(error.errCode)) + } + }) + }) +} +// ArrayBuffer转16进度字符串 +function ab2hex(buffer) { + var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) { + return ("00" + bit.toString(16)).slice(-2); + }); + return hexArr.join(""); + +} + +const util = { + formatTime: formatTime, + toArrayBuffer: toArrayBuffer, + zip_image: zip_image, + goodsGandle: goodsGandle, + getBTAdapterState: getBTAdapterState, + notifyBLEState: notifyBLEState + +} + +export default util diff --git a/src/utils/configCms.ts b/src/utils/configCms.ts new file mode 100644 index 0000000..cf8b87f --- /dev/null +++ b/src/utils/configCms.ts @@ -0,0 +1,544 @@ +/** + * @desc 公共系统配置文件 + * @author zhangshuwei + * @time 2022年12月25日 + * @Email 2966211270@qq.com + */ + + +export default { + /************************************************* + * 美团开放平台 589 secret + */ + app_secret_589: 'a81eb3df418d83d6a1a4b7c572156d2f', + app_key_589: 'a81eb3df418d83d6', + + /************************************************* + * 美团开放平台 5873 secret + */ + app_secret_5873: '41c479790a76f86326f89e8048964739', + app_key_5873: '41c479790a76f863', + + + /************************************************* + * 查询服务器版本id + */ + appId: 'wx18111a41fd17f24f', + + + /************************************************* + * 营业状态 + */ + "storeStatus": { + "0": "临时休息", + "1": "营业中", + "-1": "休息", + "-2": "禁用" + }, + + /************************************************* + * 不需要token验证的白名单接口 + */ + whiteListUrl: [ + '/v2/auth2/Login', + '/v2/auth2/AddAuthBindWithMobile', + '/v2/auth2/GetUserByMiniInfo', + '/v2/auth2/GetTokenInfo', + '/v2/auth2/SendVerifyCode', + '/v2/user2/RegisterUser', + '/v2/user2/GetMyStoreList', + '/v2/cms/GetServiceInfo', + '/v2/user2/GetSelfInfo', + '/v2/act/QueryActs', + '/v2/order/GetOrders', + '/v2/order/GetOrderInfo', + '/v2/cms/CreateQrOrBarCode', + '/v2/order/GetOrderStatusList', + '/v2/order/GetAfsOrders', + '/v2/order/GetOrderSkuInfo', + '/v2/order/ComplaintRiderList' + ], + + + /************************************************* + * 系统信息为防止出现花里胡哨的错误把他放在本地 + */ + serveInfo: { + "actCreateTypeName": { + "1": "API", + "2": "回调", + "3": "网页" + }, + "actStatusName": { + "0": "未知", + "1": "正常", + "2": "取消", + "3": "结束" + }, + "actTypeName": { + "0": "结算", + "3": "直降", + "4": "秒杀", + "5": "折扣" + }, + "afsAppealTypeName": { + "1": "仅退款", + "2": "退款", + "3": "退款." + }, + "afsReasonTypeName": { + "0": "其它", + "1": "商品质量", + "2": "错误的商品", + "3": "缺少部分商品", + "4": "全部商品未收到", + "5": "商品有损伤", + "6": "缺斤少两", + // "7": "商家通知我缺货", + "7": "买多或者买少", + "8": "商品与描述不符", + "9": "误购", + "10": "未在时效内送达" + }, + "apiFunctionName": { + "AddStoreCourierMap": "门店绑定三方配送平台", + "AddStoreVendorMap": "门店绑定", + "AutoPayForPopluarMan": "每日订单打款", + "CancelOrder": "取消订单", + "CopyStoreSkus": "京西门店商品复制到京西", + "CreateStore": "门店管理-创建门店", + "DeleteStore": "门店管理-删除门店", + "DeleteStoreCourierMap": "门店解绑三方配送平台", + "DeleteStoreVendorMap": "门店解绑", + "Login": "登录", + "RegisterUser": "注册", + "SyncStoresQualify": "上传门店营业资质", + "UpdateSku": "修改sku", + "UpdateSkuName": "修改skuName", + "UpdateStore": "门店管理-更新门店信息", + "UpdateStoreCourierMap": "门店修改三方配送平台绑定信息", + "UpdateStoreVendorMap": "门店修改平台绑定信息", + "UpdateStoresSkus": "门店商品管理", + "UpdateStoresSkusSale": "门店商品可售状态修改" + }, + "autoReplyTypeName": { + "0": "全部自动回复", + "1": "禁止差评自动回复", + "2": "禁止自动回复" + }, + "autoSaleAt": "22:00:00", + "categoryType": { + "0": "普通类别", + "1": "特殊类别" + }, + "complaintReasons": { + "1": "骑手态度恶劣", + "2": "骑手接单后未取货", + "3": "骑手取货太慢", + "4": "骑手送货太慢", + "5": "货品未送达", + "6": "货品有损坏", + "7": "骑手违规收取顾客其他费用", + "69": "骑手恶意取消订单", + "71": "骑手提前点击取货/送达" + }, + "configTypeName": { + "Bank": "银行", + "Cookie": "Cookie", + "DiscountCard": "会员折扣卡", + "FreightPack": "免运包", + "JxStore": "京西商城", + "PricePack": "价格包", + "Reply": "评论回复模板", + "Role": "角色", + "Sys": "系统" + }, + "couponsStatus": { + "0": "正常", + "1": "已被使用", + "-1": "已过期", + "-2": "还没生效", + "-4": "已删除" + }, + "ebaiSupplierID": { + "2233065879": "饿百好菜", + "2267230126": "饿百果园", + "1921188187760": "饿百商超", + "22267134648": "饿百菜市" + }, + "ebaiSupplierInfo": { + "2233065879": { + "supplierID": "2233065879", + "logo": "https://image-star.elemecdn.com/pb/b79d499b9b0be5deb3ee3ce71bf29ad0a8", + "Categorys": [ + { + "category1": 277, + "category2": 180 + }, + { + "category1": 277, + "category2": 184 + }, + { + "category1": 277, + "category2": 183 + }, + { + "category1": 277, + "category2": 181 + }, + { + "category1": 277, + "category2": 182 + } + ], + "BusinessFormID": 1917869373, + "BrandName": "好菜鲜生" + }, + "2267230126": { + "supplierID": "2267230126", + "logo": "https://fuss10.elemecdn.com/7/21/a4b2877a916e1af6c5bdbf5945d51jpeg.jpeg", + "Categorys": [ + { + "category1": 274, + "category2": 190 + } + ], + "BusinessFormID": 1917867465, + "BrandName": "京西果园" + }, + "1921188187760": { + "supplierID": "1921188187760", + "logo": "https://image-star.elemecdn.com/pb/dab294b0d3e9fa4b5fa63007ff02d06e98", + "Categorys": [ + { + "category1": 166, + "category2": 222 + } + ], + "BusinessFormID": 1672214913, + "BrandName": "京西到家" + }, + "22267134648": { + "supplierID": "22267134648", + "logo": "https://fuss10.elemecdn.com/1/34/c6d76d8e3aa86cf214e6bff5514c1jpeg.jpeg", + "Categorys": [ + { + "category1": 277, + "category2": 180 + }, + { + "category1": 277, + "category2": 184 + }, + { + "category1": 277, + "category2": 183 + }, + { + "category1": 277, + "category2": 181 + }, + { + "category1": 277, + "category2": 182 + } + ], + "BusinessFormID": 1917869373, + "BrandName": "京西菜市" + } + }, + "opRequestStatusName": { + "0": "待审核", + "1": "已批准", + "-1": "拒绝" + }, + "opRequestTypeName": { + "1": "更改价格", + "2": "关注商品" + }, + "operateType": { + "1": "修改", + "2": "新增", + "4": "删除" + }, + "orderStatus": { + "0": "一般事件", + "2": "待付款", + "3": "待接单", + "5": "新订单", + "10": "待拣货", + "15": "待配送", + "17": "取货失败待审核", + "18": "取货失败", + "20": "配送中", + "22": "投递失败", + "110": "完成", + "115": "取消", + "155": "待审核", + "160": "已审核", + "165": "退货待确认", + "167": "退货已收到", + "180": "售后成功", + "190": "售后失败", + "-10": "取消申请取消", + "-100": "通知消息", + "-20": "锁定", + "-25": "解锁", + "-5": "申请取消", + "-55": "催单", + "-6": "同意取消", + "-65": "订单调整完成", + "-7": "拒绝取消", + "-70": "取货失败审核驳回", + "-80": "小费变动" + }, + "orderTypeName": { + "1": "订单", + "2": "运单", + "3": "售后单" + }, + "payStatusName": { + "0": "待支付", + "1": "已支付", + "2": "支付失败", + "3": "支付取消", + "4": "已退款" + }, + "printerStatusName": { + "0": "未知", + "1": "离线", + "2": "正常", + "3": "异常" + }, + "printerVendorInfo": { + "201": [ + "飞鹅", + "序列号", + "KEY" + ], + "202": [ + "外卖管家", + "打印机编号", + "不填" + ], + "203": [ + "易联云", + "终端号", + "密钥" + ], + "204": [ + "中午云", + "打印机ID", + "打印机密钥" + ], + "205": [ + "京西云", + "打印机编号", + "密钥" + ], + "206": [ + "芯烨云", + "打印机编号", + "不填" + ], + "207": [ + "大趋智能", + "打印机编号", + "打印机密钥" + ] + }, + "purchaseVendorInfo": { + "0": { + "chineseName": "京东到家", + "userApplyCancelWaitMinute": 15 + }, + "1": { + "chineseName": "美团外卖", + "userApplyCancelWaitMinute": 30 + }, + "3": { + "chineseName": "饿百新零售", + "userApplyCancelWaitMinute": 15 + } + }, + "refundStatusName": { + "0": "待退款", + "1": "已退款", + "2": "退款失败" + }, + "shopChineseNames": { + "0": "京西菜市", + "1": "京西菜市", + "2": "饿鲜达", + "3": "饿鲜达", + "9": "京西菜市商城", + "11": "微盟微商城" + }, + "skuNamePrefix": [ + "新鲜", + "组合菜", + "熟食", + "鲜活现杀", + "冰冻", + "净菜", + "非熟食" + ], + "skuNameUnit": [ + "份", + "袋", + "瓶", + "只", + "组", + "个", + "盒", + "把", + "半只", + "包", + "条", + "根", + "箱", + "听", + "套", + "罐", + "件", + "块", + "片", + "支", + "杯", + "桶", + "串", + "提" + ], + "skuSpecUnit": [ + "g", + "kg", + "L", + "ml" + ], + "skuStatus": { + "0": "下架", + "1": "上架", + "2": "删除", + "3": "不可售", + "4": "可售", + "-1": "删除" + }, + "storeAuditStatusName": { + "0": "上线", + "1": "待审核", + "-1": "拒绝" + }, + "storeDeliveryRangeType": { + "2": "多边形", + "3": "圆" + }, + "storeDeliveryType": { + "0": "平台众包", + "1": "平台专送", + "2": "门店自送" + }, + "storeMsgSendStatusName": { + "0": "发送中", + "1": "成功", + "2": "部分成功", + "3": "失败" + }, + "storePriceTypeName": { + "0": "普通门店" + }, + "storeStatus": { + "0": "临时休息", + "1": "营业中", + "-1": "休息", + "-2": "禁用" + }, + "supplementType": { + "1": "差评退款", + "2": "优惠券" + }, + "taskStatusName": { + "0": "运行中", + "1": "取消中", + "2": "结束", + "3": "已取消", + "4": "失败" + }, + "thingType": { + "1": "分类", + "2": "商品库", + "3": "门店商品", + "4": "门店" + }, + "userTypeName": { + "1": "消费者", + "2": "门店老板", + "4": "运营", + "8": "老板", + "16": "受权限管理" + }, + "vendorName": { + "0": "京东到家", + "1": "美团外卖", + "2": "饿了么", + "3": "饿百新零售", + "4": "银豹", + "5": "京东商城", + "9": "京西商城", + "11": "微盟微商城", + "12": "国美", + "14": "抖店平台", + "16": "淘鲜达", + "101": "达达众包", + "102": "美团配送", + "103": "蜂鸟配送", + "105": "UU跑腿", + "106": "顺丰同城", + "201": "飞鹅", + "202": "外卖管家", + "203": "易联云", + "204": "中午云", + "205": "京西云", + "206": "芯烨云", + "207": "大趋智能", + "301": "微信公众号", + "302": "微信扫码", + "303": "微信小程序", + "311": "钉钉H5微应用", + "312": "钉钉移动接入应用(登录)", + "321": "高德导航", + "323": "七牛云", + "325": "万维易源", + "401": "京东物流" + }, + "vendorStatus": { + "0": "休息", + "1": "营业" + }, + "vendorTypeName": { + "0": "未知", + "1": "购物平台", + "2": "快递平台", + "9": "其它" + }, + "waybillStatus": { + "0": "一般事件", + "5": "新运单", + "7": "压单", + "8": "取消接受", + "10": "已接单", + "12": "已分配骑手", + "13": "骑手已取件", + "15": "已到店", + "17": "取货失败待审核", + "18": "取货失败", + "20": "配送中", + "22": "投递失败", + "26": "骑手已到达取件人地址处", + "105": "送达", + "115": "取消", + "120": "失败", + "999": "暂无配送信息" + } + } +} \ No newline at end of file diff --git a/src/utils/emoji.ts b/src/utils/emoji.ts new file mode 100644 index 0000000..47dc7f9 --- /dev/null +++ b/src/utils/emoji.ts @@ -0,0 +1,464 @@ +export const emojiArr = [ + { + text: '[微笑]', + symbol: 'smile', + position: [0, 0] + }, + { + text: '[撇嘴]', + symbol: 'pieMouth', + position: [-60, 0] + }, + { + text: '[色]', + symbol: 'tity', + position: [-120, 0] + }, + { + text: '[发呆]', + symbol: 'asleep', + position: [-180, 0] + }, + { + text: '[得意]', + symbol: 'complacent', + position: [-240, 0] + }, + { + text: '[流泪]', + symbol: 'shedTears', + position: [-300, 0] + }, + { + text: '[害羞]', + symbol: 'shy', + position: [-360, 0] + }, + { + text: '[闭嘴]', + symbol: 'shutUp', + position: [-420, 0] + }, + { + text: '[睡]', + symbol: 'sleep', + position: [0, -60] + }, + { + text: '[大哭]', + symbol: 'bigCry', + position: [-60, -60] + }, + { + text: '[尴尬]', + symbol: 'awkward', + position: [-120, -60] + }, + { + text: '[发怒]', + symbol: 'flareUp', + position: [-180, -60] + }, + { + text: '[调皮]', + symbol: 'naughty', + position: [-240, -60] + }, + { + text: '[呲牙]', + symbol: 'bareTeeth', + position: [-300, -60] + }, + { + text: '[惊讶]', + symbol: 'amazed', + position: [-360, -60] + }, + { + text: '[难过]', + symbol: 'feelSorry', + position: [-420, -60] + }, + { + text: '[酷]', + symbol: 'cool', + position: [0, -120] + }, + { + text: '[囧]', + symbol: 'orz', + position: [-60, -120] + }, + { + text: '[抓狂]', + symbol: 'crazy', + position: [-120, -120] + }, + { + text: '[吐]', + symbol: 'vomit', + position: [-180, -120] + }, + { + text: '[偷笑]', + symbol: 'titter', + position: [-240, -120] + }, + { + text: '[愉快]', + symbol: 'happy', + position: [-300, -120] + }, + { + text: '[白眼]', + symbol: 'whiteEye', + position: [-360, -120] + }, + { + text: '[傲慢]', + symbol: 'arrogance', + position: [-420, -120] + }, + { + text: '[饥饿]', + symbol: 'hunger', + position: [0, -180] + }, + { + text: '[困]', + symbol: 'tired', + position: [-60, -180] + }, + { + text: '[惊恐]', + symbol: 'terrified', + position: [-120, -180] + }, + { + text: '[流汗]', + symbol: 'sweat', + position: [-180, -180] + }, + { + text: '[憨笑]', + symbol: 'smileFatuously', + position: [-240, -180] + }, + { + text: '[悠闲]', + symbol: 'easy', + position: [-300, -180] + }, + { + text: '[奋斗]', + symbol: 'struggle', + position: [-360, -180] + }, + { + text: '[咒骂]', + symbol: 'swear', + position: [-420, -180] + }, + { + text: '[疑问]', + symbol: 'query', + position: [0, -240] + }, + { + text: '[嘘]', + symbol: 'hiss', + position: [-60, -240] + }, + { + text: '[晕]', + symbol: 'giddy', + position: [-120, -240] + }, + { + text: '[疯了]', + symbol: 'insane', + position: [-180, -240] + }, + { + text: '[衰]', + symbol: 'decline', + position: [-240, -240] + }, + { + text: '[骷髅]', + symbol: 'skull', + position: [-300, -240] + }, + { + text: '[敲打]', + symbol: 'beat', + position: [-360, -240] + }, + { + text: '[再见]', + symbol: 'goodbye', + position: [-420, -240] + }, + { + text: '[擦汗]', + symbol: 'wipePerspiration', + position: [0, -300] + }, + { + text: '[抠鼻]', + symbol: 'pickNose', + position: [-60, -300] + }, + { + text: '[鼓掌]', + symbol: 'applaud', + position: [-120, -300] + }, + { + text: '[糗大了]', + symbol: 'embarrassed', + position: [-180, -300] + }, + { + text: '[坏笑]', + symbol: 'snicker', + position: [-240, -300] + }, + { + text: '[左哼哼]', + symbol: 'leftHum', + position: [-300, -300] + }, + { + text: '[右哼哼]', + symbol: 'rightHum', + position: [-360, -300] + }, + { + text: '[哈欠]', + symbol: 'yawn', + position: [-420, -300] + }, + { + text: '[鄙视]', + symbol: 'disdain', + position: [0, -360] + }, + { + text: '[委屈]', + symbol: 'grievance', + position: [-60, -360] + }, + { + text: '[快哭了]', + symbol: 'cring', + position: [-120, -360] + }, + { + text: '[阴险]', + symbol: 'cattiness', + position: [-180, -360] + }, + { + text: '[亲亲]', + symbol: 'kiss', + position: [-240, -360] + }, + { + text: '[吓]', + symbol: 'threaten', + position: [-300, -360] + }, + { + text: '[可怜]', + symbol: 'pitiful', + position: [-360, -360] + }, + { + text: '[菜刀]', + symbol: 'kitchenKnife', + position: [-420, -360] + }, + { + text: '[西瓜]', + symbol: 'watermelon', + position: [0, -420] + }, + { + text: '[啤酒]', + symbol: 'beer', + position: [-60, -420] + }, + { + text: '[篮球]', + symbol: 'basketball', + position: [-120, -420] + }, + { + text: '[乒乓]', + symbol: 'ping-pong', + position: [-180, -420] + }, + { + text: '[咖啡]', + symbol: 'coffee', + position: [-240, -420] + }, + { + text: '[饭]', + symbol: 'rice', + position: [-300, -420] + }, + { + text: '[猪头]', + symbol: 'pigHead', + position: [-360, -420] + }, + { + text: '[玫瑰]', + symbol: 'rose', + position: [-420, -420] + }, + { + text: '[凋谢]', + symbol: 'fade', + position: [0, -480] + }, + { + text: '[嘴唇]', + symbol: 'lip', + position: [-60, -480] + }, + { + text: '[爱心]', + symbol: 'love', + position: [-120, -480] + }, + { + text: '[心碎]', + symbol: 'heartbreak', + position: [-180, -480] + }, + { + text: '[蛋糕]', + symbol: 'cake', + position: [-240, -480] + }, + { + text: '[闪电]', + symbol: 'lightning', + position: [-300, -480] + }, + { + text: '[炸弹]', + symbol: 'bombs', + position: [-360, -480] + }, + { + text: '[刀]', + symbol: 'knife', + position: [-420, -480] + }, + { + text: '[足球]', + symbol: 'soccer', + position: [0, -540] + }, + { + text: '[瓢虫]', + symbol: 'ladybird', + position: [-60, -540] + }, + { + text: '[便便]', + symbol: 'excrement', + position: [-120, -540] + }, + { + text: '[月亮]', + symbol: 'moon', + position: [-180, -540] + }, + { + text: '[太阳]', + symbol: 'sun', + position: [-240, -540] + }, + { + text: '[礼物]', + symbol: 'gift', + position: [-300, -540] + }, + { + text: '[拥抱]', + symbol: 'embrace', + position: [-360, -540] + }, + { + text: '[强]', + symbol: 'strong', + position: [-420, -540] + }, + { + text: '[弱]', + symbol: 'weak', + position: [0, -600] + }, + { + text: '[握手]', + symbol: 'handshake', + position: [-60, -600] + }, + { + text: '[胜利]', + symbol: 'victory', + position: [-120, -600] + }, + { + text: '[抱拳]', + symbol: 'holdFist', + position: [-180, -600] + }, + { + text: '[勾引]', + symbol: 'seduce', + position: [-240, -600] + }, + { + text: '[拳头]', + symbol: 'fist', + position: [-300, -600] + }, + { + text: '[差劲]', + symbol: 'bad', + position: [-360, -600] + }, + { + text: '[爱你]', + symbol: 'loveYou', + position: [-420, -600] + }, + { + text: '[NO]', + symbol: 'no', + position: [0, -660] + }, + { + text: '[OK]', + symbol: 'ok', + position: [-60, -660] + } +] + +/** + * @description emoji表情 + * @param type 值和美团返回的保持一致 + * @returns + */ +export const emojiAnanlyze = (type: string) => { + let emojiSymbol = type + let findItem = emojiArr.findIndex(item => item.text === emojiSymbol) + if (findItem !== -1) emojiSymbol = emojiArr[findItem].symbol + return emojiSymbol +} \ No newline at end of file diff --git a/src/utils/log.js b/src/utils/log.js new file mode 100644 index 0000000..870c6f9 --- /dev/null +++ b/src/utils/log.js @@ -0,0 +1,32 @@ +var log = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null +const LOG = { + debug() { + if (!log) return + log.debug.apply(log, arguments) + }, + info() { + if (!log) return + log.info.apply(log, arguments) + }, + warn() { + if (!log) return + log.warn.apply(log, arguments) + }, + error() { + if (!log) return + log.error.apply(log, arguments) + }, + setFilterMsg(msg) { // 从基础库2.7.3开始支持 + if (!log || !log.setFilterMsg) return + if (typeof msg !== 'string') return + log.setFilterMsg(msg) + }, + addFilterMsg(msg) { // 从基础库2.8.1开始支持 + if (!log || !log.addFilterMsg) return + if (typeof msg !== 'string') return + log.addFilterMsg(msg) + } +} + + +export default LOG \ No newline at end of file diff --git a/src/utils/md5.js b/src/utils/md5.js new file mode 100644 index 0000000..e1e1d9b --- /dev/null +++ b/src/utils/md5.js @@ -0,0 +1,492 @@ +class utilsMd5 { + constructor() { + + } + +} +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +utilsMd5.hex_md5 = function (s) { + return binl2hex(core_md5(str2binl(s), s.length * chrsz)); +} + +function heyh_md5(s) { + return binl2hex(core_md5(str2binl(s), s.length * chrsz)); +} + +function b64_md5(s) { + return binl2b64(core_md5(str2binl(s), s.length * chrsz)); +} + +function str_md5(s) { + return binl2str(core_md5(str2binl(s), s.length * chrsz)); +} + +function hex_hmac_md5(key, data) { + return binl2hex(core_hmac_md5(key, data)); +} + +function b64_hmac_md5(key, data) { + return binl2b64(core_hmac_md5(key, data)); +} + +function str_hmac_md5(key, data) { + return binl2str(core_hmac_md5(key, data)); +} + +/* + * Perform a simple self-test to see if the VM is working + */ +function md5_vm_test() { + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +} + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ +function core_md5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for (var i = 0; i < x.length; i += 16) { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936); + d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844); + d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) { + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); +} + +function md5_ff(a, b, c, d, x, s, t) { + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} + +function md5_gg(a, b, c, d, x, s, t) { + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} + +function md5_hh(a, b, c, d, x, s, t) { + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} + +function md5_ii(a, b, c, d, x, s, t) { + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Calculate the HMAC-MD5, of a key and some data + */ +function core_hmac_md5(key, data) { + var bkey = str2binl(key); + if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); + + var ipad = Array(16), + opad = Array(16); + for (var i = 0; i < 16; i++) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return core_md5(opad.concat(hash), 512 + 128); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert a string to an array of little-endian words + * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. + */ +function str2binl(str) { + var bin = Array(); + var mask = (1 << chrsz) - 1; + for (var i = 0; i < str.length * chrsz; i += chrsz) + bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32); + return bin; +} + +/* + * Convert an array of little-endian words to a string + */ +function binl2str(bin) { + var str = ""; + var mask = (1 << chrsz) - 1; + for (var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask); + return str; +} + +/* + * Convert an array of little-endian words to a hex string. + */ +function binl2hex(binarray) { + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i++) { + str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) + + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF); + } + return str; +} + +/* + * Convert an array of little-endian words to a base-64 string + */ +function binl2b64(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i += 3) { + var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16) | + (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8) | + ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF); + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); + } + } + return str; +} + + +var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var base64DecodeChars = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1); + +utilsMd5.base64encode = function (str) { + var out, i, len; + var c1, c2, c3; + + len = str.length; + i = 0; + out = ""; + while (i < len) { + c1 = str.charCodeAt(i++) & 0xff; + if (i == len) { + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt((c1 & 0x3) << 4); + out += "=="; + break; + } + c2 = str.charCodeAt(i++); + if (i == len) { + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); + out += base64EncodeChars.charAt((c2 & 0xF) << 2); + out += "="; + break; + } + c3 = str.charCodeAt(i++); + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); + out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)); + out += base64EncodeChars.charAt(c3 & 0x3F); + } + return out; +} + +utilsMd5.base64decode = function (str) { + var c1, c2, c3, c4; + var i, len, out; + + len = str.length; + i = 0; + out = ""; + while (i < len) { + /* c1 */ + do { + c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; + } while (i < len && c1 == -1); + if (c1 == -1) + break; + + /* c2 */ + do { + c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; + } while (i < len && c2 == -1); + if (c2 == -1) + break; + + out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); + + /* c3 */ + do { + c3 = str.charCodeAt(i++) & 0xff; + if (c3 == 61) + return out; + c3 = base64DecodeChars[c3]; + } while (i < len && c3 == -1); + if (c3 == -1) + break; + + out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2)); + + /* c4 */ + do { + c4 = str.charCodeAt(i++) & 0xff; + if (c4 == 61) + return out; + c4 = base64DecodeChars[c4]; + } while (i < len && c4 == -1); + if (c4 == -1) + break; + out += String.fromCharCode(((c3 & 0x03) << 6) | c4); + } + return out; +} + +function base64decode(str) { + var c1, c2, c3, c4; + var i, len, out; + + len = str.length; + i = 0; + out = ""; + while (i < len) { + /* c1 */ + do { + c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; + } while (i < len && c1 == -1); + if (c1 == -1) + break; + + /* c2 */ + do { + c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; + } while (i < len && c2 == -1); + if (c2 == -1) + break; + + out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); + + /* c3 */ + do { + c3 = str.charCodeAt(i++) & 0xff; + if (c3 == 61) + return out; + c3 = base64DecodeChars[c3]; + } while (i < len && c3 == -1); + if (c3 == -1) + break; + + out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2)); + + /* c4 */ + do { + c4 = str.charCodeAt(i++) & 0xff; + if (c4 == 61) + return out; + c4 = base64DecodeChars[c4]; + } while (i < len && c4 == -1); + if (c4 == -1) + break; + out += String.fromCharCode(((c3 & 0x03) << 6) | c4); + } + return out; +} + +function utf16to8(str) { + var out, i, len, c; + + out = ""; + len = str.length; + for (i = 0; i < len; i++) { + c = str.charCodeAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) { + out += str.charAt(i); + } else if (c > 0x07FF) { + out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); + out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); + out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); + } else { + out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); + out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); + } + } + return out; +} + +function utf8to16(str) { + var out, i, len, c; + var char2, char3; + + out = ""; + len = str.length; + i = 0; + while (i < len) { + c = str.charCodeAt(i++); + switch (c >> 4) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + // 0www.jingxicaishi.com + out += str.charAt(i - 1); + break; + case 12: + case 13: + // 110x xxxx 10xx xxxx + char2 = str.charCodeAt(i++); + out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); + break; + case 14: + // 1110 xxxx 10xx xxxx 10xx xxxx + char2 = str.charCodeAt(i++); + char3 = str.charCodeAt(i++); + out += String.fromCharCode(((c & 0x0F) << 12) | + ((char2 & 0x3F) << 6) | + ((char3 & 0x3F) << 0)); + break; + } + } + + return out; +} + + +utilsMd5.JsStrencode = function (strings, key) { + + strings = base64decode(strings); + var key = heyh_md5(key); //约定的解密key 现在我们就先用这个key 哈 建议你给app创建一个 config.js 方便卖出后更改配置 不然很容易搞忘记的哦 + + var len = key.length; + var code = ''; + var k, code; + for (var i = 0; i < strings.length; i++) { + + k = i % len; + code += String.fromCharCode(strings.charCodeAt(i) ^ key.charCodeAt(k)); + } + //document.write(code+"\n"); + return base64decode(code); +} + +export { + utilsMd5 +} diff --git a/src/utils/qiniuUploader.ts b/src/utils/qiniuUploader.ts new file mode 100644 index 0000000..835c196 --- /dev/null +++ b/src/utils/qiniuUploader.ts @@ -0,0 +1,163 @@ +import log from '@/utils/log' +import { getStorage } from "@/utils/storage"; +export function qiniuyun() { + var d: any = { + qiniuUploadURL: "", + qiniuImageURLPrefix: "", + qiniuUploadToken: "", + qiniuUploadTokenURL: "", + qiniuUploadTokenFunction: null + }; + + function f(g: any) { + d = { + qiniuUploadURL: "", + qiniuImageURLPrefix: "", + qiniuUploadToken: "", + qiniuUploadTokenURL: "", + qiniuUploadTokenFunction: null + }; + e(g) + } + + function e(g: any) { + if (g.uploadURL) { + d.qiniuUploadURL = g.uploadURL + } else { + console.error("qiniu uploader need uploadURL") + } if (g.uptoken) { + d.qiniuUploadToken = g.uptoken + } else { + if (g.uptokenURL) { + d.qiniuUploadTokenURL = g.uptokenURL + } else { + if (g.uptokenFunc) { + d.qiniuUploadTokenFunction = g.uptokenFunc + } + } + } if (g.domain) { + d.qiniuImageURLPrefix = g.domain + } + } + + function c(i: any, j: any, g: any, h: any) { + if (null == i) { + console.error("qiniu uploader need filePath to upload"); + return + } + if (h) { + f(h) + } + if (d.qiniuUploadToken) { + b(i, j, g, h) + } else { + if (d.qiniuUploadTokenURL) { + a(function () { + b(i, j, g, h) + }) + } else { + if (d.qiniuUploadTokenFunction) { + d.qiniuUploadToken = d.qiniuUploadTokenFunction() + } else { + console.error("qiniu uploader need one of [uptoken, uptokenURL, uptokenFunc]"); + return + } + } + } + } + + function b(j: any, l: any, g: any, i: any) { + var h = d.qiniuUploadURL; + var m = j.split("//")[1]; + if (i && i.key) { + m = i.key + } + var k = { + "token": d.qiniuUploadToken, + "key": m + }; + uni.uploadFile({ + url: h, + filePath: j, + name: "file", + formData: k, + success: function (o) { + var q = o.data; + var p = JSON.parse(q); + var n = d.qiniuImageURLPrefix + p.key; + p.imageURL = n; + l(p) + saveImgRecod({ + url:h, + method:"POST", + params:{filePath:j,name:"file",formData:k}, + data:o, + other:n + }) + }, + fail: function (n) { + g(n) + saveImgRecod({ + url:h, + method:"POST", + params:{filePath:j,name:"file",formData:k}, + data:n + }) + } + }) + } + + function a(g: any) { + uni.request({ + url: d.qiniuUploadTokenURL, + success: function (i: any) { + var h = i.data.uptoken; + d.qiniuUploadToken = h; + if (g) { + g() + } + saveImgRecod({ + url:d.qiniuUploadTokenURL, + method:"GET", + params:"", + data:i + }) + }, + fail: function (h) { + saveImgRecod({ + url:d.qiniuUploadTokenURL, + method:"GET", + params:"", + data:h + }) + console.log(h) + } + }) + } + + // 保存上传图片的记录信息 + function saveImgRecod(obj:AnyObject){ + // url:string,method:string,dns:string,params:any + let logData = { + '日志记录时间': Date(), + '调用接口': obj.url || "", + '请求方法': obj.method || "", + '请求参数': obj.params || "", + // '请求域名': obj.dns || "", + '用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN', + '用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号', + '店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID', + '店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字', + // '网络状态码': obj.statusCode || "", + '服务端数据': obj.data || "", + '其他数据':obj.other || "" + } + log.info(JSON.stringify(logData)) + } + + + return { + init: f, + upload: c, + } +} \ No newline at end of file diff --git a/src/utils/storage.ts b/src/utils/storage.ts new file mode 100644 index 0000000..db67b89 --- /dev/null +++ b/src/utils/storage.ts @@ -0,0 +1,84 @@ +/** + * @desc 本地缓存 storage 操作类 + * @author zhangshuwei + * @time 2022年12月20日 + * @Email 2966211270@qq.com + */ + + +/** + * @desc 读取本地缓存 + * @param key 本地缓存key + */ +export const getStorage = (key: string): string => { + return uni.getStorageSync(key) +} + + +/** + * @desc 保存数据至本地缓存 + * @param key 本地缓存key + * @param value 本地缓存value + */ +export const setStorage = (key: string, value: any) => { + uni.setStorageSync(key, value) +} + + +/** + * 清除指定缓存 + * @param {key} 清除指定缓存 + */ +export const cleatStorage = (key?: string) => { + if (key) { + uni.removeStorageSync(key) + } else { + uni.clearStorageSync() + } +} + + + + +/** + * @desc 登录判断默认参数是否存在,不存在给默认值 + * @param {whiteArr} 需要给默认值的缓存 + */ +export const jx_default_storage_plugin = () => { + interface NewStorageType { + key: string, + value: any + } + let whiteArr: Array = [ + { + key: 'isPlayShound', + value: true + }, + { + key: 'isPrinterUpc', + value: false + }, + { + key: 'printerRetrySize', + value: '0' + }, + { + key: 'defaultPrinter', + value: '2' + }, + { + key: 'printerCompatible', + value: false + }, + { + key: 'printerGoodsMoney', + value: false + } + ] + + for (let i = 0; i < whiteArr.length; i++) { + if (!getStorage(whiteArr[i].key).toString()) { + setStorage(whiteArr[i].key, whiteArr[i].value) + } + } +} \ No newline at end of file diff --git a/src/utils/toast.ts b/src/utils/toast.ts new file mode 100644 index 0000000..20eb43b --- /dev/null +++ b/src/utils/toast.ts @@ -0,0 +1,49 @@ + +type IconType = "success" | "error" | "none" | "loading" | undefined + +/** + * @desc 公共弹窗简化 + * @author zhangshuwei + * @time 2022年12月12日 + * @Email 2966211270@qq.com + * @param {title}-提示内容 + * @param {type}-图标类型 1:成功 2:失败 3:无图标 + * @param {timer}-提示消失时间默认 2000 毫秒 +*/ +const toast = (title = '默认内容', type = 3, timer = 2000) => { + let icon: IconType + switch (type) { + case 1: + icon = 'success' + break + case 2: + icon = 'error' + break + case 3: + icon = 'none' + break + } + + if (icon == 'none') { + uni.showToast({ + title: title, + icon: icon, + duration: timer, + }) + } else if (icon == 'error') { + uni.showToast({ + title: title, + image: '/static/image/global/error.png', + duration: timer, + }) + } else { + uni.showToast({ + title: title, + icon: 'success', + duration: timer, + }) + } +} + + +export default toast \ No newline at end of file diff --git a/src/utils/tools.ts b/src/utils/tools.ts new file mode 100644 index 0000000..8fb7f89 --- /dev/null +++ b/src/utils/tools.ts @@ -0,0 +1,319 @@ +/************************************************* + * @desc 公共工具类 + * @author zhangshuwei + * @time 2022年12月12日 + * @Email 2966211270@qq.com + */ +import CryptoJS from 'crypto-js' +import configCms from './configCms' + + +/************************************************* + * @desc 处理时间 M-D h-m + * @param {time}-需要处理的时间 + * @return {time} - -MM-DD h-m + */ +export const timeFormatDHM = (time?: number | string) => { + let timer = time ? new Date(time) : new Date() + return `${(timer.getMonth() + 1) < 10 ? '0' + (timer.getMonth() + 1) : (timer.getMonth() + 1)}-${timer.getDate() < 10 ? '0' + timer.getDate() : timer.getDate()} ${timer.getHours() < 10 ? '0' + timer.getHours() : timer.getHours()}:${timer.getMinutes() < 10 ? '0' + timer.getMinutes() : timer.getMinutes()}` +} + + +/************************************************* + * @desc 处理时间 YYY-M-D h-m-s + * @param {time}-需要处理的时间 + * @return {time} - YYYY-MM-DD h-m-s + */ +export const timeFormatHMS = (time?: number | string) => { + let timer = time ? new Date(time) : new Date() + return `${timer.getFullYear()}-${(timer.getMonth() + 1) < 10 ? '0' + (timer.getMonth() + 1) : (timer.getMonth() + 1)}-${timer.getDate() < 10 ? '0' + timer.getDate() : timer.getDate()} ${timer.getHours() < 10 ? '0' + timer.getHours() : timer.getHours()}:${timer.getMinutes() < 10 ? '0' + timer.getMinutes() : timer.getMinutes()}:${timer.getSeconds() < 10 ? '0' + timer.getSeconds() : timer.getSeconds()}` +} + + +/************************************************* + * @desc 处理时间 YYY-M-D h-m + * @param {time}-需要处理的时间 + * @return {time} - YYYY-MM-DD h-m + */ +export const timeFormatHM = (time?: number | string) => { + let timer = time ? new Date(time) : new Date() + return `${timer.getFullYear()}-${(timer.getMonth() + 1) < 10 ? '0' + (timer.getMonth() + 1) : (timer.getMonth() + 1)}-${timer.getDate() < 10 ? '0' + timer.getDate() : timer.getDate()} ${timer.getHours() < 10 ? '0' + timer.getHours() : timer.getHours()}:${timer.getMinutes() < 10 ? '0' + timer.getMinutes() : timer.getMinutes()}` +} + +/************************************************* + * @desc 处理时间 YYY-M-D + * @param {time}-需要处理的时间 + * @return {time} - YYYY-MM-DD + */ +export const timeFormatD = (time?: number | string) => { + let timer = time ? new Date(time) : new Date() + return `${timer.getFullYear()}-${(timer.getMonth() + 1) < 10 ? '0' + (timer.getMonth() + 1) : (timer.getMonth() + 1)}-${timer.getDate() < 10 ? '0' + timer.getDate() : timer.getDate()}` +} + + +/************************************************* + * @desc 处理时间是否为空时间 + * @param {data}-处理空时间 + */ +export const isNullDate = (date: string) => { + if (!date || date.indexOf('1970-01-01') !== -1 || date.indexOf('0001-01-01') !== -1) { + return true + } else { + return false + } +} + + +/************************************************* + * @desc 判断分页是否有下一页 + * @param {pageNo}-当前页数 + * @param {size}-每页条数 + * @param {totalCount}-总条数 + * @param {fn}回调方法 + * @return {boolean} 是否有下一条 + */ +export const jxNextPage = (pageNo: number, size: number, totalCount: number, fn: Function) => { + let sumNum = pageNo * size + if (sumNum >= totalCount) { + // 没有下一页 + fn && fn(false) + } else { + // 有下一页 + fn && fn(true) + } +} + + +/************************************************* + * @desc 微信小程序 App 版本判断 + * @param {ver1}-原始版本号 + * @param {ver1}-需要判断的版本号 + * @return {boolean} 版本号大小判断 + */ +export const versionCompare = (ver1: string, ver2: string) => { + let version1pre = parseFloat(ver1) + let version2pre = parseFloat(ver2) + let version1next = parseInt(ver1.replace(version1pre + '.', '')) + let version2next = parseInt(ver2.replace(version2pre + '.', '')) + if (version1pre > version2pre) return true + else if (version1pre < version2pre) return false + else { + if (version1next > version2next) return true + else return false + } +} + +/************************************************* + * @desc 节流-在一段时间内只触发一次 + * @param {time} // 节流时间 + * @param {success} // 成功 + * @param {faile} // 失败 + * @param {complete} // 成功失败都触发 + * @param {timeInter} // 定时器 + * @return {surplus} // 剩余节流时间 + */ +interface Jx_throttle_type { + time: number + success?: Function + faile?: Function + complete?: Function +} +let time: any = null +let timeInter: any = null +let surplus: number = 0 +export const jx_throttle = (object: Jx_throttle_type) => { + if (!time) { + object.success && object.success() // 成功 + surplus = object.time / 1000 // 剩余节流秒数 + clearInterval(timeInter) // 清空上一个定时器 + timeInter = setInterval(() => { + surplus = surplus - 1 // 甚于节流时间 + }, 1000) + time = setTimeout(() => { + clearTimeout(time) // 清空上一个定时器 + time = null // 归位定时器 + surplus = 0 + }, object.time) + } else { + object.faile && object.faile(surplus) // 失败回调,传递一个参数,甚于节流时间 + } + object.complete && object.complete() // 成功失败都触发 +} + + +/************************************************* + * 防抖函数 + * @param {Function} [fun] 防抖成功回调 + * @param {number} [time] 防抖时间 + * + */ +export function jx_trembling(fun: Function, time: number) { + let timer: any = null + return function (this: any, ...args: any) { + clearTimeout(timer) + timer = setTimeout(() => { + fun.apply(this, args) + }, time) + } +} + + + +interface jx_throttlesType { + /************************************************* + * 节流时间 + */ + time: number + /************************************************* + * 节流成功回调 + */ + success: Function + /************************************************* + * 节流失败回调 + */ + fail?: Function +} +/************************************************* + * 节流函数 + */ +export function jx_throttles(options: jx_throttlesType) { + let pre: number = 0 + return function (this: any, ...args: any) { + let now = Date.now() + if (now - pre >= options.time) { + options.success && options.success.apply(this, args) + pre = Date.now() + } else { + options.fail && options.fail((((pre - now) / 1000) + options.time / 1000).toFixed(0)) + } + } +} + + +/************************************************* + * ASE解密 + * @param {string} word 解密字符串 + * @return {string} utf8 明文 +*/ +export function Decrypt(word: string, platformID: string) { + let key = platformID === '5873' ? configCms.app_key_5873 : configCms.app_key_589 + let iv = platformID === '5873' ? configCms.app_key_5873 : configCms.app_key_589 + key = CryptoJS.enc.Utf8.parse(key) + iv = CryptoJS.enc.Utf8.parse(iv) + let base64 = CryptoJS.enc.Base64.parse(word) + let src = CryptoJS.enc.Base64.stringify(base64) + // 解密模式为CBC,补码方式为PKCS5Padding(也就是PKCS7) + let decrypt = CryptoJS.AES.decrypt(src, key, { + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7, + }) + + let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8) + return decryptedStr.toString() +} + + +/************************************************* + * ASE加密 +*/ +export function Encrypt(word: string, platformID: string) { + let key = platformID === '5873' ? configCms.app_key_5873 : configCms.app_key_589 + let iv = platformID === '5873' ? configCms.app_key_5873 : configCms.app_key_589 + + key = CryptoJS.enc.Utf8.parse(key); + iv = CryptoJS.enc.Utf8.parse(iv); + + let srcs = CryptoJS.enc.Utf8.parse(word); + // 加密模式为CBC,补码方式为PKCS5Padding(也就是PKCS7) + let encrypted = CryptoJS.AES.encrypt(srcs, key, { + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }); + return CryptoJS.enc.Base64.stringify(encrypted.ciphertext); + +} + +// ******************** 请求加载提示 ***************************** +//#region +/** +* @function 请求加载提示 +* @description 传递一个说明内容【有参数showLoading,无参数hideLoading】 +* @param value {string} 加载提示内容【非必传】 +* @return void +* @example +* setLoading('登录中') +*/ +export function setLoading(value?: string) { + if (value) { + uni.showLoading({ title: value }) + } else { + uni.hideLoading() + } +} +//#endregion + + +// ******************** 添加请求记录与中断请求 ***************************** +//#region +let requestTaskList: Array = [] // 请求列表 +/** +* @function 添加请求记录 +* @description 传递一个task对象 +* @param task {object} task对象 +* @return void +* @example +* addTask({}) +*/ +export function addTask(task: AnyObject): void { + if (requestTaskList.length >= 17) { + requestTaskList = [] + } + requestTaskList.push(task) +} + +/** +* @function 中断请求 +* @description 无参数 +* @return void +* @example +* clearList() +*/ +export function clearList(): void { + requestTaskList.forEach((item) => { + item.abort() + }) + requestTaskList = [] +} +//#endregion + +/** + * JOSN.parse 导致number类型超过十五位会失真 + * string to json + */ +export function jxParse(text: string) { + let aa = text.replace(/:s*([0-9]{15,})s*(,?)/g, ': "$1" $2') + return JSON.parse(aa) +} + +export function formatBusinessTime(time:string) { + let newTime = '' + let len = (time.toString()).length + switch (len) { + case 1: + newTime = `000${time}` + break + case 2: + newTime = `00${time}` + break + case 3: + newTime = `0${time}` + break + default: + newTime = time.toString() + break + } + let str =`${newTime.slice(0, 2)}:${newTime.slice(-2)}` + return str +} \ No newline at end of file diff --git a/src/utils/weapp.qrcode.esm.js b/src/utils/weapp.qrcode.esm.js new file mode 100644 index 0000000..7231270 --- /dev/null +++ b/src/utils/weapp.qrcode.esm.js @@ -0,0 +1,5 @@ +/** + * weapp.qrcode.js v1.0.0 (https://github.com/yingye/weapp-qrcode#readme) + */ + +var hasOwn=Object.prototype.hasOwnProperty,toStr=Object.prototype.toString,defineProperty=Object.defineProperty,gOPD=Object.getOwnPropertyDescriptor,isArray=function(t){return"function"==typeof Array.isArray?Array.isArray(t):"[object Array]"===toStr.call(t)},isPlainObject=function(t){if(!t||"[object Object]"!==toStr.call(t))return!1;var e,r=hasOwn.call(t,"constructor"),o=t.constructor&&t.constructor.prototype&&hasOwn.call(t.constructor.prototype,"isPrototypeOf");if(t.constructor&&!r&&!o)return!1;for(e in t);return void 0===e||hasOwn.call(t,e)},setProperty=function(t,e){defineProperty&&"__proto__"===e.name?defineProperty(t,e.name,{enumerable:!0,configurable:!0,value:e.newValue,writable:!0}):t[e.name]=e.newValue},getProperty=function(t,e){if("__proto__"===e){if(!hasOwn.call(t,e))return;if(gOPD)return gOPD(t,e).value}return t[e]},extend=function t(){var e,r,o,n,i,a,s=arguments[0],u=1,l=arguments.length,h=!1;for("boolean"==typeof s&&(h=s,s=arguments[1]||{},u=2),(null==s||"object"!=typeof s&&"function"!=typeof s)&&(s={});u=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=QRCode.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,e)},setupPositionProbePattern:function(t,e){for(var r=-1;r<=7;r++)if(!(t+r<=-1||this.moduleCount<=t+r))for(var o=-1;o<=7;o++)e+o<=-1||this.moduleCount<=e+o||(this.modules[t+r][e+o]=0<=r&&r<=6&&(0==o||6==o)||0<=o&&o<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=o&&o<=4)},getBestMaskPattern:function(){for(var t=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var o=QRUtil.getLostPoint(this);(0==r||t>o)&&(t=o,e=r)}return e},createMovieClip:function(t,e,r){var o=t.createEmptyMovieClip(e,r);this.make();for(var n=0;n>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=o}for(r=0;r<18;r++){o=!t&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=o}},setupTypeInfo:function(t,e){for(var r=this.errorCorrectLevel<<3|e,o=QRUtil.getBCHTypeInfo(r),n=0;n<15;n++){var i=!t&&1==(o>>n&1);n<6?this.modules[n][8]=i:n<8?this.modules[n+1][8]=i:this.modules[this.moduleCount-15+n][8]=i}for(n=0;n<15;n++){i=!t&&1==(o>>n&1);n<8?this.modules[8][this.moduleCount-n-1]=i:n<9?this.modules[8][15-n-1+1]=i:this.modules[8][15-n-1]=i}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var r=-1,o=this.moduleCount-1,n=7,i=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var s=0;s<2;s++)if(null==this.modules[o][a-s]){var u=!1;i>>n&1)),QRUtil.getMask(e,o,a-s)&&(u=!u),this.modules[o][a-s]=u,-1==--n&&(i++,n=7)}if((o+=r)<0||this.moduleCount<=o){o-=r,r=-r;break}}}},QRCode.PAD0=236,QRCode.PAD1=17,QRCode.createData=function(t,e,r){for(var o=QRRSBlock.getRSBlocks(t,e),n=new QRBitBuffer,i=0;i8*s)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*s+")");for(n.getLengthInBits()+4<=8*s&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*s||(n.put(QRCode.PAD0,8),n.getLengthInBits()>=8*s));)n.put(QRCode.PAD1,8);return QRCode.createBytes(n,o)},QRCode.createBytes=function(t,e){for(var r=0,o=0,n=0,i=new Array(e.length),a=new Array(e.length),s=0;s=0?g.get(c):0}}var d=0;for(h=0;h=0;)e^=QRUtil.G15<=0;)e^=QRUtil.G18<>>=1;return e},getPatternPosition:function(t){return QRUtil.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,r){switch(t){case QRMaskPattern.PATTERN000:return(e+r)%2==0;case QRMaskPattern.PATTERN001:return e%2==0;case QRMaskPattern.PATTERN010:return r%3==0;case QRMaskPattern.PATTERN011:return(e+r)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(e/2)+Math.floor(r/3))%2==0;case QRMaskPattern.PATTERN101:return e*r%2+e*r%3==0;case QRMaskPattern.PATTERN110:return(e*r%2+e*r%3)%2==0;case QRMaskPattern.PATTERN111:return(e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new QRPolynomial([1],0),r=0;r5&&(r+=3+i-5)}for(o=0;o=256;)t-=255;return QRMath.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},i=0;i<8;i++)QRMath.EXP_TABLE[i]=1<=1&&n<=127?e+=t.charAt(r):n>2047?(e+=String.fromCharCode(224|n>>12&15),e+=String.fromCharCode(128|n>>6&63),e+=String.fromCharCode(128|n>>0&63)):(e+=String.fromCharCode(192|n>>6&31),e+=String.fromCharCode(128|n>>0&63));return e}function drawQrcode(t){t=t||{},(t=extend(!0,{width:256,height:256,x:0,y:0,typeNumber:-1,correctLevel:QRErrorCorrectLevel.H,background:"#ffffff",foreground:"#000000",image:{imageResource:"",dx:0,dy:0,dWidth:100,dHeight:100}},t)).canvasId||t.ctx?function(){var e,r=new QRCode(t.typeNumber,t.correctLevel);r.addData(utf16to8(t.text)),r.make(),e=t.ctx?t.ctx:t._this?wx.createCanvasContext&&wx.createCanvasContext(t.canvasId,t._this):wx.createCanvasContext&&wx.createCanvasContext(t.canvasId);for(var o=t.width/r.getModuleCount(),n=t.height/r.getModuleCount(),i=0;i>>7-t%8&1)},put:function(t,e){for(var r=0;r>>e-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};export default drawQrcode; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ef4c58f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "target": "esnext", + "useDefineForClassFields": true, + "module": "esnext", + "moduleResolution": "node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "allowJs": true, + "ignoreDeprecations":"5.0", + "suppressImplicitAnyIndexErrors": true, + "lib": [ + "esnext", + "dom" + ], + "types": [ + "@dcloudio/types", + "node" + ], + "baseUrl": ".", + "paths": { + "@": [ + "./src" + ], + "@/*": [ + "./src/*" + ] + } + }, + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "src/pages/merchant/index.scss", + "src/subPages/login/bgImg.js" + ] +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..f243bff --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vite"; +import uni from "@dcloudio/vite-plugin-uni"; +import commonjs from '@rollup/plugin-commonjs' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [uni(), commonjs()] +});