From 7f1a2ebb76959439c7db14949346cda3410c0d8c Mon Sep 17 00:00:00 2001
From: zhengyiming <540361168@qq.com>
Date: 星期一, 15 十二月 2025 15:23:12 +0800
Subject: [PATCH] feat: 新增家政小程序
---
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.config.ts | 3
apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down-active.png | 0
apps/housekeepingMiniApp/src/components/Layout/layout.ts | 19
apps/housekeepingMiniApp/src/pages/home/index.scss | 5
apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/InnerPage.vue | 125
apps/housekeepingMiniApp/package.json | 131
apps/housekeepingMiniApp/src/components/RichEditCard/RichContent.vue | 46
apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/InnerPage.vue | 124
apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/InnerPage.vue | 48
apps/housekeepingMiniApp/src/index.html | 17
apps/housekeepingMiniApp/src/subpackages/login/userPolicy/userPolicy.vue | 238
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.config.ts | 3
apps/housekeepingMiniApp/src/components/NavigationBar/TransparentNavigationBar.vue | 77
apps/housekeepingMiniApp/src/assets/authentication/icon-result-error.png | 0
apps/housekeepingMiniApp/src/assets/home/icon-localtion.png | 0
apps/housekeepingMiniApp/src/hooks/login.ts | 76
apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.vue | 121
apps/housekeepingMiniApp/src/components/Searchbar/BlSearchbar.vue | 34
apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add.png | 0
apps/housekeepingMiniApp/src/assets/login/icon-btn-password.png | 0
apps/housekeepingMiniApp/src/components/Menu/MenuItem.vue | 224
apps/housekeepingMiniApp/src/subpackages/login/loginByForm/accountLoginForm.vue | 118
apps/housekeepingMiniApp/.eslintrc-auto-import.json | 116
apps/housekeepingMiniApp/README.md | 1
apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/InnerPage.vue | 167
apps/housekeepingMiniApp/src/assets/tabbar/icon-mine-active.png | 0
apps/housekeepingMiniApp/src/assets/user/icon-my-attention.png | 0
apps/housekeepingMiniApp/src/assets/mine/icon-agreement.png | 0
apps/housekeepingMiniApp/src/assets/user/icon-email.png | 0
apps/housekeepingMiniApp/src/hooks/access.ts | 50
apps/housekeepingMiniApp/src/components/RichEditCard/RichEditCard.vue | 137
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailItem.vue | 64
apps/housekeepingMiniApp/src/assets/authentication/icon-jbr.png | 0
apps/housekeepingMiniApp/src/assets/mine/icon-order-hire.png | 0
apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-bank.png | 0
apps/housekeepingMiniApp/types/pagination.d.ts | 43
apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-2.png | 0
apps/housekeepingMiniApp/src/constants/task.ts | 19
apps/housekeepingMiniApp/src/components/Avatar/UserInfoAvatar.vue | 95
apps/housekeepingMiniApp/src/hooks/index.ts | 6
apps/housekeepingMiniApp/src/pages/home/HomeQueryMenuView.vue | 77
apps/housekeepingMiniApp/src/custom-tab-bar/index.scss | 119
apps/housekeepingMiniApp/src/components/PageFooter/PageFooterAction.vue | 67
apps/housekeepingMiniApp/src/assets/task/icon-safe.png | 0
apps/housekeepingMiniApp/src/constants/router.ts | 44
apps/housekeepingMiniApp/src/styles/hairline.scss | 200
apps/housekeepingMiniApp/src/components/Uploader/uploader.ts | 5
apps/housekeepingMiniApp/src/subpackages/login/registerForm/registerForm.vue | 189
apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.config.ts | 3
apps/housekeepingMiniApp/src/components/Card/cardProps.ts | 20
apps/housekeepingMiniApp/src/subpackages/login/constants/index.ts | 4
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/InnerPage.vue | 241
apps/housekeepingMiniApp/src/subpackages/login/authorization/index.config.ts | 3
apps/housekeepingMiniApp/src/assets/setting/icon-warning.png | 0
apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-step-wait.png | 0
apps/housekeepingMiniApp/src/app.ts | 85
apps/housekeepingMiniApp/src/assets/task/icon-attention.png | 0
apps/housekeepingMiniApp/src/constants/enum.ts | 4
apps/housekeepingMiniApp/src/assets/mine/icon-male.png | 0
apps/housekeepingMiniApp/src/components/NavigationBar/NavBar.vue | 58
apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/InnerPage.vue | 68
apps/housekeepingMiniApp/src/components/Uploader/CoverUploader.vue | 139
apps/housekeepingMiniApp/src/assets/task/icon-no-certified.png | 0
apps/housekeepingMiniApp/src/utils/index.ts | 3
apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow.png | 0
apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.vue | 18
apps/housekeepingMiniApp/src/utils/common/localtion.ts | 12
apps/housekeepingMiniApp/src/subpackages/wallet/hooks/index.ts | 66
apps/housekeepingMiniApp/src/subpackages/login/userPolicy/index.config.ts | 3
apps/housekeepingMiniApp/src/utils/common/index.ts | 1
apps/housekeepingMiniApp/src/components/NavigationBar/commonNavigationBar.ts | 28
apps/housekeepingMiniApp/config/staging.js | 13
apps/housekeepingMiniApp/src/components/RichEditor/style.css | 715 ++
apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-alipay.png | 0
apps/housekeepingMiniApp/src/custom-tab-bar/index.tsx | 169
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.config.ts | 3
apps/housekeepingMiniApp/src/components/PageFooter/PageFooter.vue | 177
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/InnerPage.vue | 190
apps/housekeepingMiniApp/.eslintrc | 12
apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.vue | 17
apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.vue | 18
apps/housekeepingMiniApp/src/pages/mine/index.scss | 175
apps/housekeepingMiniApp/src/assets/mine/icon-services.png | 0
apps/housekeepingMiniApp/src/subpackages/mine/mineSign/InnerPage.vue | 117
apps/housekeepingMiniApp/src/assets/tabbar/icon-home-active.png | 0
apps/housekeepingMiniApp/src/components/RichEditor/RichEditorContent.vue | 59
apps/housekeepingMiniApp/src/styles/common.scss | 6
apps/housekeepingMiniApp/src/styles/font.scss | 7
apps/housekeepingMiniApp/src/assets/mine/icon-collect.png | 0
apps/housekeepingMiniApp/src/subpackages/login/loginByForm/loginByForm.vue | 79
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.vue | 28
apps/housekeepingMiniApp/src/assets/tabbar/icon-mine.png | 0
apps/housekeepingMiniApp/src/assets/task/icon-attention-active.png | 0
apps/housekeepingMiniApp/src/assets/components/icon-dark-arrow.png | 0
apps/housekeepingMiniApp/src/assets/components/icon-default-avatar.png | 0
apps/housekeepingMiniApp/src/assets/mine/icon-recruit.png | 0
apps/housekeepingMiniApp/src/assets/components/icon-add.png | 0
apps/housekeepingMiniApp/src/assets/mine/icon-phone.png | 0
apps/housekeepingMiniApp/src/assets/home/icon-logo.png | 0
apps/housekeepingMiniApp/src/components/NavigationBar/LargeTitleNavigationBar.vue | 61
apps/housekeepingMiniApp/src/assets/setting/icon-account.png | 0
apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.vue | 17
apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.vue | 18
apps/housekeepingMiniApp/src/constants/tabBar.ts | 11
apps/housekeepingMiniApp/src/styles/reset.scss | 30
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/InnerPage.vue | 244
apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.vue | 137
apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.vue | 18
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/InnerPage.vue | 41
apps/housekeepingMiniApp/src/hooks/router.ts | 28
apps/housekeepingMiniApp/src/components/InfiniteLoading/InfiniteLoading.vue | 240
apps/housekeepingMiniApp/src/assets/components/fail.png | 0
apps/housekeepingMiniApp/src/constants/app.ts | 9
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.vue | 14
apps/housekeepingMiniApp/src/components/Uploader/Uploader.vue | 137
apps/housekeepingMiniApp/src/subpackages/login/styles/login.scss | 165
apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.config.ts | 3
apps/housekeepingMiniApp/src/assets/task/icon-phone.png | 0
apps/housekeepingMiniApp/src/subpackages/mine/mineHired/InnerPage.vue | 113
apps/housekeepingMiniApp/src/components/Card/CommonCard.vue | 146
apps/housekeepingMiniApp/src/styles/var.scss | 35
apps/housekeepingMiniApp/src/components/Layout/LoadingLayout.vue | 58
apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.vue | 18
apps/housekeepingMiniApp/src/stores/modules/system.ts | 116
apps/housekeepingMiniApp/src/assets/components/icon-back-top.png | 0
apps/housekeepingMiniApp/src/styles/nut.scss | 170
apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.config.ts | 3
apps/housekeepingMiniApp/src/components/Layout/ContentScrollView.vue | 54
apps/housekeepingMiniApp/src/assets/tabbar/icon-publish.png | 0
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.vue | 17
apps/housekeepingMiniApp/types/globalType.d.ts | 8
apps/housekeepingMiniApp/src/components/UserHome/UserHomeTopView.vue | 121
apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.vue | 17
apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHomeItem.vue | 159
apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.vue | 17
apps/housekeepingMiniApp/src/styles/function.scss | 78
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/InnerPage.vue | 88
apps/housekeepingMiniApp/project.config.json | 60
apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.vue | 17
apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow-white.png | 0
apps/housekeepingMiniApp/src/pages/task/3x_categoryData.ts | 2095 +++++++
apps/housekeepingMiniApp/src/hooks/user.ts | 104
apps/housekeepingMiniApp/config/dev.js | 25
apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/InnerPage.vue | 50
apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/InnerPage.vue | 106
apps/housekeepingMiniApp/src/components/Avatar/UserAvatar.vue | 14
apps/housekeepingMiniApp/src/components/Chunk/ChunkTitle.vue | 43
apps/housekeepingMiniApp/src/stores/modules/user.ts | 292 +
apps/housekeepingMiniApp/src/components/Card/Card.vue | 64
apps/housekeepingMiniApp/src/components/Button/LargeButton.vue | 28
apps/housekeepingMiniApp/src/components/Policy/Policy.vue | 89
apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.config.ts | 3
apps/housekeepingMiniApp/config/prod.js | 42
apps/housekeepingMiniApp/src/subpackages/login/authorization/authorization.vue | 317 +
apps/housekeepingMiniApp/src/components/Layout/ContentView.vue | 29
apps/housekeepingMiniApp/src/components/index.ts | 25
apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/InnerPage.vue | 105
apps/housekeepingMiniApp/ci/upload.js | 41
apps/housekeepingMiniApp/src/assets/setting/icon-toggle-bg.png | 0
apps/housekeepingMiniApp/src/utils/storage/index.ts | 1
apps/housekeepingMiniApp/src/pages/home/index.config.ts | 5
apps/housekeepingMiniApp/types/shims-vue.d.ts | 15
apps/housekeepingMiniApp/src/pages/home/index.vue | 199
apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.vue | 17
apps/housekeepingMiniApp/mock/Purchase.mock.js | 106
apps/housekeepingMiniApp/src/assets/font/D-DIN.otf | 0
apps/housekeepingMiniApp/src/stores/index.ts | 10
apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/InnerPage.vue | 72
apps/housekeepingMiniApp/src/components/PageFooter/PageFooterBtn.vue | 34
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/InnerPage.vue | 130
apps/housekeepingMiniApp/src/pages/task/task.config.ts | 3
apps/housekeepingMiniApp/src/pages/task/InnerPage.vue | 42
apps/housekeepingMiniApp/src/assets/components/icon-small-dark-arrow.png | 0
apps/housekeepingMiniApp/src/assets/icon-developing.png | 0
apps/housekeepingMiniApp/src/utils/storage/auth.ts | 58
apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add-editor.png | 0
apps/housekeepingMiniApp/src/subpackages/login/components/LoginPageLayout/LoginPageLayout.vue | 58
apps/housekeepingMiniApp/src/app.config.ts | 118
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/InnerPage.vue | 69
apps/housekeepingMiniApp/project.tt.json | 9
apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.config.ts | 3
apps/housekeepingMiniApp/src/assets/mine/icon-order-cancel.png | 0
apps/housekeepingMiniApp/src/assets/task/icon-localtion.png | 0
apps/housekeepingMiniApp/src/components/Layout/PageLayout.vue | 139
apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.vue | 18
apps/housekeepingMiniApp/src/subpackages/mine/mineHire/InnerPage.vue | 114
apps/housekeepingMiniApp/src/utils/page.ts | 25
apps/housekeepingMiniApp/src/hooks/app.ts | 13
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.vue | 14
apps/housekeepingMiniApp/src/pages/task/task.vue | 13
apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.vue | 17
apps/housekeepingMiniApp/src/components/Chunk/Cell.vue | 76
apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.config.ts | 3
apps/housekeepingMiniApp/src/styles/custom_theme.scss | 11
apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up.png | 0
apps/housekeepingMiniApp/src/components/NoData/NoData.vue | 44
apps/housekeepingMiniApp/src/assets/components/rich-card/icon-delete.png | 0
apps/housekeepingMiniApp/src/assets/components/success.png | 0
apps/housekeepingMiniApp/src/assets/setting/icon-wx.png | 0
apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/InnerPage.vue | 69
apps/housekeepingMiniApp/src/subpackages/login/loginByForm/index.config.ts | 3
apps/housekeepingMiniApp/src/assets/login/icon-btn-captcha.png | 0
apps/housekeepingMiniApp/src/assets/user/icon-bg.png | 0
apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/index.config.ts | 3
apps/housekeepingMiniApp/src/constants/img.ts | 18
apps/housekeepingMiniApp/src/assets/user/icon-address.png | 0
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.config.ts | 3
apps/housekeepingMiniApp/src/app.scss | 1
apps/housekeepingMiniApp/src/styles/mixins.scss | 76
apps/housekeepingMiniApp/src/assets/mine/icon-arrow.png | 0
apps/housekeepingMiniApp/src/pages/mine/index.vue | 266
apps/housekeepingMiniApp/tsconfig.json | 35
apps/housekeepingMiniApp/src/assets/setting/icon-note.png | 0
apps/housekeepingMiniApp/src/assets/common/icon-common-page-bg.png | 0
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/InnerPage.vue | 85
apps/housekeepingMiniApp/src/assets/components/icon-phone.png | 0
apps/housekeepingMiniApp/src/utils/setConfig.ts | 5
apps/housekeepingMiniApp/src/assets/mine/icon-auth.png | 0
apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up-active.png | 0
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.vue | 14
pnpm-lock.yaml | 303 +
apps/housekeepingMiniApp/src/components/Layout/PageLayoutWithBg.vue | 49
apps/housekeepingMiniApp/config/index.js | 239
apps/housekeepingMiniApp/types/global.d.ts | 83
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/login/components/OtherLoginChannel/OtherLoginChannel.vue.vue | 17
apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down.png | 0
apps/housekeepingMiniApp/src/assets/mine/icon-setting.png | 0
apps/housekeepingMiniApp/src/assets/tabbar/icon-home.png | 0
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.vue | 14
apps/housekeepingMiniApp/src/subpackages/login/loginByForm/verificationCodeLoginForm.vue | 118
apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.config.ts | 3
apps/housekeepingMiniApp/mock/index.js | 5
apps/housekeepingMiniApp/src/assets/user/icon-phone.png | 0
apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/index.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/mineUserPolicy.vue | 401 +
apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/InnerPage.vue | 108
apps/housekeepingMiniApp/src/components/Chunk/CellChunk.vue | 38
apps/housekeepingMiniApp/src/assets/authentication/icon-arrow.png | 0
apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.vue | 109
apps/housekeepingMiniApp/src/assets/setting/icon-arrow.png | 0
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.config.ts | 3
apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.vue | 17
apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-1.png | 0
apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.vue | 17
apps/housekeepingMiniApp/babel.config.js | 32
apps/housekeepingMiniApp/src/pages/mine/index.config.ts | 7
apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.config.ts | 3
apps/housekeepingMiniApp/src/components/NavigationBar/navBar.ts | 14
apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.vue | 17
apps/housekeepingMiniApp/src/assets/tabbar/icon-task.png | 0
apps/housekeepingMiniApp/src/assets/task/icon-share.png | 0
apps/housekeepingMiniApp/src/styles/config.scss | 5
apps/housekeepingMiniApp/src/hooks/authentication.ts | 51
apps/housekeepingMiniApp/src/components/NavigationBar/CommonNavigationBar.vue | 104
apps/housekeepingMiniApp/src/assets/mine/icon-female.png | 0
apps/housekeepingMiniApp/src/assets/tabbar/icon-task-active.png | 0
apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.config.ts | 3
apps/housekeepingMiniApp/ci/private.wxb9e0baf4f87aa0de.key | 27
apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailCard.vue | 41
apps/housekeepingMiniApp/auto-imports.d.ts | 222
apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.config.ts | 3
apps/housekeepingMiniApp/project.private.config.json | 25
apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-wechat.png | 0
apps/housekeepingMiniApp/src/constants/index.ts | 6
apps/housekeepingMiniApp/src/utils/request/index.ts | 314 +
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/InnerPage.vue | 216
apps/housekeepingMiniApp/src/components/Menu/menu.scss | 43
apps/housekeepingMiniApp/src/constants/query.ts | 10
apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.config.ts | 3
apps/housekeepingMiniApp/src/components/Menu/Menu.vue | 216
apps/housekeepingMiniApp/src/styles/index.scss | 83
apps/housekeepingMiniApp/src/assets/setting/icon-loginout.png | 0
apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.config.ts | 3
apps/housekeepingMiniApp/src/assets/mine/icon-order-sign.png | 0
apps/housekeepingMiniApp/src/assets/authentication/icon-faren.png | 0
apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/privacyPolicy.vue | 172
apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.vue | 17
apps/housekeepingMiniApp/src/assets/authentication/icon-result-success.png | 0
apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.vue | 35
apps/housekeepingMiniApp/src/assets/setting/icon-coo.png | 0
290 files changed, 16,519 insertions(+), 13 deletions(-)
diff --git a/apps/housekeepingMiniApp/.eslintrc b/apps/housekeepingMiniApp/.eslintrc
new file mode 100644
index 0000000..b40f4a5
--- /dev/null
+++ b/apps/housekeepingMiniApp/.eslintrc
@@ -0,0 +1,12 @@
+// ESLint 妫�鏌� .vue 鏂囦欢闇�瑕佸崟鐙厤缃紪杈戝櫒锛�
+// https://eslint.vuejs.org/user-guide/#editor-integrations
+{
+ "root": true,
+
+ "env": {
+ "node": true
+ },
+
+ "extends": ["../../.eslintrc", "./.eslintrc-auto-import.json"],
+ "parser": "vue-eslint-parser"
+}
diff --git a/apps/housekeepingMiniApp/.eslintrc-auto-import.json b/apps/housekeepingMiniApp/.eslintrc-auto-import.json
new file mode 100644
index 0000000..4915a2b
--- /dev/null
+++ b/apps/housekeepingMiniApp/.eslintrc-auto-import.json
@@ -0,0 +1,116 @@
+{
+ "globals": {
+ "AppLocalConfig": true,
+ "BackType": true,
+ "Component": true,
+ "ComponentPublicInstance": true,
+ "ComputedRef": true,
+ "EffectScope": true,
+ "ExtractDefaultPropTypes": true,
+ "ExtractPropTypes": true,
+ "ExtractPublicPropTypes": true,
+ "InjectionKey": true,
+ "OssAssets": true,
+ "PropType": true,
+ "Ref": true,
+ "RouterPath": true,
+ "TabBarPageRouter": true,
+ "TaskStatus": true,
+ "TaskStatusColor": true,
+ "TaskStatusText": true,
+ "VNode": true,
+ "WritableComputedRef": true,
+ "acceptHMRUpdate": true,
+ "computed": true,
+ "createApp": true,
+ "createPinia": true,
+ "customRef": true,
+ "defineAsyncComponent": true,
+ "defineComponent": true,
+ "defineStore": true,
+ "effectScope": true,
+ "getActivePinia": true,
+ "getCurrentInstance": true,
+ "getCurrentScope": true,
+ "h": true,
+ "inject": true,
+ "isProxy": true,
+ "isReactive": true,
+ "isReadonly": true,
+ "isRef": true,
+ "mapActions": true,
+ "mapGetters": true,
+ "mapState": true,
+ "mapStores": true,
+ "mapWritableState": true,
+ "markRaw": true,
+ "myClient": true,
+ "nextTick": true,
+ "onActivated": true,
+ "onBeforeMount": true,
+ "onBeforeRouteLeave": true,
+ "onBeforeRouteUpdate": true,
+ "onBeforeUnmount": true,
+ "onBeforeUpdate": true,
+ "onDeactivated": true,
+ "onErrorCaptured": true,
+ "onMounted": true,
+ "onRenderTracked": true,
+ "onRenderTriggered": true,
+ "onScopeDispose": true,
+ "onServerPrefetch": true,
+ "onUnmounted": true,
+ "onUpdated": true,
+ "onWatcherCleanup": true,
+ "provide": true,
+ "reactive": true,
+ "readonly": true,
+ "ref": true,
+ "resolveComponent": true,
+ "setActivePinia": true,
+ "setMapStoreSuffix": true,
+ "shallowReactive": true,
+ "shallowReadonly": true,
+ "shallowRef": true,
+ "storeToRefs": true,
+ "toRaw": true,
+ "toRef": true,
+ "toRefs": true,
+ "toValue": true,
+ "triggerRef": true,
+ "unref": true,
+ "useAccessLogin": true,
+ "useAccessPersonalInfo": true,
+ "useAttrs": true,
+ "useAuth": true,
+ "useCssModule": true,
+ "useCssVars": true,
+ "useGoLogin": true,
+ "useId": true,
+ "useIsLogin": true,
+ "useLink": true,
+ "useLoginedJump": true,
+ "useModel": true,
+ "useMyCertificationAuditInfo": true,
+ "useRoute": true,
+ "useRouter": true,
+ "useSlots": true,
+ "useSwitchTab": true,
+ "useTemplateRef": true,
+ "useUser": true,
+ "useUserResume": true,
+ "watch": true,
+ "watchEffect": true,
+ "watchPostEffect": true,
+ "watchSyncEffect": true,
+ "useUpdateResume": true,
+ "useAccessReal": true,
+ "useLaunchOptions": true,
+ "APP_ENV": true,
+ "DirectiveBinding": true,
+ "MaybeRef": true,
+ "MaybeRefOrGetter": true,
+ "NODE_ENV": true,
+ "TabBarPageRouterList": true
+ }
+}
diff --git a/apps/housekeepingMiniApp/README.md b/apps/housekeepingMiniApp/README.md
new file mode 100644
index 0000000..486c5ae
--- /dev/null
+++ b/apps/housekeepingMiniApp/README.md
@@ -0,0 +1 @@
+瀹夎 pnpm install
diff --git a/apps/housekeepingMiniApp/auto-imports.d.ts b/apps/housekeepingMiniApp/auto-imports.d.ts
new file mode 100644
index 0000000..b9f92e8
--- /dev/null
+++ b/apps/housekeepingMiniApp/auto-imports.d.ts
@@ -0,0 +1,222 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// noinspection JSUnusedGlobalSymbols
+// Generated by unplugin-auto-import
+export {}
+declare global {
+ const APP_ENV: typeof import('./src/constants/app')['APP_ENV']
+ const AppLocalConfig: typeof import('./src/constants/app')['AppLocalConfig']
+ const BackType: typeof import('./src/constants/enum')['BackType']
+ const EffectScope: typeof import('vue')['EffectScope']
+ const NODE_ENV: typeof import('./src/constants/app')['NODE_ENV']
+ const OssAssets: typeof import('./src/constants/img')['OssAssets']
+ const RouterPath: typeof import('./src/constants/router')['RouterPath']
+ const TabBarPageRouter: typeof import('./src/constants/tabBar')['TabBarPageRouter']
+ const TabBarPageRouterList: typeof import('./src/constants/tabBar')['TabBarPageRouterList']
+ const TaskStatus: typeof import('./src/constants/task')['TaskStatus']
+ const TaskStatusColor: typeof import('./src/constants/task')['TaskStatusColor']
+ const TaskStatusText: typeof import('./src/constants/task')['TaskStatusText']
+ const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
+ const computed: typeof import('vue')['computed']
+ const createApp: typeof import('vue')['createApp']
+ const createPinia: typeof import('pinia')['createPinia']
+ const customRef: typeof import('vue')['customRef']
+ const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
+ const defineComponent: typeof import('vue')['defineComponent']
+ const defineStore: typeof import('pinia')['defineStore']
+ const effectScope: typeof import('vue')['effectScope']
+ const getActivePinia: typeof import('pinia')['getActivePinia']
+ const getCurrentInstance: typeof import('vue')['getCurrentInstance']
+ const getCurrentScope: typeof import('vue')['getCurrentScope']
+ const h: typeof import('vue')['h']
+ const inject: typeof import('vue')['inject']
+ const isProxy: typeof import('vue')['isProxy']
+ const isReactive: typeof import('vue')['isReactive']
+ const isReadonly: typeof import('vue')['isReadonly']
+ const isRef: typeof import('vue')['isRef']
+ const mapActions: typeof import('pinia')['mapActions']
+ const mapGetters: typeof import('pinia')['mapGetters']
+ const mapState: typeof import('pinia')['mapState']
+ const mapStores: typeof import('pinia')['mapStores']
+ const mapWritableState: typeof import('pinia')['mapWritableState']
+ const markRaw: typeof import('vue')['markRaw']
+ const myClient: typeof import('./src/constants/query')['myClient']
+ const nextTick: typeof import('vue')['nextTick']
+ const onActivated: typeof import('vue')['onActivated']
+ const onBeforeMount: typeof import('vue')['onBeforeMount']
+ const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
+ const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
+ const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
+ const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
+ const onDeactivated: typeof import('vue')['onDeactivated']
+ const onErrorCaptured: typeof import('vue')['onErrorCaptured']
+ const onMounted: typeof import('vue')['onMounted']
+ const onRenderTracked: typeof import('vue')['onRenderTracked']
+ const onRenderTriggered: typeof import('vue')['onRenderTriggered']
+ const onScopeDispose: typeof import('vue')['onScopeDispose']
+ const onServerPrefetch: typeof import('vue')['onServerPrefetch']
+ const onUnmounted: typeof import('vue')['onUnmounted']
+ const onUpdated: typeof import('vue')['onUpdated']
+ const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
+ const provide: typeof import('vue')['provide']
+ const reactive: typeof import('vue')['reactive']
+ const readonly: typeof import('vue')['readonly']
+ const ref: typeof import('vue')['ref']
+ const resolveComponent: typeof import('vue')['resolveComponent']
+ const setActivePinia: typeof import('pinia')['setActivePinia']
+ const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
+ const shallowReactive: typeof import('vue')['shallowReactive']
+ const shallowReadonly: typeof import('vue')['shallowReadonly']
+ const shallowRef: typeof import('vue')['shallowRef']
+ const storeToRefs: typeof import('pinia')['storeToRefs']
+ const toRaw: typeof import('vue')['toRaw']
+ const toRef: typeof import('vue')['toRef']
+ const toRefs: typeof import('vue')['toRefs']
+ const toValue: typeof import('vue')['toValue']
+ const triggerRef: typeof import('vue')['triggerRef']
+ const unref: typeof import('vue')['unref']
+ const useAccessLogin: typeof import('./src/hooks/access')['useAccessLogin']
+ const useAccessPersonalInfo: typeof import('./src/hooks/access')['useAccessPersonalInfo']
+ const useAccessReal: typeof import('./src/hooks/access')['useAccessReal']
+ const useAttrs: typeof import('vue')['useAttrs']
+ const useAuth: typeof import('./src/hooks/user')['useAuth']
+ const useCssModule: typeof import('vue')['useCssModule']
+ const useCssVars: typeof import('vue')['useCssVars']
+ const useGoLogin: typeof import('./src/hooks/user')['useGoLogin']
+ const useId: typeof import('vue')['useId']
+ const useIsLogin: typeof import('./src/hooks/user')['useIsLogin']
+ const useLaunchOptions: typeof import('./src/hooks/app')['useLaunchOptions']
+ const useLink: typeof import('vue-router')['useLink']
+ const useLoginedJump: typeof import('./src/hooks/login')['useLoginedJump']
+ const useModel: typeof import('vue')['useModel']
+ const useMyCertificationAuditInfo: typeof import('./src/hooks/authentication')['useMyCertificationAuditInfo']
+ const useRoute: typeof import('vue-router')['useRoute']
+ const useRouter: typeof import('vue-router')['useRouter']
+ const useSlots: typeof import('vue')['useSlots']
+ const useSwitchTab: typeof import('./src/hooks/router')['useSwitchTab']
+ const useTemplateRef: typeof import('vue')['useTemplateRef']
+ const useUser: typeof import('./src/hooks/user')['useUser']
+ const useUserResume: typeof import('./src/hooks/user')['useUserResume']
+ const watch: typeof import('vue')['watch']
+ const watchEffect: typeof import('vue')['watchEffect']
+ const watchPostEffect: typeof import('vue')['watchPostEffect']
+ const watchSyncEffect: typeof import('vue')['watchSyncEffect']
+}
+// for type re-export
+declare global {
+ // @ts-ignore
+ export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
+ import('vue')
+ // @ts-ignore
+ export type { BackType, BackType } from './src/constants/enum'
+ import('./src/constants/enum')
+ // @ts-ignore
+ export type { RouterPath, RouterPath } from './src/constants/router'
+ import('./src/constants/router')
+ // @ts-ignore
+ export type { TaskStatus, TaskStatus } from './src/constants/task'
+ import('./src/constants/task')
+}
+// for vue template auto import
+import { UnwrapRef } from 'vue'
+declare module 'vue' {
+ interface ComponentCustomProperties {
+ readonly APP_ENV: UnwrapRef<typeof import('./src/constants/app')['APP_ENV']>
+ readonly AppLocalConfig: UnwrapRef<typeof import('./src/constants/app')['AppLocalConfig']>
+ readonly BackType: UnwrapRef<typeof import('./src/constants/enum')['BackType']>
+ readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
+ readonly NODE_ENV: UnwrapRef<typeof import('./src/constants/app')['NODE_ENV']>
+ readonly OssAssets: UnwrapRef<typeof import('./src/constants/img')['OssAssets']>
+ readonly RouterPath: UnwrapRef<typeof import('./src/constants/router')['RouterPath']>
+ readonly TabBarPageRouter: UnwrapRef<typeof import('./src/constants/tabBar')['TabBarPageRouter']>
+ readonly TabBarPageRouterList: UnwrapRef<typeof import('./src/constants/tabBar')['TabBarPageRouterList']>
+ readonly TaskStatus: UnwrapRef<typeof import('./src/constants/task')['TaskStatus']>
+ readonly TaskStatusColor: UnwrapRef<typeof import('./src/constants/task')['TaskStatusColor']>
+ readonly TaskStatusText: UnwrapRef<typeof import('./src/constants/task')['TaskStatusText']>
+ readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
+ readonly computed: UnwrapRef<typeof import('vue')['computed']>
+ readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
+ readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
+ readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
+ readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
+ readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
+ readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
+ readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
+ readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
+ readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
+ readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
+ readonly h: UnwrapRef<typeof import('vue')['h']>
+ readonly inject: UnwrapRef<typeof import('vue')['inject']>
+ readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
+ readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
+ readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
+ readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
+ readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
+ readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
+ readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
+ readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>
+ readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
+ readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
+ readonly myClient: UnwrapRef<typeof import('./src/constants/query')['myClient']>
+ readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
+ readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
+ readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
+ readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
+ readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
+ readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
+ readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
+ readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
+ readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
+ readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
+ readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
+ readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
+ readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
+ readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
+ readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
+ readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
+ readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
+ readonly provide: UnwrapRef<typeof import('vue')['provide']>
+ readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
+ readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
+ readonly ref: UnwrapRef<typeof import('vue')['ref']>
+ readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
+ readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
+ readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
+ readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
+ readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
+ readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
+ readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
+ readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
+ readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
+ readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
+ readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
+ readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
+ readonly unref: UnwrapRef<typeof import('vue')['unref']>
+ readonly useAccessLogin: UnwrapRef<typeof import('./src/hooks/access')['useAccessLogin']>
+ readonly useAccessReal: UnwrapRef<typeof import('./src/hooks/access')['useAccessReal']>
+ readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
+ readonly useAuth: UnwrapRef<typeof import('./src/hooks/user')['useAuth']>
+ readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
+ readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
+ readonly useGoLogin: UnwrapRef<typeof import('./src/hooks/user')['useGoLogin']>
+ readonly useId: UnwrapRef<typeof import('vue')['useId']>
+ readonly useIsLogin: UnwrapRef<typeof import('./src/hooks/user')['useIsLogin']>
+ readonly useLaunchOptions: UnwrapRef<typeof import('./src/hooks/app')['useLaunchOptions']>
+ readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>
+ readonly useLoginedJump: UnwrapRef<typeof import('./src/hooks/login')['useLoginedJump']>
+ readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
+ readonly useMyCertificationAuditInfo: UnwrapRef<typeof import('./src/hooks/authentication')['useMyCertificationAuditInfo']>
+ readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
+ readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
+ readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
+ readonly useSwitchTab: UnwrapRef<typeof import('./src/hooks/router')['useSwitchTab']>
+ readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
+ readonly useUser: UnwrapRef<typeof import('./src/hooks/user')['useUser']>
+ readonly useUserResume: UnwrapRef<typeof import('./src/hooks/user')['useUserResume']>
+ readonly watch: UnwrapRef<typeof import('vue')['watch']>
+ readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
+ readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
+ readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
+ }
+}
diff --git a/apps/housekeepingMiniApp/babel.config.js b/apps/housekeepingMiniApp/babel.config.js
new file mode 100644
index 0000000..b20c8f5
--- /dev/null
+++ b/apps/housekeepingMiniApp/babel.config.js
@@ -0,0 +1,32 @@
+// babel-preset-taro 鏇村閫夐」鍜岄粯璁ゅ�硷細
+
+// https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md
+module.exports = {
+ compact: false,
+ presets: [
+ [
+ 'taro',
+ {
+ framework: 'vue3',
+ ts: true,
+ },
+ ],
+ ],
+ plugins: [
+ [
+ 'import',
+ {
+ libraryName: 'lodash',
+ libraryDirectory: '',
+ camel2DashComponentName: false, // default: true
+ },
+ 'lodash',
+ ],
+ // 'lodash',
+ ],
+ env: {
+ production: {
+ plugins: ['transform-remove-console'],
+ },
+ },
+};
diff --git a/apps/housekeepingMiniApp/ci/private.wxb9e0baf4f87aa0de.key b/apps/housekeepingMiniApp/ci/private.wxb9e0baf4f87aa0de.key
new file mode 100644
index 0000000..0a780a5
--- /dev/null
+++ b/apps/housekeepingMiniApp/ci/private.wxb9e0baf4f87aa0de.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA62tuwu9Aoqbl4ZumZpl1ZEflFqbhQJfvKDBxLycWbIi/xE2i
+uZQhRW+2fr8ATVclh2VJ8uA3VW2f0Xe65r7o1eLeqBTo3hslp4Xehgj/zm9Uga5/
+8ZgUFByar0dGbMpGNTb4a6s5+BBBJ2ZpK6D5aI/9IEWKW6YchhZt7xZ1U7ShwZTT
+YuB+EMW04JA248eLvmjwqljy3m06JMFuH5/Dsc6z46HdQT4icteCRzAmVms+FPrU
+uOArAtROorXWlMol6VtSAI1uNrKBENrHTR/rGVSpbj+gZ1HUKUCt8QqkkG2Gxawa
+CYNwe4dn+m0QrI5ba00o25rVbQVBCo+EovvjEwIDAQABAoIBADDxd+iNBxoJqrc5
+veGMu+wqSkVoUmI0dCMd1xoffTj5QS0VmuQMGNKvw/gby3tIx+ObOkGFPdvD27sX
+skKwpAV7kiDNoBA1AqIOYdHp4wzO9nmzhqP6own/XGVeYxTRBMGheQohYf7hmjoP
+v4OzhsanUM+5xWcCZOG3nglb2O6atAMX9VrXCT+29KXKVBmdzqZR+QSoOuW2HVIO
+la1+QmQAMKf+PeZ9jyMilI8yHAqXEoEoqWpIKUZJcq24PnuNvAzNVN5ZbJmdcJqh
+F2ix4sohtOk4tUJMkihL5OFvz3TUuAPqDwKNXQ+yViPgE+lXrqBwXB2gCTOBjFm+
+2aitfrECgYEA+Zfw2cdy5wbGjaLGqgV6um2gAgkrLi6QqcHjhVWqwSLManNxUuX4
+iSWrd2Txa84ydtqAGe/6xDu6t/3o/cNrP353srtiqoA7EoyGy92EiASWBW7qEw6O
+nAcouKbPwDTXzrfASDG0BsUQmiQGtN3vXm8yKYX/T5ewfI6eBRS4aysCgYEA8XZb
+RaGVYicY1L5hLfKJnSLaV9rbN8VH4tkNJlvkcLauLMzlev3+o8qc1qxiGpZK6GfL
+mv6tm0QIfbn1Qh17F0vhUToJ2N5RNfXzZ/JHZCIE6R+aH3f0m2EN9YcrJhtvmVdd
+rrI019pJhpEe6HjundXGsxbGNvJr0wV0ycMm07kCgYEAy1/UIBAVf0wVE6nUCQwH
+8cqLu7zu02Wb+McE9ktUpKUPPZotd+fteQsZyWKWGUrd8dyezwOtKKKmxW9+nu/R
+/t20+Q0ZG2b7O2UIHSu15wMdnvW+g6Kz700iEDvUQoCMbGNrqSfe0jlXCtJaKJxC
+hIdEr3MBE0C9zPCEsA0vLBsCgYBRetHz3kHNfEn5yEB8w8JCPzeUu+qLmEvYtcul
+LQ8aJdsCjSXG6hzaYo2oN0VnmV2vrQ7cv6IPqdZ/rpefdtlJlDZ1NXOLNgILhnJb
+mjsTBBPKIvrcMZteL1MJjlI2Kr3u7bdUMxh32lZDTYczhVNn+XJyjnXWptlRvR6a
+0vqwKQKBgC92ZdiHpOdyuKtd48rY/+24jebiQJ55zwT7eS2BMQ1UNvQA55ZL1RmB
++1LB3WdSubXOFih+L86tNhY4hCtYluUakHsoikh/r8L8GZN5+ciX+RgZ5V+P3JiL
+QzFHVujwg2c2mhGNy3yUlSWz8gDViJq2OgyNuLEWEcE/fbhccI5G
+-----END RSA PRIVATE KEY-----
diff --git a/apps/housekeepingMiniApp/ci/upload.js b/apps/housekeepingMiniApp/ci/upload.js
new file mode 100644
index 0000000..fa532cb
--- /dev/null
+++ b/apps/housekeepingMiniApp/ci/upload.js
@@ -0,0 +1,41 @@
+const config = require('../project.config.json');
+const pkg = require('../package.json');
+const path = require('path');
+const semver = require('semver');
+
+let projectPath = path.resolve(__dirname, '..');
+
+const CIPluginFn = async () => {
+ let version;
+ let robot = 30;
+ let desc = '';
+ if (process.env.NODE_ENV === 'production') {
+ version = pkg.version;
+ robot = 1;
+ desc = '姝e紡鐜灏忕▼搴�';
+ if (process.env.APP_ENV === 'staging') {
+ version = semver.inc(version, 'patch');
+ robot = 2;
+ desc = '娴嬭瘯鐜灏忕▼搴�';
+ }
+ }
+
+ /**
+ * @typedef { import("@tarojs/plugin-mini-ci").CIOptions } CIOptions
+ * @type {CIOptions}
+ */
+ return {
+ weapp: {
+ appid: config.appid,
+ privateKeyPath: `${projectPath}/ci/private.wxb9e0baf4f87aa0de.key`,
+ robot: robot,
+ setting: {
+ minify: false,
+ },
+ },
+ version,
+ desc: desc,
+ };
+};
+
+module.exports = { CIPluginFn };
diff --git a/apps/housekeepingMiniApp/config/dev.js b/apps/housekeepingMiniApp/config/dev.js
new file mode 100644
index 0000000..c84544a
--- /dev/null
+++ b/apps/housekeepingMiniApp/config/dev.js
@@ -0,0 +1,25 @@
+const mocks = require('../mock');
+
+module.exports = {
+ env: {
+ NODE_ENV: '"development"',
+ BASE_URL: '"http://localhost:53780"',
+ // BASE_URL: '"https://testfj.81812333.com"',
+ BASE_URL_JX: '"https://api.jx818.com"',
+ APP_ENV: '"development"',
+
+ OSS_URL: '"https://waterdroptest2.oss-cn-hangzhou.aliyuncs.com/"',
+ WEMAP_KEY: 'T2UBZ-N563J-ZCHFF-XDOXN-VCH7S-CJB2T',
+ },
+ plugins: [
+ [
+ '@tarojs/plugin-mock',
+ {
+ mocks: mocks,
+ },
+ ],
+ ],
+ defineConstants: {},
+ mini: {},
+ h5: {},
+};
diff --git a/apps/housekeepingMiniApp/config/index.js b/apps/housekeepingMiniApp/config/index.js
new file mode 100644
index 0000000..14ef20c
--- /dev/null
+++ b/apps/housekeepingMiniApp/config/index.js
@@ -0,0 +1,239 @@
+const path = require('path');
+const { CIPluginFn } = require('../ci/upload');
+
+import AutoImport from 'unplugin-auto-import/webpack';
+import ComponentsPlugin from 'unplugin-vue-components/webpack';
+import NutUIResolver from '@nutui/nutui-taro/dist/resolver';
+
+const config = {
+ projectName: 'vue-mini',
+ date: '2022-11-29',
+ designWidth(input) {
+ // 閰嶇疆 NutUI 375 灏哄
+ if (input?.file?.replace(/\\+/g, '/').indexOf('@nutui') > -1) {
+ return 375;
+ }
+ // 鍏ㄥ眬浣跨敤 Taro 榛樿鐨� 750 灏哄
+ return 750;
+ },
+ deviceRatio: {
+ 375: 2 / 1,
+ 640: 2.34 / 2,
+ 750: 1,
+ 828: 1.81 / 2,
+ },
+ alias: {
+ '@': path.resolve(__dirname, '..', 'src'),
+ '@components/assets': path.resolve(__dirname, '..', 'node_modules', '@12333/components/assets'),
+ },
+ sourceRoot: 'src',
+ outputRoot: 'dist',
+ plugins: [
+ ['@tarojs/plugin-mini-ci', CIPluginFn],
+ [
+ '@tarojs/plugin-vue-devtools',
+ {
+ port: 9999,
+ },
+ ],
+ '@tarojs/plugin-html',
+ [
+ '@tarojs/plugin-http',
+ {
+ enableCookie: true,
+ },
+ ],
+ 'taro-plugin-pinia',
+ [
+ '@tarojs/plugin-framework-vue3',
+ {
+ vueLoaderOption: {
+ compilerOptions: {
+ isCustomElement: (tag) => tag.includes('ec-canvas'),
+ },
+ reactivityTransform: true, // 寮�鍚痸ue3鍝嶅簲鎬ц娉曠硸
+ },
+ },
+ ],
+ ],
+
+ defineConstants: {
+ // CLIENT_ID: JSON.stringify('frontend-admin-app-client'),
+ // START_YEAR: '2022',
+ },
+ copy: {
+ patterns: [],
+ options: {},
+ },
+ framework: 'vue3',
+ compiler: {
+ type: 'webpack5',
+ prebundle: { enable: false },
+ },
+ cache: {
+ enable: false, // Webpack 鎸佷箙鍖栫紦瀛橀厤缃紝寤鸿寮�鍚�傞粯璁ら厤缃鍙傝�冿細https://docs.taro.zone/docs/config-detail#cache
+ },
+ sass: {
+ resource: [path.resolve(__dirname, '..', 'src/styles/custom_theme.scss')],
+ data: `@import "@nutui/nutui-taro/dist/styles/variables.scss";`,
+ },
+
+ mini: {
+ hot: true,
+ miniCssExtractPluginOption: {
+ ignoreOrder: true,
+ },
+ postcss: {
+ pxtransform: {
+ enable: true,
+ config: {
+ selectorBlackList: ['nut-'],
+ },
+ },
+ url: {
+ enable: true,
+ config: {
+ limit: 1024, // 璁惧畾杞崲灏哄涓婇檺
+ },
+ },
+ cssModules: {
+ enable: true, // 榛樿涓� false锛屽闇�浣跨敤 css modules 鍔熻兘锛屽垯璁句负 true
+ config: {
+ namingPattern: 'module', // 杞崲妯″紡锛屽彇鍊间负 global/module
+ generateScopedName: '[name]__[local]___[hash:base64:5]',
+ },
+ },
+ },
+ webpackChain(chain, webpack) {
+ if (process.env.NODE_ENV === 'development') {
+ chain.plugin('analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []);
+ }
+
+ chain.plugin('unplugin-auto-import').use(
+ AutoImport({
+ dirs: ['./src/constants/**', './src/hooks/**'],
+ // dirsScanOptions: {
+ // fileFilter: (file) => file.endsWith('.ts'), // Filter files
+ // types: true,
+ // },
+ vueTemplate: true,
+ imports: ['vue', 'pinia', 'vue-router'],
+ eslintrc: {
+ enabled: true, // Default `false`
+ filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
+ globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
+ },
+ })
+ );
+
+ chain.plugin('unplugin-vue-components').use(
+ ComponentsPlugin({
+ include: [/\.[tj]sx?$/, /\.vue$/, /\.vue\?vue/],
+ resolvers: [NutUIResolver({ taro: true })],
+ dts: true,
+ })
+ );
+
+ if (process.env.NODE_ENV !== 'development') {
+ chain.merge({
+ plugin: {
+ install: {
+ plugin: require('terser-webpack-plugin'),
+ args: [
+ {
+ terserOptions: {
+ compress: true, // 榛樿浣跨敤terser鍘嬬缉
+ keep_classnames: true, // 涓嶆敼鍙榗lass鍚嶇О
+ keep_fnames: true, // 涓嶆敼鍙樺嚱鏁板悕绉�
+ },
+ },
+ ],
+ },
+ },
+ });
+ }
+
+ chain.merge({
+ optimization: {
+ splitChunks: {
+ cacheGroups: {
+ nutui: {
+ name: 'nutui',
+ minChunks: 2,
+ test: (module) => {
+ return /[\\/]node_modules[\\/]@nutui[\\/]/.test(module.resource);
+ },
+ priority: 20,
+ },
+ lodash: {
+ name: 'lodash',
+ minChunks: 2,
+ test: (module) => {
+ return /[\\/]node_modules[\\/]lodash[\\/]/.test(module.resource);
+ },
+ priority: 20,
+ },
+ // senin: {
+ // name: 'senin',
+ // minChunks: 2,
+ // test: (module) => {
+ // return /[\\/]node_modules[\\/]senin-mini[\\/]/.test(module.resource);
+ // },
+ // priority: 30,
+ // },
+ },
+ },
+ },
+ });
+ },
+ commonChunks(commonChunks) {
+ commonChunks.push('nutui');
+ commonChunks.push('lodash');
+ // commonChunks.push('senin');
+ return commonChunks;
+ },
+ },
+ h5: {
+ publicPath: '/',
+ staticDirectory: 'static',
+ postcss: {
+ autoprefixer: {
+ enable: true,
+ config: {},
+ },
+ cssModules: {
+ enable: false, // 榛樿涓� false锛屽闇�浣跨敤 css modules 鍔熻兘锛屽垯璁句负 true
+ config: {
+ namingPattern: 'module', // 杞崲妯″紡锛屽彇鍊间负 global/module
+ generateScopedName: '[name]__[local]___[hash:base64:5]',
+ },
+ },
+ },
+ },
+ rn: {
+ appName: 'taroDemo',
+ postcss: {
+ cssModules: {
+ enable: false, // 榛樿涓� false锛屽闇�浣跨敤 css modules 鍔熻兘锛屽垯璁句负 true
+ },
+ },
+ },
+};
+
+module.exports = function (merge) {
+ if (process.env.NODE_ENV === 'development') {
+ return merge(
+ {},
+ config,
+ require('./dev'),
+ process.env.APP_ENV === 'staging' ? require('./staging') : {}
+ );
+ }
+
+ return merge(
+ {},
+ config,
+ require('./prod'),
+ process.env.APP_ENV === 'staging' ? require('./staging') : {}
+ );
+};
diff --git a/apps/housekeepingMiniApp/config/prod.js b/apps/housekeepingMiniApp/config/prod.js
new file mode 100644
index 0000000..53a2a6c
--- /dev/null
+++ b/apps/housekeepingMiniApp/config/prod.js
@@ -0,0 +1,42 @@
+module.exports = {
+ env: {
+ NODE_ENV: '"production"',
+ BASE_URL: '"https://lgdapi.81812333.com"',
+ BASE_URL_JX: '"https://lgdapi.jx818.com"',
+ APP_ENV: '"production"',
+
+ OSS_URL: '"https://parkmanagement.oss-cn-hangzhou.aliyuncs.com"',
+
+ WEMAP_KEY: 'DYRBZ-ZGPCF-X3OJN-N2AA3-JWUCE-HEBXJ',
+ },
+ defineConstants: {},
+ mini: {},
+ h5: {
+ /**
+ * WebpackChain 鎻掍欢閰嶇疆
+ * @docs https://github.com/neutrinojs/webpack-chain
+ */
+ // webpackChain (chain) {
+ // /**
+ // * 濡傛灉 h5 绔紪璇戝悗浣撶Н杩囧ぇ锛屽彲浠ヤ娇鐢� webpack-bundle-analyzer 鎻掍欢瀵规墦鍖呬綋绉繘琛屽垎鏋愩��
+ // * @docs https://github.com/webpack-contrib/webpack-bundle-analyzer
+ // */
+ // chain.plugin('analyzer')
+ // .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
+ // /**
+ // * 濡傛灉 h5 绔灞忓姞杞芥椂闂磋繃闀匡紝鍙互浣跨敤 prerender-spa-plugin 鎻掍欢棰勫姞杞介椤点��
+ // * @docs https://github.com/chrisvfritz/prerender-spa-plugin
+ // */
+ // const path = require('path')
+ // const Prerender = require('prerender-spa-plugin')
+ // const staticDir = path.join(__dirname, '..', 'dist')
+ // chain
+ // .plugin('prerender')
+ // .use(new Prerender({
+ // staticDir,
+ // routes: [ '/pages/index/index' ],
+ // postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') })
+ // }))
+ // }
+ },
+};
diff --git a/apps/housekeepingMiniApp/config/staging.js b/apps/housekeepingMiniApp/config/staging.js
new file mode 100644
index 0000000..596e5b9
--- /dev/null
+++ b/apps/housekeepingMiniApp/config/staging.js
@@ -0,0 +1,13 @@
+module.exports = {
+ env: {
+ // BASE_URL: '"https://testrlywx.boleyuma.com"',
+ BASE_URL: '"https://testfj.81812333.com"',
+ BASE_URL_JX: '"https://testfj.81812333.com"',
+
+ OSS_URL: '"https://waterdroptest2.oss-cn-hangzhou.aliyuncs.com/"',
+
+ APP_ENV: '"staging"',
+
+ WEMAP_KEY: 'T2UBZ-N563J-ZCHFF-XDOXN-VCH7S-CJB2T',
+ },
+};
diff --git a/apps/housekeepingMiniApp/mock/Purchase.mock.js b/apps/housekeepingMiniApp/mock/Purchase.mock.js
new file mode 100644
index 0000000..659b6f8
--- /dev/null
+++ b/apps/housekeepingMiniApp/mock/Purchase.mock.js
@@ -0,0 +1,106 @@
+const Mock = require('mockjs');
+
+module.exports = {
+ 'POST /api/Purchase/getMySells': Mock.mock({
+ error: null,
+ msg: null,
+ success: true,
+ unAuthorizedRequest: false,
+ result: {
+ pageModel: {
+ rows: 64,
+ page: 97,
+ orderInput: [],
+ totalCount: 68,
+ totalPage: 72,
+ },
+ objectData: null,
+ 'data|1-10': [
+ {
+ 'name|+1': Mock.mock('@title'),
+ 'id|+1': Mock.mock('@guid'),
+ 'categoryName|+1': Mock.mock('@cname'),
+ productId: Mock.mock('@guid'),
+ productName: Mock.mock('@cname'),
+ purchaserId: Mock.mock('@guid'),
+ purchaser: Mock.mock('@string'),
+ purchaseContacter: Mock.mock('@string'),
+ purchaseContacterPhone: Mock.mock('@string'),
+ unitPrice: Mock.mock('@integer(60, 100)'),
+ count: Mock.mock('@integer(60, 100)'),
+ amount: Mock.mock('@integer(60, 100)'),
+ 'status|+1': [0, 10, 20, -10, -20, -30],
+ purchaseDate: Mock.mock('@datetime'),
+ fixtureDate: Mock.mock('@datetime'),
+ comment: Mock.mock({
+ 'starCount|1-5': 5,
+ content: Mock.mock('@cparagraph'),
+ creationTime: Mock.mock('@datetime'),
+ }),
+ refund: {
+ refundApplyRemark: Mock.mock('@cparagraph'),
+ refundApplyTime: Mock.mock('@datetime'),
+ refundDealRemark: Mock.mock('@cparagraph'),
+ },
+ },
+ ],
+ },
+ }),
+ 'POST /api/Purchase/getMyPurchases': Mock.mock({
+ error: null,
+ msg: null,
+ success: true,
+ unAuthorizedRequest: false,
+ result: {
+ pageModel: {
+ rows: 64,
+ page: 97,
+ orderInput: [],
+ totalCount: 68,
+ totalPage: 72,
+ },
+ objectData: null,
+ 'data|8': [
+ {
+ 'id|+1': Mock.mock('@guid'),
+ 'categoryName|+1': Mock.mock('@cname'),
+ 'productId|+1': Mock.mock('@guid'),
+ productName: Mock.mock('@cname'),
+ 'covers|1-10': [
+ {
+ url: Mock.mock('@string'),
+ 'sequence|1-100': 100,
+ 'isMain|1-2': true,
+ },
+ ],
+ tags: [
+ {
+ tagId: Mock.mock('@guid'),
+ tagName: Mock.mock('@cname'),
+ 'sequence|1-100': 100,
+ type: 1,
+ },
+ ],
+ versionName: Mock.mock('@cname'),
+ count: Mock.mock('@integer(60, 100)'),
+ unitPrice: Mock.mock('@integer(60, 100)'),
+ amount: Mock.mock('@integer(60, 100)'),
+ seller: Mock.mock('@cname'),
+ purchaseDate: Mock.mock('@datetime'),
+ comment: {
+ 'starCount|1-5': 5,
+ content: Mock.mock('@cparagraph'),
+ creationTime: Mock.mock('@datetime'),
+ },
+ refund: {
+ refundApplyRemark: Mock.mock('@cparagraph'),
+ refundApplyTime: Mock.mock('@datetime'),
+ refundDealRemark: Mock.mock('@cparagraph'),
+ },
+ 'status|+1': [0, 10, 20, -10, -20, -30],
+ chargeWay: '骞�',
+ },
+ ],
+ },
+ }),
+};
diff --git a/apps/housekeepingMiniApp/mock/index.js b/apps/housekeepingMiniApp/mock/index.js
new file mode 100644
index 0000000..e593800
--- /dev/null
+++ b/apps/housekeepingMiniApp/mock/index.js
@@ -0,0 +1,5 @@
+const purchaseMocks = require('./Purchase.mock');
+
+module.exports = {
+ ...purchaseMocks,
+};
diff --git a/apps/housekeepingMiniApp/package.json b/apps/housekeepingMiniApp/package.json
new file mode 100644
index 0000000..b5f1a22
--- /dev/null
+++ b/apps/housekeepingMiniApp/package.json
@@ -0,0 +1,131 @@
+{
+ "name": "@12333/housekeepingMiniApp",
+ "version": "1.0.0",
+ "private": true,
+ "description": "",
+ "templateInfo": {
+ "name": "default",
+ "typescript": true,
+ "css": "sass"
+ },
+ "scripts": {
+ "build:weapp": "cross-env NODE_OPTIONS=--openssl-legacy-provider taro build --type weapp",
+ "build:weapp:upload": "npm run build:weapp -- --upload",
+ "build:weapp:staging": "cross-env APP_ENV=staging npm run build:weapp --",
+ "build:weapp:staging:upload": "npm run build:weapp:staging -- --upload",
+ "build:swan": "taro build --type swan",
+ "build:alipay": "taro build --type alipay",
+ "build:tt": "taro build --type tt",
+ "build:h5": "taro build --type h5",
+ "build:rn": "taro build --type rn",
+ "build:qq": "taro build --type qq",
+ "build:jd": "taro build --type jd",
+ "build:quickapp": "taro build --type quickapp",
+ "dev:weapp": "npm run build:weapp -- --watch",
+ "dev:weapp:staging": "npm run build:weapp:staging -- --watch",
+ "dev:swan": "npm run build:swan -- --watch",
+ "dev:alipay": "npm run build:alipay -- --watch",
+ "dev:tt": "npm run build:tt -- --watch",
+ "dev:h5": "npm run build:h5 -- --watch",
+ "dev:rn": "npm run build:rn -- --watch",
+ "dev:qq": "npm run build:qq -- --watch",
+ "dev:jd": "npm run build:jd -- --watch",
+ "dev:quickapp": "npm run build:quickapp -- --watch",
+ "release": "release-it --config ../../.release-it.json --git.tagName='@12333/cMiniApp/v${version}' --hooks.after:release='npm run build:weapp:upload'"
+ },
+ "browserslist": [
+ "last 3 versions",
+ "Android >= 4.1",
+ "ios >= 8"
+ ],
+ "author": "",
+ "dependencies": {
+ "@12333/components": "workspace:^",
+ "@12333/constants": "workspace:*",
+ "@12333/hooks": "workspace:^",
+ "@12333/services": "workspace:^",
+ "@12333/utils": "workspace:^",
+ "@babel/runtime": "^7.7.7",
+ "@bole-12333/chat-kit": "^1.0.1",
+ "@bole-core/request": "^0.0.1",
+ "@nutui/icons-vue-taro": "^0.0.9",
+ "@nutui/nutui-taro": "4.3.13",
+ "@tanstack/vue-query": "^4.35.3",
+ "@tarojs/components": "3.6.20",
+ "@tarojs/helper": "3.6.20",
+ "@tarojs/plugin-framework-vue3": "3.6.20",
+ "@tarojs/plugin-html": "3.6.20",
+ "@tarojs/plugin-http": "3.6.20",
+ "@tarojs/plugin-platform-alipay": "3.6.20",
+ "@tarojs/plugin-platform-jd": "3.6.20",
+ "@tarojs/plugin-platform-qq": "3.6.20",
+ "@tarojs/plugin-platform-swan": "3.6.20",
+ "@tarojs/plugin-platform-tt": "3.6.20",
+ "@tarojs/plugin-platform-weapp": "3.6.20",
+ "@tarojs/router": "3.6.20",
+ "@tarojs/runtime": "3.6.20",
+ "@tarojs/shared": "3.6.20",
+ "@tarojs/taro": "3.6.20",
+ "@tarojs/taro-h5": "3.6.20",
+ "@tencentcloud/chat-uikit-engine": "^2.0.3",
+ "@tencentcloud/chat-uikit-uniapp": "^2.0.3",
+ "@tencentcloud/tui-customer-service-plugin": "^2.0.3",
+ "@vant/weapp": "^1.11.1",
+ "axios": "^1.4.0",
+ "crypto-js": "^4.1.1",
+ "dayjs": "^1.11.6",
+ "js-base64": "^3.7.5",
+ "lodash": "^4.17.21",
+ "pinia": "^2.1.6",
+ "qs": "^6.11.1",
+ "senior-request": "^1.0.10",
+ "taro-plugin-pinia": "^1.0.0",
+ "vconsole": "^3.15.1",
+ "vue": "3.5.12",
+ "vue-component-type-helpers": "^2.1.10"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.8.0",
+ "@nutui/auto-import-resolver": "^1.0.0",
+ "@tarojs/cli": "3.6.20",
+ "@tarojs/plugin-mini-ci": "^4.0.7",
+ "@tarojs/plugin-mock": "^0.0.9",
+ "@tarojs/plugin-vue-devtools": "^3.6.20",
+ "@tarojs/service": "^3.6.20",
+ "@tarojs/webpack5-runner": "3.6.20",
+ "@types/crypto-js": "^4.1.1",
+ "@types/lodash": "^4.14.198",
+ "@types/webpack-env": "^1.13.6",
+ "@vue/babel-plugin-jsx": "^1.0.6",
+ "@vue/compiler-sfc": "^3.5.12",
+ "babel-plugin-import": "^1.13.8",
+ "babel-plugin-lodash": "^3.3.4",
+ "babel-plugin-transform-remove-console": "^6.9.4",
+ "babel-preset-taro": "3.6.20",
+ "cache-loader": "^4.1.0",
+ "cross-env": "^7.0.3",
+ "mockjs": "^1.1.0",
+ "postcss": "^8.4.19",
+ "postcss-html": "^1.5.0",
+ "postcss-loader": "^7.3.3",
+ "postcss-scss": "^4.0.6",
+ "prettier": "^2.7.1",
+ "stylelint": "^14.15.0",
+ "stylelint-config-html": "^1.1.0",
+ "stylelint-config-prettier": "^9.0.4",
+ "stylelint-config-recess-order": "^3.0.0",
+ "stylelint-config-recommended": "^9.0.0",
+ "stylelint-config-standard": "^29.0.0",
+ "stylelint-config-standard-scss": "^6.1.0",
+ "stylelint-order": "^5.0.0",
+ "stylelint-scss": "^4.3.0",
+ "taro-plugin-compiler-optimization": "^1.0.4",
+ "thread-loader": "^4.0.2",
+ "unplugin-auto-import": "^0.16.6",
+ "unplugin-vue-components": "^0.27.4",
+ "vue-eslint-parser": "^9.3.1",
+ "vue-loader": "^17.0.0",
+ "webpack": "^5.78.0",
+ "webpack-bundle-analyzer": "^4.7.0"
+ }
+}
diff --git a/apps/housekeepingMiniApp/project.config.json b/apps/housekeepingMiniApp/project.config.json
new file mode 100644
index 0000000..af19670
--- /dev/null
+++ b/apps/housekeepingMiniApp/project.config.json
@@ -0,0 +1,60 @@
+{
+ "miniprogramRoot": "dist/",
+ "description": "",
+ "setting": {
+ "urlCheck": false,
+ "es6": true,
+ "enhance": true,
+ "postcss": false,
+ "preloadBackgroundData": false,
+ "minified": false,
+ "newFeature": false,
+ "coverView": true,
+ "nodeModules": false,
+ "autoAudits": false,
+ "showShadowRootInWxmlPanel": true,
+ "scopeDataCheck": false,
+ "uglifyFileName": false,
+ "checkInvalidKey": true,
+ "checkSiteMap": false,
+ "uploadWithSourceMap": true,
+ "compileHotReLoad": false,
+ "lazyloadPlaceholderEnable": false,
+ "useMultiFrameRuntime": true,
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ },
+ "enableEngineNative": false,
+ "useIsolateContext": true,
+ "userConfirmedBundleSwitch": false,
+ "packNpmManually": false,
+ "packNpmRelationList": [],
+ "minifyWXSS": false,
+ "disableUseStrict": false,
+ "minifyWXML": false,
+ "showES6CompileOption": false,
+ "useCompilerPlugins": false,
+ "ignoreUploadUnusedFiles": true,
+ "condition": false,
+ "compileWorklet": false,
+ "localPlugins": false,
+ "swc": false,
+ "disableSWC": true
+ },
+ "compileType": "miniprogram",
+ "editorSetting": {
+ "tabIndent": "insertSpaces",
+ "tabSize": 4
+ },
+ "srcMiniprogramRoot": "dist/",
+ "condition": {},
+ "simulatorPluginLibVersion": {},
+ "appid": "wxb9e0baf4f87aa0de",
+ "packOptions": {
+ "ignore": [],
+ "include": []
+ },
+ "libVersion": "3.11.2"
+}
\ No newline at end of file
diff --git a/apps/housekeepingMiniApp/project.private.config.json b/apps/housekeepingMiniApp/project.private.config.json
new file mode 100644
index 0000000..9725f9e
--- /dev/null
+++ b/apps/housekeepingMiniApp/project.private.config.json
@@ -0,0 +1,25 @@
+{
+ "description": "椤圭洰绉佹湁閰嶇疆鏂囦欢銆傛鏂囦欢涓殑鍐呭灏嗚鐩� project.config.json 涓殑鐩稿悓瀛楁銆傞」鐩殑鏀瑰姩浼樺厛鍚屾鍒版鏂囦欢涓�傝瑙佹枃妗o細https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+ "projectname": "housekeepingMiniApp",
+ "setting": {
+ "compileHotReLoad": true,
+ "bigPackageSizeSupport": true,
+ "urlCheck": false,
+ "coverView": true,
+ "lazyloadPlaceholderEnable": false,
+ "preloadBackgroundData": false,
+ "autoAudits": false,
+ "useApiHook": true,
+ "useApiHostProcess": true,
+ "showShadowRootInWxmlPanel": true,
+ "useStaticServer": false,
+ "useLanDebug": false,
+ "showES6CompileOption": false,
+ "checkInvalidKey": true,
+ "ignoreDevUnusedFiles": true,
+ "useIsolateContext": true,
+ "skylineRenderEnable": false
+ },
+ "condition": {},
+ "libVersion": "3.11.2"
+}
\ No newline at end of file
diff --git a/apps/housekeepingMiniApp/project.tt.json b/apps/housekeepingMiniApp/project.tt.json
new file mode 100644
index 0000000..9caa7a8
--- /dev/null
+++ b/apps/housekeepingMiniApp/project.tt.json
@@ -0,0 +1,9 @@
+{
+ "miniprogramRoot": "./",
+ "projectname": "housekeepingMiniApp",
+ "appid": "testAppId",
+ "setting": {
+ "es6": false,
+ "minified": false
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/app.config.ts b/apps/housekeepingMiniApp/src/app.config.ts
new file mode 100644
index 0000000..fdd4e46
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/app.config.ts
@@ -0,0 +1,118 @@
+export default defineAppConfig({
+ entryPagePath: 'pages/home/index',
+ pages: ['pages/home/index', 'pages/task/task', 'pages/mine/index'],
+ requiredPrivateInfos: ['getLocation', 'chooseLocation'],
+ permission: {
+ 'scope.userLocation': {
+ desc: '浣犵殑浣嶇疆淇℃伅灏嗙敤浜庡皬绋嬪簭鏁版嵁鐨勬晥鏋滃睍绀�',
+ },
+ },
+ window: {
+ backgroundTextStyle: 'light',
+ navigationBarBackgroundColor: '#ff6d33',
+ navigationBarTitleText: 'WeChat',
+ navigationBarTextStyle: 'black',
+ backgroundColorTop: '#ff6d33',
+ backgroundColor: '#f7f7f7',
+ backgroundColorBottom: '#f7f7f7',
+ navigationStyle: 'custom',
+ },
+ tabBar: {
+ list: [
+ {
+ pagePath: 'pages/home/index',
+ iconPath: 'assets/tabbar/icon-home.png',
+ selectedIconPath: 'assets/tabbar/icon-home-active.png',
+ text: '棣栭〉',
+ },
+ {
+ pagePath: 'pages/task/task',
+ iconPath: 'assets/tabbar/icon-task.png',
+ selectedIconPath: 'assets/tabbar/icon-task-active.png',
+ text: '鏈嶅姟',
+ },
+ {
+ pagePath: 'pages/mine/index',
+ iconPath: 'assets/tabbar/icon-mine.png',
+ selectedIconPath: 'assets/tabbar/icon-mine-active.png',
+ text: '鎴戠殑',
+ },
+ ],
+ color: '#000',
+ selectedColor: '#ff6d33',
+ backgroundColor: '#fff',
+ borderStyle: 'black',
+ custom: true,
+ },
+ lazyCodeLoading: 'requiredComponents', // 鎸夐渶娉ㄥ叆鍜岀敤鏃舵敞鍏�(鎸夐渶娉ㄥ叆+鍗犱綅缁勪欢)
+ subpackages: [
+ {
+ root: 'subpackages/login',
+ pages: [
+ 'authorization/authorization',
+ 'userPolicy/userPolicy',
+ 'mineUserPolicy/mineUserPolicy',
+ 'privacyPolicy/privacyPolicy',
+ 'loginByForm/loginByForm',
+ 'registerForm/registerForm',
+ ],
+ },
+ {
+ root: 'subpackages/authentication',
+ pages: [
+ 'authenticationHome/authenticationHome',
+ 'authenticationFaRen/authenticationFaRen',
+ 'authenticationJBR/authenticationJBR',
+ 'authenticationResult/authenticationResult',
+ 'authenticationRealName/authenticationRealName',
+ 'authenticationFace/authenticationFace',
+ ],
+ },
+ {
+ root: 'subpackages/city',
+ pages: ['citySelect/citySelect'],
+ },
+ {
+ root: 'subpackages/mine',
+ pages: [
+ 'mineSign/mineSign',
+ 'mineHire/mineHire',
+ 'mineHired/mineHired',
+ 'mineCancel/mineCancel',
+ 'mineCollectTask/mineCollectTask',
+ 'mineAgreementSign/mineAgreementSign',
+ 'mineAgreementSignDetail/mineAgreementSignDetail',
+ 'setting/setting',
+ ],
+ },
+ {
+ root: 'subpackages/wallet',
+ pages: [
+ 'mineWallet/mineWallet',
+ 'bindBankCard/bindBankCard',
+ 'unboundBankCard/unboundBankCard',
+ 'unboundAlipay/unboundAlipay',
+ 'bindAlipay/bindAlipay',
+ 'incomeDetail/incomeDetail',
+ 'incomeDetailInfo/incomeDetailInfo',
+ 'withdraw/withdraw',
+ 'withdrawResult/withdrawResult',
+ 'withdrawDetailInfo/withdrawDetailInfo',
+ ],
+ },
+ {
+ root: 'subpackages/user',
+ pages: ['complaint/complaint'],
+ },
+ {
+ root: 'subpackages/extraPage',
+ pages: ['extraPage/extraPage'],
+ },
+ ],
+ // preloadRule: {
+ // 'pages/mine/index': {
+ // network: 'all',
+ // packages: ['subpackages/setting', 'subpackages/message'],
+ // },
+ // },
+});
diff --git a/apps/housekeepingMiniApp/src/app.scss b/apps/housekeepingMiniApp/src/app.scss
new file mode 100644
index 0000000..23ff940
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/app.scss
@@ -0,0 +1 @@
+@import '@/styles/index.scss';
diff --git a/apps/housekeepingMiniApp/src/app.ts b/apps/housekeepingMiniApp/src/app.ts
new file mode 100644
index 0000000..4bd5754
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/app.ts
@@ -0,0 +1,85 @@
+import { createApp } from 'vue';
+
+import '@nutui/nutui-taro/dist/style.css';
+import './app.scss';
+import '@/utils/setConfig';
+import { setupStore } from '@/stores';
+
+import { useSystemStore } from '@/stores/modules/system';
+import { useUserStore } from '@/stores/modules/user';
+import Taro from '@tarojs/taro';
+import { VueQueryPlugin, VueQueryPluginOptions } from '@tanstack/vue-query';
+import { myClient } from '@/constants/query';
+
+window.uni = Taro;
+
+function updateVersions() {
+ const updateManager = Taro.getUpdateManager();
+ updateManager.onCheckForUpdate(function (_res) {
+ // 璇锋眰瀹屾柊鐗堟湰淇℃伅鐨勫洖璋�
+ });
+ updateManager.onUpdateReady(function () {
+ Taro.showModal({
+ title: '鏇存柊鎻愮ず',
+ content: '鏂扮増鏈凡缁忓噯澶囧ソ锛屾槸鍚﹂噸鍚簲鐢紵',
+ success: function (res) {
+ if (res.confirm) {
+ // 鏂扮殑鐗堟湰宸茬粡涓嬭浇濂斤紝璋冪敤 applyUpdate 搴旂敤鏂扮増鏈苟閲嶅惎
+ updateManager.applyUpdate();
+ }
+ },
+ });
+ });
+ updateManager.onUpdateFailed(function () {
+ // 鏂扮殑鐗堟湰涓嬭浇澶辫触
+ Taro.showToast({
+ title: '鏂扮殑鐗堟湰涓嬭浇澶辫触,璇烽噸鏂拌繘鍏�',
+ icon: 'none',
+ duration: 2000,
+ });
+ });
+}
+
+const App = createApp({
+ // 鍙互浣跨敤鎵�鏈夌殑 Vue 鐢熷懡鍛ㄦ湡鏂规硶
+
+ mounted() {},
+
+ // 瀵瑰簲 onLaunch
+ onLaunch(options) {
+ // 濡傛灉鏄敹钘忚繘鍏�
+ if (options.query.collect) {
+ Taro.reLaunch({
+ url: '/pages/index/index',
+ });
+ return;
+ }
+ // 灏嗗惎鍔ㄥ弬鏁版斁杩涘埌鍏ㄥ眬鍘�
+ const system = useSystemStore();
+ system.init(options);
+ system.setInfo(Taro.getSystemInfoSync());
+ },
+
+ // 瀵瑰簲 onShow
+ onShow(options) {
+ updateVersions();
+ },
+
+ // 瀵瑰簲 onHide
+ onHide() {},
+ // 鍏ュ彛缁勪欢涓嶉渶瑕佸疄鐜� render 鏂规硶锛屽嵆浣垮疄鐜颁簡涔熶細琚� taro 鎵�瑕嗙洊
+});
+
+setupStore(App);
+
+import { IconFont } from '@nutui/icons-vue-taro';
+
+App.component('IconFont', IconFont); // 鍏ㄥ眬缁勪欢
+
+const vueQueryPluginOptions: VueQueryPluginOptions = {
+ queryClient: myClient,
+};
+
+App.use(VueQueryPlugin, vueQueryPluginOptions);
+
+export default App;
diff --git a/apps/housekeepingMiniApp/src/assets/authentication/icon-arrow.png b/apps/housekeepingMiniApp/src/assets/authentication/icon-arrow.png
new file mode 100644
index 0000000..321b406
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/authentication/icon-arrow.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/authentication/icon-faren.png b/apps/housekeepingMiniApp/src/assets/authentication/icon-faren.png
new file mode 100644
index 0000000..65c3c41
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/authentication/icon-faren.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/authentication/icon-jbr.png b/apps/housekeepingMiniApp/src/assets/authentication/icon-jbr.png
new file mode 100644
index 0000000..0d3ab2b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/authentication/icon-jbr.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/authentication/icon-result-error.png b/apps/housekeepingMiniApp/src/assets/authentication/icon-result-error.png
new file mode 100644
index 0000000..d2b5f19
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/authentication/icon-result-error.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/authentication/icon-result-success.png b/apps/housekeepingMiniApp/src/assets/authentication/icon-result-success.png
new file mode 100644
index 0000000..6685008
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/authentication/icon-result-success.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/common/icon-common-page-bg.png b/apps/housekeepingMiniApp/src/assets/common/icon-common-page-bg.png
new file mode 100644
index 0000000..4f73ce6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/common/icon-common-page-bg.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow-white.png b/apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow-white.png
new file mode 100644
index 0000000..96e4947
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow-white.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow.png b/apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow.png
new file mode 100644
index 0000000..12d08c5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/common/icon-navi-arrow.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/fail.png b/apps/housekeepingMiniApp/src/assets/components/fail.png
new file mode 100644
index 0000000..e5e81b4
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/fail.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/icon-add.png b/apps/housekeepingMiniApp/src/assets/components/icon-add.png
new file mode 100644
index 0000000..0f793a3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/icon-add.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/icon-back-top.png b/apps/housekeepingMiniApp/src/assets/components/icon-back-top.png
new file mode 100644
index 0000000..0b64e13
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/icon-back-top.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/icon-dark-arrow.png b/apps/housekeepingMiniApp/src/assets/components/icon-dark-arrow.png
new file mode 100644
index 0000000..58810dc
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/icon-dark-arrow.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/icon-default-avatar.png b/apps/housekeepingMiniApp/src/assets/components/icon-default-avatar.png
new file mode 100644
index 0000000..a480a27
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/icon-default-avatar.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/icon-phone.png b/apps/housekeepingMiniApp/src/assets/components/icon-phone.png
new file mode 100644
index 0000000..ab958bd
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/icon-phone.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/icon-small-dark-arrow.png b/apps/housekeepingMiniApp/src/assets/components/icon-small-dark-arrow.png
new file mode 100644
index 0000000..bf3f107
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/icon-small-dark-arrow.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add-editor.png b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add-editor.png
new file mode 100644
index 0000000..112ec29
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add-editor.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add.png b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add.png
new file mode 100644
index 0000000..eca71c7
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-add.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-delete.png b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-delete.png
new file mode 100644
index 0000000..2c7ba11
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-delete.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down-active.png b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down-active.png
new file mode 100644
index 0000000..d93cbf3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down-active.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down.png b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down.png
new file mode 100644
index 0000000..7eeaae8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-down.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up-active.png b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up-active.png
new file mode 100644
index 0000000..4f2738b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up-active.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up.png b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up.png
new file mode 100644
index 0000000..da49ac3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/rich-card/icon-move-up.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/components/success.png b/apps/housekeepingMiniApp/src/assets/components/success.png
new file mode 100644
index 0000000..1f6b732
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/components/success.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/font/D-DIN.otf b/apps/housekeepingMiniApp/src/assets/font/D-DIN.otf
new file mode 100644
index 0000000..ea5c4c8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/font/D-DIN.otf
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/home/icon-localtion.png b/apps/housekeepingMiniApp/src/assets/home/icon-localtion.png
new file mode 100644
index 0000000..71784b5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/home/icon-localtion.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/home/icon-logo.png b/apps/housekeepingMiniApp/src/assets/home/icon-logo.png
new file mode 100644
index 0000000..084a4b0
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/home/icon-logo.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/icon-developing.png b/apps/housekeepingMiniApp/src/assets/icon-developing.png
new file mode 100644
index 0000000..c721f31
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/icon-developing.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/login/icon-btn-captcha.png b/apps/housekeepingMiniApp/src/assets/login/icon-btn-captcha.png
new file mode 100644
index 0000000..94c38e3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/login/icon-btn-captcha.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/login/icon-btn-password.png b/apps/housekeepingMiniApp/src/assets/login/icon-btn-password.png
new file mode 100644
index 0000000..6f7e2bc
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/login/icon-btn-password.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-1.png b/apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-1.png
new file mode 100644
index 0000000..080a588
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-1.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-2.png b/apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-2.png
new file mode 100644
index 0000000..c645ee0
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/login/icon-tab-bg-2.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-agreement.png b/apps/housekeepingMiniApp/src/assets/mine/icon-agreement.png
new file mode 100644
index 0000000..1cd2914
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-agreement.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-arrow.png b/apps/housekeepingMiniApp/src/assets/mine/icon-arrow.png
new file mode 100644
index 0000000..f369bbf
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-arrow.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-auth.png b/apps/housekeepingMiniApp/src/assets/mine/icon-auth.png
new file mode 100644
index 0000000..e9a316a
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-auth.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-collect.png b/apps/housekeepingMiniApp/src/assets/mine/icon-collect.png
new file mode 100644
index 0000000..7f3b0e3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-collect.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-female.png b/apps/housekeepingMiniApp/src/assets/mine/icon-female.png
new file mode 100644
index 0000000..19ea574
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-female.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-male.png b/apps/housekeepingMiniApp/src/assets/mine/icon-male.png
new file mode 100644
index 0000000..8d585b6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-male.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-order-cancel.png b/apps/housekeepingMiniApp/src/assets/mine/icon-order-cancel.png
new file mode 100644
index 0000000..5cf4432
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-order-cancel.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-order-hire.png b/apps/housekeepingMiniApp/src/assets/mine/icon-order-hire.png
new file mode 100644
index 0000000..e39d2b8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-order-hire.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-order-sign.png b/apps/housekeepingMiniApp/src/assets/mine/icon-order-sign.png
new file mode 100644
index 0000000..a241ab8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-order-sign.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-phone.png b/apps/housekeepingMiniApp/src/assets/mine/icon-phone.png
new file mode 100644
index 0000000..55a2b00
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-phone.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-recruit.png b/apps/housekeepingMiniApp/src/assets/mine/icon-recruit.png
new file mode 100644
index 0000000..98107c1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-recruit.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-services.png b/apps/housekeepingMiniApp/src/assets/mine/icon-services.png
new file mode 100644
index 0000000..49107e1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-services.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/mine/icon-setting.png b/apps/housekeepingMiniApp/src/assets/mine/icon-setting.png
new file mode 100644
index 0000000..0140788
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/mine/icon-setting.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-account.png b/apps/housekeepingMiniApp/src/assets/setting/icon-account.png
new file mode 100644
index 0000000..86537bf
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-account.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-arrow.png b/apps/housekeepingMiniApp/src/assets/setting/icon-arrow.png
new file mode 100644
index 0000000..ffb29dc
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-arrow.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-coo.png b/apps/housekeepingMiniApp/src/assets/setting/icon-coo.png
new file mode 100644
index 0000000..dd6c257
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-coo.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-loginout.png b/apps/housekeepingMiniApp/src/assets/setting/icon-loginout.png
new file mode 100644
index 0000000..ee25907
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-loginout.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-note.png b/apps/housekeepingMiniApp/src/assets/setting/icon-note.png
new file mode 100644
index 0000000..c76d47e
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-note.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-toggle-bg.png b/apps/housekeepingMiniApp/src/assets/setting/icon-toggle-bg.png
new file mode 100644
index 0000000..dcaba2c
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-toggle-bg.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-warning.png b/apps/housekeepingMiniApp/src/assets/setting/icon-warning.png
new file mode 100644
index 0000000..1215f9f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-warning.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/setting/icon-wx.png b/apps/housekeepingMiniApp/src/assets/setting/icon-wx.png
new file mode 100644
index 0000000..3422645
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/setting/icon-wx.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/tabbar/icon-home-active.png b/apps/housekeepingMiniApp/src/assets/tabbar/icon-home-active.png
new file mode 100644
index 0000000..6ac80b1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/tabbar/icon-home-active.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/tabbar/icon-home.png b/apps/housekeepingMiniApp/src/assets/tabbar/icon-home.png
new file mode 100644
index 0000000..76ad785
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/tabbar/icon-home.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/tabbar/icon-mine-active.png b/apps/housekeepingMiniApp/src/assets/tabbar/icon-mine-active.png
new file mode 100644
index 0000000..8e174e6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/tabbar/icon-mine-active.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/tabbar/icon-mine.png b/apps/housekeepingMiniApp/src/assets/tabbar/icon-mine.png
new file mode 100644
index 0000000..d399adb
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/tabbar/icon-mine.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/tabbar/icon-publish.png b/apps/housekeepingMiniApp/src/assets/tabbar/icon-publish.png
new file mode 100644
index 0000000..9e0af86
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/tabbar/icon-publish.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/tabbar/icon-task-active.png b/apps/housekeepingMiniApp/src/assets/tabbar/icon-task-active.png
new file mode 100644
index 0000000..7f3906a
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/tabbar/icon-task-active.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/tabbar/icon-task.png b/apps/housekeepingMiniApp/src/assets/tabbar/icon-task.png
new file mode 100644
index 0000000..b1ce967
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/tabbar/icon-task.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/task/icon-attention-active.png b/apps/housekeepingMiniApp/src/assets/task/icon-attention-active.png
new file mode 100644
index 0000000..a226f67
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/task/icon-attention-active.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/task/icon-attention.png b/apps/housekeepingMiniApp/src/assets/task/icon-attention.png
new file mode 100644
index 0000000..81bdc6b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/task/icon-attention.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/task/icon-localtion.png b/apps/housekeepingMiniApp/src/assets/task/icon-localtion.png
new file mode 100644
index 0000000..71784b5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/task/icon-localtion.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/task/icon-no-certified.png b/apps/housekeepingMiniApp/src/assets/task/icon-no-certified.png
new file mode 100644
index 0000000..8f29a60
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/task/icon-no-certified.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/task/icon-phone.png b/apps/housekeepingMiniApp/src/assets/task/icon-phone.png
new file mode 100644
index 0000000..55a2b00
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/task/icon-phone.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/task/icon-safe.png b/apps/housekeepingMiniApp/src/assets/task/icon-safe.png
new file mode 100644
index 0000000..0addf65
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/task/icon-safe.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/task/icon-share.png b/apps/housekeepingMiniApp/src/assets/task/icon-share.png
new file mode 100644
index 0000000..546e699
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/task/icon-share.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/user/icon-address.png b/apps/housekeepingMiniApp/src/assets/user/icon-address.png
new file mode 100644
index 0000000..0af50f3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/user/icon-address.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/user/icon-bg.png b/apps/housekeepingMiniApp/src/assets/user/icon-bg.png
new file mode 100644
index 0000000..e8e3d22
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/user/icon-bg.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/user/icon-email.png b/apps/housekeepingMiniApp/src/assets/user/icon-email.png
new file mode 100644
index 0000000..787cff2
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/user/icon-email.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/user/icon-my-attention.png b/apps/housekeepingMiniApp/src/assets/user/icon-my-attention.png
new file mode 100644
index 0000000..fcf73cb
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/user/icon-my-attention.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/user/icon-phone.png b/apps/housekeepingMiniApp/src/assets/user/icon-phone.png
new file mode 100644
index 0000000..32bef71
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/user/icon-phone.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-alipay.png b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-alipay.png
new file mode 100644
index 0000000..eb18cd9
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-alipay.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-bank.png b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-bank.png
new file mode 100644
index 0000000..e0a5a4b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-bank.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-step-wait.png b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-step-wait.png
new file mode 100644
index 0000000..dc5916e
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-step-wait.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-wechat.png b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-wechat.png
new file mode 100644
index 0000000..0bb1c6b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/assets/wallet/icon-wallet-wechat.png
Binary files differ
diff --git a/apps/housekeepingMiniApp/src/components/Avatar/UserAvatar.vue b/apps/housekeepingMiniApp/src/components/Avatar/UserAvatar.vue
new file mode 100644
index 0000000..460464d
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Avatar/UserAvatar.vue
@@ -0,0 +1,14 @@
+<template>
+ <Avatar :src="userDetail?.avatar"></Avatar>
+</template>
+
+<script setup lang="ts">
+import { Avatar } from '@12333/components';
+import { useUser } from '@/hooks';
+
+defineOptions({
+ name: 'UserAvatar',
+});
+
+const { userDetail } = useUser();
+</script>
diff --git a/apps/housekeepingMiniApp/src/components/Avatar/UserInfoAvatar.vue b/apps/housekeepingMiniApp/src/components/Avatar/UserInfoAvatar.vue
new file mode 100644
index 0000000..539a701
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Avatar/UserInfoAvatar.vue
@@ -0,0 +1,95 @@
+<template>
+ <div class="user-info-avatar-wrapper">
+ <Avatar :size="60" class="user-info-avatar" :src="src" />
+ <div class="user-info">
+ <div class="user-info-item-name-wrapper">
+ <div class="user-info-item-name">{{ name }}</div>
+ <template v-if="jobTitle">
+ <div class="user-info-item-dot"></div>
+ <div class="user-info-item-jobTitle">{{ jobTitle }}</div>
+ </template>
+ </div>
+ <div class="user-info-item-company">{{ company }}</div>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { Avatar } from '@12333/components';
+
+defineOptions({
+ name: 'UserInfoAvatar',
+});
+
+type Props = {
+ src?: string;
+ name?: string;
+ company?: string;
+ jobTitle?: string;
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.user-info-avatar-wrapper {
+ display: flex;
+ flex: 1;
+ min-width: 0;
+
+ .user-info-avatar {
+ margin-right: 24px;
+ }
+
+ .user-info {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 12px 0;
+
+ .user-info-item-name-wrapper {
+ color: #ffffff;
+ line-height: 44px;
+ @include ellipsis;
+ vertical-align: middle;
+ font-size: 0;
+ }
+
+ .user-info-item-name {
+ display: inline-block;
+ font-weight: 600;
+ font-size: 32px;
+ vertical-align: middle;
+ }
+
+ .user-info-item-dot {
+ display: inline-block;
+ width: 4px;
+ height: 4px;
+ background: #ffffff;
+ vertical-align: middle;
+ border-radius: 50%;
+ margin: 0 8px;
+ }
+
+ .user-info-item-jobTitle {
+ display: inline-block;
+ font-weight: 400;
+ font-size: 28px;
+ vertical-align: middle;
+ }
+
+ .user-info-item-company {
+ font-weight: 400;
+ font-size: 24px;
+ color: #ffffff;
+ line-height: 34px;
+ @include ellipsis;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Button/LargeButton.vue b/apps/housekeepingMiniApp/src/components/Button/LargeButton.vue
new file mode 100644
index 0000000..219197b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Button/LargeButton.vue
@@ -0,0 +1,28 @@
+<template>
+ <nut-button class="large-button" type="primary">
+ <template v-for="(item, key, i) in $slots" :key="i" v-slot:[key]>
+ <slot :name="key"></slot>
+ </template>
+ </nut-button>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'LargeButton',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.page-layout-wrapper {
+ .large-button {
+ display: block;
+ height: 88px;
+ font-size: 32px;
+ font-weight: 400;
+ color: #ffffff;
+ line-height: 44px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Card/Card.vue b/apps/housekeepingMiniApp/src/components/Card/Card.vue
new file mode 100644
index 0000000..1df0b71
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Card/Card.vue
@@ -0,0 +1,64 @@
+<template>
+ <div :class="['card-wrapper', { shadow, clickable: isLink }]">
+ <slot />
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'Card',
+});
+
+type Props = {
+ shadow?: boolean;
+ isLink?: boolean;
+};
+
+withDefaults(defineProps<Props>(), {
+ shadow: false,
+ isLink: false,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.card-wrapper {
+ background: #ffffff;
+ overflow: hidden;
+ margin-bottom: 24px;
+ position: relative;
+ border-radius: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ &.shadow {
+ box-shadow: 0px 10px 30px 0px rgba(66, 66, 66, 0.1);
+ }
+
+ &:active::before {
+ opacity: 0.1;
+ }
+
+ &.clickable {
+ cursor: pointer;
+
+ &::before {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 100%;
+ height: 100%;
+ background-color: #000;
+ border: inherit;
+ border-color: #000;
+ border-radius: inherit;
+ transform: translate(-50%, -50%);
+ opacity: 0;
+ content: ' ';
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Card/CommonCard.vue b/apps/housekeepingMiniApp/src/components/Card/CommonCard.vue
new file mode 100644
index 0000000..6685d1f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Card/CommonCard.vue
@@ -0,0 +1,146 @@
+<template>
+ <div class="common-card-wrapper">
+ <div class="common-card-content">
+ <div class="common-card-title-wrapper">
+ <div class="common-card-title">{{ title }}</div>
+ <slot name="title-right"></slot>
+ </div>
+ <slot></slot>
+ </div>
+ <div class="common-card-footer">
+ <slot name="footer">
+ <Avatar
+ @click.stop="goUserHomePage"
+ class="common-card-footer-avatar"
+ :size="24"
+ :src="src ? setOSSLink(src) : ''"
+ />
+ <div class="common-card-footer-name-wrapper">
+ <div class="common-card-footer-name">{{ name }}</div>
+ <template v-if="jobTitle">
+ <div class="common-card-footer-dot"></div>
+ <div class="common-card-footer-jobTitle">{{ jobTitle }}</div>
+ </template>
+ <div class="common-card-footer-time">{{ dayjs(time).format('MM-DD HH:mm') }}</div>
+ </div>
+ </slot>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { commonCardProps } from './cardProps';
+import { Avatar } from '@12333/components';
+import { setOSSLink } from '@12333/utils';
+import dayjs from 'dayjs';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'CommonCard',
+});
+
+const props = defineProps(commonCardProps);
+
+function goUserHomePage() {
+ if (props.userId) {
+ Taro.navigateTo({
+ url: `${RouterPath.userHomePage}?userId=${props.userId}`,
+ });
+ }
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.common-card-wrapper {
+ background: #ffffff;
+ border-radius: 8px;
+ padding: 0 28px;
+ margin-bottom: 24px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .common-card-content {
+ padding: 24px 0;
+ border-bottom: 1px solid #f6f6f6;
+
+ .common-card-title-wrapper {
+ display: flex;
+ align-items: center;
+ margin-bottom: 24px;
+
+ .common-card-title {
+ flex: 1;
+ min-width: 0;
+ font-weight: 600;
+ font-size: 32px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 44px;
+ @include ellipsis;
+ }
+
+ .nut-button {
+ height: 44rpx;
+ font-size: 24rpx;
+ padding: 0 30rpx;
+ }
+ }
+ }
+
+ .common-card-footer {
+ padding: 14px 0;
+ display: flex;
+ align-items: center;
+
+ .common-card-footer-avatar {
+ margin-right: 16px;
+ }
+
+ .common-card-footer-name-wrapper {
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 34px;
+ font-size: 0;
+ display: flex;
+ align-items: center;
+ flex: 1;
+ min-width: 0;
+ }
+
+ .common-card-footer-name {
+ font-weight: 400;
+ font-size: 24px;
+ vertical-align: middle;
+ @include ellipsis;
+ }
+
+ .common-card-footer-dot {
+ width: 4px;
+ height: 4px;
+ background: boleGetCssVar('text-color', 'primary');
+ vertical-align: middle;
+ border-radius: 50%;
+ margin: 0 8px;
+ flex-shrink: 0;
+ }
+
+ .common-card-footer-jobTitle {
+ font-weight: 400;
+ font-size: 24px;
+ vertical-align: middle;
+ flex-shrink: 0;
+ }
+
+ .common-card-footer-time {
+ font-weight: 400;
+ font-size: 24px;
+ vertical-align: middle;
+ color: boleGetCssVar('text-color', 'secondary');
+ margin-left: 16px;
+ flex-shrink: 0;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Card/cardProps.ts b/apps/housekeepingMiniApp/src/components/Card/cardProps.ts
new file mode 100644
index 0000000..6f58c8f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Card/cardProps.ts
@@ -0,0 +1,20 @@
+export const commonCardProps = {
+ title: {
+ type: String,
+ },
+ src: {
+ type: String,
+ },
+ name: {
+ type: String,
+ },
+ jobTitle: {
+ type: String,
+ },
+ time: {
+ type: String,
+ },
+ userId: {
+ type: String,
+ },
+};
diff --git a/apps/housekeepingMiniApp/src/components/Chunk/Cell.vue b/apps/housekeepingMiniApp/src/components/Chunk/Cell.vue
new file mode 100644
index 0000000..5aec162
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Chunk/Cell.vue
@@ -0,0 +1,76 @@
+<template>
+ <div class="bole-cell-wrapper">
+ <div class="cell-title-wrapper" v-if="showTitle">
+ <slot name="title">
+ <div :class="titleSize === 'normal' ? 'cell-title' : 'cell-title-large'">{{ title }}</div>
+ <slot name="title-right"></slot>
+ </slot>
+ </div>
+ <slot></slot>
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'Cell',
+});
+
+type Props = {
+ title?: string;
+ titleSize?: 'large' | 'normal';
+ showTitle?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ titleSize: 'normal',
+ showTitle: true,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.bole-cell-wrapper {
+ background: #ffffff;
+ border-radius: 12px;
+ padding: 36px 34px;
+ margin-bottom: 20px;
+
+ .cell-title-wrapper {
+ display: flex;
+ align-items: center;
+ margin-bottom: 24px;
+ justify-content: space-between;
+
+ .cell-title {
+ font-weight: 600;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 40px;
+ position: relative;
+ z-index: 1;
+ @include ellipsis;
+
+ &::after {
+ content: '';
+ width: 100%;
+ height: 16px;
+ background: linear-gradient(90deg, #cfe4ff 0%, rgba(207, 228, 255, 0) 100%);
+ border-radius: 8px;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ z-index: -1;
+ }
+ }
+
+ .cell-title-large {
+ font-weight: 600;
+ font-size: 30px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 42px;
+ @include ellipsis;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Chunk/CellChunk.vue b/apps/housekeepingMiniApp/src/components/Chunk/CellChunk.vue
new file mode 100644
index 0000000..138267f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Chunk/CellChunk.vue
@@ -0,0 +1,38 @@
+<template>
+ <div class="cell-chunk-wrapper">
+ <div class="cell-title-wrapper">
+ <slot name="title">
+ <div :class="titleSize === 'normal' ? 'cell-title' : 'cell-title-large'">{{ title }}</div>
+ <slot name="title-right"></slot>
+ </slot>
+ </div>
+ <slot></slot>
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'CellChunk',
+});
+
+type Props = {
+ title?: string;
+ titleSize?: 'large' | 'normal';
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ titleSize: 'normal',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.cell-chunk-wrapper {
+ margin-bottom: 20px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Chunk/ChunkTitle.vue b/apps/housekeepingMiniApp/src/components/Chunk/ChunkTitle.vue
new file mode 100644
index 0000000..49d88d5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Chunk/ChunkTitle.vue
@@ -0,0 +1,43 @@
+<template>
+ <div class="chunk-title-wrapper">
+ <div class="chunk-title-line"></div>
+ <div class="chunk-title">{{ title }}</div>
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'ChunkTitle',
+});
+
+type Props = {
+ title?: string;
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.chunk-title-wrapper {
+ padding: 32px 0;
+ display: flex;
+ align-items: center;
+
+ .chunk-title-line {
+ width: 4px;
+ height: 32px;
+ background: linear-gradient(90deg, #7198fb 0%, #3a71ff 100%);
+ border-radius: 2px;
+ margin-right: 16px;
+ }
+
+ .chunk-title {
+ font-weight: 600;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 32px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/InfiniteLoading/InfiniteLoading.vue b/apps/housekeepingMiniApp/src/components/InfiniteLoading/InfiniteLoading.vue
new file mode 100644
index 0000000..802be7f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/InfiniteLoading/InfiniteLoading.vue
@@ -0,0 +1,240 @@
+<template>
+ <scroll-view
+ :scroll-y="true"
+ :refresher-background="'transparent'"
+ :lowerThreshold="100"
+ @scrolltolower="lower"
+ :refresherEnabled="refresherEnabled"
+ :refresherTriggered="state.triggered"
+ @refresherrefresh="onRefresherRefresh"
+ :show-scrollbar="false"
+ :style="scrollViewStyle"
+ :enable-back-to-top="true"
+ :class="[scrollViewClassName]"
+ @scroll="onScroll"
+ :scroll-top="scrollDistance"
+ enhanced
+ :scroll-with-animation="true"
+ v-bind="{ ...$attrs }"
+ >
+ <slot name="header"></slot>
+ <LoadingLayout :loading="isLoading" :error="isError" :loadError="() => refetch?.()">
+ <NoData v-if="hasNoData" />
+ <div
+ :class="['infinite-list-inner', { noShowMoreText: !showMoreText, hasPaddingTop }]"
+ v-else
+ >
+ <slot name="extra" />
+ <slot v-if="$slots.default" />
+ <template v-else>
+ <template v-for="(group, index) in listData.pages" :key="index">
+ <template v-for="(item, i) in group.data" :key="i">
+ <slot
+ name="renderItem"
+ :item="item"
+ :groupIndex="index"
+ :itemIndex="i"
+ :index="findDataIndex(item)"
+ />
+ </template>
+ </template>
+ </template>
+ </div>
+ <div
+ v-if="!hasNoData && showMoreText && (listData?.pages?.length > 0 || commonMode) && !hasMore"
+ class="loading-more-tips"
+ >
+ {{ noMoreText }}
+ </div>
+ <div v-if="isFetching && hasMore && enabledLoadingMore" class="infiniting-tips">
+ <Loading class="infiniting-tips-icon"></Loading>鏁版嵁鍔犺浇涓�...
+ </div>
+ </LoadingLayout>
+ </scroll-view>
+ <div class="back-top-wrapper" @click.stop="backToTop" v-show="oldScrollDistance > 100">
+ <img class="back-top-img" :src="IconBackTop" />
+ <div class="back-top-text">杩斿洖椤堕儴</div>
+ </div>
+</template>
+
+<script lang="ts" setup generic="T">
+import { VNode, CSSProperties } from 'vue';
+import NoData from '../NoData/NoData.vue';
+import LoadingLayout from '../Layout/LoadingLayout.vue';
+import { FetchNextPageOptions } from '@tanstack/vue-query';
+import { Loading } from '@nutui/icons-vue-taro';
+import { useScrollDistance } from 'senin-mini/hooks';
+import IconBackTop from '@/assets/components/icon-back-top.png';
+
+defineOptions({
+ name: 'InfiniteLoading',
+});
+
+type Page = {
+ data?: T[];
+ pageModel?: {
+ rows?: number;
+ page?: number;
+ totalCount?: number;
+ totalPage?: number;
+ };
+ [key: string]: any;
+};
+
+type TData = {
+ pages: Page[];
+};
+
+type Props = {
+ // list?: TData;
+ listData?: TData;
+ flattenListData?: T[];
+ renderItem?: (item: T, index: number) => VNode;
+ refresherEnabled?: boolean;
+ hasMore?: boolean;
+ isLoading?: boolean;
+ isError?: boolean;
+ isFetching?: boolean;
+ isFetchingNextPage?: boolean;
+ refetch?: (options?: any) => Promise<any>;
+ scrollViewStyle?: string | CSSProperties;
+ scrollViewClassName?: string;
+ fetchNextPage?: (options?: FetchNextPageOptions) => Promise<any>;
+ showMoreText?: boolean;
+ hasPaddingTop?: boolean;
+ noMoreText?: string;
+ enabledLoadingMore?: boolean;
+ customNoData?: boolean;
+
+ //鏅�氬崟椤垫ā寮�
+ commonMode?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ renderItem: () => () => null,
+ refresherEnabled: true,
+ showMoreText: true,
+ hasPaddingTop: false,
+ noMoreText: '娌℃湁鏇村鍐呭浜唦',
+ enabledLoadingMore: true,
+ customNoData: undefined,
+ commonMode: false,
+});
+
+const emit = defineEmits<{
+ (e: 'refresh', done: () => any): void;
+ (e: 'loadMore'): void;
+}>();
+
+const hasNoData = computed(() => {
+ if (props.customNoData !== undefined) return props.customNoData;
+ if (props.commonMode) return false;
+ if (props.listData?.pages?.length) {
+ return props.listData?.pages[0].data.length === 0;
+ }
+ return true;
+});
+
+const state = reactive({
+ triggered: false,
+});
+
+function lower() {
+ if (props.hasMore && props.enabledLoadingMore) {
+ props.fetchNextPage?.();
+ emit('loadMore');
+ }
+}
+
+// eslint-disable-next-line no-unused-vars
+async function onRefresherRefresh() {
+ try {
+ // 姝e浜庡埛鏂扮姸鎬�
+ if (state.triggered) return;
+ state.triggered = true;
+
+ await props.refetch?.();
+
+ state.triggered = false;
+ } catch (error) {}
+}
+
+const { onScroll, scrollDistance, oldScrollDistance, setScrollDistance } = useScrollDistance();
+
+function backToTop() {
+ setScrollDistance(0);
+}
+
+const scrollToBottom = (dis = 300) => {
+ setScrollDistance(scrollDistance.value + dis);
+};
+
+function findDataIndex(item: T) {
+ return props.flattenListData?.findIndex((data) => data === item);
+}
+
+defineExpose({ backToTop, scrollToBottom });
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.loading-more-tips {
+ color: boleGetCssVar('text-color', 'primary');
+ padding: 18px 10px;
+ width: auto;
+ font-size: 24px;
+ text-align: center;
+}
+
+.infinite-list-inner {
+ // padding: 30px 30px 0;
+
+ &.hasPaddingTop {
+ padding-top: 20px;
+ }
+
+ &.noShowMoreText {
+ padding-bottom: 30px;
+ }
+}
+
+.infiniting-tips {
+ color: boleGetCssVar('text-color', 'primary');
+ padding: 18px 10px;
+ width: auto;
+ font-size: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .infiniting-tips-icon {
+ margin-right: 10px;
+ }
+}
+
+.back-top-wrapper {
+ width: 92px;
+ height: 92px;
+ background: #ffffff;
+ box-shadow: 0px 0px 28px 0px rgba(0, 0, 0, 0.18);
+ position: fixed;
+ border-radius: 50%;
+ right: boleGetCssVar('size', 'body-padding-h');
+ bottom: 390px;
+
+ .back-top-img {
+ width: 44px;
+ height: 44px;
+ margin: 12px auto 2px;
+ }
+
+ .back-top-text {
+ font-weight: 400;
+ font-size: 16px;
+ color: boleGetCssVar('text-color', 'regular');
+ line-height: 22px;
+ text-align: center;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Layout/ContentScrollView.vue b/apps/housekeepingMiniApp/src/components/Layout/ContentScrollView.vue
new file mode 100644
index 0000000..1bb8a3e
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Layout/ContentScrollView.vue
@@ -0,0 +1,54 @@
+<template>
+ <scroll-view class="content-scroll-view-wrapper" :class="{ hasPaddingTop }" :scroll-y="true">
+ <ContentView
+ :class="['content-scroll-view-wrapper-inner', props.allHeight ? 'all-height' : '']"
+ :paddingH="paddingH"
+ >
+ <slot />
+ </ContentView>
+ </scroll-view>
+</template>
+
+<script setup lang="ts">
+import ContentView from './ContentView.vue';
+
+defineOptions({
+ name: 'ContentScrollView',
+});
+
+type Props = {
+ hasPaddingTop?: boolean;
+ allHeight?: boolean;
+ paddingH?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ hasPaddingTop: false,
+ allHeight: false,
+ paddingH: true,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.content-scroll-view-wrapper {
+ @include listScrollViewWithNoPadding;
+ background-color: $body-background-color;
+
+ &.hasPaddingTop {
+ padding-top: 20px;
+ }
+
+ .content-scroll-view-wrapper-inner {
+ @include ScrollViewInner;
+
+ &.all-height {
+ height: 100%;
+ padding-bottom: 0;
+ display: flex;
+ flex-direction: column;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Layout/ContentView.vue b/apps/housekeepingMiniApp/src/components/Layout/ContentView.vue
new file mode 100644
index 0000000..1ee33b6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Layout/ContentView.vue
@@ -0,0 +1,29 @@
+<template>
+ <div :class="['content-view-wrapper', { paddingH }]">
+ <slot />
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'ContentView',
+});
+
+type Props = {
+ paddingH?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ paddingH: true,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.content-view-wrapper {
+ &.paddingH {
+ padding: 0 boleGetCssVar('size', 'body-padding-h');
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Layout/LoadingLayout.vue b/apps/housekeepingMiniApp/src/components/Layout/LoadingLayout.vue
new file mode 100644
index 0000000..0a9d000
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Layout/LoadingLayout.vue
@@ -0,0 +1,58 @@
+<template>
+ <div v-if="loading" class="loading-layout-loading-content-wrapper">
+ <IconFont name="loading" />
+ <div class="list-empty-hint-text">鏁版嵁鍔犺浇涓�......</div>
+ </div>
+ <nut-empty
+ v-else-if="error"
+ class="loading-layout-error-wrapper"
+ status="error"
+ description="鍔犺浇澶辫触"
+ >
+ <div :style="{ marginTop: '10px' }">
+ <nut-button type="primary" @click="loadError"> 閲嶈瘯 </nut-button>
+ </div>
+ </nut-empty>
+ <template v-else>
+ <NoData v-if="showNoData" />
+ <slot v-else></slot>
+ </template>
+</template>
+
+<script setup lang="ts">
+import { loadingLayoutProps } from './layout';
+import { IconFont } from '@nutui/icons-vue-taro';
+import NoData from '../NoData/NoData.vue';
+
+defineOptions({
+ name: 'LoadingLayout',
+});
+
+const props = defineProps(loadingLayoutProps);
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.loading-layout-loading-content-wrapper {
+ padding: 40px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ .nut-icon {
+ color: boleGetCssVar('text-color', 'primary');
+ margin-right: 8px;
+ }
+
+ .list-empty-hint-text {
+ line-height: 1;
+ font-size: 30px;
+ color: boleGetCssVar('text-color', 'primary');
+ }
+}
+
+.loading-layout-error-wrapper {
+ height: 100%;
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Layout/PageLayout.vue b/apps/housekeepingMiniApp/src/components/Layout/PageLayout.vue
new file mode 100644
index 0000000..53b0ee6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Layout/PageLayout.vue
@@ -0,0 +1,139 @@
+<template>
+ <Portal.Host>
+ <div class="page-layout-wrapper" v-bind="$attrs">
+ <slot v-if="showNavigationBar" name="navigationBar">
+ <CommonNavigationBar v-bind="_commonNavigationBarProps" />
+ </slot>
+
+ <slot name="bg">
+ <div
+ v-if="hasLinearBg"
+ class="page-layout-linear-bg"
+ :style="{
+ height: Taro.pxTransform(props.linearBgHeight),
+ }"
+ ></div>
+ </slot>
+
+ <div class="page-layout-scroll-view-wrapper" :style="{ height: scrollViewHeight }">
+ <DevelopingLayout v-if="developing"></DevelopingLayout>
+ <template v-else>
+ <slot :scrollViewHeight="scrollViewHeight" v-if="isAuth"></slot>
+ <!-- <template v-if="isAuth">
+ <slot v-if="useView" :scrollViewHeight="scrollViewHeight"></slot>
+ <scroll-view
+ v-else
+ class="page-scrollview"
+ :scroll-y="true"
+ :style="{ height: scrollViewHeight }"
+ >
+ <slot :scrollViewHeight="scrollViewHeight"></slot>
+ </scroll-view>
+ </template> -->
+ </template>
+ </div>
+ <div v-if="!pageHeightWithTabBar" class="safe-area-bottom"></div>
+ </div>
+ </Portal.Host>
+</template>
+
+<script setup lang="ts">
+// import LoadingLayout from './LoadingLayout.vue';
+// import { loadingLayoutProps } from './layout';
+import CommonNavigationBar from '../NavigationBar/CommonNavigationBar.vue';
+import { commonNavigationBarProps } from '../NavigationBar/commonNavigationBar';
+import { useSystemStore } from '@/stores/modules/system';
+import Taro from '@tarojs/taro';
+import { TabBarPageRouter } from '@/constants';
+import { useAuth } from '@/hooks';
+import { Portal } from 'senin-mini/components';
+import { usePickProps } from 'senin-mini/hooks';
+import { DevelopingLayout } from '@12333/components';
+
+defineOptions({
+ name: 'PageLayout',
+ inheritAttrs: false,
+});
+
+const props = defineProps({
+ ...commonNavigationBarProps,
+ needAuth: {
+ type: Boolean,
+ default: true,
+ },
+ useView: {
+ type: Boolean,
+ default: false,
+ },
+ hasLinearBg: {
+ type: Boolean,
+ default: false,
+ },
+ linearBgHeight: {
+ type: Number,
+ default: 388,
+ },
+ developing: {
+ type: Boolean,
+ default: false,
+ },
+});
+
+const _commonNavigationBarProps = usePickProps(props, commonNavigationBarProps);
+
+const { isAuth } = useAuth({
+ needAuth: props.needAuth,
+});
+
+const systemStore = useSystemStore();
+const router = Taro.useRouter();
+
+const pageHeightWithTabBar = computed(() =>
+ Object.values(TabBarPageRouter).some((x) => x.toLowerCase() === router.path.toLowerCase())
+);
+
+const navigationBarHeight = computed(
+ () => systemStore.info.statusBarHeight + systemStore.navigationBarHeight
+);
+
+const scrollViewHeight = computed(() => {
+ let pageHeight = pageHeightWithTabBar.value
+ ? systemStore.pageHeightWithTab
+ : systemStore.pageHeight;
+ pageHeight = pageHeight + (props.showNavigationBar ? 0 : navigationBarHeight.value);
+ return pageHeight + 'px';
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.page-layout-wrapper {
+ // background-color: $body-background-color;
+
+ .page-layout-scroll-view-wrapper {
+ display: flex;
+ flex-direction: column;
+
+ .page-scrollview {
+ box-sizing: border-box;
+ }
+ }
+
+ .page-layout-linear-bg {
+ position: fixed;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 100%;
+ background: linear-gradient(
+ 180deg,
+ boleGetCssVar('color', 'primary') 0%,
+ #5a86f6 56%,
+ #f9f9fb 100%
+ );
+ filter: blur(0px);
+ border-radius: 0px 0px 20px 20px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Layout/PageLayoutWithBg.vue b/apps/housekeepingMiniApp/src/components/Layout/PageLayoutWithBg.vue
new file mode 100644
index 0000000..99b4aaa
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Layout/PageLayoutWithBg.vue
@@ -0,0 +1,49 @@
+<template>
+ <PageLayout v-bind="props">
+ <template #navigationBar>
+ <TransparentNavigationBar :title="title" :is-absolute="false">
+ <template #left>
+ <slot name="left"></slot>
+ </template>
+ </TransparentNavigationBar>
+ </template>
+ <template #bg>
+ <img :src="OssAssets.common.CommonPageBg" class="common-page-bg" />
+ </template>
+ <template #default="{ scrollViewHeight }">
+ <slot :scrollViewHeight="scrollViewHeight" />
+ </template>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import PageLayout from './PageLayout.vue';
+import TransparentNavigationBar from '../NavigationBar/TransparentNavigationBar.vue';
+import _ from 'lodash';
+import { OssAssets } from '@/constants';
+
+defineOptions({
+ name: 'PageLayoutWithBg',
+});
+
+type Props = {
+ title?: string;
+ developing?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.common-page-bg {
+ position: fixed;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 644px;
+ object-fit: cover;
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Layout/layout.ts b/apps/housekeepingMiniApp/src/components/Layout/layout.ts
new file mode 100644
index 0000000..a43fe7f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Layout/layout.ts
@@ -0,0 +1,19 @@
+import { PropType } from 'vue';
+
+export const loadingLayoutProps = {
+ loading: {
+ type: Boolean,
+ },
+ error: {
+ type: Boolean,
+ },
+ showNoData: {
+ type: Boolean,
+ },
+ loadError: {
+ type: Function as PropType<(...args: any[]) => any>,
+ },
+ id: {
+ type: String,
+ },
+};
diff --git a/apps/housekeepingMiniApp/src/components/Menu/Menu.vue b/apps/housekeepingMiniApp/src/components/Menu/Menu.vue
new file mode 100644
index 0000000..dbf99e6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Menu/Menu.vue
@@ -0,0 +1,216 @@
+<template>
+ <view :class="classes">
+ <view
+ :id="'nut-menu__bar' + refRandomId"
+ class="nut-menu__bar"
+ :class="{ opened: opened, around }"
+ ref="barRef"
+ >
+ <template v-for="(item, index) in children" :key="index">
+ <view
+ class="nut-menu__item"
+ @click="!item.disabled && toggleItem(index)"
+ :class="{ disabled: item.disabled, active: item.state.showPopup }"
+ :style="{ color: item.state.showPopup ? activeColor : '' }"
+ >
+ <view class="nut-menu__title" :class="getClasses(item.state.showPopup)">
+ <view class="nut-menu__title-text">{{ item.renderTitle() }}</view>
+ <span class="nut-menu__title-icon">
+ <slot name="icon">
+ <TriangleUp v-if="direction === 'up'" :size="12" />
+ <TriangleDown v-else :size="12" />
+ </slot>
+ </span>
+ </view>
+ </view>
+ </template>
+ </view>
+ <slot></slot>
+ </view>
+</template>
+<script lang="ts">
+import Taro, { usePageScroll } from '@tarojs/taro';
+import { RectUp, RectDown, TriangleDown, TriangleUp } from '@nutui/icons-vue-taro';
+import { useTaroRect } from 'senin-mini/hooks';
+import './menu.scss';
+
+const componentName = 'nut-menu';
+export default defineComponent({
+ name: 'bl-menu',
+ components: {
+ RectDown,
+ RectUp,
+ TriangleDown,
+ TriangleUp,
+ },
+ props: {
+ activeColor: {
+ type: String,
+ default: '',
+ },
+ overlay: {
+ type: Boolean,
+ default: true as const,
+ },
+ lockScroll: {
+ type: Boolean,
+ default: true as const,
+ },
+ duration: {
+ type: [Number, String],
+ default: 0.3,
+ },
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: true,
+ },
+ direction: {
+ type: String,
+ default: 'down',
+ },
+ scrollFixed: {
+ type: [Boolean, String, Number],
+ default: false,
+ },
+ titleClass: [String],
+ around: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ setup(props) {
+ const barRef = ref<HTMLElement>();
+ const refRandomId = Math.random().toString(36).slice(-8);
+ const offset = ref(0);
+ const isScrollFixed = ref(false);
+
+ const useChildren = () => {
+ const publicChildren: any[] = reactive([]);
+ const internalChildren: any[] = reactive([]);
+
+ const linkChildren = (value?: any) => {
+ const link = (child: any) => {
+ if (child.proxy) {
+ internalChildren.push(child);
+ publicChildren.push(child.proxy as any);
+ }
+ };
+
+ const removeLink = (child: any) => {
+ if (child.proxy) {
+ let internalIndex = internalChildren.indexOf(child);
+ if (internalIndex > -1) {
+ internalChildren.splice(internalIndex, 1);
+ }
+
+ let publicIndex = publicChildren.indexOf(child.proxy);
+ if (internalIndex > -1) {
+ publicChildren.splice(publicIndex, 1);
+ }
+ }
+ };
+
+ provide(
+ 'menuParent',
+ Object.assign(
+ {
+ removeLink,
+ link,
+ children: publicChildren,
+ internalChildren,
+ },
+ value
+ )
+ );
+ };
+
+ return {
+ children: publicChildren,
+ linkChildren,
+ };
+ };
+
+ const { children, linkChildren } = useChildren();
+
+ const opened = computed(() => children.some((item) => item.state.showWrapper));
+
+ const classes = computed(() => {
+ const prefixCls = componentName;
+ return {
+ [prefixCls]: true,
+ 'scroll-fixed': isScrollFixed.value,
+ 'bole-menu-wrapper': true,
+ };
+ });
+
+ const updateOffset = (children: any) => {
+ if (barRef.value) {
+ setTimeout(() => {
+ useTaroRect(barRef, Taro).then((rect: any) => {
+ if (props.direction === 'down') {
+ offset.value = rect.bottom;
+ } else {
+ offset.value = Taro.getSystemInfoSync().windowHeight - rect.top;
+ }
+ children.toggle();
+ });
+ }, 100);
+ }
+ };
+
+ linkChildren({ props, offset });
+
+ const toggleItem = (active: number) => {
+ children.forEach((item, index) => {
+ if (index === active) {
+ updateOffset(item);
+ } else if (item.state.showPopup) {
+ item.toggle(false, { immediate: true });
+ }
+ });
+ };
+
+ const onScroll = (res: { scrollTop: number }) => {
+ const { scrollFixed } = props;
+
+ const scrollTop = res.scrollTop;
+
+ isScrollFixed.value =
+ scrollTop > (typeof scrollFixed === 'boolean' ? 30 : Number(scrollFixed));
+ };
+
+ const getClasses = (showPopup: boolean) => {
+ let str = '';
+ const { titleClass } = props;
+
+ if (showPopup) {
+ str += 'active';
+ }
+
+ if (titleClass) {
+ str += ` ${titleClass}`;
+ }
+
+ return str;
+ };
+
+ usePageScroll((res) => {
+ const { scrollFixed } = props;
+
+ if (scrollFixed) {
+ onScroll(res);
+ }
+ });
+
+ return {
+ toggleItem,
+ children,
+ opened,
+ classes,
+ barRef,
+ refRandomId,
+ getClasses,
+ };
+ },
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/components/Menu/MenuItem.vue b/apps/housekeepingMiniApp/src/components/Menu/MenuItem.vue
new file mode 100644
index 0000000..227252d
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Menu/MenuItem.vue
@@ -0,0 +1,224 @@
+<template>
+ <view class="nut-menu-item" v-show="state.showWrapper" :style="style">
+ <view
+ v-show="state.showPopup"
+ @click="handleClickOutside"
+ class="nut-menu-item-placeholder-element"
+ :style="placeholderElementStyle"
+ :catch-move="parent.props.lockScroll"
+ >
+ </view>
+ <nut-popup
+ :style="{ position: 'absolute' }"
+ :overlayStyle="{ position: 'absolute' }"
+ v-bind="$attrs"
+ v-model:visible="state.showPopup"
+ :position="parent.props.direction === 'down' ? 'top' : 'bottom'"
+ :duration="parent.props.duration"
+ :destroy-on-close="false"
+ :overlay="parent.props.overlay"
+ :lockScroll="parent.props.lockScroll"
+ @closed="handleClose"
+ :close-on-click-overlay="parent.props.closeOnClickOverlay"
+ >
+ <scroll-view :scroll-y="true">
+ <view class="nut-menu-item__content" :class="{ noPadding: !options?.length }">
+ <view
+ v-for="(option, index) in options"
+ :key="index"
+ class="nut-menu-item__option"
+ :class="[{ active: optionIsActive(option) }]"
+ :style="{ 'flex-basis': 100 / cols + '%' }"
+ @click="onClick(option)"
+ >
+ <span
+ class="nut-menu-item__span"
+ v-if="optionIsActive(option)"
+ :class="[optionIsActive(option) ? activeTitleClass : inactiveTitleClass]"
+ >
+ <slot name="icon">
+ <Check v-bind="$attrs" :color="parent.props.activeColor"></Check>
+ </slot>
+ </span>
+ <view
+ :class="[optionIsActive(option) ? activeTitleClass : inactiveTitleClass]"
+ :style="{ color: optionIsActive(option) ? parent.props.activeColor : '' }"
+ >{{ option.text }}</view
+ >
+ </view>
+ </view>
+ <slot></slot>
+ </scroll-view>
+ </nut-popup>
+ </view>
+</template>
+<script lang="ts">
+import { Check } from '@nutui/icons-vue-taro';
+import { isArray } from 'lodash';
+
+type MenuItemOption = {
+ text: string;
+ value: number | string;
+};
+
+export default defineComponent({
+ name: 'bl-menu-item',
+ props: {
+ title: String,
+ options: {
+ type: Array as PropType<MenuItemOption[]>,
+ default: () => [] as MenuItemOption[],
+ },
+ disabled: {
+ type: Boolean,
+ default: false,
+ },
+ modelValue: {
+ type: [Array, String, Number],
+ },
+ cols: {
+ type: Number,
+ default: 1,
+ },
+ activeTitleClass: String,
+ inactiveTitleClass: String,
+ emptyValue: {
+ type: [String, Number],
+ default: null,
+ },
+ emptyTitle: {
+ type: String,
+ default: '',
+ },
+ enableCancelSelect: {
+ type: Boolean,
+ default: true,
+ },
+ multiple: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ components: {
+ Check,
+ },
+ emits: ['update:modelValue', 'change', 'closePopup'],
+ setup(props, { emit }) {
+ const state = reactive({
+ showPopup: false,
+ showWrapper: false,
+ });
+
+ const useParent: any = () => {
+ const parent = inject('menuParent', null);
+ if (parent) {
+ // 鑾峰彇瀛愮粍浠惰嚜宸辩殑瀹炰緥
+ const instance = getCurrentInstance()!;
+ const { link, removeLink } = parent;
+ // @ts-ignore
+ link(instance);
+ onUnmounted(() => {
+ // @ts-ignore
+ removeLink(instance);
+ });
+ return { parent };
+ }
+ };
+
+ const { parent } = useParent();
+
+ const style = computed(() => {
+ return parent.props.direction === 'down'
+ ? { top: parent.offset.value + 'px' }
+ : { bottom: parent.offset.value + 'px' };
+ });
+
+ const placeholderElementStyle = computed(() => {
+ const heightStyle = { height: parent.offset.value + 'px' };
+ if (parent.props.direction === 'down') {
+ return { ...heightStyle, top: '0px' };
+ } else {
+ return { ...heightStyle, bottom: '0px' };
+ }
+ });
+
+ const toggle = (show = !state.showPopup) => {
+ if (show === state.showPopup) {
+ return;
+ }
+ state.showPopup = show;
+ if (show) {
+ state.showWrapper = true;
+ }
+ };
+
+ const renderTitle = () => {
+ if (props.title) {
+ return props.title;
+ }
+ if (isArray(props.modelValue)) {
+ const selectedOptions = (props.options ?? [])
+ .filter((option) => (props.modelValue as any).includes(option.value))
+ .map((x) => x.text);
+ return selectedOptions.length > 0 ? selectedOptions.join(',') : props.emptyTitle;
+ }
+ const match: any = props.options?.find((option: any) => option.value === props.modelValue);
+ return match ? match.text : props.emptyTitle;
+ };
+
+ const onClick = (option: MenuItemOption) => {
+ console.log(1);
+
+ state.showPopup = false;
+ if (props.multiple) {
+ const modelValue = props.modelValue as Array<any>;
+ const val = modelValue.includes(option.value)
+ ? modelValue.filter((x) => x !== option.value)
+ : [...modelValue, option.text];
+ console.log('val: ', val);
+
+ emit('update:modelValue', val);
+ emit('change', val);
+ } else {
+ if (option.value !== props.modelValue) {
+ emit('update:modelValue', option.value);
+ emit('change', option.value);
+ } else {
+ if (props.enableCancelSelect) {
+ emit('update:modelValue', props.emptyValue);
+ emit('change', props.emptyValue);
+ }
+ }
+ }
+ };
+
+ const handleClose = () => {
+ state.showWrapper = false;
+ };
+
+ const handleClickOutside = () => {
+ state.showPopup = false;
+ emit('closePopup');
+ };
+
+ function optionIsActive(option: MenuItemOption) {
+ return isArray(props.modelValue)
+ ? props.modelValue.includes(option.value)
+ : option.value === props.modelValue;
+ }
+
+ return {
+ style,
+ placeholderElementStyle,
+ renderTitle,
+ state,
+ parent,
+ toggle,
+ onClick,
+ handleClose,
+ handleClickOutside,
+ optionIsActive,
+ };
+ },
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/components/Menu/menu.scss b/apps/housekeepingMiniApp/src/components/Menu/menu.scss
new file mode 100644
index 0000000..4641c59
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Menu/menu.scss
@@ -0,0 +1,43 @@
+@import '@/styles/common.scss';
+.bole-menu-wrapper {
+ font-size: 24px !important;
+ color: boleGetCssVar('text-color', 'primary');
+
+ .nut-menu__title-icon {
+ color: boleGetCssVar('text-color', 'secondary');
+ }
+
+ .nut-menu__title.active {
+ .nut-menu__title-icon {
+ color: boleGetCssVar('color', 'primary');
+ }
+ }
+
+ &.nut-menu {
+ .nut-menu__bar {
+ box-shadow: none;
+ // padding: 0 48rpx;
+ padding: 0;
+ justify-content: space-between;
+ background-color: transparent;
+ .nut-menu__item {
+ flex: none;
+ .nut-menu__title-text {
+ padding-left: 0;
+ font-size: 26rpx;
+ color: #000;
+ }
+ }
+
+ &.around {
+ padding: 0 96rpx;
+ }
+ }
+
+ .nut-menu-item__content {
+ &.noPadding {
+ padding: 0;
+ }
+ }
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/components/NavigationBar/CommonNavigationBar.vue b/apps/housekeepingMiniApp/src/components/NavigationBar/CommonNavigationBar.vue
new file mode 100644
index 0000000..c2e9a93
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/NavigationBar/CommonNavigationBar.vue
@@ -0,0 +1,104 @@
+<template>
+ <NavBar v-bind="props">
+ <div
+ :class="['common-navigation-bar-wrapper', { dark: props.mode == 'dark' }]"
+ :style="barStyle"
+ >
+ <div
+ class="menu-btn-wrapper"
+ v-if="(!isLastPage || !isTabbarPage) && showLeftArrow"
+ @click="handleBack()"
+ >
+ <img class="menu-btn" :src="props.mode == 'dark' ? IconArrowWhite : IconArrow" />
+ </div>
+ <span class="common-navigation-bar-title">{{ title }}</span>
+ </div>
+ </NavBar>
+</template>
+
+<script setup lang="ts">
+import NavBar from './NavBar.vue';
+import { commonNavigationBarProps } from './commonNavigationBar';
+import { useSystemStore } from '@/stores/modules/system';
+import { CSSProperties } from 'vue';
+import IconArrow from '@/assets/common/icon-navi-arrow.png';
+import IconArrowWhite from '@/assets/common/icon-navi-arrow-white.png';
+import Taro from '@tarojs/taro';
+import { goBack } from '@/utils';
+import { TabBarPageRouter } from '@/constants';
+
+defineOptions({
+ name: 'CommonNavigationBar',
+});
+
+const systemStore = useSystemStore();
+
+const props = defineProps(commonNavigationBarProps);
+
+const router = Taro.useRouter();
+
+const isLastPage = computed(() => {
+ const pages = Taro.getCurrentPages();
+ return pages.length <= 1;
+});
+
+const isTabbarPage = computed(() =>
+ Object.values(TabBarPageRouter).some((x) => x.toLowerCase() === router.path.toLowerCase())
+);
+
+const barStyle = computed(() => {
+ const distance = systemStore.menuButtonWidth + systemStore.menuButtonRightDistance + 4;
+ return {
+ paddingLeft: `${distance}px`,
+ paddingRight: `${distance}px`,
+
+ height: systemStore.navigationBarHeight + 'px',
+ } as CSSProperties;
+});
+
+function handleBack() {
+ if (props.backFn) {
+ props.backFn();
+ } else {
+ goBack();
+ }
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.common-navigation-bar-wrapper {
+ width: 100%;
+ line-height: 1;
+ font-size: 32px;
+ color: boleGetCssVar('color', 'title-color');
+ min-width: 0;
+ position: relative;
+ align-items: center;
+ display: flex;
+ justify-content: center;
+
+ .common-navigation-bar-title {
+ @include ellipsis;
+ font-weight: 600;
+ }
+
+ &.dark {
+ color: #fff;
+ }
+
+ .menu-btn-wrapper {
+ padding: 20px;
+ padding-left: 0;
+ position: absolute;
+ left: boleGetCssVar('size', 'body-padding-h');
+ // top: -20px;
+ }
+
+ .menu-btn {
+ width: 20px;
+ height: 30px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/NavigationBar/LargeTitleNavigationBar.vue b/apps/housekeepingMiniApp/src/components/NavigationBar/LargeTitleNavigationBar.vue
new file mode 100644
index 0000000..61451db
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/NavigationBar/LargeTitleNavigationBar.vue
@@ -0,0 +1,61 @@
+<template>
+ <NavBar v-bind="props" class="large-title-navigation-bar">
+ <div :class="['large-title-navigation-bar-wrapper']" :style="barStyle">
+ <slot name="title">
+ <span class="large-title-navigation-bar-title">{{ title }}</span>
+ </slot>
+ </div>
+ </NavBar>
+</template>
+
+<script setup lang="ts">
+import NavBar from './NavBar.vue';
+import { commonNavigationBarProps } from './commonNavigationBar';
+import { useSystemStore } from '@/stores/modules/system';
+import { CSSProperties } from 'vue';
+// import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'LargeTitleNavigationBar',
+});
+
+const systemStore = useSystemStore();
+
+const props = defineProps(commonNavigationBarProps);
+
+const barStyle = computed(() => {
+ const distance = systemStore.menuButtonWidth + systemStore.menuButtonRightDistance + 4;
+ return {
+ // paddingLeft: `${distance}px`,
+ paddingRight: `${distance}px`,
+ height: systemStore.navigationBarHeight + 'px',
+ } as CSSProperties;
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.large-title-navigation-bar {
+ background-color: transparent;
+ position: relative;
+ z-index: 1;
+}
+
+.large-title-navigation-bar-wrapper {
+ width: 100%;
+ line-height: 1;
+ font-size: 40px;
+ color: #fff;
+ min-width: 0;
+ position: relative;
+ align-items: center;
+ display: flex;
+ font-weight: bold;
+ padding-left: 30px;
+
+ .large-title-navigation-bar-title {
+ @include ellipsis;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/NavigationBar/NavBar.vue b/apps/housekeepingMiniApp/src/components/NavigationBar/NavBar.vue
new file mode 100644
index 0000000..23138fb
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/NavigationBar/NavBar.vue
@@ -0,0 +1,58 @@
+<template>
+ <div
+ :class="[
+ 'navigation-bar-wrapper',
+ { active: props.mode === 'dark', plain: props.plain, hasBorder: props.hasBorder },
+ ]"
+ :style="barStyle"
+ >
+ <slot></slot>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { CSSProperties } from 'vue';
+import { useSystemStore } from '@/stores/modules/system';
+import { navigationBarProps } from './navBar';
+
+defineOptions({
+ name: 'NavBar',
+});
+
+const props = defineProps(navigationBarProps);
+
+const systemStore = useSystemStore();
+
+const barStyle = computed(
+ () =>
+ ({
+ paddingTop: systemStore.info.statusBarHeight + 'px',
+ // height: systemStore.navigationBarHeight + 'px',
+ } as CSSProperties)
+);
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.navigation-bar-wrapper {
+ background-color: #fff;
+ display: flex;
+ position: relative;
+ // box-shadow: 0px 1px 7px 0px rgb(237, 238, 241);
+ z-index: 10;
+
+ &.plain {
+ border-bottom-left-radius: 20px;
+ border-bottom-right-radius: 20px;
+ }
+
+ &.active {
+ background-color: boleGetCssVar('color', 'primary');
+ }
+
+ &.hasBorder {
+ border-bottom: 1px solid #f6f6f6;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/NavigationBar/TransparentNavigationBar.vue b/apps/housekeepingMiniApp/src/components/NavigationBar/TransparentNavigationBar.vue
new file mode 100644
index 0000000..5ffc2e8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/NavigationBar/TransparentNavigationBar.vue
@@ -0,0 +1,77 @@
+<template>
+ <NavBar v-bind="props" dark class="transparent-navigation-bar" :style="wrapperStyle">
+ <div :class="['common-navigation-bar-wrapper', { dark: mode == 'dark' }]" :style="barStyle">
+ <slot name="left">
+ <div
+ class="menu-btn-wrapper"
+ v-if="(!isLastPage || !isTabbarPage) && showLeftArrow"
+ @click="goBack()"
+ >
+ <img v-if="props.navigationArrowWhite" class="menu-btn" :src="IconArrowWhite" />
+ <img v-else class="menu-btn" :src="IconArrow" />
+ </div>
+ </slot>
+ <span class="common-navigation-bar-title">{{ title }}</span>
+ </div>
+ </NavBar>
+</template>
+
+<script setup lang="ts">
+import NavBar from './NavBar.vue';
+import { commonNavigationBarProps } from './commonNavigationBar';
+import { useSystemStore } from '@/stores/modules/system';
+import { CSSProperties } from 'vue';
+import IconArrow from '@/assets/common/icon-navi-arrow.png';
+import IconArrowWhite from '@/assets/common/icon-navi-arrow-white.png';
+import Taro from '@tarojs/taro';
+import { goBack } from '@/utils';
+import { TabBarPageRouter } from '@/constants';
+
+defineOptions({
+ name: 'TransparentNavigationBar',
+});
+
+const systemStore = useSystemStore();
+
+const props = defineProps(commonNavigationBarProps);
+
+const router = Taro.useRouter();
+
+const isLastPage = computed(() => {
+ const pages = Taro.getCurrentPages();
+ return pages.length <= 1;
+});
+
+const isTabbarPage = computed(() =>
+ Object.values(TabBarPageRouter).some((x) => x.toLowerCase() === router.path.toLowerCase())
+);
+
+const barStyle = computed(() => {
+ const distance = systemStore.menuButtonWidth + systemStore.menuButtonRightDistance + 4;
+ return {
+ paddingLeft: `${distance}px`,
+ paddingRight: `${distance}px`,
+ height: systemStore.navigationBarHeight + 'px',
+ } as CSSProperties;
+});
+
+const wrapperStyle = computed(() => {
+ return props.isAbsolute
+ ? ({
+ position: 'absolute',
+ } as CSSProperties)
+ : {};
+});
+</script>
+
+<style lang="scss">
+.transparent-navigation-bar.navigation-bar-wrapper {
+ background-color: transparent;
+ /* position: absolute; */
+ width: 100%;
+
+ .common-navigation-bar-title {
+ height: 36px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/NavigationBar/commonNavigationBar.ts b/apps/housekeepingMiniApp/src/components/NavigationBar/commonNavigationBar.ts
new file mode 100644
index 0000000..8c8be8d
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/NavigationBar/commonNavigationBar.ts
@@ -0,0 +1,28 @@
+import { navigationBarProps } from './navBar';
+
+export const commonNavigationBarProps = {
+ title: {
+ type: String,
+ default: '',
+ },
+ showLeftArrow: {
+ type: Boolean,
+ default: true,
+ },
+ showNavigationBar: {
+ type: Boolean,
+ default: true,
+ },
+ navigationArrowWhite: {
+ type: Boolean,
+ default: false,
+ },
+ isAbsolute: {
+ type: Boolean,
+ default: true,
+ },
+ backFn: {
+ type: Function,
+ },
+ ...navigationBarProps,
+};
diff --git a/apps/housekeepingMiniApp/src/components/NavigationBar/navBar.ts b/apps/housekeepingMiniApp/src/components/NavigationBar/navBar.ts
new file mode 100644
index 0000000..2069e68
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/NavigationBar/navBar.ts
@@ -0,0 +1,14 @@
+export const navigationBarProps = {
+ mode: {
+ type: String as PropType<'light' | 'dark'>,
+ default: 'light',
+ },
+ plain: {
+ type: Boolean,
+ default: false,
+ },
+ hasBorder: {
+ type: Boolean,
+ default: false,
+ },
+};
diff --git a/apps/housekeepingMiniApp/src/components/NoData/NoData.vue b/apps/housekeepingMiniApp/src/components/NoData/NoData.vue
new file mode 100644
index 0000000..4e3cb23
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/NoData/NoData.vue
@@ -0,0 +1,44 @@
+<template>
+ <div class="no-data-wrapper">
+ <img class="no-data-img" :src="NoDataImage" alt="" />
+ <span class="no-data-text">鏆傛棤鏁版嵁</span>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+import { NoDataImage } from '@12333/constants';
+
+export default defineComponent({
+ name: 'NoData',
+
+ setup() {
+ return {
+ NoDataImage,
+ };
+ },
+});
+</script>
+
+<style lang="scss">
+.no-data-wrapper {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+
+ .no-data-img {
+ width: 284px;
+ height: 202px;
+ }
+
+ .no-data-text {
+ font-size: 20px;
+ color: #333333;
+ line-height: 2.4;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/PageFooter/PageFooter.vue b/apps/housekeepingMiniApp/src/components/PageFooter/PageFooter.vue
new file mode 100644
index 0000000..e10f059
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/PageFooter/PageFooter.vue
@@ -0,0 +1,177 @@
+<template>
+ <div :class="['page-footer', { isOnlyAction }]">
+ <div class="page-footer-inner">
+ <slot></slot>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'PageFooter',
+});
+
+type Props = {
+ isOnlyAction?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ isOnlyAction: true,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.page-footer {
+ /* height: 112px; */
+ background-color: #fff;
+ // position: fixed;
+ // bottom: 0;
+ width: 100%;
+ display: flex;
+ box-shadow: $base-footer-box-shadow;
+ position: relative;
+ z-index: 1;
+
+ // padding-bottom: constant(safe-area-inset-bottom);
+ // padding-bottom: env(safe-area-inset-bottom);
+
+ // z-index: 10000;
+
+ &::after {
+ content: '';
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ transform: translateY(100%);
+ padding-bottom: constant(safe-area-inset-bottom);
+ padding-bottom: env(safe-area-inset-bottom);
+ background-color: #fff;
+ }
+
+ .page-footer-inner {
+ padding: 24px 0;
+ width: 100%;
+ display: flex;
+ box-sizing: border-box;
+ align-items: center;
+ }
+
+ &.isOnlyAction {
+ .page-footer-inner {
+ padding: 16px 0;
+ align-items: flex-start;
+ }
+ }
+
+ .is-button-footer {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ padding: 25px 30px;
+ box-sizing: border-box;
+
+ .common-page-footer-btn-group {
+ margin: 0 -12rpx;
+ display: flex;
+ width: calc(100% + 24rpx);
+ }
+
+ .nut-button {
+ flex: 1;
+ margin: 0 12rpx;
+ height: 100%;
+ font-size: 32rpx;
+ border-radius: 10rpx;
+ border: none;
+ font-weight: 400;
+
+ &.cancel-btn {
+ color: boleGetCssVar('text-color', 'primary') !important;
+ }
+
+ &.confirm-btn {
+ box-shadow: 0px 3px 7px 0px rgba(240, 67, 73, 0.35);
+ }
+ }
+ }
+
+ .common-page-footer {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ align-items: center;
+
+ .common-page-footer-actions {
+ flex: 1;
+ display: flex;
+ justify-content: space-around;
+ min-width: 0;
+ padding-right: 20px;
+
+ .common-page-footer-action {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ .common-page-footer-action-icon {
+ width: 35px;
+ height: 35px;
+ margin-bottom: 14px;
+ }
+
+ .common-page-footer-action-text {
+ line-height: 1;
+ font-size: 22px;
+ color: #1b232f;
+ }
+ }
+ }
+
+ .common-page-footer-btn-group {
+ display: flex;
+ margin: 0 -20rpx;
+ width: auto;
+
+ .nut-button {
+ margin: 0 20rpx;
+ }
+
+ &.small {
+ margin: 0 -12rpx;
+
+ .nut-button {
+ margin: 0 12rpx;
+ }
+ }
+
+ .one-btn {
+ width: 364px;
+ font-size: 26px;
+ border-radius: 36px;
+ }
+ }
+
+ .common-page-footer-btn-badge {
+ z-index: 10;
+ }
+
+ .common-page-footer-btn {
+ width: 200px;
+ height: 80px;
+ border-radius: 10px;
+ min-width: 0;
+ font-size: 32px;
+ flex: none;
+ }
+
+ .contact-btn {
+ margin: 0;
+ margin-left: 20px;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/PageFooter/PageFooterAction.vue b/apps/housekeepingMiniApp/src/components/PageFooter/PageFooterAction.vue
new file mode 100644
index 0000000..7b5f1df
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/PageFooter/PageFooterAction.vue
@@ -0,0 +1,67 @@
+<template>
+ <button :class="['page-footer-action', { isFlex }]">
+ <img :src="icon" class="page-footer-action-icon" />
+ <div class="page-footer-action-text">{{ text }}</div>
+ </button>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'PageFooterAction',
+});
+
+type Props = {
+ isFlex?: boolean;
+ icon?: string;
+ text?: string;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ isFlex: true,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.page-footer-action {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background-color: transparent;
+ border-radius: 0;
+ outline: none;
+ border: none;
+ padding: 0;
+ appearance: none;
+ user-select: none;
+ margin: 0 28px;
+
+ &::after {
+ display: none;
+ }
+
+ &.isFlex {
+ flex: 1;
+ min-width: 0;
+ margin: 0;
+
+ & + .page-footer-action.isFlex {
+ border-left: 1px solid #ebebeb;
+ }
+ }
+
+ .page-footer-action-icon {
+ width: 40px;
+ height: 40px;
+ margin-bottom: 4px;
+ }
+
+ .page-footer-action-text {
+ font-weight: 400;
+ font-size: 24px;
+ color: boleGetCssVar('text-color', 'regular');
+ line-height: 34px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/PageFooter/PageFooterBtn.vue b/apps/housekeepingMiniApp/src/components/PageFooter/PageFooterBtn.vue
new file mode 100644
index 0000000..f67770c
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/PageFooter/PageFooterBtn.vue
@@ -0,0 +1,34 @@
+<template>
+ <nut-button class="page-footer-btn" $attrs>
+ <slot></slot>
+ </nut-button>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'PageFooterBtn',
+});
+
+// type Props = {
+// text;
+// };
+
+// const props = withDefaults(defineProps<Props>(), {});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.page-footer-btn.h5-button {
+ flex: 1;
+ min-width: 0;
+ height: 88px;
+ font-size: 32px;
+ margin: 0 28px;
+ border-radius: 44px;
+
+ &.nut-button--plain {
+ border-width: 1px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Policy/Policy.vue b/apps/housekeepingMiniApp/src/components/Policy/Policy.vue
new file mode 100644
index 0000000..debe20f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Policy/Policy.vue
@@ -0,0 +1,89 @@
+<template>
+ <div class="policy-wrapper">
+ <nut-radio-group v-model="innerModelValue">
+ <BlRadio :label="true">
+ <div class="policy-content">
+ {{ props.policyBtnText }}
+ <div class="policy-content-btn" @click.stop="goPolicy">銆婄敤鎴峰崗璁拰闅愮鏀跨瓥銆�</div>
+ </div>
+ </BlRadio>
+ </nut-radio-group>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { Radio as BlRadio } from '@12333/components';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'Policy',
+});
+
+const props = defineProps<{
+ modelValue: boolean;
+ policyBtnText?: string;
+}>();
+
+const emit = defineEmits<{
+ (e: 'update:modelValue', value: boolean): void;
+}>();
+
+const innerModelValue = computed({
+ get() {
+ return props.modelValue;
+ },
+ set(val) {
+ emit('update:modelValue', val);
+ },
+});
+
+function goPolicy() {
+ Taro.navigateTo({
+ url: RouterPath.userPolicy,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.policy-wrapper {
+ text-align: center;
+ padding: 0 64px;
+
+ .nut-radio-group {
+ vertical-align: middle;
+
+ .nutui-iconfont {
+ font-size: 12px;
+ height: 16px !important;
+ width: 16px !important;
+ }
+
+ .bl-radio {
+ align-items: flex-start;
+ }
+
+ .nut-radio__icon--unchecked {
+ color: boleGetCssVar('text-color', 'secondary');
+ }
+ }
+
+ .nut-radio__label {
+ margin-left: 2px;
+ }
+
+ .policy-content {
+ font-size: 24px;
+ color: boleGetCssVar('text-color', 'secondary');
+ line-height: 30px;
+ text-align: left;
+ word-break: break-all;
+
+ .policy-content-btn {
+ color: boleGetCssVar('color', 'primary');
+ display: inline;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/RichEditCard/RichContent.vue b/apps/housekeepingMiniApp/src/components/RichEditCard/RichContent.vue
new file mode 100644
index 0000000..ac9f4b2
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/RichEditCard/RichContent.vue
@@ -0,0 +1,46 @@
+<template>
+ <div :class="['rich-edit-content', size]">
+ <template v-for="(item, index) in content" :key="index">
+ <AutoWidthImage
+ v-if="item.type === EditorType.Image"
+ wrapperClassName="rich-content-item rich-content-image-item"
+ :src="setOSSLink(item.path)"
+ />
+ <Video
+ v-else-if="item.type === EditorType.Video"
+ class="rich-content-item rich-content-video-item"
+ :src="setOSSLink(item.path)"
+ ></Video>
+ <RichEditorContent
+ v-else-if="item.type === EditorType.Rich || item.type === EditorType.WXContent"
+ :content="item.content"
+ ></RichEditorContent>
+ <div v-else class="rich-content-item rich-content-text-item">
+ {{ item.content }}
+ </div>
+ </template>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { AutoWidthImage } from '@12333/components';
+import { EditorType } from '@12333/constants';
+import { setOSSLink } from '@12333/utils';
+import { Video } from '@tarojs/components';
+import RichEditorContent from '../RichEditor/RichEditorContent.vue';
+// import {} from '@nutui/nutui-taro/dist/packages/video'
+
+defineOptions({
+ name: 'RichContent',
+});
+
+type Props = {
+ content?: API.IntroInfo[];
+ size?: 'small' | 'default' | 'large';
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ content: () => [],
+ size: 'default',
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/components/RichEditCard/RichEditCard.vue b/apps/housekeepingMiniApp/src/components/RichEditCard/RichEditCard.vue
new file mode 100644
index 0000000..cba993b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/RichEditCard/RichEditCard.vue
@@ -0,0 +1,137 @@
+<template>
+ <Card class="rich-edit-card">
+ <div class="rich-edit-card-title">{{ title }}</div>
+ <slot>
+ <RichContent v-if="content.length > 0" :content="content" />
+ <div class="rich-edit-card-add-wrapper" @click="handleClick">
+ <img :src="AddIcon" class="rich-edit-card-add-icon" />
+ <div class="rich-edit-card-add-text">鍙坊鍔犲浘鏂囦粙缁�</div>
+ <div class="rich-edit-card-add-danger">鍘荤紪杈�</div>
+ </div>
+ </slot>
+ </Card>
+</template>
+
+<script setup lang="ts">
+import Card from '../Card/Card.vue';
+import AddIcon from '@/assets/components/rich-card/icon-add.png';
+import Taro from '@tarojs/taro';
+import RichContent from './RichContent.vue';
+import { EmptyTextEditorItem } from '@12333/constants';
+
+defineOptions({
+ name: 'RichEditCard',
+});
+
+type Props = {
+ title?: string;
+ content?: API.IntroInfo[];
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ content: () => [],
+});
+
+const emit = defineEmits<{
+ (e: 'update:content', content: Props['content']): void;
+}>();
+
+function handleClick() {
+ Taro.navigateTo({
+ url: RouterPath.editRichContent,
+ events: {
+ addRichContent: function (data: { content: API.IntroInfo[] }) {
+ console.log('EditRichContent onChange', data.content);
+ emit(
+ 'update:content',
+ data.content.length > 0 ? data.content : [{ ...EmptyTextEditorItem }]
+ );
+ },
+ },
+ success: function (res) {
+ res.eventChannel.emit('acceptRichContent', { content: props.content });
+ },
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.rich-edit-card {
+ padding: 28px 32px;
+
+ .rich-edit-card-title {
+ margin-bottom: 20px;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ // font-weight: bold;
+ }
+
+ .rich-edit-card-add-wrapper {
+ margin-top: 32px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ .rich-edit-card-add-icon {
+ width: 20px;
+ height: 20px;
+ margin-right: 10px;
+ }
+
+ .rich-edit-card-add-text,
+ .rich-edit-card-add-danger {
+ line-height: 1;
+ font-size: 26px;
+ }
+
+ .rich-edit-card-add-text {
+ color: #8c8c8c;
+ margin-right: 6px;
+ }
+
+ .rich-edit-card-add-danger {
+ color: boleGetCssVar('color', 'primary');
+ }
+ }
+
+ .nut-textarea {
+ padding: 0;
+ }
+}
+
+.rich-edit-content {
+ .rich-content-item {
+ margin-bottom: 10px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .rich-content-image-item {
+ display: block;
+ }
+
+ .rich-content-text-item {
+ word-break: break-all;
+ white-space: pre-line;
+ font-size: 30px;
+ line-height: 50px;
+ color: boleGetCssVar('text-color', 'primary');
+ }
+
+ .rich-content-video-item {
+ width: 100%;
+ height: 300px;
+ }
+
+ &.small {
+ .rich-content-text-item {
+ font-size: 24px;
+ line-height: 36px;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/RichEditor/RichEditorContent.vue b/apps/housekeepingMiniApp/src/components/RichEditor/RichEditorContent.vue
new file mode 100644
index 0000000..32ca067
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/RichEditor/RichEditorContent.vue
@@ -0,0 +1,59 @@
+<template>
+ <div class="rich-text-wrapper">
+ <rich-text :nodes="_content" style="word-wrap: break-word"></rich-text>
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'RichEditorContent',
+});
+
+type Props = {
+ content: string;
+};
+
+const _content = computed(() =>
+ props.content.replace(/<img[^>]*>/g, (match) => {
+ let str = match.replace(`width=""`, '').replace(`height=""`, '').replace(`style=""`, '');
+
+ if (/style="/.test(str)) {
+ str = str.replace('style="', 'style="max-width: 100%; ');
+ } else {
+ str = str.replace('<img', '<img style="max-width: 100%;" ');
+ }
+
+ return str;
+ })
+);
+
+const props = withDefaults(defineProps<Props>(), {});
+</script>
+
+<!-- <style>
+@import './style.css';
+</style> -->
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.rich-text-wrapper {
+ overflow-x: hidden;
+ color: boleGetCssVar('text-color', 'primary');
+ font-size: 28px;
+
+ rich-text {
+ overflow-x: hidden;
+ word-wrap: break-word;
+ white-space: normal;
+ }
+
+ /* .h5-img,
+ img {
+ max-width: 100%;
+ min-height: 20px;
+ min-width: 20px;
+ display: inline !important;
+ } */
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/RichEditor/style.css b/apps/housekeepingMiniApp/src/components/RichEditor/style.css
new file mode 100644
index 0000000..52c28c1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/RichEditor/style.css
@@ -0,0 +1,715 @@
+:host,
+:root {
+ --w-e-textarea-bg-color: #fff;
+ --w-e-textarea-color: #333;
+ --w-e-textarea-border-color: #ccc;
+ --w-e-textarea-slight-border-color: #e8e8e8;
+ --w-e-textarea-slight-color: #d4d4d4;
+ --w-e-textarea-slight-bg-color: #f5f2f0;
+ --w-e-textarea-selected-border-color: #b4d5ff;
+ --w-e-textarea-handler-bg-color: #4290f7;
+ --w-e-toolbar-color: #595959;
+ --w-e-toolbar-bg-color: #fff;
+ --w-e-toolbar-active-color: #333;
+ --w-e-toolbar-active-bg-color: #f1f1f1;
+ --w-e-toolbar-disabled-color: #999;
+ --w-e-toolbar-border-color: #e8e8e8;
+ --w-e-modal-button-bg-color: #fafafa;
+ --w-e-modal-button-border-color: #d9d9d9;
+}
+.w-e-text-container *,
+.w-e-toolbar * {
+ box-sizing: border-box;
+ margin: 0;
+ outline: none;
+ padding: 0;
+}
+.w-e-text-container blockquote,
+.w-e-text-container li,
+.w-e-text-container p,
+.w-e-text-container td,
+.w-e-text-container th,
+.w-e-toolbar * {
+ line-height: 1.5;
+}
+.w-e-text-container {
+ background-color: var(--w-e-textarea-bg-color);
+ color: var(--w-e-textarea-color);
+ height: 100%;
+ position: relative;
+}
+.no-scroll {
+ width: 100%;
+}
+.w-e-text-container .w-e-scroll {
+ -webkit-overflow-scrolling: touch;
+ height: 100%;
+}
+.w-e-text-container [data-slate-editor] {
+ word-wrap: break-word;
+ border-top: 1px solid transparent;
+ min-height: 100%;
+ outline: 0;
+ padding: 0 10px;
+ white-space: pre-wrap;
+}
+.w-e-text-container [data-slate-editor] p {
+ margin: 15px 0;
+}
+.w-e-text-container [data-slate-editor] h1,
+.w-e-text-container [data-slate-editor] h2,
+.w-e-text-container [data-slate-editor] h3,
+.w-e-text-container [data-slate-editor] h4,
+.w-e-text-container [data-slate-editor] h5 {
+ margin: 20px 0;
+}
+.w-e-text-container img {
+ cursor: default;
+ display: inline !important;
+ max-width: 100%;
+ min-height: 20px;
+ min-width: 20px;
+}
+.w-e-text-container [data-slate-editor] span {
+ text-indent: 0;
+}
+.w-e-text-container [data-slate-editor] [data-selected='true'] {
+ box-shadow: 0 0 0 2px var(--w-e-textarea-selected-border-color);
+}
+.w-e-text-placeholder {
+ font-style: italic;
+ left: 10px;
+ top: 17px;
+ width: 90%;
+}
+.w-e-max-length-info,
+.w-e-text-placeholder {
+ color: var(--w-e-textarea-slight-color);
+ pointer-events: none;
+ position: absolute;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+.w-e-max-length-info {
+ bottom: 0.5em;
+ right: 1em;
+}
+.w-e-bar {
+ background-color: var(--w-e-toolbar-bg-color);
+ color: var(--w-e-toolbar-color);
+ font-size: 14px;
+ padding: 0 5px;
+}
+.w-e-bar svg {
+ fill: var(--w-e-toolbar-color);
+ height: 14px;
+ width: 14px;
+}
+.w-e-bar-show {
+ display: flex;
+}
+.w-e-bar-hidden {
+ display: none;
+}
+.w-e-hover-bar {
+ border: 1px solid var(--w-e-toolbar-border-color);
+ border-radius: 3px;
+ box-shadow: 0 2px 5px #0000001f;
+ position: absolute;
+}
+.w-e-toolbar {
+ flex-wrap: wrap;
+ position: relative;
+}
+.w-e-bar-divider {
+ background-color: var(--w-e-toolbar-border-color);
+ display: inline-flex;
+ height: 40px;
+ margin: 0 5px;
+ width: 1px;
+}
+.w-e-bar-item {
+ display: flex;
+ height: 40px;
+ padding: 4px;
+ position: relative;
+ text-align: center;
+}
+.w-e-bar-item,
+.w-e-bar-item button {
+ align-items: center;
+ justify-content: center;
+}
+.w-e-bar-item button {
+ background: transparent;
+ border: none;
+ color: var(--w-e-toolbar-color);
+ cursor: pointer;
+ display: inline-flex;
+ height: 32px;
+ overflow: hidden;
+ padding: 0 8px;
+ white-space: nowrap;
+}
+.w-e-bar-item button:hover {
+ background-color: var(--w-e-toolbar-active-bg-color);
+ color: var(--w-e-toolbar-active-color);
+}
+.w-e-bar-item button .title {
+ margin-left: 5px;
+}
+.w-e-bar-item .active {
+ background-color: var(--w-e-toolbar-active-bg-color);
+ color: var(--w-e-toolbar-active-color);
+}
+.w-e-bar-item .disabled {
+ color: var(--w-e-toolbar-disabled-color);
+ cursor: not-allowed;
+}
+.w-e-bar-item .disabled svg {
+ fill: var(--w-e-toolbar-disabled-color);
+}
+.w-e-bar-item .disabled:hover {
+ background-color: var(--w-e-toolbar-bg-color);
+ color: var(--w-e-toolbar-disabled-color);
+}
+.w-e-bar-item .disabled:hover svg {
+ fill: var(--w-e-toolbar-disabled-color);
+}
+.w-e-menu-tooltip-v5:before {
+ background-color: var(--w-e-toolbar-active-color);
+ border-radius: 5px;
+ color: var(--w-e-toolbar-bg-color);
+ content: attr(data-tooltip);
+ font-size: 0.75em;
+ padding: 5px 10px;
+ text-align: center;
+ top: 40px;
+ white-space: pre;
+ z-index: 1;
+}
+.w-e-menu-tooltip-v5:after,
+.w-e-menu-tooltip-v5:before {
+ opacity: 0;
+ position: absolute;
+ transition: opacity 0.6s;
+ visibility: hidden;
+}
+.w-e-menu-tooltip-v5:after {
+ border: 5px solid transparent;
+ border-bottom: 5px solid var(--w-e-toolbar-active-color);
+ content: '';
+ top: 30px;
+}
+.w-e-menu-tooltip-v5:hover:after,
+.w-e-menu-tooltip-v5:hover:before {
+ opacity: 1;
+ visibility: visible;
+}
+.w-e-menu-tooltip-v5.tooltip-right:before {
+ left: 100%;
+ top: 10px;
+}
+.w-e-menu-tooltip-v5.tooltip-right:after {
+ border-bottom-color: transparent;
+ border-left-color: transparent;
+ border-right-color: var(--w-e-toolbar-active-color);
+ border-top-color: transparent;
+ left: 100%;
+ margin-left: -10px;
+ top: 16px;
+}
+.w-e-bar-item-group .w-e-bar-item-menus-container {
+ background-color: var(--w-e-toolbar-bg-color);
+ border: 1px solid var(--w-e-toolbar-border-color);
+ border-radius: 3px;
+ box-shadow: 0 2px 10px #0000001f;
+ display: none;
+ left: 0;
+ margin-top: 40px;
+ position: absolute;
+ top: 0;
+ z-index: 1;
+}
+.w-e-bar-item-group:hover .w-e-bar-item-menus-container {
+ display: block;
+}
+.w-e-select-list {
+ background-color: var(--w-e-toolbar-bg-color);
+ border: 1px solid var(--w-e-toolbar-border-color);
+ border-radius: 3px;
+ box-shadow: 0 2px 10px #0000001f;
+ left: 0;
+ margin-top: 40px;
+ max-height: 350px;
+ min-width: 100px;
+ overflow-y: auto;
+ position: absolute;
+ top: 0;
+ z-index: 1;
+}
+.w-e-select-list ul {
+ line-height: 1;
+ list-style: none;
+}
+.w-e-select-list ul .selected {
+ background-color: var(--w-e-toolbar-active-bg-color);
+}
+.w-e-select-list ul li {
+ cursor: pointer;
+ padding: 7px 0 7px 25px;
+ position: relative;
+ text-align: left;
+ white-space: nowrap;
+}
+.w-e-select-list ul li:hover {
+ background-color: var(--w-e-toolbar-active-bg-color);
+}
+.w-e-select-list ul li svg {
+ left: 0;
+ margin-left: 5px;
+ margin-top: -7px;
+ position: absolute;
+ top: 50%;
+}
+.w-e-bar-bottom .w-e-select-list {
+ bottom: 0;
+ margin-bottom: 40px;
+ margin-top: 0;
+ top: inherit;
+}
+.w-e-drop-panel {
+ background-color: var(--w-e-toolbar-bg-color);
+ border: 1px solid var(--w-e-toolbar-border-color);
+ border-radius: 3px;
+ box-shadow: 0 2px 10px #0000001f;
+ margin-top: 40px;
+ min-width: 200px;
+ padding: 10px;
+ position: absolute;
+ top: 0;
+ z-index: 1;
+}
+.w-e-bar-bottom .w-e-drop-panel {
+ bottom: 0;
+ margin-bottom: 40px;
+ margin-top: 0;
+ top: inherit;
+}
+.w-e-modal {
+ background-color: var(--w-e-toolbar-bg-color);
+ border: 1px solid var(--w-e-toolbar-border-color);
+ border-radius: 3px;
+ box-shadow: 0 2px 10px #0000001f;
+ color: var(--w-e-toolbar-color);
+ font-size: 14px;
+ min-height: 40px;
+ min-width: 100px;
+ padding: 20px 15px 0;
+ position: absolute;
+ text-align: left;
+ z-index: 1;
+}
+.w-e-modal .btn-close {
+ cursor: pointer;
+ line-height: 1;
+ padding: 5px;
+ position: absolute;
+ right: 8px;
+ top: 7px;
+}
+.w-e-modal .btn-close svg {
+ fill: var(--w-e-toolbar-color);
+ height: 10px;
+ width: 10px;
+}
+.w-e-modal .babel-container {
+ display: block;
+ margin-bottom: 15px;
+}
+.w-e-modal .babel-container span {
+ display: block;
+ margin-bottom: 10px;
+}
+.w-e-modal .button-container {
+ margin-bottom: 15px;
+}
+.w-e-modal button {
+ background-color: var(--w-e-modal-button-bg-color);
+ cursor: pointer;
+ font-weight: 400;
+ height: 32px;
+ padding: 4.5px 15px;
+ text-align: center;
+ touch-action: manipulation;
+ transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ white-space: nowrap;
+}
+.w-e-modal button,
+.w-e-modal input[type='number'],
+.w-e-modal input[type='text'],
+.w-e-modal textarea {
+ border: 1px solid var(--w-e-modal-button-border-color);
+ border-radius: 4px;
+ color: var(--w-e-toolbar-color);
+}
+.w-e-modal input[type='number'],
+.w-e-modal input[type='text'],
+.w-e-modal textarea {
+ font-feature-settings: 'tnum';
+ background-color: var(--w-e-toolbar-bg-color);
+ font-variant: tabular-nums;
+ padding: 4.5px 11px;
+ transition: all 0.3s;
+ width: 100%;
+}
+.w-e-modal textarea {
+ min-height: 60px;
+}
+body .w-e-modal,
+body .w-e-modal * {
+ box-sizing: border-box;
+}
+.w-e-progress-bar {
+ background-color: var(--w-e-textarea-handler-bg-color);
+ height: 1px;
+ position: absolute;
+ transition: width 0.3s;
+ width: 0;
+}
+.w-e-full-screen-container {
+ bottom: 0 !important;
+ display: flex !important;
+ flex-direction: column !important;
+ height: 100% !important;
+ left: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ position: fixed;
+ right: 0 !important;
+ top: 0 !important;
+ width: 100% !important;
+}
+.w-e-full-screen-container [data-w-e-textarea='true'] {
+ flex: 1 !important;
+}
+.w-e-text-container [data-slate-editor] code {
+ background-color: var(--w-e-textarea-slight-bg-color);
+ border-radius: 3px;
+ font-family: monospace;
+ padding: 3px;
+}
+.w-e-panel-content-color {
+ list-style: none;
+ text-align: left;
+ width: 230px;
+}
+.w-e-panel-content-color li {
+ border: 1px solid var(--w-e-toolbar-bg-color);
+ border-radius: 3px 3px;
+ cursor: pointer;
+ display: inline-block;
+ padding: 2px;
+}
+.w-e-panel-content-color li:hover {
+ border-color: var(--w-e-toolbar-color);
+}
+.w-e-panel-content-color li .color-block {
+ border: 1px solid var(--w-e-toolbar-border-color);
+ border-radius: 3px 3px;
+ height: 17px;
+ width: 17px;
+}
+.w-e-panel-content-color .active {
+ border-color: var(--w-e-toolbar-color);
+}
+.w-e-panel-content-color .clear {
+ line-height: 1.5;
+ margin-bottom: 5px;
+ width: 100%;
+}
+.w-e-panel-content-color .clear svg {
+ height: 16px;
+ margin-bottom: -4px;
+ width: 16px;
+}
+.w-e-text-container [data-slate-editor] blockquote {
+ background-color: var(--w-e-textarea-slight-bg-color);
+ border-left: 8px solid var(--w-e-textarea-selected-border-color);
+ display: block;
+ font-size: 100%;
+ line-height: 1.5;
+ margin: 10px 0;
+ padding: 10px;
+}
+.w-e-panel-content-emotion {
+ font-size: 20px;
+ list-style: none;
+ text-align: left;
+ width: 300px;
+}
+.w-e-panel-content-emotion li {
+ border-radius: 3px 3px;
+ cursor: pointer;
+ display: inline-block;
+ padding: 0 5px;
+}
+.w-e-panel-content-emotion li:hover {
+ background-color: var(--w-e-textarea-slight-bg-color);
+}
+.w-e-textarea-divider {
+ border-radius: 3px;
+ margin: 20px auto;
+ padding: 20px;
+}
+.w-e-textarea-divider hr {
+ background-color: var(--w-e-textarea-border-color);
+ border: 0;
+ display: block;
+ height: 1px;
+}
+.w-e-text-container [data-slate-editor] pre > code {
+ background-color: var(--w-e-textarea-slight-bg-color);
+ border: 1px solid var(--w-e-textarea-slight-border-color);
+ border-radius: 4px 4px;
+ display: block;
+ font-size: 14px;
+ padding: 10px;
+ text-indent: 0;
+}
+.w-e-text-container [data-slate-editor] .w-e-image-container {
+ display: inline-block;
+ margin: 0 3px;
+}
+.w-e-text-container [data-slate-editor] .w-e-image-container:hover {
+ box-shadow: 0 0 0 2px var(--w-e-textarea-selected-border-color);
+}
+.w-e-text-container [data-slate-editor] .w-e-selected-image-container {
+ overflow: hidden;
+ position: relative;
+}
+.w-e-text-container [data-slate-editor] .w-e-selected-image-container .w-e-image-dragger {
+ background-color: var(--w-e-textarea-handler-bg-color);
+ height: 7px;
+ position: absolute;
+ width: 7px;
+}
+.w-e-text-container [data-slate-editor] .w-e-selected-image-container .left-top {
+ cursor: nwse-resize;
+ left: 0;
+ top: 0;
+}
+.w-e-text-container [data-slate-editor] .w-e-selected-image-container .right-top {
+ cursor: nesw-resize;
+ right: 0;
+ top: 0;
+}
+.w-e-text-container [data-slate-editor] .w-e-selected-image-container .left-bottom {
+ bottom: 0;
+ cursor: nesw-resize;
+ left: 0;
+}
+.w-e-text-container [data-slate-editor] .w-e-selected-image-container .right-bottom {
+ bottom: 0;
+ cursor: nwse-resize;
+ right: 0;
+}
+.w-e-text-container [contenteditable='false'] .w-e-image-container:hover,
+.w-e-text-container [data-slate-editor] .w-e-selected-image-container:hover {
+ box-shadow: none;
+}
+
+.w-e-text-container [data-slate-editor] .table-container {
+ border: 1px dashed var(--w-e-textarea-border-color);
+ border-radius: 5px;
+ margin-top: 10px;
+ overflow-x: auto;
+ padding: 10px;
+ position: relative;
+ width: 100%;
+}
+.w-e-text-container [data-slate-editor] table {
+ border-collapse: collapse;
+ table-layout: fixed;
+}
+.w-e-text-container [data-slate-editor] table td,
+.w-e-text-container [data-slate-editor] table th {
+ border: 1px solid var(--w-e-textarea-border-color);
+ line-height: 1.5;
+ min-width: 30px;
+ overflow: hidden;
+ overflow-wrap: break-word;
+ padding: 3px 5px;
+ text-align: left;
+ white-space: pre-wrap;
+ word-break: break-all;
+}
+.w-e-text-container [data-slate-editor] table th {
+ background-color: var(--w-e-textarea-slight-bg-color);
+ font-weight: 700;
+ text-align: center;
+}
+.w-e-text-container [data-slate-editor] table td.w-e-selected,
+.w-e-text-container [data-slate-editor] table th.w-e-selected {
+ background-color: rgba(20, 86, 240, 0.18);
+}
+.w-e-text-container [data-slate-editor] table.table-selection-none ::-moz-selection {
+ background: none;
+}
+.w-e-text-container [data-slate-editor] table.table-selection-none ::selection {
+ background: none;
+}
+.w-e-text-container [data-slate-editor] .column-resizer {
+ display: flex;
+ height: 0;
+ left: 11px;
+ position: absolute;
+ top: 10px;
+ width: 0;
+ z-index: 1;
+}
+.w-e-text-container [data-slate-editor] .column-resizer .column-resizer-item {
+ position: relative;
+}
+.w-e-text-container [data-slate-editor] .resizer-line-hotzone {
+ cursor: col-resize;
+ opacity: 0;
+ position: absolute;
+ right: -3px;
+ transition: opacity 0.2s ease, visibility 0.2s ease;
+ visibility: hidden;
+ width: 10px;
+}
+.w-e-text-container [data-slate-editor] .resizer-line-hotzone .resizer-line {
+ background: rgba(20, 86, 240, 0.8);
+ height: 100%;
+ margin-left: 5px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ width: 2px;
+}
+.w-e-text-container [data-slate-editor] .resizer-line-hotzone.visible {
+ visibility: visible;
+}
+.w-e-text-container [data-slate-editor] .resizer-line-hotzone.highlight {
+ opacity: 1;
+}
+.w-e-panel-content-table {
+ background-color: var(--w-e-toolbar-bg-color);
+}
+.w-e-panel-content-table table {
+ border-collapse: collapse;
+ table-layout: fixed;
+}
+.w-e-panel-content-table td,
+.w-e-panel-content-table th {
+ overflow: hidden;
+ overflow-wrap: break-word;
+ white-space: pre-wrap;
+ word-break: break-all;
+}
+.w-e-panel-content-table td {
+ border: 1px solid var(--w-e-toolbar-border-color);
+ cursor: pointer;
+ height: 15px;
+ padding: 3px 5px;
+ width: 20px;
+}
+.w-e-panel-content-table td.active {
+ background-color: var(--w-e-toolbar-active-bg-color);
+}
+.w-e-textarea-video-container {
+ background-image: linear-gradient(45deg, #eee 25%, transparent 0, transparent 75%, #eee 0, #eee),
+ linear-gradient(45deg, #eee 25%, #fff 0, #fff 75%, #eee 0, #eee);
+ background-position: 0 0, 10px 10px;
+ background-size: 20px 20px;
+ border: 1px dashed var(--w-e-textarea-border-color);
+ border-radius: 5px;
+ margin: 10px auto 0;
+ padding: 10px 0;
+ text-align: center;
+}
+
+.w-e-text-container [data-slate-editor] pre > code {
+ word-wrap: normal;
+ font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
+ -webkit-hyphens: none;
+ hyphens: none;
+ line-height: 1.5;
+ margin: 0.5em 0;
+ overflow: auto;
+ padding: 1em;
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+ text-align: left;
+ text-shadow: 0 1px #fff;
+ white-space: pre;
+ word-break: normal;
+ word-spacing: normal;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.cdata,
+.w-e-text-container [data-slate-editor] pre > code .token.comment,
+.w-e-text-container [data-slate-editor] pre > code .token.doctype,
+.w-e-text-container [data-slate-editor] pre > code .token.prolog {
+ color: #708090;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.punctuation {
+ color: #999;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.namespace {
+ opacity: 0.7;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.boolean,
+.w-e-text-container [data-slate-editor] pre > code .token.constant,
+.w-e-text-container [data-slate-editor] pre > code .token.deleted,
+.w-e-text-container [data-slate-editor] pre > code .token.number,
+.w-e-text-container [data-slate-editor] pre > code .token.property,
+.w-e-text-container [data-slate-editor] pre > code .token.symbol,
+.w-e-text-container [data-slate-editor] pre > code .token.tag {
+ color: #905;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.attr-name,
+.w-e-text-container [data-slate-editor] pre > code .token.builtin,
+.w-e-text-container [data-slate-editor] pre > code .token.char,
+.w-e-text-container [data-slate-editor] pre > code .token.inserted,
+.w-e-text-container [data-slate-editor] pre > code .token.selector,
+.w-e-text-container [data-slate-editor] pre > code .token.string {
+ color: #690;
+}
+.w-e-text-container [data-slate-editor] pre > code .language-css .token.string,
+.w-e-text-container [data-slate-editor] pre > code .style .token.string,
+.w-e-text-container [data-slate-editor] pre > code .token.entity,
+.w-e-text-container [data-slate-editor] pre > code .token.operator,
+.w-e-text-container [data-slate-editor] pre > code .token.url {
+ color: #9a6e3a;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.atrule,
+.w-e-text-container [data-slate-editor] pre > code .token.attr-value,
+.w-e-text-container [data-slate-editor] pre > code .token.keyword {
+ color: #07a;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.class-name,
+.w-e-text-container [data-slate-editor] pre > code .token.function {
+ color: #dd4a68;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.important,
+.w-e-text-container [data-slate-editor] pre > code .token.regex,
+.w-e-text-container [data-slate-editor] pre > code .token.variable {
+ color: #e90;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.bold,
+.w-e-text-container [data-slate-editor] pre > code .token.important {
+ font-weight: 700;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.italic {
+ font-style: italic;
+}
+.w-e-text-container [data-slate-editor] pre > code .token.entity {
+ cursor: help;
+}
diff --git a/apps/housekeepingMiniApp/src/components/Searchbar/BlSearchbar.vue b/apps/housekeepingMiniApp/src/components/Searchbar/BlSearchbar.vue
new file mode 100644
index 0000000..3e7ee41
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Searchbar/BlSearchbar.vue
@@ -0,0 +1,34 @@
+<template>
+ <nut-searchbar shape="round" class="bole-search-bar" v-model.trim="model" v-bind="$attrs">
+ <template #leftin>
+ <Search2 />
+ </template>
+ </nut-searchbar>
+</template>
+
+<script setup lang="ts">
+import { Search2 } from '@nutui/icons-vue-taro';
+
+defineOptions({
+ name: 'BlSearchbar',
+});
+
+// type Props = {};
+
+// const props = withDefaults(defineProps<Props>(), {});
+const model = defineModel<string>();
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.bole-search-bar {
+ padding: 0;
+ background-color: transparent;
+
+ .nut-searchbar__search-input {
+ box-shadow: none;
+ border: 1px solid boleGetCssVar('color', 'primary');
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Uploader/CoverUploader.vue b/apps/housekeepingMiniApp/src/components/Uploader/CoverUploader.vue
new file mode 100644
index 0000000..d94f567
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Uploader/CoverUploader.vue
@@ -0,0 +1,139 @@
+<template>
+ <div class="cover-uploader-wrapper">
+ <Uploader v-model:file-list="innerFileList">
+ <template #extra-img="{ item }">
+ <div class="set-cover-btn" @click="handleSetCover(item)">
+ {{ item.isMain ? '鍙栨秷灏侀潰' : '璁句负灏侀潰' }}
+ </div>
+ </template>
+ </Uploader>
+ <div class="system-cover-uploader-wrapper" v-if="demoCoverList.length > 0">
+ <div class="system-cover-uploader-title">鎮ㄨ繕鍙互浠庣郴缁熶腑閫夋嫨鍥剧墖</div>
+ <div class="system-cover-uploader-list">
+ <div
+ v-for="cover in demoCoverList"
+ :key="cover.url"
+ class="system-cover-uploader-list-item"
+ @click="handleUploadSystemCover(cover.url)"
+ >
+ <img class="system-cover-uploader-list-img" :src="cover.url" />
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import Uploader from './Uploader.vue';
+import { CoverItem } from './uploader';
+import { convertApiPath2Url } from '@12333/utils';
+
+defineOptions({
+ name: 'CoverUploader',
+});
+
+type Props = {
+ fileList: CoverItem[];
+ demoCoverList?: API.CoverMsg[];
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ demoCoverList: () => [] as API.CoverMsg[],
+});
+
+const emit = defineEmits<{
+ (e: 'update:fileList', list: CoverItem[]): void;
+}>();
+
+const innerFileList = computed({
+ get() {
+ return props.fileList;
+ },
+ set(val) {
+ emit('update:fileList', val);
+ },
+});
+
+function handleUploadSystemCover(url: string) {
+ emit('update:fileList', [
+ ...props.fileList,
+ {
+ ...(convertApiPath2Url(url) as any),
+ },
+ ]);
+}
+
+function handleSetCover(item: CoverItem) {
+ emit(
+ 'update:fileList',
+ props.fileList.map((x) => {
+ return {
+ ...x,
+ isMain: x.uid === item.uid,
+ };
+ })
+ );
+}
+
+watch(
+ () => props.fileList.length,
+ (newValue, oldValue) => {
+ if (newValue !== oldValue) {
+ const index = props.fileList.findIndex((x) => x.isMain);
+ if (index < 0) {
+ handleSetCover(props.fileList[0]);
+ }
+ }
+ }
+);
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.cover-uploader-wrapper {
+ padding-top: 16px;
+
+ .nut-uploader__preview.picture {
+ .set-cover-btn {
+ width: 100%;
+ position: absolute;
+ height: 30px;
+ line-height: 30px;
+ text-align: center;
+ bottom: 0;
+ left: 0;
+ font-size: 16px;
+ background-color: rgba(#000, 0.3);
+ color: #fff;
+ }
+ }
+
+ .system-cover-uploader-wrapper {
+ margin-top: 16px;
+
+ .system-cover-uploader-title {
+ font-size: 24px;
+ color: boleGetCssVar('text-color', 'regular');
+ margin-bottom: 10px;
+ }
+
+ .system-cover-uploader-list {
+ display: flex;
+ flex-wrap: wrap;
+ margin: -10px;
+
+ .system-cover-uploader-list-item {
+ padding: 10px;
+
+ .system-cover-uploader-list-img {
+ width: 100px;
+ height: 100px;
+ border: 1px solid #dadada;
+ border-radius: 4px;
+ }
+ }
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/Uploader/Uploader.vue b/apps/housekeepingMiniApp/src/components/Uploader/Uploader.vue
new file mode 100644
index 0000000..851aee1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Uploader/Uploader.vue
@@ -0,0 +1,137 @@
+<template>
+ <nut-uploader
+ v-if="$slots.default"
+ v-model:file-list="innerFileList"
+ multiple
+ :media-type="['image']"
+ :sourceType="sourceType"
+ :before-xhr-upload="beforeXhrUpload"
+ @failure="handleFailure"
+ :maximize="maximize"
+ >
+ <template #upload-icon>
+ <slot name="upload-icon"></slot>
+ </template>
+ <template #default>
+ <slot></slot>
+ </template>
+ <template #extra-img>
+ <slot name="extra-img"></slot>
+ </template>
+ <template #item="{ item }">
+ <slot name="item" :item="item"></slot>
+ </template>
+ </nut-uploader>
+ <nut-uploader
+ v-else
+ v-model:file-list="innerFileList"
+ multiple
+ :media-type="['image']"
+ :sourceType="sourceType"
+ :before-xhr-upload="beforeXhrUpload"
+ @failure="handleFailure"
+ :maximize="maximize"
+ >
+ <template #upload-icon>
+ <slot name="upload-icon"></slot>
+ </template>
+ <template #extra-img="extraImgProps">
+ <slot name="extra-img" v-bind="extraImgProps"></slot>
+ </template>
+ <template #item="{ item }">
+ <slot name="item" :item="item"></slot>
+ </template>
+ </nut-uploader>
+</template>
+
+<script setup lang="ts">
+import { ossUpload } from '@12333/utils/oss';
+import { guid } from '@12333/utils';
+import { FileItem } from '@nutui/nutui-taro/dist/types/__VUE/uploader/type';
+import { UploadOptions } from '@nutui/nutui-taro/dist/types/__VUE/uploader/uploader';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'Uploader',
+});
+
+type SourceType = 'album' | 'camera';
+
+type Props = {
+ fileList: FileItem[];
+ onMySuccess?: (file: FileItem) => any;
+ limitFileSize?: number;
+ sourceType?: SourceType[];
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ limitFileSize: 2,
+ sourceType: () => ['album', 'camera'],
+});
+
+const emit = defineEmits<{
+ (e: 'update:fileList', list: FileItem[]): void;
+}>();
+
+const innerFileList = computed({
+ get() {
+ return props.fileList;
+ },
+ set(val) {
+ emit('update:fileList', val);
+ },
+});
+
+const maximize = computed(() => props.limitFileSize * 1024 * 1024);
+
+const beforeXhrUpload = (taroUploadFile: any, options: UploadOptions) => {
+ const current = innerFileList.value.find((x) => x.path === options.taroFilePath);
+ const uploadTask = ossUpload({
+ filePath: options.taroFilePath,
+ fileType: options.fileType,
+ name: options.name || 'file',
+ customFileName: () => guid(),
+ showLoading: false,
+ success(response: { errMsg: any; statusCode: number; data: string }, ossRes) {
+ options.onSuccess?.(response, options);
+ current.name = ossRes.name;
+ current.path = ossRes.path;
+ current.url = ossRes.url;
+ // innerFileList.value.map((x) => {
+ // if (x.uid === current.uid) {
+ // return {
+ // ...x,
+ // name: ossRes.name,
+ // path: ossRes.path,
+ // url: ossRes.url,
+ // };
+ // }
+ // return { ...x };
+ // })
+ // emit('update:fileList', innerFileList.value);
+ nextTick(() => {
+ props.onMySuccess?.(innerFileList.value.find((x) => x.path === ossRes.path));
+ });
+ },
+ fail(e: any) {
+ console.log('e: ', e);
+ options.onFailure?.(e, options);
+ },
+ });
+
+ options.onStart?.(options);
+ // uploadTask?.progress(
+ // (res: { progress: any; totalBytesSent: any; totalBytesExpectedToSend: any }) => {
+ // options.onProgress?.(res, options);
+ // // console.log('涓婁紶杩涘害', res.progress);
+ // // console.log('宸茬粡涓婁紶鐨勬暟鎹暱搴�', res.totalBytesSent);
+ // // console.log('棰勬湡闇�瑕佷笂浼犵殑鏁版嵁鎬婚暱搴�', res.totalBytesExpectedToSend);
+ // }
+ // );
+ // uploadTask.abort(); // 鍙栨秷涓婁紶浠诲姟
+};
+
+function handleFailure(ev) {
+ console.log('Failure ev: ', ev);
+}
+</script>
diff --git a/apps/housekeepingMiniApp/src/components/Uploader/uploader.ts b/apps/housekeepingMiniApp/src/components/Uploader/uploader.ts
new file mode 100644
index 0000000..36dc6c3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/Uploader/uploader.ts
@@ -0,0 +1,5 @@
+import { FileItem } from '@nutui/nutui-taro/dist/types/__VUE/uploader/type';
+
+export type CoverItem = Partial<FileItem> & {
+ isMain?: boolean;
+};
diff --git a/apps/housekeepingMiniApp/src/components/UserHome/UserHomeTopView.vue b/apps/housekeepingMiniApp/src/components/UserHome/UserHomeTopView.vue
new file mode 100644
index 0000000..ad26953
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/UserHome/UserHomeTopView.vue
@@ -0,0 +1,121 @@
+<template>
+ <div class="mine-page-top-view">
+ <slot name="avatar"></slot>
+ <div class="setting-wrapper" v-if="showUserHomePageBtn" @click="goMineCurriculumVitae">
+ <div class="setting-text">
+ 鎴戠殑绠�鍘�<IconFont name="rect-right" size="16" color="#6D6E6E"></IconFont>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { useUser } from '@/hooks';
+import Taro from '@tarojs/taro';
+import { RouterPath } from '@/constants';
+
+defineOptions({
+ name: 'UserHomeTopView',
+});
+
+type Props = {
+ showUserHomePageBtn?: boolean;
+ showOperation?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ showUserHomePageBtn: false,
+ showOperation: false,
+});
+
+const { userDetail } = useUser();
+
+function goMineCurriculumVitae() {
+ Taro.navigateTo({
+ url: RouterPath.mineCurriculumVitae,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mine-page-top-view {
+ padding-top: 34px;
+ display: flex;
+ margin-bottom: 20px;
+
+ .setting-wrapper {
+ align-self: flex-start;
+ display: flex;
+ align-items: center;
+ margin-top: 8px;
+ margin-right: calc(boleGetCssVar('size', 'body-padding-h') * -1);
+
+ .setting-text {
+ font-weight: 400;
+ font-size: 28px;
+ line-height: 40px;
+ display: flex;
+ align-items: center;
+ color: boleGetCssVar('text-color', 'primary');
+ padding-right: 20px;
+ }
+ }
+}
+
+.mine-page-operation-wrapper {
+ display: flex;
+ padding-top: 22px;
+ margin-bottom: 36px;
+
+ .mine-page-operation-item {
+ flex: 1;
+ min-width: 0;
+ align-items: center;
+ display: flex;
+ padding-left: 28px;
+ border-right: 1px solid #efefef;
+
+ &:last-child {
+ border-right: none;
+ }
+
+ &.share {
+ background-color: transparent;
+ padding-right: 0;
+ appearance: none;
+ text-align: left;
+
+ &::after {
+ border: none;
+ }
+ /* .mine-page-operation-item-inner {
+ display: flex;
+ align-items: center;
+ } */
+ }
+
+ .mine-page-operation-item-icon {
+ width: 32px;
+ height: 32px;
+ margin-right: 8px;
+ }
+
+ .mine-page-operation-item-text {
+ flex: 1;
+ min-width: 0;
+ font-weight: bold;
+ font-size: 24px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 34px;
+ }
+
+ .mine-page-operation-item-arrow {
+ width: 28px;
+ height: 28px;
+ margin-right: 28px;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/components/index.ts b/apps/housekeepingMiniApp/src/components/index.ts
new file mode 100644
index 0000000..b185311
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/components/index.ts
@@ -0,0 +1,25 @@
+export { default as CommonNavigationBar } from './NavigationBar/CommonNavigationBar.vue';
+export { default as TransparentNavigationBar } from './NavigationBar/TransparentNavigationBar.vue';
+export { default as LargeTitleNavigationBar } from './NavigationBar/LargeTitleNavigationBar.vue';
+export { default as PageLayout } from './Layout/PageLayout.vue';
+export { default as PageLayoutWithBg } from './Layout/PageLayoutWithBg.vue';
+export { default as LoadingLayout } from './Layout/LoadingLayout.vue';
+export { default as Policy } from './Policy/Policy.vue';
+export { default as Menu } from './Menu/Menu.vue';
+export { default as MenuItem } from './Menu/MenuItem.vue';
+export { default as InfiniteLoading } from './InfiniteLoading/InfiniteLoading.vue';
+export { default as PageFooter } from './PageFooter/PageFooter.vue';
+export { default as Uploader } from './Uploader/Uploader.vue';
+export { default as CoverUploader } from './Uploader/CoverUploader.vue';
+export * from './Uploader/uploader';
+export { default as LargeButton } from './Button/LargeButton.vue';
+export { default as RichEditCard } from './RichEditCard/RichEditCard.vue';
+export { default as RichContent } from './RichEditCard/RichContent.vue';
+export { default as NoData } from './NoData/NoData.vue';
+export { default as UserAvatar } from './Avatar/UserAvatar.vue';
+export { default as ContentScrollView } from './Layout/ContentScrollView.vue';
+export { default as ContentView } from './Layout/ContentView.vue';
+export { default as PageFooterAction } from './PageFooter/PageFooterAction.vue';
+export { default as PageFooterBtn } from './PageFooter/PageFooterBtn.vue';
+export { default as ChunkTitle } from './Chunk/ChunkTitle.vue';
+export { default as UserHomeTopView } from './UserHome/UserHomeTopView.vue';
diff --git a/apps/housekeepingMiniApp/src/constants/app.ts b/apps/housekeepingMiniApp/src/constants/app.ts
new file mode 100644
index 0000000..6e317b5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/app.ts
@@ -0,0 +1,9 @@
+import { EnumUserType, EnumClientType } from '@12333/constants';
+
+export const AppLocalConfig = {
+ userType: EnumUserType.Personal,
+ clientType: EnumClientType.Wxmp,
+};
+
+export const APP_ENV = process.env.APP_ENV;
+export const NODE_ENV = process.env.NODE_ENV;
diff --git a/apps/housekeepingMiniApp/src/constants/enum.ts b/apps/housekeepingMiniApp/src/constants/enum.ts
new file mode 100644
index 0000000..6d77347
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/enum.ts
@@ -0,0 +1,4 @@
+export enum BackType {
+ toDetail = 'toDetail',
+ back = 'back',
+}
diff --git a/apps/housekeepingMiniApp/src/constants/img.ts b/apps/housekeepingMiniApp/src/constants/img.ts
new file mode 100644
index 0000000..68af272
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/img.ts
@@ -0,0 +1,18 @@
+const OssBasePath = 'https://renliyuan.oss-cn-hangzhou.aliyuncs.com/12333';
+
+export const OssAssets = {
+ common: {
+ CommonPageBg: `${OssBasePath}/flexJobMini/assets/common/icon-common-page-bg.png`,
+ },
+ mine: {
+ Bg: `${OssBasePath}/matchMakingMini/assets/mine/icon-bg.png`,
+ IdBg: `${OssBasePath}/matchMakingMini/assets/mine/icon-id-bg.png`,
+ UseResumeVideo: `${OssBasePath}/flexJobMini/temp/%E7%AE%80%E5%8E%86%E4%B8%AA%E4%BA%BA%E8%A7%86%E9%A2%91%E6%A8%A1%E6%9D%BF-v2.mp4`,
+ },
+ setting: {
+ ToggleBg: `${OssBasePath}/matchMakingMini/assets/setting/icon-toggle-bg.png`,
+ },
+ user: {
+ Bg: `${OssBasePath}/matchMakingMini/assets/user/icon-bg.png`,
+ },
+};
diff --git a/apps/housekeepingMiniApp/src/constants/index.ts b/apps/housekeepingMiniApp/src/constants/index.ts
new file mode 100644
index 0000000..935d9cf
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/index.ts
@@ -0,0 +1,6 @@
+export * from './enum';
+export * from './tabBar';
+export * from './router';
+export * from './img';
+export * from './task';
+export * from './app';
diff --git a/apps/housekeepingMiniApp/src/constants/query.ts b/apps/housekeepingMiniApp/src/constants/query.ts
new file mode 100644
index 0000000..338dd9b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/query.ts
@@ -0,0 +1,10 @@
+import { QueryClient } from '@tanstack/vue-query';
+
+export const myClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false,
+ retry: false,
+ },
+ },
+});
diff --git a/apps/housekeepingMiniApp/src/constants/router.ts b/apps/housekeepingMiniApp/src/constants/router.ts
new file mode 100644
index 0000000..2f62a74
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/router.ts
@@ -0,0 +1,44 @@
+export enum RouterPath {
+ authorization = '/subpackages/login/authorization/authorization',
+ userPolicy = '/subpackages/login/userPolicy/userPolicy',
+ mineUserPolicy = '/subpackages/login/mineUserPolicy/mineUserPolicy',
+ privacyPolicy = '/subpackages/login/privacyPolicy/privacyPolicy',
+ loginByForm = '/subpackages/login/loginByForm/loginByForm',
+ registerForm = '/subpackages/login/registerForm/registerForm',
+ home = '/pages/home/index',
+ task = '/pages/task/task',
+ mine = '/pages/mine/index',
+ editRichContent = '/subpackages/editRichContent/editRichContent',
+
+ complaint = '/subpackages/user/complaint/complaint',
+
+ authenticationHome = '/subpackages/authentication/authenticationHome/authenticationHome',
+ authenticationResult = '/subpackages/authentication/authenticationResult/authenticationResult',
+ authenticationFaRen = '/subpackages/authentication/authenticationFaRen/authenticationFaRen',
+ authenticationJBR = '/subpackages/authentication/authenticationJBR/authenticationJBR',
+ authenticationRealName = '/subpackages/authentication/authenticationRealName/authenticationRealName',
+ authenticationFace = '/subpackages/authentication/authenticationFace/authenticationFace',
+ citySelect = '/subpackages/city/citySelect/citySelect',
+
+ mineSign = '/subpackages/mine/mineSign/mineSign',
+ mineHire = '/subpackages/mine/mineHire/mineHire',
+ mineHired = '/subpackages/mine/mineHired/mineHired',
+ mineCancel = '/subpackages/mine/mineCancel/mineCancel',
+ mineCollectTask = '/subpackages/mine/mineCollectTask/mineCollectTask',
+ mineAgreementSign = '/subpackages/mine/mineAgreementSign/mineAgreementSign',
+ mineAgreementSignDetail = '/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail',
+ setting = '/subpackages/mine/setting/setting',
+
+ mineWallet = '/subpackages/wallet/mineWallet/mineWallet',
+ unboundBankCard = '/subpackages/wallet/unboundBankCard/unboundBankCard',
+ bindBankCard = '/subpackages/wallet/bindBankCard/bindBankCard',
+ unboundAlipay = '/subpackages/wallet/unboundAlipay/unboundAlipay',
+ bindAlipay = '/subpackages/wallet/bindAlipay/bindAlipay',
+ incomeDetail = '/subpackages/wallet/incomeDetail/incomeDetail',
+ incomeDetailInfo = '/subpackages/wallet/incomeDetailInfo/incomeDetailInfo',
+ withdraw = '/subpackages/wallet/withdraw/withdraw',
+ withdrawResult = '/subpackages/wallet/withdrawResult/withdrawResult',
+ withdrawDetailInfo = '/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo',
+
+ extraPage = '/subpackages/extraPage/extraPage/extraPage',
+}
diff --git a/apps/housekeepingMiniApp/src/constants/tabBar.ts b/apps/housekeepingMiniApp/src/constants/tabBar.ts
new file mode 100644
index 0000000..aec3007
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/tabBar.ts
@@ -0,0 +1,11 @@
+export const TabBarPageRouter = {
+ Home: '/pages/home/index',
+ Task: '/pages/task/task',
+ Mine: '/pages/mine/index',
+};
+
+export const TabBarPageRouterList = [
+ TabBarPageRouter.Home,
+ TabBarPageRouter.Task,
+ TabBarPageRouter.Mine,
+];
diff --git a/apps/housekeepingMiniApp/src/constants/task.ts b/apps/housekeepingMiniApp/src/constants/task.ts
new file mode 100644
index 0000000..98af4e3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/constants/task.ts
@@ -0,0 +1,19 @@
+export enum TaskStatus {
+ All = 0,
+ WaitSign = 10,
+ Effect = 20,
+ Terminated = 30,
+}
+
+export const TaskStatusText = {
+ [TaskStatus.All]: '鍏ㄩ儴',
+ [TaskStatus.WaitSign]: '寰呯绾�',
+ [TaskStatus.Effect]: '鐢熸晥涓�',
+ [TaskStatus.Terminated]: '宸茬粓姝�',
+};
+
+export const TaskStatusColor = {
+ [TaskStatus.WaitSign]: '#FF7D00',
+ [TaskStatus.Effect]: '#3A71FF',
+ [TaskStatus.Terminated]: '#9FA4AC',
+};
diff --git a/apps/housekeepingMiniApp/src/custom-tab-bar/index.scss b/apps/housekeepingMiniApp/src/custom-tab-bar/index.scss
new file mode 100644
index 0000000..d084602
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/custom-tab-bar/index.scss
@@ -0,0 +1,119 @@
+@import '@/styles/common.scss';
+
+.bottom-tab {
+ position: fixed;
+ display: flex;
+ width: 100%;
+ height: 118px;
+ // height: 100px;
+ background: white;
+ box-shadow: 0px -5px 6px 1px rgba(0, 0, 0, 0.04);
+ bottom: 0;
+
+ .bottom-tab-left,
+ .bottom-tab-right {
+ height: 100%;
+ display: flex;
+ width: 50%;
+ justify-content: space-around;
+ }
+
+ .bottom-tab-left {
+ padding-right: 20px;
+ }
+
+ .bottom-tab-right {
+ padding-left: 20px;
+ }
+
+ &-item {
+ // padding: 36px 20px 32px;
+ // padding-bottom: 16px;
+ padding: 20px 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: flex-start;
+ flex: 1;
+ position: relative;
+
+ .bottom-tab-item-icon-wrapper {
+ margin-bottom: 8px;
+ position: relative;
+ }
+
+ .bottom-tab-item-icon {
+ width: 48px;
+ height: 48px;
+ }
+
+ .bottom-tab-item-text {
+ color: #707070;
+ font-size: 24px;
+ line-height: 28px;
+ }
+
+ .bottom-tab-item-badge {
+ line-height: 28px;
+ padding: 0 8px;
+ background: #ff4d4f;
+ border-radius: 14px;
+ color: #fff;
+ font-size: 22px;
+ position: absolute;
+ top: -6px;
+ right: -10px;
+ }
+
+ &.active {
+ .bottom-tab-item-text {
+ color: #3a71ff;
+ }
+ }
+ }
+
+ .publish-wrapper {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+
+ .bottom-tab-item-text {
+ margin-top: 50px;
+ }
+
+ .bottom-tab-item-img-publish {
+ position: absolute;
+ width: 103px;
+ height: 103px;
+ left: 50%;
+ top: -50px;
+ transform: translateX(-50%);
+ }
+
+ .bottom-tab-float-btn {
+ position: absolute;
+ width: 85px;
+ height: 85px;
+ background: #ffffff;
+ box-shadow: 0px -9px 9px 1px rgba(209, 209, 209, 0.35);
+ border-radius: 50%;
+ left: 50%;
+ top: -30px;
+ transform: translateX(-50%);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ .bottom-tab-float-btn-inner {
+ width: 70px;
+ height: 70px;
+ background: linear-gradient(88deg, #2c7eff, #629dfa);
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ }
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/custom-tab-bar/index.tsx b/apps/housekeepingMiniApp/src/custom-tab-bar/index.tsx
new file mode 100644
index 0000000..44fb564
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/custom-tab-bar/index.tsx
@@ -0,0 +1,169 @@
+import './index.scss';
+
+import { SetupContext } from 'vue';
+import { View, Text, Image } from '@tarojs/components';
+import Taro from '@tarojs/taro';
+import { useSystemStore } from '@/stores/modules/system';
+import { storeToRefs } from 'pinia';
+import { TabBarPageRouter } from '@/constants';
+// import IconPublish from '@/assets/tabbar/icon-publish.png';
+import { useUser, useIsLogin } from '@/hooks';
+import { Message } from '@12333/utils';
+
+type TarBarItemProps = {
+ text: string;
+ icon: string;
+ activeIcon: string;
+ pagePath: string;
+ currentPath: string;
+ active: boolean;
+ className: string;
+ onClick?: (url: string, index: number) => any;
+ index: number;
+ badge?: number;
+};
+
+type TarBarItemEvents = {
+ click: (url: string, index: number) => any;
+};
+
+const TarBarItem = function (props: TarBarItemProps, context: SetupContext<TarBarItemEvents>) {
+ const _badge = props.badge > 99 ? '99+' : props.badge;
+ // const isActive = props.currentPath.toLowerCase().includes(props.pagePath.toLowerCase());
+ const isActive = props.active;
+ return (
+ <div
+ class={['bottom-tab-item', { active: isActive }, props.className]}
+ onClick={() => context.emit('click', props.pagePath, props.index)}
+ >
+ <div class="bottom-tab-item-icon-wrapper">
+ {props.badge > 0 && <div class="bottom-tab-item-badge">{_badge}</div>}
+ <img class="bottom-tab-item-icon" src={isActive ? props.activeIcon : props.icon} />
+ </div>
+ <div class="bottom-tab-item-text">{props.text}</div>
+ </div>
+ );
+};
+
+TarBarItem.emits = {
+ click: (url: string, index: number) => typeof url === 'string',
+};
+
+const whitePageList = [RouterPath.home, RouterPath.mine];
+
+export default {
+ name: 'CustomTabBar',
+ components: {
+ View,
+ Text,
+ Image,
+ TarBarItem,
+ },
+ setup() {
+ const system = useSystemStore();
+ const { IPhoneXPadding } = storeToRefs(system);
+
+ const router = Taro.useRouter();
+
+ const isLogin = useIsLogin();
+
+ const loginTipShowed = ref(false);
+ const isClicking = ref(false);
+
+ const switchTab = (url: string, index: number) => {
+ if (isClicking.value) return;
+ if (!isLogin.value && whitePageList.every((x) => x !== url)) {
+ if (!loginTipShowed.value) {
+ loginTipShowed.value = true;
+ Message.confirm({ message: '璇峰墠寰�鐧诲綍' })
+ .then(() => {
+ Taro.navigateTo({
+ url: `${RouterPath.authorization}?redirect=${url}`,
+ });
+ })
+ .finally(() => {
+ loginTipShowed.value = false;
+ });
+ }
+ return;
+ }
+ isClicking.value = true;
+ Taro.switchTab({ url })
+ .then(() => {
+ system.setTabIndex(index);
+ })
+ .finally(() => {
+ isClicking.value = false;
+ });
+ };
+
+ function goPublish() {
+ if (!isLogin.value) {
+ if (!loginTipShowed.value) {
+ loginTipShowed.value = true;
+ Message.confirm({ message: '璇峰墠寰�鐧诲綍' })
+ .then(() => {
+ Taro.navigateTo({
+ url: `${RouterPath.authorization}?redirect=${RouterPath.home}`,
+ });
+ })
+ .finally(() => {
+ loginTipShowed.value = false;
+ });
+ }
+
+ return;
+ }
+ // Taro.navigateTo({
+ // url: RouterPath.pulishCircleFriend,
+ // });
+ }
+
+ return () => {
+ const _router = Taro.useRouter();
+ return (
+ <View
+ class="bottom-tab"
+ style={{
+ paddingBottom: `${IPhoneXPadding.value}px`,
+ }}
+ >
+ <TarBarItem
+ text={'鎵惧伐浣�'}
+ icon="../assets/tabbar/icon-home.png"
+ activeIcon="../assets/tabbar/icon-home-active.png"
+ pagePath={TabBarPageRouter.Home}
+ currentPath={_router.path}
+ index={0}
+ active={system.activeTab === 0}
+ className="home"
+ onClick={switchTab}
+ ></TarBarItem>
+
+ <TarBarItem
+ text="浠诲姟"
+ icon="../assets/tabbar/icon-task.png"
+ activeIcon="../assets/tabbar/icon-task-active.png"
+ pagePath={TabBarPageRouter.Task}
+ currentPath={_router.path}
+ active={system.activeTab === 1}
+ className="task"
+ onClick={switchTab}
+ index={1}
+ ></TarBarItem>
+ <TarBarItem
+ text="鎴戠殑"
+ icon="../assets/tabbar/icon-mine.png"
+ activeIcon="../assets/tabbar/icon-mine-active.png"
+ pagePath={TabBarPageRouter.Mine}
+ currentPath={_router.path}
+ active={system.activeTab === 2}
+ className="mine"
+ onClick={switchTab}
+ index={2}
+ ></TarBarItem>
+ </View>
+ );
+ };
+ },
+};
diff --git a/apps/housekeepingMiniApp/src/hooks/access.ts b/apps/housekeepingMiniApp/src/hooks/access.ts
new file mode 100644
index 0000000..66a110b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/hooks/access.ts
@@ -0,0 +1,50 @@
+import { useUserStore } from '@/stores/modules/user';
+import Taro from '@tarojs/taro';
+import { Message } from '@12333/utils';
+import { useIsLogin, useUser } from './user';
+
+/**
+ * 闇�瑕佺櫥褰�
+ */
+export function useAccessLogin<T extends (...args: any[]) => any>(fn: T) {
+ const isLogin = useIsLogin();
+ const router = Taro.useRouter();
+
+ const _fn = (...args2) => {
+ if (!isLogin.value) {
+ Message.confirm({ message: '璇峰墠寰�鐧诲綍' }).then(() => {
+ Taro.navigateTo({
+ url: `${RouterPath.authorization}`,
+ });
+ });
+ return;
+ }
+ fn?.(...args2);
+ };
+ return _fn as T;
+}
+
+type UseAccessRealOptions = {
+ message?: string;
+};
+
+export function useAccessReal<T extends (...args: any[]) => any>(
+ fn: T,
+ options: UseAccessRealOptions = { message: '璇峰墠寰�瀹炲悕璁よ瘉' }
+) {
+ const { message } = options;
+ const { isCertified } = useUser();
+
+ const _fn = useAccessLogin((...args2) => {
+ if (!isCertified.value) {
+ Message.confirm({ message: message }).then(() => {
+ Taro.navigateTo({
+ url: `${RouterPath.authenticationHome}`,
+ });
+ });
+ return;
+ }
+ fn?.(...args2);
+ });
+ return _fn as T;
+}
diff --git a/apps/housekeepingMiniApp/src/hooks/app.ts b/apps/housekeepingMiniApp/src/hooks/app.ts
new file mode 100644
index 0000000..dfe8750
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/hooks/app.ts
@@ -0,0 +1,13 @@
+import Taro from '@tarojs/taro';
+import { useUserStoreWithOut } from '@/stores/modules/user';
+
+export function useLaunchOptions() {
+ const options = Taro.getLaunchOptionsSync();
+ const userStore = useUserStoreWithOut();
+ console.log('userStore: ', userStore);
+ if (userStore.firstLaunch) {
+ userStore.setFirstLaunch(false);
+ return options;
+ }
+ return {} as Taro.getLaunchOptionsSync.LaunchOptions;
+}
diff --git a/apps/housekeepingMiniApp/src/hooks/authentication.ts b/apps/housekeepingMiniApp/src/hooks/authentication.ts
new file mode 100644
index 0000000..dfa4a32
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/hooks/authentication.ts
@@ -0,0 +1,51 @@
+import * as electronSignServices from '@12333/services/apiV2/electronSign';
+import { useQuery, useQueryClient } from '@tanstack/vue-query';
+import { getUserCertificationFrontStatusAdapter } from '@12333/utils';
+import { UserCertificationFrontStatus } from '@12333/constants';
+import { useUser } from './user';
+
+type UseMyCertificationAuditInfoOptions = {
+ onSuccess?: (data: API.GetPersonalUserRealResultQueryResult) => void;
+};
+
+export function useMyCertificationAuditInfo(options: UseMyCertificationAuditInfoOptions = {}) {
+ const { onSuccess } = options;
+
+ const { updateUserInfo } = useUser();
+
+ const queryClient = useQueryClient();
+
+ const { data, isLoading } = useQuery({
+ queryKey: ['electronSignServices/getPersonalUserRealResult'],
+ queryFn: async () => {
+ return await electronSignServices.getPersonalUserRealResult({}, { showLoading: false });
+ },
+ placeholderData: () => null as API.GetPersonalUserRealResultQueryResult,
+ select(data) {
+ return data;
+ },
+ onSuccess(data) {
+ onSuccess?.(data);
+ },
+ });
+
+ function invalidateCertificationAuditInfo() {
+ updateUserInfo();
+ return queryClient.invalidateQueries({
+ queryKey: ['electronSignServices/getPersonalUserRealResult'],
+ });
+ }
+
+ function ensureCertificationAuditInfo() {
+ return queryClient.ensureQueryData({
+ queryKey: ['electronSignServices/getPersonalUserRealResult'],
+ });
+ }
+
+ return {
+ myCertificationAuditInfo: data,
+ isLoading,
+ invalidateCertificationAuditInfo,
+ ensureCertificationAuditInfo,
+ };
+}
diff --git a/apps/housekeepingMiniApp/src/hooks/index.ts b/apps/housekeepingMiniApp/src/hooks/index.ts
new file mode 100644
index 0000000..7c11112
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/hooks/index.ts
@@ -0,0 +1,6 @@
+export * from './user';
+export * from './router';
+export * from './access';
+export * from './login';
+export * from './authentication';
+export * from './app';
diff --git a/apps/housekeepingMiniApp/src/hooks/login.ts b/apps/housekeepingMiniApp/src/hooks/login.ts
new file mode 100644
index 0000000..04d3ca4
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/hooks/login.ts
@@ -0,0 +1,76 @@
+import Taro from '@tarojs/taro';
+import { object2query } from '@12333/utils';
+import { goBack } from '@/utils';
+import { useSwitchTab } from './router';
+import { TabBarPageRouter } from '@/constants';
+import { useQueryClient } from '@tanstack/vue-query';
+
+function getOtherQuery(query: Partial<Record<string, string>>) {
+ if (query) {
+ return Object.keys(query).reduce((acc, cur) => {
+ if (cur !== 'redirect' && cur !== '$taroTimestamp') {
+ acc[cur] = query[cur];
+ }
+ return acc;
+ }, {});
+ }
+}
+
+export function useLoginedJump() {
+ const router = Taro.useRouter();
+ const { redirect } = router.params;
+
+ const otherQuery = getOtherQuery(router.params);
+
+ const otherQueryString = computed(() => {
+ const str = object2query(otherQuery);
+ return str.length > 0 ? `${str}` : '';
+ });
+
+ const redirectPath = computed(() => {
+ return redirect
+ ? otherQueryString.value
+ ? `${redirect}?${otherQueryString.value}`
+ : redirect
+ : '';
+ });
+
+ const redirectParams = computed(() => {
+ return redirect ? `${redirect}&${otherQueryString.value}` : '';
+ });
+
+ const switchTab = useSwitchTab();
+
+ const queryClient = useQueryClient();
+
+ const pages = Taro.getCurrentPages();
+
+ function goBackFromAuthorization() {
+ const authorizationIndex = pages.findIndex((x) =>
+ `/${x.route}`.includes(RouterPath.authorization)
+ );
+ let delta = authorizationIndex >= 0 ? pages.length - authorizationIndex : 1;
+ goBack(delta);
+ }
+
+ function jump() {
+ if (redirect) {
+ const isTabBarPage = Object.values(TabBarPageRouter).includes(redirect as any);
+ if (isTabBarPage) {
+ switchTab({
+ url: redirectPath.value,
+ });
+ } else {
+ // Taro.redirectTo({
+ // url: redirectPath.value,
+ // });
+ goBackFromAuthorization();
+ }
+ } else {
+ goBackFromAuthorization();
+ }
+ queryClient.refetchQueries();
+ }
+
+ return { jump, redirectPath, redirectParams };
+}
diff --git a/apps/housekeepingMiniApp/src/hooks/router.ts b/apps/housekeepingMiniApp/src/hooks/router.ts
new file mode 100644
index 0000000..a138cc5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/hooks/router.ts
@@ -0,0 +1,28 @@
+import Taro from '@tarojs/taro';
+import { TabBarPageRouter, TabBarPageRouterList } from '@/constants';
+import { useSystemStore } from '@/stores/modules/system';
+
+export function useSwitchTab() {
+ const systemStore = useSystemStore();
+
+ const switchTab = (option: Taro.switchTab.Option) => {
+ const index = TabBarPageRouterList.findIndex((x) => option.url.includes(x));
+ console.log('index: ', index);
+ Taro.switchTab(option).then(() => {
+ systemStore.setTabIndex(index);
+ });
+ };
+ return switchTab;
+}
+
+// export function useFirstEnter() {
+// const systemStore = useSystemStore();
+// const { isFirstEnter } = storeToRefs(systemStore);
+// console.log('isFirstEnter: ', isFirstEnter);
+
+// onMounted(() => {
+// systemStore.setIsFirstEnter(false);
+// });
+
+// return { isFirstEnter };
+// }
diff --git a/apps/housekeepingMiniApp/src/hooks/user.ts b/apps/housekeepingMiniApp/src/hooks/user.ts
new file mode 100644
index 0000000..9b980e1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/hooks/user.ts
@@ -0,0 +1,104 @@
+import { useUserStore } from '@/stores/modules/user';
+import Taro from '@tarojs/taro';
+import { object2query, LocationUtils } from '@12333/utils';
+import {
+ EnumUserBankCardAccess,
+ ParkOrHRStatus,
+ UserCertificationFrontStatus,
+} from '@12333/constants';
+import { useQuery, useQueryClient } from '@tanstack/vue-query';
+import { MaybeRef } from 'vue';
+import { useRefeshDidShow } from '@12333/hooks/infiniteLoading';
+import * as userResumeServices from '@12333/services/apiV2/userResume';
+import { useUserResume as useUserResumeHook } from '@12333/hooks';
+
+export function useUser() {
+ const userStore = useUserStore();
+
+ const { userDetail, userInfo, locationCity, userId } = storeToRefs(userStore);
+
+ function updateUserInfo() {
+ return userStore.getCurrentUserInfo();
+ }
+
+ const isCertified = computed(() => {
+ return userDetail.value?.isReal;
+ });
+
+ const isBindBank = computed(() => {
+ return userDetail.value?.bankCardAAccesses?.includes(EnumUserBankCardAccess.Bank);
+ });
+
+ const isBindAlipay = computed(() => {
+ return userDetail.value?.bankCardAAccesses?.includes(EnumUserBankCardAccess.AliPay);
+ });
+
+ const isBindWechat = computed(() => {
+ return userDetail.value?.bankCardAAccesses?.includes(EnumUserBankCardAccess.WeChatPay);
+ });
+
+ return {
+ user: userInfo,
+ userDetail: userDetail,
+ updateUserInfo,
+ isCertified,
+ locationCity,
+ userId,
+ isBindBank,
+ isBindAlipay,
+ isBindWechat,
+ };
+}
+
+export function useIsLogin() {
+ const { user, userDetail } = useUser();
+ return computed(() => !!user.value);
+ // return user?.isPersonal ? !!user : !!user && !!enterpriseInfo;
+}
+
+type UseAuthOptions = {
+ needAuth?: boolean;
+};
+
+export function useAuth(options: UseAuthOptions = {}) {
+ const { needAuth = true } = options;
+ const userStore = useUserStore();
+
+ const isLogin = useIsLogin();
+
+ const isAuth = computed(() => !needAuth || isLogin.value);
+
+ const router = Taro.useRouter();
+
+ Taro.useReady(async () => {
+ if (isLogin.value && userStore.firstGetUserDetail) {
+ userStore.getCurrentUserInfo();
+ }
+ if (needAuth && !isLogin.value) {
+ Taro.navigateTo({
+ url: `${RouterPath.authorization}?redirect=${router.path}&${object2query(router.params)}`,
+ });
+ }
+ });
+
+ return { isAuth };
+}
+
+export function useGoLogin() {
+ const router = Taro.useRouter();
+
+ function goLoginFn() {
+ Taro.navigateTo({
+ url: `${RouterPath.authorization}?redirect=${router.path}&${object2query(router.params)}`,
+ });
+ }
+
+ return {
+ goLoginFn,
+ };
+}
+
+export function useUserResume() {
+ const { userId } = useUser();
+ return useUserResumeHook({ userId });
+}
diff --git a/apps/housekeepingMiniApp/src/index.html b/apps/housekeepingMiniApp/src/index.html
new file mode 100644
index 0000000..46e4d7c
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+ <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="apple-touch-fullscreen" content="yes">
+ <meta name="format-detection" content="telephone=no,address=no">
+ <meta name="apple-mobile-web-app-status-bar-style" content="white">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" >
+ <title>vue-mini</title>
+ <script><%= htmlWebpackPlugin.options.script %></script>
+</head>
+<body>
+ <div id="app"></div>
+</body>
+</html>
diff --git a/apps/housekeepingMiniApp/src/pages/home/HomeQueryMenuView.vue b/apps/housekeepingMiniApp/src/pages/home/HomeQueryMenuView.vue
new file mode 100644
index 0000000..422550e
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/home/HomeQueryMenuView.vue
@@ -0,0 +1,77 @@
+<template>
+ <QueryMenuView @close="handleReset" @confirm="emit('close')" cancelText="閲嶇疆">
+ <div class="home-query-menu-view">
+ <QueryMenuItem title="缁撶畻鏂瑰紡">
+ <ProRadio
+ v-model="query.settlementCycle"
+ :value-enum="EnumSettlementCycleText"
+ show-all-btn
+ ></ProRadio>
+ </QueryMenuItem>
+ <QueryMenuItem title="鍛樺伐绂忓埄">
+ <ProRadio v-model="query.benefitCodes" :value-enum="welfareList" show-all-btn></ProRadio>
+ </QueryMenuItem>
+ <QueryMenuItem title="鎬у埆瑕佹眰">
+ <ProRadio
+ v-model="query.genderLimit"
+ :value-enum="EnumUserGenderText"
+ show-all-btn
+ ></ProRadio>
+ </QueryMenuItem>
+ </div>
+ </QueryMenuView>
+</template>
+
+<script setup lang="ts">
+import { QueryMenuView, QueryMenuItem, ProRadio } from '@12333/components';
+import {
+ EnumUserGenderText,
+ EnumSettlementCycle,
+ CategoryCode,
+ EnumSettlementCycleText,
+} from '@12333/constants';
+import { useDictionaryDataSelect } from '@12333/hooks';
+
+defineOptions({
+ name: 'HomeQueryMenuView',
+});
+
+// type Props = {};
+
+// const props = withDefaults(defineProps<Props>(), {});
+
+const { dictionaryDataList: welfareList } = useDictionaryDataSelect({
+ categoryCode: CategoryCode.Welfare,
+});
+
+const emit = defineEmits<{
+ (e: 'reset'): void;
+ (e: 'close'): void;
+}>();
+
+const query = defineModel<{
+ genderLimit: number | string;
+ settlementCycle: EnumSettlementCycle;
+ benefitCodes: string;
+}>('query');
+
+const DefaultQuery = {
+ ...query.value,
+};
+
+function handleReset() {
+ for (const key in DefaultQuery) {
+ query.value[key] = DefaultQuery[key];
+ }
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.home-query-menu-view {
+ max-height: 400px;
+ padding: 30px;
+ overflow: auto;
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/pages/home/index.config.ts b/apps/housekeepingMiniApp/src/pages/home/index.config.ts
new file mode 100644
index 0000000..eaecd79
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/home/index.config.ts
@@ -0,0 +1,5 @@
+export default definePageConfig({
+ navigationStyle: 'custom',
+ disableScroll: true,
+ navigationBarTextStyle: 'white',
+});
diff --git a/apps/housekeepingMiniApp/src/pages/home/index.scss b/apps/housekeepingMiniApp/src/pages/home/index.scss
new file mode 100644
index 0000000..3811705
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/home/index.scss
@@ -0,0 +1,5 @@
+@import '@/styles/common.scss';
+
+page {
+ background-color: #fff;
+}
diff --git a/apps/housekeepingMiniApp/src/pages/home/index.vue b/apps/housekeepingMiniApp/src/pages/home/index.vue
new file mode 100644
index 0000000..bee98ed
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/home/index.vue
@@ -0,0 +1,199 @@
+<template>
+ <PageLayoutWithBg class="index-page-wrapper" :title="''" :need-auth="false">
+ <template #left>
+ <div class="menu-btn-wrapper menu-logo">
+ <img :src="IconLogo" class="logo" />
+ </div>
+ </template>
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ commonMode
+ v-bind="infiniteLoadingProps"
+ >
+ <div class="home-header">
+ <div class="home-searchbar-wrapper">
+ <div class="searchbar-container">
+ <BlSearchbar
+ v-model.trim="searchValue"
+ placeholder="鎼滅储浠诲姟"
+ @search="handleSearch"
+ @change="handleSearch"
+ ></BlSearchbar>
+ </div>
+ <div class="city-btn" @click="goCitySelect">
+ <img :src="IconLocaltion" class="city-btn-icon" />
+ <div class="city-btn-text">{{ locationCity }}</div>
+ </div>
+ </div>
+ <div class="home-banner-wrapper">
+ <nut-swiper :auto-play="3000">
+ <nut-swiper-item v-for="(item, index) in list" :key="index">
+ <img :src="item" class="banner-img" draggable="false" />
+ </nut-swiper-item>
+ </nut-swiper>
+ </div>
+ <nut-grid class="home-gird">
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ <nut-grid-item text="text"><Dongdong /></nut-grid-item>
+ </nut-grid>
+ </div>
+ <div class="home-good-list">
+ <TaskCard
+ v-for="item in infiniteLoadingProps.flattenListData"
+ :key="item.id"
+ @click="goTaskDetail(item)"
+ v-bind="item"
+ style="min-width: 0"
+ />
+ </div>
+ </InfiniteLoading>
+
+ <!-- <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ :key="queryState.orderType"
+ >
+ <template #renderItem="{ item }">
+ <TaskCard @click="goTaskDetail(item)" v-bind="item" />
+ </template>
+ </InfiniteLoading>-->
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import { useUser } from '@/hooks';
+import Taro from '@tarojs/taro';
+import { setLocationCity } from '@/utils';
+import _ from 'lodash';
+import IconLogo from '@/assets/home/icon-logo.png';
+import { TaskCard, ProTabs, ProTabPane } from '@12333/components';
+import HomeQueryMenuView from './HomeQueryMenuView.vue';
+import IconLocaltion from '@/assets/task/icon-localtion.png';
+import { useAllAreaList, useTaskList, HomeOrderType } from '@12333/hooks';
+import { useAccessLogin } from '@/hooks';
+import { Dongdong } from '@nutui/icons-vue-taro';
+
+const { locationCity } = useUser();
+
+const { findAreaCodeFromName } = useAllAreaList();
+
+const { searchValue, queryState, handleSearch, infiniteLoadingProps, queryMenuState } = useTaskList(
+ {
+ cityCode: computed(() => findAreaCodeFromName(locationCity.value)),
+ enabled: computed(() => !!findAreaCodeFromName(locationCity.value)),
+ }
+);
+
+onMounted(async () => {
+ try {
+ await setLocationCity();
+ } catch (error) {}
+});
+
+function goCitySelect() {
+ Taro.navigateTo({
+ url: RouterPath.citySelect,
+ });
+}
+
+const list = ref([
+ 'https://storage.360buyimg.com/jdc-article/NutUItaro34.jpg',
+ 'https://storage.360buyimg.com/jdc-article/NutUItaro2.jpg',
+ 'https://storage.360buyimg.com/jdc-article/welcomenutui.jpg',
+ 'https://storage.360buyimg.com/jdc-article/fristfabu.jpg',
+]);
+
+const selectItem = ref();
+
+function handleMenuSelectClose() {
+ selectItem.value?.toggle?.();
+}
+
+function goTaskDetail(item: API.GetTaskInfosQueryResultItem) {
+ // Taro.navigateTo({
+ // url: `${RouterPath.taskDetail}?id=${item.id}&from=apply`,
+ // });
+}
+
+const goTaskApply = useAccessLogin((item: API.GetTaskInfosQueryResultItem) => {
+ console.log('item: ', item);
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.index-page-wrapper {
+ .menu-logo {
+ padding: 0;
+
+ .logo {
+ width: 96px;
+ height: 64px;
+ }
+ }
+
+ .home-searchbar-wrapper {
+ padding: 32px 0;
+ display: flex;
+
+ .searchbar-container {
+ flex: 1;
+ min-width: 0;
+ }
+
+ .city-btn {
+ display: flex;
+ align-items: center;
+ padding-left: 36px;
+ color: boleGetCssVar('text-color', 'primary');
+
+ .city-btn-icon {
+ width: 40px;
+ height: 40px;
+ }
+
+ .city-btn-text {
+ max-width: 200px;
+ @include ellipsis;
+ margin-left: 12px;
+ font-size: 30px;
+ }
+ }
+ }
+
+ .home-banner-wrapper {
+ margin-bottom: 20px;
+
+ .banner-img {
+ width: 100%;
+ height: 260px;
+ object-fit: cover;
+ }
+ }
+
+ .home-gird {
+ margin-bottom: 20px;
+ }
+
+ .home-header {
+ // padding: 0 boleGetCssVar('size', 'body-padding-h');
+ }
+
+ .home-good-list {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ grid-gap: 20px;
+ }
+}
+
+.home-list {
+ @include infiniteLoadingInTabBarPage;
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/pages/mine/index.config.ts b/apps/housekeepingMiniApp/src/pages/mine/index.config.ts
new file mode 100644
index 0000000..fc5601f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/mine/index.config.ts
@@ -0,0 +1,7 @@
+export default definePageConfig({
+ navigationBarTitleText: 'Mine',
+ usingComponents: {},
+ disableScroll: true,
+ navigationBarTextStyle: 'white',
+ enableShareAppMessage: true,
+});
diff --git a/apps/housekeepingMiniApp/src/pages/mine/index.scss b/apps/housekeepingMiniApp/src/pages/mine/index.scss
new file mode 100644
index 0000000..0e0604e
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/mine/index.scss
@@ -0,0 +1,175 @@
+@import '@/styles/common.scss';
+
+.mine-page-bg {
+ position: fixed;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 750px;
+ height: 434px;
+ object-fit: cover;
+}
+
+.mine-page-wrapper {
+ .mine-avatar-wrapper {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+
+ .mine-avatar {
+ margin-right: 22px;
+ }
+
+ .user-info {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+ padding: 6px 0;
+ justify-content: space-between;
+
+ .user-info-item {
+ font-weight: 600;
+ font-size: 34px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 44px;
+ @include ellipsis;
+ }
+ .user-info-auth {
+ display: inline-flex;
+ .user-info-auth-item {
+ margin-right: 20px;
+ display: inline-flex;
+ align-items: center;
+
+ .user-info-unCertified {
+ display: inline-flex;
+ align-items: center;
+ height: 34px;
+ width: fit-content;
+
+ .user-info-unCertified-icon {
+ width: 20px;
+ height: 28px;
+ margin-right: 6px;
+ }
+
+ .user-info-unCertified-text {
+ font-weight: 400;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'secondary');
+ }
+ .user-info-unCertified-btn {
+ font-weight: 400;
+ font-size: 28px;
+ color: boleGetCssVar('color', 'primary');
+ }
+ }
+ }
+ }
+ }
+
+ .mine-go-login {
+ font-size: 40px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 104px;
+ }
+ }
+
+ .mine-content-scroll-view {
+ padding-top: 26px;
+ background-color: transparent;
+
+ .mine-order-list {
+ margin-bottom: 18px;
+ padding: 0 24px;
+ .mine-order-list-title {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ border-bottom: 2px solid #eeeeee;
+ padding: 24px 0;
+ .mine-order-list-title-text {
+ font-weight: 600;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 32px;
+ }
+ .mine-order-list-title-icon {
+ width: 32px;
+ height: 32px;
+ }
+ }
+ .mine-order-list-content {
+ padding: 24px 0;
+ display: flex;
+ justify-content: space-around;
+
+ .mine-order-list-item {
+ display: inline-flex;
+ flex-direction: column;
+ align-items: center;
+ .mine-order-list-icon {
+ width: 64px;
+ height: 64px;
+ }
+ .mine-order-list-text {
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ }
+ }
+ }
+ }
+ .mine-balance {
+ margin-bottom: 18px;
+ padding: 24px;
+ padding-left: 34px;
+ .mine-balance-content {
+ display: flex;
+ justify-content: space-between;
+ .mine-balance-content-item {
+ display: flex;
+ flex-direction: column;
+ text-align: center;
+ .mine-balance-content-item-title {
+ font-size: 30px;
+ line-height: 42px;
+ color: boleGetCssVar('text-color', 'primary');
+ margin-bottom: 16px;
+ }
+ .mine-balance-content-item-money {
+ font-size: 36px;
+ line-height: 68px;
+ color: boleGetCssVar('text-color', 'primary');
+
+ &.income {
+ color: boleGetCssVar('color', 'primary');
+ }
+ &.settlement {
+ color: boleGetCssVar('color', 'success');
+ }
+ &.withdraw {
+ color: boleGetCssVar('color', 'warning');
+ }
+ }
+ }
+ }
+
+ .mine-balance-btn {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ font-size: 22px;
+ color: boleGetCssVar('text-color', 'regular');
+ line-height: 36px;
+ .mine-balance-btn-icon {
+ width: 32px;
+ height: 32px;
+ }
+ }
+ }
+ .mine-list-wrapper {
+ border-radius: 12px;
+ }
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/pages/mine/index.vue b/apps/housekeepingMiniApp/src/pages/mine/index.vue
new file mode 100644
index 0000000..68cc1c8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/mine/index.vue
@@ -0,0 +1,266 @@
+<template>
+ <PageLayoutWithBg class="mine-page-wrapper" title="鎴戠殑" :need-auth="false">
+ <template #navigationBar>
+ <TransparentNavigationBar
+ title="涓汉涓績"
+ :is-absolute="false"
+ mode="dark"
+ ></TransparentNavigationBar>
+ </template>
+ <template #bg>
+ <img :src="OssAssets.mine.Bg" class="mine-page-bg" :style="{ height: `${bgHeight}px` }" />
+ </template>
+ <ContentView>
+ <UserHomeTopView :showUserHomePageBtn="isLogin" :showOperation="isLogin">
+ <template #avatar>
+ <div class="mine-avatar-wrapper" @click="goLogin">
+ <UserAvatar :size="52" class="mine-avatar" />
+ <div class="user-info" v-if="isLogin">
+ <div class="user-info-item">{{ userDetail?.name ?? '' }}</div>
+ <div class="user-info-auth">
+ <div class="user-info-auth-item">
+ <div class="user-info-unCertified">
+ <div
+ class="user-info-unCertified-text"
+ v-if="userDetail?.realStatus === EnumPersonalUserRealStatus.UnReal"
+ >
+ 鏈璇�
+ </div>
+ <div class="user-info-unCertified-text" v-else>
+ {{ EnumUserRealMethodText[userDetail?.realMethod]
+ }}{{ EnumPersonalUserRealStatusText[userDetail?.realStatus] }}
+ </div>
+ <div
+ class="user-info-unCertified-btn"
+ @click.stop="goAuthentication"
+ v-if="
+ userDetail?.realStatus === EnumPersonalUserRealStatus.UnReal ||
+ userDetail?.realStatus === EnumPersonalUserRealStatus.Fail
+ "
+ >
+ 绔嬪嵆璁よ瘉
+ </div>
+ </div>
+ <!-- <div class="user-info-unCertified" v-else>
+ <img :src="IconAuth" class="user-info-unCertified-icon" />
+ <div class="user-info-unCertified-text">
+ {{ EnumUserRealMethodText[userDetail?.realMethod] }}{{ EnumPersonalUserRealStatusText[userDetail?.realStatus] }}
+ </div>
+ </div> -->
+ </div>
+ </div>
+ </div>
+ <div class="mine-go-login" v-else>鍘荤櫥褰�</div>
+ </div>
+ </template>
+ </UserHomeTopView>
+ </ContentView>
+ <ContentScrollView v-if="isLogin" class="mine-content-scroll-view">
+ <List class="mine-list-wrapper mine-balance">
+ <div class="mine-balance-content">
+ <div class="mine-balance-content-item">
+ <div class="mine-balance-content-item-title">鎴戠殑鏀剁泭</div>
+ <div class="mine-balance-content-item-money income">
+ 锟{ toThousand(userDetail?.incomeCount ?? 0) }}
+ </div>
+ </div>
+ <div class="mine-balance-content-item">
+ <div class="mine-balance-content-item-title">寰呯粨绠�</div>
+ <div class="mine-balance-content-item-money settlement">
+ 锟{ toThousand(userDetail?.waitSettlement ?? 0) }}
+ </div>
+ </div>
+ <div class="mine-balance-content-item">
+ <div class="mine-balance-content-item-title">宸插彂鏀�</div>
+ <div class="mine-balance-content-item-money withdraw">
+ 锟{ toThousand(userDetail?.releaseedCount ?? 0) }}
+ </div>
+ </div>
+ </div>
+ <div class="mine-balance-btn" @click="goMineWallet">
+ 杩涘叆鎴戠殑閽卞寘
+ <img :src="IconArrow" class="mine-balance-btn-icon" />
+ </div>
+ </List>
+ <List class="mine-list-wrapper mine-order-list">
+ <div class="mine-order-list-title">
+ <div class="mine-order-list-title-text">鎴戠殑璁㈠崟</div>
+ <img :src="IconArrow" class="mine-order-list-title-icon" />
+ </div>
+ <div class="mine-order-list-content">
+ <nut-badge
+ class="mine-order-list-item"
+ top="8"
+ :dot="userDetail?.taskCount > 0"
+ @click="goMineSign"
+ >
+ <img :src="IconOrderSign" class="mine-order-list-icon" />
+ <div class="mine-order-list-text">宸叉姤鍚�</div>
+ </nut-badge>
+ <nut-badge
+ class="mine-order-list-item"
+ top="8"
+ :dot="userDetail?.hirePassTaskCount > 0"
+ @click="goMineHired"
+ >
+ <img :src="IconOrderHire" class="mine-order-list-icon" />
+ <div class="mine-order-list-text">宸插綍鐢�</div>
+ </nut-badge>
+ <nut-badge
+ class="mine-order-list-item"
+ top="8"
+ :dot="userDetail?.arrangeCompleteTaskCount > 0"
+ @click="goMineHire"
+ >
+ <img :src="IconOrderHire" class="mine-order-list-icon" />
+ <div class="mine-order-list-text">宸插畨鎺�</div>
+ </nut-badge>
+
+ <!-- <nut-badge
+ class="mine-order-list-item"
+ top="8"
+ :value="userDetail?.hirePassTaskCount ?? 0"
+ @click="goMineHire"
+ >
+ <img :src="IconOrderHire" class="mine-order-list-icon" />
+ <div class="mine-order-list-text">宸插畨鎺�</div>
+ </nut-badge>
+ <nut-badge
+ class="mine-order-list-item"
+ top="8"
+ :value="userDetail?.hireRefuseTaskCount ?? 0"
+ @click="goMineCancel"
+ >
+ <img :src="IconOrderCancel" class="mine-order-list-icon" />
+ <div class="mine-order-list-text">宸插彇娑�</div>
+ </nut-badge> -->
+ </div>
+ </List>
+ <List class="mine-list-wrapper mine-setting-list">
+ <ListItem :icon="IconCollect" title="鎴戞敹钘忕殑浠诲姟" @click="goMineCollectTask"></ListItem>
+ <ListItem :icon="IconAgreement" title="鍗忚绛剧害" @click="goMineAgreementSign"></ListItem>
+ <ListItem :icon="IconSetting" title="璁剧疆" @click="goSetting"></ListItem>
+ <!-- <ListItem :icon="IconRecruit" title="鎴戣鎷涗汉/鐢ㄤ汉" @click="goSetting"></ListItem> -->
+ </List>
+ </ContentScrollView>
+ <CustomerServiceButton />
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import { TransparentNavigationBar, ContentScrollView, UserHomeTopView } from '@/components';
+import IconArrow from '@/assets/setting/icon-arrow.png';
+import IconSetting from '@/assets/mine/icon-setting.png';
+import IconCollect from '@/assets/mine/icon-collect.png';
+import IconAgreement from '@/assets/mine/icon-agreement.png';
+import IconRecruit from '@/assets/mine/icon-recruit.png';
+import IconOrderSign from '@/assets/mine/icon-order-sign.png';
+import IconOrderHire from '@/assets/mine/icon-order-hire.png';
+import IconOrderCancel from '@/assets/mine/icon-order-cancel.png';
+import IconAuth from '@/assets/mine/icon-auth.png';
+import { useUser, useIsLogin, useGoLogin } from '@/hooks';
+import Taro from '@tarojs/taro';
+import { RouterPath, OssAssets } from '@/constants';
+import {
+ EnumUserRealMethodText,
+ EnumPersonalUserRealStatusText,
+ EnumPersonalUserRealStatus,
+} from '@12333/constants';
+import { List, ListItem, CustomerServiceButton } from '@12333/components';
+import { useSystemStore } from '@/stores/modules/system';
+import PageLayoutWithBg from '@/components/Layout/PageLayoutWithBg.vue';
+import { toThousand } from '@12333/utils';
+import { useIntervalFn } from 'senin-mini/hooks';
+import { useQuery } from '@tanstack/vue-query';
+
+const { userDetail, isCertified, updateUserInfo } = useUser();
+const isLogin = useIsLogin();
+const systemStore = useSystemStore();
+const { goLoginFn } = useGoLogin();
+const bgHeight = computed(() => 133 + systemStore.navHeight);
+
+useQuery({
+ queryKey: ['updateUserInfo'],
+ queryFn: () => {},
+ enabled: computed(
+ () => isLogin.value && userDetail.value?.realStatus === EnumPersonalUserRealStatus.Checking
+ ),
+ refetchInterval: 5000,
+});
+
+Taro.useDidShow(() => {
+ if (isLogin.value) {
+ updateUserInfo();
+ }
+});
+
+function goLogin() {
+ if (!isLogin.value) {
+ goLoginFn();
+ }
+}
+
+function goPage(routeName: string) {
+ Taro.navigateTo({
+ url: routeName,
+ });
+}
+
+function goSetting() {
+ goPage(RouterPath.setting);
+}
+
+Taro.showShareMenu({
+ showShareItems: ['shareAppMessage'],
+});
+
+Taro.useShareAppMessage((res) => {
+ return {
+ // title: `${userDetail.value?.contacter}鍚嶇墖`,
+ // path: `${RouterPath.userHomePage}?userId=${userDetail.value?.userId}`,
+ // imageUrl: userDetail.value?.avatarUrl,
+ };
+});
+
+function goAuthentication() {
+ goPage(RouterPath.authenticationHome);
+}
+function goMineSign() {
+ goPage(RouterPath.mineSign);
+}
+function goMineHire() {
+ goPage(RouterPath.mineHire);
+}
+function goMineCancel() {
+ goPage(RouterPath.mineCancel);
+}
+function goMineHired() {
+ goPage(RouterPath.mineHired);
+}
+function goMineCollectTask() {
+ goPage(RouterPath.mineCollectTask);
+}
+function goMineAgreementSign() {
+ goPage(RouterPath.mineAgreementSign);
+}
+
+function goMineWallet() {
+ goPage(RouterPath.mineWallet);
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+@import './index.scss';
+
+.mine-setting-badge {
+ margin-right: 20px;
+}
+
+.mine-setting-list {
+ .pro-list-item-icon {
+ width: 48px;
+ height: 48px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/pages/task/3x_categoryData.ts b/apps/housekeepingMiniApp/src/pages/task/3x_categoryData.ts
new file mode 100644
index 0000000..28d0607
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/task/3x_categoryData.ts
@@ -0,0 +1,2095 @@
+export const categorydata = {
+ categoryChild: [
+ {
+ catId: '1581',
+ catName: '鍦版柟鐗逛骇',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/183517/38/7834/227702/60be1915Ed04664b0/eaf7536ab2c5f4b0.jpg',
+ catId: '1589',
+ catName: '鏂扮枂',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/88907/33/6457/231663/5df33b56Eae1ffafd/819f96550ae520a3.jpg',
+ catId: '2644',
+ catName: '鍖椾含',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/109937/34/10781/169393/5e81b698Ede55aa35/62f6c77ce58c8866.jpg',
+ catId: '2647',
+ catName: '灞辫タ',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/28325/2/11472/104599/5c90b563E7f9df943/c7c4e5f8ba45e64e.jpg',
+ catId: '2648',
+ catName: '鍐呰挋鍙�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t23359/28/1944198302/228556/cb81ba0c/5b6d5786Nf3c63ac8.jpg',
+ catId: '2653',
+ catName: '绂忓缓',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '1583',
+ catName: '浼戦棽椋熷搧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/124512/30/4055/648064/5ed85dacE631811d6/a1ddb3d215909a1f.jpg',
+ catId: '1590',
+ catName: '浼戦棽闆堕',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/199261/17/17179/132409/6191fb65E1d49e5d2/d42c69c018b646d0.jpg',
+ catId: '1591',
+ catName: '鍧氭灉鐐掕揣',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/126378/6/3795/857665/5ed5ab9fE61ee75df/79253ec46360ca43.png',
+ catId: '1592',
+ catName: '鑲夊共鑲夎劘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/221194/12/2713/225980/6191fceeE2e5d1fee/b7140001d23c9198.jpg',
+ catId: '1593',
+ catName: '铚滈ク鏋滃共',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/130034/25/15618/523938/5fac8e15E84b871da/45dc31dee1a4e220.png',
+ catId: '1594',
+ catName: '绯栨灉',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/177728/10/9717/731375/60cb77e9E4c10e9e1/7ae1d424f0c4d406.png',
+ catId: '1595',
+ catName: '楗煎共铔嬬硶',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '1585',
+ catName: '楗枡鍐茶皟',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/175064/33/23005/219475/6168eee1Ed59f4aef/a7f7dab7fb5c8d99.jpg',
+ catId: '1601',
+ catName: '鍐查ギ璋风墿',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t25171/268/1139055306/236004/bb244324/5b88b326Na7890577.jpg',
+ catId: '1602',
+ catName: '楗枡',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/171130/22/6024/128321/6020b2e4Ef4ba4542/353a556d47c25121.jpg',
+ catId: '3986',
+ catName: '鍜栧暋/濂惰尪',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/107411/30/15915/199263/5eaf6b4cE0a7b4080/41335d5d95f576ce.jpg',
+ catId: '9434',
+ catName: '鐗涘ザ涔冲搧',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/201557/13/17647/135095/61a9ceecE312cb7f8/81b6c24f7d7727c1.jpg',
+ catId: '10975',
+ catName: '楗敤姘�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/51415/33/16609/122207/61397309E88c81fbc/7c38686c1f2ffb84.jpg',
+ catId: '12200',
+ catName: '铚傝湝/鏌氬瓙鑼�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ categoryInfo: {
+ level: 1,
+ showPic: true,
+ catType: 1,
+ category: [
+ {
+ catId: 'reccat',
+ catName: '鎺ㄨ崘鍒嗙被',
+ catType: 1,
+ showPic: true,
+ showVideo: false,
+ children: [
+ {
+ catId: '1581',
+ catName: '鍦版柟鐗逛骇',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/183517/38/7834/227702/60be1915Ed04664b0/eaf7536ab2c5f4b0.jpg',
+ catId: '1589',
+ catName: '鏂扮枂',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/88907/33/6457/231663/5df33b56Eae1ffafd/819f96550ae520a3.jpg',
+ catId: '2644',
+ catName: '鍖椾含',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/109937/34/10781/169393/5e81b698Ede55aa35/62f6c77ce58c8866.jpg',
+ catId: '2647',
+ catName: '灞辫タ',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/28325/2/11472/104599/5c90b563E7f9df943/c7c4e5f8ba45e64e.jpg',
+ catId: '2648',
+ catName: '鍐呰挋鍙�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t23359/28/1944198302/228556/cb81ba0c/5b6d5786Nf3c63ac8.jpg',
+ catId: '2653',
+ catName: '绂忓缓',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '1583',
+ catName: '浼戦棽椋熷搧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/124512/30/4055/648064/5ed85dacE631811d6/a1ddb3d215909a1f.jpg',
+ catId: '1590',
+ catName: '浼戦棽闆堕',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/199261/17/17179/132409/6191fb65E1d49e5d2/d42c69c018b646d0.jpg',
+ catId: '1591',
+ catName: '鍧氭灉鐐掕揣',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/126378/6/3795/857665/5ed5ab9fE61ee75df/79253ec46360ca43.png',
+ catId: '1592',
+ catName: '鑲夊共鑲夎劘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/221194/12/2713/225980/6191fceeE2e5d1fee/b7140001d23c9198.jpg',
+ catId: '1593',
+ catName: '铚滈ク鏋滃共',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/130034/25/15618/523938/5fac8e15E84b871da/45dc31dee1a4e220.png',
+ catId: '1594',
+ catName: '绯栨灉',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/177728/10/9717/731375/60cb77e9E4c10e9e1/7ae1d424f0c4d406.png',
+ catId: '1595',
+ catName: '楗煎共铔嬬硶',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '1585',
+ catName: '楗枡鍐茶皟',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/175064/33/23005/219475/6168eee1Ed59f4aef/a7f7dab7fb5c8d99.jpg',
+ catId: '1601',
+ catName: '鍐查ギ璋风墿',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t25171/268/1139055306/236004/bb244324/5b88b326Na7890577.jpg',
+ catId: '1602',
+ catName: '楗枡',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/171130/22/6024/128321/6020b2e4Ef4ba4542/353a556d47c25121.jpg',
+ catId: '3986',
+ catName: '鍜栧暋/濂惰尪',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/107411/30/15915/199263/5eaf6b4cE0a7b4080/41335d5d95f576ce.jpg',
+ catId: '9434',
+ catName: '鐗涘ザ涔冲搧',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/201557/13/17647/135095/61a9ceecE312cb7f8/81b6c24f7d7727c1.jpg',
+ catId: '10975',
+ catName: '楗敤姘�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/51415/33/16609/122207/61397309E88c81fbc/7c38686c1f2ffb84.jpg',
+ catId: '12200',
+ catName: '铚傝湝/鏌氬瓙鑼�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ },
+ {
+ catId: '9987',
+ catName: '鎵嬫満閫氳',
+ showPic: true,
+ showVideo: false,
+ children: [
+ {
+ catId: '830',
+ catName: '鎵嬫満閰嶄欢',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/206917/11/8226/66945/6184e893E5d49b030/9fa0ff3ea1c0f225.jpg',
+ catId: '862',
+ catName: '鎵嬫満鑰虫満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/130927/35/4485/194202/5f0ec040Ea97208b8/0eae5c7b0b297997.jpg',
+ catId: '863',
+ catName: '钃濈墮鑰虫満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/120377/21/4107/341055/5ed85e6dE336adeea/2c772c9d717511e9.png',
+ catId: '866',
+ catName: '鎵嬫満澹�/淇濇姢濂�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/160485/24/20708/173705/607ecbabE197a1e08/c3b555933f691fa6.jpg',
+ catId: '867',
+ catName: '鎵嬫満璐磋啘',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '6880',
+ catName: '杩愯惀鍟�',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/212672/25/6617/327229/61aa3c03E9b9ec15f/0442811781abfa3f.png',
+ catId: '1195',
+ catName: '鍔炲彿鍗�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/178088/18/6103/40858/60ae120bE8778c70f/7471a46e8181a0ec.jpg',
+ catId: '6881',
+ catName: '鍚堢害鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '12360',
+ catName: '閫夊彿涓績',
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/162272/13/3732/87442/6008d8a9Ee3b2d2a9/a9c704fea3f3d614.jpg',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '12416',
+ catName: '鍔炲椁�',
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/220433/36/5663/349755/619f422fEfff5cf6f/9fa248b09a4efd3f.jpg',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/153760/39/13721/29797/5ff67a83E3418fcb0/b096d1562f4a09bc.png',
+ catId: '12428',
+ catName: '瑁呭甯�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '12854',
+ catName: '鎵嬫満鏈嶅姟',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/201179/36/6163/687995/6139ea73E848221ba/2f00ea7f90a2421e.png',
+ catId: '16940',
+ catName: '鐢垫睜鎹㈡柊',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '16941',
+ catName: '鎵嬫満鏁呴殰',
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/119422/38/7484/85445/5ed4772fE938d1579/c80feb43768d2df9.png',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/180855/25/5073/53913/60a5c434Efef4378a/9d4e4bf3f435136b.jpg',
+ catId: '16942',
+ catName: '淇濋殰鏈嶅姟',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ },
+ {
+ catId: '737',
+ catName: '瀹剁敤鐢靛櫒',
+ showPic: true,
+ showVideo: false,
+ children: [
+ {
+ catId: '1276',
+ catName: '涓姢鍋ュ悍',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/111806/7/6224/135242/5eb8ab4cE5e11f458/7f7c4cee0f56c026.png',
+ catId: '739',
+ catName: '鍓冮』鍒�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/23018/23/4644/40085/5c330e8aEb906ed16/94f3022b373bf991.jpg',
+ catId: '740',
+ catName: '鐢靛惞椋�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/924/5/6171/84389/5ba0d23eE29525bad/831de1d140d64324.jpg',
+ catId: '741',
+ catName: '鐢靛姩鐗欏埛',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/21909/19/15282/67307/5cada1a9E91d3c650/8357525300892955.jpg',
+ catId: '742',
+ catName: '鍓�/鑴辨瘺鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/146229/33/25122/90830/61a61900E8b12f06e/ede18da7f2b2464e.jpg',
+ catId: '795',
+ catName: '缇庡鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/195392/11/18575/99164/611c7898E753d700b/fcef61c165630da1.jpg',
+ catId: '963',
+ catName: '瓒虫荡鐩�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '738',
+ catName: '鐢熸椿鐢靛櫒',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/87733/18/16825/166536/5e805074E26d4452e/c5c065ffaa0210b9.jpg',
+ catId: '745',
+ catName: '鍚稿皹鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/211573/33/672/69416/6141bfa9Ee58f5672/6fae52befc5894f0.jpg',
+ catId: '747',
+ catName: '鍙栨殩鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/155798/29/24190/102698/618ddcafE56de10a2/ffdc73b81c11103a.jpg',
+ catId: '748',
+ catName: '鍔犳箍鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/92412/37/13642/189343/5e57302aEf8b210ab/77593981fd6dc3e7.png',
+ catId: '749',
+ catName: '绌烘皵鍑�鍖栧櫒',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/98849/20/14506/136527/5e644d30Ef58bac63/520c7cc48c690660.png',
+ catId: '750',
+ catName: '楗按鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/156235/36/63/99785/5fd46d24Ec2c1eb5d/6a17096a998b264e.jpg',
+ catId: '12395',
+ catName: '骞茶。鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '752',
+ catName: '鍘ㄦ埧灏忕數',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/198635/37/19113/111052/61a88cafE8c6b1efd/72ab8492e054f97b.jpg',
+ catId: '753',
+ catName: '鐢甸キ鐓�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/1003/34/268/263837/5b90c900Ebfa45a56/bb2f0b531efa2748.jpg',
+ catId: '754',
+ catName: '澶氱敤閫旈攨',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/179560/24/2721/53462/6094ef9eEcc91e624/86af729ea287b806.jpg',
+ catId: '755',
+ catName: '鏂欑悊鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t27319/289/322424139/158501/c147e059/5b8e57a6N70fc8cd7.jpg',
+ catId: '756',
+ catName: '璞嗘祮鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/7019/5/7650/123532/5be3a032Ea98f04c8/aa9be3dc737a6a0d.jpg',
+ catId: '757',
+ catName: '鐢电鐐�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/87016/13/13418/303575/5e5732a9Ee1499029/f5988daaa9fe3be6.png',
+ catId: '758',
+ catName: '寰尝鐐�',
+ showPic: true,
+ showVideo: false,
+ },
+
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/118020/36/1123/275741/5e9521d3Ebb729427/5263ec33aa17c394.png',
+ catId: '882',
+ catName: '鐢甸ゼ閾�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/689/35/13471/416696/5bd6b22bE9302f10c/ac4cc60490b5745a.jpg',
+ catId: '899',
+ catName: '闈㈠寘鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/129297/10/6713/300795/5f07d05cE5aadb859/133e411945d53c4e.jpg',
+ catId: '901',
+ catName: '鏋滆敩鍑�鍖栨竻娲楁満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/188265/5/21502/66882/61304c0bE01520e0d/2eef51f48d6c0cf9.jpg',
+ catId: '902',
+ catName: '鐓泲鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/169069/31/21640/281425/61308fa2E15b636f7/51a04acd12e164b1.jpg',
+ catId: '9249',
+ catName: '鐢电倴閿�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/114491/8/8395/346376/5ecf22e4E5cd62935/f8362dd19d4e5c70.png',
+ catId: '12397',
+ catName: '鍏荤敓澹�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '794',
+ catName: '澶� 瀹� 鐢�',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/192770/29/7851/123130/60c5ab65Ede341670/957fefcd7aea4944.jpg',
+ catId: '798',
+ catName: '骞虫澘鐢佃',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/162683/40/23245/88224/61407766E57726d97/ef8203d216d0fe99.png',
+ catId: '870',
+ catName: '绌鸿皟',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/158902/15/6386/117369/601e0c0cE07a801c4/0b65cf93dee18e35.jpg',
+ catId: '878',
+ catName: '鍐扮',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/162207/29/11606/108318/60487f15E05196633/9dc849beda2b9ecf.jpg',
+ catId: '880',
+ catName: '娲楄。鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/194494/6/7259/137017/60c175dcEb0c7d501/0e9622e5629cde85.jpg',
+ catId: '12392',
+ catName: '鍐锋煖/鍐板惂',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '13297',
+ catName: '鍘ㄥ崼澶х數',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/63075/40/5178/414628/5d3551a4E1abd0749/dc396ff3ec7f2e40.jpg',
+ catId: '1300',
+ catName: '娌圭儫鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/86163/31/13550/196051/5e5c622fE38026796/5750f728f18cddff.png',
+ catId: '1301',
+ catName: '娑堟瘨鏌�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/86716/8/14218/379572/5e644d3fE65c0be47/2866ef0b5a9f2e2f.png',
+ catId: '13117',
+ catName: '娲楃鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/10279/18/5582/133914/5c18c360E4b2089c9/391c910f23a4f2f5.jpg',
+ catId: '13298',
+ catName: '鐕冩皵鐏�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '14857',
+ catName: '鍟嗙敤鐢靛櫒',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/200342/21/3939/146637/611f2707Ea099625f/1dedb277373069a3.jpg',
+ catId: '14858',
+ catName: '鍟嗙敤鐑ょ',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/198137/6/11999/91654/615ffb7dE527fdbe5/e3ba90a5658d794b.jpg',
+ catId: '14859',
+ catName: '閱掑彂绠�',
+ showPic: true,
+ showVideo: false,
+ },
+
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/59173/4/16826/82895/6135a8faE646794ea/6e0fa5d5ac168d9d.jpg',
+ catId: '14863',
+ catName: '鍟嗙敤鐢甸ゼ閾�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/104362/18/15364/341244/5e71de02Edef01042/af5d9db87e022028.jpg',
+ catId: '14864',
+ catName: '鑲犵矇鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/120779/6/6476/198887/5f03441eE0edc3eec/2c47e836ae440048.jpg',
+ catId: '14865',
+ catName: '淇濇俯鍞キ鍙�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '14866',
+ catName: '妫夎姳绯栨満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '14867',
+ catName: '绔犻奔涓告満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/156615/8/73/92699/5fd466a4E4eba1fc8/f17b10b8f5338ce4.jpg',
+ catId: '14868',
+ catName: '鍟嗙敤寮�姘村櫒',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/12279/34/1853/168915/5c16fc12Eb4dfe5ef/3a7e0418a8a74a76.jpg',
+ catId: '14869',
+ catName: '鏋滅硸鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/96433/33/13285/234434/5e5730b2Efb8d5151/3cfc58d26753dda6.png',
+ catId: '14870',
+ catName: '棣欒偁/鐑嫍鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/211267/35/7962/38621/61864517Ee3f50fd2/b8861ef0fd029095.jpg',
+ catId: '14871',
+ catName: '鐢靛姩椁愯溅',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/216048/23/5219/133383/619af275Ed45ea712/2cab380ed4f8bbf1.jpg',
+ catId: '14872',
+ catName: '鍟嗙敤缁炶倝鏈�/鍒囪倝鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/149056/9/13433/99301/5fa51409E873772c9/9d138f0d366e333d.jpg',
+ catId: '14873',
+ catName: '灞曠ず鏌�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '16962',
+ catName: '瀹剁數鏈嶅姟',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/99176/38/16243/144180/5e796380Ef4db82ab/00ee2afb2f794451.png',
+ catId: '16963',
+ catName: '瀹剁數瀹夎',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '16964',
+ catName: '瀹剁數娓呮礂',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t27532/136/1921084935/101552/b8580619/5bf293d8N96ac6e78.jpg',
+ catId: '16965',
+ catName: '瀹剁數缁翠慨',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ },
+ {
+ catId: '652',
+ catName: '鏁扮爜',
+ showPic: true,
+ showVideo: false,
+ children: [
+ {
+ catId: '654',
+ catName: '鎽勫奖鎽勫儚',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t25420/359/2411692934/85651/b8831335/5be43ee8Nc3be9509.jpg',
+ catId: '831',
+ catName: '鏁扮爜鐩告満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/35828/26/5078/324781/5cbea100Eb22bb637/4d2d5e3bcd86fba4.jpg',
+ catId: '832',
+ catName: '鍗曞弽鐩告満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/31505/19/15256/302254/5cc15b32E0ef27f91/ecc74ee1929f4b98.jpg',
+ catId: '833',
+ catName: '鎽勫儚鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t27217/164/123983469/100291/8ce505bf/5b85132dN7c54da7d.jpg',
+ catId: '834',
+ catName: '闀滃ご',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t26581/257/1933748659/197103/ac1af01/5bf4af9cN731ff59e.jpg',
+ catId: '844',
+ catName: '鏁扮爜鐩告',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/110907/1/2262/435001/5ea0fdcdE5de43bf9/bc3c5e5e66f61ede.png',
+ catId: '5012',
+ catName: '寰崟鐩告満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/49558/5/8512/120845/5d5e36deE2f255ae1/14add63bc0c2105e.jpg',
+ catId: '7170',
+ catName: '鎷嶇珛寰�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '829',
+ catName: '鏁扮爜閰嶄欢',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t28927/243/1198717160/216636/43a35e65/5cda169aNd5da1f97.jpg',
+ catId: '835',
+ catName: '婊ら暅',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/965/27/3389/106502/5b988507Eac39c0bd/53c6e926221e0191.jpg',
+ catId: '836',
+ catName: '闂厜鐏�/鎵嬫焺',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/164122/21/18307/170951/606c23f0E7ff3fc35/d9a66b058c6f64fc.jpg',
+ catId: '845',
+ catName: '瀛樺偍鍗�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/180559/34/13135/80418/60e697ddE5f40bc5e/0469d7d1d7764923.jpg',
+ catId: '846',
+ catName: '璇诲崱鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/105418/15/6639/145373/5df60725Eaafb4c3d/0816c8238f356b08.jpg',
+ catId: '847',
+ catName: '鐩告満鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/45659/34/3381/84131/5d11993fEf95f2562/62c37ab476bdeb00.jpg',
+ catId: '848',
+ catName: '涓夎剼鏋�/浜戝彴',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '828',
+ catName: '褰遍煶濞变箰',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/198030/11/10316/108414/6151618dE7d5eb219/89fe648ef71a9b3b.jpg',
+ catId: '837',
+ catName: 'MP3/MP4',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/160046/24/23560/187078/616134beE9a333ad1/26d2c5984dc10ae1.jpg',
+ catId: '841',
+ catName: '闊崇/闊冲搷',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/210855/21/941/153358/614464d6E894fc37f/c86f1b7dcc2f0339.jpg',
+ catId: '842',
+ catName: '鑰虫満/鑰抽害',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/9950/3/1213/172349/5bcd6855Ebfc35884/f145193d604ef1ae.jpg',
+ catId: '869',
+ catName: '楹﹀厠椋�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/156439/31/6619/96248/60066943E56001d13/16d10f7fb8d835e7.jpg',
+ catId: '962',
+ catName: '涓撲笟闊抽',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/200676/24/609/29419/610d0af0E5362e966/9d1aef32b1e6fade.jpg',
+ catId: '5270',
+ catName: '鑻规灉閰嶄欢',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '12346',
+ catName: '鐢靛瓙鏁欒偛',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/62708/7/1154/300095/5cf6171dE1724a70a/a96afc52bbab03da.jpg',
+ catId: '838',
+ catName: '鐢靛瓙璇嶅吀',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/144359/19/1392/465976/5ef2c8c0Ed65003a5/09237c9017cc6880.png',
+ catId: '840',
+ catName: '褰曢煶绗�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/113845/3/16758/69369/5f505231E36b77f92/aa5da012d5349097.jpg',
+ catId: '1203',
+ catName: '鐢电焊涔�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/47972/11/8203/120944/5d5b960bEb69e1e3b/3868a0c13d198992.jpg',
+ catId: '12356',
+ catName: '澶嶈鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/111247/9/15214/107780/5f3b9f70E6b6d86b2/f50820c3a3e5379c.jpg',
+ catId: '12357',
+ catName: '鐐硅鏈�/绗�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/73905/2/17016/114908/61429dbaEd7104fb8/9a1e699e925aa96e.jpg',
+ catId: '12358',
+ catName: '瀛︾敓骞虫澘',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '981',
+ catName: '铏氭嫙鍟嗗搧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/15442/35/311/98412/5c08ce53Ee980dd2a/2febbd9466191b94.jpg',
+ catId: '982',
+ catName: '寤朵繚鏈嶅姟',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '12345',
+ catName: '鏅鸿兘璁惧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/168905/18/25204/99018/619de3f3E8d8d42e3/db2e0bde9d8ca513.jpg',
+ catId: '12347',
+ catName: '鏅鸿兘鎵嬬幆',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/144244/13/4483/47045/5f28cf2eEc21dce00/a7e906be6d41fa46.jpg',
+ catId: '12348',
+ catName: '鏅鸿兘鎵嬭〃',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t27277/335/3069813/79993/66cd0b05/5b7fd200Ne836aae2.jpg',
+ catId: '12349',
+ catName: 'VR鐪奸暅',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/18703/10/12450/166846/5c98af08E99a3e374/0cdd2ff68fc6fa46.jpg',
+ catId: '12350',
+ catName: '杩愬姩璺熻釜鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/76305/5/7837/202299/5d5cb524Ed7616b1f/58dbb5a9da73e66c.jpg',
+ catId: '12351',
+ catName: '鍋ュ悍鐩戞祴',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/205762/9/7700/34808/614beed1Ec4def372/d3078d5fcfc09e67.jpg',
+ catId: '12352',
+ catName: '鏅鸿兘閰嶉グ',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '16951',
+ catName: '鏁扮爜缁翠慨',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ catId: '16954',
+ catName: '鍏朵粬鏁扮爜浜у搧缁翠慨',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ },
+ {
+ catId: '670',
+ catName: '鐢佃剳銆佸姙鍏�',
+ showPic: true,
+ showVideo: false,
+ children: [
+ {
+ catId: '671',
+ catName: '鐢佃剳鏁存満',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/185736/8/20860/30110/61244419E228fec46/4d3c0603d3a8b555.jpg',
+ catId: '672',
+ catName: '绗旇鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/174779/29/18358/138749/60e41e89Ed5d73229/bed842c889662923.jpg',
+ catId: '673',
+ catName: '鍙板紡鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/29909/27/1036/253555/5c0f26f2E7f3d5004/1eb24ded8ecbc177.jpg',
+ catId: '674',
+ catName: '鏈嶅姟鍣�/宸ヤ綔绔�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/147502/6/8170/278953/5f5c3b75Eb9c79df6/fba5fca19d452b4f.png',
+ catId: '675',
+ catName: '绗旇鏈厤浠�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/179498/37/9908/196541/60cc5949E35d8816c/174adc6732564fef.jpg',
+ catId: '1105',
+ catName: '娓告垙鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/20937/25/11570/118978/5c90682aEa60e4a17/20f239aafde1faa1.jpg',
+ catId: '2694',
+ catName: '骞虫澘鐢佃剳',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '677',
+ catName: '鐢佃剳缁勪欢',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/201010/7/13094/133768/61694f3fE609d4f5e/5cbe7975e8f135f1.jpg',
+ catId: '678',
+ catName: 'CPU',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/148416/4/19398/47178/5fe19f74Eb0769b8c/f4b12168e77b6340.jpg',
+ catId: '679',
+ catName: '鏄惧崱',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/208644/15/5284/300516/61696163Ee1631c65/5ce015cc41d3c353.png',
+ catId: '680',
+ catName: '鍐呭瓨',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/115260/4/8889/642066/5ed5cee4E0ba41585/0d2f9dec64e48990.jpg',
+ catId: '681',
+ catName: '涓绘澘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/160559/33/14567/160361/60598d4aE1313beb2/a6905b67911b0dcf.jpg',
+ catId: '682',
+ catName: '鏁g儹鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/2108/21/2626/259487/5b972db7E43119e11/6eb212035c7955a9.jpg',
+ catId: '683',
+ catName: '纭洏',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '686',
+ catName: '澶栬浜у搧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/198519/21/17143/99664/6194b7d5E2ca1e932/7bb0c55d26eecf7a.jpg',
+ catId: '689',
+ catName: '閿洏',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/188348/40/17288/178695/610ce11aE203c54b0/3fdf0ba391279b2c.png',
+ catId: '690',
+ catName: '榧犳爣',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/135947/25/19732/81210/5fd56d76Edf622a15/d51eeade2d3c6bfc.png',
+ catId: '692',
+ catName: '鎽勫儚澶�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/143524/23/21579/88637/61a581ffEd05f4c44/ba625836b8f237cc.jpg',
+ catId: '693',
+ catName: '绉诲姩鏈烘纭洏',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/194484/20/4837/83221/60ac95beE886cefa4/912712a051a96cd2.jpg',
+ catId: '694',
+ catName: 'U鐩�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '716',
+ catName: '鍔炲叕璁惧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/99250/2/15872/103371/5e75702eE539d0da8/704e524239abbb93.png',
+ catId: '717',
+ catName: '鎵撳嵃鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/141920/1/3399/74385/5f17d82bEdc56eda7/0d40af07e80bc5d3.jpg',
+ catId: '718',
+ catName: '浼犵湡璁惧',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/207527/24/1922/98123/614d3e6eE046a0fcf/48f268e5c81aa3bb.jpg',
+ catId: '719',
+ catName: '澶嶅悎鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/203113/37/4885/282916/61333b7eE22dda16e/fd31b813258a2f5b.jpg',
+ catId: '721',
+ catName: '鎵弿浠�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/110171/17/7209/225195/5e574638E1c8ee2bb/240ad34ff94aa2bf.png',
+ catId: '722',
+ catName: '鎶曞奖鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/186941/14/19527/205582/6122f2e6E8ef28859/54906e93211c3e3d.jpg',
+ catId: '723',
+ catName: '纰庣焊鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '729',
+ catName: '鏂囧叿',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/100927/20/8515/315477/5e056961Ed2d3b736/ab972a77af024c51.jpg',
+ catId: '728',
+ catName: '璁$畻鍣�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/152506/22/5765/66130/5fae3357E2fa54527/d55432475f77dcec.jpg',
+ catId: '1449',
+ catName: '瀛︾敓鏂囧叿',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t25270/146/1067048244/35116/47a9f798/5b8635b4N7a2cee7a.jpg',
+ catId: '2603',
+ catName: '绗旂被',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/200478/11/14185/147508/61726c58Ef81354cc/8e69563bb6eb4c34.jpg',
+ catId: '4837',
+ catName: '鍔炲叕鏂囧叿',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/209741/11/11225/710515/61a74b0aE586435ab/ceb6323be0c33028.png',
+ catId: '4840',
+ catName: '鏂囦欢绠$悊',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t24766/285/812760926/237390/abd267e6/5b7cd922N5b4b8f5b.jpg',
+ catId: '7371',
+ catName: '鏈唽/渚跨',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '807',
+ catName: '璧犲搧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/99796/18/13760/51851/5e5dd49bEe7087eb9/06ade2771372c418.jpg',
+ catId: '808',
+ catName: '璧犲搧',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '703',
+ catName: '鏈嶅姟浜у搧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t23656/63/2528454929/133205/ebe1b59f/5b84a4efNd4763086.jpg',
+ catId: '1009',
+ catName: '浜笢鏈嶅姟',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/88965/31/18541/93152/5e95275eE1a2bdf4c/59cc5f9de9d4b72a.jpg',
+ catId: '5011',
+ catName: '鐢佃剳杞欢',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/149766/9/12363/68179/5f990b32Ef313145f/15298fa9d5b24a40.jpg',
+ catId: '10969',
+ catName: '寤朵繚鏈嶅姟',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '12429',
+ catName: '鐢佃剳鍔炲叕璁惧淇濆吇',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '12800',
+ catName: '娓告垙璁惧',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/206841/38/9144/126907/618e3d40Eb6465d31/bf82156849471adb.jpg',
+ catId: '12801',
+ catName: '娓告垙鏈�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/180989/13/12186/161700/60dd96efEb78c40c5/2b2bd6bb59a77eb2.jpg',
+ catId: '12802',
+ catName: '娓告垙鑰虫満',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/183531/29/3285/77470/6098e467E67e89d4b/06ee24c69e03e948.jpg',
+ catId: '12803',
+ catName: '鎵嬫焺/鏂瑰悜鐩�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/110939/14/9127/388611/5ed727d3E8f4d688c/bbb5b65ad3a172e6.png',
+ catId: '12804',
+ catName: '娓告垙杞欢',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/57029/27/7832/88398/5d551190E667ec139/d006bbe9e8b4b8f3.jpg',
+ catId: '12805',
+ catName: '娓告垙鍛ㄨ竟',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '16943',
+ catName: '鐢佃剳鍔炲叕瀹夎',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/149479/11/5835/133911/5f3df83eEd8b8106b/c617eb2a013805bf.jpg',
+ catId: '16944',
+ catName: '鐢佃剳瀹夎',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/178697/36/9948/44892/60cc4e1cEd20b2c96/8e6a3e67c09cb776.jpg',
+ catId: '16945',
+ catName: '鍔炲叕璁惧瀹夎',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '16946',
+ catName: '鐢佃剳鍔炲叕缁翠慨',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/202120/26/5241/362323/6135b1dcEaeb2379f/5207b32b6efbbf09.jpg',
+ catId: '16948',
+ catName: '绗旇鏈淮淇�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '16949',
+ catName: '骞虫澘缁翠慨',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '21076',
+ catName: '鍔炲叕鑰楁潗',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/140497/27/20635/108724/5fe94b08E2b2a45f1/f0918579230fb24d.jpg',
+ catId: '21077',
+ catName: '鍒诲綍纰熺墖',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/94257/16/13195/330258/5e5734fcEbfa1fac3/2f31d37c3595433a.png',
+ catId: '21078',
+ catName: '绾哥被',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/206357/18/5127/151060/6135ca3cE53149f6e/5f17655dada7fed9.jpg',
+ catId: '21079',
+ catName: '纭掗紦',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/69527/25/12456/295322/5d9c35c5E2d362238/760b8f1cabc905de.jpg',
+ catId: '21080',
+ catName: '澧ㄧ洅',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/107302/16/7107/412437/5e572beeE166c6ab3/b8f97bd299be6c76.png',
+ catId: '21081',
+ catName: '鑹插甫',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ },
+ {
+ catId: '17329',
+ catName: '绠卞寘鐨叿',
+ showPic: true,
+ showVideo: false,
+ children: [
+ {
+ catId: '2576',
+ catName: '绮惧搧鐢峰寘',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/86811/33/15751/689271/5e757002Ec402ae4f/4234f1e93d42477f.png',
+ catId: '1455',
+ catName: '鍟嗗姟鍏枃鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/109530/37/8480/206516/5e68a81bE97e423b1/a4fcf6c1270048bc.jpg',
+ catId: '2584',
+ catName: '鐢峰+閽卞寘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/99767/4/15178/641744/5e7195cbE6204d137/2203589848a13609.png',
+ catId: '5262',
+ catName: '鐢峰+鎵嬪寘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/99009/22/14594/411773/5e686b6bEb5114218/9d39423b17d247de.png',
+ catId: '12071',
+ catName: '鍙岃偐鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/209476/14/6958/170589/6179044fEafa5008e/5355d2c6d284d200.jpg',
+ catId: '12072',
+ catName: '鍗曡偐/鏂滄寧鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/151623/21/10589/162201/5fdcaf97Ed52d19c4/a7479db85105b02b.jpg',
+ catId: '12073',
+ catName: '閽ュ寵鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/204691/28/15918/140290/6197209eEe524d4cd/0216dadde57a57d4.jpg',
+ catId: '13542',
+ catName: '鍗″寘鍚嶇墖澶�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/174382/13/6196/206626/6083916aE04c5abad/f6320f2e6394ffef.jpg',
+ catId: '13762',
+ catName: '鎵嬫満鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/191763/2/11394/485400/60dff12fEa41b7e9a/cba4f4233a16e216.png',
+ catId: '13763',
+ catName: '璇佷欢鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '2575',
+ catName: '娼祦濂冲寘',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/168587/33/15876/157844/6066cf24E611ae6c9/dedac97916652533.jpg',
+ catId: '2580',
+ catName: '閽卞寘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/104688/20/14793/413783/5e69914fE2638cba6/9f1b91d4b28009e2.png',
+ catId: '5256',
+ catName: '鎵嬫嬁鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/194540/4/19329/667370/6121dbbcE246cd4a3/8b705b2550c414e0.png',
+ catId: '5257',
+ catName: '鍗曡偐鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/89132/4/16236/441642/5e79630cEaa69c2dc/baa52867d7521f2a.png',
+ catId: '5258',
+ catName: '濂冲+鍙岃偐鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/189993/7/17456/189236/61110fe0E6c3b9908/98869265ddd393b2.jpg',
+ catId: '5259',
+ catName: '鎵嬫彁鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/206254/22/2721/225164/6124bd85E7b40eeb0/87fc0e6d588e2a24.jpg',
+ catId: '5260',
+ catName: '鏂滄寧鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/168598/14/8887/259057/603f265eEe5055621/b524e5f7cdc9102a.png',
+ catId: '12069',
+ catName: '閽ュ寵鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/137332/33/16752/316096/5fb884f4E80f257d8/39d01ddae44ffa4f.png',
+ catId: '12070',
+ catName: '鍗″寘/闆堕挶鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/59161/13/4770/209337/5d26ebf3E327f0859/0fe7aa222bfc29bf.jpg',
+ catId: '13764',
+ catName: '鍖栧鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '2577',
+ catName: '鍔熻兘绠卞寘',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/135675/36/6344/120410/5f2d5243E139150f1/66c03fd8b44b5bc1.jpg',
+ catId: '2587',
+ catName: '鐧诲北鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/155624/5/23684/86386/618887fbEc4c7033b/adc67d21659d75fb.jpg',
+ catId: '2588',
+ catName: '鏃呰鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/23747/29/11790/126764/5c91fa3aE8881658e/4227598ba4ba8ba4.jpg',
+ catId: '2589',
+ catName: '鎷夋潌绠�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/194841/26/13307/86198/60efe982Eb9874438/ad1aed5a1b609665.jpg',
+ catId: '3997',
+ catName: '鐢佃剳鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t29251/208/865778281/344849/6e95ef/5c00ff99N79a7e322.jpg',
+ catId: '3998',
+ catName: '浼戦棽杩愬姩鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t24502/173/2397470667/302228/44391882/5b7d36d9N34eaf74c.jpg',
+ catId: '4000',
+ catName: '鏃呰閰嶄欢',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/10118/21/2046/298944/5be00e3dEfb40af17/f85b15c508646560.jpg',
+ catId: '5265',
+ catName: '涔﹀寘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/169161/21/24193/320681/618f8f03E7eb69a30/fe7ae663d55b6402.jpg',
+ catId: '12076',
+ catName: '鑵板寘/鑳稿寘',
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/128985/4/13896/70729/5f715aa3E46d9e03a/fccb2ac66b7ccb94.jpg',
+ catId: '13543',
+ catName: '鎷夋潌鍖�',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ {
+ catId: '17330',
+ catName: '绠卞寘鐨叿閰嶄欢',
+ catLevel: 2,
+ catType: 1,
+ childCateList: [
+ {
+ backImg:
+ 'https://m.360buyimg.com/n2/jfs/t1/64678/14/16857/69808/613ec336E1b44c59f/08d620e59291eecd.jpg',
+ catId: '13761',
+ catName: '绠卞寘閰嶄欢',
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ showPic: true,
+ showVideo: false,
+ },
+ ],
+ },
+ ],
+ },
+ customCategory: [
+ {
+ catId: 'A1',
+ catName: '鐢佃鏈�',
+ showPic: false,
+ showVideo: false,
+ },
+ {
+ catId: 'A2',
+ catName: '椋熷搧',
+ showPic: false,
+ showVideo: false,
+ },
+ {
+ catId: 'A3',
+ catName: '鏁扮爜',
+ showPic: false,
+ showVideo: false,
+ },
+ {
+ catId: 'A4',
+ catName: '鍋ュ悍',
+ showPic: false,
+ showVideo: false,
+ },
+ {
+ catId: 'A5',
+ catName: '杩愬姩鏈烘',
+ showPic: false,
+ showVideo: false,
+ },
+ ],
+};
diff --git a/apps/housekeepingMiniApp/src/pages/task/InnerPage.vue b/apps/housekeepingMiniApp/src/pages/task/InnerPage.vue
new file mode 100644
index 0000000..b0a12a9
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/task/InnerPage.vue
@@ -0,0 +1,42 @@
+<template>
+ <nut-category :category="data.category" @change="change" class="category-page-inner">
+ <nut-category-pane :categoryChild="data.categoryChild" @onChange="onChange">
+ </nut-category-pane>
+ </nut-category>
+</template>
+
+<script setup lang="ts">
+import Taro from '@tarojs/taro';
+import { useCheckReceiveTasks, useTaskList } from '@12333/hooks';
+import { EnumTaskCheckReceiveStatus, EnumTaskCheckReceiveMethod } from '@12333/constants';
+import dayjs from 'dayjs';
+import { categorydata } from './3x_categoryData';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const data = reactive({
+ categoryInfo: categorydata.categoryInfo,
+ category: categorydata.categoryInfo.category,
+ categoryChild: categorydata.categoryChild,
+});
+
+const change = (index: number) => {
+ data.categoryChild = [].concat(data.categoryInfo.category[index + 1].children);
+};
+const onChange = () => {
+ console.log('褰撳墠鍒嗙被鏁版嵁');
+};
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.task-page-wrapper {
+ .category-page-inner {
+ height: 100%;
+ background-color: transparent;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/pages/task/task.config.ts b/apps/housekeepingMiniApp/src/pages/task/task.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/task/task.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/pages/task/task.vue b/apps/housekeepingMiniApp/src/pages/task/task.vue
new file mode 100644
index 0000000..38ad18d
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/pages/task/task.vue
@@ -0,0 +1,13 @@
+<template>
+ <PageLayoutWithBg class="task-page-wrapper" title="鍏ㄩ儴鍒嗙被">
+ <InnerPage />
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'task',
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/stores/index.ts b/apps/housekeepingMiniApp/src/stores/index.ts
new file mode 100644
index 0000000..efaf6c9
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/stores/index.ts
@@ -0,0 +1,10 @@
+import type { App } from 'vue';
+import { createPinia } from 'pinia';
+
+const store = createPinia();
+
+export function setupStore(app: App<Element>) {
+ app.use(store);
+}
+
+export { store };
diff --git a/apps/housekeepingMiniApp/src/stores/modules/system.ts b/apps/housekeepingMiniApp/src/stores/modules/system.ts
new file mode 100644
index 0000000..8fdd047
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/stores/modules/system.ts
@@ -0,0 +1,116 @@
+import Taro from '@tarojs/taro';
+import { defineStore } from 'pinia';
+import { store } from '@/stores';
+
+export interface Options {
+ path: string;
+ scene: number;
+ query: object;
+ shareTicket: string;
+ referrerInfo: object;
+ tabIndex: number;
+ IPhoneXPadding: number;
+ navHeight: number;
+ safeAreaTop: number;
+ buttonBottom: number;
+
+ redirectPath: string;
+ isTabSwitch: boolean;
+ isFirstEnter: boolean;
+}
+
+export const useSystemStore = defineStore({
+ id: 'app-system',
+ /** 鐘舵�� */
+ state: () => ({
+ options: {} as Options,
+
+ activeTab: 0,
+
+ info: {} as Taro.getSystemInfoSync.Result,
+
+ designWidth: 750,
+
+ screenHeight: 0,
+ screenWidth: 0,
+ pageHeightWithTab: 0,
+ pageHeight: 0,
+
+ IPhoneXPadding: 0,
+
+ navHeight: 0,
+ bottomNavHeight: 0,
+
+ safeAreaTop: 0,
+
+ navigationBarHeight: 0,
+ //鍙充笂瑙掕兌鍥婃寜閽珮搴�
+ menuButtonHeight: 0,
+ menuButtonWidth: 0,
+ menuButtonRightDistance: 0,
+ menuButtonTop: 0,
+
+ isFirstEnter: true,
+ }),
+
+ actions: {
+ init(options: Options) {
+ this.options = options; // 鏀句竴涓嬮〉闈㈢浉鍏崇殑鏁版嵁渚嬪scene绛� 椤甸潰楂樺害涔嬬被鐨勪笉瀛橈紒
+ },
+
+ setInfo(info: Taro.getSystemInfoSync.Result) {
+ this.info = info;
+ console.log('info: ', info);
+
+ this.setNavigationBarHeight(info);
+
+ this.screenHeight = info.screenHeight;
+ this.screenWidth = info.screenWidth;
+
+ this.IPhoneXPadding = info.screenHeight - info.safeArea.bottom;
+ this.navHeight = info.statusBarHeight + this.navigationBarHeight;
+
+ this.safeAreaTop = info.safeArea.top;
+
+ const scale = info.screenWidth / this.designWidth;
+
+ /**
+ * 100涓哄簳閮╰abber鐨勯珮搴�
+ */
+ this.bottomNavHeight = 118 * scale;
+
+ this.pageHeight = info.screenHeight - this.navHeight - this.IPhoneXPadding; // 鏃犲簳閮╰abber
+ this.pageHeightWithTab = this.pageHeight - this.bottomNavHeight; // 鏈夊簳閮╰abber
+ },
+
+ setNavigationBarHeight(systemInfo: Taro.getSystemInfoSync.Result) {
+ const { right, height, width, top } = Taro.getMenuButtonBoundingClientRect();
+
+ let navigationBarHeight = 0;
+
+ if (systemInfo.platform === 'android') {
+ navigationBarHeight = 48;
+ } else {
+ navigationBarHeight = 44;
+ }
+ this.menuButtonHeight = height;
+ this.menuButtonWidth = width;
+ this.menuButtonTop = top;
+ this.menuButtonRightDistance = systemInfo.screenWidth - right;
+ this.navigationBarHeight = navigationBarHeight;
+ },
+
+ setTabIndex(tabIndex: number) {
+ this.activeTab = tabIndex;
+ },
+
+ setIsFirstEnter(isFirstEnter: boolean) {
+ this.isFirstEnter = isFirstEnter;
+ },
+ },
+});
+
+// Need to be used outside the setup
+export function useSystemStoreWithOut() {
+ return useSystemStore(store);
+}
diff --git a/apps/housekeepingMiniApp/src/stores/modules/user.ts b/apps/housekeepingMiniApp/src/stores/modules/user.ts
new file mode 100644
index 0000000..cf8e0bf
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/stores/modules/user.ts
@@ -0,0 +1,292 @@
+import { defineStore } from 'pinia';
+import { store } from '@/stores';
+import {
+ getToken as getCacheToken,
+ getUserInfo as getCacheUserInfo,
+ setUserInfo,
+ removeUserInfo,
+ setUserDetail,
+ getUserDetail,
+ removeUserDetail,
+} from '@/utils/storage/auth';
+import Taro, { useRouter } from '@tarojs/taro';
+import { ButtonProps } from '@tarojs/components';
+import { debounce } from 'lodash';
+import { goHome, getStorageLocationCity, setStorageLocationCity } from '@/utils';
+import {
+ getAccountInfoFromAccessToken,
+ AccountInfo,
+ setOSSLink,
+ getUserCertificationFrontStatusAdapter,
+ LocationUtils,
+ md5Encrypt,
+} from '@12333/utils';
+import DefaultAvatar from '@/assets/components/icon-default-avatar.png';
+import { myClient } from '@/constants/query';
+import { globalEventEmitter } from '@12333/hooks';
+import * as authServices from '@12333/services/apiV2/auth';
+import { AppLocalConfig } from '@/constants';
+
+interface UserState {
+ userInfo?: Nullable<API.LoginCommandCallback>;
+ token?: Nullable<string>;
+ refreshToken?: Nullable<string>;
+ userDetail?: Nullable<API.GetPersonalLoginInfoQueryResult>;
+ firstGetUserDetail?: boolean;
+ firstLaunch?: boolean;
+
+ locationCity?: string;
+ locationProvince?: string;
+ firstSetLocation?: boolean;
+}
+
+const goAuthorization = debounce(
+ () => {
+ const route = Taro.getCurrentInstance().router;
+ if (route.path !== RouterPath.authorization) {
+ Taro.navigateTo({
+ url: RouterPath.authorization,
+ });
+ }
+ },
+ 300,
+ {
+ leading: true,
+ trailing: false,
+ }
+);
+
+export const useUserStore = defineStore({
+ id: 'app-user',
+ state: (): UserState => {
+ const userInfo = getCacheUserInfo();
+ const userDetail = getUserDetail();
+ const storageLocation = getStorageLocationCity();
+
+ return {
+ // user info
+ userInfo: userInfo,
+ // token
+ token: userInfo?.accessToken ?? '',
+
+ refreshToken: userInfo?.refreshToken ?? '',
+ userDetail: userDetail,
+ firstGetUserDetail: true,
+ firstLaunch: true,
+ locationCity: storageLocation?.city ?? '鍖椾含甯�',
+ locationProvince: storageLocation?.province ?? '鍖椾含',
+ firstSetLocation: true,
+ };
+ },
+ getters: {
+ cacheRefreshToken: (state) => {
+ return state.refreshToken;
+ },
+
+ accountInfo(): Partial<AccountInfo> {
+ return getAccountInfoFromAccessToken(this.userInfo?.accessToken);
+ },
+
+ userId: (state) => {
+ return state.userDetail?.id ?? '';
+ },
+ },
+ actions: {
+ // 鎵嬫満鍙锋巿鏉僀ode鐧诲綍
+ async getTokenByPhone(
+ detail: ButtonProps.onGetPhoneNumberEventDetail,
+ wxMiniAppUserLoginRes: API.LoginCommandCallback
+ ) {
+ try {
+ let res: API.LoginCommandCallback = wxMiniAppUserLoginRes;
+ if (!wxMiniAppUserLoginRes?.isBindPhoneNumber) {
+ let bindRes = await authServices.bindWxmpUserInfo({
+ encryptedData: detail.encryptedData,
+ iv: detail.iv,
+ sessionKey: wxMiniAppUserLoginRes.sessionKey,
+ accessToken: wxMiniAppUserLoginRes.accessToken,
+ });
+ res.accessToken = bindRes.accessToken;
+ this.loginSuccess(res);
+ }
+ return res;
+ } catch (error) {
+ console.log('error3: ', error);
+ }
+ },
+
+ // 鐢ㄦ埛鎵嬫満楠岃瘉鐮佺櫥鍏�
+ async loginByUsername(data: API.SmsLoginCommand) {
+ let res = await authServices.smsLogin(
+ {
+ phoneNumber: data.phoneNumber,
+ verifyCode: data.verifyCode,
+ type: AppLocalConfig.userType,
+ clientType: AppLocalConfig.clientType,
+ },
+ { showLoading: false }
+ );
+
+ if (res) {
+ this.loginSuccess(res);
+ }
+ return res;
+ },
+
+ // 鐢ㄦ埛璐﹀彿瀵嗙爜鐧诲叆
+ async loginByPassword(params: API.PasswordLoginCommand) {
+ let res = await authServices.passwordLogin(
+ {
+ userName: params.userName,
+ // password: md5Encrypt(params.password),
+ password: params.password,
+ type: AppLocalConfig.userType,
+ clientType: AppLocalConfig.clientType,
+ },
+ { showLoading: false }
+ );
+ if (res) {
+ this.loginSuccess(res);
+ }
+ return res;
+ },
+
+ async loginSuccess(res: API.LoginCommandCallback) {
+ try {
+ this.setUserInfoAction(res);
+ this.setTokenAction(res);
+ await this.getCurrentUserInfo();
+ } catch (error) {}
+ },
+
+ async wxMiniAppUserLoginFromScan(wxIndentityRes: API.WxMiniAppIndentityInfo, uuid: string) {
+ // try {
+ // let res = await accountServices.wxMiniAppUserLoginFromScan({
+ // uId: uuid,
+ // userName: wxIndentityRes.userName,
+ // openId: wxIndentityRes.openId,
+ // });
+ // this.loginSuccess(res);
+ // return res;
+ // } catch (error) {}
+ },
+
+ async wxMiniAppPhoneAuthLoginFromScan(
+ detail: ButtonProps.onGetPhoneNumberEventDetail,
+ wxIndentityRes: API.WxMiniAppIndentityInfo,
+ uuid: string
+ ) {
+ // try {
+ // let res = await accountServices.wxMiniAppPhoneAuthLoginFromScan({
+ // uId: uuid,
+ // openId: wxIndentityRes.openId,
+ // sessionKey: wxIndentityRes.sessionKey,
+ // encryptedData: detail.encryptedData,
+ // iv: detail.iv,
+ // wxMiniApp: WxMiniAppEnum.C绔皬绋嬪簭,
+ // });
+ // this.loginSuccess(res);
+ // return res;
+ // } catch (error) {}
+ },
+
+ async getCurrentUserInfo() {
+ try {
+ let res = await authServices.getPersonalLoginInfo({}, { showLoading: false });
+ if (res) {
+ // res.frontStatus = getUserCertificationFrontStatusAdapter(
+ // res.userCertificationStatus,
+ // res.userCertificationAuditStatus
+ // );
+ res.originalAvatar = res.avatar;
+ res.avatar = res.avatar ? setOSSLink(res.avatar) : DefaultAvatar;
+ this.setUserDetail(res);
+ this.firstGetUserDetail = false;
+ }
+ } catch (error) {}
+ },
+
+ setTokenAction(tokenInfo: API.LoginCommandCallback) {
+ this.token = tokenInfo?.accessToken;
+ this.refreshToken = tokenInfo.refreshToken ?? '';
+ },
+
+ setUserInfoAction(info: API.LoginCommandCallback) {
+ this.userInfo = {
+ ...this.userInfo,
+ ...info,
+ };
+ setUserInfo(this.userInfo);
+ },
+
+ setUserDetail(detail: API.GetPersonalLoginInfoQueryResult) {
+ this.userDetail = detail;
+ setUserDetail(detail);
+ },
+
+ resetState() {
+ this.userInfo = null;
+ this.token = '';
+ this.refreshToken = '';
+ this.userDetail = null;
+ removeUserInfo();
+ removeUserDetail();
+ },
+
+ /**
+ * @description: logout
+ */
+ logout() {
+ this.resetState();
+ // myClient.removeQueries();
+ goAuthorization();
+ },
+
+ logoutAndToHome() {
+ this.resetState();
+ goHome();
+ },
+
+ toLoginPage(targetUrl?: string) {
+ // 瀛� 鐧诲綍鍚庤烦杞洰鏍囬〉
+ if (targetUrl) {
+ // tabbar 璺宠浆锛氫笉鏄湪鍏蜂綋椤甸潰鍒ゆ柇鐢ㄦ埛鏄惁鐧诲綍
+ } else {
+ // 椤甸潰閲� 璺宠浆鐧诲綍椤� 瀛樺綋鍓嶉〉闈㈣矾寰� 宸蹭緵鐧婚檰鍚�
+ const currentPage = useRouter();
+
+ // const params = omit(currentPage.params, '$taroTimestamp');
+
+ console.log(currentPage.params);
+
+ // 鐩存帴鐢╟urrentPage.path锛宲arams 浼氫涪澶�
+
+ Taro.redirectTo({
+ url: `/packageLogin/authLogin/index`,
+ });
+ }
+ },
+
+ setLocationCity(cityName: string, provinceName: string) {
+ this.locationCity = cityName;
+ this.locationProvince = provinceName;
+ this.firstSetLocation = false;
+ setStorageLocationCity({ city: cityName, province: provinceName });
+ // if (LocationUtils.isProvinceChange(provinceName)) {
+ // this.resetState();
+ // myClient.removeQueries();
+ // globalEventEmitter.trigger('logout/refresh');
+ // }
+ LocationUtils.currentProvinceName = provinceName;
+ },
+
+ setFirstLaunch(firstLaunch: boolean) {
+ this.firstLaunch = firstLaunch;
+ },
+ },
+});
+
+// Need to be used outside the setup
+export function useUserStoreWithOut() {
+ return useUserStore(store);
+}
diff --git a/apps/housekeepingMiniApp/src/styles/common.scss b/apps/housekeepingMiniApp/src/styles/common.scss
new file mode 100644
index 0000000..fd7aff2
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/common.scss
@@ -0,0 +1,6 @@
+@forward './custom_theme.scss';
+@forward './var.scss';
+@forward './function.scss';
+@forward './hairline.scss';
+@forward './mixins.scss';
+@forward 'sass:map';
diff --git a/apps/housekeepingMiniApp/src/styles/config.scss b/apps/housekeepingMiniApp/src/styles/config.scss
new file mode 100644
index 0000000..000f822
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/config.scss
@@ -0,0 +1,5 @@
+$bole-namespace: 'bole' !default;
+$bole-separator: '-' !default;
+$bole-element-separator: '__' !default;
+$bole-modifier-separator: '--' !default;
+$bole-state-prefix: 'is-' !default;
diff --git a/apps/housekeepingMiniApp/src/styles/custom_theme.scss b/apps/housekeepingMiniApp/src/styles/custom_theme.scss
new file mode 100644
index 0000000..b2641aa
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/custom_theme.scss
@@ -0,0 +1,11 @@
+$primary-color: #3a71ff;
+$primary-color-end: #496af2;
+
+$form-item-error-line-color: #fa2c19;
+$form-item-required-color: #fa2c19;
+$form-item-error-message-color: #fa2c19;
+
+$button-border-width: 0;
+
+$button-primary-background-color: $primary-color;
+$body-background-color: #f9f9fb;
diff --git a/apps/housekeepingMiniApp/src/styles/font.scss b/apps/housekeepingMiniApp/src/styles/font.scss
new file mode 100644
index 0000000..fe9117f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/font.scss
@@ -0,0 +1,7 @@
+@font-face {
+ font-family: D-DIN; /* Project id 4331987 */
+ src: url('../assets/font/D-DIN.otf') format('otf');
+ // url('@/assets/font/D-DIN') format('otf');
+ // url('iconfont.woff?t=1700036113989') format('woff'),
+ // url('iconfont.ttf?t=1700036113989') format('truetype');
+}
diff --git a/apps/housekeepingMiniApp/src/styles/function.scss b/apps/housekeepingMiniApp/src/styles/function.scss
new file mode 100644
index 0000000..28aa575
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/function.scss
@@ -0,0 +1,78 @@
+/* stylelint-disable */
+@use 'sass:map';
+@use './config.scss';
+
+@mixin bole-set-css-var-value($name, $value) {
+ #{boleJoinVarName($name)}: #{$value};
+}
+
+@function boleJoinVarName($list) {
+ $name: '--' + config.$bole-namespace;
+
+ @each $item in $list {
+ @if $item != '' {
+ $name: $name + '-' + $item;
+ }
+ }
+
+ @return $name;
+}
+
+// getCssVar('button', 'text-color') => var(--bole-button-text-color)
+@function boleGetCssVar($args...) {
+ @return var(#{boleJoinVarName($args)});
+}
+
+// getCssVarName('button', 'text-color') => '--bole-button-text-color'
+@function boleGetCssVarName($args...) {
+ @return boleJoinVarName($args);
+}
+
+// getCssVarWithDefault(('button', 'text-color'), red) => var(--el-button-text-color, red)
+@function boleGetCssVarWithDefault($args, $default) {
+ @return var(#{boleJoinVarName($args)}, #{$default});
+}
+
+// set all css var for component by map
+@mixin bole-set-component-css-var($name, $variables) {
+ @each $attribute, $value in $variables {
+ @if $attribute == 'default' {
+ #{boleGetCssVarName($name)}: #{$value};
+ } @else {
+ #{boleGetCssVarName($name, $attribute)}: #{$value};
+ }
+ }
+}
+
+// bem('block', 'element', 'modifier') => 'el-block__element--modifier'
+@function bem($block, $element: '', $modifier: '') {
+ $name: config.$bole-namespace + config.$bole-separator + $block;
+
+ @if $element != '' {
+ $name: $name + config.$bole-element-separator + $element;
+ }
+
+ @if $modifier != '' {
+ $name: $name + config.$bole-modifier-separator + $modifier;
+ }
+
+ // @debug $name;
+ @return $name;
+}
+
+@mixin bole-set-css-color-type($colors, $type) {
+ @include bole-set-css-var-value(('color', $type), map.get($colors, $type, 'base'));
+
+ @each $i in (3, 5, 7, 8, 9) {
+ @include bole-set-css-var-value(
+ ('color', $type, 'light', $i),
+ map.get($colors, $type, 'light-#{$i}')
+ );
+ }
+
+ @include bole-set-css-var-value(('color', $type, 'dark-2'), map.get($colors, $type, 'dark-2'));
+}
+
+@function mapGet($args1, $args2) {
+ @return map.get($args1, $args2);
+}
diff --git a/apps/housekeepingMiniApp/src/styles/hairline.scss b/apps/housekeepingMiniApp/src/styles/hairline.scss
new file mode 100644
index 0000000..474efba
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/hairline.scss
@@ -0,0 +1,200 @@
+$color-border-light: #eaeaea;
+
+@mixin hairline-common() {
+ content: '';
+ position: absolute;
+ transform-origin: center;
+ box-sizing: border-box;
+ pointer-events: none;
+}
+
+@mixin hairline() {
+ @include hairline-common();
+ top: -50%;
+ right: -50%;
+ bottom: -50%;
+ left: -50%;
+ border: 0 solid $color-border-light;
+ transform: scale(0.5);
+}
+
+@mixin hairline-base($color: $color-border-light, $style: solid) {
+ @include hairline-common();
+
+ top: -50%;
+ left: -50%;
+ right: -50%;
+ bottom: -50%;
+ border: 0 $style $color;
+ transform: scale(0.5);
+}
+
+@mixin hairline-surround($color: $color-border-light, $style: solid, $width: 1px) {
+ position: relative;
+
+ &::after {
+ @include hairline-base($color, $style);
+
+ border-width: $width;
+ }
+}
+
+@mixin hairline-top($color: $color-border-light, $style: solid, $width: 1px) {
+ position: relative;
+
+ &::after {
+ @include hairline-base($color, $style);
+
+ border-top-width: $width;
+ }
+}
+
+@mixin hairline-bottom($color: $color-border-light, $style: solid, $width: 1px) {
+ position: relative;
+
+ &::after {
+ @include hairline-base($color, $style);
+
+ border-bottom-width: $width;
+ }
+}
+
+@mixin hairline-left($color: $color-border-light, $style: solid, $width: 1px) {
+ position: relative;
+
+ &::after {
+ @include hairline-base($color, $style);
+
+ border-left-width: $width;
+ }
+}
+
+@mixin hairline-right($color: $color-border-light, $style: solid, $width: 1px) {
+ position: relative;
+
+ &::after {
+ @include hairline-base($color, $style);
+
+ border-right-width: $width;
+ }
+}
+
+@mixin hairline-top-bottom($color: $color-border-light, $style: solid, $width: 1px) {
+ position: relative;
+
+ &::after {
+ @include hairline-base($color, $style);
+
+ border-top-width: $width;
+ border-bottom-width: $width;
+ }
+}
+
+@mixin hairline-bottom-relative($color: $color-border-light, $style: solid, $width: 1px, $left: 0) {
+ position: relative;
+
+ &::after {
+ @include hairline-common();
+
+ top: auto;
+ left: $left;
+ right: 0;
+ bottom: 0;
+ transform: scaleY(0.5);
+ border-bottom: $width $style $color;
+ }
+}
+
+@mixin hairline-top-relative($color: $color-border-light, $style: solid, $width: 1px, $left: 0) {
+ position: relative;
+
+ &::before {
+ @include hairline-common();
+
+ top: 0;
+ left: $left;
+ right: 0;
+ bottom: auto;
+ transform: scaleY(0.5);
+ border-top: $width $style $color;
+ }
+}
+
+@mixin hairline-left-relative($color: $color-border-light, $style: solid, $width: 1px, $top: 0) {
+ position: relative;
+
+ &::after {
+ @include hairline-common();
+
+ top: $top;
+ left: 0;
+ right: auto;
+ bottom: 0;
+ transform: scaleX(0.5);
+ border-left: $width $style $color;
+ }
+}
+
+@mixin hairline-right-relative($color: $color-border-light, $style: solid, $width: 1px, $top: 0) {
+ position: relative;
+
+ &::after {
+ @include hairline-common();
+
+ top: $top;
+ left: auto;
+ right: 0;
+ bottom: 0;
+ transform: scaleX(0.5);
+ border-right: $width $style $color;
+ }
+}
+
+.van-hairline--bottom {
+ @include hairline-bottom(#ddd, 0, 0);
+}
+
+[class*='van-hairline'] {
+ &::after {
+ @include hairline();
+ }
+}
+
+.van-hairline {
+ &,
+ &--top,
+ &--left,
+ &--right,
+ &--bottom,
+ &--surround,
+ &--top-bottom {
+ position: relative;
+ }
+
+ &--top::after {
+ border-top-width: 1px;
+ }
+
+ &--left::after {
+ border-left-width: 1px;
+ }
+
+ &--right::after {
+ border-right-width: 1px;
+ }
+
+ &--bottom::after {
+ border-bottom-width: 1px;
+ }
+
+ &,
+ &-unset {
+ &--top-bottom::after {
+ border-width: 1px 0;
+ }
+ }
+
+ &--surround::after {
+ border-width: 1px;
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/styles/index.scss b/apps/housekeepingMiniApp/src/styles/index.scss
new file mode 100644
index 0000000..9b655fc
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/index.scss
@@ -0,0 +1,83 @@
+@use './var.scss' as *;
+@use './function.scss' as *;
+@use './reset.scss' as *;
+@use './nut.scss' as *;
+@use './mixins.scss' as *;
+@use './font.scss' as *;
+@use 'sass:map';
+@use 'senin-mini/dist/styles/index.scss' as *;
+
+:root,
+page {
+ @include bole-set-component-css-var('color', $bole-colors);
+ @include bole-set-component-css-var('text-color', $bole-text-color);
+ @include bole-set-component-css-var('size', $bole-size);
+ background-color: map-get($bole-colors, 'body-background-color');
+
+ font-family: Source Han Sans CN, 'PingFang SC', 'miui', 'Microsoft Yahei', BlinkMacSystemFont,
+ 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'Hiragino Sans GB', sans-serif;
+
+ --primary-color: #{map-get($bole-colors, 'primary')};
+ overflow: hidden;
+
+ --nut-primary-color: #{map-get($bole-colors, 'primary')};
+ --nut-primary-color-end: $primary-color-end;
+
+ --nut-tag-success-background-color: #d0f8e2;
+ --nut-tag-danger-background-color: #ffe5e5;
+
+ --nut-badge-background-color: #{map-get($bole-colors, 'danger')};
+}
+
+.clearfix:after {
+ content: '';
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+.clearfix {
+ /* 瑙﹀彂 hasLayout */
+ zoom: 1;
+}
+
+// 瑙e喅iPhone x 浠ュ悗鐨勬満鍨� 搴曢儴瀹夊叏鍖哄煙鐨勯棶棰� https://jelly.jd.com/article/6006b1055b6c6a01506c87fd
+.safe-area-bottom {
+ padding-bottom: constant(safe-area-inset-bottom);
+ padding-bottom: env(safe-area-inset-bottom);
+}
+
+.primary {
+ color: boleGetCssVar('color', 'primary');
+}
+
+.warning {
+ color: boleGetCssVar('color', 'warning');
+}
+
+.danger {
+ color: boleGetCssVar('color', 'danger');
+}
+
+.success {
+ color: boleGetCssVar('color', 'success');
+}
+
+.common-infinite-scroll-list-no-padding {
+ @include listScrollViewWithNoPadding;
+}
+
+.common-infinite-scroll-list {
+ @include listScrollView;
+}
+
+.common-page-infinite-scroll-list {
+ @include listScrollView;
+ padding-top: 16px;
+}
+
+.id-imgUrl-wrapper {
+ display: flex;
+ gap: 40px;
+}
diff --git a/apps/housekeepingMiniApp/src/styles/mixins.scss b/apps/housekeepingMiniApp/src/styles/mixins.scss
new file mode 100644
index 0000000..a883f74
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/mixins.scss
@@ -0,0 +1,76 @@
+@use './var.scss' as *;
+
+@mixin multi-ellipsis($lines) {
+ display: -webkit-box;
+
+ overflow: hidden;
+ text-overflow: ellipsis;
+ -webkit-line-clamp: $lines;
+ -webkit-box-orient: vertical;
+}
+
+@mixin ellipsis() {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.ellipsis {
+ @include ellipsis();
+}
+
+.multi-ellipsis--l2 {
+ @include multi-ellipsis(2);
+}
+
+.multi-ellipsis--l3 {
+ @include multi-ellipsis(3);
+}
+
+.multi-ellipsis--l9 {
+ @include multi-ellipsis(9);
+}
+
+@mixin infiniteLoadingInTabBarPage {
+ .loading-more-tips,
+ .infiniting-tips {
+ padding-bottom: 40px;
+ }
+}
+
+@mixin safe-area-bottom() {
+ padding-bottom: constant(safe-area-inset-bottom);
+ padding-bottom: env(safe-area-inset-bottom);
+}
+
+@mixin listScrollViewWithNoPadding {
+ flex: 1;
+ min-height: 0;
+ box-sizing: border-box;
+}
+
+@mixin listScrollView {
+ padding: 0 map-get($bole-size, 'body-padding-h');
+ @include listScrollViewWithNoPadding;
+}
+
+@mixin infiniteLoadingInTabBarPage {
+ .loading-more-tips,
+ .infiniting-tips {
+ padding-bottom: 50px;
+ }
+}
+
+@mixin ScrollViewInner {
+ // padding: 20px 0;
+ padding-bottom: 24px;
+}
+
+@mixin hiddenScrollBar {
+ ::-webkit-scrollbar {
+ display: none;
+ width: 0;
+ height: 0;
+ color: transparent;
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/styles/nut.scss b/apps/housekeepingMiniApp/src/styles/nut.scss
new file mode 100644
index 0000000..ee5295d
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/nut.scss
@@ -0,0 +1,170 @@
+@use './function.scss' as *;
+@use './hairline.scss' as *;
+
+:root,
+page {
+ .category-searchbar-container {
+ padding: 30px;
+ }
+
+ .h5-view.nut-popup.nut-popup--bottom {
+ padding-bottom: constant(safe-area-inset-bottom);
+ padding-bottom: env(safe-area-inset-bottom);
+ }
+
+ .nut-button.dark-btn {
+ color: boleGetCssVar('text-color', 'primary') !important;
+ }
+
+ .nut-form {
+ .nut-cell-group__wrap {
+ margin-top: 0;
+ border-radius: 0;
+ }
+
+ .nut-cell.bole-form-item {
+ --nut-form-item-label-width: 120px;
+ &:not(.alignTop) {
+ align-items: center !important;
+ }
+
+ &.labelTop {
+ display: block;
+ }
+
+ padding: 30rpx;
+
+ &::after {
+ border-bottom: 1px solid #f0f0f0;
+ left: 30rpx;
+ right: 30rpx;
+ display: none;
+ }
+
+ .nut-form-item__body__tips {
+ position: absolute;
+ bottom: 0;
+ }
+ &:not(.bole-form-item-phone) {
+ .nut-form-item__body__tips {
+ right: 30rpx;
+ }
+ }
+
+ .nut-form-item__label {
+ font-size: 28rpx;
+ color: boleGetCssVar('text-color', 'primary');
+ }
+
+ &.vertical {
+ flex-direction: column;
+ align-items: flex-start !important;
+ }
+
+ .nut-form-item__label.required::before {
+ position: absolute;
+ left: 12rpx;
+ }
+
+ .nut-radio-group--horizontal {
+ .nut-radio {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ }
+
+ .nut-rate {
+ vertical-align: middle;
+ }
+
+ &.hidden-label {
+ .nut-form-item__label {
+ opacity: 0;
+ }
+ }
+
+ .bole-uploader {
+ padding-top: 16rpx;
+
+ &.nopaddingtop {
+ padding-top: 0;
+ }
+ }
+ }
+
+ .bole-form-item-phone {
+ padding: 24rpx 30rpx;
+ }
+
+ .nut-uploader {
+ // justify-content: flex-end;
+ }
+
+ .nut-form-item__top {
+ .nut-form-item__label {
+ margin-right: 0;
+ }
+
+ .nut-form-item__body {
+ width: 100%;
+ }
+ }
+ }
+
+ .bole-input-text:not(.nut-input--disabled) {
+ .h5-input {
+ color: boleGetCssVar('text-color', 'primary') !important;
+ display: block;
+ font-size: 26rpx;
+ }
+
+ .input-placeholder {
+ color: boleGetCssVar('text-color', 'placeholder') !important;
+ font-size: 26rpx;
+ }
+ }
+
+ .bole-input-textarea:not(.nut-input--disabled) {
+ color: boleGetCssVar('text-color', 'primary') !important;
+ height: 100rpx;
+ }
+
+ .bole-input-text-placeholder {
+ color: boleGetCssVar('text-color', 'placeholder') !important;
+ font-size: 26rpx;
+ line-height: 20rpx;
+ }
+
+ .form-item-divider {
+ margin: 0 28px;
+ width: calc(100% - 56px);
+ color: #f0f0f0;
+ }
+
+ // .nut-overlay {
+ // z-index: 20022221 !important;
+ // }
+
+ // .nut-popup {
+ // z-index: 2222222222 !important;
+ // }
+
+ .nut-tabs__titles-item__smile {
+ // display: none;
+ opacity: 0;
+ transition: width 0.3s ease;
+ }
+
+ .nut-tabs__titles.smile .nut-tabs__titles-item.active .nut-tabs__titles-item__smile {
+ // display: block;
+ opacity: 1;
+ }
+
+ .nut-toast {
+ z-index: 99999999999;
+ }
+
+ .pro-form-item-tips {
+ word-break: break-all;
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/styles/reset.scss b/apps/housekeepingMiniApp/src/styles/reset.scss
new file mode 100644
index 0000000..98ca895
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/reset.scss
@@ -0,0 +1,30 @@
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+strong,
+p,
+ul,
+input,
+i,
+b,
+em,
+li,
+ol,
+dl,
+dd,
+page {
+ font: 32px Source Han Sans CN;
+ font-family: Source Han Sans CN, 'PingFang SC', 'miui', 'Microsoft Yahei', BlinkMacSystemFont,
+ 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'Hiragino Sans GB', sans-serif;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+img {
+ border: none;
+ display: block;
+}
diff --git a/apps/housekeepingMiniApp/src/styles/var.scss b/apps/housekeepingMiniApp/src/styles/var.scss
new file mode 100644
index 0000000..400367a
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/styles/var.scss
@@ -0,0 +1,35 @@
+@use './custom_theme.scss' as *;
+@use 'sass:map';
+@use 'sass:math';
+
+$bole-colors: () !default;
+$bole-colors: map.deep-merge(
+ (
+ 'primary': $primary-color,
+ 'body-background-color': $body-background-color,
+ 'title-color': #444444,
+ 'shadow-color': rgba(0, 0, 0, 0.15),
+ 'warning': #ff7d00,
+ 'danger': #fe3333,
+ 'success': #31b573,
+ 'info': #e9e8e8,
+ ),
+ $bole-colors
+);
+
+$bole-text-color: (
+ 'primary': #1d2129,
+ 'regular': #4e5969,
+ 'secondary': #9fa4ac,
+ 'placeholder': #cbcbcb,
+);
+
+$bole-size: () !default;
+$bole-size: map.deep-merge(
+ (
+ 'body-padding-h': 28px,
+ ),
+ $bole-size
+);
+
+$base-footer-box-shadow: 0px -10px 40px 0px map-get($bole-colors, 'shadow-color');
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/InnerPage.vue
new file mode 100644
index 0000000..00859ee
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/InnerPage.vue
@@ -0,0 +1,216 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <!-- <nut-form :model-value="form" ref="formRef" :rules="rules">
+ <nut-form-item label="钀ヤ笟鎵х収:" class="bole-form-item alignTop" prop="licenseUrl" required>
+ <Uploader
+ v-model:file-list="form.licenseUrl"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ @my-success="handleLicenseUrlChange"
+ >
+ </Uploader>
+ <div class="pro-form-item-tips">
+ 璇蜂笂浼犳渶鏂扮殑钀ヤ笟鎵х収鍘熶欢鐓х墖銆佹壂鎻忎欢鎴栧姞鐩栧叕绔犵殑澶嶅嵃浠讹紝鏀寔png/jpg/jpeg鏍煎紡锛屾枃浠跺ぇ灏忎笉瓒呰繃10MB
+ </div>
+ </nut-form-item>
+ <nut-form-item label="浼佷笟鍏ㄧО:" class="bole-form-item" prop="enterpriseName" required>
+ <nut-input
+ v-model.trim="form.enterpriseName"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ユ偍钀ヤ笟鎵х収涓婄殑浼佷笟鍚嶇О"
+ type="text"
+ :max-length="35"
+ />
+ </nut-form-item>
+ <nut-form-item
+ label="缁熶竴绀句細淇$敤浠g爜:"
+ class="bole-form-item"
+ prop="societyCreditCode"
+ required
+ >
+ <nut-input
+ v-model.trim="form.societyCreditCode"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ユ偍钀ヤ笟鎵х収涓婄殑淇$敤浠g爜"
+ type="text"
+ />
+ </nut-form-item>
+ <ProFormItemCell label="娉曚汉韬唤璇佺収鐗�:" required>
+ <div class="id-imgUrl-wrapper">
+ <nut-form-item
+ label=" "
+ class="bole-form-item"
+ prop="legalPersonIdFrontImgUrl"
+ label-width="0px"
+ >
+ <Uploader
+ v-model:file-list="form.legalPersonIdFrontImgUrl"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ @my-success="handleFrontImgUrlChange"
+ >
+ <template #upload-icon>
+ <div class="photograph-wrapper">
+ <Photograph color="#808080" />
+ <div>韬唤璇佷汉鍍忛潰</div>
+ </div>
+ </template>
+ </Uploader>
+ </nut-form-item>
+ <nut-form-item
+ label=" "
+ class="bole-form-item"
+ prop="legalPersonIdBackImgUrl"
+ label-width="0px"
+ >
+ <Uploader
+ v-model:file-list="form.legalPersonIdBackImgUrl"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ >
+ <template #upload-icon>
+ <div class="photograph-wrapper">
+ <Photograph color="#808080" />
+ <div>韬唤璇佸浗寰介潰</div>
+ </div>
+ </template>
+ </Uploader>
+ </nut-form-item>
+ </div>
+
+ <div class="pro-form-item-tips">
+ 璇蜂笂浼犳硶浜鸿韩浠借瘉鐨勬鍙嶉潰鐓х墖锛岀‘淇濊韩浠借瘉娓呮櫚鍙锛屾敮鎸乸ng/jpg/jpeg鏍煎紡锛屾枃浠跺ぇ灏忎笉瓒呰繃10MB
+ </div>
+ </ProFormItemCell>
+ <nut-form-item label="娉曚汉濮撳悕:" class="bole-form-item" prop="legalPersonName" required>
+ <nut-input
+ v-model.trim="form.legalPersonName"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欎紒涓氭硶浜虹殑濮撳悕"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item
+ label="娉曚汉韬唤璇佸彿:"
+ class="bole-form-item"
+ prop="legalPersonIdNumber"
+ required
+ >
+ <nut-input
+ v-model.trim="form.legalPersonIdNumber"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欎紒涓氭硶浜虹殑韬唤璇佸彿鐮�"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item
+ label="娉曚汉鎵嬫満鍙�:"
+ class="bole-form-item"
+ prop="legalPersonContactPhone"
+ required
+ >
+ <nut-input
+ v-model.trim="form.legalPersonContactPhone"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欎紒涓氭硶浜虹殑鎵嬫満鍙风爜"
+ type="text"
+ >
+ <template #right>
+ <ProFormCaptcha
+ :onGetCaptcha="() => onGetCaptcha(form.legalPersonContactPhone)"
+ :phonePropName="['legalPersonContactPhone', 'legalPersonName', 'legalPersonIdNumber']"
+ :validateField="formRef?.validate"
+ ></ProFormCaptcha>
+ </template>
+ </nut-input>
+ </nut-form-item>
+ <nut-form-item label="鐭俊楠岃瘉鐮�:" class="bole-form-item" prop="verificationCode" required>
+ <nut-input
+ v-model.trim="form.verificationCode"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ラ獙璇佺爜"
+ type="number"
+ />
+ </nut-form-item>
+ </nut-form> -->
+ </ContentScrollView>
+ <PageFooter :isOnlyAction="false">
+ <!-- <PageFooterBtn type="primary" @click="handleSubmit()" :loading="loading"
+ >鎻愪氦璁よ瘉</PageFooterBtn
+ > -->
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+// import { useAuthenticationFlow } from '../hooks';
+import {
+ UserCertificationModeEnumV2,
+ VerificationCodeBusinessType,
+ UserCertificationElementEnum,
+} from '@12333/constants';
+import { ProFormCaptcha, ProFormItemCell } from 'senin-mini/components';
+import * as commonServices from '@12333/services/api/Common';
+import { FileItem } from '@nutui/nutui-taro/dist/types/__VUE/uploader/type';
+import { vatLicense } from '@12333/hooks';
+import { Message } from '@12333/utils';
+import { Photograph } from '@nutui/icons-vue-taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+// const { form, rules, formRef, handleSubmit, loading } = useAuthenticationFlow({
+// certificationMode: UserCertificationModeEnumV2.LegalPersonPhoneCertification,
+// certificationElement: UserCertificationElementEnum.Identity4,
+// });
+
+// async function onGetCaptcha(phoneNumber: string) {
+// await commonServices.sendPhoneCertificationVerificationCode(
+// {
+// name: form.legalPersonName,
+// identity: form.legalPersonIdNumber,
+// mobile: form.legalPersonContactPhone,
+// businessType: VerificationCodeBusinessType.UserCertificationPhoneCertification,
+// },
+// { showLoading: false }
+// );
+// }
+
+// const handleLicenseUrlChange = (response: FileItem) => {
+// vatLicense(response, {
+// onSuccess(res) {
+// let tips: string[] = [];
+// res?.name ? (form.enterpriseName = res.name) : tips.push('浼佷笟鍚嶇О');
+// res?.societyCode ? (form.societyCreditCode = res.societyCode) : tips.push('缁熶竴绀句細淇$敤浠g爜');
+// if (tips.length > 0) {
+// Message.error(`鏈兘璇嗗埆鍒版偍涓婁紶鐨勫浘鐗囷紝璇烽噸鏂颁笂浼犳竻鏅扮殑鍥剧墖鎴栨墜鍔ㄨ緭鍏�${tips.join('鍜�')}`);
+// }
+// },
+// });
+// };
+
+function handleFrontImgUrlChange(response: FileItem) {
+ // userCredentialVerifyOcrIDCard(response, {
+ // onSuccess(res) {
+ // if (res.realName) form.legalPersonName = res.realName;
+ // if (res.idcardNum) form.legalPersonIdNumber = res.idcardNum;
+ // },
+ // });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authenticationFaRen-page-wrapper {
+ .photograph-wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.config.ts b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.vue
new file mode 100644
index 0000000..439f4b2
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFaRen/authenticationFaRen.vue
@@ -0,0 +1,14 @@
+<template>
+ <PageLayout title="浼佷笟娉曚汉璁よ瘉" class="authenticationFaRen-page-wrapper" hasBorder developing>
+ <InnerPage />
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'authenticationFaRen',
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/InnerPage.vue
new file mode 100644
index 0000000..6c414e3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/InnerPage.vue
@@ -0,0 +1,41 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <nut-form :model-value="form" ref="formRef">
+ <nut-form-item label="鍒疯劯:" class="bole-form-item alignTop" prop="licenseUrl" required>
+ </nut-form-item>
+ </nut-form>
+ </ContentScrollView>
+ <PageFooter :isOnlyAction="false">
+ <PageFooterBtn type="primary" @click="handleSubmit()" :loading="loading"
+ >鍒疯劯璁よ瘉</PageFooterBtn
+ >
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const form = reactive({
+ licenseUrl: [],
+});
+
+const formRef = ref<any>(null);
+const loading = ref(false);
+
+function handleSubmit() {
+ if (!formRef.value) return;
+ formRef.value.validate().then(({ valid, errors }: any) => {
+ if (valid) {
+ // submit();
+ }
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.config.ts b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.vue
new file mode 100644
index 0000000..2e507b1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationFace/authenticationFace.vue
@@ -0,0 +1,14 @@
+<template>
+ <PageLayout title="瀹炰汉璁よ瘉" class="authenticationFace-page-wrapper" hasBorder developing>
+ <InnerPage />
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'authenticationFace',
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/InnerPage.vue
new file mode 100644
index 0000000..4f8be7b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/InnerPage.vue
@@ -0,0 +1,69 @@
+<template>
+ <ContentScrollView class="authenticationHome-page-view">
+ <div class="authenticationHome-page-title">瀹炲悕璁よ瘉</div>
+ <authenticationHomeItem
+ title="涓汉瀹炲悕璁よ瘉"
+ :icon="IconFaren"
+ :info="[['韬唤璇佺収鐗�'], ['鎵嬫満鍙风爜(鎺ユ敹鐭俊楠岃瘉鐮佽繘琛岀煭淇℃牳楠�)']]"
+ @click="goRealName('realName')"
+ ></authenticationHomeItem>
+ <authenticationHomeItem
+ title="瀹炰汉璁よ瘉"
+ isJBR
+ :icon="IconJBR"
+ :info="[['瀹炰汉鎵劯璁よ瘉']]"
+ @click="goFace('face')"
+ >
+ </authenticationHomeItem>
+ </ContentScrollView>
+</template>
+
+<script setup lang="ts">
+import authenticationHomeItem from './authenticationHomeItem.vue';
+import IconFaren from '@/assets/authentication/icon-faren.png';
+import IconJBR from '@/assets/authentication/icon-jbr.png';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+function goRealName(type: string) {
+ Taro.navigateTo({ url: `${RouterPath.authenticationRealName}?type=${type}` });
+}
+
+function goFace(type: string) {
+ Taro.navigateTo({ url: `${RouterPath.authenticationRealName}?type=${type}` });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authenticationHome-page-wrapper {
+ .authenticationHome-page-view {
+ padding-top: 48px;
+ background-color: transparent;
+
+ .authentication-home-item-info {
+ flex-direction: column;
+ }
+ }
+
+ .authenticationHome-page-title {
+ font-weight: 600;
+ font-size: 44px;
+ color: #2f4879;
+ line-height: 60px;
+ margin-bottom: 44px;
+ }
+
+ .authenticationHome-page-title-btn {
+ font-weight: bold;
+ font-size: 24px;
+ color: boleGetCssVar('color', 'primary');
+ line-height: 34px;
+ margin-left: 24px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.config.ts b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.vue
new file mode 100644
index 0000000..ac39fb5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHome.vue
@@ -0,0 +1,35 @@
+<template>
+ <PageLayout class="authenticationHome-page-wrapper">
+ <template #navigationBar>
+ <TransparentNavigationBar title="瀹炲悕璁よ瘉" :is-absolute="false"></TransparentNavigationBar>
+ </template>
+ <template #bg>
+ <img :src="OssAssets.authentication.AuthenticationBg" class="authenticationHome-page-bg" />
+ </template>
+ <InnerPage />
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import { OssAssets } from '@12333/constants';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'authenticationHome',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authenticationHome-page-bg {
+ position: fixed;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHomeItem.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHomeItem.vue
new file mode 100644
index 0000000..450e8e3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationHome/authenticationHomeItem.vue
@@ -0,0 +1,159 @@
+<template>
+ <div :class="['authentication-home-item', { isJBR }]">
+ <div class="authentication-home-item-top">
+ <img class="authentication-home-item-icon" :src="icon" />
+ <div class="authentication-home-item-title-wrapper">
+ <div class="authentication-home-item-title">
+ <div class="authentication-home-item-title-text">
+ {{ title }}
+ </div>
+ <slot name="title-extra"></slot>
+ </div>
+ <div class="authentication-home-item-subtitle">鎮ㄩ渶瑕佸噯澶�</div>
+ </div>
+ <img :src="IconArrow" alt="" class="authentication-home-item-arrow" />
+ </div>
+ <div class="authentication-home-item-info">
+ <div class="authentication-home-item-info-row" v-for="(infoItem, index) in info" :key="index">
+ <div class="authentication-home-item-info-item" v-for="(item, i) in infoItem" :key="i">
+ <div class="authentication-home-item-info-item-dot"></div>
+ <div class="authentication-home-item-info-item-text">{{ item }}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import IconArrow from '@/assets/authentication/icon-arrow.png';
+
+defineOptions({
+ name: 'authenticationHomeItem',
+});
+
+type Props = {
+ title?: string;
+ isJBR?: boolean;
+ icon?: string;
+ info?: string[][];
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ info: () => [],
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authentication-home-item {
+ background-color: #fff;
+ padding: 36px 24px 32px;
+ border-radius: 32px;
+ position: relative;
+ z-index: 1;
+ margin-bottom: 32px;
+
+ &::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 80px;
+ background: linear-gradient(180deg, #eff6ff 0%, rgba(239, 246, 255, 0) 100%);
+ border-radius: 30px 30px 0px 0px;
+ z-index: -1;
+ }
+
+ &.isJBR {
+ &::before {
+ background: linear-gradient(180deg, #fff7f7 0%, rgba(255, 247, 247, 0) 100%);
+ }
+ }
+
+ .authentication-home-item-top {
+ display: flex;
+ align-items: center;
+ margin-bottom: 40px;
+
+ .authentication-home-item-icon {
+ width: 72px;
+ height: 72px;
+ margin-right: 16px;
+ }
+
+ .authentication-home-item-title-wrapper {
+ flex: 1;
+ min-width: 0;
+
+ .authentication-home-item-title {
+ font-weight: 600;
+ font-size: 32px;
+ line-height: 44px;
+ display: flex;
+ align-items: center;
+
+ .authentication-home-item-title-text {
+ color: boleGetCssVar('text-color', 'primary');
+ }
+ }
+
+ .authentication-home-item-subtitle {
+ font-weight: 400;
+ font-size: 24px;
+ color: boleGetCssVar('text-color', 'regular');
+ line-height: 34px;
+ }
+ }
+
+ .authentication-home-item-arrow {
+ width: 32px;
+ height: 32px;
+ }
+ }
+
+ .authentication-home-item-info {
+ background: #f9fbff;
+ border-radius: 8px;
+ padding: 24px;
+ display: flex;
+ flex-wrap: wrap;
+
+ .authentication-home-item-info-row {
+ display: flex;
+ align-items: center;
+ margin-bottom: 16px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .authentication-home-item-info-item {
+ display: flex;
+ align-items: center;
+ margin-right: 24px;
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ .authentication-home-item-info-item-dot {
+ width: 8px;
+ height: 8px;
+ background: #7bb0f6;
+ border-radius: 50%;
+ margin-right: 16px;
+ }
+
+ .authentication-home-item-info-item-text {
+ font-weight: 400;
+ font-size: 24px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 34px;
+ }
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/InnerPage.vue
new file mode 100644
index 0000000..be2f9bb
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/InnerPage.vue
@@ -0,0 +1,244 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <!-- <nut-form :model-value="form" ref="formRef" :rules="rules">
+ <nut-form-item label="钀ヤ笟鎵х収:" class="bole-form-item alignTop" prop="licenseUrl" required>
+ <Uploader
+ v-model:file-list="form.licenseUrl"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ @my-success="handleLicenseUrlChange"
+ >
+ </Uploader>
+ <div class="pro-form-item-tips">
+ 璇蜂笂浼犳渶鏂扮殑钀ヤ笟鎵х収鍘熶欢鐓х墖銆佹壂鎻忎欢鎴栧姞鐩栧叕绔犵殑澶嶅嵃浠讹紝鏀寔png/jpg/jpeg鏍煎紡锛屾枃浠跺ぇ灏忎笉瓒呰繃10MB
+ </div>
+ </nut-form-item>
+ <nut-form-item label="浼佷笟鍏ㄧО:" class="bole-form-item" prop="enterpriseName" required>
+ <nut-input
+ v-model.trim="form.enterpriseName"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ユ偍钀ヤ笟鎵х収涓婄殑浼佷笟鍚嶇О"
+ type="text"
+ :max-length="35"
+ />
+ </nut-form-item>
+ <nut-form-item
+ label="缁熶竴绀句細淇$敤浠g爜:"
+ class="bole-form-item"
+ prop="societyCreditCode"
+ required
+ >
+ <nut-input
+ v-model.trim="form.societyCreditCode"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ユ偍钀ヤ笟鎵х収涓婄殑淇$敤浠g爜"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item label="娉曚汉濮撳悕:" class="bole-form-item" prop="legalPersonName" required>
+ <nut-input
+ v-model.trim="form.legalPersonName"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欎紒涓氭硶浜虹殑濮撳悕"
+ type="text"
+ />
+ </nut-form-item>
+ <ProFormItemCell label="缁忓姙浜鸿韩浠借瘉鐓х墖:" required>
+ <div class="id-imgUrl-wrapper">
+ <nut-form-item
+ label=" "
+ class="bole-form-item"
+ prop="proxyPersonIdFrontImgUrl"
+ label-width="0px"
+ >
+ <Uploader
+ v-model:file-list="form.proxyPersonIdFrontImgUrl"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ @my-success="handleFrontImgUrlChange"
+ >
+ <template #upload-icon>
+ <div class="photograph-wrapper">
+ <Photograph color="#808080" />
+ <div>韬唤璇佷汉鍍忛潰</div>
+ </div>
+ </template>
+ </Uploader>
+ </nut-form-item>
+ <nut-form-item
+ label=" "
+ class="bole-form-item"
+ prop="proxyPersonIdBackImgUrl"
+ label-width="0px"
+ >
+ <Uploader
+ v-model:file-list="form.proxyPersonIdBackImgUrl"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ >
+ <template #upload-icon>
+ <div class="photograph-wrapper">
+ <Photograph color="#808080" />
+ <div>韬唤璇佸浗寰介潰</div>
+ </div>
+ </template>
+ </Uploader>
+ </nut-form-item>
+ </div>
+
+ <div class="pro-form-item-tips">
+ 璇蜂笂浼犵粡鍔炰汉韬唤璇佺殑姝e弽闈㈢収鐗囷紝纭繚韬唤璇佹竻鏅板彲瑙侊紝鏀寔png/jpg/jpeg鏍煎紡锛屾枃浠跺ぇ灏忎笉瓒呰繃10MB
+ </div>
+ </ProFormItemCell>
+ <nut-form-item label="缁忓姙浜哄鍚�:" class="bole-form-item" prop="proxyPersonName" required>
+ <nut-input
+ v-model.trim="form.proxyPersonName"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欑粡鍔炰汉鐨勫鍚�"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item
+ label="缁忓姙浜鸿韩浠借瘉鍙�:"
+ class="bole-form-item"
+ prop="proxyPersonIdNumber"
+ required
+ >
+ <nut-input
+ v-model.trim="form.proxyPersonIdNumber"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欑粡鍔炰汉鐨勮韩浠借瘉鍙风爜"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item
+ label="缁忓姙浜烘墜鏈哄彿:"
+ class="bole-form-item"
+ prop="proxyPersonContactPhone"
+ required
+ >
+ <nut-input
+ v-model.trim="form.proxyPersonContactPhone"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欑粡鍔炰汉鐨勬墜鏈哄彿鐮�"
+ type="text"
+ >
+ <template #right>
+ <ProFormCaptcha
+ :onGetCaptcha="() => onGetCaptcha(form.proxyPersonContactPhone)"
+ phonePropName="proxyPersonContactPhone"
+ :validateField="formRef?.validate"
+ ></ProFormCaptcha>
+ </template>
+ </nut-input>
+ </nut-form-item>
+ <nut-form-item label="鐭俊楠岃瘉鐮�:" class="bole-form-item" prop="verificationCode" required>
+ <nut-input
+ v-model.trim="form.verificationCode"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ラ獙璇佺爜"
+ type="number"
+ />
+ </nut-form-item>
+ <nut-form-item
+ label="浼佷笟鎺堟潈涔�:"
+ class="bole-form-item alignTop"
+ prop="proxyPowerAttorneyUrl"
+ required
+ >
+ <Uploader
+ v-model:file-list="form.proxyPowerAttorneyUrl"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ >
+ </Uploader>
+ <div class="pro-form-item-tips">
+ 璇蜂笂浼犲姞鐩栧叕绔犵殑浼佷笟鎺堟潈涔︾収鐗囨垨鎵弿浠讹紝鏀寔png/jpg/jpeg/pdf鏍煎紡锛屾枃浠跺ぇ灏忎笉瓒呰繃10MB
+ <span class="primary" @click="downloadPowerAttorneyTemplate">鎺堟潈涔︽ā鏉夸笅杞�</span>
+ </div>
+ </nut-form-item>
+ </nut-form> -->
+ </ContentScrollView>
+ <PageFooter :isOnlyAction="false">
+ <!-- <PageFooterBtn type="primary" @click="handleSubmit()" :loading="loading"
+ >鎻愪氦璁よ瘉</PageFooterBtn
+ > -->
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+// import { useAuthenticationFlow, useDownloadPowerAttorneyTemplate } from '../hooks';
+import {
+ UserCertificationModeEnumV2,
+ VerificationCodeBusinessType,
+ UserCertificationElementEnum,
+} from '@12333/constants';
+import { ProFormCaptcha, ProFormItemCell } from 'senin-mini/components';
+import * as commonServices from '@12333/services/api/Common';
+import { FileItem } from '@nutui/nutui-taro/dist/types/__VUE/uploader/type';
+import { vatLicense } from '@12333/hooks';
+import { Message } from '@12333/utils';
+import { Photograph } from '@nutui/icons-vue-taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+// const { form, rules, formRef, handleSubmit, loading } = useAuthenticationFlow({
+// certificationMode: UserCertificationModeEnumV2.ProxyPersonPhoneCertification,
+// certificationElement: UserCertificationElementEnum.Identity3,
+// });
+
+// const { downloadPowerAttorneyTemplate } = useDownloadPowerAttorneyTemplate();
+
+// async function onGetCaptcha(phoneNumber: string) {
+// await commonServices.sendPhoneCertificationVerificationCode(
+// {
+// name: form.proxyPersonName,
+// identity: form.proxyPersonIdNumber,
+// mobile: form.proxyPersonContactPhone,
+// businessType: VerificationCodeBusinessType.UserCertificationPhoneCertification,
+// },
+// { showLoading: false }
+// );
+// }
+
+// const handleLicenseUrlChange = (response: FileItem) => {
+// vatLicense(response, {
+// onSuccess(res) {
+// let tips: string[] = [];
+// res?.name ? (form.enterpriseName = res.name) : tips.push('浼佷笟鍚嶇О');
+// res?.societyCode ? (form.societyCreditCode = res.societyCode) : tips.push('缁熶竴绀句細淇$敤浠g爜');
+// if (tips.length > 0) {
+// Message.error(`鏈兘璇嗗埆鍒版偍涓婁紶鐨勫浘鐗囷紝璇烽噸鏂颁笂浼犳竻鏅扮殑鍥剧墖鎴栨墜鍔ㄨ緭鍏�${tips.join('鍜�')}`);
+// }
+// },
+// });
+// };
+
+function handleFrontImgUrlChange(response: FileItem) {
+ // userCredentialVerifyOcrIDCard(response, {
+ // onSuccess(res) {
+ // if (res.realName) form.proxyPersonName = res.realName;
+ // if (res.idcardNum) form.proxyPersonIdNumber = res.idcardNum;
+ // },
+ // });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authenticationJBR-page-wrapper {
+ .photograph-wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.config.ts b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.vue
new file mode 100644
index 0000000..888de66
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationJBR/authenticationJBR.vue
@@ -0,0 +1,14 @@
+<template>
+ <PageLayout title="浼佷笟缁忓姙浜鸿璇�" class="authenticationJBR-page-wrapper" hasBorder developing>
+ <InnerPage />
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'authenticationJBR',
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/InnerPage.vue
new file mode 100644
index 0000000..6e5dda9
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/InnerPage.vue
@@ -0,0 +1,241 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <nut-form :model-value="form" ref="formRef" :rules="rules">
+ <ProFormItemCell label="韬唤璇佺収鐗�:" required>
+ <div class="id-imgUrl-wrapper">
+ <nut-form-item label=" " class="bole-form-item" prop="identityImg" label-width="0px">
+ <Uploader
+ v-model:file-list="form.identityImg"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ @my-success="handleFrontImgUrlChange"
+ @delete="handleFrontImgUrlDelete"
+ >
+ <template #upload-icon>
+ <div class="photograph-wrapper">
+ <Photograph color="#808080" />
+ <div>韬唤璇佷汉鍍忛潰</div>
+ </div>
+ </template>
+ </Uploader>
+ </nut-form-item>
+ <nut-form-item label=" " class="bole-form-item" prop="identityBackImg" label-width="0px">
+ <Uploader
+ v-model:file-list="form.identityBackImg"
+ :maximum="1"
+ :limitFileSize="10"
+ class="bole-uploader nopaddingtop"
+ >
+ <template #upload-icon>
+ <div class="photograph-wrapper">
+ <Photograph color="#808080" />
+ <div>韬唤璇佸浗寰介潰</div>
+ </div>
+ </template>
+ </Uploader>
+ </nut-form-item>
+ </div>
+
+ <div class="pro-form-item-tips">
+ 璇蜂笂浼犺韩浠借瘉鐨勬鍙嶉潰鐓х墖锛岀‘淇濊韩浠借瘉娓呮櫚鍙锛屾敮鎸乸ng/jpg/jpeg鏍煎紡锛屾枃浠跺ぇ灏忎笉瓒呰繃10MB
+ </div>
+ </ProFormItemCell>
+ <nut-form-item label="濮撳悕:" class="bole-form-item" prop="name" required>
+ <nut-input
+ v-model.trim="form.name"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欏鍚�"
+ :formatter="filterNotCN"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item label="韬唤璇佸彿:" class="bole-form-item" prop="identity" required>
+ <nut-input
+ v-model.trim="form.identity"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欒韩浠借瘉鍙风爜"
+ type="text"
+ />
+ </nut-form-item>
+ <template v-if="type === 'realName'">
+ <nut-form-item label="鎵嬫満鍙�:" class="bole-form-item" prop="phoneNumber" required>
+ <nut-input
+ v-model.trim="form.phoneNumber"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欐墜鏈哄彿鐮�"
+ type="text"
+ >
+ <template #right>
+ <ProFormCaptcha
+ :onGetCaptcha="() => onGetCaptcha(form.phoneNumber)"
+ :phonePropName="['phoneNumber', 'name', 'identity']"
+ :validateField="formRef?.validate"
+ ></ProFormCaptcha>
+ </template>
+ </nut-input>
+ </nut-form-item>
+ <nut-form-item label="鐭俊楠岃瘉鐮�:" class="bole-form-item" prop="verifyCode" required>
+ <nut-input
+ v-model.trim="form.verifyCode"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ラ獙璇佺爜"
+ type="number"
+ :max-length="6"
+ />
+ </nut-form-item>
+ </template>
+ </nut-form>
+ </ContentScrollView>
+ <PageFooter :isOnlyAction="false">
+ <PageFooterBtn type="primary" @click="handleSubmit()" :loading="loading"
+ >鎻愪氦璁よ瘉</PageFooterBtn
+ >
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+import { ProFormCaptcha, ProFormItemCell } from 'senin-mini/components';
+import * as electronSignServices from '@12333/services/apiV2/electronSign';
+import { FileItem } from '@nutui/nutui-taro/dist/types/__VUE/uploader/type';
+import { Photograph } from '@nutui/icons-vue-taro';
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import { FormValidator, filterNotCN } from '@12333/utils';
+import Taro from '@tarojs/taro';
+import { userCredentialVerifyOcrIDCard } from '@12333/hooks';
+import { EnumOcrAccess } from '@12333/constants';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { userDetail, updateUserInfo } = useUser();
+const router = Taro.useRouter();
+const type = router.params?.type ?? '';
+
+const form = reactive({
+ identityImg: [] as FileItem[],
+ identityBackImg: [] as FileItem[],
+ name: '',
+ identity: '',
+ phoneNumber: userDetail.value?.contactPhoneNumber,
+ verifyCode: '',
+});
+
+const formRef = ref<any>(null);
+const loading = ref(false);
+
+const rules: FormRules = {
+ name: [{ required: true, message: '璇峰~鍐欏鍚�' }],
+ identityImg: [
+ { required: true, message: '璇蜂笂浼犺韩浠借瘉浜哄儚闈�', validator: FormValidator.validatorArray },
+ ],
+ identityBackImg: [
+ { required: true, message: '璇蜂笂浼犺韩浠借瘉鍥藉窘闈�', validator: FormValidator.validatorArray },
+ ],
+ identity: [
+ { required: true, message: '璇峰~鍐欒韩浠借瘉鍙风爜' },
+ { message: '璇疯緭鍏ユ纭殑韬唤璇佸彿鐮�', validator: FormValidator.validatorIDCard },
+ ],
+ phoneNumber: [
+ { required: true, message: '璇峰~鍐欐墜鏈哄彿鐮�' },
+ { message: '璇疯緭鍏ユ纭殑鎵嬫満鍙风爜', validator: FormValidator.validatorPhoneNumber },
+ ],
+ verifyCode: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜' }],
+};
+
+async function onGetCaptcha(phoneNumber: string) {
+ await electronSignServices.sendPersonalUserIdentity3RealSms(
+ {
+ name: form.name,
+ identity: form.identity,
+ phoneNumber: form.phoneNumber,
+ },
+ { showLoading: false }
+ );
+}
+
+function handleFrontImgUrlChange(response: FileItem) {
+ userCredentialVerifyOcrIDCard({
+ url: response?.url,
+ access: EnumOcrAccess.Baidu,
+ onSuccess(res) {
+ if (res.model?.name) form.name = res.model?.name;
+ if (res.model?.identity) form.identity = res.model?.identity;
+ },
+ });
+}
+
+function handleSubmit() {
+ if (!formRef.value) return;
+ formRef.value.validate().then(({ valid, errors }: any) => {
+ if (valid) {
+ submit();
+ }
+ });
+}
+
+function submit() {
+ if (type === 'realName') {
+ personalUserIdentity3Real();
+ }
+ if (type === 'face') {
+ personalUserFaceReal();
+ }
+}
+
+async function personalUserIdentity3Real() {
+ try {
+ let params: API.PersonalUserIdentity3RealCommand = {
+ name: form.name,
+ phoneNumber: form.phoneNumber,
+ identity: form.identity,
+ identityImg: form.identityImg?.[0]?.path ?? '',
+ identityBackImg: form.identityBackImg?.[0]?.path ?? '',
+ verifyCode: form.verifyCode,
+ };
+ let res = await electronSignServices.personalUserIdentity3Real(params);
+ if (res) {
+ Taro.navigateTo({ url: `${RouterPath.authenticationResult}` });
+ }
+ } catch (error) {}
+}
+
+async function personalUserFaceReal() {
+ try {
+ let params: API.PersonalUserFaceRealCommand = {
+ name: form.name,
+ identity: form.identity,
+ identityImg: form.identityImg?.[0]?.path ?? '',
+ identityBackImg: form.identityBackImg?.[0]?.path ?? '',
+ };
+ let res = await electronSignServices.personalUserFaceReal(params);
+ if (res) {
+ // 涓轰簡鍏煎鏃х増鏈殑api res鐩存帴鏄痜aceUrl
+ const encodedUrl = encodeURIComponent(typeof res === 'string' ? res : res.faceUrl);
+ updateUserInfo();
+ Taro.navigateTo({ url: `${RouterPath.extraPage}?url=${encodedUrl}` });
+ }
+ } catch (error) {}
+}
+
+function handleFrontImgUrlDelete({ files, fileList, index }) {
+ if (fileList?.length === 0) {
+ form.name = '';
+ form.identity = '';
+ }
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authenticationRealName-page-wrapper {
+ .photograph-wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.config.ts b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.vue
new file mode 100644
index 0000000..1dc69e3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationRealName/authenticationRealName.vue
@@ -0,0 +1,14 @@
+<template>
+ <PageLayout title="瀹炲悕璁よ瘉" class="authenticationRealName-page-wrapper" hasBorder>
+ <InnerPage />
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'authenticationRealName',
+});
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/InnerPage.vue
new file mode 100644
index 0000000..f2abe5b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/InnerPage.vue
@@ -0,0 +1,88 @@
+<template>
+ <LoadingLayout :loading="isLoading">
+ <!-- <div class="result-wrapper" v-if="!myCertificationAuditInfo?.isReal">
+ <div class="result-title">鏈璇�</div>
+ </div> -->
+ <div class="result-wrapper" v-if="myCertificationAuditInfo?.isReal">
+ <img class="result-icon" :src="IconSuccess" />
+ <div class="result-title">璁よ瘉鎴愬姛</div>
+ <div class="result-subtitle">鎮ㄧ殑瀹炲悕宸茶璇佹垚鍔�</div>
+ <PageFooterBtn type="primary" class="result-btn" @click="goUserCenter"
+ >杩斿洖涓汉涓績</PageFooterBtn
+ >
+ </div>
+ <div class="result-wrapper" v-else>
+ <img class="result-icon" :src="IconError" />
+ <div class="result-title">璁よ瘉澶辫触</div>
+ <div class="result-subtitle">鎮ㄧ殑瀹炲悕璁よ瘉澶辫触</div>
+ <div class="result-subtitle">
+ 澶辫触鍘熷洜锛歿{ myCertificationAuditInfo?.realFailMessage ?? '' }}
+ </div>
+ <PageFooterBtn type="primary" class="result-btn" @click="goBack()"
+ >閲嶆柊鎻愪氦璁よ瘉</PageFooterBtn
+ >
+ </div>
+ </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import { useMyCertificationAuditInfo, useSwitchTab } from '@/hooks';
+import { goBack } from '@/utils';
+import IconSuccess from '@/assets/authentication/icon-result-success.png';
+import IconError from '@/assets/authentication/icon-result-error.png';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { myCertificationAuditInfo, isLoading } = useMyCertificationAuditInfo();
+
+const switchTab = useSwitchTab();
+
+function goUserCenter() {
+ switchTab({
+ url: RouterPath.mine,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authenticationResult-page-wrapper {
+ .result-wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding-top: 150px;
+
+ .result-icon {
+ width: 320px;
+ height: 184px;
+ object-fit: cover;
+ margin-bottom: 12px;
+ }
+
+ .result-title {
+ font-weight: 400;
+ font-size: 32px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 32px;
+ margin-bottom: 32px;
+ }
+
+ .result-subtitle {
+ font-weight: 400;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'regular');
+ line-height: 44px;
+ margin-bottom: 40px;
+ }
+
+ .result-btn {
+ width: 542px;
+ font-size: 28px;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.config.ts b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.vue b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.vue
new file mode 100644
index 0000000..46cfd6b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/authentication/authenticationResult/authenticationResult.vue
@@ -0,0 +1,28 @@
+<template>
+ <PageLayout
+ title="瀹炲悕璁よ瘉"
+ class="authenticationResult-page-wrapper"
+ hasBorder
+ :backFn="handleBack"
+ >
+ <InnerPage />
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+import { useSwitchTab } from '@/hooks';
+
+defineOptions({
+ name: 'authenticationResult',
+});
+
+const switchTab = useSwitchTab();
+
+function handleBack() {
+ switchTab({
+ url: RouterPath.mine,
+ });
+}
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.config.ts b/apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.vue b/apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.vue
new file mode 100644
index 0000000..b6718bc
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/city/citySelect/citySelect.vue
@@ -0,0 +1,137 @@
+<template>
+ <PageLayout title="閫夋嫨鍩庡競" class="citySelect-page-wrapper" :need-auth="false">
+ <ContentView class="citySelect-content-wrapper">
+ <!-- <div class="current-city">褰撳墠鍩庡競锛歿{ locationCity }}</div> -->
+ <div class="home-searchbar-wrapper">
+ <div class="city-btn-wrapper">
+ <div class="city-btn">
+ <img :src="IconLocaltion" class="city-btn-icon" />
+ <div class="city-btn-text">褰撳墠瀹氫綅锛歿{ locationCity }}</div>
+ </div>
+ </div>
+ <div class="reset-localtion" @click="resetLocation">閲嶆柊瀹氫綅</div>
+ </div>
+ <Elevator :index-list="elevatorData" :height="'100%'" @click-item="clickItem" />
+ </ContentView>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout, LoadingLayout, ContentScrollView, ContentView } from '@/components';
+import { useUser } from '@/hooks';
+import { useArea } from '@12333/hooks';
+import { AreaType } from '@12333/constants';
+import { groupBy, sortBy } from 'lodash';
+import { useUserStore } from '@/stores/modules/user';
+import { Elevator } from '@12333/components';
+import IconLocaltion from '@/assets/task/icon-localtion.png';
+import { setLocationCity } from '@/utils';
+
+defineOptions({
+ name: 'citySelect',
+});
+
+const { completeAreaList, getAreaByAreaCode } = useArea();
+const { locationCity } = useUser();
+const userStore = useUserStore();
+
+const cityList = computed(() => {
+ if (completeAreaList.value?.length > 0) {
+ return [...completeAreaList.value].filter((x) => x.layer === AreaType.City);
+ }
+ return [];
+});
+
+const elevatorData = computed(() => {
+ let cityGroups = groupBy(
+ sortBy(cityList.value, (c) => c.quickQuery.charAt(0)),
+ (city) => city.quickQuery.charAt(0)
+ );
+ const _elevatorData = [];
+ for (let key in cityGroups) {
+ _elevatorData.push({
+ title: key,
+ list: cityGroups[key].map((x) => ({
+ name: x.areaName,
+ id: x.areaCode,
+ parentId: x.parentCode,
+ })),
+ });
+ }
+ return _elevatorData;
+});
+
+const clickItem = (key: string, item: any) => {
+ userStore.setLocationCity(item.name, getAreaByAreaCode(item.parentId).areaName);
+};
+
+async function resetLocation() {
+ try {
+ await setLocationCity();
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.citySelect-page-wrapper {
+ .home-searchbar-wrapper {
+ padding: 32px 0 28px;
+ display: flex;
+ align-items: center;
+
+ .city-btn-wrapper {
+ flex: 1;
+ min-width: 0;
+
+ .city-btn {
+ display: flex;
+ align-items: center;
+ padding-right: 36px;
+ color: boleGetCssVar('text-color', 'primary');
+
+ .city-btn-icon {
+ width: 40px;
+ height: 40px;
+ }
+
+ .city-btn-text {
+ @include ellipsis;
+ margin-left: 12px;
+ font-size: 30px;
+ }
+ }
+ }
+
+ .reset-localtion {
+ font-weight: 400;
+ font-size: 24px;
+ color: boleGetCssVar('color', 'primary');
+ line-height: 28px;
+ }
+ }
+
+ .current-city {
+ padding: 20px 0;
+ color: boleGetCssVar('text-color', 'primary');
+ font-size: 28px;
+ }
+
+ .citySelect-content-wrapper {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ }
+
+ .nut-elevator {
+ flex: 1;
+ min-height: 0;
+
+ .nut-elevator__list__item__name,
+ .nut-elevator__list__item__code {
+ padding: 0;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.config.ts b/apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.vue b/apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.vue
new file mode 100644
index 0000000..6501518
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/extraPage/extraPage/extraPage.vue
@@ -0,0 +1,17 @@
+<template>
+ <web-view :src="urlLink" />
+</template>
+
+<script setup lang="ts">
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'extraPage',
+});
+
+const router = Taro.useRouter();
+
+const url = (router.params.url as string) ?? '';
+
+const urlLink = computed(() => decodeURIComponent(url));
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/authorization/authorization.vue b/apps/housekeepingMiniApp/src/subpackages/login/authorization/authorization.vue
new file mode 100644
index 0000000..1ec19b9
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/authorization/authorization.vue
@@ -0,0 +1,317 @@
+<template>
+ <LoginPageLayout class="authorization-page-wrapper">
+ <div class="authorization-page-wechat-btn-wrapper">
+ <nut-button
+ v-if="isAccount"
+ type="primary"
+ class="authorization-page-wechat-wrapper"
+ @click="handleLoginByHasAccount"
+ >
+ <div class="authorization-page-wechat">鎵嬫満鍙峰揩閫熺櫥褰�</div></nut-button
+ >
+ <AccessOpenTypeButton
+ v-else
+ type="primary"
+ class="authorization-page-wechat-wrapper"
+ open-type="getPhoneNumber"
+ :access="state.policyChecked"
+ @noAccess="noAccess"
+ @getphonenumber="login"
+ >
+ <div class="authorization-page-wechat">鎵嬫満鍙峰揩閫熺櫥褰�</div>
+ </AccessOpenTypeButton>
+ </div>
+ <Policy
+ v-model="state.policyChecked"
+ policyBtnText="鑻ユ墜鏈哄彿鏈敞鍐岋紝灏嗕负鎮ㄧ洿鎺ユ敞鍐岃处鍙凤紝娉ㄥ唽鍗充负鍚屾剰"
+ />
+ <!-- <div class="other-login-channel-wrapper" v-if="!isLoginByWeb"> -->
+ <div class="other-login-channel-wrapper" v-if="NODE_ENV === 'development'">
+ <nut-divider>鍏朵粬鐧诲綍鏂瑰紡</nut-divider>
+ <div class="other-login-channel-list">
+ <div class="other-login-channel-list-item" @click="goLoginByForm()">
+ <div class="other-login-channel-list-item-icon">
+ <img :src="IconCaptcha" />
+ </div>
+ <div class="other-login-channel-list-item-text">楠岃瘉鐮佺櫥褰�</div>
+ </div>
+ <div
+ class="other-login-channel-list-item"
+ @click="goLoginByForm(LoginFormTabs.AccountLogin)"
+ >
+ <div class="other-login-channel-list-item-icon">
+ <img :src="IconPassword" />
+ </div>
+ <div class="other-login-channel-list-item-text">璐︽埛鐧诲綍</div>
+ </div>
+ </div>
+ </div>
+ </LoginPageLayout>
+</template>
+
+<script setup lang="ts">
+import { Policy } from '@/components';
+import { AccessOpenTypeButton } from '@12333/components';
+import LoginPageLayout from '../components/LoginPageLayout/LoginPageLayout.vue';
+import { useUserStore } from '@/stores/modules/user';
+import { Message } from '@12333/utils';
+import { CommonEventFunction, ButtonProps } from '@tarojs/components';
+import Taro from '@tarojs/taro';
+import { useLoginedJump } from '@/hooks';
+import IconCaptcha from '@/assets/login/icon-btn-captcha.png';
+import IconPassword from '@/assets/login/icon-btn-password.png';
+import { LoginFormTabs } from '../constants';
+import * as authServices from '@12333/services/apiV2/auth';
+import { NODE_ENV } from '@/constants';
+import { subscribeMessageTemplateIdsForC } from '@12333/constants';
+console.log('NODE_ENV: ', NODE_ENV);
+
+defineOptions({
+ name: 'authorization',
+});
+
+const state = reactive({
+ policyChecked: false,
+});
+
+const userStore = useUserStore();
+
+function noAccess() {
+ Message.warning('璇峰厛闃呰骞跺嬀閫夊崗璁�');
+}
+
+const { jump, redirectParams } = useLoginedJump();
+
+const launchOptions = Taro.getEnterOptionsSync();
+console.log('launchOptions: ', launchOptions);
+const router = Taro.useRouter();
+
+const uuid = router.params?.scene ?? '';
+
+const isLoginByWeb = computed(
+ () =>
+ RouterPath.authorization.includes(launchOptions.path) && launchOptions.scene === 1047 && uuid
+);
+
+const wxIndentityRes = ref<API.LoginCommandCallback>();
+const wxMiniAppUserLoginRes = ref<API.LoginCommandCallback>();
+
+const isAccount = ref(false);
+
+onMounted(async () => {
+ try {
+ let loginRes = await Taro.login();
+ if (isLoginByWeb.value) {
+ // const wxIndentity = await authServices.wxmpLogin({
+ // code: loginRes.code,
+ // type: AppLocalConfig.userType,
+ // });
+ // wxIndentityRes.value = wxIndentity;
+ // if (wxIndentityRes.value.isBindPhoneNumber) {
+ // isAccount.value = true;
+ // }
+ } else {
+ const params: API.WxmpLoginCommand = {
+ code: loginRes.code,
+ type: AppLocalConfig.userType,
+ };
+ wxMiniAppUserLoginRes.value = await authServices.wxmpLogin(params);
+ if (wxMiniAppUserLoginRes.value?.isBindPhoneNumber) {
+ isAccount.value = true;
+ }
+ }
+ } catch (error) {}
+});
+
+const login: CommonEventFunction<ButtonProps.onGetPhoneNumberEventDetail> = async function (ev) {
+ try {
+ const { errMsg, code } = ev.detail;
+ console.log('errMsg: ', errMsg, isLoginByWeb.value);
+ if (errMsg === 'getPhoneNumber:ok') {
+ if (isLoginByWeb.value) {
+ // let res = await userStore.wxMiniAppPhoneAuthLoginFromScan(
+ // ev.detail,
+ // wxIndentityRes.value,
+ // uuid
+ // );
+ // if (res) {
+ // handleLoginSuccess();
+ // }
+ } else {
+ let res = await userStore.getTokenByPhone(ev.detail, wxMiniAppUserLoginRes.value);
+ if (res) {
+ handleLoginSuccess();
+ }
+ }
+ } else {
+ Message.warning('鏃犳硶鑾峰彇鎵嬫満鍙凤紒');
+ }
+ } catch (error) {
+ console.log('error: ', error);
+ }
+};
+
+async function handleLoginByHasAccount() {
+ try {
+ if (state.policyChecked) {
+ if (isLoginByWeb.value) {
+ console.log('uuid: ', uuid);
+ // let res = await userStore.wxMiniAppUserLoginFromScan(wxIndentityRes.value, uuid);
+ // if (res) {
+ // handleLoginSuccess();
+ // }
+ } else {
+ userStore.loginSuccess(wxMiniAppUserLoginRes.value);
+ handleLoginSuccess();
+ }
+ } else {
+ noAccess();
+ }
+ } catch (error) {}
+}
+
+async function handleLoginSuccess() {
+ try {
+ if (!Taro.requestSubscribeMessage) {
+ await Message.confirm({ message: '浣犵殑寰俊鐗堟湰杩囦綆锛屼笉鏀寔璁㈤槄娑堟伅锛屾槸鍚︾户缁紵' });
+ }
+ const res = await Taro.getSetting({
+ withSubscriptions: true,
+ });
+ let setting: boolean[] = [];
+ if (res.subscriptionsSetting && res.subscriptionsSetting.itemSettings) {
+ setting = subscribeMessageTemplateIdsForC
+ .map((id) => res.subscriptionsSetting.itemSettings[id] !== 'accept')
+ .filter(Boolean);
+ }
+ // if (setting.length > 0) {
+ Taro.requestSubscribeMessage({
+ tmplIds: subscribeMessageTemplateIdsForC,
+ success: function (res) {
+ console.log('res: ', res);
+ },
+ });
+ console.log('setting: ', setting);
+ // }
+ Message.success('鎺堟潈鐧诲綍鎴愬姛', {
+ onClosed: () => {
+ jump();
+ },
+ });
+ } catch (error) {
+ console.log('error: ', error);
+ }
+}
+
+function goLoginByForm(tab = LoginFormTabs.VerificationCodeLogin) {
+ Taro.navigateTo({
+ url: `${RouterPath.loginByForm}?redirect=${redirectParams.value}&tab=${tab}`,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.authorization-page-wrapper {
+ .authorization-page-top {
+ width: 750px;
+ height: 225px;
+ margin-bottom: 78px;
+ }
+
+ .authorization-page-title {
+ margin-bottom: 160px;
+ }
+
+ .authorization-page-wechat-btn-wrapper {
+ padding: 0 64px;
+ margin-bottom: 40px;
+ }
+
+ .authorization-page-wechat-wrapper {
+ width: 100%;
+ height: 88px;
+ }
+
+ .authorization-page-wechat {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-weight: 400;
+ font-size: 32px;
+ color: #ffffff;
+ line-height: 44px;
+
+ .authorization-page-wechat-icon {
+ width: 44px;
+ height: 36px;
+ margin-right: 10px;
+ }
+ }
+
+ .page-layout-scroll-view-wrapper {
+ position: relative;
+
+ .other-login-channel-wrapper {
+ width: 520px;
+ position: absolute;
+ bottom: 40px;
+ left: 50%;
+ transform: translateX(-50%);
+
+ .nut-divider {
+ margin: 0;
+ margin-bottom: 40rpx;
+ color: boleGetCssVar('text-color', 'secondary');
+
+ &::before,
+ &::after {
+ border-color: #f0f0f0;
+ }
+ }
+
+ .other-login-channel-list {
+ display: flex;
+ justify-content: space-around;
+
+ .other-login-channel-list-item {
+ .other-login-channel-list-item-icon {
+ width: 80px;
+ height: 80px;
+ background: #f5f5f5;
+ border-radius: 50%;
+ margin: 0 auto 8px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ img {
+ width: 38px;
+ height: 48px;
+ }
+ }
+
+ .other-login-channel-list-item-text {
+ font-weight: 400;
+ font-size: 24px;
+ color: boleGetCssVar('text-color', 'regular');
+ line-height: 34px;
+ text-align: center;
+ }
+ }
+ }
+ }
+ }
+}
+
+.authorization-page-auth {
+ position: fixed;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 750px;
+ height: 1624px;
+ object-fit: cover;
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/authorization/index.config.ts b/apps/housekeepingMiniApp/src/subpackages/login/authorization/index.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/authorization/index.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/components/LoginPageLayout/LoginPageLayout.vue b/apps/housekeepingMiniApp/src/subpackages/login/components/LoginPageLayout/LoginPageLayout.vue
new file mode 100644
index 0000000..3c7c64a
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/components/LoginPageLayout/LoginPageLayout.vue
@@ -0,0 +1,58 @@
+<template>
+ <PageLayout :needAuth="false" class="login-page-layout">
+ <template #navigationBar>
+ <TransparentNavigationBar :title="title" :is-absolute="false"></TransparentNavigationBar>
+ </template>
+ <template #bg>
+ <img :src="OssAssets.login.AuthBg" class="authorization-page-auth" />
+ </template>
+
+ <div class="authorization-page-title">娆㈣繋浣跨敤宸ユ槗璧�</div>
+
+ <slot></slot>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout, TransparentNavigationBar } from '@/components';
+import { OssAssets } from '@12333/constants';
+
+defineOptions({
+ name: 'LoginPageLayout',
+});
+
+type Props = {
+ title?: string;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ title: '鐧诲綍',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.login-page-layout {
+ .authorization-page-title {
+ font-size: 60px;
+ color: boleGetCssVar('text-color', 'primary');
+ font-weight: bold;
+ text-align: center;
+ margin-bottom: 108px;
+ margin-top: 136px;
+ line-height: 84px;
+ @include ellipsis;
+ }
+}
+
+.authorization-page-auth {
+ position: fixed;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 750px;
+ height: 1624px;
+ object-fit: cover;
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/components/OtherLoginChannel/OtherLoginChannel.vue.vue b/apps/housekeepingMiniApp/src/subpackages/login/components/OtherLoginChannel/OtherLoginChannel.vue.vue
new file mode 100644
index 0000000..8c25e92
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/components/OtherLoginChannel/OtherLoginChannel.vue.vue
@@ -0,0 +1,17 @@
+<template>
+ <div></div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'OtherLoginChannel',
+});
+
+// type Props = {};
+
+// const props = withDefaults(defineProps<Props>(), {});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/constants/index.ts b/apps/housekeepingMiniApp/src/subpackages/login/constants/index.ts
new file mode 100644
index 0000000..3ebbbf2
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/constants/index.ts
@@ -0,0 +1,4 @@
+export enum LoginFormTabs {
+ VerificationCodeLogin = 10,
+ AccountLogin,
+}
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/accountLoginForm.vue b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/accountLoginForm.vue
new file mode 100644
index 0000000..3499730
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/accountLoginForm.vue
@@ -0,0 +1,118 @@
+<template>
+ <div class="verification-code-login-form-wrapper">
+ <nut-form class="verification-code-login-form" ref="formRef" :model-value="form" :rules="rules">
+ <nut-form-item label="" class="bole-form-item" prop="userName" required>
+ <nut-input
+ v-model.trim="form.userName"
+ class="bole-input-text"
+ placeholder="璇疯緭鍏ヨ处鍙�/鎵嬫満鍙�/閭"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item label="" class="bole-form-item" prop="userPassword" required>
+ <nut-input
+ v-model.trim="form.userPassword"
+ class="bole-input-text"
+ placeholder="璇疯緭鍏ュ瘑鐮�"
+ :type="isShowPassword ? 'text' : 'password'"
+ :key="isShowPassword ? 'text' : 'password'"
+ >
+ <template #right>
+ <div class="password-icon-wrapper" @click="isShowPassword = !isShowPassword">
+ <Eye v-if="isShowPassword"></Eye>
+ <Marshalling v-else></Marshalling>
+ </div>
+ </template>
+ </nut-input>
+ </nut-form-item>
+ </nut-form>
+ <LargeButton class="login-btn" @click="handleLogin" :loading="form.loading">鐧诲綍</LargeButton>
+ <div class="go-register-btn" @click="goRegister">绔嬪嵆娉ㄥ唽</div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { Message } from '@12333/utils';
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import { LargeButton } from '@/components';
+import { useLoginedJump } from '@/hooks';
+import { useUserStore } from '@/stores/modules/user';
+import { Eye, Marshalling } from '@nutui/icons-vue-taro';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'AccountLoginForm',
+});
+
+type Props = {
+ policyChecked?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+
+const userStore = useUserStore();
+
+const { jump } = useLoginedJump();
+
+const isShowPassword = ref(false);
+
+const formRef = ref(null);
+
+const form = reactive({
+ loading: false,
+ userName: '',
+ userPassword: '',
+});
+
+const rules = reactive<FormRules>({
+ userName: [{ required: true, message: '璇疯緭鍏ヨ处鍙�/鎵嬫満鍙�/閭' }],
+ userPassword: [{ required: true, message: '璇疯緭鍏ュ瘑鐮�' }],
+});
+
+async function handleLogin() {
+ try {
+ if (props.policyChecked) {
+ const { valid } = await formRef.value.validate();
+ if (valid) {
+ form.loading = true;
+ await userStore.loginByPassword({
+ userName: form.userName,
+ password: form.userPassword,
+ });
+ jump();
+ }
+ } else {
+ noAccess();
+ }
+ } catch (error) {
+ } finally {
+ form.loading = false;
+ }
+}
+
+function noAccess() {
+ Message.warning('璇峰厛闃呰骞跺嬀閫夊崗璁�');
+}
+
+function goRegister() {
+ console.log('RouterPath.registerForm: ', RouterPath.registerForm);
+ Taro.navigateTo({
+ url: RouterPath.registerForm,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.verification-code-login-form-wrapper {
+ .password-icon-wrapper {
+ padding: 0 10px;
+ display: inline-flex;
+
+ .nutui-iconfont {
+ font-size: 28px;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/index.config.ts b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/index.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/index.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/loginByForm.vue b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/loginByForm.vue
new file mode 100644
index 0000000..54e02e0
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/loginByForm.vue
@@ -0,0 +1,79 @@
+<template>
+ <LoginPageLayout class="loginByForm-page-wrapper">
+ <div class="loginB-form-wrapper">
+ <div class="loginB-form-tab">
+ <div
+ :class="[
+ 'loginB-form-tab-item',
+ { active: tabType === LoginFormTabs.VerificationCodeLogin },
+ ]"
+ @click="handleTabChange(LoginFormTabs.VerificationCodeLogin)"
+ >
+ <img :src="IconTabBg1" alt="" class="loginB-form-tab-item-bg1" />
+ <div class="loginB-form-tab-item-content">
+ <div class="loginB-form-tab-item-text">楠岃瘉鐮佺櫥褰�</div>
+ <div class="loginB-form-tab-item-line"></div>
+ </div>
+ </div>
+ <!-- <div
+ :class="['loginB-form-tab-item', { active: tabType === LoginFormTabs.AccountLogin }]"
+ @click="handleTabChange(LoginFormTabs.AccountLogin)"
+ >
+ <img :src="IconTabBg2" alt="" class="loginB-form-tab-item-bg2" />
+ <div class="loginB-form-tab-item-content">
+ <div class="loginB-form-tab-item-text">璐︽埛鐧诲綍</div>
+ <div class="loginB-form-tab-item-line"></div>
+ </div>
+ </div> -->
+ </div>
+ <VerificationCodeLoginForm
+ v-show="tabType === LoginFormTabs.VerificationCodeLogin"
+ :policyChecked="state.policyChecked"
+ />
+ <AccountLoginForm
+ v-show="tabType === LoginFormTabs.AccountLogin"
+ :policyChecked="state.policyChecked"
+ />
+ </div>
+ <Policy
+ v-model="state.policyChecked"
+ policyBtnText="鎴戝凡闃呰骞跺悓鎰�"
+ class="loginB-form-policy"
+ />
+ </LoginPageLayout>
+</template>
+
+<script setup lang="ts">
+import { useUserStore } from '@/stores/modules/user';
+import LoginPageLayout from '../components/LoginPageLayout/LoginPageLayout.vue';
+import { LoginFormTabs } from '../constants';
+import IconTabBg1 from '@/assets/login/icon-tab-bg-1.png';
+import IconTabBg2 from '@/assets/login/icon-tab-bg-2.png';
+import VerificationCodeLoginForm from './verificationCodeLoginForm.vue';
+import AccountLoginForm from './accountLoginForm.vue';
+import { Policy } from '@/components';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'loginByForm',
+});
+
+const userStore = useUserStore();
+
+const state = reactive({
+ policyChecked: false,
+});
+
+const router = Taro.useRouter();
+
+const tabType = ref(Number(router.params?.tab ?? LoginFormTabs.VerificationCodeLogin));
+
+function handleTabChange(tab: LoginFormTabs) {
+ tabType.value = tab;
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+@import '../styles/login.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/verificationCodeLoginForm.vue b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/verificationCodeLoginForm.vue
new file mode 100644
index 0000000..6c4c260
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/loginByForm/verificationCodeLoginForm.vue
@@ -0,0 +1,118 @@
+<template>
+ <div class="verification-code-login-form-wrapper">
+ <nut-form class="verification-code-login-form" ref="formRef" :model-value="form" :rules="rules">
+ <nut-form-item label="" class="bole-form-item" prop="phoneNumber" required>
+ <nut-input
+ v-model.trim="form.phoneNumber"
+ class="bole-input-text"
+ placeholder="璇疯緭鍏ユ墜鏈哄彿"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item label="" class="bole-form-item" prop="verificationCode" required>
+ <nut-input
+ v-model.trim="form.verificationCode"
+ class="bole-input-text"
+ placeholder="璇疯緭鍏ラ獙璇佺爜"
+ type="number"
+ >
+ <template #right>
+ <ProFormCaptcha
+ :onGetCaptcha="onGetCaptcha"
+ phonePropName="phoneNumber"
+ :validateField="formRef?.validate"
+ ></ProFormCaptcha>
+ </template>
+ </nut-input>
+ </nut-form-item>
+ </nut-form>
+ <LargeButton class="login-btn" @click="handleLogin" :loading="form.loading">鐧诲綍</LargeButton>
+ <div class="go-register-btn" @click="goRegister">绔嬪嵆娉ㄥ唽</div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import { FormValidator, Message } from '@12333/utils';
+import { LargeButton } from '@/components';
+import { ProFormCaptcha } from 'senin-mini/components';
+import { useLoginedJump } from '@/hooks';
+import { useUserStore } from '@/stores/modules/user';
+import Taro from '@tarojs/taro';
+import * as authServices from '@12333/services/apiV2/auth';
+import { APP_ENV } from '@/constants';
+
+defineOptions({
+ name: 'verificationCodeLoginForm',
+});
+
+type Props = {
+ policyChecked?: boolean;
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+
+const userStore = useUserStore();
+
+const { jump } = useLoginedJump();
+
+const formRef = ref(null);
+
+const form = reactive({
+ loading: false,
+ phoneNumber: '',
+ verificationCode: '',
+});
+
+const rules = reactive<FormRules>({
+ phoneNumber: [
+ { required: true, message: '璇疯緭鍏ユ墜鏈哄彿' },
+ { validator: FormValidator.validatorPhoneNumber, message: '璇疯緭鍏ユ纭殑鎵嬫満鍙�' },
+ ],
+ verificationCode: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜' }],
+});
+
+async function onGetCaptcha() {
+ const res = await authServices.sendLoginOrRegisterVerifyCode(
+ {
+ phoneNumber: form.phoneNumber,
+ },
+ { showLoading: false, getResponse: true }
+ );
+ if (res && APP_ENV === 'staging') {
+ // @ts-ignore
+ form.verificationCode = res?.data?.extras?.code ?? '';
+ }
+}
+
+async function handleLogin() {
+ try {
+ if (props.policyChecked) {
+ const { valid } = await formRef.value.validate();
+ if (valid) {
+ form.loading = true;
+ await userStore.loginByUsername({
+ phoneNumber: form.phoneNumber,
+ verifyCode: form.verificationCode,
+ });
+ jump();
+ }
+ } else {
+ noAccess();
+ }
+ } catch (error) {
+ } finally {
+ form.loading = false;
+ }
+}
+
+function noAccess() {
+ Message.warning('璇峰厛闃呰骞跺嬀閫夊崗璁�');
+}
+
+function goRegister() {
+ Taro.navigateTo({
+ url: RouterPath.registerForm,
+ });
+}
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/index.config.ts b/apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/index.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/index.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/mineUserPolicy.vue b/apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/mineUserPolicy.vue
new file mode 100644
index 0000000..ffb1c02
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/mineUserPolicy/mineUserPolicy.vue
@@ -0,0 +1,401 @@
+<template>
+ <PageLayout title="鐢ㄦ埛鍗忚" :needAuth="false" class="userPolicy-page-wrapper">
+ <scroll-view style="height: 100%" :scroll-y="true">
+ <div class="userPolicy-page-scrollview-content">
+ <div class="userPolicy-page-title">818骞冲彴鐢ㄦ埛鏈嶅姟鍗忚</div>
+ <UserPolicyCell title="涓�銆佹帴鍙楁潯娆�">
+ <div>
+ 1銆佹湰鍗忚鐢辨偍涓�818骞冲彴鐨勭粡钀ヨ�咃紙浠ヤ笅绉扳�滃钩鍙扳�濓級鍏卞悓缂旂粨锛屾湰鏈嶅姟鍗忚鍏锋湁鍚堝悓鏁堝姏銆�
+ </div>
+ <div>
+ 2銆佺敱浜庝簰鑱旂綉楂橀�熷彂灞曪紝鎮ㄤ笌骞冲彴绛剧讲鐨勬湰鍗忚鍒楁槑鐨勬潯娆惧苟涓嶈兘瀹屾暣缃楀垪骞惰鐩栨偍涓庡钩鍙版墍鏈夋潈鍒╀笌涔夊姟锛岀幇鏈夌殑绾﹀畾涔熶笉鑳戒繚璇佸畬鍏ㄧ鍚堟湭鏉ュ彂灞曠殑闇�姹傘�傚洜姝わ紝鎵�鏈夊钩鍙板凡缁忓彂甯冪殑鎴栧皢鏉ュ彲鑳藉彂甯冪殑鍚勭被瑙勫垯鍧囦负鏈崗璁殑琛ュ厖鍗忚锛屼笌鏈崗璁笉鍙垎鍓蹭笖鍏锋湁鍚岀瓑娉曞緥鏁堝姏銆傚鎮ㄧ户缁娇鐢ㄥ钩鍙版湇鍔★紝瑙嗕负鎮ㄥ悓鎰忎笂杩拌ˉ鍏呭崗璁��
+ </div>
+ <div>
+ 3銆佸湪鏈湇鍔″崗璁腑娌℃湁浠モ�滆鍒欌�濆瓧鏍疯〃绀虹殑閾炬帴鏂囧瓧鎵�鎸囩ず鐨勬枃浠朵笉灞炰簬鏈湇鍔″崗璁殑缁勬垚閮ㄥ垎锛岃�屾槸鍏跺畠鍐呭鐨勫崗璁垨鏈夊叧鍙傝�冩暟鎹紝涓庢湰鍗忚娌℃湁娉曞緥涓婄殑鐩存帴鍏崇郴銆�
+ </div>
+ <div>
+ 4銆佺敤鎴峰湪浣跨敤骞冲彴鎻愪緵鐨勫悇椤规湇鍔$殑鍚屾椂锛屾壙璇烘帴鍙楀苟閬靛畧鍚勯」鐩稿叧瑙勫垯鐨勮瀹氥�傚钩鍙版湁鏉冩牴鎹渶瑕佷笉鏃跺湴鍒跺畾銆佷慨鏀规湰鍗忚鎴栧悇绫昏鍒欙紝濡傛湰鍗忚鏈変换浣曞彉鏇达紝骞冲彴灏嗕互缃戠珯鍏憡鐨勫舰寮忚繘琛屾洿鏂帮紝涓嶅啀鍗曠嫭閫氱煡浜堟偍銆傚鐢ㄦ埛涓嶅悓鎰忕浉鍏冲彉鏇达紝蹇呴』鍋滄浣跨敤鈥滄湇鍔♀�濄�傜粡淇鐨勫崗璁竴缁忓湪骞冲彴缃戠珯涓婂叕甯冨悗锛岀珛鍗宠嚜鍔ㄧ敓鏁堛�傚悇绫昏鍒欎細鍦ㄥ彂甯冨悗鐢熸晥锛屼害鎴愪负鏈崗璁殑涓�閮ㄥ垎銆傜櫥褰曟垨缁х画浣跨敤鈥滄湇鍔♀�濆皢琛ㄧず鐢ㄦ埛鎺ュ彈缁忎慨璁㈢殑鍗忚銆傞櫎鍙﹁鏄庣‘澹版槑澶栵紝浠讳綍浣库�滄湇鍔♀�濊寖鍥存墿澶ф垨鍔熻兘澧炲己鐨勬柊鍐呭鍧囧彈鏈崗璁害鏉熴��
+ </div>
+ <div>
+ 5銆佺敤鎴风‘璁ゆ湰鏈嶅姟鍗忚鍚庯紝鏈湇鍔″崗璁嵆鍦ㄧ敤鎴峰拰骞冲彴涔嬮棿浜х敓娉曞緥鏁堝姏銆傝鐢ㄦ埛鍔″繀鍦ㄦ敞鍐屼箣鍓嶈鐪熼槄璇诲叏閮ㄦ湇鍔″崗璁唴瀹癸紝濡傛湁浠讳綍鐤戦棶锛屽彲鍚戝钩鍙板挩璇€��
+ <div>
+ 1锛夋棤璁虹敤鎴蜂簨瀹炰笂鏄惁鍦ㄦ敞鍐屼箣鍓嶈鐪熼槄璇讳簡鏈湇鍔″崗璁紝鍙鐢ㄦ埛鐐瑰嚮鍗忚姝f湰涓嬫柟鐨勨�滅‘璁も�濇寜閽苟鎸夌収骞冲彴娉ㄥ唽绋嬪簭鎴愬姛娉ㄥ唽涓虹敤鎴凤紝鐢ㄦ埛鐨勮涓轰粛鐒惰〃绀哄叾鍚屾剰骞剁缃蹭簡鏈湇鍔″崗璁��
+ </div>
+ <div>2锛夋湰鍗忚涓嶆秹鍙婄敤鎴蜂笌骞冲彴鍏跺畠鐢ㄦ埛涔嬮棿鍥犵綉涓婁氦鏄撹�屼骇鐢熺殑娉曞緥鍏崇郴鍙婃硶寰嬬籂绾枫��</div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="浜屻�佸畾涔�">
+ <div>
+ 1銆�818骞冲彴锛�818骞冲彴鎸囩敱818骞冲彴缁忚惀鑰呰繍钀ョ殑缃戠粶骞冲彴锛屽寘鎷絾涓嶉檺浜�818浜哄姏璧勬簮浜т笟閾惧钩鍙帮紝鍩熷悕涓簑ww.81812333.com鍙�81812333灏忕▼搴忕瓑銆�
+ </div>
+ <div>
+ 2銆�818骞冲彴缁忚惀鑰咃細骞冲彴缁忚惀鑰呮槸鎸囨硶寰嬭鍙殑缁忚惀璇ュ钩鍙扮綉绔欑殑璐d换涓讳綋锛屾湁鍏�818骞冲彴缁忚惀鑰呯殑淇℃伅璇锋煡鐪�818骞冲彴棣栭〉椤堕儴鐨勨�滃叧浜庘�濋摼鎺ャ��
+ </div>
+ <div>
+ 3銆�818骞冲彴鏈嶅姟锛�818骞冲彴鏈嶅姟鏄寚骞冲彴娉ㄥ唽鐢ㄦ埛鍙湪818骞冲彴涓婂彂甯冧紒涓氫俊鎭�佷氦鏄撲俊鎭�佹煡璇骇鍝併�佷骇鍝佺浉鍏充俊鎭強鍏朵粬鏈嶅姟淇℃伅銆佽揪鎴愪氦鏄撴剰鍚戝苟杩涜浜ゆ槗銆佸鍏朵粬娉ㄥ唽鐢ㄦ埛杩涜璇勪环銆佸弬鍔犲钩鍙扮粍缁囩殑娲诲姩浠ュ強浣跨敤鍏跺畠淇℃伅鏈嶅姟鍙婃妧鏈湇鍔°��
+ </div>
+ <div>
+ 4銆佺敤鎴峰強鐢ㄦ埛璐︽埛锛�
+ <div>
+ 1.鐢ㄦ埛锛氱敤鎴峰繀椤绘槸鍏峰瀹屽叏姘戜簨琛屼负鑳藉姏鐨勮嚜鐒朵汉锛屾垨鑰呮槸鍏锋湁鍚堟硶缁忚惀璧勬牸鐨勫疄浣撶粍缁囥�傛棤姘戜簨琛屼负鑳藉姏浜恒�侀檺鍒舵皯浜嬭涓鸿兘鍔涗汉浠ュ強鏃犵粡钀ユ垨鐗瑰畾缁忚惀璧勬牸鐨勭粍缁囦笉褰撴敞鍐屼负骞冲彴鐢ㄦ埛鎴栬秴杩囧叾姘戜簨鏉冨埄鎴栬涓鸿兘鍔涜寖鍥翠粠浜嬩氦鏄撶殑锛屽叾涓庡钩鍙颁箣闂寸殑鏈嶅姟鍗忚鑷鏃犳晥锛屽钩鍙颁竴缁忓彂鐜帮紝鏈夋潈绔嬪嵆娉ㄩ攢璇ョ敤鎴凤紝骞惰拷绌跺叾浣跨敤骞冲彴鈥滄湇鍔♀�濈殑涓�鍒囨硶寰嬭矗浠汇��
+ </div>
+ <div>
+ 2.鐢ㄦ埛娉ㄥ唽锛氱敤鎴锋敞鍐屾槸鎸囩敤鎴风櫥闄嗗钩鍙帮紝骞舵寜瑕佹眰濉啓鐩稿叧淇℃伅骞剁‘璁ゅ悓鎰忓饱琛岀浉鍏崇敤鎴峰崗璁殑杩囩▼銆�
+ </div>
+ <div>
+ 3.璐︽埛杞锛氱敱浜庣敤鎴疯处鎴峰叧鑱旂敤鎴蜂俊鐢ㄤ俊鎭紝浠呭綋鏈夋硶寰嬫槑鏂囪瀹氥�佸徃娉曡瀹氭垨缁忓钩鍙板悓鎰忕殑鎯呭喌涓嬶紝鎮ㄥ彲杩涜璐︽埛鐨勮浆璁┿�傛偍鐨勮处鎴蜂竴缁忚浆璁╋紝璇ヨ处鎴烽」涓嬫潈鍒╀箟鍔′竴骞惰浆绉汇�傞櫎姝ゅ锛屾偍鐨勮处鎴蜂笉寰椾互浠讳綍鏂瑰紡杞锛屽惁鍒欏钩鍙版湁鏉冭拷绌舵偍鐨勮繚绾﹁矗浠伙紝涓旂敱姝や骇鐢熺殑涓�鍒囪矗浠诲潎鐢辨偍鎵挎媴銆�
+ </div>
+ <div>
+ 4.瀹炲悕璁よ瘉锛氫负浣挎偍鏇村ソ鍦颁娇鐢ㄥ钩鍙扮殑鍚勯」鏈嶅姟锛屼繚闅滄偍鐨勮处鎴峰畨鍏紝骞冲彴鍙姹傛偍鎸夊浗瀹舵硶寰嬫硶瑙勭殑瑙勫畾瀹屾垚瀹炲悕璁よ瘉銆�
+ </div>
+ <div>
+ 5.涓嶆椿璺冭处鎴峰洖鏀讹細濡傛偍鐨勮处鎴峰悓鏃剁鍚堜互涓嬫潯浠讹紝鎮ㄧ殑骞冲彴鐧诲綍璐︽埛鍙兘琚睆钄斤紝涓嶈兘鍐嶇櫥闄嗗钩鍙帮紝鎵�鏈夊钩鍙版湇鍔″皢鍚屾椂缁堟锛�
+ </div>
+ <div>5.1.鏈�氳繃瀹炲悕璁よ瘉鐨勫钩鍙拌处鎴凤紱</div>
+ <div>5.2.杩炵画180澶╂湭浣跨敤鎮ㄧ殑閭銆佹墜鏈烘垨骞冲彴璁ゅ彲鐨勫叾浠栨柟寮忓拰瀵嗙爜鐧诲綍杩囧钩鍙扮綉绔欙紱</div>
+ <div>5.3.涓嶅瓨鍦ㄦ湭鍒版湡鐨勬湁鏁堜笟鍔�</div>
+ <div>6.娉ㄥ唽淇℃伅绠$悊</div>
+ <div>
+ 6.1.鍦ㄥ畬鎴愭敞鍐屾垨婵�娲绘祦绋嬫椂锛屾偍搴斿綋鎸夊钩鍙扮浉搴旈〉闈㈢殑鎻愮ず鍑嗙‘瀹屾暣鍦版彁渚涘苟鍙婃椂鏇存柊鎮ㄧ殑淇℃伅锛屼互浣夸箣鐪熷疄銆佸強鏃讹紝瀹屾暣鍜屽噯纭�傚湪鍥藉娉曞緥娉曡鏈夋槑纭瀹氳姹傚钩鍙颁綔涓哄钩鍙版湇鍔℃彁渚涜�呭繀椤诲鐢ㄦ埛锛堝浜哄姏璧勬簮鍏徃绛夛級鐨勪俊鎭繘琛屾牳瀹炵殑鎯呭喌涓嬶紝骞冲彴灏嗕緷娉曚笉鏃跺湴瀵规偍鐨勪俊鎭繘琛屾鏌ユ牳瀹烇紝鎮ㄥ簲褰撻厤鍚堟彁渚涙渶鏂般�佺湡瀹炪�佸畬鏁淬�佹湁鏁堢殑淇℃伅銆�
+ </div>
+ <div>
+ 6.2.濡傚钩鍙版寜鎮ㄦ渶鍚庝竴娆℃彁渚涚殑淇℃伅涓庢偍鑱旂郴鏈灉銆佹偍鏈寜骞冲彴鐨勮姹傚強鏃舵彁渚涗俊鎭�佹偍鎻愪緵鐨勪俊鎭瓨鍦ㄦ槑鏄句笉瀹炴垨琛屾斂鍙告硶鏈哄叧鏍稿疄鎮ㄦ彁渚涚殑淇℃伅鏃犳晥鐨勶紝鎮ㄥ皢鎵挎媴鍥犳瀵规偍鑷韩銆佷粬浜哄強骞冲彴閫犳垚鐨勫叏閮ㄦ崯澶变笌涓嶅埄鍚庢灉銆傚钩鍙板彲鍚戞偍鍙戝嚭璇㈤棶鎴栬姹傛暣鏀圭殑閫氱煡锛屽苟瑕佹眰鎮ㄨ繘琛岃祫鏂欐洿鏂版垨閲嶆柊璁よ瘉锛岀洿鑷充腑姝€�佺粓姝㈠鎮ㄦ彁渚涢儴鍒嗘垨鍏ㄩ儴骞冲彴鏈嶅姟锛屽钩鍙板姝や笉鎵挎媴璐d换銆�
+ </div>
+ <div>
+ 6.3.鎮ㄨ缃殑璐︽埛鐧诲綍鍚嶅強鏄电О涓嶅緱杩濆弽鍥藉娉曞緥娉曡鍙婂钩鍙拌鍒欑殑鐩稿簲绠$悊瑙勫畾锛屽惁鍒欏钩鍙板彲鍥炴敹鎮ㄧ殑鐧诲綍鍚嶅強鏄电О锛屽苟鎸夊钩鍙拌鍒欒繘琛岀浉搴旂殑澶勭悊銆�
+ </div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="涓夈�佺敤鎴风殑鏉冨埄鍜屼箟鍔�">
+ <div>
+ 1銆佺敤鎴锋湁鏉冧娇鐢ㄦ偍璁剧疆鎴栫‘璁ょ殑閭銆佹墜鏈哄彿鐮侊紙浠ヤ笅绠�绉扳�滆处鎴峰悕绉扳�濓級鍙婃偍璁剧疆鐨勫瘑鐮侊紙璐︽埛鍚嶇О鍙婂瘑鐮佸悎绉扳�滆处鎴封�濓級鐧诲綍骞冲彴銆�
+ 鐢变簬鎮ㄧ殑骞冲彴缃戣处鎴峰叧鑱旀偍鐨勪釜浜轰俊鎭強骞冲彴鍟嗕笟淇℃伅锛屾偍鐨勫钩鍙扮綉璐︽埛浠呴檺鎮ㄦ湰浜轰娇鐢ㄣ�傛湭缁忓钩鍙板悓鎰忥紝鎮ㄧ洿鎺ユ垨闂存帴鎺堟潈绗笁鏂逛娇鐢ㄦ偍骞冲彴缃戣处鎴锋垨鑾峰彇鎮ㄨ处鎴烽」涓嬩俊鎭殑琛屼负鏃犳晥銆傚骞冲彴鍒ゆ柇鎮ㄨ处鎴风殑浣跨敤鍙兘鍗卞強鎮ㄧ殑璐︽埛瀹夊叏鍙�/鎴栧钩鍙颁俊鎭畨鍏ㄧ殑锛屽钩鍙板彲鎷掔粷鎻愪緵鐩稿簲鏈嶅姟鎴栫粓姝㈡湰鍗忚銆�
+ </div>
+ <div>
+ 2銆佺敤鎴峰簲绉瀬缁存姢骞冲彴杩愯惀绉╁簭锛屼笉寰楅�氳繃杞欢銆佺▼搴忕瓑鏂瑰紡锛屽ぇ鎵归噺娉ㄥ唽璐︽埛锛屽Θ瀹冲钩鍙拌繍钀ョЗ搴忥紙浠ヤ笅绠�绉扳�滀笉褰撴敞鍐屸�濓級銆傚浜庡钩鍙版帓鏌ュ埌鐨勬秹瀚屼笉褰撴敞鍐岀殑浼氬憳锛屽钩鍙板皢瑙嗘儏鑺傞噰鍙栬鍛娿�佽韩浠介獙璇併�侀檺鍒跺紑閫氬睍鍙般�侀檺鍒惰喘涔扮綉绔欑浉鍏虫湇鍔°�侀檺鍒跺彂甯冧骇鍝併�侀檺鍒剁綉绔欑櫥褰曠瓑涓存椂鎬х鐞嗘帾鏂姐��
+ </div>
+ <div>
+ 3銆佺敤鎴锋湁鏉冩牴鎹湰鏈嶅姟鍗忚鐨勮瀹氫互鍙婂钩鍙颁笂鍙戝竷鐨勭浉鍏宠鍒欏埄鐢ㄥ钩鍙板彂甯冧紒涓氫俊鎭�佷氦鏄撲俊鎭�佹煡璇骇鍝併�佷骇鍝佺浉鍏充俊鎭強鍏朵粬鏈嶅姟淇℃伅銆佽揪鎴愪氦鏄撴剰鍚戝苟杩涜浜ゆ槗銆佸鍏朵粬娉ㄥ唽鐢ㄦ埛杩涜璇勪环銆佸弬鍔犲钩鍙扮粍缁囩殑娲诲姩浠ュ強浣跨敤鍏跺畠淇℃伅鏈嶅姟鍙婃妧鏈湇鍔°��
+ </div>
+ <div>
+ 4銆佺敤鎴峰湪骞冲彴缃戜笂浜ゆ槗杩囩▼涓涓庡钩鍙板叾浠栫敤鎴峰洜浜ゆ槗浜х敓绾犵悍锛屽彲浠ヨ姹傚钩鍙颁粠涓簣浠ュ崗璋冦�傜敤鎴峰鍙戠幇骞冲彴鍏朵粬鐢ㄦ埛鏈夎繚娉曟垨杩濆弽鏈湇鍔″崗璁殑琛屼负锛屽彲浠ュ悜骞冲彴杩涜鍙嶆槧瑕佹眰澶勭悊銆傚鐢ㄦ埛鍥犵綉涓婁氦鏄撲笌鍏朵粬鐢ㄦ埛浜х敓璇夎鐨勶紝鐢ㄦ埛鏈夋潈閫氳繃鍙告硶閮ㄩ棬瑕佹眰骞冲彴鎻愪緵鐩稿叧璧勬枡锛�
+ </div>
+ <div>
+ 5銆佺敤鎴锋湁涔夊姟鍦ㄦ敞鍐屾椂鎻愪緵鑷繁鐨勭湡瀹炶祫鏂欙紝骞朵繚璇佽濡傜數瀛愰偖浠跺湴鍧�銆佽仈绯荤數璇濄�佽仈绯诲湴鍧�銆侀偖鏀跨紪鐮佺瓑鍐呭鐨勬湁鏁堟�у強瀹夊叏鎬э紝淇濊瘉骞冲彴鍙婂钩鍙板叾浠栫敤鎴峰彲浠ラ�氳繃涓婅堪鑱旂郴鏂瑰紡涓庤嚜宸辫繘琛岃仈绯汇�傚悓鏃讹紝鐢ㄦ埛涔熸湁涔夊姟鍦ㄧ浉鍏宠祫鏂欏疄闄呭彉鏇存椂鍙婃椂鏇存柊鏈夊叧娉ㄥ唽璧勬枡銆傜敤鎴蜂繚璇佷笉浠ヤ粬浜鸿祫鏂欏湪骞冲彴涓婅繘琛屾敞鍐屾垨璁よ瘉锛涘鐢ㄦ埛鎻愪緵鐨勪俊鎭笉鐪熷疄銆佷笉鍑嗙‘銆佷笉鍙婃椂鎴栦笉瀹屽叏锛屾垨骞冲彴鏈夊悎鐞嗙殑鐞嗙敱鎬�鐤戝叾鐪熷疄鎬с�佸噯纭�с�佸強鏃舵�у拰瀹屾暣鎬э紝鍒欏钩鍙版湁鏉冭鎯呭喌瀵圭敤鎴烽噰鍙栬鍛娿�佽处鎴烽檺鏉冮檺鍒剁洿鑷宠处鎴峰睆钄界瓑绠$悊鎺柦锛屽苟鏈夋潈鎷掔粷鐢ㄦ埛浣跨敤浠讳綍鐜版湁鐨勬湇鍔″強浠ュ悗鍙兘鎻愪緵鐨勪换浣曞姛鑳芥垨鏈嶅姟銆�
+ </div>
+ <div>
+ 6銆佺敤鎴峰簲鍏呭垎浜嗚В骞跺悓鎰忥紝818浜哄姏璧勬簮浜т笟閾惧钩鍙版槸涓�涓涓氬钩鍙帮紝鏁呮偍鐨勮浠枫�侀噰璐涓哄簲褰撳熀浜庣湡瀹炵殑琛屼笟闇�姹傦紝涓嶅緱瀛樺湪瀵逛骇鍝佸強/鎴栨湇鍔″疄鏂芥伓鎰忚浠枫�侀噰璐�佹伓鎰忕淮鏉冪瓑鎵颁贡骞冲彴姝e父浜ゆ槗绉╁簭鐨勮涓恒�傚熀浜庣淮鎶ゅ钩鍙颁氦鏄撶З搴忓強浜ゆ槗瀹夊叏鐨勯渶瑕侊紝骞冲彴鍙戠幇涓婅堪鎯呭舰鏃跺彲涓诲姩鎵ц鍏抽棴鐩稿叧浜ゆ槗璁㈠崟绛夋搷浣溿��
+ </div>
+ <div>7銆佺敤鎴峰湪骞冲彴涓婁笉寰楀彂甯冨涓嬪悇绫昏繚娉曟垨杩濊淇℃伅锛�</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍥涖�佸钩鍙扮殑鏉冨埄鍜屼箟鍔�">
+ <div>
+ 1銆佸钩鍙版湁涔夊姟鍦ㄧ幇鏈夋妧鏈笂缁存姢鏁翠釜骞冲彴鐨勬甯歌繍琛岋紝骞跺姫鍔涙彁鍗囧拰鏀硅繘鎶�鏈紝浣跨敤鎴风綉涓婁氦鏄撴椿鍔ㄥ緱浠ラ『鍒╄繘琛岋紱
+ </div>
+ <div>
+ 2銆佸鐢ㄦ埛鍦ㄦ敞鍐屼娇鐢ㄥ钩鍙颁腑鎵�閬囧埌鐨勪笌浜ゆ槗鎴栨敞鍐屾湁鍏崇殑闂鍙婂弽鏄犵殑鎯呭喌锛屽钩鍙板簲鍙婃椂浣滃嚭鍥炲锛�
+ </div>
+ <div>
+ 3銆佸浜庣敤鎴峰湪骞冲彴涓婄殑涓嶅綋琛屼负鎴栧叾瀹冧换浣曞钩鍙拌涓哄簲褰撶粓姝㈡湇鍔$殑鎯呭喌锛屽钩鍙版湁鏉冮殢鏃朵綔鍑哄垹闄ょ浉鍏充俊鎭�佺粓姝㈡湇鍔℃彁渚涚瓑澶勭悊锛岃�屾棤椤诲緛寰楃敤鎴风殑鍚屾剰锛�
+ </div>
+ <div>
+ 4銆佸洜缃戜笂浜ゆ槗骞冲彴鐨勭壒娈婃�э紝骞冲彴娌℃湁涔夊姟瀵规墍鏈夌敤鎴风殑娉ㄥ唽鏁版嵁銆佹墍鏈夌殑浜ゆ槗琛屼负浠ュ強涓庝氦鏄撴湁鍏崇殑鍏跺畠浜嬮」杩涜浜嬪厛瀹℃煡锛屼絾濡傚瓨鍦ㄤ笅鍒楁儏鍐碉細
+ <div>1锛夌敤鎴锋垨鍏跺畠绗笁鏂归�氱煡骞冲彴锛岃涓烘煇涓叿浣撶敤鎴锋垨鍏蜂綋浜ゆ槗浜嬮」鍙兘瀛樺湪閲嶅ぇ闂锛�</div>
+ <div>
+ 2锛夌敤鎴锋垨鍏跺畠绗笁鏂瑰悜骞冲彴鍛婄煡骞冲彴涓婃湁杩濇硶鎴栦笉褰撹涓虹殑锛屽钩鍙颁互鏅�氶潪涓撲笟浜ゆ槗鑰呯殑鐭ヨ瘑姘村钩鏍囧噯瀵圭浉鍏冲唴瀹硅繘琛屽垽鍒紝鍙互鏄庢樉璁や负杩欎簺鍐呭鎴栬涓哄叿鏈夎繚娉曟垨涓嶅綋鎬ц川鐨勶紱
+ </div>
+ <div>
+ 閽堝涓婅堪鎯呭喌锛堝寘鎷絾涓嶉檺浜庯級锛屽钩鍙版湁鏉冩牴鎹笉鍚屾儏鍐甸�夋嫨淇濈暀鎴栧垹闄ょ浉鍏充俊鎭垨缁х画銆佸仠姝㈠璇ョ敤鎴锋彁渚涙湇鍔★紝骞惰拷绌剁浉鍏虫硶寰嬭矗浠汇��
+ </div>
+ </div>
+ <div>
+ 5銆佺敤鎴峰湪骞冲彴浜ゆ槗杩囩▼涓涓庡钩鍙板叾瀹冪敤鎴峰洜浜ゆ槗浜х敓绾犵悍锛岃姹傚钩鍙颁粠涓簣浠ヨ皟澶勶紝缁忓钩鍙板鏍稿悗锛屽钩鍙版湁鏉冮�氳繃鐢佃瘽銆佺數瀛愰偖浠剁瓑鑱旂郴鏂瑰紡鍚戠籂绾峰弻鏂逛簡瑙f儏鍐碉紝骞跺皢鎵�浜嗚В鐨勬儏鍐甸�氳繃鐢佃瘽銆佺數瀛愰偖浠剁瓑鑱旂郴鏂瑰紡浜掔浉閫氱煡瀵规柟锛�
+ </div>
+ <div>
+ 6銆佺敤鎴峰洜鍦ㄥ钩鍙颁笂浜ゆ槗涓庡叾瀹冪敤鎴蜂骇鐢熻瘔璁肩殑锛岀敤鎴烽�氳繃鍙告硶閮ㄩ棬鎴栬鏀块儴闂ㄤ緷鐓ф硶瀹氱▼搴忚姹傚钩鍙版彁渚涚浉鍏虫暟鎹紝骞冲彴搴旂Н鏋侀厤鍚堝苟鎻愪緵鏈夊叧璧勬枡锛�
+ </div>
+ <div>
+ 7銆佸钩鍙版湁鏉冨鐢ㄦ埛鐨勬敞鍐屾暟鎹強浜ゆ槗琛屼负杩涜鏌ラ槄锛屽彂鐜版敞鍐屾暟鎹垨浜ゆ槗琛屼负涓瓨鍦ㄤ换浣曢棶棰樻垨鎬�鐤戯紝鍧囨湁鏉冨悜鐢ㄦ埛鍙戝嚭璇㈤棶鍙婅姹傛敼姝g殑閫氱煡鎴栬�呯洿鎺ヤ綔鍑哄垹闄ょ瓑澶勭悊锛�
+ </div>
+ <div>
+ 8銆佺粡鍥藉鐢熸晥娉曞緥鏂囦功鎴栬鏀垮缃氬喅瀹氱‘璁ょ敤鎴峰瓨鍦ㄨ繚娉曡涓猴紝鎴栬�呭钩鍙版湁瓒冲浜嬪疄渚濇嵁鍙互璁ゅ畾鐢ㄦ埛瀛樺湪杩濇硶鎴栬繚鍙嶆湇鍔″崗璁涓虹殑锛屽钩鍙版湁鏉冨湪骞冲彴涓婁互鍏憡鍙戝竷鐨勫舰寮忓叕甯冪敤鎴风殑杩濇硶琛屼负锛�
+ </div>
+ <div>
+ 9銆佸浜庣敤鎴峰湪骞冲彴鍙戝竷鐨勪笅鍒楀悇绫讳俊鎭紝骞冲彴鏈夋潈鍦ㄤ笉閫氱煡鐢ㄦ埛鐨勫墠鎻愪笅杩涜鍒犻櫎鎴栭噰鍙栧叾瀹冮檺鍒舵�ф帾鏂斤紝鍖呮嫭浣嗕笉闄愪簬浠ヨ閬胯垂鐢ㄤ负鐩殑鐨勪俊鎭紱浠ョ倰浣滀俊鐢ㄤ负鐩殑鐨勪俊鎭紱骞冲彴鏈夌悊鐢辩浉淇″瓨鍦ㄦ璇堢瓑鎭舵剰鎴栬櫄鍋囧唴瀹圭殑淇℃伅锛涘钩鍙版湁鐞嗙敱鐩镐俊涓庣綉涓婁氦鏄撴棤鍏虫垨涓嶆槸浠ヤ氦鏄撲负鐩殑鐨勪俊鎭紱骞冲彴鏈夌悊鐢辩浉淇″瓨鍦ㄦ伓鎰忕珵浠锋垨鍏跺畠璇曞浘鎵颁贡姝e父浜ゆ槗绉╁簭鍥犵礌鐨勪俊鎭紱骞冲彴鏈夌悊鐢辩浉淇¤淇℃伅杩濆弽鍏叡鍒╃泭鎴栧彲鑳戒弗閲嶆崯瀹冲钩鍙板拰鍏跺畠鐢ㄦ埛鍚堟硶鍒╃泭鐨勶紱
+ </div>
+ <div>
+ 10銆佺敤鎴峰洜杩涜浜ゆ槗銆佽幏鍙栨湁鍋挎湇鍔℃垨鎺ヨЕ骞冲彴鏈嶅姟鍣ㄨ�屽彂鐢熺殑鎵�鏈夊簲绾崇◣璧嬶紝浠ュ強涓�鍒囩‖浠躲�佽蒋浠躲�佹湇鍔″強鍏跺畠鏂归潰鐨勮垂鐢ㄥ潎鐢辩敤鎴疯礋璐f敮浠橈紱
+ </div>
+ <div>
+ 11銆佸钩鍙颁粎浣滀负浜ゆ槗鍦扮偣銆傚钩鍙颁粎浣滀负鐢ㄦ埛鐗╄壊浜ゆ槗瀵硅薄锛屽氨浜у搧鍜屾湇鍔$殑浜ゆ槗杩涜鍗忓晢锛屼互鍙婅幏鍙栧悇绫荤浉鍏崇殑鏈嶅姟鐨勫湴鐐广�傚钩鍙颁笉鑳芥帶鍒朵氦鏄撴墍娑夊強鐨勭墿鍝併�佹湇鍔$殑璐ㄩ噺銆佸畨鍏ㄦ垨鍚堟硶鎬э紝淇℃伅鐨勭湡瀹炴�ф垨鍑嗙‘鎬э紝浠ュ強浜ゆ槗鏂瑰饱琛屽叾鍦ㄥ崗璁」涓嬬殑鍚勯」涔夊姟鐨勮兘鍔涳紱
+ </div>
+ <div>
+ 12銆佸钩鍙板苟涓嶄綔涓轰拱瀹舵垨鏄崠瀹剁殑韬唤鍙備笌涔板崠琛屼负鐨勬湰韬�傚钩鍙版彁閱掔敤鎴峰簲璇ラ�氳繃鑷繁鐨勮皑鎱庡垽鏂‘瀹氱浉鍏充俊鎭殑鐪熷疄鎬с�佸悎娉曟�у拰鏈夋晥鎬э紱
+ </div>
+ <div>
+ 13銆佽鍙娇鐢ㄦ潈銆�
+ 鐢ㄦ埛浠ユ鎺堜簣骞冲彴鍙婂叾鍏宠仈鍏徃鐙鐨勩�佸叏鐞冮�氱敤鐨勩�佹案涔呯殑銆佸厤璐圭殑璁稿彲浣跨敤鏉冨埄
+ (骞舵湁鏉冨湪澶氫釜灞傞潰瀵硅鏉冨埄杩涜鍐嶆巿鏉�)锛屼娇骞冲彴鍙婂叾鍏宠仈鍏徃鏈夋潈(鍏ㄩ儴鎴栭儴浠藉湴)
+ 浣跨敤銆佸鍒躲�佷慨璁€�佹敼鍐欍�佸彂甯冦�佺炕璇戙�佸垎鍙戙�佹墽琛屽拰灞曠ず鐢ㄦ埛鐨勫叏閮ㄨ祫鏂欐暟鎹紙鍖呮嫭浣嗕笉闄愪簬娉ㄥ唽璧勬枡銆佷氦鏄撹涓烘暟鎹強鍏ㄩ儴灞曠ず浜庣綉绔欑殑鍚勭被淇℃伅锛夋垨鍒朵綔鍏舵淳鐢熶綔鍝侊紝鍜�/鎴栦互鐜板湪宸茬煡鎴栨棩鍚庡紑鍙戠殑浠讳綍褰㈠紡銆佸獟浣撴垨鎶�鏈紝灏嗕笂杩颁俊鎭撼鍏ュ叾瀹冧綔鍝佸唴銆�
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="浜斻�佺敤鎴风殑杩濈害鍙婂鐞�">
+ <div>1銆佽繚绾﹁瀹�</div>
+ <div>鍙戠敓濡備笅鎯呭舰涔嬩竴鐨勶紝瑙嗕负鎮ㄨ繚绾︼細</div>
+ <div>1.浣跨敤骞冲彴鏈嶅姟鏃惰繚鍙嶆湁鍏虫硶寰嬫硶瑙勮瀹氱殑锛�</div>
+ <div>2.杩濆弽鏈崗璁垨骞冲彴灏嗗湪鏈潵鏇存柊鐨勫叾浠栫被鍨嬬殑琛ュ厖鍗忚鐨勶紱</div>
+ <div>
+ 涓洪�傚簲鐢靛瓙鍟嗗姟鍙戝睍鍜屾弧瓒虫捣閲忕敤鎴峰楂樻晥浼樿川鏈嶅姟鐨勯渶姹傦紝鎮ㄧ悊瑙e苟鍚屾剰锛屽钩鍙板彲鍦ㄥ钩鍙拌鍒欎腑绾﹀畾杩濈害璁ゅ畾鐨勭▼搴忓拰鏍囧噯銆傚锛氬钩鍙板彲渚濇嵁鎮ㄧ殑鐢ㄦ埛鏁版嵁涓庢捣閲忕敤鎴锋暟鎹殑鍏崇郴鏉ヨ瀹氭偍鏄惁鏋勬垚杩濈害锛涙偍鏈変箟鍔″鎮ㄧ殑鏁版嵁寮傚父鐜拌薄杩涜鍏呭垎涓捐瘉鍜屽悎鐞嗚В閲婏紝鍚﹀垯灏嗚璁ゅ畾涓鸿繚绾︺��
+ </div>
+ <div>2銆佽繚绾﹀鐞嗘帾鏂�</div>
+ <div>
+ 1.鎮ㄥ湪骞冲彴涓婂彂甯冪殑淇℃伅鏋勬垚杩濈害鐨勶紝骞冲彴鍙牴鎹浉搴旇鍒欑珛鍗冲鐩稿簲淇℃伅杩涜鍒犻櫎銆佸睆钄藉鐞嗐��
+ </div>
+ <div>
+ 2.鎮ㄥ湪骞冲彴涓婂疄鏂界殑琛屼负锛屾垨铏芥湭鍦ㄥ钩鍙颁笂瀹炴柦浣嗗骞冲彴鍙婂叾鐢ㄦ埛浜х敓褰卞搷鐨勮涓烘瀯鎴愯繚绾︾殑锛屽钩鍙板彲渚濇嵁鐩稿簲瑙勫垯瀵规偍鎵ц璐︽埛鎯╂垝銆侀檺鍒跺弬鍔犳椿鍔ㄣ�佷腑姝㈠悜鎮ㄦ彁渚涢儴鍒嗘垨鍏ㄩ儴鏈嶅姟銆佸垝鎵h繚绾﹂噾绛夊鐞嗘帾鏂姐�傚鎮ㄧ殑琛屼负鏋勬垚鏍规湰杩濈害鐨勶紝骞冲彴鍙叧闂偍鐨勮处鎴凤紝缁堟鍚戞偍鎻愪緵鏈嶅姟銆�
+ </div>
+ <div>
+ 3.褰撴偍杩濈害鐨勫悓鏃跺瓨鍦ㄦ璇堛�佸敭鍋囥�佺洍鐢ㄤ粬浜鸿处鎴风瓑鐗瑰畾鎯呭舰鎴栨偍瀛樺湪鍗卞強浠栦汉浜ゆ槗瀹夊叏鎴栬处鎴峰畨鍏ㄩ闄╂椂锛屽钩鍙颁細渚濈収鎮ㄨ涓虹殑椋庨櫓绋嬪害瀵规偍鐨勫钩鍙拌处鎴烽噰鍙栧彇娑堟敹娆俱�佽祫閲戞浠樼瓑寮哄埗鎺柦銆�
+ </div>
+ <div>
+ 4.骞冲彴鍙皢瀵规偍涓婅堪杩濈害琛屼负澶勭悊鎺柦淇℃伅浠ュ強鍏朵粬缁忓浗瀹惰鏀挎垨鍙告硶鏈哄叧鐢熸晥娉曞緥鏂囦功纭鐨勮繚娉曚俊鎭湪骞冲彴涓婁簣浠ュ叕绀恒��
+ </div>
+ <div>3銆佽禂鍋胯矗浠�</div>
+ <div>
+ 1.濡傛偍鐨勮涓轰娇骞冲彴閬彈鎹熷け锛堝寘鎷嚜韬殑鐩存帴缁忔祹鎹熷け銆佸晢瑾夋崯澶卞強瀵瑰鏀粯鐨勮禂鍋块噾銆佸拰瑙f銆佸緥甯堣垂銆佽瘔璁艰垂绛夐棿鎺ョ粡娴庢崯澶憋級锛屾偍搴旇禂鍋垮钩鍙扮殑涓婅堪鍏ㄩ儴鎹熷け銆�
+ </div>
+ <div>
+ 2.濡傛偍鐨勮涓轰娇骞冲彴閬彈绗笁浜轰富寮犳潈鍒╋紝骞冲彴鍙湪瀵圭涓変汉鎵挎媴閲戦挶缁欎粯绛変箟鍔″悗灏卞叏閮ㄦ崯澶卞悜鎮ㄨ拷鍋裤��
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍏�佹湇鍔$殑涓柇鍜岀粓姝�">
+ <div>
+ 1銆佺敤鎴峰悓鎰忥紝鍦ㄥ钩鍙版湭鍚戠敤鎴锋敹鍙栨湇鍔¤垂鐨勬儏鍐典笅锛屽钩鍙板彲鑷鍏ㄦ潈鍐冲畾浠ヤ换浣曠悊鐢�
+ (鍖呮嫭浣嗕笉闄愪簬骞冲彴璁や负鐢ㄦ埛宸茶繚鍙嶆湰鍗忚鐨勫瓧闈㈡剰涔夊拰绮剧锛屾垨浠ヤ笉绗﹀悎鏈崗璁殑瀛楅潰鎰忎箟鍜岀簿绁炵殑鏂瑰紡琛屼簨锛屾垨鐢ㄦ埛鍦ㄨ秴杩�180澶╃殑鏃堕棿鍐呮湭浠ョ敤鎴风殑璐﹀彿鍙婂瘑鐮佺櫥褰曠綉绔欑瓑)
+ 缁堟鐢ㄦ埛鐨勨�滄湇鍔♀�濆瘑鐮併�佽处鎴� (鎴栧叾浠讳綍閮ㄤ唤)
+ 鎴栫敤鎴峰鈥滄湇鍔♀�濈殑浣跨敤锛屽苟鍒犻櫎锛堜笉鍐嶄繚瀛橈級鐢ㄦ埛鍦ㄤ娇鐢ㄢ�滄湇鍔♀�濅腑鎻愪氦鐨勪换浣曡祫鏂欍�傚悓鏃跺钩鍙板彲鑷鍏ㄦ潈鍐冲畾锛屽湪鍙戝嚭閫氱煡鎴栦笉鍙戝嚭閫氱煡鐨勬儏鍐典笅锛岄殢鏃跺仠姝㈡彁渚涒�滄湇鍔♀�濇垨鍏朵换浣曢儴浠姐�傝处鍙风粓姝㈠悗锛屽钩鍙版病鏈変箟鍔′负鐢ㄦ埛淇濈暀鍘熻处鍙蜂腑鎴栦笌涔嬬浉鍏崇殑浠讳綍淇℃伅锛屾垨杞彂浠讳綍鏈浘闃呰鎴栧彂閫佺殑淇℃伅缁欑敤鎴锋垨绗笁鏂广�傛澶栵紝鐢ㄦ埛鍚屾剰锛屽钩鍙颁笉灏辩粓姝㈢敤鎴锋帴鍏モ�滄湇鍔♀�濊�屽鐢ㄦ埛鎴栦换浣曠涓夎�呮壙鎷呬换浣曡矗浠伙紱
+ </div>
+ <div>
+ 2銆佸鐢ㄦ埛鍚戝钩鍙版彁鍑烘敞閿�骞冲彴娉ㄥ唽鐢ㄦ埛韬唤鏃讹紝缁忓钩鍙板鏍稿悓鎰忥紝鐢卞钩鍙版敞閿�璇ユ敞鍐岀敤鎴凤紝鐢ㄦ埛鍗宠В闄や笌骞冲彴鐨勬湇鍔″崗璁叧绯汇�備絾娉ㄩ攢璇ョ敤鎴疯处鍙峰悗锛屽钩鍙颁粛淇濈暀涓嬪垪鏉冨埄锛�
+ </div>
+ <div>1锛夌敤鎴锋敞閿�鍚庯紝骞冲彴鏈夋潈淇濈暀璇ョ敤鎴风殑娉ㄥ唽鏁版嵁鍙婁互鍓嶇殑浜ゆ槗琛屼负璁板綍锛�</div>
+ <div>
+ 2锛夌敤鎴锋敞閿�鍚庯紝濡傜敤鎴峰湪娉ㄩ攢鍓嶅湪骞冲彴浜ゆ槗骞冲彴涓婂瓨鍦ㄨ繚娉曡涓烘垨杩濆弽鍚堝悓鐨勮涓猴紝骞冲彴浠嶅彲琛屼娇鏈湇鍔″崗璁墍瑙勫畾鐨勬潈鍒┿��
+ </div>
+ <div>3銆佸湪涓嬪垪鎯呭喌涓嬶紝骞冲彴鍙互閫氳繃娉ㄩ攢鐢ㄦ埛鐨勬柟寮忕粓姝㈡湇鍔★細</div>
+ <div>
+ 1锛夊湪鐢ㄦ埛杩濆弽鏈湇鍔″崗璁浉鍏宠瀹氭椂锛屽钩鍙版湁鏉冪粓姝㈠悜璇ョ敤鎴锋彁渚涙湇鍔°�傚钩鍙板皢鍦ㄤ腑鏂湇鍔℃椂閫氱煡鐢ㄦ埛銆備絾濡傝鐢ㄦ埛鍦ㄨ骞冲彴缁堟鎻愪緵鏈嶅姟鍚庯紝鍐嶄竴娆$洿鎺ユ垨闂存帴鎴栦互浠栦汉鍚嶄箟娉ㄥ唽涓哄钩鍙扮敤鎴风殑锛屽钩鍙版湁鏉冨啀娆″崟鏂归潰缁堟鍚戣鐢ㄦ埛鎻愪緵鏈嶅姟锛�
+ </div>
+ <div>
+ 2锛夊骞冲彴閫氳繃鐢ㄦ埛鎻愪緵鐨勪俊鎭笌鐢ㄦ埛鑱旂郴鏃讹紝鍙戠幇鐢ㄦ埛鍦ㄦ敞鍐屾椂濉啓鐨勬墜鏈哄彿鐮併�佺數瀛愰偖绠卞凡涓嶅瓨鍦ㄦ垨鏃犳硶鎺ュ惉鐢佃瘽鎴栨帴鏀剁數瀛愰偖浠剁殑锛岀粡骞冲彴浠ュ叾瀹冭仈绯绘柟寮忛�氱煡鐢ㄦ埛鏇存敼锛岃�岀敤鎴峰湪涓変釜宸ヤ綔鏃ュ唴浠嶆湭鑳芥彁渚涙柊鐨勬墜鏈哄彿鐮佹垨鐢靛瓙閭鍦板潃鐨勶紝骞冲彴鏈夋潈缁堟鍚戣鐢ㄦ埛鎻愪緵鏈嶅姟锛�
+ </div>
+ <div>
+ 3锛変竴鏃﹀钩鍙板彂鐜扮敤鎴锋敞鍐屾暟鎹腑涓昏鍐呭鏄櫄鍋囩殑锛屽钩鍙版湁鏉冮殢鏃剁粓姝㈠悜璇ョ敤鎴锋彁渚涙湇鍔★紱
+ </div>
+ <div>
+ 4锛変竴鏃﹀钩鍙板彂鐜扮敤鎴风洍鐢ㄤ粬浜鸿处鎴枫�佸彂甯冭繚绂佷俊鎭�佹璇堛�佸敭鍋囥�佹壈涔卞競鍦虹З搴忋�侀噰鍙栦笉姝e綋鎵嬫鐗熷埄绛夎涓虹殑锛屽钩鍙版湁鏉冮殢鏃剁粓姝㈠悜璇ョ敤鎴锋彁渚涙湇鍔★紱
+ </div>
+ <div>
+ 5锛夊钩鍙板熀浜庡悎鐞嗙悊鐢辩浉淇$敤鎴风殑琛屼负鍙兘浼氫娇骞冲彴鍙婂钩鍙扮敤鎴风瓑鐩稿叧鏂瑰彂鐢熶弗閲嶆崯瀹虫垨浜х敓娉曞緥璐d换鐨勶紝骞冲彴鏈夋潈闅忔椂缁堟鍚戣鐢ㄦ埛鎻愪緵鏈嶅姟锛�
+ </div>
+ <div>6锛夊浜庨殣鐬掑叾浠庝簨鍚屼笟浜掕仈缃戞湇鍔$殑鐢ㄦ埛锛屽钩鍙颁竴缁忓彂鐜帮紝鏈夋潈绔嬪嵆缁堟鏈嶅姟锛�</div>
+ <div>7锛夋湰鏈嶅姟鍗忚缁堟鎴栨洿鏂版椂锛岀敤鎴锋槑绀轰笉鎰挎帴鍙楁柊鐨勬湇鍔″崗璁殑锛�</div>
+ <div>8锛夊叾瀹冨钩鍙拌涓洪渶缁堟鏈嶅姟鐨勬儏鍐点��</div>
+ <div>
+ 4銆佹湇鍔′腑鏂�佺粓姝箣鍓嶇敤鎴蜂氦鏄撹涓虹殑澶勭悊鍥犵敤鎴疯繚鍙嶆硶寰嬫硶瑙勬垨鑰呰繚鍙嶆湇鍔″崗璁瀹氳�岃嚧浣垮钩鍙颁腑鏂�佺粓姝㈠鐢ㄦ埛鏈嶅姟鐨勶紝瀵逛簬鏈嶅姟涓柇銆佺粓姝箣鍓嶇敤鎴蜂氦鏄撹涓轰緷涓嬪垪鍘熷垯澶勭悊锛�
+ </div>
+ <div>
+ 1锛夋湇鍔′腑鏂�佺粓姝箣鍓嶏紝鐢ㄦ埛宸茬粡涓婁紶鑷冲钩鍙扮殑浜у搧灏氭湭浜ゆ槗鎴栧皻鏈氦鏄撳畬鎴愮殑锛屽钩鍙版湁鏉冨湪涓柇銆佺粓姝㈡湇鍔$殑鍚屾椂鍒犻櫎姝ら」浜у搧鐨勭浉鍏充俊鎭紱
+ </div>
+ <div>
+ 2锛夋湇鍔′腑鏂�佺粓姝箣鍓嶏紝鐢ㄦ埛宸茬粡灏卞叾瀹冪敤鎴峰嚭鍞殑鍏蜂綋浜у搧浣滃嚭瑕佺害锛屼絾浜ゆ槗灏氭湭缁撴潫锛屽钩鍙版湁鏉冨湪涓柇鎴栫粓姝㈡湇鍔$殑鍚屾椂鍒犻櫎璇ョ敤鎴风殑鐩稿叧瑕佺害锛�
+ </div>
+ <div>
+ 3锛夋湇鍔′腑鏂�佺粓姝箣鍓嶏紝鐢ㄦ埛宸茬粡涓庡彟涓�鐢ㄦ埛灏卞叿浣撲氦鏄撹揪鎴愪竴鑷达紝骞冲彴鍙互涓嶅垹闄よ椤逛氦鏄擄紝浣嗗钩鍙版湁鏉冨湪涓柇銆佺粓姝㈡湇鍔$殑鍚屾椂灏嗙敤鎴疯涓柇鎴栫粓姝㈡湇鍔$殑鎯呭喌閫氱煡鐢ㄦ埛鐨勪氦鏄撳鏂广��
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="涓冦�侀殣绉佹潈鏀跨瓥">
+ <div>1銆侀�傜敤鑼冨洿锛�</div>
+ <div>1锛夊湪鐢ㄦ埛娉ㄥ唽骞冲彴璐︽埛鏃讹紝鐢ㄦ埛鏍规嵁骞冲彴瑕佹眰鎻愪緵鐨勪釜浜烘敞鍐屼俊鎭紱</div>
+ <div>
+ 2锛夊湪鐢ㄦ埛浣跨敤骞冲彴鏈嶅姟锛屽弬鍔犲钩鍙版椿鍔紝鎴栬闂钩鍙扮綉绔欐椂锛屽钩鍙拌嚜鍔ㄦ帴鏀跺苟璁板綍鐨勭敤鎴锋祻瑙堝櫒涓婄殑鏈嶅姟鍣ㄦ暟鍊硷紝鍖呮嫭浣嗕笉闄愪簬IP鍦板潃绛夋暟鎹強鐢ㄦ埛瑕佹眰鍙栫敤鐨勭綉椤佃褰曪紱
+ </div>
+ <div>
+ 3锛夊钩鍙版敹闆嗗埌鐨勭敤鎴峰湪骞冲彴杩涜浜ゆ槗鐨勬湁鍏虫暟鎹紝鍖呮嫭浣嗕笉闄愪簬鍑轰环銆佽喘涔般�佷骇鍝佺櫥褰曘�佷俊鐢ㄨ瘎浠峰強杩濊璁板綍锛�
+ </div>
+ <div>4锛夊钩鍙伴�氳繃鍚堟硶閫斿緞浠庡晢涓氫紮浼村鍙栧緱鐨勭敤鎴蜂釜浜烘暟鎹��</div>
+ <div>
+ 5锛夋垜浠敹闆嗘暟鎹槸鏍规嵁鎮ㄤ笌鎴戜滑鐨勪簰鍔ㄥ拰鎮ㄦ墍鍋氬嚭鐨勯�夋嫨锛屽寘鎷偍鐨勯殣绉佽缃互鍙婃偍浣跨敤鐨勪骇鍝佸拰鍔熻兘銆傛垜浠敹闆嗙殑鏁版嵁鍙兘鍖呮嫭SDK/API/JS浠g爜鐗堟湰銆佹祻瑙堝櫒銆佷簰鑱旂綉鏈嶅姟鎻愪緵鍟嗐�両P鍦板潃銆佸钩鍙般�佹椂闂存埑銆佸簲鐢ㄦ爣璇嗙銆佸簲鐢ㄧ▼搴忕増鏈�佸簲鐢ㄥ垎鍙戞笭閬撱�佺嫭绔嬭澶囨爣璇嗙銆乮OS骞垮憡鏍囪瘑绗︼紙IDFA)銆佸畨鍗撳箍鍛婁富鏍囪瘑绗︺�佺綉鍗★紙MAC锛夊湴鍧�銆佸浗闄呯Щ鍔ㄨ澶囪瘑鍒爜锛圛MEI锛夈�佽澶囧瀷鍙枫�佺粓绔埗閫犲巶鍟嗐�佺粓绔澶囨搷浣滅郴缁熺増鏈�佷細璇濆惎鍔�/鍋滄鏃堕棿銆佽瑷�鎵�鍦ㄥ湴銆佹椂鍖哄拰缃戠粶鐘舵�侊紙WiFi绛夛級銆佺‖鐩樸�丆PU鍜岀數姹犱娇鐢ㄦ儏鍐电瓑銆�
+ </div>
+ <div>2銆佷俊鎭娇鐢細</div>
+ <div>1锛夊钩鍙颁笉浼氬悜浠讳綍浜哄嚭鍞垨鍑哄�熺敤鎴风殑涓汉淇℃伅锛岄櫎闈炰簨鍏堝緱鍒扮敤鎴峰緱璁稿彲銆�</div>
+ <div>
+ 2锛夊钩鍙颁害涓嶅厑璁镐换浣曠涓夋柟浠ヤ换浣曟墜娈垫敹闆嗐�佺紪杈戙�佸嚭鍞垨鑰呮棤鍋夸紶鎾敤鎴风殑涓汉淇℃伅銆備换浣曠敤鎴峰浠庝簨涓婅堪娲诲姩锛屼竴缁忓彂鐜帮紝骞冲彴鏈夋潈绔嬪嵆缁堟涓庤鐢ㄦ埛鐨勬湇鍔″崗璁紝鏌ュ皝鍏惰处鍙枫��
+ </div>
+ <div>
+ 3锛変负鏈嶅姟鐢ㄦ埛鐨勭洰鐨勶紝骞冲彴鍙兘閫氳繃浣跨敤鐢ㄦ埛鐨勪釜浜轰俊鎭紝鍚戠敤鎴锋彁渚涙湇鍔″強浜у搧鏀硅繘锛屽寘鎷絾涓嶉檺浜庡悜鐢ㄦ埛鍙戝嚭浜у搧鍜屾湇鍔′俊鎭紝鎴栬�呬笌骞冲彴鍚堜綔浼欎即鍏变韩淇℃伅浠ヤ究浠栦滑鍚戠敤鎴峰彂閫佹湁鍏冲叾浜у搧鍜屾湇鍔$殑淇℃伅锛堝悗鑰呴渶瑕佺敤鎴风殑浜嬪厛鍚屾剰锛夈�備緥濡傦紝鎴戜滑鑱樿鏉ユ彁渚涙暟鎹垎鏋愭湇鍔$殑鍏徃鍙兘闇�瑕侀噰闆嗗拰璁块棶涓汉鏁版嵁浠ヨ繘琛屾暟鎹粺璁″拰鍒嗘瀽銆傚湪杩欑鎯呭喌涓嬶紝杩欎簺鍏徃蹇呴』閬靛畧鎴戜滑鐨勬暟鎹殣绉佸拰瀹夊叏瑕佹眰銆�
+ </div>
+ <div>
+ 4锛夋垜浠凡鍦ㄤ笂鏂囦粙缁嶄簡澶勭悊涓汉鏁版嵁鐨勭洰鐨勩�傛垜浠鐞嗕釜浜烘暟鎹殑娉曞緥鍩虹鍖呮嫭锛氫负灞ヨ涓庢偍涔嬮棿鐨勫悎鍚岋紙渚嬪锛屼负鎮ㄦ彁渚涙偍鎵�璇锋眰鐨勬湇鍔°�佸鎮ㄨ繘琛岃瘑鍒拰璁よ瘉锛屼互渚挎偍鍙互浣跨敤缃戠珯锛夛紱涓洪伒瀹堟硶寰嬭姹傦紙渚嬪锛屼负閬靛畧閫傜敤鐨勪細璁¤鍒欙紝灞ヨ鎵ф硶閮ㄩ棬寮哄埗鎶湶鐨勮姹傦級锛涗负淇濇姢鎴戜滑鐨勬褰撳埄鐩婏紙渚嬪锛岀鐞嗘垜浠笌鎮ㄧ殑鍏崇郴锛屼负纭繚鎴戜滑鏈嶅姟鐨勫畨鍏ㄦ�э紝涓庢偍娌熼�氭垜浠殑浜у搧鍜屾湇鍔★級锛涗互鍙婂熀浜庢垜浠鎴风殑鍚屾剰锛堜緥濡傦紝鎶曟斁cookies锛屼负骞垮憡瀹d紶涔嬬洰鐨勪笌绗笁鏂瑰叡浜偍鐨勪俊鎭級銆傚湪鏌愪簺鎯呭喌涓嬶紝鎮ㄥ彲鑳介渶瑕佷负鎴戜滑鎻愪緵涓汉鏁版嵁浠ヨ繘琛屼笂杩扮殑澶勭悊锛屼互渚挎垜浠兘澶熶负鎮ㄦ彁渚涙垜浠殑鍏ㄩ儴鏈嶅姟锛屽苟鏂逛究鎮ㄤ娇鐢ㄦ垜浠綉绔欑殑鍏ㄩ儴鍔熻兘銆�
+ </div>
+ <div>
+ 5锛変釜浜烘暟鎹殑璺ㄥ浼犺緭銆傞拡瀵规鐩熸垚鍛樺浗鐢ㄦ埛锛屾垜浠殑涓氬姟鍙兘闇�瑕佹垜浠浆绉绘偍鐨勪釜浜烘暟鎹嚦娆ф床缁忔祹鍖轰互澶栫殑鍥藉锛堜腑鍥斤級銆傛垜浠細閲囧彇閫傚綋鐨勬帾鏂戒互纭繚鎮ㄤ釜浜烘暟鎹殑鎺ユ敹鑰呭饱琛屼繚瀵嗕箟鍔★紝骞剁‘淇濆鏍囧噯鍚堝悓鏉℃绛夋帾鏂界殑鎵ц銆傛偍鍙互閫氳繃鑱旂郴鎴戜滑鐨勫府鍔╀腑蹇冭幏寰楄繖浜涙潯娆俱��
+ </div>
+ <div>
+ 6锛夐拡瀵规鐩熸垚鍛樺浗鐢ㄦ埛锛屾牴鎹�傜敤娉曞緥锛屾偍鏈夋潈鍙嶅鎴栬姹傞檺鍒跺鎮ㄤ釜浜烘暟鎹殑澶勭悊锛屽苟瑕佹眰鎮ㄦ湰浜烘暟鎹殑璁块棶銆佹牎姝c�佸垹闄ゅ拰鍙惡甯︽潈銆傚湪瀵规偍鐨勪俊鎭殑浣跨敤鏄熀浜庢偍鐨勫悓鎰忕殑鎯呭喌涓嬶紝鎮ㄦ湁鏉冨湪浠讳綍鏃跺�欐挙鍥炶鍚屾剰锛屼絾鍚屾剰鐨勬挙鍥炰笉褰卞搷鎾ゅ洖鍓嶅熀浜庡悓鎰忚繘琛岀殑鏁版嵁澶勭悊鐨勫悎娉曟�с�傛偍鍙互閫氳繃瀹㈡湇鐢佃瘽16505012333鍚戞垜浠彁浜ゆ偍鐨勮姹傘�傚鏋滄偍鍙戠幇鎮ㄧ殑淇℃伅鍙戠敓鍙樺寲鎴栦笉鍑嗙‘锛岃灏嗚繖浜涘彉鍖栭�氱煡鎴戜滑浠ヤ究鎴戜滑鐨勮褰曞彲浠ヨ鏇存柊鎴栨洿姝c�傚鏋滄偍璁や负鎴戜滑瀵规偍涓汉鏁版嵁鐨勫鐞嗚繚鍙嶄簡閫傜敤娉曞緥锛屾偍鍙互鍚戠洃绠℃満鏋勬姇璇夈�傛垜浠鎮ㄤ釜浜烘暟鎹殑淇濈暀鏃堕棿瑙嗗悜鎮ㄦ彁渚涙湇鍔℃垨浜у搧鐨勯渶瑕佽�屽畾锛屾垨鏍规嵁閫傜敤娉曞緥濡傜◣娉曞拰浼氳娉曠殑瑕佹眰鎴栬鍙‘瀹氥��
+ </div>
+ <div>3銆佷俊鎭姭闇诧紝鐢ㄦ埛鐨勪釜浜轰俊鎭皢鍦ㄤ笅杩版儏鍐典笅閮ㄥ垎鎴栧叏閮ㄨ鎶湶锛�</div>
+ <div>1锛夌粡鐢ㄦ埛鍚屾剰锛屽悜绗笁鏂规姭闇诧紱</div>
+ <div>
+ 2锛夊鐢ㄦ埛鏄鍚堣祫鏍肩殑鐭ヨ瘑浜ф潈鎶曡瘔浜哄苟宸叉彁璧锋姇璇夛紝搴旇鎶曡瘔浜鸿姹傦紝鍚戣鎶曡瘔浜烘姭闇诧紝浠ヤ究鍙屾柟澶勭悊鍙兘鐨勬潈鍒╃籂绾凤紱
+ </div>
+ <div>
+ 3锛夋牴鎹硶寰嬬殑鏈夊叧瑙勫畾锛屾垨鑰呰鏀挎垨鍙告硶鏈烘瀯鐨勮姹傦紝鍚戠涓夋柟鎴栬�呰鏀裤�佸徃娉曟満鏋勬姭闇诧紱
+ </div>
+ <div>4锛夊鏋滅敤鎴峰嚭鐜拌繚鍙嶄腑鍥芥湁鍏虫硶寰嬫垨鑰呯綉绔欐斂绛栫殑鎯呭喌锛岄渶瑕佸悜绗笁鏂规姭闇诧紱</div>
+ <div>5锛変负鎻愪緵鎮ㄦ墍瑕佹眰鐨勪骇鍝佸拰鏈嶅姟锛岃�屽繀椤诲拰绗笁鏂瑰垎浜敤鎴风殑涓汉淇℃伅锛�</div>
+ <div>
+ 6锛夊湪骞冲彴涓婂垱寤虹殑鏌愪竴浜ゆ槗涓紝濡備氦鏄撲换浣曚竴鏂瑰饱琛屾垨閮ㄥ垎灞ヨ浜嗕氦鏄撲箟鍔″苟鎻愬嚭淇℃伅鎶湶璇锋眰鐨勶紝骞冲彴鏈夊叏鏉冨彲浠ュ喅瀹氬悜璇ョ敤鎴锋彁渚涘叾浜ゆ槗瀵规柟鐨勮仈缁滄柟寮忕瓑蹇呰淇℃伅锛屼互淇冩垚浜ゆ槗鐨勫畬鎴愭垨绾犵悍鐨勮В鍐筹紱
+ </div>
+ <div>7锛夊叾瀹冨钩鍙版牴鎹硶寰嬫垨鑰呯綉绔欐斂绛栬涓哄悎閫傜殑鎶湶銆�</div>
+ <div>4銆佷俊鎭畨鍏細</div>
+ <div>1锛夊钩鍙板強骞冲彴璐︽埛鍧囨湁瀹夊叏淇濇姢鍔熻兘锛岃濡ュ杽淇濈鐢ㄦ埛鐨勮处鎴峰強瀵嗙爜淇℃伅锛�</div>
+ <div>
+ 2锛夊湪浣跨敤骞冲彴鏈嶅姟杩涜缃戜笂浜ゆ槗鏃讹紝鐢ㄦ埛涓嶅彲閬垮厤鐨勮鍚戜氦鏄撳鏂规垨娼滃湪鐨勪氦鏄撳鏂规彁渚涜嚜宸辩殑涓汉淇℃伅锛屽鑱旂粶鏂瑰紡鎴栬�呴偖鏀垮湴鍧�銆傝鐢ㄦ埛濡ュ杽淇濇姢鑷繁鐨勪釜浜轰俊鎭紝浠呭湪蹇呰鐨勬儏褰笅鍚戜粬浜烘彁渚涳紱
+ </div>
+ <div>
+ 3锛夊鏋滅敤鎴峰彂鐜拌嚜宸辩殑涓汉淇℃伅娉勫瘑锛屽挨鍏舵槸骞冲彴璐︽埛鍙婂瘑鐮佸彂鐢熸硠闇诧紝璇风敤鎴风珛鍗宠仈缁滃钩鍙板鏈嶏紝浠ヤ究骞冲彴閲囧彇鐩稿簲鎺柦銆�
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍏�佽矗浠昏寖鍥村拰璐d换闄愬埗">
+ <div>
+ 1銆佹偍鏄庣‘鐞嗚В鍜屽悓鎰忥紝骞冲彴涓嶅鍥犱笅杩颁换涓�鎯呭喌鑰屽彂鐢熺殑浠讳綍鎹熷璧斿伩鎵挎媴璐d换锛屽寘鎷絾涓嶉檺浜庡埄娑︺�佸晢瑾夈�佷娇鐢ㄣ�佹暟鎹瓑鏂归潰鐨勬崯澶辨垨鍏朵粬鏃犲舰鎹熷け鐨勬崯瀹宠禂鍋�
+ (鏃犺骞冲彴鏄惁宸茶鍛婄煡璇ョ瓑鎹熷璧斿伩鐨勫彲鑳芥��)锛�
+ </div>
+ <div>1锛変娇鐢ㄦ垨鏈兘浣跨敤鈥滄湇鍔★紱</div>
+ <div>2锛夌涓夋柟鏈粡鎵瑰噯鐨勬帴鍏ユ垨绗笁鏂规洿鏀圭敤鎴风殑浼犺緭鏁版嵁鎴栨暟鎹紱</div>
+ <div>
+ 3锛夌涓夋柟瀵光�滄湇鍔♀�濈殑澹版槑鎴栧叧浜庘�滄湇鍔♀�濈殑琛屼负锛涙垨闈炲洜骞冲彴鐨勫師鍥犺�屽紩璧风殑涓庘�滄湇鍔♀�濇湁鍏崇殑浠讳綍鍏跺畠浜嬪疁锛屽寘鎷枏蹇姐��
+ </div>
+ <div>
+ 2銆佸钩鍙颁細灏戒竴鍒囧姫鍔涗娇鎮ㄥ湪浣跨敤骞冲彴鐨勮繃绋嬩腑寰楀埌涔愯叮銆傞仐鎲剧殑鏄紝骞冲彴涓嶈兘闅忔椂棰勮鍒颁换浣曟妧鏈笂鐨勯棶棰樻垨鍏朵粬鍥伴毦銆傝绛夊洶闅惧彲鑳戒細瀵艰嚧鏁版嵁鎹熷け鎴栧叾浠栨湇鍔′腑鏂�備负姝わ紝鎮ㄦ槑纭悊瑙e拰鍚屾剰锛屾偍浣跨敤鈥滄湇鍔♀�濈殑椋庨櫓鐢辨偍鑷鎵挎媴锛屼笖鈥滄湇鍔♀�濅互鈥滄寜鐜扮姸鈥濆拰鈥滄寜鍙緱鍒�
+ 鈥濈殑鐘舵�佹彁渚涖�傚钩鍙版槑纭0鏄庝笉浣滀换浣曠绫荤殑鏄庣ず鎴栨殫绀虹殑淇濊瘉锛屽寘鎷絾涓嶉檺浜庡叧浜庨�傞攢鎬с�侀�傜敤浜庢煇涓�鐗瑰畾鐢ㄩ�斿拰鏃犱镜鏉冭涓虹瓑鏂归潰鐨勪繚璇併�傚钩鍙板涓嬭堪鍐呭涓嶄綔淇濊瘉锛�
+ </div>
+ <div>1锛夆�滄湇鍔♀�濅細绗﹀悎鎮ㄧ殑瑕佹眰锛�</div>
+ <div>2锛夆�滄湇鍔♀�濅笉浼氫腑鏂紝涓旈�傛椂銆佸畨鍏ㄥ拰涓嶅甫浠讳綍閿欒锛�</div>
+ <div>3锛夐�氳繃浣跨敤鈥滄湇鍔♀�濊�屽彲鑳借幏鍙栫殑缁撴灉灏嗘槸鍑嗙‘鎴栧彲淇¤禆鐨勶紱</div>
+ <div>
+ 4锛夋偍閫氳繃鈥滄湇鍔♀�濊�岃喘涔版垨鑾峰彇鐨勪换浣曚骇鍝併�佹湇鍔°�佽祫鏂欐垨鍏朵粬鏉愭枡鐨勮川閲忓皢绗﹀悎鎮ㄧ殑棰勬湡銆傞�氳繃浣跨敤鈥滄湇鍔♀�濊�屼笅杞芥垨浠ュ叾浠栧舰寮忚幏鍙栦换浣曟潗鏂欐槸鐢辨偍鑷鍏ㄦ潈鍐冲畾杩涜鐨勶紝涓斾笌姝ゆ湁鍏崇殑椋庨櫓鐢辨偍鑷鎵挎媴锛屽浜庡洜鎮ㄤ笅杞戒换浣曡绛夋潗鏂欒�屽彂鐢熺殑鎮ㄧ殑鐢佃剳绯荤粺鐨勪换浣曟崯姣佹垨浠讳綍鏁版嵁鎹熷け锛屾偍灏嗚嚜琛屾壙鎷呰矗浠汇�傛偍浠庡钩鍙版垨閫氳繃鎴栦粠鈥滄湇鍔♀�濊幏鍙栫殑浠讳綍鍙eご鎴栦功闈㈡剰瑙佹垨璧勬枡锛屽潎涓嶄骇鐢熸湭鍦ㄦ湰鍗忚鍐呮槑纭浇鏄庣殑浠讳綍淇濊瘉璐d换銆�
+ </div>
+ <div>
+ 3銆佷笉璁哄湪浣曠鎯呭喌涓嬶紝骞冲彴鍧囦笉瀵圭敱浜庝俊鎭綉缁滄甯哥殑璁惧缁存姢锛屼俊鎭綉缁滆繛鎺ユ晠闅滐紝鐢佃剳銆侀�氳鎴栧叾浠栫郴缁熺殑鏁呴殰锛岀數鍔涙晠闅滐紝缃㈠伐锛屽姵鍔ㄤ簤璁紝鏆翠贡锛岃捣涔夛紝楠氫贡锛岀敓浜у姏鎴栫敓浜ц祫鏂欎笉瓒筹紝鐏伨锛屾椽姘达紝椋庢毚锛岀垎鐐革紝鎴樹簤锛屾斂搴滆涓猴紝鍙告硶琛屾斂鏈哄叧鐨勫懡浠ゆ垨绗笁鏂圭殑涓嶄綔涓鸿�岄�犳垚鐨勪笉鑳芥湇鍔℃垨寤惰繜鏈嶅姟鎵挎媴璐d换銆�
+ </div>
+ <div>
+ 4銆佸钩鍙颁粎鍚戞偍鎻愪緵鏈崗璁害瀹氫箣鏈嶅姟锛屾偍浜嗚В骞冲彴涓婄殑淇℃伅绯荤敤鎴疯嚜琛屽彂甯冿紝涓斿彲鑳藉瓨鍦ㄩ闄╁拰鐟曠柕銆傚钩鍙板皢閫氳繃渚濈収娉曞緥瑙勫畾寤虹珛鐩稿叧妫�鏌ョ洃鎺у埗搴﹀敖鍙兘淇濋殰鎮ㄥ湪骞冲彴涓婄殑鍚堟硶鏉冪泭鍙婅壇濂戒綋楠屻�傚悓鏃讹紝閴翠簬骞冲彴鍏峰瀛樺湪娴烽噺淇℃伅鍙婁俊鎭綉缁滅幆澧冧笅淇℃伅涓庡疄鐗╃浉鍒嗙鐨勭壒鐐癸紝骞冲彴鏃犳硶閫愪竴瀹℃煡浜у搧鍙�/鎴栨湇鍔$殑淇℃伅锛屾棤娉曢�愪竴瀹℃煡浜ゆ槗鎵�娑夊強鐨勪骇鍝佸強/鎴栨湇鍔$殑璐ㄩ噺銆佸畨鍏ㄤ互鍙婂悎娉曟�с�佺湡瀹炴�с�佸噯纭�э紝瀵规鎮ㄥ簲璋ㄦ厧鍒ゆ柇銆�
+ </div>
+ <div>
+ 5銆佹偍鐞嗚В骞跺悓鎰忥紝鍦ㄤ簤璁皟澶勬湇鍔′腑锛屽钩鍙扮殑瀹㈡湇骞堕潪涓撲笟浜哄+锛屼粎鑳戒互鏅�氫汉鐨勮鐭ュ鐢ㄦ埛鎻愪氦鐨勫嚟璇佽繘琛屽垽鏂紝骞冲彴涓嶄繚璇佷簤璁皟澶勫喅瀹氫竴瀹氱鍚堟偍鐨勬湡鏈涳紝闄ゅ瓨鍦ㄦ晠鎰忔垨閲嶅ぇ杩囧け澶栵紝骞冲彴瀵逛簤璁皟澶勫喅瀹氬厤璐c��
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="涔濄�佹斂绛栦慨鏀癸細骞冲彴淇濈暀瀵规湰鏀跨瓥浣滃嚭涓嶆椂淇敼鐨勬潈鍒┿��"></UserPolicyCell>
+ <UserPolicyCell title="鍗併�佸晢鏍囥�佺煡璇嗕骇鏉冪殑淇濇姢">
+ <div>
+ 1銆佸钩鍙颁笂鎵�鏈夊唴瀹癸紝鍖呮嫭浣嗕笉闄愪簬钁椾綔銆佸浘鐗囥�佹。妗堛�佽祫璁�佽祫鏂欍�佺綉绔欐灦鏋勩�佺綉绔欑敾闈㈢殑瀹夋帓銆佺綉椤佃璁★紝鍧囩敱骞冲彴渚濇硶鎷ユ湁鍏剁煡璇嗕骇鏉冿紝鍖呮嫭浣嗕笉闄愪簬鍟嗘爣鏉冦�佷笓鍒╂潈銆佽憲浣滄潈銆佸晢涓氱瀵嗙瓑銆�
+ </div>
+ <div>
+ 2銆侀潪缁忓钩鍙颁功闈㈠悓鎰忥紝浠讳綍浜轰笉寰楁搮鑷娇鐢ㄣ�佷慨鏀广�佸鍒躲�佸叕寮�浼犳挱銆佹敼鍙樸�佹暎甯冦�佸彂琛屾垨鍏紑鍙戣〃骞冲彴缃戠珯绋嬪簭鎴栧唴瀹广��
+ </div>
+ <div>3銆佸皧閲嶇煡璇嗕骇鏉冩槸鎮ㄥ簲灏界殑涔夊姟锛屽鏈夎繚鍙嶏紝鎮ㄥ簲鎵挎媴鎹熷璧斿伩璐d换銆�</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍗佷竴銆佹硶寰嬮�傜敤銆佺杈栧強鍏朵粬">
+ <div>
+ 1銆佹湰鍗忚涔嬫晥鍔涖�佽В閲娿�佸彉鏇淬�佹墽琛屼笌浜夎瑙e喅鍧囬�傜敤涓崕浜烘皯鍏卞拰鍥藉ぇ闄嗗湴鍖烘硶寰嬶紝濡傛棤鐩稿叧娉曞緥瑙勫畾鐨勶紝鍒欏簲鍙傜収閫氱敤鍥介檯鍟嗕笟鎯緥鍜岋紙鎴栵級琛屼笟鎯緥锛�
+ </div>
+ <div>
+ 2銆佹偍涓庡钩鍙颁粎涓虹嫭绔嬭绾︿汉鍏崇郴銆傛湰鍗忚鏃犳剰缁撴垚鎴栧垱璁句换浣曚唬鐞嗐�佸悎浼欍�佸悎钀ャ�侀泧浣d笌琚泧浣f垨鐗规�ф巿鏉冧笌琚巿鏉冨叧绯伙紱
+ </div>
+ <div>
+ 3銆佹偍鍚屾剰骞冲彴鍥犵粡钀ヤ笟鍔¢渶瑕佹湁鏉冨皢鏈崗璁」涓嬬殑鏉冨姏涔夊姟灏遍儴鍒嗘垨鍏ㄩ儴杩涜杞锛岃�屾棤椤诲啀閫氱煡浜堟偍骞跺彇寰楁偍鐨勫悓鎰忥紱
+ </div>
+ <div>
+ 4銆佸洜鏈崗璁垨骞冲彴鏈嶅姟鎵�寮曡捣鎴栦笌鍏舵湁鍏崇殑浠讳綍浜夎搴斿悜骞冲彴缁忚惀鑰呮墍鍦ㄥ湴浜烘皯娉曢櫌鎻愯捣璇夎锛�
+ </div>
+ <div>
+ 5銆佹湰鍗忚鍙栦唬鎮ㄥ拰骞冲彴鍏堝墠灏辩浉鍚屼簨椤硅绔嬬殑浠讳綍涔﹂潰鎴栧彛澶村崗璁�傚�樿嫢鏈崗璁换浣曟潯娆捐瑁佸畾涓烘棤鏁堟垨涓嶅彲寮哄埗鎵ц锛岃椤规潯娆惧簲琚挙閿�锛岃�屽叾浣欐潯娆惧簲浜堥伒瀹堝拰鎵ц銆傛潯娆炬爣棰樹粎涓烘柟渚垮弬闃呰�岃锛屽苟涓嶄互浠讳綍鏂瑰紡鐣屽畾銆侀檺鍒躲�佽В閲婃垨鎻忚堪璇ユ潯娆剧殑鑼冨洿鎴栭檺搴︺�傚钩鍙版湭灏辨偍鎴栧叾浠栦汉澹殑鏌愰」杩濈害琛屼负閲囧彇琛屽姩锛屽苟涓嶈〃鏄庡钩鍙版挙鍥炲氨浠讳綍缁у悗鎴栫被浼肩殑杩濈害浜嬩欢閲囧彇鍔ㄧ殑鏉冨埄銆�
+ </div>
+ </UserPolicyCell>
+ </div>
+ </scroll-view>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import { ScrollView } from '@tarojs/components';
+
+defineOptions({
+ name: 'mineUserPolicy',
+});
+
+const UserPolicyCell = defineComponent({
+ name: 'UserPolicyCell',
+ props: {
+ title: {
+ type: String,
+ },
+ content: {
+ type: String,
+ },
+ },
+ setup(props, { slots }) {
+ return () => {
+ return h('div', { class: 'userPolicy-cell-wrapper' }, [
+ h('div', { class: 'userPolicy-cell-title' }, [props.title]),
+ h('div', { class: 'userPolicy-cell-content' }, slots.default?.()),
+ ]);
+ };
+ },
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.userPolicy-page-wrapper {
+ background-color: #fafafa;
+
+ .userPolicy-page-scrollview {
+ // flex: 1;
+ height: 100%;
+ box-sizing: border-box;
+ }
+
+ .userPolicy-page-scrollview-content {
+ padding: 42px;
+
+ .userPolicy-page-title {
+ margin-bottom: 40px;
+ }
+ }
+
+ .userPolicy-cell-wrapper {
+ margin-bottom: 32px;
+
+ .userPolicy-cell-title {
+ color: #292929;
+ font-size: 30px;
+ margin-bottom: 22px;
+ font-weight: 500;
+ }
+
+ .userPolicy-cell-content {
+ div {
+ font-size: 24px;
+ line-height: 40px;
+ text-indent: 28px;
+ color: #888888;
+ }
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/index.config.ts b/apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/index.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/index.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/privacyPolicy.vue b/apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/privacyPolicy.vue
new file mode 100644
index 0000000..036f695
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/privacyPolicy/privacyPolicy.vue
@@ -0,0 +1,172 @@
+<template>
+ <PageLayout title="闅愮鏀跨瓥" :needAuth="false" class="userPolicy-page-wrapper">
+ <scroll-view style="height: 100%" :scroll-y="true">
+ <div class="userPolicy-page-scrollview-content">
+ <div class="userPolicy-page-title">818浜哄姏璧勬簮浜т笟閾惧钩鍙扮敤鎴锋湇鍔¢殣绉佹斂绛�</div>
+ <UserPolicyCell title="1銆侀�傜敤鑼冨洿锛�">
+ <div>
+ 1锛夊湪鐢ㄦ埛娉ㄥ唽818浜哄姏璧勬簮浜т笟閾惧钩鍙拌处鎴锋椂锛堜互涓嬬畝绉扳�滃钩鍙扳�濓級锛岀敤鎴锋牴鎹钩鍙拌姹傛彁渚涚殑鐩稿叧涓汉淇℃伅锛�
+ </div>
+ <div>
+ 2锛夊湪鐢ㄦ埛浣跨敤骞冲彴鏈嶅姟锛屽弬鍔犲钩鍙版椿鍔紝鎴栬闂钩鍙扮綉绔欐椂锛屽钩鍙板皢鑷姩鎺ユ敹骞惰褰曠殑鐢ㄦ埛娴忚鍣ㄤ笂鐨勬湇鍔″櫒鏁板�硷紝鍖呮嫭浣嗕笉闄愪簬IP鍦板潃绛夋暟鎹強鐢ㄦ埛瑕佹眰鍙栫敤鐨勭綉椤�/瀹㈡埛绔褰曪紱
+ </div>
+ <div>
+ 3锛夊钩鍙版敹闆嗗埌鐨勭敤鎴峰湪骞冲彴杩涜浜ゆ槗鐨勬湁鍏虫暟鎹紝鍖呮嫭浣嗕笉闄愪簬鍑轰环銆佽喘涔般�佷骇鍝佺櫥褰曘�佷俊鐢ㄨ瘎浠峰強杩濊璁板綍锛�
+ </div>
+ <div>4锛夊钩鍙伴�氳繃鍚堟硶閫斿緞浠庡晢涓氫紮浼村鍙栧緱鐨勭敤鎴蜂釜浜烘暟鎹��</div>
+ <div>
+ 5锛夋垜浠敹闆嗘暟鎹槸鏍规嵁鎮ㄤ笌鎴戜滑鐨勪簰鍔ㄥ拰鎮ㄦ墍鍋氬嚭鐨勯�夋嫨锛屽寘鎷偍鐨勯殣绉佽缃互鍙婃偍浣跨敤鐨勪骇鍝佸拰鍔熻兘銆傛垜浠敹闆嗙殑鏁版嵁鍙兘鍖呮嫭SDK/API/JS浠g爜鐗堟湰銆佹祻瑙堝櫒銆佷簰鑱旂綉鏈嶅姟鎻愪緵鍟嗐�両P鍦板潃銆佸钩鍙般�佹椂闂存埑銆佸簲鐢ㄦ爣璇嗙銆佸簲鐢ㄧ▼搴忕増鏈�佸簲鐢ㄥ垎鍙戞笭閬撱�佺嫭绔嬭澶囨爣璇嗙銆乮OS骞垮憡鏍囪瘑绗︼紙IDFA)銆佸畨鍗撳箍鍛婁富鏍囪瘑绗︺�佺綉鍗★紙MAC锛夊湴鍧�銆佸浗闄呯Щ鍔ㄨ澶囪瘑鍒爜锛圛MEI锛夈�佽澶囧瀷鍙枫�佺粓绔埗閫犲巶鍟嗐�佺粓绔澶囨搷浣滅郴缁熺増鏈�佷細璇濆惎鍔�/鍋滄鏃堕棿銆佽瑷�鎵�鍦ㄥ湴銆佹椂鍖哄拰缃戠粶鐘舵�侊紙WiFi绛夛級绛夈��
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="2銆佷俊鎭娇鐢細">
+ <div>1锛夊钩鍙颁笉浼氬悜浠讳綍浜哄嚭鍞垨鍑哄�熺敤鎴风殑涓汉淇℃伅锛岄櫎闈炰簨鍏堝緱鍒扮敤鎴峰緱璁稿彲銆�</div>
+ <div>
+ 2锛夊钩鍙颁害涓嶅厑璁镐换浣曠涓夋柟浠ヤ换浣曟墜娈垫敹闆嗐�佺紪杈戙�佸嚭鍞垨鑰呮棤鍋夸紶鎾敤鎴风殑涓汉淇℃伅銆備换浣曠敤鎴峰浠庝簨涓婅堪娲诲姩锛屼竴缁忓彂鐜帮紝骞冲彴鏈夋潈绔嬪嵆缁堟涓庤鐢ㄦ埛鐨勬湇鍔″崗璁紝鏌ュ皝鍏惰处鍙枫��
+ </div>
+ <div>
+ 3锛変负鏈嶅姟鐢ㄦ埛鐨勭洰鐨勶紝骞冲彴鍙兘閫氳繃浣跨敤鐢ㄦ埛鐨勪釜浜轰俊鎭紝鍚戠敤鎴锋彁渚涙湇鍔″強浜у搧鏀硅繘锛屽寘鎷絾涓嶉檺浜庡悜鐢ㄦ埛鍙戝嚭浜у搧鍜屾湇鍔′俊鎭紝鎴栬�呬笌骞冲彴鍚堜綔浼欎即鍏变韩淇℃伅浠ヤ究浠栦滑鍚戠敤鎴峰彂閫佹湁鍏冲叾浜у搧鍜屾湇鍔$殑淇℃伅锛堝悗鑰呴渶瑕佺敤鎴风殑浜嬪厛鍚屾剰锛夈�備緥濡傦紝鎴戜滑鑱樿鏉ユ彁渚涙暟鎹垎鏋愭湇鍔$殑鍏徃鍙兘闇�瑕侀噰闆嗗拰璁块棶涓汉鏁版嵁浠ヨ繘琛屾暟鎹粺璁″拰鍒嗘瀽銆傚湪杩欑鎯呭喌涓嬶紝杩欎簺鍏徃蹇呴』閬靛畧鎴戜滑鐨勬暟鎹殣绉佸拰瀹夊叏瑕佹眰銆�
+ </div>
+ <div>
+ 4锛夋垜浠凡鍦ㄤ笂鏂囦粙缁嶄簡澶勭悊涓汉鏁版嵁鐨勭洰鐨勩�傛垜浠鐞嗕釜浜烘暟鎹殑娉曞緥鍩虹鍖呮嫭锛氫负灞ヨ涓庢偍涔嬮棿鐨勫悎鍚岋紙渚嬪锛屼负鎮ㄦ彁渚涙偍鎵�璇锋眰鐨勬湇鍔°�佸鎮ㄨ繘琛岃瘑鍒拰璁よ瘉锛屼互渚挎偍鍙互浣跨敤缃戠珯锛夛紱涓洪伒瀹堟硶寰嬭姹傦紙渚嬪锛屼负閬靛畧閫傜敤鐨勪細璁¤鍒欙紝灞ヨ鎵ф硶閮ㄩ棬寮哄埗鎶湶鐨勮姹傦級锛涗负淇濇姢鎴戜滑鐨勬褰撳埄鐩婏紙渚嬪锛岀鐞嗘垜浠笌鎮ㄧ殑鍏崇郴锛屼负纭繚鎴戜滑鏈嶅姟鐨勫畨鍏ㄦ�э紝涓庢偍娌熼�氭垜浠殑浜у搧鍜屾湇鍔★級锛涗互鍙婂熀浜庢垜浠鎴风殑鍚屾剰锛堜緥濡傦紝鎶曟斁cookies锛屼负骞垮憡瀹d紶涔嬬洰鐨勪笌绗笁鏂瑰叡浜偍鐨勪俊鎭級銆傚湪鏌愪簺鎯呭喌涓嬶紝鎮ㄥ彲鑳介渶瑕佷负鎴戜滑鎻愪緵涓汉鏁版嵁浠ヨ繘琛屼笂杩扮殑澶勭悊锛屼互渚挎垜浠兘澶熶负鎮ㄦ彁渚涙垜浠殑鍏ㄩ儴鏈嶅姟锛屽苟鏂逛究鎮ㄤ娇鐢ㄦ垜浠綉绔欑殑鍏ㄩ儴鍔熻兘銆�
+ </div>
+ <div>
+ 5锛変釜浜烘暟鎹殑璺ㄥ浼犺緭銆傞拡瀵规鐩熸垚鍛樺浗鐢ㄦ埛锛屾垜浠殑涓氬姟鍙兘闇�瑕佹垜浠浆绉绘偍鐨勪釜浜烘暟鎹嚦娆ф床缁忔祹鍖轰互澶栫殑鍥藉锛堜腑鍥斤級銆傛垜浠細閲囧彇閫傚綋鐨勬帾鏂戒互纭繚鎮ㄤ釜浜烘暟鎹殑鎺ユ敹鑰呭饱琛屼繚瀵嗕箟鍔★紝骞剁‘淇濆鏍囧噯鍚堝悓鏉℃绛夋帾鏂界殑鎵ц銆傛偍鍙互閫氳繃鑱旂郴鎴戜滑鐨勫府鍔╀腑蹇冭幏寰楄繖浜涙潯娆俱��
+ </div>
+ <div>
+ 6锛夐拡瀵规鐩熸垚鍛樺浗鐢ㄦ埛锛屾牴鎹�傜敤娉曞緥锛屾偍鏈夋潈鍙嶅鎴栬姹傞檺鍒跺鎮ㄤ釜浜烘暟鎹殑澶勭悊锛屽苟瑕佹眰鎮ㄦ湰浜烘暟鎹殑璁块棶銆佹牎姝c�佸垹闄ゅ拰鍙惡甯︽潈銆傚湪瀵规偍鐨勪俊鎭殑浣跨敤鏄熀浜庢偍鐨勫悓鎰忕殑鎯呭喌涓嬶紝鎮ㄦ湁鏉冨湪浠讳綍鏃跺�欐挙鍥炶鍚屾剰锛屼絾鍚屾剰鐨勬挙鍥炰笉褰卞搷鎾ゅ洖鍓嶅熀浜庡悓鎰忚繘琛岀殑鏁版嵁澶勭悊鐨勫悎娉曟�с�傛偍鍙互閫氳繃瀹㈡湇鐢佃瘽锛�16505012333鍚戞垜浠彁浜ゆ偍鐨勮姹傘�傚鏋滄偍鍙戠幇鎮ㄧ殑淇℃伅鍙戠敓鍙樺寲鎴栦笉鍑嗙‘锛岃灏嗚繖浜涘彉鍖栭�氱煡鎴戜滑浠ヤ究鎴戜滑鐨勮褰曞彲浠ヨ鏇存柊鎴栨洿姝c�傚鏋滄偍璁や负鎴戜滑瀵规偍涓汉鏁版嵁鐨勫鐞嗚繚鍙嶄簡閫傜敤娉曞緥锛屾偍鍙互鍚戠洃绠℃満鏋勬姇璇夈�傛垜浠鎮ㄤ釜浜烘暟鎹殑淇濈暀鏃堕棿瑙嗗悜鎮ㄦ彁渚涙湇鍔℃垨浜у搧鐨勯渶瑕佽�屽畾锛屾垨鏍规嵁閫傜敤娉曞緥濡傜◣娉曞拰浼氳娉曠殑瑕佹眰鎴栬鍙‘瀹氥��
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="3銆佷俊鎭姭闇诧紝鐢ㄦ埛鐨勪釜浜轰俊鎭皢鍦ㄤ笅杩版儏鍐典笅閮ㄥ垎鎴栧叏閮ㄨ鎶湶锛�">
+ <div>1锛夌粡鐢ㄦ埛鍚屾剰锛屽悜绗笁鏂规姭闇诧紱</div>
+ <div>
+ 2锛夊鐢ㄦ埛鏄鍚堣祫鏍肩殑鐭ヨ瘑浜ф潈鎶曡瘔浜哄苟宸叉彁璧锋姇璇夛紝搴旇鎶曡瘔浜鸿姹傦紝鍚戣鎶曡瘔浜烘姭闇诧紝浠ヤ究鍙屾柟澶勭悊鍙兘鐨勬潈鍒╃籂绾凤紱
+ </div>
+ <div>
+ 3锛夋牴鎹硶寰嬬殑鏈夊叧瑙勫畾锛屾垨鑰呰鏀挎垨鍙告硶鏈烘瀯鐨勮姹傦紝鍚戠涓夋柟鎴栬�呰鏀裤�佸徃娉曟満鏋勬姭闇诧紱
+ </div>
+ <div>4锛夊鏋滅敤鎴峰嚭鐜拌繚鍙嶄腑鍥芥湁鍏虫硶寰嬫垨鑰呯綉绔欐斂绛栫殑鎯呭喌锛岄渶瑕佸悜绗笁鏂规姭闇诧紱</div>
+ <div>5锛変负鎻愪緵鎮ㄦ墍瑕佹眰鐨勪骇鍝佸拰鏈嶅姟锛岃�屽繀椤诲拰绗笁鏂瑰垎浜敤鎴风殑涓汉淇℃伅锛�</div>
+ <div>
+ 6锛夊湪骞冲彴缃戜笂鍒涘缓鐨勬煇涓�浜ゆ槗涓紝濡備氦鏄撲换浣曚竴鏂瑰饱琛屾垨閮ㄥ垎灞ヨ浜嗕氦鏄撲箟鍔″苟鎻愬嚭淇℃伅鎶湶璇锋眰鐨勶紝骞冲彴鏈夊叏鏉冨彲浠ュ喅瀹氬悜璇ョ敤鎴锋彁渚涘叾浜ゆ槗瀵规柟鐨勮仈缁滄柟寮忕瓑蹇呰淇℃伅锛屼互淇冩垚浜ゆ槗鐨勫畬鎴愭垨绾犵悍鐨勮В鍐筹紱
+ </div>
+ <div>7锛夊叾瀹冨钩鍙版牴鎹硶寰嬫垨鑰呯綉绔欐斂绛栬涓哄悎閫傜殑鎶湶銆�</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="4銆佷俊鎭畨鍏細">
+ <div>1锛夊钩鍙板強骞冲彴璐︽埛鍧囨湁瀹夊叏淇濇姢鍔熻兘锛岃濡ュ杽淇濈鐢ㄦ埛鐨勮处鎴峰強瀵嗙爜淇℃伅锛�</div>
+ <div>
+ 2锛夊湪浣跨敤骞冲彴鏈嶅姟杩涜缃戜笂浜ゆ槗鏃讹紝鐢ㄦ埛涓嶅彲閬垮厤鐨勮鍚戜氦鏄撳鏂规垨娼滃湪鐨勪氦鏄撳鏂规彁渚涜嚜宸辩殑涓汉淇℃伅锛屽鑱旂粶鏂瑰紡鎴栬�呴偖鏀垮湴鍧�銆傝鐢ㄦ埛濡ュ杽淇濇姢鑷繁鐨勪釜浜轰俊鎭紝浠呭湪蹇呰鐨勬儏褰笅鍚戜粬浜烘彁渚涳紱
+ </div>
+ <div>
+ 3锛夊鏋滅敤鎴峰彂鐜拌嚜宸辩殑涓汉淇℃伅娉勫瘑锛屽挨鍏舵槸骞冲彴璐︽埛鍙婂瘑鐮佸彂鐢熸硠闇诧紝璇风敤鎴风珛鍗宠仈缁滃钩鍙板鏈嶏紝浠ヤ究骞冲彴閲囧彇鐩稿簲鎺柦銆�
+ 濡傜敤鎴峰濡備綍鎾ゅ洖淇℃伅鎺堟潈鏈夌枒闂紝鍙互鍦ㄥ伐浣滄棩锛堝懆涓�鍒板懆浜� 鍙�
+ 娉曞畾鑺傚亣鏃ヨ皟鏁寸殑宸ヤ綔鏃ワ級宸ヤ綔鏃堕棿锛�09:00 -- 18:00锛�
+ 鑷寸數骞冲彴瀹㈡湇鐢佃瘽锛�16505012333锛岃瀹㈡湇浜哄憳鍗忓姪澶勭悊
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="5銆佸浣曟敞閿�/鍒犻櫎璐︽埛">
+ <div>
+ 1锛夌敤鎴峰彲浠ュ湪宸ヤ綔鏃ワ紙鍛ㄤ竴鍒板懆浜斿強娉曞畾鑺傚亣鏃ヨ皟鏁寸殑宸ヤ綔鏃ワ級宸ヤ綔鏃堕棿锛�09:00 -- 18:00锛�
+ 鑷寸數骞冲彴瀹㈡湇鐢佃瘽锛�16505012333锛屽憡鐭ュ鏈嶄汉鍛樻敞鍐岃处鎴蜂俊鎭�,骞跺憡鐭ュ鏈嶄汉鍛橀渶瑕佹敞閿�/鍒犻櫎涓汉鐢ㄦ埛淇℃伅锛岃嚧鐢电浜屾棩寮�濮嬭绠楋紝涓や釜宸ヤ綔鏃ュ唴鍔炵粨骞惰嚧鐢�/鐭俊閫氱煡鐢宠浜恒��
+ </div>
+ <div>
+ 2锛夌敤鎴峰彲浠ヤ换浣曟椂闂达紝璁块棶骞冲彴鍙嶉涓績缃戦〉锛寃ww.81812333.com鍦ㄧ嚎鐣欒█锛屽鏈嶅伐浣滄棩鎺ユ敹淇℃伅鍚庯紝浼氳嚧鐢电敵璇蜂汉纭淇℃伅锛屽苟鍦ㄤ袱涓伐浣滄棩鍐呭姙缁撱��
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="6銆丄PP鎵�鏀堕泦涓汉淇℃伅鐨勭洰鐨勩�佹柟寮忓拰鑼冨洿">
+ <div>1锛夈�佸钩鍙版墍鏀堕泦鐨勪俊鎭紝浠呴檺浜庣敤鎴峰湪骞冲彴缃戝紑灞曞熀纭�涓氬姟娲诲姩銆�</div>
+ <div>2锛夈�佷俊鎭敹闆嗙殑鏂瑰紡鍜岃寖鍥�</div>
+ <div>鑾峰彇鎮ㄧ浉鍐屻�佺浉鏈虹殑鏉冮檺锛岀敤浜庝紒涓氫俊鎭�佽鍗曞彂甯冦�佷釜浜哄ご鍍忕殑鍥剧墖涓婁紶銆�</div>
+ <div>
+ 鑾峰彇鏈湴瀛樺偍鏉冮檺锛屾垜浠皢璇锋眰鎮ㄧ殑瀛樺偍鏉冮檺鑾峰彇澶栫疆瀛樺偍淇℃伅锛圫D鍗℃暟鎹級浠ヤ繚瀛樻偍鍦ㄥ钩鍙板崈璇㈢殑浣跨敤杩囩▼涓殑涓氬姟鏁版嵁銆�
+ </div>
+ <div>
+ 鑾峰彇鎮ㄧ殑璁惧淇℃伅锛堝寘鎷琁MEI銆佽澶囧簭鍒楀彿銆丱AID銆丮EID銆丄ndroid
+ ID銆両MSI銆丟UID銆丮AC鍦板潃銆丼IM鍗″簭鍒楀彿锛夛紝璁惧鐗瑰緛鐮佸拰IP鍦板潃锛屽凡瀹夎APP淇℃伅鎴栬繍琛屼腑鐨勮繘绋嬩俊鎭紝鏉ヤ繚璇佹偍璐﹀彿浣跨敤鐨勫敮涓�鎬с�佸畨鍏ㄦ�с��
+ </div>
+ <div>
+ 褰撴偍鎾斁瑙嗛绛夊唴瀹规椂锛屼负浜嗛�傞厤鎮ㄧ殑璁惧鐘舵�侊紝鎴戜滑浼氳皟鐢ㄨ澶囩殑閲嶅姏銆佸姞閫熷害绛変紶鎰熷櫒淇℃伅锛屼互璇嗗埆鎮ㄧ殑璁惧妯珫灞忕姸鎬併��
+ </div>
+ <div>
+ 鍦ㄦ偍鍒嗕韩鎴栨帴鏀惰鍒嗕韩鐨勪俊鎭椂锛岄渶瑕佸湪鏈湴璁块棶鎮ㄧ殑鍓垏鏉匡紝璇诲彇鍏朵腑鍖呭惈鐨勫彛浠ゃ�佸垎浜爜銆侀摼鎺ョ瓑锛屼互瀹炵幇璺宠浆銆佸垎浜�佹椿鍔ㄨ仈鍔ㄧ瓑鍔熻兘鎴栨湇鍔°��
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="7銆佽嚜鍚姩鍜屽叧鑱斿惎鍔ㄨ鏄�">
+ <div>
+ 涓虹‘淇濇湰搴旂敤澶勪簬鍏抽棴鎴栧悗鍙拌繍琛岀姸鎬佷笅鍙甯告帴鏀跺埌瀹㈡埛绔帹閫佺殑骞挎挱娑堟伅锛屾湰搴旂敤椤讳娇鐢紙鑷惎鍔級鑳藉姏锛屽皢瀛樺湪涓�瀹氶鐜囬�氳繃绯荤粺鍙戦�佸箍鎾敜閱掓湰搴旂敤鑷惎鍔ㄦ垨鍏宠仈鍚姩琛屼负锛屾槸鍥犲疄鐜板姛鑳藉強鏈嶅姟鎵�蹇呰鐨勩��
+ </div>
+ </UserPolicyCell>
+ </div>
+ </scroll-view>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import { ScrollView } from '@tarojs/components';
+
+defineOptions({
+ name: 'privacyPolicy',
+});
+
+const UserPolicyCell = defineComponent({
+ name: 'UserPolicyCell',
+ props: {
+ title: {
+ type: String,
+ },
+ content: {
+ type: String,
+ },
+ },
+ setup(props, { slots }) {
+ return () => {
+ return h('div', { class: 'userPolicy-cell-wrapper' }, [
+ h('div', { class: 'userPolicy-cell-title' }, [props.title]),
+ h('div', { class: 'userPolicy-cell-content' }, slots.default?.()),
+ ]);
+ };
+ },
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.userPolicy-page-wrapper {
+ background-color: #fafafa;
+
+ .userPolicy-page-scrollview {
+ // flex: 1;
+ height: 100%;
+ box-sizing: border-box;
+ }
+
+ .userPolicy-page-scrollview-content {
+ padding: 42px;
+
+ .userPolicy-page-title {
+ margin-bottom: 40px;
+ }
+ }
+
+ .userPolicy-cell-wrapper {
+ margin-bottom: 32px;
+
+ .userPolicy-cell-title {
+ color: #292929;
+ font-size: 30px;
+ margin-bottom: 22px;
+ font-weight: 500;
+ }
+
+ .userPolicy-cell-content {
+ div {
+ font-size: 24px;
+ line-height: 40px;
+ text-indent: 28px;
+ color: #888888;
+ }
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/registerForm/registerForm.vue b/apps/housekeepingMiniApp/src/subpackages/login/registerForm/registerForm.vue
new file mode 100644
index 0000000..2dbd899
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/registerForm/registerForm.vue
@@ -0,0 +1,189 @@
+<template>
+ <LoginPageLayout class="registerForm-page-wrapper" title="娉ㄥ唽">
+ <div class="loginB-form-wrapper">
+ <div class="register-form-title-wrapper">
+ <div class="register-form-title">娉ㄥ唽</div>
+ <div class="register-form-title-line"></div>
+ </div>
+ <div class="verification-code-login-form-wrapper">
+ <nut-form
+ class="verification-code-login-form"
+ ref="formRef"
+ :model-value="form"
+ :rules="rules"
+ >
+ <nut-form-item label="" class="bole-form-item" prop="phoneNumber" required>
+ <nut-input
+ v-model.trim="form.phoneNumber"
+ class="bole-input-text"
+ placeholder="璇疯緭鍏ユ墜鏈哄彿"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item label="" class="bole-form-item" prop="verificationCode" required>
+ <nut-input
+ v-model.trim="form.verificationCode"
+ class="bole-input-text"
+ placeholder="璇疯緭鍏ラ獙璇佺爜"
+ type="number"
+ >
+ <template #right>
+ <ProFormCaptcha
+ :onGetCaptcha="onGetCaptcha"
+ phonePropName="phoneNumber"
+ :validateField="formRef?.validate"
+ ></ProFormCaptcha>
+ </template>
+ </nut-input>
+ </nut-form-item>
+ </nut-form>
+ <LargeButton class="login-btn" @click="handleRegister" :loading="form.loading"
+ >娉ㄥ唽</LargeButton
+ >
+ <div class="go-register-btn" @click="goLogin">绔嬪嵆鐧诲綍</div>
+ </div>
+ </div>
+ <Policy
+ v-model="state.policyChecked"
+ policyBtnText="鎴戝凡闃呰骞跺悓鎰�"
+ class="loginB-form-policy"
+ />
+ </LoginPageLayout>
+</template>
+
+<script setup lang="ts">
+import LoginPageLayout from '../components/LoginPageLayout/LoginPageLayout.vue';
+import { Policy } from '@/components';
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import { FormValidator, Message } from '@12333/utils';
+import { LargeButton } from '@/components';
+import { ProFormCaptcha } from 'senin-mini/components';
+import { VerificationCodeBusinessType } from '@12333/constants';
+import Taro from '@tarojs/taro';
+import { ResponseCode } from '@12333/constants';
+import * as authServices from '@12333/services/apiV2/auth';
+import { APP_ENV } from '@/constants';
+import { useUserStore } from '@/stores/modules/user';
+
+defineOptions({
+ name: 'registerForm',
+});
+
+const userStore = useUserStore();
+
+const { jump } = useLoginedJump();
+
+const state = reactive({
+ policyChecked: false,
+});
+
+const formRef = ref(null);
+
+const form = reactive({
+ loading: false,
+ phoneNumber: '',
+ verificationCode: '',
+});
+
+const rules = reactive<FormRules>({
+ phoneNumber: [
+ { required: true, message: '璇疯緭鍏ユ墜鏈哄彿' },
+ { validator: FormValidator.validatorPhoneNumber, message: '璇疯緭鍏ユ纭殑鎵嬫満鍙�' },
+ ],
+ verificationCode: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜' }],
+});
+
+async function onGetCaptcha() {
+ const res = await authServices.sendLoginOrRegisterVerifyCode(
+ {
+ phoneNumber: form.phoneNumber,
+ },
+ {
+ showLoading: false,
+ getResponse: true,
+ // customErrorHandler(error) {
+ // if (error?.response?.data?.error?.code === ResponseCode.RegisterExistsPhoneNumber) {
+ // Message.confirm({
+ // message: '璇ユ墜鏈哄彿宸叉敞鍐岋紝璇峰幓鐧诲綍椤电櫥褰�',
+ // confirmText: '鍘荤櫥褰�',
+ // }).then(() => {
+ // goLogin();
+ // });
+ // return true;
+ // }
+ // },
+ }
+ );
+
+ if (res && APP_ENV === 'staging') {
+ // @ts-ignore
+ form.verificationCode = res?.data?.extras?.code ?? '';
+ }
+}
+
+async function handleRegister() {
+ try {
+ if (state.policyChecked) {
+ const { valid } = await formRef.value.validate();
+ if (valid) {
+ let params: API.RegisterPersonalUserCommand = {
+ verifyCode: form.verificationCode,
+ phoneNumber: form.phoneNumber,
+ };
+ let res = await authServices.registerPersonalUser(params);
+ if (res) {
+ Message.success('娉ㄥ唽鎴愬姛', {
+ onClosed: async () => {
+ userStore.loginSuccess(res);
+ jump();
+ },
+ });
+ }
+ }
+ } else {
+ noAccess();
+ }
+ } catch (error) {
+ } finally {
+ form.loading = false;
+ }
+}
+
+function noAccess() {
+ Message.warning('璇峰厛闃呰骞跺嬀閫夊崗璁�');
+}
+
+const router = Taro.useRouter();
+
+function goLogin() {
+ Taro.navigateBack();
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+@import '../styles/login.scss';
+
+.registerForm-page-wrapper {
+ .register-form-title-wrapper {
+ padding-top: 20px;
+ margin-bottom: 92px;
+
+ .register-form-title {
+ font-weight: 400;
+ font-size: 28px;
+ color: boleGetCssVar('color', 'primary');
+ line-height: 40px;
+ text-align: center;
+ margin-bottom: 8px;
+ }
+
+ .register-form-title-line {
+ width: 38px;
+ height: 2px;
+ background-color: boleGetCssVar('color', 'primary');
+ margin: 0 auto;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/styles/login.scss b/apps/housekeepingMiniApp/src/subpackages/login/styles/login.scss
new file mode 100644
index 0000000..c1f57b6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/styles/login.scss
@@ -0,0 +1,165 @@
+@import '@/styles/common.scss';
+
+.loginB-form-wrapper {
+ flex: 1;
+ min-height: 0;
+ background-color: #fff;
+ border-radius: 32px 32px 0px 0px;
+ margin: 0 32px;
+ display: flex;
+ flex-direction: column;
+
+ .loginB-form-tab {
+ height: 108px;
+ display: flex;
+ margin-bottom: 46px;
+
+ .loginB-form-tab-item {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ justify-content: center;
+ padding-top: 20px;
+ position: relative;
+
+ .loginB-form-tab-item-content {
+ position: relative;
+ z-index: 1;
+ }
+
+ .loginB-form-tab-item-text {
+ font-weight: 400;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ line-height: 40px;
+ margin-bottom: 8px;
+ }
+
+ .loginB-form-tab-item-line {
+ width: 36px;
+ height: 2px;
+ background-color: boleGetCssVar('color', 'primary');
+ margin: 0 auto;
+ display: none;
+ }
+
+ .loginB-form-tab-item-bg1 {
+ position: absolute;
+ z-index: 0;
+ width: 376px;
+ height: 108px;
+ top: 1px;
+ left: 1px;
+ }
+
+ .loginB-form-tab-item-bg2 {
+ position: absolute;
+ z-index: 0;
+ width: 376px;
+ height: 108px;
+ top: 1px;
+ right: 1px;
+ }
+
+ &.active {
+ .loginB-form-tab-item-text {
+ color: boleGetCssVar('color', 'primary');
+ }
+
+ .loginB-form-tab-item-line {
+ display: block;
+ }
+
+ .loginB-form-tab-item-bg1,
+ .loginB-form-tab-item-bg2 {
+ display: none;
+ }
+ }
+ }
+ }
+
+ .nut-cell-group__wrap {
+ overflow: visible;
+ }
+
+ .bole-form-item {
+ padding: 0 !important;
+ margin-bottom: 40px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ &.error.line::before {
+ z-index: 1;
+ display: none;
+ // right: 0;
+ // left: 0;
+ // top: 0;
+ // border-radius: 44px;
+ }
+
+ &.error {
+ .bole-input-text {
+ border: 1px solid #fa2c19;
+ box-sizing: border-box;
+ }
+ }
+
+ .nut-form-item__body__tips {
+ left: 30rpx !important;
+ bottom: -36rpx !important;
+ }
+ }
+
+ .bole-input-text {
+ // border-bottom: none;
+ border: 1px solid #f5f7fb;
+ height: 88px;
+ background: #f5f7fb;
+ border-radius: 44px;
+ padding: 24px 32px;
+
+ /* .nut-input-value {
+ display: flex;
+ align-items: center;
+ } */
+
+ .h5-input {
+ font-size: 28px;
+ }
+ }
+}
+
+.loginByForm-page-wrapper,
+.registerForm-page-wrapper {
+ .loginB-form-policy {
+ margin-bottom: 40px;
+ }
+}
+
+.verification-code-login-form-wrapper {
+ display: flex;
+ flex-direction: column;
+ padding: 0 32px;
+
+ .verification-code-login-form {
+ margin-bottom: 60px;
+
+ .nut-cell-group__wrap {
+ box-shadow: none;
+ margin-bottom: 0;
+ }
+ }
+
+ .login-btn {
+ margin-bottom: 32px;
+ }
+
+ .go-register-btn {
+ align-self: center;
+ color: boleGetCssVar('color', 'primary');
+ font-size: 24px;
+ line-height: 34px;
+ }
+}
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/userPolicy/index.config.ts b/apps/housekeepingMiniApp/src/subpackages/login/userPolicy/index.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/userPolicy/index.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/login/userPolicy/userPolicy.vue b/apps/housekeepingMiniApp/src/subpackages/login/userPolicy/userPolicy.vue
new file mode 100644
index 0000000..04f57f8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/login/userPolicy/userPolicy.vue
@@ -0,0 +1,238 @@
+<template>
+ <PageLayout title="鐢ㄦ埛鏈嶅姟鍗忚" :needAuth="false" class="userPolicy-page-wrapper">
+ <scroll-view style="height: 100%" :scroll-y="true">
+ <div class="userPolicy-page-scrollview-content">
+ <div class="userPolicy-page-title">鐢ㄦ埛鏈嶅姟鍗忚</div>
+ <UserPolicyCell title="鐗瑰埆鎻愮ず">
+ <div>銆愬鎱庨槄璇汇�戝湪鎮ㄧ敵璇锋敞鍐屾垚涓烘窐闂伐鐢ㄦ埛涔嬪墠锛屽簲褰撹鐪熼槄璇汇�婂畞娉㈠垱鑳滀俊鎭妧鏈湇鍔℃湁闄愬叕鍙告窐闂伐骞冲彴鐢ㄦ埛鏈嶅姟鍗忚銆嬶紙浠ヤ笅绠�绉扳�滄湰鍗忚鈥濓級锛岃鎮ㄥ姟蹇呭鎱庨槄璇汇�佸厖鍒嗙悊瑙e悇鏉℃鍐呭锛岀壒鍒槸鍏嶉櫎鎴栬�呴檺鍒惰矗浠荤殑鏉℃銆佷簤璁В鍐冲拰娉曞緥閫傜敤鏉℃锛屽叾涓厤闄ゆ垨鑰呴檺鍒惰矗浠荤殑鏉℃灏嗕互鍔犵矖瀛椾綋鏄剧ず锛屾偍搴旈噸鐐归槄璇汇�傚鎮ㄥ鏈崗璁湁浠讳綍鐤戦棶锛屽彲鍚戞窐闂伐鍦ㄧ嚎瀹㈡湇鎴栫數璇濆鏈嶅挩璇紝瀹㈡湇鐢佃瘽锛� 16505012333 锛岄偖绠憋細 12333@818nb.com </div>
+ <div>銆愮绾﹀姩浣溿�戝綋鎮ㄦ寜鐓ф敞鍐屾垨鐧诲綍椤甸潰闃呰骞跺悓鎰忔湰鍗忚涓斿畬鎴愭敞鍐屾垨鐧诲綍鍚庯紝鍗宠〃绀烘偍宸插厖鍒嗛槄璇汇�佺悊瑙e苟鎺ュ彈鏈崗璁殑鍏ㄩ儴鍐呭锛屽苟涓庡畞娉㈠垱鑳滀俊鎭妧鏈湇鍔℃湁闄愬叕鍙歌揪鎴愪竴鑷达紝鎴愪负娣橀棯宸ュ钩鍙扮殑鈥滅敤鎴封��,鏈崗璁嚜姝ょ敓鏁堛�傞槄璇绘湰鍗忚鐨勮繃绋嬩腑锛屽鏋滄偍涓嶅悓鎰忔湰鍗忚鎴栧叾涓换浣曟潯娆剧害瀹氾紝鎮ㄥ簲绔嬪嵆鍋滄娉ㄥ唽鎴栫櫥褰曠▼搴忋��</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="涓�銆佸畾涔�">
+ <div>1.1 鍒涜儨锛氬畞娉㈠垱鑳滀俊鎭妧鏈湇鍔℃湁闄愬叕鍙革紝涔熺О鈥滄窐闂伐缁忚惀鑰呪�濄��</div>
+ <div>1.2 娣橀棯宸ュ钩鍙帮細鎸囨窐闂伐锛堢郴缁熷悕绉颁负 鐏靛伐杈俱�佸伐鏄撹禋 锛夊畼缃戙�佸鎴风銆佸皬绋嬪簭鎴栫綉椤碉紝浠ヤ笅绠�绉扳�滃钩鍙扳�濄��</div>
+ <div>1.3 鍏宠仈鍏徃锛氭寚鎺у埗涓�鏂癸紝琚鏂规帶鍒躲�佹垨涓庤鏂瑰叡鍚岃鎺у埗鐨勪换浣曞叕鍙搞�佽嚜鐒朵汉銆佸悎浼欐垨鍏朵粬瀹炰綋锛屽叾涓�滄帶鍒垛�濈殑鍚箟鏄寚鐩存帴鎴栭棿鎺ユ嫢鏈夎瀹炰綋瓒呰繃鐧惧垎涔嬩簲鍗�(50%)鏈夎〃鍐虫潈鐨勭エ璇佹垨璇ュ疄浣撶殑鍏朵粬鎵�鏈夋潈鍒╃泭锛屾垨鐩存帴鎴栭棿鎺ユ嫢鏈夋垨鎺у埗璇ュ疄浣撶殑鏉冨姏锛屾棤璁烘槸閫氳繃鎷ユ湁琛ㄥ喅鏉冪殑绁ㄨ瘉銆佸崗璁垨鍏朵粬鏂瑰紡锛堝叿鏈夆�滃彈鎺т簬鈥濆拰鈥滃叡鍚屾帶鍒垛�濈瓑鐩稿叧瀹氫箟锛夈��</div>
+ <div>1.4娣橀棯宸ュ钩鍙颁负鎮ㄦ彁渚涚壒绉嶅煿璁�佹帴娲句换鍔℃湇鍔★細鎸囦互浜掕仈缃戞妧鏈负渚濇墭鏋勫缓鏈嶅姟骞冲彴锛屾暣鍚堜緵闇�淇℃伅锛屼娇鐢ㄧ鍚堟潯浠剁殑鏈嶅姟锛岀畝绉扳�滄窐闂伐鏈嶅姟鈥濄��</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="浜屻�佸崗璁寖鍥村強鍙樻洿">
+ <div>
+ 2.1 绛剧害涓讳綋
+ <div>2.1.1 鏈崗璁敱鎮ㄤ笌瀹佹尝鍒涜儨淇℃伅鎶�鏈湇鍔℃湁闄愬叕鍙稿叡鍚岀紨缁擄紝鏈崗璁鎮ㄤ笌瀹佹尝鍒涜儨淇℃伅鎶�鏈湇鍔℃湁闄愬叕鍙稿潎鍏锋湁鍚堝悓鏁堝姏銆�</div>
+ <div>2.1.2聽娣橀棯宸ョ粡钀ヨ�呭彲鑳芥牴鎹钩鍙扮殑涓氬姟璋冩暣鑰屽彂鐢熷彉鏇达紝鍙樻洿鍚庣殑娣橀棯宸ョ粡钀ヨ�呬笌鎮ㄥ叡鍚屽饱琛屾湰鍗忚骞跺悜鎮ㄦ彁渚涙湇鍔★紝娣橀棯宸ョ粡钀ヨ�呯殑鍙樻洿涓嶄細褰卞搷鎮ㄦ湰鍗忚椤逛笅鐨勬潈鐩娿��</div>
+ </div>
+ <div>
+ 2.2 琛ュ厖鍗忚
+ <div>骞冲彴鍚勯」瑙勫垯鍧囦负鏈崗璁殑琛ュ厖鍗忚锛屼笌鏈崗璁笉鍙垎鍓蹭笖鍏锋湁鍚岀瓑娉曞緥鏁堝姏銆傚鎮ㄤ娇鐢ㄥ钩鍙版湇鍔★紝瑙嗕负鎮ㄥ悓鎰忎笂杩拌ˉ鍏呭崗璁��</div>
+ </div>
+ <div>
+ 2.3聽鍗忚鍙樻洿
+ <div>2.3.1 鍒涜儨鍙牴鎹浗瀹舵硶寰嬫硶瑙勫彉鍖栧強缁存姢浜ゆ槗绉╁簭銆佷繚鎶ゆ秷璐硅�呮潈鐩婇渶瑕侊紝涓嶆椂淇敼鏈崗璁�佽ˉ鍏呭崗璁紝鍙樻洿鍚庣殑鍗忚銆佽ˉ鍏呭崗璁紙涓嬬О鈥滃彉鏇翠簨椤光�濓級灏嗛�氳繃娉曞畾绋嬪簭骞朵互鏈崗璁鍗佷竴鏉$害瀹氱殑鏂瑰紡閫氱煡鎮ㄣ�傚鎮ㄤ笉鍚屾剰鍙樻洿浜嬮」锛屾偍鏈夋潈浜庡彉鏇翠簨椤圭‘瀹氱殑鐢熸晥鏃ュ墠鑱旂郴骞冲彴瀹㈡湇鍙嶉鎰忚銆�</div>
+ <div>2.3.2 濡傛偍瀵瑰凡鐢熸晥鐨勫彉鏇翠簨椤逛粛涓嶅悓鎰忕殑锛屾偍搴斿綋浜庡彉鏇翠簨椤圭‘瀹氱殑鐢熸晥涔嬫棩璧峰仠姝娇鐢ㄥ钩鍙版湇鍔★紝鍙樻洿浜嬮」瀵规偍涓嶄骇鐢熸晥鍔涳紱濡傛偍鍦ㄥ彉鏇翠簨椤圭敓鏁堝悗浠嶇户缁娇鐢ㄥ钩鍙版湇鍔★紝鍒欒涓烘偍鍚屾剰宸茬敓鏁堢殑鍙樻洿浜嬮」銆�</div>
+ </div>
+ <div>
+ 2.4聽鍗忚閫傜敤
+ <div>鏈崗璁粎閫傜敤浜庡垱鑳滀负鎮ㄦ彁渚涚壒绉嶅煿璁�佹帴娲句换鍔℃湇鍔★紝涓嶉�傜敤浜庡钩鍙颁腑宸插彟琛岀嫭绔嬭缃湇鍔″崗璁殑浜у搧鎴栨湇鍔°��</div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="涓夈�佹敞鍐屼笌璐︽埛">
+ <div>
+ 3.1 鐢ㄦ埛璧勬牸聽
+ <div>鎮ㄧ‘璁わ紝鍦ㄦ偍瀹屾垚骞冲彴娉ㄥ唽绋嬪簭鎴栦互鍒涜儨鍏佽鐨勫叾浠栨柟寮忓疄闄呬娇鐢ㄥ钩鍙版湇鍔℃椂锛屾偍搴斿綋鍏峰涓崕浜烘皯鍏卞拰鍥芥硶寰嬭瀹氱殑涓庢偍琛屼负鐩搁�傚簲鐨勬皯浜嬭涓鸿兘鍔涖�傝嫢鎮ㄤ笉鍏峰鍓嶈堪涓讳綋璧勬牸锛屽垯鎮ㄥ強鎮ㄧ殑鐩戞姢浜哄簲渚濈収娉曞緥瑙勫畾鎵挎媴鍥犳鑰屽鑷寸殑涓�鍒囧悗鏋滐紝涓斿垱鑳滄湁鏉冨洜姝ゆ垨鎺ュ彈鎮ㄧ洃鎶や汉鐨勬寚绀哄鎮ㄧ殑璐︽埛閲囧彇涓鎴栫粓姝㈤儴鍒嗘垨鍏ㄩ儴鏈嶅姟銆佹敞閿�绛夋帾鏂姐��</div>
+ </div>
+ <div>
+ 3.2 娉ㄥ唽鍜岃处鎴�
+ <div>3.2.1 褰撴偍鎸夌収娉ㄥ唽椤甸潰鎻愮ず濉啓淇℃伅銆侀槄璇诲苟鍚屾剰鏈崗璁笖瀹屾垚鍏ㄩ儴娉ㄥ唽绋嬪簭鍚庯紝鎮ㄥ嵆鎴愪负骞冲彴鐢ㄦ埛銆傛敞鍐屽悗锛屾偍鍙互浣跨敤鎵嬫満鍙风爜鎴栬�呭井淇°�佹敮浠樺疂绛夌涓夋柟骞冲彴灏忕▼搴忓厑璁哥殑鍏跺畠鏂瑰紡浣滀负鐧诲綍鎵嬫杩涘叆骞冲彴銆�</div>
+ <div>3.2.2 鎮ㄧ殑璐︽埛涓嶅緱浠ヤ换浣曟柟寮忎拱鍗栥�佽浆璁┿�佽禒涓庛�佺户鎵挎垨鍊熶笌浠栦汉浣跨敤锛岄櫎闈炴湁娉曞緥鏄庣‘瑙勫畾鎴栫敓鏁堟硶寰嬫枃涔︼紝骞剁粡鍒涜儨鍚屾剰涓旀寜骞冲彴瑙勫畾鐨勬祦绋嬪姙鐞嗐�傚惁鍒欐偍浠ヤ换浣曟柟寮忎拱鍗栥�佽浆璁┿�佽禒涓庛�佺户鎵挎垨鍊熶笌浠栦汉浣跨敤骞冲彴璐︽埛鐨勮涓哄潎涓烘棤鏁堬紝鎴戜滑鏈夋潈杩界┒鎮ㄧ殑杩濈害璐d换锛屼笖鐢辨浜х敓鐨勮矗浠诲強鍚庢灉鍧囩敱鎮ㄨ嚜琛屾壙鎷呫��</div>
+ </div>
+ <div>
+ 3.3 娉ㄥ唽淇℃伅
+ <div>3.3.1 鍦ㄦ敞鍐屽強浣跨敤骞冲彴鏃讹紝鎮ㄥ簲褰撴寜鐩稿簲椤甸潰鐨勬彁绀哄噯纭彁渚涙偍鐨勮祫鏂欙紝浠ヤ究骞冲彴涓烘偍鎻愪緵鏈嶅姟鍙�/鎴栦笌鎮ㄨ仈绯汇�傛偍浜嗚В骞跺悓鎰忥紝鎮ㄦ湁涔夊姟淇濇寔鎮ㄦ彁渚涗俊鎭殑鐪熷疄鎬у強鏈夋晥鎬э紝骞朵簬璧勬枡淇℃伅鍙樻洿鏃跺強鏃舵洿鏂帮紝浠ヤ繚璇佹偍鎵�鎻愪氦璧勬枡鐨勭湡瀹炪�佸畬鏁村拰鍑嗙‘銆�</div>
+ <div>3.3.2 鎮ㄨ缃殑骞冲彴鏄电О銆佸ご鍍忎笉寰楄繚鍙嶅浗瀹舵硶寰嬫硶瑙勩�佸叕搴忚壇淇楀強骞冲彴瑙勫垯鐨勭浉鍏宠瀹氾紝鍚﹀垯骞冲彴鏈夋潈瀵规偍鐨勮处鎴烽噰鍙栭檺鍒舵垨閮ㄥ垎闄愬埗鎮ㄤ娇鐢ㄥ钩鍙版湇鍔$殑鎺柦銆�</div>
+ </div>
+ <div>
+ 3.4 璐︽埛瀹夊叏
+ <div>3.4.1 鎮ㄧ殑璐︽埛涓烘偍鑷璁剧疆骞剁敱鎮ㄤ繚绠★紝鎴戜滑浠讳綍鏃跺�欏潎涓嶄細涓诲姩瑕佹眰鎮ㄦ彁渚涙偍鐨勮处鎴峰瘑鐮併�傚洜姝わ紝寤鸿鎮ㄥ姟蹇呬繚绠″ソ鎮ㄧ殑璐︽埛銆傝处鎴峰洜鎮ㄤ富鍔ㄦ硠闇叉垨鍥犳偍閬彈浠栦汉鏀诲嚮銆佽瘓楠楃瓑琛屼负瀵艰嚧鐨勬崯澶卞強鍚庢灉锛屽垱鑳滃苟涓嶆壙鎷呰矗浠伙紝鎮ㄥ簲閫氳繃鍙告硶銆佽鏀跨瓑鏁戞祹閫斿緞鍚戜镜鏉冭涓轰汉杩藉伩銆�</div>
+ <div>3.4.2 闄ゅ垱鑳滄壙鎷呰繃閿欎箣澶栵紝鎮ㄩ』瀵规偍鍦ㄨ璐︽埛涓嬪彂鐢熺殑鎵�鏈夋椿鍔紙鍖呮嫭浣嗕笉闄愪簬鍦ㄧ嚎绛剧讲鍗忚銆佷俊鎭姭闇层�佸彂甯冧换鍔¢渶姹傘�佽垂鐢ㄦ敮浠樼瓑锛夋壙鎷呰矗浠汇��</div>
+ <div>3.4.3 濡傛偍鍙戠幇浠讳綍浜烘湭缁忔巿鏉冧娇鐢ㄦ偍鐨勫钩鍙拌处鎴锋垨鍏朵粬鍙兘瀵艰嚧鎮ㄨ处鎴烽伃绐冦�侀仐澶辩殑鎯呭喌锛屽缓璁偍绔嬪嵆閫氱煡骞冲彴瀹㈡湇锛屽苟鎺堟潈骞冲彴瀵规偍鐨勮处鎴峰仛蹇呰鐨勫簲鎬ュ鐞嗭紙鍖呮嫭浣嗕笉闄愪簬璐︽埛鍐荤粨銆侀檺鍒惰处鎴烽儴鍒嗗姛鑳界敋鑷宠处鎴锋敞閿�锛夈�傛偍鐞嗚В鎴戜滑瀵规偍鐨勪换浣曡姹傞噰鍙栬鍔ㄥ潎闇�瑕佸悎鐞嗘椂闂达紝涓旀垜浠簲鎮ㄨ姹傝�岄噰鍙栫殑琛屽姩鍙兘鏃犳硶閬垮厤鎴栭樆姝镜瀹冲悗鏋滅殑褰㈡垚鎴栨墿澶э紝闄ゅ垱鑳滃瓨鍦ㄦ硶瀹氳繃閿欏锛屽垱鑳滀笉鎵挎媴璐d换銆�</div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍥涖�佸垱鑳滀负鎮ㄦ彁渚涚壒绉嶅煿璁�佹帴娲句换鍔℃湇鍔�">
+ <div>4.1 鍒涜儨涓烘偍鎻愪緵鐗圭鍩硅銆佹帴娲句换鍔℃湇鍔★紙绠�绉扳�滅壒绉嶅煿璁�佹帴娲句换鍔℃湇鍔♀�濓級锛屾湇鍔′骇鍝佸寘鎷絾涓嶉檺浜庡揩浜�佹儬浜�佷笓浜笌灏婁韩绛夛紙鍏蜂綋鏈嶅姟浜у搧浠ュ疄闄呮彁渚涙湇鍔$殑浜у搧椤甸潰涓哄噯锛夈��</div>
+ <div>4.2聽鍒涜儨涓烘偍鎻愪緵鐗圭鍩硅銆佹帴娲句换鍔℃湇鍔$殑鍏蜂綋鍐呭鍙婅寖鍥村彈涓嶅悓鍩庡競钀ヨ繍绛栫暐銆佸綋鍦版斂搴滃噯鍏ヨ鍙強鐩稿叧娉曞緥娉曡鍙婃斂绛栫殑褰卞搷鍙兘瀛樺湪宸紓鍙婂彉鍖栵紝璇蜂互鎮ㄦ帴鍙楁湇鍔℃椂骞冲彴瀹為檯鎻愪緵鐨勬湇鍔″唴瀹逛负鍑嗐��</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="浜斻�佺敤鎴疯涓鸿鑼�">
+ <div>
+ 5.1聽杞欢浣跨敤瑙勮寖
+ <div>闄ら潪娉曞緥鍏佽鎴栧垱鑳滀功闈㈣鍙紝鎮ㄤ娇鐢ㄥ钩鍙拌繃绋嬩腑涓嶅緱浠庝簨涓嬪垪琛屼负锛�</div>
+ <div>5.1.1 鍒犻櫎骞冲彴涓婂叧浜庣煡璇嗕骇鏉冪殑淇℃伅锛�</div>
+ <div>5.1.2 瀵瑰钩鍙拌繘琛屽弽鍚戝伐绋嬨�佸弽鍚戞眹缂栥�佸弽鍚戠紪璇戯紝鎴栬�呬互鍏朵粬鏂瑰紡灏濊瘯鍙戠幇骞冲彴鐨勬簮浠g爜锛�</div>
+ <div>5.1.3 瀵瑰钩鍙版嫢鏈夌煡璇嗕骇鏉冪殑鍐呭杩涜浣跨敤銆佸嚭绉熴�佸嚭鍊熴�佸鍒躲�佷慨鏀广�侀摼鎺ャ�佽浆杞姐�佹眹缂栥�佸彂琛ㄣ�佸嚭鐗堛�佸缓绔嬮暅鍍忕珯鐐圭瓑锛�</div>
+ <div>5.1.4 瀵瑰钩鍙板強鐩稿叧绯荤粺杩愯杩囩▼涓噴鏀惧埌浠讳綍缁堢鍐呭瓨涓殑鏁版嵁銆佺綉绔欒繍琛岃繃绋嬩腑瀹㈡埛绔笌鏈嶅姟鍣ㄧ鐨勪氦浜掓暟鎹紝浠ュ強骞冲彴杩愯鎵�蹇呴渶鐨勭郴缁熸暟鎹紝杩涜澶嶅埗銆佷慨鏀广�佸鍔犮�佸垹闄ゃ�佹寕鎺ヨ繍琛屾垨鍒涗綔浠讳綍琛嶇敓浣滃搧锛屽舰寮忓寘鎷絾涓嶉檺浜庝娇鐢ㄦ彃浠躲�佸鎸傛垨闈炵粡鍒涜儨鎺堟潈鐨勭涓夋柟宸ュ叿/鏈嶅姟鎺ュ叆骞冲彴鍜岀浉鍏崇郴缁燂紱</div>
+ <div>5.1.5 閫氳繃淇敼鎴栦吉閫犵綉绔欒繍琛屼腑鐨勬寚浠ゃ�佹暟鎹紝澧炲姞銆佸垹鍑忋�佸彉鍔ㄧ綉绔欑殑鍔熻兘鎴栬繍琛屾晥鏋滐紝鎴栬�呭皢鐢ㄤ簬涓婅堪鐢ㄩ�旂殑杞欢銆佹柟娉曡繘琛岃繍钀ユ垨鍚戝叕浼椾紶鎾紝鏃犺杩欎簺琛屼负鏄惁涓哄晢涓氱洰鐨勶紱</div>
+ <div>5.1.6 閫氳繃闈炲垱鑳滃紑鍙戙�佹巿鏉冪殑绗笁鏂硅蒋浠躲�佹彃浠躲�佸鎸傘�佺郴缁燂紝鐧诲綍鎴栦娇鐢ㄥ钩鍙板強鏈嶅姟锛屾垨鍒朵綔銆佸彂甯冦�佷紶鎾笂杩板伐鍏凤紱</div>
+ <div>5.1.7 鑷鎴栬�呮巿鏉冧粬浜恒�佺涓夋柟杞欢瀵规湰缃戠珯鍙婂叾缁勪欢銆佹ā鍧椼�佹暟鎹繘琛屽共鎵帮紱</div>
+ <div>5.1.8 鐮磋В骞舵姄鍙栨帴鍙d俊鎭悗鎭舵剰鏀诲嚮骞冲彴锛�</div>
+ <div>5.1.9 娉曞緥銆佽鏀挎硶瑙勭姝㈢殑锛岃繚鑳岀ぞ浼氬叕鍏卞埄鐩婃垨鍏叡閬撳痉鎴栦緷鎹浉鍏冲钩鍙拌鍒欑殑瑙勫畾绂佹渚靛鍒涜儨鍚堟硶鏉冪泭鐨勮涓恒��</div>
+ </div>
+ <div>
+ 5.2聽淇℃伅鍐呭瑙勮寖
+ <div>鎮ㄥ簲褰撶‘淇濇偍鎵�鍙戝竷鐨勪俊鎭紙鍖呮嫭浣嗕笉闄愪簬澶村儚銆佹樀绉版垨鍏朵粬鎮ㄥ彲鍏紑鍙戝竷鐨勪俊鎭級涓嶅寘鍚互涓嬪唴瀹癸細</div>
+ <div>5.2.1 鍙嶅瀹硶鎵�纭畾鐨勫熀鏈師鍒欑殑锛�</div>
+ <div>5.2.2 鍗卞鍥藉瀹夊叏锛屾硠闇插浗瀹剁瀵嗭紝棰犺鍥藉鏀挎潈锛岀牬鍧忓浗瀹剁粺涓�鐨勶紱</div>
+ <div>5.2.3 鎹熷鍥藉鑽h獕鍜屽埄鐩婄殑锛�</div>
+ <div>5.2.4 姝洸銆佷笐鍖栥�佷旱娓庛�佸惁瀹氳嫳闆勭儓澹簨杩瑰拰绮剧锛屼互渚颈銆佽璋ゆ垨鑰呭叾浠栨柟寮忎镜瀹宠嫳闆勭儓澹殑濮撳悕銆佽倴鍍忋�佸悕瑾夈�佽崳瑾夌殑锛�</div>
+ <div>5.2.5 瀹f壃鎭愭�栦富涔夈�佹瀬绔富涔夋垨鑰呯吔鍔ㄥ疄鏂芥亹鎬栨椿鍔ㄣ�佹瀬绔富涔夋椿鍔ㄧ殑锛�</div>
+ <div>5.2.6 鐓藉姩姘戞棌浠囨仺銆佹皯鏃忔瑙嗭紝鐮村潖姘戞棌鍥㈢粨鐨勶紱</div>
+ <div>5.2.7 鐮村潖鍥藉瀹楁暀鏀跨瓥锛屽鎵偑鏁欏拰灏佸缓杩蜂俊鐨勶紱</div>
+ <div>5.2.8 鏁e竷璋h█锛屾壈涔辩粡娴庣З搴忓拰绀句細绉╁簭鐨勶紱</div>
+ <div>5.2.9 鏁e竷娣Ы銆佽壊鎯呫�佽祵鍗氥�佹毚鍔涖�佸嚩鏉�銆佹亹鎬栨垨鑰呮暀鍞嗙姱缃殑锛�</div>
+ <div>5.2.10 渚颈鎴栬�呰璋や粬浜猴紝渚靛浠栦汉鍚嶈獕銆侀殣绉佸拰鍏朵粬鍚堟硶鏉冪泭鐨勶紱</div>
+ <div>5.2.11 娉曞緥銆佽鏀挎硶瑙勭姝㈢殑锛岃繚鑳岀ぞ浼氬叕鍏卞埄鐩婃垨鍏叡閬撳痉鎴栦緷鎹浉鍏冲钩鍙板崗璁�佽鍒欑殑瑙勫畾涓嶉�傚悎鍦ㄥ钩鍙颁笂鍙戝竷鐨勫叾浠栦俊鎭��</div>
+ </div>
+ <div>
+ 5.3聽鏈嶅姟瑙勮寖
+ <div>鎮ㄤ娇鐢ㄥ钩鍙颁娇鐢ㄥ垱鑳滀负鎮ㄦ彁渚涚壒绉嶅煿璁�佹帴娲句换鍔℃湇鍔℃椂搴旈伒瀹堜互涓嬭鑼冿細</div>
+ <div>5.3.1 鎮ㄧ殑鍙戝竷鐪熷疄闇�姹傦紝骞朵粩缁嗙‘璁や换鍔℃墍鍦ㄤ綅缃�佹墜鏈哄彿鐮侊紙濡傞渶锛夌瓑淇℃伅锛屼笉寰楀疄鏂芥伓鎰忓彂甯冦�佹伓鎰忕淮鏉冩垨涓查�氱涓夋柟瀹炴柦闈炴硶鑾峰埄鎬ц涓虹瓑鎵颁贡骞冲彴姝e父浜ゆ槗绉╁簭鐨勮涓猴紱</div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍏�佽矗浠婚檺鍒�">
+ <div>
+ 6.1聽鍒涜儨搴斾緷鐓ф硶寰嬭瀹氬饱琛屽熀纭�淇濋殰涔夊姟锛屼絾瀵逛簬涓嬭堪鍘熷洜瀵艰嚧鐨勫悎鍚屽饱琛岄殰纰嶃�佸饱琛岀憰鐤点�佸饱琛屽欢鍚庢垨灞ヨ鍐呭鍙樻洿绛夋儏褰紝鍒涜儨骞朵笉鎵挎媴鐩稿簲鐨勮繚绾﹁矗浠伙細
+ <div>1)鍥犺嚜鐒剁伨瀹炽�佺舰宸ャ�佹毚涔便�佹垬浜夈�佹斂搴滆涓恒�佸徃娉曡鏀垮懡浠ょ瓑涓嶅彲鎶楀姏鍥犵礌锛�</div>
+ <div>2)鍥犵數鍔涗緵搴旀晠闅溿�侀�氳缃戠粶鏁呴殰绛夊叕鍏辨湇鍔″洜绱犳垨绗笁浜哄洜绱狅紱</div>
+ <div>3)鍦ㄥ垱鑳滃凡灏藉杽鎰忕鐞嗙殑鎯呭喌涓嬶紝鍥犲父瑙勬垨绱ф�ョ殑璁惧涓庣郴缁熺淮鎶ゃ�佽澶囦笌绯荤粺鏁呴殰绛夊洜绱犮��</div>
+ </div>
+ <div>6.2聽浠庢偍鍙戦�佽鍗曞苟鐢辩郴缁熸垚鍔熷尮閰嶅紑濮嬶紝鍒拌鍗曞畬鎴愪箣鏃讹紝 鍒涜儨鍦ㄤ互骞冲彴涓烘偍鎻愪緵鐗圭鍩硅銆佹帴娲句换鍔℃湇鍔″尯闂村唴锛屾牴鎹�傜敤娉曞緥娉曡鐨勮姹傛壙鎷呯浉搴旂殑娉曞緥璐d换銆傚洜绗笁鏂逛镜鏉冩垨杩濈害瀵艰嚧鎮ㄩ伃鍙楁崯澶辩殑锛屽垱鑳滀笉鎵挎媴娉曞緥璐d换锛屼絾灏嗕細绉瀬鍗忚皟鐩稿叧浜哄憳銆佷繚闄╁叕鍙革紙濡傞�傜敤锛夎繘琛屽鐞嗐��</div>
+ <div>6.3聽鍦ㄦ硶寰嬪厑璁哥殑鑼冨洿鍐咃紝鍒涜儨涓嶅浠讳綍闂存帴鎬с�佸悗鏋滄�с�佹儵缃氭�с�佸伓鐒舵�х殑鎹熷鎵挎媴璐d换銆�</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="涓冦�佺敤鎴蜂釜浜轰俊鎭繚鎶�">
+ <div>鍒涜儨闈炲父閲嶈鐢ㄦ埛涓汉淇℃伅鐨勪繚鎶わ紝鍦ㄦ偍浣跨敤鍒涜儨鎻愪緵鐨勬湇鍔℃椂锛屾偍鍚屾剰鍒涜儨鎸夌収鍦ㄥ钩鍙颁笂鍏竷鐨勯殣绉佹潈鏀跨瓥鏀堕泦銆佸瓨鍌ㄣ�佷娇鐢ㄣ�佹姭闇插拰淇濇姢鎮ㄧ殑涓汉淇℃伅銆傚缓璁偍瀹屾暣鍦伴槄璇汇�婇殣绉佹潈鏀跨瓥銆嬶紝浠ュ府鍔╂偍鏇村ソ鍦颁繚鎶ゆ偍鐨勯殣绉佹潈銆�</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍏�佽繚绾﹁矗浠�">
+ <div>
+ 8.1 杩濈害璁ゅ畾
+ <div>鍙戠敓濡備笅鎯呭舰涔嬩竴鐨勶紝瑙嗕负鎮ㄨ繚绾︼細</div>
+ <div>8.1.1 浣跨敤骞冲彴鏈嶅姟鏃惰繚鍙嶆湁鍏虫硶寰嬫硶瑙勮瀹氱殑锛�</div>
+ <div>8.1.2 杩濆弽鏈崗璁垨鏈崗璁ˉ鍏呭崗璁紙鍗虫湰鍗忚绗�2.2鏉★級绾﹀畾鐨勩��</div>
+ </div>
+ <div>
+ 8.2 杩濈害澶勭悊鎺柦
+ <div>8.2.1 銆愪俊鎭鐞嗐�戞偍鍦ㄥ钩鍙颁笂鍙戝竷鐨勪俊鎭瀯鎴愯繚绾︾殑锛屽垱鑳滃彲鏍规嵁鐩稿簲瑙勫垯绔嬪嵆瀵圭浉搴斾俊鎭繘琛屽垹闄ゃ�佸睆钄藉鐞嗭紝骞惰鎯呭舰鍐荤粨璐﹀彿閮ㄥ垎鎴栧叏閮ㄥ姛鑳姐��</div>
+ <div>8.2.2 銆愯涓洪檺鍒躲�戞偍鍦ㄥ钩鍙颁笂瀹炴柦鐨勮涓猴紙鍖呮嫭浣嗕笉闄愪簬杞欢浣跨敤琛屼负锛夛紝鎴栬櫧鏈湪骞冲彴涓婂疄鏂戒絾瀵瑰钩鍙般�佺敤鎴蜂骇鐢熷奖鍝嶇殑琛屼负鏋勬垚杩濈害鐨勶紝鍒涜儨鏈夋潈鐙珛鍒ゆ柇骞惰鎯呭喌閲囧彇涓鎴栫粓姝㈠悜鎮ㄦ彁渚涢儴鍒嗘垨鍏ㄩ儴鏈嶅姟绛夊鐞嗘帾鏂斤紝鑻ュ洜姝ゅ鑷存偍閬彈鎹熷け鐨勶紝鐢辨偍鑷鎵挎媴銆�</div>
+ <div>8.2.3 鍩轰簬缁存姢骞冲彴浜ゆ槗绉╁簭鍙婁氦鏄撳畨鍏ㄧ殑闇�瑕侊紝鍒涜儨鍙戠幇涓婅堪鎯呭舰鏃跺彲涓诲姩鎵ц鍏抽棴鐩稿叧璁㈠崟鍙婅处鎴风瓑鎿嶄綔銆�</div>
+ </div>
+ <div>
+ 8.3 璧斿伩璐d换
+ <div>8.3.1 濡傛偍鐨勮涓轰娇鍒涜儨鍙�/鎴栧叾鍏宠仈鍏徃閬彈鎹熷け锛堝寘鎷嚜韬殑鐩存帴缁忔祹鎹熷け銆佸晢瑾夋崯澶卞強瀵瑰鏀粯鐨勮禂鍋块噾銆佸拰瑙f銆佸緥甯堣垂銆佽瘔璁艰垂绛夐棿鎺ョ粡娴庢崯澶憋級锛屾偍搴旇禂鍋垮垱鑳滃強/鎴栧叾鍏宠仈鍏徃涓婅堪鍏ㄩ儴鎹熷け銆�</div>
+ <div>8.3.2 濡傛偍鐨勮涓轰娇鍒涜儨鍙�/鎴栧叾鍏宠仈鍏徃閬彈绗笁浜轰富寮犳潈鍒╋紝鍒涜儨鍙�/鎴栧叾鍏宠仈鍏徃鍙湪瀵圭涓変汉鎵挎媴閲戦挶缁欎粯绛変箟鍔″悗灏卞叏閮ㄦ崯澶卞悜鎮ㄨ拷鍋裤��</div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="涔濄�佸崗璁粓姝�">
+ <div>
+ 9.1 缁堟鐨勬儏褰�
+ <div>9.1.1 銆愮敤鎴峰彂璧风殑缁堟銆戞偍鏈夋潈閫氳繃浠ヤ笅浠讳竴鏂瑰紡缁堟鏈崗璁細</div>
+ <div>1)鍦ㄦ弧瓒冲钩鍙板叕绀虹殑璐︽埛娉ㄩ攢鏉′欢鏃舵偍鑷富娉ㄩ攢鎮ㄧ殑璐︽埛鐨勶紱</div>
+ <div>2)鍙樻洿浜嬮」鐢熸晥鍓嶆偍鍋滄浣跨敤骞舵槑绀轰笉鎰挎帴鍙楀彉鏇翠簨椤圭殑锛�</div>
+ <div>3)鎮ㄦ槑绀轰笉鎰跨户缁娇鐢ㄥ钩鍙版湇鍔★紝涓旂鍚堝钩鍙扮粓姝㈡潯浠剁殑銆�</div>
+ <div>9.1.2 銆愬垱鑳滃彂璧风殑缁堟銆戝嚭鐜颁互涓嬫儏鍐垫椂锛屽垱鑳滃彲浠ユ湰鍗忚绗節鏉$殑鎵�鍒楃殑鏂瑰紡閫氱煡鎮ㄧ粓姝㈡湰鍗忚锛�</div>
+ <div>1)鎮ㄨ繚鍙嶆湰鍗忚绾﹀畾锛屽垱鑳滀緷鎹繚绾︽潯娆剧粓姝㈡湰鍗忚鐨勶紱</div>
+ <div>2)鎮ㄧ洍鐢ㄤ粬浜鸿处鎴枫�佸彂甯冭繚绂佷俊鎭�佹壈涔卞競鍦虹З搴忋�侀噰鍙栦笉姝e綋鎵嬫璋嬪埄绛夎涓猴紝鍒涜儨渚濇嵁骞冲彴瑙勫垯瀵规偍鐨勮处鎴蜂簣浠ユ煡灏佺殑锛�</div>
+ <div>3)闄や笂杩版儏褰㈠锛屽洜鎮ㄥ娆¤繚鍙嶅钩鍙拌鍒欑浉鍏宠瀹氫笖鎯呰妭涓ラ噸锛屽垱鑳滀緷鎹钩鍙拌鍒欏鎮ㄧ殑璐︽埛浜堜互鏌ュ皝鐨勶紱</div>
+ <div>4)鍏跺畠搴斿綋缁堟鏈嶅姟鐨勬儏鍐点��</div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍗併�侀�氱煡">
+ <div>10.1 鎮ㄥ悓鎰忓垱鑳滃悜鎮ㄧ殑鎵嬫満鍙风爜鎴栬�呯數瀛愰偖绠卞彂閫佹偍鎰熷叴瓒g殑鍟嗗搧骞垮憡淇℃伅銆佷績閿�浼樻儬绛夊晢涓氭�т俊鎭紱鎮ㄥ鏋滀笉鎰挎剰鎺ユ敹姝ょ被淇℃伅锛屾偍鏈夋潈閫氳繃鍒涜儨鎻愪緵鐨勭浉搴旂殑閫�璁㈠姛鑳借繘琛岄��璁€��</div>
+ <div>
+ 10.2 閫氱煡鐨勯�佽揪
+ <div>10.2.1 鍒涜儨閫氳繃鑱旂郴鏂瑰紡鍚戞偍鍙戝嚭閫氱煡锛屽叾涓互鐢靛瓙鐨勬柟寮忓彂鍑虹殑涔﹂潰閫氱煡锛堝寘鎷絾涓嶉檺浜庡湪骞冲彴鍏憡锛屽悜鎮ㄦ彁渚涚殑鑱旂郴鐢佃瘽鍙戦�佹墜鏈虹煭淇★紝鍚戞偍鎻愪緵鐨勭數瀛愰偖浠跺湴鍧�鍙戦�佺數瀛愰偖浠讹紝鍚戞偍鐨勮处鍙峰彂閫佺郴缁熸秷鎭瓑锛夛紝鍦ㄥ彂閫佹垚鍔熷悗鍗宠涓洪�佽揪锛涗互绾歌川杞戒綋鍙戝嚭鐨勪功闈㈤�氱煡锛屼互蹇�掓垨鐗╂祦鍏徃绯荤粺鏄剧ず绛炬敹鏃跺嵆瑙嗕负閫佽揪銆�</div>
+ <div>10.2.2 瀵逛簬鍦ㄥ钩鍙颁笂鍥犱氦鏄撴椿鍔ㄥ紩璧风殑浠讳綍绾犵悍锛屾偍鍚屾剰鍙告硶鏈哄叧锛堝寘鎷絾涓嶉檺浜庝汉姘戞硶闄級鍙互閫氳繃鎵嬫満鐭俊銆佺數瀛愰偖浠剁瓑鐜颁唬閫氳鏂瑰紡鎴栭偖瀵勬柟寮忓悜鎮ㄩ�佽揪娉曞緥鏂囦功锛堝寘鎷絾涓嶉檺浜庤瘔璁兼枃涔︼級銆傛偍鎸囧畾鎺ユ敹娉曞緥鏂囦功鐨勬墜鏈哄彿鐮併�佺數瀛愰偖绠辩瓑鑱旂郴鏂瑰紡涓烘偍鍦ㄥ钩鍙版敞鍐屻�佹洿鏂版椂鎻愪緵鐨勬墜鏈哄彿鐮併�佺數瀛愰偖绠辫仈绯绘柟寮忥紝鍙告硶鏈哄叧鍚戜笂杩拌仈绯绘柟寮忓彂鍑烘硶寰嬫枃涔﹀嵆瑙嗕负閫佽揪銆傛偍鎸囧畾鐨勯偖瀵勫湴鍧�涓烘偍鐨勬硶瀹氳仈绯诲湴鍧�鎴栨偍鎻愪緵鐨勬湁鏁堣仈绯诲湴鍧�銆�</div>
+ <div>10.2.3 鎮ㄥ悓鎰忓徃娉曟満鍏冲彲閲囧彇浠ヤ笂涓�绉嶆垨澶氱閫佽揪鏂瑰紡鍚戞偍閫佽揪娉曞緥鏂囦功锛屽徃娉曟満鍏抽噰鍙栧绉嶆柟寮忓悜鎮ㄩ�佽揪娉曞緥鏂囦功锛岄�佽揪鏃堕棿浠ヤ笂杩伴�佽揪鏂瑰紡涓渶鍏堥�佽揪鐨勪负鍑嗐��</div>
+ <div>10.2.4 鎮ㄥ悓鎰忎笂杩伴�佽揪鏂瑰紡閫傜敤浜庡悇涓徃娉曠▼搴忛樁娈点�傚杩涘叆璇夎绋嬪簭鐨勶紝鍖呮嫭浣嗕笉闄愪簬涓�瀹°�佷簩瀹°�佸啀瀹°�佹墽琛屼互鍙婄潱淇冪▼搴忕瓑銆�</div>
+ <div>10.2.5 鎮ㄥ簲褰撲繚璇佹墍鎻愪緵鐨勮仈绯绘柟寮忔槸鍑嗙‘銆佹湁鏁堢殑锛屽苟杩涜瀹炴椂鏇存柊銆傚鏋滃洜鎻愪緵鐨勮仈绯绘柟寮忎笉纭垏锛屾垨涓嶅強鏃跺憡鐭ュ彉鏇村悗鐨勮仈绯绘柟寮忥紝浣挎硶寰嬫枃涔︽棤娉曢�佽揪鎴栨湭鍙婃椂閫佽揪锛岀敱鎮ㄨ嚜琛屾壙鎷呯敱姝ゅ彲鑳戒骇鐢熺殑娉曞緥鍚庢灉銆�</div>
+ </div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍗佷竴銆佺煡璇嗕骇鏉�">
+ <div>11.1 骞冲彴鏈嶅姟涓彁渚涚殑鍐呭锛堝寘鎷絾涓嶉檺浜庤蒋浠躲�佹妧鏈�佺▼搴忋�佺綉椤点�佹枃瀛椼�佸浘鐗囥�佸浘鍍忋�侀煶棰戙�佽棰戙�佸浘琛ㄣ�佺増闈㈣璁°�佺數瀛愭枃妗g瓑锛夌殑鐭ヨ瘑浜ф潈灞炰簬鍒涜儨鎵�鏈夈��</div>
+ <div>11.2 骞冲彴鏈嶅姟鎵�渚濇墭鐨勮蒋浠剁殑钁椾綔鏉冦�佷笓鍒╂潈鍙婂叾浠栫煡璇嗕骇鏉冨潎褰掑垱鑳滄墍鏈夈��</div>
+ <div>11.3 鍒涜儨涓哄钩鍙板紑鍙戙�佽繍钀ユ彁渚涙妧鏈敮鎸侊紝骞跺鐏垫椿鐢ㄥ伐杞欢鍙婄浉鍏虫湇鍔$殑寮�鍙戝拰杩愯惀绛夎繃绋嬩腑浜х敓鐨勬墍鏈夋暟鎹拰淇℃伅绛変韩鏈夋硶寰嬫硶瑙勫厑璁歌寖鍥村唴鐨勫叏閮ㄦ潈鍒┿��</div>
+ <div>11.4 鏈粡鍒涜儨鍙﹁涔﹂潰鎺堟潈锛屾偍涓嶅緱浣跨敤鈥滄窐闂伐銆佺伒宸ヨ揪銆佸伐鏄撹禋鈥濈瓑鍦ㄥ唴鐨勪换浣曞晢鏍囥�佹湇鍔℃爣璁般�丩OGO銆佸晢鍙枫�佸煙鍚嶃�佺綉绔欏悕绉版垨鍏朵粬鏄捐憲鍝佺墝鐗瑰緛绛夛紙浠ヤ笅缁熺О涓衡�滄爣璇嗏�濓級锛屼笉寰楀皢鏈潯娆惧墠杩版爣璇嗕互鍗曠嫭鎴栫粨鍚堜换浣曟柟寮忓睍绀恒�佷娇鐢ㄦ垨鐢宠娉ㄥ唽鍟嗘爣銆佽繘琛屽煙鍚嶆敞鍐岀瓑锛屼篃涓嶅緱瀹炴柦鍚戜粬浜烘槑绀烘垨鏆楃ず鏈夋潈灞曠ず銆佷娇鐢ㄣ�佹垨鍏朵粬鏈夋潈澶勭悊璇ヤ簺鏍囪瘑鐨勮涓恒�傜敱浜庢偍杩濆弽鏈崗璁娇鐢ㄤ笂杩板晢鏍囥�佹爣璇嗙瓑缁欏垱鑳滄垨浠栦汉閫犳垚鎹熷け鐨勶紝鐢辨偍鎵挎媴鍏ㄩ儴娉曞緥璐d换銆�</div>
+ </UserPolicyCell>
+ <UserPolicyCell title="鍗佷簩銆佹硶寰嬮�傜敤銆佺杈栦笌鍏朵粬">
+ <div>12.1銆愭硶寰嬮�傜敤涓庣杈栥�戞湰鍗忚涔嬫晥鍔涖�佽В閲娿�佸彉鏇淬�佹墽琛屼笌浜夎瑙e喅鍧囬�傜敤涓崕浜烘皯鍏卞拰鍥芥硶寰嬨�傚洜鏈崗璁骇鐢熶箣浜夎锛屽潎搴斾緷鐓т腑鍗庝汉姘戝叡鍜屽浗娉曞緥浜堜互澶勭悊锛屽苟鐢辨睙鑻忕渷姹熷畞缁忔祹鎶�鏈紑鍙戝尯浜烘皯娉曢櫌绠¤緰锛堝叕鍙告敞鍐屽湴浜烘皯娉曢櫌锛岃鏀癸級銆�</div>
+ <div>12.2銆愬彲鍒嗘�с�戞湰鍗忚浠讳竴鏉℃琚涓哄簾姝€�佹棤鏁堟垨涓嶅彲鎵ц锛岃鏉″簲瑙嗕负鍙垎鐨勪笖骞朵笉褰卞搷鏈崗璁叾浣欐潯娆剧殑鏈夋晥鎬у強鍙墽琛屾�с��</div>
+ </UserPolicyCell>
+ </div>
+ </scroll-view>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import { ScrollView } from '@tarojs/components';
+
+defineOptions({
+ name: 'userPolicy',
+});
+
+const UserPolicyCell = defineComponent({
+ name: 'UserPolicyCell',
+ props: {
+ title: {
+ type: String,
+ },
+ content: {
+ type: String,
+ },
+ },
+ setup(props, { slots }) {
+ return () => {
+ return h('div', { class: 'userPolicy-cell-wrapper' }, [
+ h('div', { class: 'userPolicy-cell-title' }, [props.title]),
+ h('div', { class: 'userPolicy-cell-content' }, slots.default?.()),
+ ]);
+ };
+ },
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.userPolicy-page-wrapper {
+ background-color: #fafafa;
+
+ .userPolicy-page-scrollview {
+ // flex: 1;
+ height: 100%;
+ box-sizing: border-box;
+ }
+
+ .userPolicy-page-scrollview-content {
+ padding: 42px;
+
+ .userPolicy-page-title {
+ margin-bottom: 40px;
+ }
+ }
+
+ .userPolicy-cell-wrapper {
+ margin-bottom: 32px;
+
+ .userPolicy-cell-title {
+ color: #292929;
+ font-size: 30px;
+ margin-bottom: 22px;
+ font-weight: 500;
+ }
+
+ .userPolicy-cell-content {
+ div {
+ font-size: 24px;
+ line-height: 40px;
+ text-indent: 28px;
+ color: #888888;
+ }
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/InnerPage.vue
new file mode 100644
index 0000000..498c579
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/InnerPage.vue
@@ -0,0 +1,85 @@
+<template>
+ <ProTabs
+ v-model="queryState.userSignContractStatus"
+ name="home-tab"
+ :showPaneContent="false"
+ class="home-tabs"
+ isTransparent
+ title-gutter="12"
+ title-scroll
+ >
+ <ProTabPane :title="`鍏ㄩ儴`" :pane-key="0"></ProTabPane>
+ <ProTabPane :title="`寰呯绾" :pane-key="EnumTaskUserSignContractStatus.Wait"></ProTabPane>
+ <ProTabPane :title="`鐢熸晥涓璥" :pane-key="EnumTaskUserSignContractStatus.Pass"></ProTabPane>
+ <ProTabPane :title="`宸茬粓姝" :pane-key="EnumTaskUserSignContractStatus.Stop"></ProTabPane>
+ </ProTabs>
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ :key="queryState.userSignContractStatus"
+ >
+ <template #renderItem="{ item }">
+ <MineAgreementSignCard
+ :enterpriseName="item.enterpriseName"
+ :userSignContractStatus="item.userSignContractStatus"
+ @click="goDetail(item)"
+ >
+ </MineAgreementSignCard>
+ </template>
+ </InfiniteLoading>
+</template>
+
+<script setup lang="ts">
+import { MineAgreementSignCard, ProTabs, ProTabPane } from '@12333/components';
+import { useUserStore } from '@/stores/modules/user';
+import { useInfiniteLoading } from '@12333/hooks';
+import { EnumPagedListOrder, EnumTaskUserSignContractStatus } from '@12333/constants';
+import * as enterpriseEmployeeServices from '@12333/services/apiV2/enterpriseEmployee';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const queryState = reactive({
+ userSignContractStatus: 0 as any as EnumTaskUserSignContractStatus,
+});
+
+const userStore = useUserStore();
+
+const { infiniteLoadingProps } = useInfiniteLoading(
+ ({ pageParam }) => {
+ let params: API.GetPersonalUserElectronSignsQuery = {
+ pageModel: {
+ rows: 20,
+ page: pageParam,
+ orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
+ },
+ userSignContractStatus: Number(queryState.userSignContractStatus)
+ ? queryState.userSignContractStatus
+ : null,
+ };
+
+ return enterpriseEmployeeServices.getPersonalUserElectronSigns(params, {
+ showLoading: false,
+ });
+ },
+ {
+ queryKey: ['enterpriseEmployeeServices/getPersonalUserElectronSigns', queryState],
+ }
+);
+
+function goDetail(row: API.GetPersonalUserElectronSignsQueryResultItem) {
+ Taro.navigateTo({
+ url: `${RouterPath.mineAgreementSignDetail}?id=${row.id}`,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+// .mineAgreementSign-page-wrapper {
+//
+// }
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.vue
new file mode 100644
index 0000000..3bf5d51
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSign/mineAgreementSign.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayoutWithBg class="mineAgreementSign-page-wrapper" :title="'鍗忚绛剧害'">
+ <InnerPage></InnerPage>
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineAgreementSign',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/InnerPage.vue
new file mode 100644
index 0000000..cb8ae8c
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/InnerPage.vue
@@ -0,0 +1,190 @@
+<template>
+ <LoadingLayout>
+ <ContentScrollView :paddingH="false" style="background-color: transparent">
+ <div class="mine-agreement-sign-detail">
+ <MineAgreementSignDetailCard title="鍩烘湰淇℃伅">
+ <template #content>
+ <MineAgreementSignDetailItem
+ label="鍗忚缂栧彿"
+ :detail="detail?.contractCode"
+ ></MineAgreementSignDetailItem>
+ <MineAgreementSignDetailItem
+ label="鍗忚鐘舵��"
+ :detail="EnumTaskUserSignContractStatusSignText[detail?.userSignContractStatus]"
+ ></MineAgreementSignDetailItem>
+ </template>
+ </MineAgreementSignDetailCard>
+ <MineAgreementSignDetailCard title="绛剧害鏂逛俊鎭� - 鍛樺伐">
+ <template #content>
+ <MineAgreementSignDetailItem
+ label="鍛樺伐濮撳悕"
+ :detail="detail?.name"
+ ></MineAgreementSignDetailItem>
+ <MineAgreementSignDetailItem
+ label="璇佷欢绫诲瀷"
+ :detail="detail?.identityType"
+ ></MineAgreementSignDetailItem>
+ <MineAgreementSignDetailItem
+ label="璇佷欢鍙风爜"
+ :detail="detail?.identity"
+ ></MineAgreementSignDetailItem>
+ <MineAgreementSignDetailItem
+ label="绛剧害鏃堕棿"
+ :detail="format(detail?.userSignContractTime, 'YYYY-MM-DD')"
+ ></MineAgreementSignDetailItem>
+ </template>
+ </MineAgreementSignDetailCard>
+ <MineAgreementSignDetailCard title="绛剧害鏂逛俊鎭� - 鍏徃涓讳綋">
+ <template #content>
+ <MineAgreementSignDetailItem
+ label="涓讳綋绫诲瀷"
+ :detail="detail?.enterpriseType"
+ ></MineAgreementSignDetailItem>
+ <MineAgreementSignDetailItem
+ label="绛剧害涓讳綋"
+ :detail="detail?.enterpriseName"
+ ></MineAgreementSignDetailItem>
+ <MineAgreementSignDetailItem
+ label="绛剧害鏃堕棿"
+ :detail="format(detail?.enterpriseSignContractTime, 'YYYY-MM-DD')"
+ ></MineAgreementSignDetailItem>
+ </template>
+ </MineAgreementSignDetailCard>
+ <MineAgreementSignDetailCard title="绛剧害鍐呭">
+ <template #content>
+ <MineAgreementSignDetailItem label="鍗忚鍐呭">
+ <template #detail>
+ <div class="detail-card-btn" @click="checkAgreement">鏌ョ湅鍗忚</div>
+ </template>
+ </MineAgreementSignDetailItem>
+ </template>
+ </MineAgreementSignDetailCard>
+ </div>
+ </ContentScrollView>
+ <PageFooter v-if="detail?.userSignContractStatus === EnumTaskUserSignContractStatus.Wait">
+ <PageFooterBtn type="primary" @click="goToSign" :loading="btnLoading">鍘荤绾�</PageFooterBtn>
+ </PageFooter>
+ </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import { useQuery } from '@tanstack/vue-query';
+import MineAgreementSignDetailCard from './MineAgreementSignDetailCard.vue';
+import MineAgreementSignDetailItem from './MineAgreementSignDetailItem.vue';
+import * as enterpriseEmployeeServices from '@12333/services/apiV2/enterpriseEmployee';
+import {
+ EnumElectronSignAccess,
+ EnumTaskUserSignContractStatus,
+ EnumTaskUserSignContractStatusSignText,
+} from '@12333/constants';
+import { format, hiddenPhone, Message, setOSSLink, openDocument } from '@12333/utils';
+import Taro from '@tarojs/taro';
+import _ from 'lodash';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { userDetail } = useUser();
+const router = Taro.useRouter();
+const options = Taro.getLaunchOptionsSync();
+//鐏靛伐Id
+const id = router.params?.id;
+const code = router.params?.code || options?.query?.scene;
+const btnLoading = ref(false);
+
+const {
+ isLoading,
+ isError,
+ data: detail,
+ refetch,
+} = useQuery({
+ queryKey: ['enterpriseEmployeeServices/getPersonalUserElectronSign', id, code],
+ queryFn: async () => {
+ return await enterpriseEmployeeServices.getPersonalUserElectronSign(
+ { id: id, code: code },
+ {
+ showLoading: false,
+ }
+ );
+ },
+ placeholderData: () => ({} as API.GetPersonalUserElectronSignQueryResult),
+ onSuccess(data) {
+ // if (data.isExistTradeChatRecord) setTrue();
+ },
+});
+
+async function checkAgreement() {
+ try {
+ const res = await refetch();
+ if (res?.data?.userSignContractStatus === EnumTaskUserSignContractStatus.Wait) {
+ goToSign();
+ }
+ if (
+ res?.data?.userSignContractStatus === EnumTaskUserSignContractStatus.Stop ||
+ res?.data?.userSignContractStatus === EnumTaskUserSignContractStatus.Pass
+ ) {
+ if (!res?.data?.contractUrl) {
+ Message.warning('鍗忚鏃犳硶鏌ョ湅锛岃绋嶅悗鍐嶈瘯');
+ return;
+ }
+ openDocument(setOSSLink(res?.data?.contractUrl));
+ }
+ } catch (error) {}
+}
+
+const goToSign = useAccessReal(async () => {
+ try {
+ btnLoading.value = true;
+ let params: API.PersonalUserElectronSignCommand = {
+ id: detail.value?.id,
+ returnUrl: `${RouterPath.mineAgreementSignDetail}?id=${id}`,
+ };
+ let res = await enterpriseEmployeeServices.personalUserElectronSign(params);
+ if (res) {
+ if (detail.value?.contractTemplateAccess === EnumElectronSignAccess.AlipaySign) {
+ try {
+ await Message.confirm({
+ message: `绛剧害鐭俊宸插彂閫佽嚦鎮�${hiddenPhone(
+ detail.value?.contactPhoneNumber
+ )}鐨勬墜鏈猴紝璇峰強鏃舵煡鐪嬪苟绛剧害`,
+ cancelText: '鏈敹鍒扮煭淇�',
+ });
+ } catch (error) {
+ goToSign();
+ }
+ } else {
+ const encodedUrl = encodeURIComponent(res.signContractLongUrl);
+ Taro.redirectTo({ url: `${RouterPath.extraPage}?url=${encodedUrl}` });
+ }
+ btnLoading.value = false;
+ } else {
+ btnLoading.value = false;
+ }
+ } catch (error) {
+ btnLoading.value = false;
+ }
+});
+
+Taro.useDidShow(() => {
+ refetch();
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mineAgreementSignDetail-page-wrapper {
+ .mine-agreement-sign-detail {
+ padding: 20px 28px 0;
+
+ .mine-agreement-sign-detail-card {
+ margin-bottom: 24px;
+ }
+ }
+
+ .detail-card-btn {
+ color: boleGetCssVar('color', 'primary');
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailCard.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailCard.vue
new file mode 100644
index 0000000..756807e
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailCard.vue
@@ -0,0 +1,41 @@
+<template>
+ <div class="mine-agreement-sign-detail-card">
+ <div class="mine-agreement-sign-detail-card-title">
+ <slot name="title">
+ {{ title }}
+ </slot>
+ </div>
+ <div class="mine-agreement-sign-detail-card-content">
+ <slot name="content"></slot>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'MineAgreementSignDetailCard',
+});
+
+type Props = {
+ title?: string;
+};
+
+const props = withDefaults(defineProps<Props>(), {});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mine-agreement-sign-detail-card {
+ background-color: #fff;
+ border-radius: 12px;
+ padding: 24px 34px 34px;
+
+ .mine-agreement-sign-detail-card-title {
+ font-size: 30px;
+ line-height: 42px;
+ color: boleGetCssVar('text-color', 'primary');
+ margin-bottom: 36px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailItem.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailItem.vue
new file mode 100644
index 0000000..2d7db50
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/MineAgreementSignDetailItem.vue
@@ -0,0 +1,64 @@
+<template>
+ <div class="mine-agreement-sign-detail-item">
+ <div
+ class="mine-agreement-sign-detail-item-lebel"
+ :style="{ width: labelWidth, textAlign: textAlign }"
+ >
+ <slot name="label">
+ {{ label }}
+ </slot>
+ </div>
+ <div class="mine-agreement-sign-detail-item-detail">
+ <slot name="detail">
+ {{ detail }}
+ </slot>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+ name: 'MineAgreementSignDetailItem',
+});
+
+type Props = {
+ label?: string;
+ detail?: string;
+ labelWidth?: any;
+ textAlign?: any;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+ labelWidth: '50px',
+ textAlign: 'left',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mine-agreement-sign-detail-item {
+ margin-bottom: 24px;
+ display: flex;
+ align-items: center;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .mine-agreement-sign-detail-item-lebel {
+ font-size: 24px;
+ line-height: 36px;
+ margin-right: 24px;
+ color: boleGetCssVar('text-color', 'regular');
+ }
+
+ .mine-agreement-sign-detail-item-detail {
+ font-size: 24px;
+ line-height: 36px;
+ color: boleGetCssVar('text-color', 'primary');
+ flex: 1;
+ min-width: 0;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.vue
new file mode 100644
index 0000000..2be18fe
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineAgreementSignDetail/mineAgreementSignDetail.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayoutWithBg class="mineAgreementSignDetail-page-wrapper" :title="'鍗忚璇︽儏'">
+ <InnerPage> </InnerPage>
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineAgreementSignDetail',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/InnerPage.vue
new file mode 100644
index 0000000..48ee139
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/InnerPage.vue
@@ -0,0 +1,72 @@
+<template>
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ >
+ <template #renderItem="{ item }">
+ <TaskCard
+ :name="item.name"
+ :begin-time="item.beginTime"
+ :end-time="item.endTime"
+ :billing-method="item.billingMethod"
+ :benefits="item.benefits"
+ :service-fee="item.serviceFee"
+ :settlement-cycle="item.settlementCycle"
+ :address-name="item.addressName"
+ @click="goTaskDetail(item)"
+ >
+ <template #actions>
+ <div class="task-card-actions-text">{{ '宸插彇娑�' }}</div>
+ </template>
+ </TaskCard>
+ </template>
+ </InfiniteLoading>
+</template>
+
+<script setup lang="ts">
+import { TaskCard } from '@12333/components';
+import { useInfiniteLoading } from '@12333/hooks';
+import { EnumPagedListOrder } from '@12333/constants';
+import * as taskServices from '@12333/services/apiV2/task';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { infiniteLoadingProps } = useInfiniteLoading(
+ ({ pageParam }) => {
+ let params: API.GetPersonalCancelTaskInfosQuery = {
+ pageModel: {
+ rows: 20,
+ page: pageParam,
+ orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
+ },
+ };
+ return taskServices.getPersonalCancelTaskInfos(params, {
+ showLoading: false,
+ });
+ },
+ {
+ queryKey: ['taskServices/getPersonalCancelTaskInfos'],
+ }
+);
+
+function goTaskDetail(item: API.GetPersonalHireTaskInfosQueryResultItem) {
+ Taro.navigateTo({
+ url: `${RouterPath.taskDetail}?id=${item.id}&from=cancel`,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mineCancel-page-wrapper {
+ .task-card-actions-text {
+ font-size: 24px;
+ line-height: 42px;
+ color: #9fa4ac;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.vue
new file mode 100644
index 0000000..c38a214
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineCancel/mineCancel.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayoutWithBg class="mineCancel-page-wrapper" :title="'宸插彇娑�'">
+ <InnerPage></InnerPage>
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineCancel',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/InnerPage.vue
new file mode 100644
index 0000000..39bcc63
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/InnerPage.vue
@@ -0,0 +1,106 @@
+<template>
+ <div class="my-collect-task">
+ <div class="my-collect-task-title">鏀惰棌浠诲姟鍒楄〃</div>
+ <div class="my-collect-task-btn" @click="clearExpiredTask">娓呯┖宸插け鏁堜换鍔�</div>
+ </div>
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ >
+ <template #renderItem="{ item }">
+ <TaskCard
+ :id="item.id"
+ :name="item.name"
+ :address-name="item.addressName"
+ :begin-time="item.beginTime"
+ :end-time="item.endTime"
+ :gender-limit="item.genderLimit"
+ :service-fee="item.serviceFee"
+ :billing-method="item.billingMethod"
+ :settlement-cycle="item.settlementCycle"
+ :benefits="item.benefits"
+ :show-actions="true"
+ :release-status="item.releaseStatus"
+ :hireStatus="item.hireStatus"
+ @apply="goTaskDetail"
+ >
+ </TaskCard>
+ </template>
+ </InfiniteLoading>
+</template>
+
+<script setup lang="ts">
+import { TaskCard } from '@12333/components';
+import * as taskServices from '@12333/services/apiV2/task';
+import * as taskUserServices from '@12333/services/apiV2/taskUser';
+import { useInfiniteLoading, useTaskList } from '@12333/hooks';
+import Taro from '@tarojs/taro';
+import { Message } from '@12333/utils';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { infiniteLoadingProps, invalidateQueries } = useInfiniteLoading(
+ ({ pageParam }) => {
+ let params: API.GetTaskInfosQuery = {
+ pageModel: {
+ rows: 20,
+ page: pageParam,
+ },
+ isCollected: true,
+ };
+
+ return taskServices.getTaskInfos(params, {
+ showLoading: false,
+ });
+ },
+ {
+ queryKey: ['taskServices/getTaskInfos'],
+ }
+);
+
+function goTaskDetail(id: string) {
+ Taro.navigateTo({
+ url: `${RouterPath.taskDetail}?id=${id}&from=apply`,
+ });
+}
+
+async function clearExpiredTask() {
+ try {
+ await Message.confirm({
+ message: '纭畾瑕佹竻绌哄凡澶辨晥浠诲姟鍚楋紵',
+ });
+ let res = await taskUserServices.clearTaskCollect({});
+ if (res) {
+ Message.success('娓呯┖鎴愬姛');
+ invalidateQueries();
+ }
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mineCollectTask-page-wrapper {
+ .my-collect-task {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 30px 40px;
+
+ .my-collect-task-title {
+ font-size: 28px;
+ line-height: 40px;
+ color: boleGetCssVar('text-color', 'primary');
+ }
+
+ .my-collect-task-btn {
+ font-size: 24px;
+ line-height: 34px;
+ color: boleGetCssVar('text-color', 'regular');
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.vue
new file mode 100644
index 0000000..13044ff
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineCollectTask/mineCollectTask.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayoutWithBg class="mineCollectTask-page-wrapper" :title="'鎴戞敹钘忕殑浠诲姟'">
+ <InnerPage></InnerPage>
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineCollectTask',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/InnerPage.vue
new file mode 100644
index 0000000..494c1a5
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/InnerPage.vue
@@ -0,0 +1,114 @@
+<template>
+ <ProTabs
+ v-model="queryState.status"
+ name="home-tab"
+ :showPaneContent="false"
+ class="home-tabs"
+ isTransparent
+ title-gutter="12"
+ title-scroll
+ >
+ <ProTabPane :title="`鍏ㄩ儴`" :pane-key="0"></ProTabPane>
+ <ProTabPane :title="`寰呭紑濮媊" :pane-key="GetPersonalHireTaskInfosQueryStatus.Wait"></ProTabPane>
+ <ProTabPane
+ :title="`杩涜涓璥"
+ :pane-key="GetPersonalHireTaskInfosQueryStatus.InProcess"
+ ></ProTabPane>
+ <ProTabPane
+ :title="`宸插畬鎴恅"
+ :pane-key="GetPersonalHireTaskInfosQueryStatus.Completed"
+ ></ProTabPane>
+ </ProTabs>
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ :key="queryState.status"
+ >
+ <template #renderItem="{ item }">
+ <TaskCard
+ :name="item.name"
+ :begin-time="item.beginTime"
+ :end-time="item.endTime"
+ :billing-method="item.billingMethod"
+ :benefits="item.benefits"
+ :service-fee="item.serviceFee"
+ :settlement-cycle="item.settlementCycle"
+ :address-name="item.addressName"
+ :unRead="item.unRead"
+ @click="goTaskDetail(item)"
+ >
+ <template #actions>
+ <div
+ class="task-card-actions-text"
+ :style="{ color: GetPersonalHireTaskInfosQueryStatusColor[item.status] }"
+ >
+ {{ GetPersonalHireTaskInfosQueryStatusText[item.status] }}
+ </div>
+ </template>
+ </TaskCard>
+ </template>
+ </InfiniteLoading>
+</template>
+
+<script setup lang="ts">
+import { TaskCard, ProTabs, ProTabPane } from '@12333/components';
+import { useInfiniteLoading } from '@12333/hooks';
+import {
+ EnumPagedListOrder,
+ GetPersonalHireTaskInfosQueryStatus,
+ GetPersonalHireTaskInfosQueryStatusText,
+ GetPersonalHireTaskInfosQueryStatusColor,
+ EnumTaskUserArrangeStatus,
+ EnumReadScene,
+} from '@12333/constants';
+import * as taskServices from '@12333/services/apiV2/task';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const queryState = reactive({
+ status: 0 as any as GetPersonalHireTaskInfosQueryStatus,
+});
+
+const { infiniteLoadingProps } = useInfiniteLoading(
+ ({ pageParam }) => {
+ let params: API.GetPersonalHireTaskInfosQuery = {
+ pageModel: {
+ rows: 20,
+ page: pageParam,
+ orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
+ },
+ // status: GetPersonalHireTaskInfosQueryStatus.InProcess,
+ arrangeStatus: EnumTaskUserArrangeStatus.Complete,
+ };
+ if (Number(queryState.status)) {
+ params.status = queryState.status;
+ }
+ return taskServices.getPersonalHireTaskInfos(params, {
+ showLoading: false,
+ });
+ },
+ {
+ queryKey: ['taskServices/getPersonalHireTaskInfos', queryState],
+ }
+);
+
+function goTaskDetail(item: API.GetPersonalHireTaskInfosQueryResultItem) {
+ Taro.navigateTo({
+ url: `${RouterPath.taskDetail}?id=${item.id}&from=hire&readScene=${EnumReadScene.TaskUserArrangePassForPersonal}`,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mineHire-page-wrapper {
+ .task-card-actions-text {
+ font-size: 24px;
+ line-height: 42px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.vue
new file mode 100644
index 0000000..30a41f3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineHire/mineHire.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayoutWithBg class="mineHire-page-wrapper" :title="'浠诲姟涓�'">
+ <InnerPage></InnerPage>
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineHire',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/InnerPage.vue
new file mode 100644
index 0000000..c24d147
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/InnerPage.vue
@@ -0,0 +1,113 @@
+<template>
+ <!-- <ProTabs
+ v-model="queryState.status"
+ name="home-tab"
+ :showPaneContent="false"
+ class="home-tabs"
+ isTransparent
+ title-gutter="12"
+ title-scroll
+ >
+ <ProTabPane :title="`鍏ㄩ儴`" :pane-key="0"></ProTabPane>
+ <ProTabPane :title="`寰呭紑濮媊" :pane-key="GetPersonalHireTaskInfosQueryStatus.Wait"></ProTabPane>
+ <ProTabPane
+ :title="`杩涜涓璥"
+ :pane-key="GetPersonalHireTaskInfosQueryStatus.InProcess"
+ ></ProTabPane>
+ <ProTabPane
+ :title="`宸插畬鎴恅"
+ :pane-key="GetPersonalHireTaskInfosQueryStatus.Completed"
+ ></ProTabPane>
+ </ProTabs> -->
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ :key="queryState.status"
+ >
+ <template #renderItem="{ item }">
+ <TaskCard
+ :name="item.name"
+ :begin-time="item.beginTime"
+ :end-time="item.endTime"
+ :billing-method="item.billingMethod"
+ :benefits="item.benefits"
+ :service-fee="item.serviceFee"
+ :settlement-cycle="item.settlementCycle"
+ :address-name="item.addressName"
+ :unRead="item.unRead"
+ @click="goTaskDetail(item)"
+ >
+ <template #actions>
+ <div
+ class="task-card-actions-text"
+ :style="{ color: GetPersonalHireTaskInfosQueryStatusColor[item.status] }"
+ >
+ {{ GetPersonalHireTaskInfosQueryStatusText[item.status] }}
+ </div>
+ </template>
+ </TaskCard>
+ </template>
+ </InfiniteLoading>
+</template>
+
+<script setup lang="ts">
+import { TaskCard, ProTabs, ProTabPane } from '@12333/components';
+import { useInfiniteLoading } from '@12333/hooks';
+import {
+ EnumPagedListOrder,
+ GetPersonalHireTaskInfosQueryStatus,
+ GetPersonalHireTaskInfosQueryStatusText,
+ GetPersonalHireTaskInfosQueryStatusColor,
+ EnumTaskUserHireStatus,
+ EnumReadScene,
+} from '@12333/constants';
+import * as taskServices from '@12333/services/apiV2/task';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const queryState = reactive({
+ status: 0 as any as GetPersonalHireTaskInfosQueryStatus,
+});
+
+const { infiniteLoadingProps } = useInfiniteLoading(
+ ({ pageParam }) => {
+ let params: API.GetPersonalHireTaskInfosQuery = {
+ pageModel: {
+ rows: 20,
+ page: pageParam,
+ orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
+ },
+ hireStatus: EnumTaskUserHireStatus.Pass,
+ };
+ // if (Number(queryState.status)) {
+ // params.status = queryState.status;
+ // }
+ return taskServices.getPersonalHireTaskInfos(params, {
+ showLoading: false,
+ });
+ },
+ {
+ queryKey: ['taskServices/getPersonalHireTaskInfos', queryState],
+ }
+);
+
+function goTaskDetail(item: API.GetPersonalHireTaskInfosQueryResultItem) {
+ Taro.navigateTo({
+ url: `${RouterPath.taskDetail}?id=${item.id}&readScene=${EnumReadScene.TaskUserHirePassForPersonal}`,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mineHired-page-wrapper {
+ .task-card-actions-text {
+ font-size: 24px;
+ line-height: 42px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.vue
new file mode 100644
index 0000000..855ba32
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineHired/mineHired.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayoutWithBg class="mineHired-page-wrapper" :title="'宸插綍鐢�'">
+ <InnerPage></InnerPage>
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineHired',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/InnerPage.vue
new file mode 100644
index 0000000..0115ec4
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/InnerPage.vue
@@ -0,0 +1,117 @@
+<template>
+ <ProTabs
+ v-model="queryState.status"
+ name="home-tab"
+ :showPaneContent="false"
+ class="home-tabs"
+ isTransparent
+ title-gutter="12"
+ title-scroll
+ >
+ <ProTabPane :title="`鍏ㄩ儴`" :pane-key="0"></ProTabPane>
+ <ProTabPane
+ :title="`寰呯‘璁"
+ :pane-key="GetPersonalApplyTaskInfosQueryStatus.WaitHire"
+ ></ProTabPane>
+ <ProTabPane
+ :title="`寰呯绾"
+ :pane-key="GetPersonalApplyTaskInfosQueryStatus.WaitSignContract"
+ ></ProTabPane>
+ <ProTabPane
+ :title="`宸茶阿缁漙"
+ :pane-key="GetPersonalApplyTaskInfosQueryStatus.HireRefuse"
+ ></ProTabPane>
+ </ProTabs>
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ :key="queryState.status"
+ >
+ <template #renderItem="{ item }">
+ <TaskCard
+ :name="item.name"
+ :begin-time="item.beginTime"
+ :end-time="item.endTime"
+ :billing-method="item.billingMethod"
+ :benefits="item.benefits"
+ :service-fee="item.serviceFee"
+ :settlement-cycle="item.settlementCycle"
+ :address-name="item.addressName"
+ :unRead="item.unRead"
+ @click="goTaskDetail(item)"
+ >
+ <template #actions>
+ <div
+ class="task-card-actions-text"
+ :style="{ color: GetPersonalApplyTaskInfosQueryStatusColor[item.status] }"
+ >
+ {{ GetPersonalApplyTaskInfosQueryStatusText[item.status] }}
+ </div>
+ </template>
+ </TaskCard>
+ </template>
+ </InfiniteLoading>
+</template>
+
+<script setup lang="ts">
+import { TaskCard, ProTabs, ProTabPane } from '@12333/components';
+import { useUserStore } from '@/stores/modules/user';
+import { useInfiniteLoading } from '@12333/hooks';
+import {
+ EnumPagedListOrder,
+ GetPersonalApplyTaskInfosQueryStatus,
+ GetPersonalApplyTaskInfosQueryStatusText,
+ GetPersonalApplyTaskInfosQueryStatusColor,
+ EnumReadScene,
+} from '@12333/constants';
+import * as taskServices from '@12333/services/apiV2/task';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const queryState = reactive({
+ status: 0 as any as GetPersonalApplyTaskInfosQueryStatus,
+});
+
+const userStore = useUserStore();
+
+const { infiniteLoadingProps } = useInfiniteLoading(
+ ({ pageParam }) => {
+ let params: API.GetPersonalApplyTaskInfosQuery = {
+ pageModel: {
+ rows: 20,
+ page: pageParam,
+ orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
+ },
+ };
+ if (Number(queryState.status)) {
+ params.status = queryState.status;
+ }
+ return taskServices.getPersonalApplyTaskInfos(params, {
+ showLoading: false,
+ });
+ },
+ {
+ queryKey: ['taskServices/getPersonalApplyTaskInfos', queryState],
+ }
+);
+
+function goTaskDetail(item: API.GetPersonalApplyTaskInfosQueryResultItem) {
+ Taro.navigateTo({
+ url: `${RouterPath.taskDetail}?id=${item.id}&from=sign&readScene=${EnumReadScene.TaskUserApplyForPersonal}`,
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mineSign-page-wrapper {
+ .task-card-actions-text {
+ font-size: 24px;
+ line-height: 42px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.vue b/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.vue
new file mode 100644
index 0000000..082fd8f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/mineSign/mineSign.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayoutWithBg class="mineSign-page-wrapper" :title="'鎴戠殑鎶ュ悕'">
+ <InnerPage></InnerPage>
+ </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineSign',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.config.ts b/apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.vue b/apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.vue
new file mode 100644
index 0000000..0bf35f9
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/mine/setting/setting.vue
@@ -0,0 +1,109 @@
+<template>
+ <PageLayout title="璁剧疆" class="setting-page-wrapper" hasBorder>
+ <List>
+ <!-- <ListItem title="鐧诲綍璐﹀彿">
+ <template #extra>
+ <div class="user-account">
+ {{ userAccount }}
+ </div>
+ </template>
+ </ListItem> -->
+ <ListItem title="鐢ㄦ埛鍗忚" @click="goMineUserPolicy"></ListItem>
+ <ListItem title="闅愮鏀跨瓥" @click="goPrivacyPolicy"></ListItem>
+ <ListItem title="閫�鍑虹櫥褰�" @click="handleLoginout"></ListItem>
+ <!-- <ListItem title="浜哄伐瀹㈡湇" @click="goMineService"></ListItem> -->
+ <!-- <nut-button :open-type="'contact'" class="setting-page-service">浜哄伐瀹㈡湇</nut-button> -->
+ </List>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import { List, ListItem } from '@12333/components';
+import { addStarForString, Message } from '@12333/utils';
+import { useUserStore } from '@/stores/modules/user';
+import { useQueryClient } from '@tanstack/vue-query';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'setting',
+});
+
+const userStore = useUserStore();
+const queryClient = useQueryClient();
+
+const userAccount = computed(() => {
+ return addStarForString(userStore?.userDetail?.name, 4, 8);
+});
+
+function goMineUserPolicy() {
+ Taro.navigateTo({
+ url: RouterPath.mineUserPolicy,
+ });
+}
+function goPrivacyPolicy() {
+ Taro.navigateTo({
+ url: RouterPath.privacyPolicy,
+ });
+}
+
+async function handleLoginout() {
+ try {
+ await Message.confirm({
+ message: '纭畾瑕侀��鍑虹櫥褰曞悧锛�',
+ });
+ userStore.logoutAndToHome();
+ queryClient.removeQueries({
+ predicate: (query) => !query.queryKey.includes('taskServices/getOpenTaskInfos'),
+ });
+ } catch (error) {}
+}
+
+function goMineService() {
+ // const encodedUrl = encodeURIComponent('https://work.weixin.qq.com/kfid/kfcd24e0c60fd91099');
+ Taro.openCustomerServiceChat({
+ extInfo: {
+ // url: 'https://work.weixin.qq.com/kfid/kfcd24e0c60fd91099',
+ url: `${RouterPath.setting}`,
+ },
+ corpId: 'wwc84cb8e0525c772f',
+ // corpId: 'kfc2335f41fb4f0c0bc',
+ fail: (res) => {
+ Taro.showToast({
+ title: res.errMsg,
+ icon: 'none',
+ });
+ },
+ });
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.setting-page-wrapper {
+ .user-account {
+ color: boleGetCssVar('text-color', 'regular');
+ font-size: 24px;
+ }
+
+ .setting-page-service {
+ height: 104px;
+ padding-left: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ width: 100%;
+
+ &::before {
+ display: none;
+ }
+
+ &::after {
+ display: none;
+ }
+
+ .nut-button__wrap {
+ justify-content: flex-start;
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.config.ts b/apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.vue b/apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.vue
new file mode 100644
index 0000000..afd4841
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/user/complaint/complaint.vue
@@ -0,0 +1,121 @@
+<template>
+ <PageLayout
+ title="鎶曡瘔涓炬姤"
+ class="cooperation-page-wrapper"
+ hasBorder
+ :needAuth="false"
+ developing
+ >
+ <ContentScrollView :paddingH="false">
+ <nut-form :model-value="form" ref="formRef" :rules="rules">
+ <nut-form-item label="浼佷笟鍚嶇О:" class="bole-form-item" prop="companyName" required>
+ <nut-input
+ v-model.trim="form.companyName"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ヤ紒涓氬悕绉�"
+ type="text"
+ :max-length="35"
+ show-word-limit
+ />
+ </nut-form-item>
+ <nut-form-item label="鑱旂郴浜�:" class="bole-form-item" prop="contact" required>
+ <nut-input
+ v-model.trim="form.contact"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ヨ仈绯讳汉濮撳悕"
+ type="text"
+ :max-length="10"
+ show-word-limit
+ />
+ </nut-form-item>
+ <nut-form-item label="鑱旂郴鐢佃瘽:" class="bole-form-item" prop="contactPhone" required>
+ <nut-input
+ v-model.trim="form.contactPhone"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ヨ仈绯讳汉鐢佃瘽"
+ type="text"
+ />
+ </nut-form-item>
+ <nut-form-item label="鎶曡瘔璇存槑:" class="bole-form-item alignTop" prop="remark" required>
+ <nut-textarea
+ placeholder="璇疯緭鍏ヤ妇鎶ユ姇璇夌殑璇存槑"
+ placeholderClass="bole-input-text-placeholder"
+ autoSize
+ class="bole-input-textarea"
+ v-model="form.remark"
+ :max-length="500"
+ show-word-limit
+ >
+ </nut-textarea>
+ </nut-form-item>
+ </nut-form>
+ </ContentScrollView>
+ <PageFooter :isOnlyAction="false">
+ <PageFooterBtn type="primary" @click="handleConfirm">鎻愪氦</PageFooterBtn>
+ </PageFooter>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import { CooperateTypeText, CooperateApplyTypeEnum } from '@12333/constants';
+import { FormValidator, Message } from '@12333/utils';
+import Taro from '@tarojs/taro';
+import { useUser } from '@/hooks';
+
+defineOptions({
+ name: 'complaint',
+});
+
+const { userDetail } = useUser();
+
+const form = reactive({
+ companyName: userDetail.value?.customerName ?? '',
+ contact: userDetail.value?.contacter ?? '',
+ contactPhone: userDetail.value?.phoneNumber ?? '',
+ remark: '',
+});
+
+const rules = reactive<FormRules>({
+ companyName: [{ required: true, message: '璇疯緭鍏ヤ紒涓氬悕绉�' }],
+ contact: [{ required: true, message: '璇疯緭鍏ヨ仈绯讳汉濮撳悕' }],
+ contactPhone: [
+ { required: true, message: '璇疯緭鍏ヨ仈绯荤數璇�' },
+ { message: '璇疯緭鍏ユ纭殑鑱旂郴鐢佃瘽', validator: FormValidator.validatorTelNumber },
+ ],
+ remark: [{ required: true, message: '璇疯緭鍏ヤ妇鎶ユ姇璇夌殑璇存槑' }],
+});
+
+const formRef = ref<any>(null);
+
+function handleConfirm() {
+ if (!formRef.value) return;
+ formRef.value.validate().then(({ valid, errors }: any) => {
+ if (valid) {
+ createPlatformCooperationApply();
+ }
+ });
+}
+
+async function createPlatformCooperationApply() {
+ try {
+ // let params: API.CreatePlatformCooperationApplyInput = {
+ // title: CooperateTypeText.Complaint,
+ // contact: form.contact,
+ // contactPhone: form.contactPhone,
+ // applyDescription: form.remark,
+ // companyName: form.companyName,
+ // applyType: CooperateApplyTypeEnum.Complaint,
+ // };
+ // let res = await cooperationApplyServices.createPlatformCooperationApply(params);
+ // if (res) {
+ // await Message.confirm({
+ // message: '淇℃伅宸叉彁浜わ紝璇疯�愬績绛夊緟宸ヤ綔浜哄憳鐨勮仈绯�',
+ // });
+ // Taro.navigateBack({
+ // delta: 1,
+ // });
+ // }
+ } catch (error) {}
+}
+</script>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/InnerPage.vue
new file mode 100644
index 0000000..48f2006
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/InnerPage.vue
@@ -0,0 +1,50 @@
+<template>
+ <BindWalletView
+ :type="EnumUserBankCardAccess.AliPay"
+ :detail="detail"
+ @Unbind="handleUnbind"
+ ></BindWalletView>
+</template>
+
+<script setup lang="ts">
+import { Message } from '@12333/utils';
+import * as userServices from '@12333/services/apiV2/user';
+import { EnumUserBankCardAccess } from '@12333/constants';
+import { BindWalletView } from '@12333/components';
+import { usePersonalUserBankCard } from '../hooks';
+import { goBack } from '@/utils';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const switchTab = useSwitchTab();
+
+const { updateUserInfo } = useUser();
+
+const { detail } = usePersonalUserBankCard({
+ access: EnumUserBankCardAccess.AliPay,
+});
+
+async function handleUnbind() {
+ try {
+ await Message.confirm({ message: '纭畾瑕佽В缁戞敮浠樺疂鍚楋紵' });
+ let params: API.DeletePersonalUserBankCardCommand = {
+ access: EnumUserBankCardAccess.AliPay,
+ };
+ let res = await userServices.deletePersonalUserBankCard(params);
+ if (res) {
+ Message.success('瑙g粦鎴愬姛', {
+ onClosed() {
+ updateUserInfo();
+ goBack();
+ },
+ });
+ }
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.vue
new file mode 100644
index 0000000..4c569b8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/bindAlipay/bindAlipay.vue
@@ -0,0 +1,18 @@
+<template>
+ <PageLayout class="bindAlipay-page-wrapper" :title="'缁戝畾鏀粯瀹�'">
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'bindAlipay',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/InnerPage.vue
new file mode 100644
index 0000000..287d3a3
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/InnerPage.vue
@@ -0,0 +1,48 @@
+<template>
+ <BindWalletView
+ :type="EnumUserBankCardAccess.Bank"
+ :detail="detail"
+ @Unbind="handleUnbind"
+ ></BindWalletView>
+</template>
+
+<script setup lang="ts">
+import { Message } from '@12333/utils';
+import * as userServices from '@12333/services/apiV2/user';
+import { EnumUserBankCardAccess } from '@12333/constants';
+import { BindWalletView } from '@12333/components';
+import { usePersonalUserBankCard } from '../hooks';
+import { goBack } from '@/utils';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { updateUserInfo } = useUser();
+
+const { detail } = usePersonalUserBankCard({
+ access: EnumUserBankCardAccess.Bank,
+});
+
+async function handleUnbind() {
+ try {
+ await Message.confirm({ message: '纭畾瑕佽В缁戦摱琛屽崱鍚楋紵' });
+ let params: API.DeletePersonalUserBankCardCommand = {
+ access: EnumUserBankCardAccess.Bank,
+ };
+ let res = await userServices.deletePersonalUserBankCard(params);
+ if (res) {
+ Message.success('瑙g粦鎴愬姛', {
+ onClosed() {
+ updateUserInfo();
+ goBack();
+ },
+ });
+ }
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.vue
new file mode 100644
index 0000000..f3ee2e4
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/bindBankCard/bindBankCard.vue
@@ -0,0 +1,18 @@
+<template>
+ <PageLayout class="bindBankCard-page-wrapper" :title="'缁戝畾閾惰鍗�'">
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'bindBankCard',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/hooks/index.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/hooks/index.ts
new file mode 100644
index 0000000..6ab885d
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/hooks/index.ts
@@ -0,0 +1,66 @@
+import { useQuery } from '@tanstack/vue-query';
+import * as userServices from '@12333/services/apiV2/user';
+import { MaybeRef, unref } from 'vue';
+import { EnumUserBankCardAccess } from '@12333/constants';
+
+type UsePersonalUserTransactionOptions = {
+ id?: MaybeRef<string>;
+};
+
+export function useGetPersonalUserTransaction(options: UsePersonalUserTransactionOptions = {}) {
+ const { id } = options;
+
+ const {
+ isLoading,
+ isError,
+ data: detail,
+ refetch,
+ } = useQuery({
+ queryKey: ['userServices/getPersonalUserTransaction', id],
+ queryFn: async () => {
+ return await userServices.getPersonalUserTransaction(
+ { id: unref(id) },
+ {
+ showLoading: false,
+ }
+ );
+ },
+ placeholderData: () => ({} as API.GetPersonalUserTransactionQueryResult),
+ enabled: computed(() => !!unref(id)),
+ });
+
+ return {
+ detail,
+ };
+}
+
+type UsePersonalUserBankCardOptions = {
+ access?: EnumUserBankCardAccess;
+};
+
+export function usePersonalUserBankCard(options: UsePersonalUserBankCardOptions = {}) {
+ const { access } = options;
+
+ const {
+ isLoading,
+ isError,
+ data: detail,
+ refetch,
+ } = useQuery({
+ queryKey: ['userServices/getPersonalUserBankCard'],
+ queryFn: async () => {
+ return await userServices.getPersonalUserBankCard(
+ { access: access },
+ {
+ showLoading: false,
+ }
+ );
+ },
+ placeholderData: () => ({} as API.GetPersonalUserBankCardQueryResult),
+ onSuccess(data) {},
+ });
+
+ return {
+ detail,
+ };
+}
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/InnerPage.vue
new file mode 100644
index 0000000..a36c3a8
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/InnerPage.vue
@@ -0,0 +1,167 @@
+<template>
+ <!-- <ProTabs
+ v-model="queryState.type"
+ name="home-tab"
+ :showPaneContent="false"
+ class="home-tabs"
+ isTransparent
+ title-gutter="12"
+ title-scroll
+ >
+ <ProTabPane :title="`鍏ㄩ儴`" :pane-key="0"></ProTabPane>
+ <ProTabPane :title="`鏀跺叆`" :pane-key="EnumUserWalletTransactionType.Income"></ProTabPane>
+ <ProTabPane :title="`鎻愮幇`" :pane-key="EnumUserWalletTransactionType.Withdraw"></ProTabPane>
+ </ProTabs> -->
+ <List>
+ <IncomeDetailListItem hasPaddingH :item="`鏀跺叆锛氾骏${toThousand(sumIncome)} `">
+ <template #title>
+ <div class="income-detail-time-picker">
+ <ChooseInputWithDatePicker
+ v-model="queryState.month"
+ type="year-month"
+ :max-date="nowDate"
+ format="YYYY-MM"
+ />
+ <IconFont name="triangle-down" class="income-detail-time-picker-icon"></IconFont>
+ </div>
+ </template>
+ </IncomeDetailListItem>
+ </List>
+ <InfiniteLoading
+ scrollViewClassName="common-infinite-scroll-list home-list"
+ v-bind="infiniteLoadingProps"
+ :key="queryState.type"
+ >
+ <template #renderItem="{ item }">
+ <IncomeDetailListItem
+ :title="item.title"
+ :funds="item.amount"
+ :item="dayjs(item.createdTime).format('YYYY-MM-DD HH:mm:ss')"
+ :value="`閽卞寘浣欓锛�${toThousand(item.balance)}`"
+ @click="goIncomeDetailInfo(item)"
+ >
+ </IncomeDetailListItem>
+ </template>
+ </InfiniteLoading>
+</template>
+
+<script setup lang="ts">
+import {
+ List,
+ IncomeDetailListItem,
+ ChooseInputWithDatePicker,
+ ProTabs,
+ ProTabPane,
+} from '@12333/components';
+import { IconFont } from '@nutui/icons-vue-taro';
+import Taro from '@tarojs/taro';
+import dayjs from 'dayjs';
+import { useInfiniteLoading } from '@12333/hooks';
+import { EnumPagedListOrder, EnumUserWalletTransactionType } from '@12333/constants';
+import { toThousand } from '@12333/utils';
+import * as userServices from '@12333/services/apiV2/user';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const nowDate = dayjs().toDate();
+
+const queryState = reactive({
+ month: dayjs().format('YYYY-MM'),
+ type: 0 as any as EnumUserWalletTransactionType,
+});
+
+const sumIncome = computed(() => {
+ return infiniteLoadingProps.value?.listData?.pages?.[0]?.objectData?.sumIncome ?? 0;
+});
+const sumWithdraw = computed(() => {
+ return infiniteLoadingProps.value?.listData?.pages?.[0]?.objectData?.sumWithdraw ?? 0;
+});
+
+const { infiniteLoadingProps } = useInfiniteLoading(
+ ({ pageParam }) => {
+ let params: API.GetPersonalUserTransactionsQuery = {
+ pageModel: {
+ rows: 20,
+ page: pageParam,
+ orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
+ },
+ type: EnumUserWalletTransactionType.Income,
+ };
+ // if (Number(queryState.type)) {
+ // params.type = queryState.type;
+ // }
+ if (queryState.month) {
+ params.createdTimeStart = dayjs(queryState.month).startOf('month').format('YYYY-MM-DD');
+ params.createdTimeEnd = dayjs(queryState.month).endOf('month').format('YYYY-MM-DD');
+ }
+ return userServices.getPersonalUserTransactions(params, {
+ showLoading: false,
+ });
+ },
+ {
+ queryKey: ['userServices/getPersonalUserTransactions', queryState],
+ }
+);
+
+function goIncomeDetailInfo(row: API.GetPersonalUserTransactionsQueryResultItem) {
+ Taro.navigateTo({
+ url: `${RouterPath.incomeDetailInfo}?id=${row.id}`,
+ });
+ // if (row.type === EnumUserWalletTransactionType.Income) {
+ // Taro.navigateTo({
+ // url: `${RouterPath.incomeDetailInfo}?id=${row.id}`,
+ // });
+ // }
+ // if (row.type === EnumUserWalletTransactionType.Withdraw) {
+ // Taro.navigateTo({
+ // url: `${RouterPath.withdrawDetailInfo}?id=${row.id}`,
+ // });
+ // }
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.incomeDetail-page-wrapper {
+ .income-detail-time-picker {
+ position: relative;
+
+ .nut-input {
+ border-bottom: none;
+ padding: 0;
+ width: 100%;
+
+ .input-text {
+ font-size: 20px;
+ font-weight: 500;
+ height: 28px;
+ }
+
+ .nut-input-right-box {
+ display: none;
+ }
+ }
+
+ .income-detail-time-picker-icon {
+ position: absolute;
+ top: 12px;
+ left: 220px;
+ }
+ }
+
+ .common-infinite-scroll-list {
+ background-color: #ffffff;
+ }
+
+ .pro-list {
+ background: transparent;
+ }
+
+ .nut-input {
+ background: transparent;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.vue
new file mode 100644
index 0000000..9141308
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetail/incomeDetail.vue
@@ -0,0 +1,18 @@
+<template>
+ <PageLayout class="incomeDetail-page-wrapper" :title="'鏀跺叆鏄庣粏'">
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'incomeDetail',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/InnerPage.vue
new file mode 100644
index 0000000..698bf6c
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/InnerPage.vue
@@ -0,0 +1,108 @@
+<template>
+ <WithdrawMoneyCard
+ :money="detail?.amount"
+ :title="EnumUserWalletTransactionTypeText[detail.type]"
+ ></WithdrawMoneyCard>
+ <List>
+ <ListItem title="娴佹按鍙�" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ detail?.code }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="浼佷笟鍚嶇О" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ detail?.enterpriseName }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="缁撶畻鏃ユ湡" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">
+ {{ dayjs(detail?.settlementTime).format('YYYY-MM-DD') }}
+ </div>
+ </template>
+ </ListItem>
+ <ListItem title="浠诲姟鍚嶇О" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">
+ {{ detail?.taskName }}
+ </div>
+ </template>
+ </ListItem>
+ <ListItem title="浠诲姟鍗曞彿" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">
+ {{ detail?.taskCode }}
+ </div>
+ </template>
+ </ListItem>
+ <ListItem title="缁撶畻閲戦" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">
+ {{ `${toThousand(detail?.settlementAmount)}鍏僠 }}
+ </div>
+ </template>
+ </ListItem>
+ <ListItem title="瀹炲彂閲戦" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ `${toThousand(detail?.amount)}鍏僠 }}</div>
+ </template>
+ </ListItem>
+ </List>
+</template>
+
+<script setup lang="ts">
+import { List, ListItem, WithdrawMoneyCard } from '@12333/components';
+import { EnumUserWalletTransactionTypeText } from '@12333/constants';
+import Taro from '@tarojs/taro';
+import dayjs from 'dayjs';
+import { toThousand } from '@12333/utils';
+import { useGetPersonalUserTransaction } from '../hooks';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const router = Taro.useRouter();
+const id = router.params?.id;
+
+const { detail } = useGetPersonalUserTransaction({
+ id: id,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.incomeDetailInfo-page-wrapper {
+ .income-detail-info-money {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ background-color: #ffffff;
+ padding: 70px 0;
+
+ .income-detail-info-money-value {
+ display: flex;
+ align-items: center;
+ font-weight: 600;
+ color: boleGetCssVar('text-color', 'primary');
+
+ .income-detail-info-money-value-unit {
+ font-size: 32px;
+ }
+
+ .income-detail-info-money-value-num {
+ font-size: 64px;
+ }
+ }
+
+ .income-detail-info-money-type {
+ margin-top: 10px;
+ font-weight: 400;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'primary');
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.vue
new file mode 100644
index 0000000..a318788
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/incomeDetailInfo/incomeDetailInfo.vue
@@ -0,0 +1,18 @@
+<template>
+ <PageLayout class="incomeDetailInfo-page-wrapper" :title="'鏀跺叆璇︽儏'">
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'incomeDetailInfo',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/InnerPage.vue
new file mode 100644
index 0000000..8ce8c31
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/InnerPage.vue
@@ -0,0 +1,105 @@
+<template>
+ <!-- <div class="mine-wallet-balance">
+ <WithdrawMoneyCard :money="userDetail.balance" title="璐︽埛浣欓(鍏�)"></WithdrawMoneyCard>
+ <nut-button type="primary" class="mine-wallet-balance-btn" @click="goWithdraw">鎻愮幇</nut-button>
+ </div> -->
+ <List>
+ <ListItem title="鏀跺叆鏄庣粏" @click="goIncomeDetail"> </ListItem>
+ <ListItem title="閾惰鍗�" @click="goBankBind">
+ <template #extra>
+ <div class="bind-bank-card">
+ {{ isBindBank ? '宸茬粦瀹�' : '鏈粦瀹氥�佺珛鍗崇粦瀹�' }}
+ </div>
+ </template>
+ </ListItem>
+ <ListItem title="鏀粯瀹�" @click="goBankAlipay">
+ <template #extra>
+ <div class="bind-bank-card">
+ {{ isBindAlipay ? '宸茬粦瀹�' : '鏈粦瀹氥�佺珛鍗崇粦瀹�' }}
+ </div>
+ </template>
+ </ListItem>
+ <ListItem title="寰俊">
+ <template #extra>
+ <div class="bind-bank-card">
+ {{ '宸茬粦瀹�' }}
+ </div>
+ </template>
+ </ListItem>
+ </List>
+</template>
+
+<script setup lang="ts">
+import { List, ListItem, WithdrawMoneyCard } from '@12333/components';
+import { EnumUserBankCardAccess } from '@12333/constants';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { userDetail, isBindBank, isBindAlipay, isBindWechat } = useUser();
+
+function goIncomeDetail() {
+ Taro.navigateTo({
+ url: `${RouterPath.incomeDetail}`,
+ });
+}
+
+const goWithdraw = useAccessReal(
+ () => {
+ Taro.navigateTo({
+ url: `${RouterPath.withdraw}`,
+ });
+ },
+ { message: '瀹屾垚瀹炲悕璁よ瘉鍚庢墠鍙彁鐜�' }
+);
+const goBankBind = useAccessReal(
+ () => {
+ Taro.navigateTo({
+ url: `${isBindBank.value ? RouterPath.bindBankCard : RouterPath.unboundBankCard}`,
+ });
+ },
+ { message: '瀹屾垚瀹炲悕璁よ瘉鍚庢墠鍙繘琛岄摱琛屽崱缁戝畾' }
+);
+
+const goBankAlipay = useAccessReal(
+ () => {
+ Taro.navigateTo({
+ url: `${isBindAlipay.value ? RouterPath.bindAlipay : RouterPath.unboundAlipay}`,
+ });
+ },
+ { message: '瀹屾垚瀹炲悕璁よ瘉鍚庢墠鍙繘琛屾敮浠樺疂缁戝畾' }
+);
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.mineWallet-page-wrapper {
+ .mine-wallet-balance {
+ text-align: center;
+ padding-bottom: 60px;
+
+ .mine-wallet-balance-item {
+ font-size: 28px;
+ font-weight: 500;
+ margin-bottom: 40px;
+
+ &.money {
+ font-size: 48px;
+ font-weight: 500;
+ }
+ }
+
+ .mine-wallet-balance-btn {
+ width: 60%;
+ }
+ }
+
+ .bind-bank-card {
+ color: boleGetCssVar('text-color', 'regular');
+ font-size: 24px;
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.vue
new file mode 100644
index 0000000..2a730f7
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/mineWallet/mineWallet.vue
@@ -0,0 +1,18 @@
+<template>
+ <PageLayout class="mineWallet-page-wrapper" :title="'鎴戠殑閽卞寘'">
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'mineWallet',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/InnerPage.vue
new file mode 100644
index 0000000..9cc5847
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/InnerPage.vue
@@ -0,0 +1,69 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <nut-form :model-value="form" ref="formRef" :rules="rules">
+ <nut-form-item label="鏀粯瀹濇埛鍚�:" class="bole-form-item" prop="name">
+ <nut-input v-model.trim="form.name" placeholder="璇疯緭鍏ユ敮浠樺疂鎴峰悕" readonly />
+ </nut-form-item>
+ <nut-form-item label="鏀粯瀹濊处鍙�:" class="bole-form-item" prop="code">
+ <nut-input v-model.trim="form.code" placeholder="璇疯緭鍏ユ敮浠樺疂璐﹀彿" />
+ </nut-form-item>
+ </nut-form>
+ </ContentScrollView>
+ <PageFooter>
+ <PageFooterBtn type="primary" @click="handleConfirm">缁戝畾鏀粯瀹�</PageFooterBtn>
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import { Message } from '@12333/utils';
+import * as userServices from '@12333/services/apiV2/user';
+import { EnumUserBankCardAccess } from '@12333/constants';
+import { goBack } from '@/utils';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const { userDetail, updateUserInfo } = useUser();
+const form = reactive({
+ name: userDetail.value?.name ?? '',
+ code: '',
+});
+
+const rules = reactive<FormRules>({
+ code: [{ required: true, message: '璇疯緭鍏ユ敮浠樺疂璐﹀彿' }],
+});
+
+const formRef = ref<any>(null);
+function handleConfirm() {
+ if (!formRef.value) return;
+ formRef.value.validate().then(({ valid, errors }: any) => {
+ if (valid) {
+ confirm();
+ }
+ });
+}
+
+async function confirm() {
+ try {
+ let params: API.SavePersonalUserBankCardCommand = {
+ code: form.code,
+ access: EnumUserBankCardAccess.AliPay,
+ };
+ let res = await userServices.savePersonalUserBankCard(params);
+ if (res) {
+ Message.success('缁戝畾鎴愬姛', {
+ onClosed() {
+ updateUserInfo();
+ goBack();
+ },
+ });
+ }
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.vue
new file mode 100644
index 0000000..c79ecde
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundAlipay/unboundAlipay.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayout class="unboundBankCard-page-wrapper" title="缁戝畾鏀粯瀹�" has-border>
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'unboundAlipay',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/InnerPage.vue
new file mode 100644
index 0000000..591c34f
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/InnerPage.vue
@@ -0,0 +1,130 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <nut-form :model-value="form" ref="formRef" :rules="rules">
+ <nut-form-item label="鎸佸崱浜�:" class="bole-form-item" prop="name">
+ <nut-input v-model.trim="form.name" placeholder="璇疯緭鍏ユ寔鍗′汉" readonly />
+ </nut-form-item>
+ <nut-form-item label="韬唤璇佸彿:" class="bole-form-item" prop="identity">
+ <nut-input v-model.trim="form.identity" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�" readonly />
+ </nut-form-item>
+ <nut-form-item label="閾惰鍗″彿:" class="bole-form-item" prop="code">
+ <nut-input
+ v-model.trim="form.code"
+ placeholder="璇疯緭鍏ラ摱琛屽崱鍙�"
+ :formatter="(val:string)=>val.replace(/\s/g,'')"
+ />
+ </nut-form-item>
+ <nut-form-item label="寮�鎴疯:" class="bole-form-item" prop="bank">
+ <nut-input v-model.trim="form.bank" placeholder="璇疯緭鍏ュ紑鎴疯" />
+ </nut-form-item>
+ <nut-form-item label="鎵嬫満鍙�:" class="bole-form-item" prop="phoneNumber" required>
+ <nut-input
+ v-model.trim="form.phoneNumber"
+ class="nut-input-text bole-input-text"
+ placeholder="璇峰~鍐欓摱琛岄鐣欐墜鏈哄彿"
+ type="text"
+ >
+ <template #right>
+ <ProFormCaptcha
+ :onGetCaptcha="() => onGetCaptcha(form.phoneNumber)"
+ phonePropName="phoneNumber"
+ :validateField="formRef?.validate"
+ ></ProFormCaptcha>
+ </template>
+ </nut-input>
+ </nut-form-item>
+ <nut-form-item label="鐭俊楠岃瘉鐮�:" class="bole-form-item" prop="verifyCode" required>
+ <nut-input
+ v-model.trim="form.verifyCode"
+ class="nut-input-text bole-input-text"
+ placeholder="璇疯緭鍏ラ獙璇佺爜"
+ type="number"
+ />
+ </nut-form-item>
+ </nut-form>
+ </ContentScrollView>
+ <PageFooter>
+ <PageFooterBtn type="primary" @click="handleConfirm">缁戝畾閾惰鍗�</PageFooterBtn>
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import { ProFormCaptcha } from 'senin-mini/components';
+import { FormValidator, Message } from '@12333/utils';
+import * as userServices from '@12333/services/apiV2/user';
+import { EnumUserBankCardAccess } from '@12333/constants';
+import { goBack } from '@/utils';
+
+defineOptions({
+ name: 'InnerPage',
+});
+const { userDetail, updateUserInfo } = useUser();
+
+const form = reactive({
+ name: userDetail.value?.name ?? '',
+ identity: userDetail.value?.identity ?? '',
+ phoneNumber: '',
+ code: '',
+ bank: '',
+ bankBranch: '',
+ verifyCode: '',
+});
+
+const rules = reactive<FormRules>({
+ code: [
+ { required: true, message: '璇疯緭鍏ラ摱琛屽崱鍙�' },
+ { message: '璇疯緭鍏ユ纭殑閾惰鍗″彿', validator: FormValidator.validatorBankCard },
+ ],
+ bank: [{ required: true, message: '璇疯緭鍏ュ紑鎴疯' }],
+ phoneNumber: [
+ { required: true, message: '璇峰~鍐欐墜鏈哄彿鐮�' },
+ { message: '璇疯緭鍏ユ纭殑鎵嬫満鍙风爜', validator: FormValidator.validatorPhoneNumber },
+ ],
+ verifyCode: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜' }],
+});
+
+async function onGetCaptcha(phoneNumber: string) {
+ await userServices.sendSavePersonalUserBankCardVerifyCode(
+ {
+ phoneNumber: form.phoneNumber,
+ },
+ { showLoading: false }
+ );
+}
+
+const formRef = ref<any>(null);
+function handleConfirm() {
+ if (!formRef.value) return;
+ formRef.value.validate().then(({ valid, errors }: any) => {
+ if (valid) {
+ confirm();
+ }
+ });
+}
+
+async function confirm() {
+ try {
+ let params: API.SavePersonalUserBankCardCommand = {
+ code: form.code,
+ bank: form.bank,
+ phoneNumber: form.phoneNumber,
+ verifyCode: form.verifyCode,
+ access: EnumUserBankCardAccess.Bank,
+ };
+ let res = await userServices.savePersonalUserBankCard(params);
+ if (res) {
+ Message.success('缁戝畾鎴愬姛', {
+ onClosed() {
+ updateUserInfo();
+ goBack();
+ },
+ });
+ }
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.vue
new file mode 100644
index 0000000..0108c1a
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/unboundBankCard/unboundBankCard.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayout class="unboundBankCard-page-wrapper" title="缁戝畾閾惰鍗�" has-border>
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'unboundBankCard',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/InnerPage.vue
new file mode 100644
index 0000000..9d5c397
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/InnerPage.vue
@@ -0,0 +1,124 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <nut-form :model-value="form" ref="formRef" :rules="rules">
+ <nut-form-item label="鎻愮幇閲戦:" class="bole-form-item" prop="name">
+ <nut-input v-model.trim="form.name" placeholder="璇疯緭鍏ユ彁鐜伴噾棰�" />
+ </nut-form-item>
+ <div class="withdraw-divider">
+ <div class="withdraw-divider-text">{{ `褰撳墠璐︽埛浣欓${'188.88'}鍏冿紝` }}</div>
+ <div class="withdraw-divider-btn">鍏ㄩ儴鎻愮幇</div>
+ </div>
+ <nut-form-item label-width="0" class="bole-form-item">
+ <nut-radio-group class="withdraw-form-wrapper" v-model="form.alipay">
+ <div class="withdraw-form-item">
+ <nut-radio label="alipay"> {{ '鎻愮幇鍒版敮浠樺疂' }} </nut-radio>
+ <img :src="IconWalletAlipay" class="withdraw-icon" />
+ </div>
+ <div class="withdraw-form-item">
+ <nut-radio label="wechat"> {{ '鎻愮幇鍒板井淇�' }} </nut-radio>
+ <img :src="IconWalletWechat" class="withdraw-icon" />
+ </div>
+ <div class="withdraw-form-item">
+ <nut-radio label="bank"> {{ '鎻愮幇鍒伴摱琛屽崱' }} </nut-radio>
+ <img :src="IconWalletBank" class="withdraw-icon" />
+ </div>
+ </nut-radio-group>
+ </nut-form-item>
+ <template v-if="form.alipay === 'alipay'">
+ <nut-form-item label="鏀粯瀹濇埛鍚�:" class="bole-form-item" prop="name">
+ <nut-input readonly v-model.trim="form.name" placeholder="璇疯緭鍏ユ敮浠樺疂鎴峰悕" />
+ </nut-form-item>
+ <!-- <nut-form-item label="韬唤璇佸彿:" class="bole-form-item" prop="name">
+ <nut-input readonly v-model.trim="form.name" placeholder="璇疯緭鍏ヨ韩浠借瘉鍙�" />
+ </nut-form-item> -->
+ <nut-form-item label="鏀粯瀹濊处鍙�:" class="bole-form-item" prop="phoneNumber">
+ <nut-input v-model.trim="form.name" placeholder="璇疯緭鍏ユ敮浠樺疂璐﹀彿/鎵嬫満鍙�" />
+ </nut-form-item>
+ </template>
+ </nut-form>
+ </ContentScrollView>
+ <PageFooter>
+ <PageFooterBtn type="plain" @click="goBack">鍙栨秷</PageFooterBtn>
+ <PageFooterBtn type="primary" @click="handleConfirm">纭鎻愮幇</PageFooterBtn>
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
+import IconWalletAlipay from '@/assets/wallet/icon-wallet-alipay.png';
+import IconWalletWechat from '@/assets/wallet/icon-wallet-wechat.png';
+import IconWalletBank from '@/assets/wallet/icon-wallet-bank.png';
+import { goBack } from '@/utils';
+import Taro from '@tarojs/taro';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const form = reactive({
+ name: '',
+ alipay: 'alipay',
+});
+
+const rules = reactive<FormRules>({
+ name: [{ required: true, message: '璇疯緭鍏�' }],
+});
+
+const formRef = ref<any>(null);
+function handleConfirm() {
+ Taro.navigateTo({
+ url: `${RouterPath.withdrawResult}`,
+ });
+ // if (!formRef.value) return;
+ // formRef.value.validate().then(({ valid, errors }: any) => {
+ // if (valid) {
+ // confirm();
+ // }
+ // });
+}
+
+async function confirm() {
+ try {
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.withdraw-page-wrapper {
+ .withdraw-divider {
+ display: flex;
+ align-items: center;
+ font-size: 28px;
+ color: boleGetCssVar('text-color', 'secondary');
+ padding: 20px 40px;
+
+ .withdraw-divider-btn {
+ color: boleGetCssVar('color', 'primary');
+ }
+ }
+
+ .withdraw-form-wrapper {
+ width: 100%;
+
+ .withdraw-form-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding-right: 40px;
+ margin-bottom: 12px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .withdraw-icon {
+ width: 36px;
+ height: 36px;
+ display: inline-block;
+ }
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.vue
new file mode 100644
index 0000000..350834b
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdraw/withdraw.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayout class="withdraw-page-wrapper" title="鎻愮幇" has-border>
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'withdraw',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/InnerPage.vue
new file mode 100644
index 0000000..f682131
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/InnerPage.vue
@@ -0,0 +1,68 @@
+<template>
+ <WithdrawMoneyCard
+ :money="detail?.amount"
+ :title="EnumUserWalletTransactionTypeText[detail.type]"
+ ></WithdrawMoneyCard>
+ <List>
+ <ListItem title="鎻愮幇鍗曞彿" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ detail?.code }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="鎻愮幇閲戦" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ toThousand(detail?.amount) }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="鎻愮幇鏂瑰紡" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">
+ {{ detail.type ? EnumUserWalletTransactionTypeText[detail.type] : '' }}
+ </div>
+ </template>
+ </ListItem>
+ <ListItem title="鏀粯瀹濇埛鍚�" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="鏀粯瀹濊处鍙�" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="鏈嶅姟璐�" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ toThousand(detail?.serviceFee) }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="瀹為檯鍒拌处" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ toThousand(detail?.actualAmount) }}</div>
+ </template>
+ </ListItem>
+ </List>
+</template>
+
+<script setup lang="ts">
+import { List, ListItem, WithdrawMoneyCard } from '@12333/components';
+import { EnumUserWalletTransactionTypeText } from '@12333/constants';
+import Taro from '@tarojs/taro';
+import { useGetPersonalUserTransaction } from '../hooks';
+import { toThousand } from '@12333/utils';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const router = Taro.useRouter();
+const id = router.params?.id;
+
+const { detail } = useGetPersonalUserTransaction({
+ id: id,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.vue
new file mode 100644
index 0000000..2b654da
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawDetailInfo/withdrawDetailInfo.vue
@@ -0,0 +1,18 @@
+<template>
+ <PageLayout class="withdrawDetailInfo-page-wrapper" :title="'鎻愮幇璇︽儏'">
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import { PageLayout } from '@/components';
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'withdrawDetailInfo',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/InnerPage.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/InnerPage.vue
new file mode 100644
index 0000000..81848a0
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/InnerPage.vue
@@ -0,0 +1,125 @@
+<template>
+ <ContentScrollView :paddingH="false">
+ <div class="withdraw-result-step-wrapper">
+ <div class="withdraw-result-step-title">浣欓鎻愮幇</div>
+ <nut-steps
+ class="withdraw-result-step-content"
+ progress-dot
+ direction="vertical"
+ :current="2"
+ >
+ <nut-step title="鍙戣捣鎻愮幇" :content="dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')">
+ </nut-step>
+ <nut-step
+ title="鏈烘瀯澶勭悊涓�"
+ :content="`棰勮${dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')}鍓嶅埌璐"
+ >
+ <template #icon>
+ <img class="withdraw-result-step-icon-wait" :src="IconWalletStepWait" alt="" />
+ </template>
+ </nut-step>
+ <nut-step title="鎻愮幇鍒拌处" :content="dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')">
+ </nut-step>
+ </nut-steps>
+ </div>
+ <List>
+ <ListItem title="鎻愮幇鍗曞彿" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="鎻愮幇閲戦" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="鎻愮幇鏂瑰紡" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <template v-if="walletType === 'alipay'">
+ <ListItem title="鏀粯瀹濇埛鍚�" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="鏀粯瀹濊处鍙�" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ </template>
+ <template v-if="walletType === 'bank'">
+ <ListItem title="閾惰鍗″彿" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="寮�鎴疯" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ </template>
+ <ListItem title="鏈嶅姟璐�" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ <ListItem title="瀹為檯鍒拌处" :show-arrow="false">
+ <template #extra>
+ <div class="income-detail-info-value">{{ '5893485943859843095843' }}</div>
+ </template>
+ </ListItem>
+ </List>
+ </ContentScrollView>
+ <PageFooter>
+ <PageFooterBtn type="primary" @click="handleConfirm">瀹屾垚</PageFooterBtn>
+ </PageFooter>
+</template>
+
+<script setup lang="ts">
+import { List, ListItem } from '@12333/components';
+import dayjs from 'dayjs';
+import IconWalletStepWait from '@/assets/wallet/icon-wallet-step-wait.png';
+
+defineOptions({
+ name: 'InnerPage',
+});
+
+const walletType = ref('alipay');
+
+async function handleConfirm() {
+ try {
+ } catch (error) {}
+}
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.withdrawResult-page-wrapper {
+ .withdraw-result-step-wrapper {
+ padding: 20px 60px;
+
+ .withdraw-result-step-title {
+ font-size: 32px;
+ font-weight: bold;
+ text-align: center;
+ margin-bottom: 40px;
+ }
+
+ .withdraw-result-step-content {
+ .nut-step-main {
+ margin-bottom: 20px;
+ }
+
+ .withdraw-result-step-icon-wait {
+ width: 40px;
+ height: 40px;
+ }
+ }
+ }
+}
+</style>
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.config.ts b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+ disableScroll: true,
+});
diff --git a/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.vue b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.vue
new file mode 100644
index 0000000..f848d95
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/subpackages/wallet/withdrawResult/withdrawResult.vue
@@ -0,0 +1,17 @@
+<template>
+ <PageLayout class="withdrawResult-page-wrapper" title="鎻愮幇" has-border>
+ <InnerPage></InnerPage>
+ </PageLayout>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+ name: 'withdrawResult',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/housekeepingMiniApp/src/utils/common/index.ts b/apps/housekeepingMiniApp/src/utils/common/index.ts
new file mode 100644
index 0000000..8c712ab
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/common/index.ts
@@ -0,0 +1 @@
+export * from './localtion';
diff --git a/apps/housekeepingMiniApp/src/utils/common/localtion.ts b/apps/housekeepingMiniApp/src/utils/common/localtion.ts
new file mode 100644
index 0000000..55cdb3c
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/common/localtion.ts
@@ -0,0 +1,12 @@
+import { LocationUtils } from '@12333/utils';
+import { useUserStoreWithOut } from '@/stores/modules/user';
+
+export async function setLocationCity() {
+ try {
+ let res = await LocationUtils.getLocation();
+ if (res?.result?.ad_info?.city) {
+ const userStore = useUserStoreWithOut();
+ userStore.setLocationCity(res.result.ad_info.city, res.result.ad_info.province);
+ }
+ } catch (error) {}
+}
diff --git a/apps/housekeepingMiniApp/src/utils/index.ts b/apps/housekeepingMiniApp/src/utils/index.ts
new file mode 100644
index 0000000..b030767
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/index.ts
@@ -0,0 +1,3 @@
+export * from './storage';
+export * from './page';
+export * from './common';
diff --git a/apps/housekeepingMiniApp/src/utils/page.ts b/apps/housekeepingMiniApp/src/utils/page.ts
new file mode 100644
index 0000000..067f334
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/page.ts
@@ -0,0 +1,25 @@
+import { TabBarPageRouterList } from '@/constants';
+import Taro from '@tarojs/taro';
+import { useSystemStoreWithOut } from '@/stores/modules/system';
+
+export function goBack(delta = 1) {
+ const pages = Taro.getCurrentPages();
+
+ const systemStore = useSystemStoreWithOut();
+
+ if (pages.length > 1) {
+ Taro.navigateBack({ delta: delta });
+ } else {
+ Taro.switchTab({
+ url: TabBarPageRouterList[systemStore.activeTab],
+ });
+ }
+}
+
+export function goHome() {
+ const systemStore = useSystemStoreWithOut();
+ systemStore.setTabIndex(0);
+ Taro.switchTab({
+ url: '/pages/home/index',
+ });
+}
diff --git a/apps/housekeepingMiniApp/src/utils/request/index.ts b/apps/housekeepingMiniApp/src/utils/request/index.ts
new file mode 100644
index 0000000..2ebbed6
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/request/index.ts
@@ -0,0 +1,314 @@
+import { type IRequestOptions, Request, type RequestConfig } from 'senior-request';
+import { type AxiosRequestConfig, type AxiosError } from 'axios';
+import qs from 'qs';
+import Taro from '@tarojs/taro';
+import { getToken } from '@/utils';
+import { tokenIsExpired, Message, SensitiveManage, httpLoggerRecord } from '@12333/utils';
+import { useUserStoreWithOut } from '@/stores/modules/user';
+
+const RefreshTokenUrl = '/gettokenbyrefreshtoken';
+
+/** 璇锋眰鐧藉悕鍗曪紝鏀剧疆涓�浜涗笉闇�瑕乼oken鐨勬帴鍙o紙閫氳繃璁剧疆璇锋眰鐧藉悕鍗曪紝闃叉token杩囨湡鍚庡啀璇锋眰閫犳垚鐨勬寰幆闂锛� */
+const whiteList = [RefreshTokenUrl];
+const RefreshTokenBlackList = ['wxmpLogin'];
+
+export function startLoading(showNavigationBarLoading: boolean) {
+ if (showNavigationBarLoading) {
+ Taro.showNavigationBarLoading();
+ } else {
+ Taro.showLoading({
+ title: '',
+ mask: true,
+ });
+ }
+}
+
+export function endLoading() {
+ Taro.hideNavigationBarLoading();
+ Taro.hideLoading();
+}
+
+// 閿欒澶勭悊鏂规锛� 閿欒绫诲瀷
+enum ErrorShowType {
+ /**
+ * 鍟ヤ篃涓嶅共
+ */
+ SILENT = 0,
+
+ WARN_MESSAGE = 1,
+ ERROR_MESSAGE = 2,
+ /**
+ * 閫氱煡鎶ラ敊
+ */
+ NOTIFICATION = 3,
+ /**
+ * 閲嶅畾鍚�
+ */
+ REDIRECT = 9,
+}
+// 涓庡悗绔害瀹氱殑鍝嶅簲鏁版嵁鏍煎紡
+interface ResponseStructure {
+ success: boolean;
+ data: any;
+ /**
+ * http鐘舵�佸悧
+ */
+ code?: number;
+ /**
+ * 閿欒鐮�
+ */
+ errorCode?: string;
+ /**
+ * 閿欒淇℃伅
+ */
+ msg?: string;
+ showType?: ErrorShowType;
+ traceId?: string;
+}
+
+interface ErrorResponse {
+ error?: {
+ data: any;
+ code: number;
+ message: string;
+ };
+}
+
+interface ErrorInfo {
+ errorCode?: number;
+ errorMessage?: string;
+ showType?: ErrorShowType;
+ data: any;
+}
+
+const AxiosOptions: AxiosRequestConfig = {
+ baseURL: process.env.BASE_URL,
+ timeout: 10 * 1000,
+ headers: {
+ Accept: 'application/json, text/plain, */*',
+ 'Content-Type': 'application/json',
+ 'X-Requested-With': 'XMLHttpRequest',
+ },
+ // 鏁扮粍鏍煎紡鍙傛暟搴忓垪鍖�
+ paramsSerializer: {
+ //@ts-ignore
+ serialize: (params) => qs.stringify(params, { indices: false }),
+ },
+ withCredentials: true,
+};
+
+const config: RequestConfig<ResponseStructure, IRequestOptions> = {
+ ...AxiosOptions,
+
+ errorConfig: {
+ // 閿欒鎺ユ敹鍙婂鐞�
+ errorHandler: (error, opts) => {
+ console.log('error: ', error);
+
+ const url = opts.url ?? '';
+ httpLoggerRecord.error({
+ message: `[${url}] 璇锋眰閿欒`,
+ httpParams: {
+ url: url,
+ //@ts-ignore
+ traceId: error?.info?.traceId,
+ stackTrace: error.stack,
+ },
+ args: [{ data: opts.data, params: opts.params, headers: opts.headers }],
+ });
+
+ if (opts?.skipErrorHandler) throw error;
+
+ if (opts?.customErrorHandler) {
+ if (opts?.customErrorHandler(error)) {
+ return;
+ }
+ }
+
+ // 鎴戜滑鐨� errorThrower 鎶涘嚭鐨勯敊璇��
+ if (error.name === 'BizError') {
+ const errorInfo: ErrorInfo | undefined = (error as any).info;
+ if (errorInfo) {
+ const { errorMessage, errorCode } = errorInfo;
+ if (Number(errorCode) === 401) {
+ handleLogout();
+ }
+ switch (errorInfo.showType) {
+ case ErrorShowType.SILENT:
+ // do nothing
+ break;
+ case ErrorShowType.WARN_MESSAGE:
+ Message.warning(errorMessage);
+ break;
+ case ErrorShowType.ERROR_MESSAGE:
+ Message.error(errorMessage);
+ break;
+ case ErrorShowType.NOTIFICATION:
+ Message.error(errorMessage);
+ break;
+ case ErrorShowType.REDIRECT:
+ // TODO: redirect
+ break;
+ default:
+ Message.error(errorMessage);
+ }
+ }
+ } else if ((error as AxiosError<ResponseStructure, IRequestOptions>).response) {
+ // Axios 鐨勯敊璇�
+ // 璇锋眰鎴愬姛鍙戝嚭涓旀湇鍔″櫒涔熷搷搴斾簡鐘舵�佺爜锛屼絾鐘舵�佷唬鐮佽秴鍑轰簡 2xx 鐨勮寖鍥�
+ handleAxiosResponseError(error as AxiosError<ResponseStructure, IRequestOptions>);
+ // Message.errorMessage(`Response status:${(error as AxiosError).response.status}`);
+ } else if ((error as AxiosError).request) {
+ // 璇锋眰宸茬粡鎴愬姛鍙戣捣锛屼絾娌℃湁鏀跺埌鍝嶅簲
+ // \`error.request\` 鍦ㄦ祻瑙堝櫒涓槸 XMLHttpRequest 鐨勫疄渚嬶紝
+ // 鑰屽湪node.js涓槸 http.ClientRequest 鐨勫疄渚�
+ Message.error('鏈嶅姟鍣ㄦ棤鍝嶅簲锛岃閲嶈瘯');
+ } else {
+ // 鍙戦�佽姹傛椂鍑轰簡鐐归棶棰�
+ Message.error('鍙戦�佽姹傛椂鍑轰簡鐐归棶棰�');
+ }
+ },
+
+ // 閿欒鎶涘嚭
+ errorThrower: (res) => {
+ const { success, data, errorCode, msg, showType } = res;
+ if (!success) {
+ const error: any = new Error(msg);
+ error.name = 'BizError';
+ error.info = { errorCode, errorMessage: msg, showType, data };
+ throw error; // 鎶涘嚭鑷埗鐨勯敊璇�
+ }
+ },
+ },
+
+ requestInterceptors: [
+ [
+ (config) => {
+ const $config = config;
+
+ httpLoggerRecord.info({
+ message: `[${$config.url}] 璇锋眰寮�濮媊,
+ httpParams: {
+ url: $config.url,
+ },
+ args: [{ data: $config.data, params: $config.params, headers: $config.headers }],
+ });
+
+ const token = getToken();
+
+ const userStore = useUserStoreWithOut();
+
+ const userInfo = userStore.userInfo;
+
+ const { showLoading = true, showNavigationBarLoading, mock } = $config;
+
+ if (mock && process.env.NODE_ENV === 'development') {
+ $config.baseURL = 'http://localhost:9527';
+ }
+
+ /**
+ * 濡傛灉鏄痳efreshToken杩欎釜鏂规硶 灏辩洿鎺ヨ繑鍥� 闃叉鍐呭瓨娉勬紡
+ */
+ if (whiteList.some((url) => $config.url!.toLowerCase().includes(url.toLowerCase()))) {
+ return $config;
+ }
+
+ if (showLoading) {
+ startLoading(showNavigationBarLoading);
+ }
+
+ return new Promise((resolve, reject) => {
+ if (userInfo && token && $config.withCredentials) {
+ $config.headers['Authorization'] = 'Bearer ' + userInfo.accessToken;
+ $config.headers['X-Authorization'] = 'Bearer ' + userInfo.refreshToken;
+ resolve($config);
+ } else {
+ resolve($config);
+ }
+ });
+ },
+ (error: AxiosError) => {
+ endLoading();
+ return Promise.reject(error);
+ },
+ ],
+ ],
+ responseInterceptors: [
+ [
+ (response) => {
+ const $config = response.config as IRequestOptions;
+
+ httpLoggerRecord.info({
+ message: `[${$config.url}] 璇锋眰缁撴潫`,
+ httpParams: {
+ url: $config.url,
+ traceId: response.data?.traceId,
+ },
+ args: [{ data: $config.data, params: $config.params, headers: $config.headers }],
+ });
+
+ const { needNProcess, getResponse = false } = $config;
+
+ const userStore = useUserStoreWithOut();
+
+ if (
+ response.headers['x-access-token'] &&
+ RefreshTokenBlackList.every((url) => !response.config.url?.includes(url))
+ ) {
+ const tokenInfo: API.LoginCommandCallback = {
+ accessToken: response.headers['access-token'],
+ refreshToken: response.headers['x-access-token'],
+ };
+ userStore.setTokenAction(tokenInfo);
+ userStore.setUserInfoAction(tokenInfo);
+ }
+
+ endLoading();
+
+ return getResponse ? response : SensitiveManage.filterSensitiveWord(response.data.data);
+ },
+ (error) => {
+ endLoading();
+ return Promise.reject(error);
+ },
+ ],
+ ],
+};
+
+const ErrorMessageMap = {
+ [400]: '璇锋眰閿欒',
+ [401]: '鏈巿鏉冿紝璇风櫥褰�',
+ [403]: '鎷掔粷璁块棶',
+ [404]: '璇锋眰鍦板潃鍑洪敊',
+ [408]: '璇锋眰瓒呮椂',
+ [500]: '鏈嶅姟鍣ㄥ唴閮ㄩ敊璇�',
+ [501]: '鏈嶅姟鏈疄鐜�',
+ [502]: '缃戝叧閿欒',
+ [503]: '鏈嶅姟涓嶅彲鐢�',
+ [504]: '缃戝叧瓒呮椂',
+ [505]: 'HTTP鐗堟湰涓嶅彈鏀寔',
+};
+
+function handleAxiosResponseError(error: AxiosError<ResponseStructure, IRequestOptions>) {
+ if (error.response.config.url.toLowerCase().includes(RefreshTokenUrl.toLowerCase())) {
+ handleLogout();
+ return;
+ }
+ if (error && error.response) {
+ let message = ErrorMessageMap[error.response?.status] ?? '璇锋眰閿欒';
+ if (error.response.data?.msg) {
+ message = error.response.data?.msg;
+ }
+ if (error.response?.status === 401 || error.response.data.code === 401) {
+ handleLogout();
+ }
+
+ Message.error(message);
+ }
+}
+
+function handleLogout() {
+ useUserStoreWithOut().logout();
+}
+
+export const request = Request.create(config);
diff --git a/apps/housekeepingMiniApp/src/utils/setConfig.ts b/apps/housekeepingMiniApp/src/utils/setConfig.ts
new file mode 100644
index 0000000..2f4e93d
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/setConfig.ts
@@ -0,0 +1,5 @@
+import { setUtilsConfig } from '@12333/utils/config';
+
+setUtilsConfig({
+ appName: '宸ユ槗璧氬皬绋嬪簭',
+});
diff --git a/apps/housekeepingMiniApp/src/utils/storage/auth.ts b/apps/housekeepingMiniApp/src/utils/storage/auth.ts
new file mode 100644
index 0000000..fb3a306
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/storage/auth.ts
@@ -0,0 +1,58 @@
+import { storageLocal } from '@12333/utils';
+import { useUserStoreWithOut } from '@/stores/modules/user';
+
+const StorageKey = {
+ USER_INFO_KEY: 'USER__INFO__',
+ USER_DETAIL_KEY: 'USER_DETAIL_KEY',
+ MatchMakingIdentity_KEY: 'MatchMakingIdentity_KEY',
+ LocationCity_KEY: 'LocationCity_KEY',
+};
+
+export function getToken() {
+ return useUserStoreWithOut().token;
+}
+
+export function getRefreshToken() {
+ return useUserStoreWithOut().refreshToken;
+}
+
+export function getUserInfo() {
+ return storageLocal.getItem<API.LoginCommandCallback>(StorageKey.USER_INFO_KEY);
+}
+
+export function setUserInfo(userInfo: API.LoginCommandCallback) {
+ return storageLocal.setItem(StorageKey.USER_INFO_KEY, userInfo);
+}
+
+export function removeUserInfo() {
+ return storageLocal.removeItem(StorageKey.USER_INFO_KEY);
+}
+
+export function getUserDetail() {
+ return storageLocal.getItem<API.GetPersonalLoginInfoQueryResult>(StorageKey.USER_DETAIL_KEY);
+}
+
+export function setUserDetail(userDetail: API.GetPersonalLoginInfoQueryResult) {
+ return storageLocal.setItem(StorageKey.USER_DETAIL_KEY, userDetail);
+}
+
+export function removeUserDetail() {
+ return storageLocal.removeItem(StorageKey.USER_DETAIL_KEY);
+}
+
+type StorageLocation = {
+ city: string;
+ province: string;
+};
+
+export function getStorageLocationCity() {
+ return storageLocal.getItem<StorageLocation>(StorageKey.LocationCity_KEY);
+}
+
+export function setStorageLocationCity(location: StorageLocation) {
+ return storageLocal.setItem(StorageKey.LocationCity_KEY, location);
+}
+
+export function removeStorageLocationCity() {
+ return storageLocal.removeItem(StorageKey.LocationCity_KEY);
+}
diff --git a/apps/housekeepingMiniApp/src/utils/storage/index.ts b/apps/housekeepingMiniApp/src/utils/storage/index.ts
new file mode 100644
index 0000000..269586e
--- /dev/null
+++ b/apps/housekeepingMiniApp/src/utils/storage/index.ts
@@ -0,0 +1 @@
+export * from './auth';
diff --git a/apps/housekeepingMiniApp/tsconfig.json b/apps/housekeepingMiniApp/tsconfig.json
new file mode 100644
index 0000000..124fefc
--- /dev/null
+++ b/apps/housekeepingMiniApp/tsconfig.json
@@ -0,0 +1,35 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "ignoreDeprecations": "5.0",
+ "paths": {
+ "@12333/*": ["../../packages/*"],
+ "@/*": ["src/*"]
+ },
+ "composite": true,
+ "types": [
+ "node",
+ "@12333/services/api/typings.d.ts",
+ "@12333/services/apiV2/typings.d.ts",
+ "@12333/services/types.d.ts",
+ "@12333/services/globalType.d.ts",
+ "@tarojs/components/vue3"
+ ]
+ },
+ "include": [
+ "./src/**/*",
+ "./types/**/*.d.ts",
+ "./components.d.ts",
+ "./auto-imports.d.ts",
+ "../../types/api.d.ts"
+ ],
+ "exclude": ["node_modules", "dist"],
+ "references": [
+ { "path": "../../packages/constants" },
+ { "path": "../../packages/services" },
+ { "path": "../../packages/hooks" },
+ { "path": "../../packages/utils" },
+ { "path": "../../packages/components" }
+ ]
+}
diff --git a/apps/housekeepingMiniApp/types/global.d.ts b/apps/housekeepingMiniApp/types/global.d.ts
new file mode 100644
index 0000000..e8d25a3
--- /dev/null
+++ b/apps/housekeepingMiniApp/types/global.d.ts
@@ -0,0 +1,83 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/// <reference types="@tarojs/taro" />
+
+declare module '*.png'
+declare module '*.gif'
+declare module '*.jpg'
+declare module '*.jpeg'
+declare module '*.svg'
+declare module '*.css'
+declare module '*.less'
+declare module '*.scss'
+declare module '*.sass'
+declare module '*.styl'
+
+declare module '*.vue' {
+ import { ComponentOptions } from 'vue'
+ const componentOptions: ComponentOptions
+ export default componentOptions
+}
+
+declare module '*.tsx' {
+ import Vue from 'compatible-vue';
+ export default Vue;
+}
+
+declare global {
+ namespace JSX {
+ type Element = VNode;
+ type ElementClass = Vue;
+ interface IntrinsicElements {
+ [elem: string]: any;
+ }
+ }
+
+}
+
+declare namespace NodeJS {
+ interface ProcessEnv {
+ TARO_ENV: 'weapp' | 'swan' | 'alipay' | 'h5' | 'rn' | 'tt' | 'quickapp' | 'qq' | 'jd'
+
+ NODE_ENV: 'development' | 'production';
+ APP_ENV: 'staging'| 'development' | 'production';
+
+ BASE_URL: string;
+ TEST_BASE_URL: string;
+
+ OSS_URL: string;
+ TEST_OSS_URL: string;
+ WEMAP_KEY: string;
+ }
+}
+
+declare module '@tarojs/components' {
+ export * from '@tarojs/components/types/index.vue3'
+}
+
+declare const CLIENT_ID: string
+
+declare type Nullable<T> = T | null
+declare type Recordable<T = unknown> = Record<string, T>
+declare type ReadonlyRecordable<T = any> = {
+ readonly [key: string]: T
+}
+declare type Indexable<T = any> = {
+ [key: string]: T
+}
+declare type DeepPartial<T> = {
+ [P in keyof T]?: DeepPartial<T[P]>
+}
+
+declare interface WeMapModel {
+ latitude?: number;
+ longitude?: number;
+ provinceName?: string;
+ cityName?: string;
+ countyName?: string;
+ provinceCode?: number;
+ cityCode?: number;
+ countyCode?: number;
+ address?: string;
+}
+
+declare const uni = Taro
\ No newline at end of file
diff --git a/apps/housekeepingMiniApp/types/globalType.d.ts b/apps/housekeepingMiniApp/types/globalType.d.ts
new file mode 100644
index 0000000..0eecef8
--- /dev/null
+++ b/apps/housekeepingMiniApp/types/globalType.d.ts
@@ -0,0 +1,8 @@
+import type { AxiosRequestConfig } from 'axios';
+
+declare namespace GlobalType {
+ interface RequestConfig extends AxiosRequestConfig {}
+}
+
+export = GlobalType;
+export as namespace GlobalType;
\ No newline at end of file
diff --git a/apps/housekeepingMiniApp/types/pagination.d.ts b/apps/housekeepingMiniApp/types/pagination.d.ts
new file mode 100644
index 0000000..cebea7b
--- /dev/null
+++ b/apps/housekeepingMiniApp/types/pagination.d.ts
@@ -0,0 +1,43 @@
+/**
+ * Pagination Start
+ */
+
+// declare type PageOutput<T> = {
+// data: T[]
+// pageModel: Pagination
+// objectData: unknown
+// }
+
+// declare type Pagination = {
+// rows: number
+// page: number
+// orderInput?: OrderInput[]
+// totalCount?: number
+// }
+
+// declare type PageInput = {
+// pageModel: Pagination
+// }
+
+// declare enum OrderTypeEnum {
+// Asc = 0,
+// Desc = 1,
+// }
+
+// declare type OrderInput = {
+// property: string
+// order: OrderTypeEnum
+// }
+
+declare type PageState = {
+ hasMore: boolean
+ pageInfo: {
+ rows: number
+ page: number
+ total?: number
+ }
+}
+
+/**
+ * Pagination End
+ */
diff --git a/apps/housekeepingMiniApp/types/shims-vue.d.ts b/apps/housekeepingMiniApp/types/shims-vue.d.ts
new file mode 100644
index 0000000..535aaa8
--- /dev/null
+++ b/apps/housekeepingMiniApp/types/shims-vue.d.ts
@@ -0,0 +1,15 @@
+import { ComponentObjectPropsOptions as VComponentObjectPropsOptions } from 'vue';
+import Taro from '@tarojs/taro'
+
+type Data = {
+ [x: string]: unknown;
+}
+
+declare global {
+ type ComponentObjectPropsOptions<T=Data> = VComponentObjectPropsOptions<T>
+
+ interface Window {
+ uni: Taro
+ }
+}
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e87a666..2a7f933 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -647,6 +647,265 @@
specifier: ^4.7.0
version: 4.7.0
+ apps/housekeepingMiniApp:
+ dependencies:
+ '@12333/components':
+ specifier: workspace:^
+ version: link:../../packages/components
+ '@12333/constants':
+ specifier: workspace:*
+ version: link:../../packages/constants
+ '@12333/hooks':
+ specifier: workspace:^
+ version: link:../../packages/hooks
+ '@12333/services':
+ specifier: workspace:^
+ version: link:../../packages/services
+ '@12333/utils':
+ specifier: workspace:^
+ version: link:../../packages/utils
+ '@babel/runtime':
+ specifier: ^7.7.7
+ version: 7.25.6
+ '@bole-12333/chat-kit':
+ specifier: ^1.0.1
+ version: 1.0.1(@tencentcloud/chat-uikit-engine@2.5.7)(lodash@4.17.21)(vue@3.5.12)
+ '@bole-core/request':
+ specifier: ^0.0.1
+ version: 0.0.1(axios@1.4.0)
+ '@nutui/icons-vue-taro':
+ specifier: ^0.0.9
+ version: 0.0.9
+ '@nutui/nutui-taro':
+ specifier: 4.3.13
+ version: 4.3.13(patch_hash=bed3oxqszgaxivruhi4wkqxbjy)(unplugin-vue-components@0.27.4)(vue@3.5.12)
+ '@tanstack/vue-query':
+ specifier: ^4.35.3
+ version: 4.35.3(@vue/composition-api@1.7.2)(vue@3.5.12)
+ '@tarojs/components':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/helper':
+ specifier: 3.6.20
+ version: 3.6.20
+ '@tarojs/plugin-framework-vue3':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-html':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-http':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-platform-alipay':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-platform-jd':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-platform-qq':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-platform-swan':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-platform-tt':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-platform-weapp':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/router':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/runtime':
+ specifier: 3.6.20
+ version: 3.6.20
+ '@tarojs/shared':
+ specifier: 3.6.20
+ version: 3.6.20
+ '@tarojs/taro':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/taro-h5':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tencentcloud/chat-uikit-engine':
+ specifier: ^2.0.3
+ version: 2.5.7
+ '@tencentcloud/chat-uikit-uniapp':
+ specifier: ^2.0.3
+ version: 2.0.3(@vue/runtime-dom@3.5.12)(vue@3.5.12)(webpack@5.78.0)
+ '@tencentcloud/tui-customer-service-plugin':
+ specifier: ^2.0.3
+ version: 2.2.6(@tencentcloud/tui-core@2.5.1)(@vue/composition-api@1.7.2)(vue@3.5.12)
+ '@vant/weapp':
+ specifier: ^1.11.1
+ version: 1.11.1
+ axios:
+ specifier: ^1.4.0
+ version: 1.4.0
+ crypto-js:
+ specifier: ^4.1.1
+ version: 4.1.1
+ dayjs:
+ specifier: ^1.11.6
+ version: 1.11.13
+ js-base64:
+ specifier: ^3.7.5
+ version: 3.7.5
+ lodash:
+ specifier: ^4.17.21
+ version: 4.17.21
+ pinia:
+ specifier: ^2.1.6
+ version: 2.1.6(@vue/composition-api@1.7.2)(typescript@5.2.2)(vue@3.5.12)
+ qs:
+ specifier: ^6.11.1
+ version: 6.13.0
+ senior-request:
+ specifier: ^1.0.10
+ version: 1.0.10(axios@1.4.0)
+ taro-plugin-pinia:
+ specifier: ^1.0.0
+ version: 1.0.0
+ vconsole:
+ specifier: ^3.15.1
+ version: 3.15.1
+ vue:
+ specifier: 3.5.12
+ version: 3.5.12(typescript@5.2.2)
+ vue-component-type-helpers:
+ specifier: ^2.1.10
+ version: 2.1.10
+ devDependencies:
+ '@babel/core':
+ specifier: ^7.8.0
+ version: 7.25.2
+ '@nutui/auto-import-resolver':
+ specifier: ^1.0.0
+ version: 1.0.0
+ '@tarojs/cli':
+ specifier: 3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/plugin-mini-ci':
+ specifier: ^4.0.7
+ version: 4.0.7(miniprogram-ci@1.9.16)
+ '@tarojs/plugin-mock':
+ specifier: ^0.0.9
+ version: 0.0.9
+ '@tarojs/plugin-vue-devtools':
+ specifier: ^3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/service':
+ specifier: ^3.6.20
+ version: 3.6.20(postcss@8.4.47)(vue@3.5.12)
+ '@tarojs/webpack5-runner':
+ specifier: 3.6.20
+ version: 3.6.20(@babel/core@7.25.2)(@swc/core@1.3.96)(@vue/compiler-sfc@3.5.12)(cache-loader@4.1.0)(postcss@8.4.47)(prettier@2.7.1)(typescript@5.2.2)(vue@3.5.12)(webpack@5.78.0)
+ '@types/crypto-js':
+ specifier: ^4.1.1
+ version: 4.1.1
+ '@types/lodash':
+ specifier: ^4.14.198
+ version: 4.17.7
+ '@types/webpack-env':
+ specifier: ^1.13.6
+ version: 1.13.6
+ '@vue/babel-plugin-jsx':
+ specifier: ^1.0.6
+ version: 1.0.6(@babel/core@7.25.2)
+ '@vue/compiler-sfc':
+ specifier: ^3.5.12
+ version: 3.5.12
+ babel-plugin-import:
+ specifier: ^1.13.8
+ version: 1.13.8
+ babel-plugin-lodash:
+ specifier: ^3.3.4
+ version: 3.3.4
+ babel-plugin-transform-remove-console:
+ specifier: ^6.9.4
+ version: 6.9.4
+ babel-preset-taro:
+ specifier: 3.6.20
+ version: 3.6.20(@babel/core@7.25.2)
+ cache-loader:
+ specifier: ^4.1.0
+ version: 4.1.0(webpack@5.78.0)
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ mockjs:
+ specifier: ^1.1.0
+ version: 1.1.0
+ postcss:
+ specifier: ^8.4.19
+ version: 8.4.47
+ postcss-html:
+ specifier: ^1.5.0
+ version: 1.5.0
+ postcss-loader:
+ specifier: ^7.3.3
+ version: 7.3.3(postcss@8.4.47)(typescript@5.2.2)(webpack@5.78.0)
+ postcss-scss:
+ specifier: ^4.0.6
+ version: 4.0.6(postcss@8.4.47)
+ prettier:
+ specifier: ^2.7.1
+ version: 2.7.1
+ stylelint:
+ specifier: ^14.15.0
+ version: 14.15.0
+ stylelint-config-html:
+ specifier: ^1.1.0
+ version: 1.1.0(postcss-html@1.5.0)(stylelint@14.15.0)
+ stylelint-config-prettier:
+ specifier: ^9.0.4
+ version: 9.0.4(stylelint@14.15.0)
+ stylelint-config-recess-order:
+ specifier: ^3.0.0
+ version: 3.0.0(stylelint@14.15.0)
+ stylelint-config-recommended:
+ specifier: ^9.0.0
+ version: 9.0.0(stylelint@14.15.0)
+ stylelint-config-standard:
+ specifier: ^29.0.0
+ version: 29.0.0(stylelint@14.15.0)
+ stylelint-config-standard-scss:
+ specifier: ^6.1.0
+ version: 6.1.0(postcss@8.4.47)(stylelint@14.15.0)
+ stylelint-order:
+ specifier: ^5.0.0
+ version: 5.0.0(stylelint@14.15.0)
+ stylelint-scss:
+ specifier: ^4.3.0
+ version: 4.3.0(stylelint@14.15.0)
+ taro-plugin-compiler-optimization:
+ specifier: ^1.0.4
+ version: 1.0.4
+ thread-loader:
+ specifier: ^4.0.2
+ version: 4.0.2(webpack@5.78.0)
+ unplugin-auto-import:
+ specifier: ^0.16.6
+ version: 0.16.6
+ unplugin-vue-components:
+ specifier: ^0.27.4
+ version: 0.27.4(vue@3.5.12)
+ vue-eslint-parser:
+ specifier: ^9.3.1
+ version: 9.3.1(eslint@8.41.0)
+ vue-loader:
+ specifier: ^17.0.0
+ version: 17.0.0(webpack@5.78.0)
+ webpack:
+ specifier: ^5.78.0
+ version: 5.78.0(@swc/core@1.3.96)
+ webpack-bundle-analyzer:
+ specifier: ^4.7.0
+ version: 4.7.0
+
apps/underTakeMiniApp:
dependencies:
'@12333/components':
@@ -3687,6 +3946,18 @@
vue: 3.5.12(typescript@5.2.2)
dev: false
+ /@bole-12333/chat-kit@1.0.1(@tencentcloud/chat-uikit-engine@2.5.7)(lodash@4.17.21)(vue@3.5.12):
+ resolution: {integrity: sha512-yeSh4XLagaM+uNZRdcG49mhDJO3UbYEpIYZS4Lk303ROnTwxuZyuh5jkoflnCFwWN3Ib3AolfQy999oOqF012A==}
+ peerDependencies:
+ '@tencentcloud/chat-uikit-engine': '*'
+ lodash: '*'
+ vue: 3.5.12
+ dependencies:
+ '@tencentcloud/chat-uikit-engine': 2.5.7
+ lodash: 4.17.21
+ vue: 3.5.12(typescript@5.2.2)
+ dev: false
+
/@bole-core/request@0.0.1(axios@1.4.0):
resolution: {integrity: sha512-NHUZBAxWehzUfV9vm2MsafsEy+d+p9C8r/PfB8QFbiXe06iQ7gzug/XegAv0tzd/6qQknUIELhOKRNH5f6dpag==}
peerDependencies:
@@ -6402,7 +6673,7 @@
'@tarojs/shared': 3.6.20
'@tarojs/taro': 3.6.20(postcss@8.4.19)(vue@3.5.12)
'@vue/devtools': 6.0.0-beta.15
- cross-spawn: 7.0.3
+ cross-spawn: 7.0.6
detect-port: 1.6.1
transitivePeerDependencies:
- '@swc/helpers'
@@ -7020,8 +7291,8 @@
tuikit-logger: 0.0.4-beta.1
dev: false
- /@tencentcloud/call-uikit-vue2.6@4.0.11(vue@3.5.12):
- resolution: {integrity: sha512-2f7raW37qG762pS8PQ+bobAjDy0dh6dIMCuyXcVIGJMAEpw9JkYdYYN/1J+I/hHqXboELhYTYBvxU4XvD0H7kw==}
+ /@tencentcloud/call-uikit-vue2.6@4.0.12(vue@3.5.12):
+ resolution: {integrity: sha512-GMmNENINnH/EKv5hxYl7m1yfl1ve4TtT2gVC/f6RVe5CXXEjFLnmMoNq7alm3wJTSbb8mEmpqzc8kkcxznWCTw==}
dependencies:
'@tencentcloud/call-engine-js': 3.3.0
'@tencentcloud/chat': 3.5.9
@@ -7031,8 +7302,8 @@
- vue
dev: false
- /@tencentcloud/call-uikit-vue@4.0.11:
- resolution: {integrity: sha512-SeUPs5Ow/Y+spAlhzu7HeQY9Zjg4BWMl64JbLGrFv6M389hLOhL5ZFmHb9eqkUIggIQoY5Rrkn2A23CxMWUT/w==}
+ /@tencentcloud/call-uikit-vue@4.0.12:
+ resolution: {integrity: sha512-cKkYmDVAV2uXp0naelEcXLx0j5RIC0kvZ/4L6g95GXwQX2gsNaMCVEYX4GsFobz+qB3J1WBhuZVAxtAILnv8vw==}
dependencies:
'@tencentcloud/call-engine-js': 3.3.0
'@tencentcloud/chat': 3.5.9
@@ -7042,7 +7313,7 @@
/@tencentcloud/call-uikit-wechat@3.3.9:
resolution: {integrity: sha512-SzEegN2nif7sQakA127AneF0I8Dby905JuE8xfZnm6jOYwb07J/lHN++zoxQ/coRbBpyG4VuuuM/JR87dGPb0w==}
dependencies:
- '@tencentcloud/chat': 3.5.9
+ '@tencentcloud/chat': 3.6.1
'@tencentcloud/tui-core': 2.5.1
tuicall-engine-wx: 2.2.8
dev: false
@@ -7050,7 +7321,7 @@
/@tencentcloud/chat-uikit-engine@2.0.3:
resolution: {integrity: sha512-UMAEsXOuZ+cgp97ebWnZRoOCRRzV/y0ONdvTF7bn4X+dVAYTTFxvrS4vGVC+6HNjGs3rZZc74ZmJCEVELSfkLA==}
dependencies:
- '@tencentcloud/chat': 3.5.9
+ '@tencentcloud/chat': 3.6.1
tim-profanity-filter-plugin: 1.1.0
tim-upload-plugin: 1.4.3
dev: false
@@ -7058,7 +7329,7 @@
/@tencentcloud/chat-uikit-engine@2.5.6:
resolution: {integrity: sha512-hzGkruR3j5S/9hx7HfGBWvHAZ7FZqpkl5LEz0z9sVm3faG/IaBkeTCjPmvN9kGIdDIan8Jn6mhVW57EEx7E8UQ==}
dependencies:
- '@tencentcloud/chat': 3.5.9
+ '@tencentcloud/chat': 3.6.1
tim-profanity-filter-plugin: 1.1.0
tim-upload-plugin: 1.4.3
dev: false
@@ -7066,7 +7337,7 @@
/@tencentcloud/chat-uikit-engine@2.5.7:
resolution: {integrity: sha512-2C2x84k7D2cCvSQQlxo4Erw1EYrYf0BTz7IJuqkA99ac91ZwO8vNZEtQbd7wF1h7adNMXoxESCjaR24iDBTDhg==}
dependencies:
- '@tencentcloud/chat': 3.5.9
+ '@tencentcloud/chat': 3.6.1
tim-profanity-filter-plugin: 1.1.0
tim-upload-plugin: 1.4.3
dev: false
@@ -7074,8 +7345,8 @@
/@tencentcloud/chat-uikit-uniapp@2.0.3(@vue/runtime-dom@3.5.12)(vue@3.5.12)(webpack@5.78.0):
resolution: {integrity: sha512-9zjM6lUN6ZcW+oGRomxOPiMRj1E13H9lMCQiwoLEeo/YS2OozbhNmiHx1C96iwDzL60aXslKtzhRUySmKBOJBg==}
dependencies:
- '@tencentcloud/call-uikit-vue': 4.0.11
- '@tencentcloud/call-uikit-vue2.6': 4.0.11(vue@3.5.12)
+ '@tencentcloud/call-uikit-vue': 4.0.12
+ '@tencentcloud/call-uikit-vue2.6': 4.0.12(vue@3.5.12)
'@tencentcloud/call-uikit-wechat': 3.3.9
'@tencentcloud/chat-uikit-engine': 2.5.7
'@tencentcloud/tui-core': 2.5.1
@@ -7104,10 +7375,14 @@
resolution: {integrity: sha512-DRCF5o1cZez1xjIFC8UmXE3NpWYfYWQ4+yjKtuOXk09N28dJSfdwYw2jyfJ2N0DWPB6icVCCxh2MDP+sp4HLpw==}
dev: false
+ /@tencentcloud/chat@3.6.1:
+ resolution: {integrity: sha512-YKftPfO2Mzo/RhSmUq2806FrB2ZB9AiuVmhHupxXtG6g8RMHTJICQulp6z+3bBzU7qko9BancR8rtvfdpDTpmQ==}
+ dev: false
+
/@tencentcloud/tui-core@2.5.1:
resolution: {integrity: sha512-aXZG0INkV9WvFUHgmVQRibCs10r2u/oVb8qAEjW3maytBiLWOJQiK7dzshK9fnfadJAWQ027cpR8lCKz5r5Tlw==}
dependencies:
- '@tencentcloud/chat': 3.5.9
+ '@tencentcloud/chat': 3.6.1
tim-profanity-filter-plugin: 1.1.0
tim-upload-plugin: 1.4.3
dev: false
@@ -13846,6 +14121,7 @@
/intersection-observer@0.7.0:
resolution: {integrity: sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg==}
+ deprecated: The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019.
/into-stream@3.1.0:
resolution: {integrity: sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==}
@@ -16461,6 +16737,7 @@
/phin@3.7.1:
resolution: {integrity: sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==}
engines: {node: '>= 8'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
dependencies:
centra: 2.7.0
transitivePeerDependencies:
@@ -19530,7 +19807,7 @@
/tuicall-engine-wx@2.2.8:
resolution: {integrity: sha512-TPipPfE4J7axm0Z/GsAB/kVe4PVggUF5DkAqI8NIc3IhzuweSNZTtKv7I7xuu6JSrI2XR+XsU7/T3VibhLt66g==}
dependencies:
- '@tencentcloud/chat': 3.5.9
+ '@tencentcloud/chat': 3.6.1
trtc-wx-sdk: 1.1.14
dev: false
--
Gitblit v1.10.0