From e77c77ef96d34c032a1a6b8e1b3f4d08da465426 Mon Sep 17 00:00:00 2001 From: txb Date: Thu, 21 Apr 2022 15:53:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 16 + .eslintignore | 9 + .eslintrc.js | 8 + .gitattributes | 63 + .gitignore | 41 + .prettierignore | 23 + .prettierrc.js | 5 + .stylelintrc.js | 5 + Jenkinsfile | 139 ++ README.md | 57 + config/config.dev.js | 14 + config/config.js | 74 + config/defaultSettings.js | 16 + config/oneapi.json | 619 ++++++ config/proxy.js | 89 + config/routes.js | 614 ++++++ default.conf | 13 + dockerfile | 4 + jest.config.js | 10 + jsconfig.json | 12 + k8s_kitchenweb.yaml | 55 + mock/listTableList.js | 178 ++ mock/notices.js | 105 + mock/route.js | 7 + mock/user.js | 207 ++ package.json | 120 ++ public/CNAME | 1 + public/favicon.ico | Bin 0 -> 4286 bytes public/icons/icon-128x128.png | Bin 0 -> 1329 bytes public/icons/icon-192x192.png | Bin 0 -> 1856 bytes public/icons/icon-512x512.png | Bin 0 -> 5082 bytes public/logo.png | Bin 0 -> 109743 bytes public/logo.svg | 1 + public/pro_icon.svg | 5 + src/access.js | 50 + src/app.jsx | 782 ++++++++ src/components/Footer/index.jsx | 18 + src/components/HeaderDropdown/index.jsx | 10 + src/components/HeaderDropdown/index.less | 16 + src/components/HeaderSearch/index.jsx | 83 + src/components/HeaderSearch/index.less | 25 + src/components/NoticeIcon/NoticeIcon.jsx | 114 ++ src/components/NoticeIcon/NoticeList.jsx | 97 + src/components/NoticeIcon/NoticeList.less | 103 + src/components/NoticeIcon/index.jsx | 147 ++ src/components/NoticeIcon/index.less | 35 + .../RightContent/AvatarDropdown.jsx | 98 + src/components/RightContent/index.jsx | 63 + src/components/RightContent/index.less | 62 + src/components/index.md | 272 +++ src/e2e/baseLayout.e2e.js | 61 + src/global.jsx | 101 + src/global.less | 57 + src/global_data.js | 7 + src/locales/en-US.js | 24 + src/locales/en-US/component.js | 5 + src/locales/en-US/globalHeader.js | 17 + src/locales/en-US/menu.js | 52 + src/locales/en-US/pages.js | 70 + src/locales/en-US/pwa.js | 6 + src/locales/en-US/settingDrawer.js | 31 + src/locales/en-US/settings.js | 60 + src/locales/zh-CN.js | 24 + src/locales/zh-CN/component.js | 5 + src/locales/zh-CN/globalHeader.js | 17 + src/locales/zh-CN/menu.js | 55 + src/locales/zh-CN/pages.js | 67 + src/locales/zh-CN/pwa.js | 6 + src/locales/zh-CN/settingDrawer.js | 31 + src/locales/zh-CN/settings.js | 55 + src/locales/zh-TW.js | 19 + src/locales/zh-TW/component.js | 5 + src/locales/zh-TW/globalHeader.js | 17 + src/locales/zh-TW/menu.js | 52 + src/locales/zh-TW/pwa.js | 6 + src/locales/zh-TW/settingDrawer.js | 31 + src/locales/zh-TW/settings.js | 55 + src/manifest.json | 22 + src/pages/404.jsx | 18 + src/pages/Admin.jsx | 52 + src/pages/Welcome.jsx | 47 + src/pages/Welcome.less | 8 + .../components/ConfigurationForm.jsx | 279 +++ .../components/CreateForm copy 2.jsx | 368 ++++ .../components/CreateForm copy.jsx | 217 ++ .../activityInfo/components/CreateForm.jsx | 589 ++++++ src/pages/activity/activityInfo/index.jsx | 427 ++++ src/pages/activity/activityInfo/service.js | 98 + src/pages/activity/activityRecord/index.jsx | 135 ++ src/pages/activity/activityRecord/services.js | 60 + .../admin/users/components/CreateForm.jsx | 69 + src/pages/admin/users/components/OrgForm.jsx | 64 + src/pages/admin/users/components/RoleForm.jsx | 85 + src/pages/admin/users/index.jsx | 438 ++++ src/pages/admin/users/index.scss | 0 src/pages/admin/users/service.js | 56 + .../bom/bomreplace/components/CreateForm.jsx | 55 + src/pages/bom/bomreplace/index.jsx | 291 +++ src/pages/bom/bomreplace/services.js | 49 + .../bom/manage/components/AddBomInfo.jsx | 55 + src/pages/bom/manage/components/BomList.jsx | 241 +++ .../bom/manage/components/CreateForm.jsx | 46 + src/pages/bom/manage/index.jsx | 286 +++ src/pages/bom/manage/services.js | 73 + src/pages/bom/push/components/CreateForm.jsx | 61 + src/pages/bom/push/index.jsx | 437 ++++ src/pages/bom/push/services.js | 65 + .../coupon-Batch/components/ShowRecord.jsx | 157 ++ .../components/customerCouponInfo.jsx | 142 ++ .../coupon-Batch/components/sendCoupon.jsx | 319 +++ src/pages/crm/coupon/coupon-Batch/index.jsx | 181 ++ src/pages/crm/coupon/coupon-Batch/service.js | 69 + .../couponInfo/components/CreateForm.jsx | 175 ++ .../couponInfo/components/RecordForm.jsx | 165 ++ .../coupon/couponInfo/components/service.js | 42 + src/pages/crm/coupon/couponInfo/index.jsx | 601 ++++++ src/pages/crm/coupon/couponInfo/service.js | 84 + src/pages/crm/coupon/customerCoupon/index.jsx | 179 ++ .../crm/coupon/customerCoupon/service.js | 20 + .../deviceFood/components/CreateForm.jsx | 64 + src/pages/device/deviceFood/index.jsx | 233 +++ src/pages/device/deviceFood/service.js | 40 + .../deviceInfo/components/CreateForm.jsx | 90 + src/pages/device/deviceInfo/index.jsx | 344 ++++ src/pages/device/deviceInfo/services.js | 43 + .../deviceStock/components/CreateForm.jsx | 81 + src/pages/device/deviceStock/index.jsx | 311 +++ src/pages/device/deviceStock/services.js | 53 + .../deviceType/components/CreateForm.jsx | 40 + src/pages/device/deviceType/index.jsx | 203 ++ src/pages/device/deviceType/services.js | 43 + src/pages/document.ejs | 212 ++ src/pages/erp/basic/product/add.jsx | 29 + .../product/components/CreateForm copy.jsx | 272 +++ .../basic/product/components/CreateForm.jsx | 286 +++ .../erp/basic/product/components/style.less | 81 + src/pages/erp/basic/product/index.jsx | 471 +++++ src/pages/erp/basic/product/service.js | 83 + .../productType/components/CreateForm.jsx | 54 + src/pages/erp/basic/productType/index.jsx | 342 ++++ src/pages/erp/basic/productType/services.js | 60 + .../erp/basic/unit/components/CreateForm.jsx | 53 + src/pages/erp/basic/unit/index.jsx | 316 +++ src/pages/erp/basic/unit/services.js | 51 + src/pages/erp/bill/dialog/productlist.jsx | 151 ++ src/pages/erp/bill/dialog/services.js | 29 + .../components/CreateForm copy 2.jsx | 172 ++ .../components/CreateForm copy.jsx | 231 +++ .../purchaseOrder/components/CreateForm.jsx | 189 ++ src/pages/erp/bill/purchaseOrder/index.jsx | 329 +++ src/pages/erp/bill/purchaseOrder/services.js | 124 ++ .../receivingNote/components/CreateForm.jsx | 312 +++ .../receivingNote/components/CreateForm1.jsx | 295 +++ .../bill/receivingNote/components/style.less | 65 + src/pages/erp/bill/receivingNote/index.jsx | 274 +++ src/pages/erp/bill/receivingNote/services.js | 70 + src/pages/erp/stock/index.jsx | 152 ++ src/pages/erp/stock/services.js | 27 + .../finance/components/finance.css | 3 + .../finance/components/financeDetail copy.jsx | 382 ++++ .../finance/components/financeDetail.jsx | 489 +++++ .../finance/components/secondDetail.jsx | 163 ++ src/pages/financereport/finance/index.jsx | 442 ++++ src/pages/financereport/finance/services.js | 75 + .../foodMenu/components/CreateForm.jsx | 96 + src/pages/foodMenu/foodMenu/index.jsx | 214 ++ src/pages/foodMenu/foodMenu/service.js | 39 + .../foodMenuInfo/components/CreateForm.jsx | 43 + src/pages/foodMenu/foodMenuInfo/index.jsx | 208 ++ src/pages/foodMenu/foodMenuInfo/services.js | 34 + .../storeFoodMenu/components/CreateForm.jsx | 66 + src/pages/foodMenu/storeFoodMenu/index.jsx | 207 ++ src/pages/foodMenu/storeFoodMenu/service.js | 40 + .../components/CreateForm.jsx | 55 + src/pages/goods/goods-bom-replace/index.jsx | 291 +++ src/pages/goods/goods-bom-replace/services.js | 49 + .../components/CreateForm.jsx | 61 + src/pages/goods/goods-boms-manage/index.jsx | 438 ++++ src/pages/goods/goods-boms-manage/services.js | 65 + .../goods-manage/components/CreateForm.jsx | 81 + src/pages/goods/goods-manage/index.jsx | 412 ++++ src/pages/goods/goods-manage/service.js | 63 + src/pages/goods/goods-taste/index.jsx | 157 ++ src/pages/goods/goods-taste/service.js | 17 + .../components/CreateForm.jsx | 69 + src/pages/goods/goods-type-manage/index.jsx | 302 +++ src/pages/goods/goods-type-manage/service.js | 51 + .../goodsInfo/components/GoodsbomFrom.jsx | 59 + src/pages/goods/goodsInfo/index.jsx | 413 ++++ src/pages/goods/goodsInfo/service.js | 40 + src/pages/goods/goodsInfo/style.less | 60 + .../components/CreateForm.jsx | 58 + .../goods/goodsParentTypemanage/index.jsx | 278 +++ .../goods/goodsParentTypemanage/service.js | 37 + .../goods/newgoods/components/AddBom.jsx | 74 + .../goods/newgoods/components/CreateForm.jsx | 81 + src/pages/goods/newgoods/index.jsx | 404 ++++ src/pages/goods/newgoods/service.js | 89 + .../goods/unit/components/CreateForm.jsx | 53 + src/pages/goods/unit/index.jsx | 311 +++ src/pages/goods/unit/services.js | 33 + .../components/CommonRuleForm.jsx | 93 + .../components/CreateTypeForm.jsx | 300 +++ .../integral/integralConfigure/index.jsx | 1256 ++++++++++++ .../integral/integralConfigure/service.js | 208 ++ src/pages/member/memberAnalysis/index.jsx | 479 +++++ src/pages/member/memberAnalysis/service.js | 53 + .../memberInfo/components/CreateForm.jsx | 137 ++ .../memberInfo/components/IntegralRecord.jsx | 81 + src/pages/member/memberInfo/index.jsx | 511 +++++ src/pages/member/memberInfo/service.js | 69 + .../membertag/components/CreateForm.jsx | 71 + .../components/CreateMemberInfoForm.jsx | 49 + .../membertag/components/memberInfoList.jsx | 191 ++ src/pages/member/membertag/index.jsx | 347 ++++ src/pages/member/membertag/services.js | 60 + src/pages/order/exOrder/index.jsx | 139 ++ src/pages/order/exOrder/service.js | 17 + .../order-flow-manage/OrderflowDetail.jsx | 229 +++ src/pages/order/order-flow-manage/index.jsx | 341 ++++ src/pages/order/order-flow-manage/service.js | 99 + src/pages/order/order-manage/index.jsx | 199 ++ src/pages/order/order-manage/service.js | 48 + src/pages/order/order-storeBatch/index.jsx | 171 ++ src/pages/order/order-storeBatch/service.js | 60 + .../order/order-summary-manage/index.jsx | 392 ++++ .../order/order-summary-manage/service.js | 62 + src/pages/order/orderDetail/index.jsx | 441 ++++ src/pages/order/orderDetail/service.js | 62 + .../order/ordersalescountbyday/index.jsx | 451 +++++ .../order/ordersalescountbyday/service.js | 62 + src/pages/order/ordersalescountbyday/test.jsx | 70 + .../order/ordersalescountbyday/test1.jsx | 36 + .../refundment/OrderAfterSales/Detail.jsx | 44 + .../OrderAfterSales/components/CreateForm.jsx | 46 + .../refundment/OrderAfterSales/index.jsx | 226 +++ .../refundment/OrderAfterSales/service.js | 64 + .../refund/components/CreateForm.jsx | 51 + src/pages/refundment/refund/index.jsx | 264 +++ src/pages/refundment/refund/service.js | 23 + .../FranchiseePlan/components/CreateForm.jsx | 202 ++ src/pages/split/FranchiseePlan/index.jsx | 370 ++++ src/pages/split/FranchiseePlan/services.js | 53 + .../split/account/components/CreateForm.jsx | 198 ++ src/pages/split/account/index.jsx | 420 ++++ src/pages/split/account/services.js | 70 + .../split/plan/components/CreateForm.jsx | 65 + src/pages/split/plan/index.jsx | 349 ++++ src/pages/split/plan/services.js | 51 + src/pages/split/splitOrders/index.jsx | 84 + src/pages/split/splitOrders/services.js | 12 + .../stockInventory/components/CreateForm.jsx | 75 + .../stockManager/stockInventory/index.jsx | 383 ++++ .../stockManager/stockInventory/service.js | 67 + .../stockItem/components/CreateForm.jsx | 109 + src/pages/stockManager/stockItem/index.jsx | 370 ++++ src/pages/stockManager/stockItem/services.js | 77 + src/pages/stockManager/stockReports/index.jsx | 229 +++ .../stockManager/stockReports/service.js | 38 + .../store/printer/Printer/index copy.jsx | 374 ++++ src/pages/store/printer/Printer/index.jsx | 341 ++++ src/pages/store/printer/Printer/service.js | 64 + .../store/printer/printerTemplate/index.jsx | 148 ++ .../store/printer/printerTemplate/service.js | 33 + .../components/CreateForm.jsx | 70 + src/pages/store/storeAddGoodsInfo/index.jsx | 206 ++ src/pages/store/storeAddGoodsInfo/services.js | 40 + .../components/CreateForm.jsx | 284 +++ src/pages/store/storeAdvertisement/index.jsx | 380 ++++ src/pages/store/storeAdvertisement/service.js | 73 + .../components/CreateForm.jsx | 82 + src/pages/store/storeBatchingStock/index.jsx | 330 +++ .../store/storeBatchingStock/services.js | 82 + .../components/CreateForm.jsx | 55 + src/pages/store/storeDesktopNumber/index.jsx | 182 ++ .../store/storeDesktopNumber/services.js | 25 + .../storeGoods/components/CreateForm.jsx | 76 + src/pages/store/storeGoods/index.jsx | 250 +++ src/pages/store/storeGoods/services.js | 63 + .../storeGoodsInfo/components/CreateForm.jsx | 76 + .../store/storeGoodsInfo/components/Logs.jsx | 167 ++ src/pages/store/storeGoodsInfo/index.jsx | 314 +++ src/pages/store/storeGoodsInfo/services.js | 81 + .../store/storeInfo/components/CreateForm.jsx | 110 + src/pages/store/storeInfo/index.jsx | 462 +++++ src/pages/store/storeInfo/services.js | 57 + .../storeLevel/components/CreateForm.jsx | 39 + src/pages/store/storeLevel/index.jsx | 227 +++ src/pages/store/storeLevel/services.js | 42 + .../store/storeType/components/CreateForm.jsx | 49 + src/pages/store/storeType/index.jsx | 258 +++ src/pages/store/storeType/services.js | 42 + .../sys/company/components/CreateForm.jsx | 76 + src/pages/sys/company/components/MenuForm.jsx | 50 + src/pages/sys/company/index.jsx | 416 ++++ src/pages/sys/company/service.js | 66 + .../dictdata/components/CreateForm.jsx | 76 + src/pages/sys/dictionary/dictdata/index.jsx | 337 ++++ src/pages/sys/dictionary/dictdata/service.js | 43 + .../dicttype/components/CreateForm.jsx | 69 + src/pages/sys/dictionary/dicttype/index.jsx | 313 +++ src/pages/sys/dictionary/dicttype/service.js | 32 + src/pages/sys/log/index copy.jsx | 138 ++ src/pages/sys/log/index.jsx | 167 ++ src/pages/sys/log/service.js | 8 + src/pages/sys/menus/components/CreateForm.jsx | 135 ++ src/pages/sys/menus/index.jsx | 288 +++ src/pages/sys/menus/service.js | 46 + src/pages/sys/org/components/CreateForm.jsx | 83 + src/pages/sys/org/index.jsx | 361 ++++ src/pages/sys/org/service.js | 78 + src/pages/sys/roles/components/CreateForm.jsx | 64 + src/pages/sys/roles/components/MenuForm.jsx | 50 + src/pages/sys/roles/components/OrgForm.jsx | 73 + src/pages/sys/roles/components/UpdateForm.jsx | 68 + src/pages/sys/roles/components/service.js | 19 + src/pages/sys/roles/index.jsx | 364 ++++ src/pages/sys/roles/service.js | 65 + src/pages/sys/storemanage/index.jsx | 231 +++ src/pages/sys/storemanage/service.js | 43 + src/pages/sys/storemanage/style.less | 60 + .../sys/sysSettings/components/BaseView.less | 65 + .../sysSettings/components/EnterpriseLog.jsx | 125 ++ src/pages/sys/sysSettings/components/base.jsx | 238 +++ .../sys/sysSettings/components/service.js | 22 + .../sys/sysSettings/geographic/city.json | 1784 +++++++++++++++++ .../sys/sysSettings/geographic/province.json | 138 ++ src/pages/sys/sysSettings/index.jsx | 101 + src/pages/sys/sysSettings/style.less | 93 + src/pages/sys/user/components/AlterForm.jsx | 52 + src/pages/sys/user/components/CreateForm.jsx | 67 + src/pages/sys/user/components/OrgForm.jsx | 60 + src/pages/sys/user/components/PwdForm.jsx | 48 + .../sys/user/components/RoleAlterForm.jsx | 66 + src/pages/sys/user/components/RoleAuth.jsx | 51 + src/pages/sys/user/components/service.js | 9 + src/pages/sys/user/index.jsx | 431 ++++ src/pages/sys/user/service.js | 94 + src/pages/test/index.jsx | 105 + src/pages/test/style.less | 60 + src/pages/test/update/index copy 2.jsx | 95 + src/pages/test/update/index copy.jsx | 111 + src/pages/test/update/index.jsx | 93 + src/pages/test/update/services.js | 9 + src/pages/user/login/index.jsx | 317 +++ src/pages/user/login/index.less | 151 ++ src/service-worker.js | 66 + src/services/api.js | 42 + src/services/apibase.js | 33 + src/services/swagger/index.js | 13 + src/services/swagger/pet.js | 110 + src/services/swagger/store.js | 41 + src/services/swagger/user.js | 79 + tests/PuppeteerEnvironment.js | 41 + tests/beforeTest.js | 39 + tests/getBrowser.js | 45 + tests/run-tests.js | 50 + tests/setupTests.js | 10 + 358 files changed, 49702 insertions(+) create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc.js create mode 100644 .stylelintrc.js create mode 100644 Jenkinsfile create mode 100644 README.md create mode 100644 config/config.dev.js create mode 100644 config/config.js create mode 100644 config/defaultSettings.js create mode 100644 config/oneapi.json create mode 100644 config/proxy.js create mode 100644 config/routes.js create mode 100644 default.conf create mode 100644 dockerfile create mode 100644 jest.config.js create mode 100644 jsconfig.json create mode 100644 k8s_kitchenweb.yaml create mode 100644 mock/listTableList.js create mode 100644 mock/notices.js create mode 100644 mock/route.js create mode 100644 mock/user.js create mode 100644 package.json create mode 100644 public/CNAME create mode 100644 public/favicon.ico create mode 100644 public/icons/icon-128x128.png create mode 100644 public/icons/icon-192x192.png create mode 100644 public/icons/icon-512x512.png create mode 100644 public/logo.png create mode 100644 public/logo.svg create mode 100644 public/pro_icon.svg create mode 100644 src/access.js create mode 100644 src/app.jsx create mode 100644 src/components/Footer/index.jsx create mode 100644 src/components/HeaderDropdown/index.jsx create mode 100644 src/components/HeaderDropdown/index.less create mode 100644 src/components/HeaderSearch/index.jsx create mode 100644 src/components/HeaderSearch/index.less create mode 100644 src/components/NoticeIcon/NoticeIcon.jsx create mode 100644 src/components/NoticeIcon/NoticeList.jsx create mode 100644 src/components/NoticeIcon/NoticeList.less create mode 100644 src/components/NoticeIcon/index.jsx create mode 100644 src/components/NoticeIcon/index.less create mode 100644 src/components/RightContent/AvatarDropdown.jsx create mode 100644 src/components/RightContent/index.jsx create mode 100644 src/components/RightContent/index.less create mode 100644 src/components/index.md create mode 100644 src/e2e/baseLayout.e2e.js create mode 100644 src/global.jsx create mode 100644 src/global.less create mode 100644 src/global_data.js create mode 100644 src/locales/en-US.js create mode 100644 src/locales/en-US/component.js create mode 100644 src/locales/en-US/globalHeader.js create mode 100644 src/locales/en-US/menu.js create mode 100644 src/locales/en-US/pages.js create mode 100644 src/locales/en-US/pwa.js create mode 100644 src/locales/en-US/settingDrawer.js create mode 100644 src/locales/en-US/settings.js create mode 100644 src/locales/zh-CN.js create mode 100644 src/locales/zh-CN/component.js create mode 100644 src/locales/zh-CN/globalHeader.js create mode 100644 src/locales/zh-CN/menu.js create mode 100644 src/locales/zh-CN/pages.js create mode 100644 src/locales/zh-CN/pwa.js create mode 100644 src/locales/zh-CN/settingDrawer.js create mode 100644 src/locales/zh-CN/settings.js create mode 100644 src/locales/zh-TW.js create mode 100644 src/locales/zh-TW/component.js create mode 100644 src/locales/zh-TW/globalHeader.js create mode 100644 src/locales/zh-TW/menu.js create mode 100644 src/locales/zh-TW/pwa.js create mode 100644 src/locales/zh-TW/settingDrawer.js create mode 100644 src/locales/zh-TW/settings.js create mode 100644 src/manifest.json create mode 100644 src/pages/404.jsx create mode 100644 src/pages/Admin.jsx create mode 100644 src/pages/Welcome.jsx create mode 100644 src/pages/Welcome.less create mode 100644 src/pages/activity/activityInfo/components/ConfigurationForm.jsx create mode 100644 src/pages/activity/activityInfo/components/CreateForm copy 2.jsx create mode 100644 src/pages/activity/activityInfo/components/CreateForm copy.jsx create mode 100644 src/pages/activity/activityInfo/components/CreateForm.jsx create mode 100644 src/pages/activity/activityInfo/index.jsx create mode 100644 src/pages/activity/activityInfo/service.js create mode 100644 src/pages/activity/activityRecord/index.jsx create mode 100644 src/pages/activity/activityRecord/services.js create mode 100644 src/pages/admin/users/components/CreateForm.jsx create mode 100644 src/pages/admin/users/components/OrgForm.jsx create mode 100644 src/pages/admin/users/components/RoleForm.jsx create mode 100644 src/pages/admin/users/index.jsx create mode 100644 src/pages/admin/users/index.scss create mode 100644 src/pages/admin/users/service.js create mode 100644 src/pages/bom/bomreplace/components/CreateForm.jsx create mode 100644 src/pages/bom/bomreplace/index.jsx create mode 100644 src/pages/bom/bomreplace/services.js create mode 100644 src/pages/bom/manage/components/AddBomInfo.jsx create mode 100644 src/pages/bom/manage/components/BomList.jsx create mode 100644 src/pages/bom/manage/components/CreateForm.jsx create mode 100644 src/pages/bom/manage/index.jsx create mode 100644 src/pages/bom/manage/services.js create mode 100644 src/pages/bom/push/components/CreateForm.jsx create mode 100644 src/pages/bom/push/index.jsx create mode 100644 src/pages/bom/push/services.js create mode 100644 src/pages/crm/coupon/coupon-Batch/components/ShowRecord.jsx create mode 100644 src/pages/crm/coupon/coupon-Batch/components/customerCouponInfo.jsx create mode 100644 src/pages/crm/coupon/coupon-Batch/components/sendCoupon.jsx create mode 100644 src/pages/crm/coupon/coupon-Batch/index.jsx create mode 100644 src/pages/crm/coupon/coupon-Batch/service.js create mode 100644 src/pages/crm/coupon/couponInfo/components/CreateForm.jsx create mode 100644 src/pages/crm/coupon/couponInfo/components/RecordForm.jsx create mode 100644 src/pages/crm/coupon/couponInfo/components/service.js create mode 100644 src/pages/crm/coupon/couponInfo/index.jsx create mode 100644 src/pages/crm/coupon/couponInfo/service.js create mode 100644 src/pages/crm/coupon/customerCoupon/index.jsx create mode 100644 src/pages/crm/coupon/customerCoupon/service.js create mode 100644 src/pages/device/deviceFood/components/CreateForm.jsx create mode 100644 src/pages/device/deviceFood/index.jsx create mode 100644 src/pages/device/deviceFood/service.js create mode 100644 src/pages/device/deviceInfo/components/CreateForm.jsx create mode 100644 src/pages/device/deviceInfo/index.jsx create mode 100644 src/pages/device/deviceInfo/services.js create mode 100644 src/pages/device/deviceStock/components/CreateForm.jsx create mode 100644 src/pages/device/deviceStock/index.jsx create mode 100644 src/pages/device/deviceStock/services.js create mode 100644 src/pages/device/deviceType/components/CreateForm.jsx create mode 100644 src/pages/device/deviceType/index.jsx create mode 100644 src/pages/device/deviceType/services.js create mode 100644 src/pages/document.ejs create mode 100644 src/pages/erp/basic/product/add.jsx create mode 100644 src/pages/erp/basic/product/components/CreateForm copy.jsx create mode 100644 src/pages/erp/basic/product/components/CreateForm.jsx create mode 100644 src/pages/erp/basic/product/components/style.less create mode 100644 src/pages/erp/basic/product/index.jsx create mode 100644 src/pages/erp/basic/product/service.js create mode 100644 src/pages/erp/basic/productType/components/CreateForm.jsx create mode 100644 src/pages/erp/basic/productType/index.jsx create mode 100644 src/pages/erp/basic/productType/services.js create mode 100644 src/pages/erp/basic/unit/components/CreateForm.jsx create mode 100644 src/pages/erp/basic/unit/index.jsx create mode 100644 src/pages/erp/basic/unit/services.js create mode 100644 src/pages/erp/bill/dialog/productlist.jsx create mode 100644 src/pages/erp/bill/dialog/services.js create mode 100644 src/pages/erp/bill/purchaseOrder/components/CreateForm copy 2.jsx create mode 100644 src/pages/erp/bill/purchaseOrder/components/CreateForm copy.jsx create mode 100644 src/pages/erp/bill/purchaseOrder/components/CreateForm.jsx create mode 100644 src/pages/erp/bill/purchaseOrder/index.jsx create mode 100644 src/pages/erp/bill/purchaseOrder/services.js create mode 100644 src/pages/erp/bill/receivingNote/components/CreateForm.jsx create mode 100644 src/pages/erp/bill/receivingNote/components/CreateForm1.jsx create mode 100644 src/pages/erp/bill/receivingNote/components/style.less create mode 100644 src/pages/erp/bill/receivingNote/index.jsx create mode 100644 src/pages/erp/bill/receivingNote/services.js create mode 100644 src/pages/erp/stock/index.jsx create mode 100644 src/pages/erp/stock/services.js create mode 100644 src/pages/financereport/finance/components/finance.css create mode 100644 src/pages/financereport/finance/components/financeDetail copy.jsx create mode 100644 src/pages/financereport/finance/components/financeDetail.jsx create mode 100644 src/pages/financereport/finance/components/secondDetail.jsx create mode 100644 src/pages/financereport/finance/index.jsx create mode 100644 src/pages/financereport/finance/services.js create mode 100644 src/pages/foodMenu/foodMenu/components/CreateForm.jsx create mode 100644 src/pages/foodMenu/foodMenu/index.jsx create mode 100644 src/pages/foodMenu/foodMenu/service.js create mode 100644 src/pages/foodMenu/foodMenuInfo/components/CreateForm.jsx create mode 100644 src/pages/foodMenu/foodMenuInfo/index.jsx create mode 100644 src/pages/foodMenu/foodMenuInfo/services.js create mode 100644 src/pages/foodMenu/storeFoodMenu/components/CreateForm.jsx create mode 100644 src/pages/foodMenu/storeFoodMenu/index.jsx create mode 100644 src/pages/foodMenu/storeFoodMenu/service.js create mode 100644 src/pages/goods/goods-bom-replace/components/CreateForm.jsx create mode 100644 src/pages/goods/goods-bom-replace/index.jsx create mode 100644 src/pages/goods/goods-bom-replace/services.js create mode 100644 src/pages/goods/goods-boms-manage/components/CreateForm.jsx create mode 100644 src/pages/goods/goods-boms-manage/index.jsx create mode 100644 src/pages/goods/goods-boms-manage/services.js create mode 100644 src/pages/goods/goods-manage/components/CreateForm.jsx create mode 100644 src/pages/goods/goods-manage/index.jsx create mode 100644 src/pages/goods/goods-manage/service.js create mode 100644 src/pages/goods/goods-taste/index.jsx create mode 100644 src/pages/goods/goods-taste/service.js create mode 100644 src/pages/goods/goods-type-manage/components/CreateForm.jsx create mode 100644 src/pages/goods/goods-type-manage/index.jsx create mode 100644 src/pages/goods/goods-type-manage/service.js create mode 100644 src/pages/goods/goodsInfo/components/GoodsbomFrom.jsx create mode 100644 src/pages/goods/goodsInfo/index.jsx create mode 100644 src/pages/goods/goodsInfo/service.js create mode 100644 src/pages/goods/goodsInfo/style.less create mode 100644 src/pages/goods/goodsParentTypemanage/components/CreateForm.jsx create mode 100644 src/pages/goods/goodsParentTypemanage/index.jsx create mode 100644 src/pages/goods/goodsParentTypemanage/service.js create mode 100644 src/pages/goods/newgoods/components/AddBom.jsx create mode 100644 src/pages/goods/newgoods/components/CreateForm.jsx create mode 100644 src/pages/goods/newgoods/index.jsx create mode 100644 src/pages/goods/newgoods/service.js create mode 100644 src/pages/goods/unit/components/CreateForm.jsx create mode 100644 src/pages/goods/unit/index.jsx create mode 100644 src/pages/goods/unit/services.js create mode 100644 src/pages/integral/integralConfigure/components/CommonRuleForm.jsx create mode 100644 src/pages/integral/integralConfigure/components/CreateTypeForm.jsx create mode 100644 src/pages/integral/integralConfigure/index.jsx create mode 100644 src/pages/integral/integralConfigure/service.js create mode 100644 src/pages/member/memberAnalysis/index.jsx create mode 100644 src/pages/member/memberAnalysis/service.js create mode 100644 src/pages/member/memberInfo/components/CreateForm.jsx create mode 100644 src/pages/member/memberInfo/components/IntegralRecord.jsx create mode 100644 src/pages/member/memberInfo/index.jsx create mode 100644 src/pages/member/memberInfo/service.js create mode 100644 src/pages/member/membertag/components/CreateForm.jsx create mode 100644 src/pages/member/membertag/components/CreateMemberInfoForm.jsx create mode 100644 src/pages/member/membertag/components/memberInfoList.jsx create mode 100644 src/pages/member/membertag/index.jsx create mode 100644 src/pages/member/membertag/services.js create mode 100644 src/pages/order/exOrder/index.jsx create mode 100644 src/pages/order/exOrder/service.js create mode 100644 src/pages/order/order-flow-manage/OrderflowDetail.jsx create mode 100644 src/pages/order/order-flow-manage/index.jsx create mode 100644 src/pages/order/order-flow-manage/service.js create mode 100644 src/pages/order/order-manage/index.jsx create mode 100644 src/pages/order/order-manage/service.js create mode 100644 src/pages/order/order-storeBatch/index.jsx create mode 100644 src/pages/order/order-storeBatch/service.js create mode 100644 src/pages/order/order-summary-manage/index.jsx create mode 100644 src/pages/order/order-summary-manage/service.js create mode 100644 src/pages/order/orderDetail/index.jsx create mode 100644 src/pages/order/orderDetail/service.js create mode 100644 src/pages/order/ordersalescountbyday/index.jsx create mode 100644 src/pages/order/ordersalescountbyday/service.js create mode 100644 src/pages/order/ordersalescountbyday/test.jsx create mode 100644 src/pages/order/ordersalescountbyday/test1.jsx create mode 100644 src/pages/refundment/OrderAfterSales/Detail.jsx create mode 100644 src/pages/refundment/OrderAfterSales/components/CreateForm.jsx create mode 100644 src/pages/refundment/OrderAfterSales/index.jsx create mode 100644 src/pages/refundment/OrderAfterSales/service.js create mode 100644 src/pages/refundment/refund/components/CreateForm.jsx create mode 100644 src/pages/refundment/refund/index.jsx create mode 100644 src/pages/refundment/refund/service.js create mode 100644 src/pages/split/FranchiseePlan/components/CreateForm.jsx create mode 100644 src/pages/split/FranchiseePlan/index.jsx create mode 100644 src/pages/split/FranchiseePlan/services.js create mode 100644 src/pages/split/account/components/CreateForm.jsx create mode 100644 src/pages/split/account/index.jsx create mode 100644 src/pages/split/account/services.js create mode 100644 src/pages/split/plan/components/CreateForm.jsx create mode 100644 src/pages/split/plan/index.jsx create mode 100644 src/pages/split/plan/services.js create mode 100644 src/pages/split/splitOrders/index.jsx create mode 100644 src/pages/split/splitOrders/services.js create mode 100644 src/pages/stockManager/stockInventory/components/CreateForm.jsx create mode 100644 src/pages/stockManager/stockInventory/index.jsx create mode 100644 src/pages/stockManager/stockInventory/service.js create mode 100644 src/pages/stockManager/stockItem/components/CreateForm.jsx create mode 100644 src/pages/stockManager/stockItem/index.jsx create mode 100644 src/pages/stockManager/stockItem/services.js create mode 100644 src/pages/stockManager/stockReports/index.jsx create mode 100644 src/pages/stockManager/stockReports/service.js create mode 100644 src/pages/store/printer/Printer/index copy.jsx create mode 100644 src/pages/store/printer/Printer/index.jsx create mode 100644 src/pages/store/printer/Printer/service.js create mode 100644 src/pages/store/printer/printerTemplate/index.jsx create mode 100644 src/pages/store/printer/printerTemplate/service.js create mode 100644 src/pages/store/storeAddGoodsInfo/components/CreateForm.jsx create mode 100644 src/pages/store/storeAddGoodsInfo/index.jsx create mode 100644 src/pages/store/storeAddGoodsInfo/services.js create mode 100644 src/pages/store/storeAdvertisement/components/CreateForm.jsx create mode 100644 src/pages/store/storeAdvertisement/index.jsx create mode 100644 src/pages/store/storeAdvertisement/service.js create mode 100644 src/pages/store/storeBatchingStock/components/CreateForm.jsx create mode 100644 src/pages/store/storeBatchingStock/index.jsx create mode 100644 src/pages/store/storeBatchingStock/services.js create mode 100644 src/pages/store/storeDesktopNumber/components/CreateForm.jsx create mode 100644 src/pages/store/storeDesktopNumber/index.jsx create mode 100644 src/pages/store/storeDesktopNumber/services.js create mode 100644 src/pages/store/storeGoods/components/CreateForm.jsx create mode 100644 src/pages/store/storeGoods/index.jsx create mode 100644 src/pages/store/storeGoods/services.js create mode 100644 src/pages/store/storeGoodsInfo/components/CreateForm.jsx create mode 100644 src/pages/store/storeGoodsInfo/components/Logs.jsx create mode 100644 src/pages/store/storeGoodsInfo/index.jsx create mode 100644 src/pages/store/storeGoodsInfo/services.js create mode 100644 src/pages/store/storeInfo/components/CreateForm.jsx create mode 100644 src/pages/store/storeInfo/index.jsx create mode 100644 src/pages/store/storeInfo/services.js create mode 100644 src/pages/store/storeLevel/components/CreateForm.jsx create mode 100644 src/pages/store/storeLevel/index.jsx create mode 100644 src/pages/store/storeLevel/services.js create mode 100644 src/pages/store/storeType/components/CreateForm.jsx create mode 100644 src/pages/store/storeType/index.jsx create mode 100644 src/pages/store/storeType/services.js create mode 100644 src/pages/sys/company/components/CreateForm.jsx create mode 100644 src/pages/sys/company/components/MenuForm.jsx create mode 100644 src/pages/sys/company/index.jsx create mode 100644 src/pages/sys/company/service.js create mode 100644 src/pages/sys/dictionary/dictdata/components/CreateForm.jsx create mode 100644 src/pages/sys/dictionary/dictdata/index.jsx create mode 100644 src/pages/sys/dictionary/dictdata/service.js create mode 100644 src/pages/sys/dictionary/dicttype/components/CreateForm.jsx create mode 100644 src/pages/sys/dictionary/dicttype/index.jsx create mode 100644 src/pages/sys/dictionary/dicttype/service.js create mode 100644 src/pages/sys/log/index copy.jsx create mode 100644 src/pages/sys/log/index.jsx create mode 100644 src/pages/sys/log/service.js create mode 100644 src/pages/sys/menus/components/CreateForm.jsx create mode 100644 src/pages/sys/menus/index.jsx create mode 100644 src/pages/sys/menus/service.js create mode 100644 src/pages/sys/org/components/CreateForm.jsx create mode 100644 src/pages/sys/org/index.jsx create mode 100644 src/pages/sys/org/service.js create mode 100644 src/pages/sys/roles/components/CreateForm.jsx create mode 100644 src/pages/sys/roles/components/MenuForm.jsx create mode 100644 src/pages/sys/roles/components/OrgForm.jsx create mode 100644 src/pages/sys/roles/components/UpdateForm.jsx create mode 100644 src/pages/sys/roles/components/service.js create mode 100644 src/pages/sys/roles/index.jsx create mode 100644 src/pages/sys/roles/service.js create mode 100644 src/pages/sys/storemanage/index.jsx create mode 100644 src/pages/sys/storemanage/service.js create mode 100644 src/pages/sys/storemanage/style.less create mode 100644 src/pages/sys/sysSettings/components/BaseView.less create mode 100644 src/pages/sys/sysSettings/components/EnterpriseLog.jsx create mode 100644 src/pages/sys/sysSettings/components/base.jsx create mode 100644 src/pages/sys/sysSettings/components/service.js create mode 100644 src/pages/sys/sysSettings/geographic/city.json create mode 100644 src/pages/sys/sysSettings/geographic/province.json create mode 100644 src/pages/sys/sysSettings/index.jsx create mode 100644 src/pages/sys/sysSettings/style.less create mode 100644 src/pages/sys/user/components/AlterForm.jsx create mode 100644 src/pages/sys/user/components/CreateForm.jsx create mode 100644 src/pages/sys/user/components/OrgForm.jsx create mode 100644 src/pages/sys/user/components/PwdForm.jsx create mode 100644 src/pages/sys/user/components/RoleAlterForm.jsx create mode 100644 src/pages/sys/user/components/RoleAuth.jsx create mode 100644 src/pages/sys/user/components/service.js create mode 100644 src/pages/sys/user/index.jsx create mode 100644 src/pages/sys/user/service.js create mode 100644 src/pages/test/index.jsx create mode 100644 src/pages/test/style.less create mode 100644 src/pages/test/update/index copy 2.jsx create mode 100644 src/pages/test/update/index copy.jsx create mode 100644 src/pages/test/update/index.jsx create mode 100644 src/pages/test/update/services.js create mode 100644 src/pages/user/login/index.jsx create mode 100644 src/pages/user/login/index.less create mode 100644 src/service-worker.js create mode 100644 src/services/api.js create mode 100644 src/services/apibase.js create mode 100644 src/services/swagger/index.js create mode 100644 src/services/swagger/pet.js create mode 100644 src/services/swagger/store.js create mode 100644 src/services/swagger/user.js create mode 100644 tests/PuppeteerEnvironment.js create mode 100644 tests/beforeTest.js create mode 100644 tests/getBrowser.js create mode 100644 tests/run-tests.js create mode 100644 tests/setupTests.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7e3649a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..dafff25 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +/lambda/ +/scripts +/config +.history +public +dist +.umi +mock +src \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..b882c20 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + extends: [require.resolve('@umijs/fabric/dist/eslint')], + globals: { + ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true, + page: true, + REACT_APP_ENV: true, + }, +}; diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9878537 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +**/node_modules +# roadhog-api-doc ignore +/src/utils/request-temp.js +_roadhog-api-doc + +# production +/dist +/.vscode + +# misc +.DS_Store +npm-debug.log* +yarn-error.log + +/coverage +.idea +yarn.lock +package-lock.json +*bak +.vscode +.vs +.git +# visual studio code +.history +*.log +functions/* +.temp/** + +# umi +.umi +.umi-production + +# screenshot +screenshot +.firebase +.eslintcache + +build diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d17efb4 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,23 @@ +**/*.svg +package.json +.umi +.umi-production +/dist +.dockerignore +.DS_Store +.eslintignore +*.png +*.toml +docker +.editorconfig +Dockerfile* +.gitignore +.prettierignore +LICENSE +.eslintcache +*.lock +yarn-error.log +.history +CNAME +/build +/public \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..7b597d7 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,5 @@ +const fabric = require('@umijs/fabric'); + +module.exports = { + ...fabric.prettier, +}; diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 0000000..c203078 --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,5 @@ +const fabric = require('@umijs/fabric'); + +module.exports = { + ...fabric.stylelint, +}; diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..2544773 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,139 @@ + +def getHost(){ + def remote = [:] + remote.name = 'eip' + remote.host = '10.6.1.50' + remote.user = 'root' + remote.port = 22 + remote.password = '120962839' + remote.allowAnyHosts = true + return remote +} + +pipeline{ + agent any + parameters { + choice( + description: 'EIP环境', + name: 'environment', + choices: ['dev1'] + ) + + choice( + description: '执行操作(发布|回滚)', + name: 'operation', + choices: ['develop', 'rollback'] + ) + + choice( + description: '分支名', + name: 'branchName', + choices: ['master'] + ) + + string( + name: 'tag', + defaultValue: '', + description: '版本tag' + ) + + } + + stages + { + + stage('Prepare') { + steps { + script{ + echo "1.Prepare Stage" + echo "当前环境${params.environment}" + if(params.operation=='develop') + { + checkout scm + script { + build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() + if (env.BRANCH_NAME != 'master') { + build_tag = "${env.BRANCH_NAME}-${build_tag}" + } + } + } + else{ + build_tag="${params.tag}" + } + } + } + } + stage('Test') { + steps { + script{ + echo "2.Test Stage" + } + } + + } + stage('Build') { + steps { + script{ + echo "3.Build Docker Image Stage" + if(params.operation=='develop') + { + nodejs("nodejs") { + + } + sh "npm install --unsafe-perm=true --allow-root" + sh "rm -rf ./dist/*" + sh "npm run build" + sh "docker build -t 10.2.1.24:10242/bpa/kitchenweb:${build_tag} ." + } + } + } + + } + + + + + + stage('Push') { + steps { + script{ + echo "4.Push Docker Image Stage" + withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'harborPassword', usernameVariable: 'harborUser')]) { + sh "docker login -u ${harborUser} -p ${harborPassword} 10.2.1.24:10242" + if(params.operation=='develop') + { + sh "docker push 10.2.1.24:10242/bpa/kitchenweb:${build_tag}" + } + } + } + } + + + + + } + + + stage('Deploy') { + + steps { + script{ + echo "5. Deploy Stage" + // server = getHost() + // sshCommand remote: server, command: """ + // /root/eip/web/shell/linux-eipweb.install.sh eipweb ${build_tag} 80 + // """ + + sh "sed -i 's//${build_tag}/' k8s_kitchenweb.yaml" + sh "sed -i 's//${env.BRANCH_NAME}/' k8s_kitchenweb.yaml" + sh "sed -i 's//${params.environment}/' k8s_kitchenweb.yaml" + sh "kubectl apply -f k8s_kitchenweb.yaml --record" + } + + + + } + } + } + +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..27ea928 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Ant Design Pro + +This project is initialized with [Ant Design Pro](https://pro.ant.design). Follow is the quick guide for how to use. + +## Environment Prepare + +Install `node_modules`: + +```bash +npm install +``` + +or + +```bash +yarn +``` + +## Provided Scripts + +Ant Design Pro provides some useful script to help you quick start and build with web project, code style check and test. + +Scripts provided in `package.json`. It's safe to modify or add additional script: + +### Start project + +```bash +npm start +``` + +### Build project + +```bash +npm run build +``` + +### Check code style + +```bash +npm run lint +``` + +You can also use script to auto fix some lint error: + +```bash +npm run lint:fix +``` + +### Test code + +```bash +npm test +``` + +## More + +You can view full document on our [official website](https://pro.ant.design). And welcome any feedback in our [github](https://github.com/ant-design/ant-design-pro). diff --git a/config/config.dev.js b/config/config.dev.js new file mode 100644 index 0000000..8e33701 --- /dev/null +++ b/config/config.dev.js @@ -0,0 +1,14 @@ +// https://umijs.org/config/ +import { defineConfig } from 'umi'; +export default defineConfig({ + plugins: [ + // https://github.com/zthxxx/react-dev-inspector + 'react-dev-inspector/plugins/umi/react-inspector', + ], + // https://github.com/zthxxx/react-dev-inspector#inspector-loader-props + inspectorConfig: { + exclude: [], + babelPlugins: [], + babelOptions: {}, + }, +}); diff --git a/config/config.js b/config/config.js new file mode 100644 index 0000000..6db2c1f --- /dev/null +++ b/config/config.js @@ -0,0 +1,74 @@ +// https://umijs.org/config/ +import { defineConfig } from 'umi'; +import { join } from 'path'; +import defaultSettings from './defaultSettings'; +import proxy from './proxy'; +import routes from './routes'; +const { REACT_APP_ENV } = process.env; +export default defineConfig({ + hash: true, + antd: {}, + dva: { + hmr: true, + }, + define: { + 'process.env.UMI_ENV': process.env.UMI_ENV || 'dev', + }, + layout: { + // https://umijs.org/zh-CN/plugins/plugin-layout + locale: false, + siderWidth: 208, + ...defaultSettings, + }, + // https://umijs.org/zh-CN/plugins/plugin-locale + locale: { + // default zh-CN + default: 'zh-CN', + antd: true, + // default true, when it is true, will use `navigator.language` overwrite default + baseNavigator: true, + }, + dynamicImport: { + loading: '@ant-design/pro-layout/es/PageLoading', + }, + targets: { + ie: 11, + }, + // umi routes: https://umijs.org/docs/routing + routes, + // Theme for antd: https://ant.design/docs/react/customize-theme-cn + theme: { + 'primary-color': defaultSettings.primaryColor, + }, + // esbuild is father build tools + // https://umijs.org/plugins/plugin-esbuild + esbuild: {}, + title: false, + ignoreMomentLocale: true, + proxy: proxy[REACT_APP_ENV || 'dev'], + manifest: { + basePath: '/', + }, + // Fast Refresh 热更新 + fastRefresh: {}, + openAPI: [ + { + requestLibPath: "import { request } from 'umi'", + // 或者使用在线的版本 + // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json" + schemaPath: join(__dirname, 'oneapi.json'), + mock: false, + }, + { + requestLibPath: "import { request } from 'umi'", + schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json', + projectName: 'swagger', + }, + ], + nodeModulesTransform: { + type: 'none', + }, + mfsu: {}, + webpack5: {}, + exportStatic: {}, +}); diff --git a/config/defaultSettings.js b/config/defaultSettings.js new file mode 100644 index 0000000..bcf6bec --- /dev/null +++ b/config/defaultSettings.js @@ -0,0 +1,16 @@ +const Settings = { + navTheme: 'dark', + // 拂晓蓝 + primaryColor: '#FA541C', //'#1890ff', + layout: 'side', + contentWidth: 'Fluid', + fixedHeader: false, + fixSiderbar: true, + colorWeak: false, + title: '加盟商管理系统', + pwa: false, + logo: '/logo.svg', + iconfontUrl: '', +}; + +export default Settings; diff --git a/config/oneapi.json b/config/oneapi.json new file mode 100644 index 0000000..78efb57 --- /dev/null +++ b/config/oneapi.json @@ -0,0 +1,619 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Ant Design Pro", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:44324/" + }, + { + "url": "https://localhost:44324/" + } + ], + "paths": { + "/kitchen/api/currentUser": { + "get": { + "tags": [ + "api" + ], + "description": "获取当前的用户", + "operationId": "currentUser", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CurrentUser" + } + } + } + }, + "401": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "x-swagger-router-controller": "api" + }, + "/kitchen/api/login/captcha": { + "post": { + "description": "发送验证码", + "operationId": "getFakeCaptcha", + "tags": [ + "login" + ], + "parameters": [ + { + "name": "phone", + "in": "query", + "description": "手机号", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FakeCaptcha" + } + } + } + } + } + } + }, + "/kitchen/api/login/outLogin": { + "post": { + "description": "登录接口", + "operationId": "outLogin", + "tags": [ + "login" + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "x-swagger-router-controller": "api" + }, + "/kitchen/api/login/account": { + "post": { + "tags": [ + "login" + ], + "description": "登录接口", + "operationId": "login", + "requestBody": { + "description": "登录系统", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginParams" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginResult" + } + } + } + }, + "401": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + }, + "x-codegen-request-body-name": "body" + }, + "x-swagger-router-controller": "api" + }, + "/kitchen/api/notices": { + "summary": "getNotices", + "description": "NoticeIconItem", + "get": { + "tags": [ + "api" + ], + "operationId": "getNotices", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeIconList" + } + } + } + } + } + } + }, + "/kitchen/api/rule": { + "get": { + "tags": [ + "rule" + ], + "description": "获取规则列表", + "operationId": "rule", + "parameters": [ + { + "name": "current", + "in": "query", + "description": "当前的页码", + "schema": { + "type": "number" + } + }, + { + "name": "pageSize", + "in": "query", + "description": "页面的容量", + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleList" + } + } + } + }, + "401": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "post": { + "tags": [ + "rule" + ], + "description": "新建规则", + "operationId": "addRule", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleListItem" + } + } + } + }, + "401": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "rule" + ], + "description": "新建规则", + "operationId": "updateRule", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleListItem" + } + } + } + }, + "401": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "rule" + ], + "description": "删除规则", + "operationId": "removeRule", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + }, + "x-swagger-router-controller": "api" + }, + "/swagger": { + "x-swagger-pipe": "swagger_raw" + } + }, + "components": { + "schemas": { + "CurrentUser": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "avatar": { + "type": "string" + }, + "userid": { + "type": "string" + }, + "email": { + "type": "string" + }, + "signature": { + "type": "string" + }, + "title": { + "type": "string" + }, + "group": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "notifyCount": { + "type": "integer", + "format": "int32" + }, + "unreadCount": { + "type": "integer", + "format": "int32" + }, + "country": { + "type": "string" + }, + "access": { + "type": "string" + }, + "geographic": { + "type": "object", + "properties": { + "province": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "key": { + "type": "string" + } + } + }, + "city": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "key": { + "type": "string" + } + } + } + } + }, + "address": { + "type": "string" + }, + "phone": { + "type": "string" + } + } + }, + "LoginResult": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "type": { + "type": "string" + }, + "currentAuthority": { + "type": "string" + } + } + }, + "PageParams": { + "type": "object", + "properties": { + "current": { + "type": "number" + }, + "pageSize": { + "type": "number" + } + } + }, + "RuleListItem": { + "type": "object", + "properties": { + "key": { + "type": "integer", + "format": "int32" + }, + "disabled": { + "type": "boolean" + }, + "href": { + "type": "string" + }, + "avatar": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "string" + }, + "desc": { + "type": "string" + }, + "callNo": { + "type": "integer", + "format": "int32" + }, + "status": { + "type": "integer", + "format": "int32" + }, + "updatedAt": { + "type": "string", + "format": "datetime" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "progress": { + "type": "integer", + "format": "int32" + } + } + }, + "RuleList": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RuleListItem" + } + }, + "total": { + "type": "integer", + "description": "列表的内容总数", + "format": "int32" + }, + "success": { + "type": "boolean" + } + } + }, + "FakeCaptcha": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "status": { + "type": "string" + } + } + }, + "LoginParams": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "autoLogin": { + "type": "boolean" + }, + "type": { + "type": "string" + } + } + }, + "ErrorResponse": { + "required": [ + "errorCode" + ], + "type": "object", + "properties": { + "errorCode": { + "type": "string", + "description": "业务约定的错误码" + }, + "errorMessage": { + "type": "string", + "description": "业务上的错误信息" + }, + "success": { + "type": "boolean", + "description": "业务上的请求是否成功" + } + } + }, + "NoticeIconList": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NoticeIconItem" + } + }, + "total": { + "type": "integer", + "description": "列表的内容总数", + "format": "int32" + }, + "success": { + "type": "boolean" + } + } + }, + "NoticeIconItemType": { + "title": "NoticeIconItemType", + "description": "已读未读列表的枚举", + "type": "string", + "properties": {}, + "enum": [ + "notification", + "message", + "event" + ] + }, + "NoticeIconItem": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "extra": { + "type": "string", + "format": "any" + }, + "key": { + "type": "string" + }, + "read": { + "type": "boolean" + }, + "avatar": { + "type": "string" + }, + "title": { + "type": "string" + }, + "status": { + "type": "string" + }, + "datetime": { + "type": "string", + "format": "date" + }, + "description": { + "type": "string" + }, + "type": { + "extensions": { + "x-is-enum": true + }, + "$ref": "#/components/schemas/NoticeIconItemType" + } + } + } + } + } +} diff --git a/config/proxy.js b/config/proxy.js new file mode 100644 index 0000000..6ed7f93 --- /dev/null +++ b/config/proxy.js @@ -0,0 +1,89 @@ +/** + * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置 + * ------------------------------- + * The agent cannot take effect in the production environment + * so there is no configuration of the production environment + * For details, please see + * https://pro.ant.design/docs/deploy + */ +export default { + dev: { + '/kitchen/api/': { + target: 'http://10.2.1.26:21527', + changeOrigin: true, + secure: false, //关闭证书验证 + pathRewrite: { + '^': '', + }, + }, + // Nginx发布的时候需要配置 + '/cos/':{ + target: 'https://hbl-test-1305371387.cos.ap-chengdu.myqcloud.com', + changeOrigin: true, + secure: false, //关闭证书验证 + pathRewrite: { + '/cos/': '/', + }, + } + }, + test: { + '/api/': { + target: 'http://localhost:7002', + changeOrigin: true, + secure: false, + pathRewrite: { + '^': '', + }, + }, + }, + pre: { + '/api/': { + target: 'http://localhost:7002', + changeOrigin: true, + secure: false, + pathRewrite: { + '^': '', + }, + }, + }, +}; +// /** +// * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置 +// * ------------------------------- +// * The agent cannot take effect in the production environment +// * so there is no configuration of the production environment +// * For details, please see +// * https://pro.ant.design/docs/deploy +// */ +// export default { +// dev: { +// '/api/': { +// target: 'http://114.117.161.250:7002', +// changeOrigin: true, +// secure: false, //关闭证书验证 +// pathRewrite: { +// '^': '', +// }, +// }, +// }, +// test: { +// '/api/': { +// target: 'http://114.117.161.250:7002', +// changeOrigin: true, +// secure: false, +// pathRewrite: { +// '^': '', +// }, +// }, +// }, +// pre: { +// '/api/': { +// target: 'http://114.117.161.250:7002', +// changeOrigin: true, +// secure: false, +// pathRewrite: { +// '^': '', +// }, +// }, +// }, +// }; diff --git a/config/routes.js b/config/routes.js new file mode 100644 index 0000000..9ac961c --- /dev/null +++ b/config/routes.js @@ -0,0 +1,614 @@ +/** + * SYS 系统设置 + * admin 系统用户 + * erp 供应链管理 + * basic 基础信息管理 + * bill 单据管理 + * crm crm会员管理 + * franchisee 加盟商 + * srd 店铺管理 + **/ +export default [ + { + path: '/user', + layout: false, + routes: [ + { + name: '系统登录', + path: '/user/login', + component: './user/login', + access: 'k1', + }, + ], + }, + { + name: '系统管理', + icon: 'SettingOutlined', + path: '/sys', + routes: [ + { + name: '加盟商管理', + icon: 'smile', + path: '/sys/company', + component: './sys/company', + access: 'k2', + }, + { + name: '组织管理', + icon: 'smile', + path: '/sys/Org', + component: './sys/Org', + access: 'k2', + }, + { + name: '操作日志', + icon: 'smile', + path: '/sys/Log', + component: './sys/Log', + access: 'k3', + }, + { + name: '系统用户', + icon: 'smile', + path: '/sys/user', + component: './sys/user', + access: 'k4', + }, + { + name: '角色权限', + icon: 'smile', + path: '/sys/Roles', + component: './sys/Roles', + access: 'k5', + }, + { + name: '系统菜单', + icon: 'smile', + path: '/sys/Menus', + component: './sys/Menus', + access: 'k6', + }, + { + name: '字典信息', + icon: 'smile', + path: '/sys/dictionary/dictdata', + component: './sys/dictionary/dictdata', + access: 'k6', + }, + { + name: '字典类型', + icon: 'smile', + path: '/sys/dictionary/dicttype', + component: './sys/dictionary/dicttype', + access: 'k6', + }, + { + name: '系统配置', + icon: 'smile', + path: '/sys/sysSettings', + component: './sys/sysSettings', + access: 'k6', + }, + { + name: '设备管理', + icon: 'smile', + path: '/sys/storemanage', + component: './sys/storemanage', + access: 'k6', + }, + ], + }, + { + name: '物料管理', + icon: 'DropboxSquareFilled', + path: '/erp', + routes: [ + { + name: '物料信息', + icon: 'smile', + path: '/erp/basic/product', + component: './erp/basic/product', + access: 'k7', + }, + { + name: '物料单位', + icon: 'smile', + path: '/erp/basic/unit', + component: './erp/basic/unit', + access: 'k8', + }, + { + name: '物料分类', + icon: 'smile', + path: '/erp/basic/productType', + component: './erp/basic/productType', + access: 'k9', + }, + { + name: '验收入库', + icon: 'smile', + path: '/erp/Bill/ReceivingNote', + component: './erp/Bill/ReceivingNote', + access: 'k15', + }, + { + name: '采购管理', + icon: 'smile', + path: '/erp/Bill/purchaseOrder', + component: './erp/Bill/purchaseOrder', + }, + { + name: '物料库存', + icon: 'smile', + path: '/erp/stock', + component: './erp/stock', + access: 'k16', + }, + ], + }, + { + name: '物料管理', + icon: 'DropboxSquareFilled', + path: '/bom', + routes: [ + { + name: '配方管理', + icon: 'smile', + path: '/bom/manage', + component: './bom/manage', + access: 'k7', + }, + { + name: '配方下发', + icon: 'smile', + path: '/bom/push', + component: './bom/push', + access: 'k8', + }, + ], + }, + { + name: '商品管理', + icon: 'ProjectFilled', + path: '/goods', + routes: [ + { + name: '商品管理', + icon: 'smile', + path: '/goods/goods-manage', + component: './goods/goods-manage', + access: 'k10', + }, + { + name: '商品管理新', + icon: 'smile', + path: '/goods/newgoods', + component: './goods/newgoods', + access: 'k10', + }, + { + name: '商品口味', + icon: 'smile', + path: '/goods/goods-taste', + component: './goods/goods-taste', + access: 'k11', + }, + { + name: '商品小类', + icon: 'smile', + path: '/goods/goods-type-manage', + component: './goods/goods-type-manage', + access: 'k11', + }, + { + name: '商品大类', + icon: 'smile', + path: '/goods/goodsParentTypemanage', + component: './goods/goodsParentTypemanage', + access: 'k11', + }, + { + name: '商品单位', + icon: 'smile', + path: '/goods/unit', + component: './goods/unit', + access: 'k11', + }, + { + name: '商品详情', + icon: 'smile', + path: '/goods/goodsInfo', + component: './goods/goodsInfo', + access: 'k11', + }, + + + + ], + }, + + { + name: '店铺管理', + icon: 'BankFilled', + path: '/store', + routes: [ + { + name: '店铺类型', + icon: 'smile', + path: '/store/storeType', + component: './store/storeType', + access: 'k12', + }, + { + name: '店铺小票打印机', + icon: 'smile', + path: '/store/printer/Printer', + component: './store/printer/Printer', + access: 'k12', + }, + { + name: '打印机模板', + icon: 'smile', + path: '/store/printer/printerTemplate', + component: './store/printer/printerTemplate', + access: 'k12', + }, + + { + name: '店铺桌面码', + icon: 'smile', + path: '/store/storeDesktopNumber', + component: './store/storeDesktopNumber', + access: 'k12', + }, + { + name: '店铺等级', + icon: 'smile', + path: '/store/storeLevel', + component: './store/storeLevel', + access: 'k13', + }, + { + name: '店铺信息', + icon: 'smile', + path: '/store/storeInfo', + component: './store/storeInfo', + access: 'k14', + }, + { + name: '加购商品', + icon: 'smile', + path: '/store/storeAddGoodsInfo', + component: './store/storeAddGoodsInfo', + access: 'k14', + }, + { + name: '店铺商品', + icon: 'smile', + path: '/store/storeGoodsInfo', + component: './store/storeGoodsInfo', + access: 'k14', + }, + { + name: '店铺广告', + icon: 'smile', + path: '/store/storeAdvertisement', + component: './store/storeAdvertisement', + access: 'k39', + }, + ], + }, + { + name: '设备管理', + icon: 'BankFilled', + path: '/device', + routes: [ + { + name: '设备分类', + icon: 'smile', + path: '/device/deviceType', + component: './device/deviceType', + access: 'k12', + }, + { + name: '设备信息', + icon: 'smile', + path: '/device/deviceInfo', + component: './device/deviceInfo', + access: 'k14', + }, + { + name: '设备商品管理', + icon: 'smile', + path: '/device/deviceFood', + component: './device/deviceFood', + access: 'k14', + }, + { + name: '设备补货', + icon: 'smile', + path: '/device/deviceStock', + component: './device/deviceStock', + access: 'k14', + } + + + ], + }, + { + name: '积分管理', + icon: 'BankFilled', + path: '/integral', + routes: [ + { + name: '积分规则', + icon: 'smile', + path: '/integral/integralConfigure', + component: './integral/integralConfigure', + access: 'k12', + }, + ] + }, + { + name: '菜谱管理', + icon: 'BankFilled', + path: '/foodMenu', + routes: [ + { + name: '菜谱设置', + icon: 'smile', + path: '/foodMenu/foodMenuInfo', + component: './foodMenu/foodMenuInfo', + access: 'k12', + }, + { + name: '菜谱关联门店', + icon: 'smile', + path: '/foodMenu/storeFoodMenu', + component: './foodMenu/storeFoodMenu', + access: 'k14', + }, + { + name: '菜谱关联菜品', + icon: 'smile', + path: '/foodMenu/foodMenu', + component: './foodMenu/foodMenu', + access: 'k14', + } + ] + }, + { + name: '会员管理', + icon: 'UserSwitchOutlined', + path: '/member', + routes: [ + { + name: '会员信息', + icon: 'smile', + path: '/member/memberInfo', + component: './member/memberInfo', + access: 'k17', + }, + { + name: '会员标签信息', + icon: 'smile', + path: '/member/membertag', + component: './member/membertag', + access: 'k18', + }, + { + name: '会员数据分析', + icon: 'smile', + path: '/member/memberAnalysis', + component: './member/memberAnalysis', + access: 'k19', + }, + ], + }, + { + name: '活动管理', + icon: 'CarryOutOutlined', + path: '/activity', + routes: [ + { + name: '活动信息', + icon: 'smile', + path: '/activity/activityInfo', + component: './activity/activityInfo', + access: 'k20', + }, + { + name: '活动记录信息', + icon: 'smile', + path: '/activity/activityRecord', + component: './activity/activityRecord', + access: 'k21', + }, + ], + }, + { + name: '优惠券管理', + icon: 'WalletOutlined', + path: '/crm', + routes: [ + { + name: '优惠卷管理', + icon: 'smile', + path: '/crm/coupon/couponInfo', + component: './crm/coupon/couponInfo', + access: 'k22', + }, + { + name: '优惠卷批次信息', + icon: 'smile', + path: '/crm/coupon/coupon-Batch', + component: './crm/coupon/coupon-Batch', + access: 'k23', + }, + { + name: '优惠卷领取信息', + icon: 'smile', + path: '/crm/coupon/customerCoupon', + component: './crm/coupon/customerCoupon', + access: 'k24', + }, + ], + }, + { + name: '分账管理', + icon: 'RedEnvelopeOutlined', + path: '/split', + routes: [ + { + name: '分账账户管理', + icon: 'smile', + path: '/split/account', + component: './split/account', + access: 'k25', + }, + { + name: '加盟商分账方案', + icon: 'smile', + path: '/split/FranchiseePlan', + component: './split/FranchiseePlan', + access: 'k25', + }, + { + name: '分账方案管理', + icon: 'smile', + path: '/split/plan', + component: './split/plan', + access: 'k26', + }, + { + name: '分账订单管理', + icon: 'smile', + path: '/split/splitOrders', + component: './split/splitOrders', + access: 'k27', + }, + ], + }, + { + name: '退款操作', + icon: 'AccountBookOutlined', + path: '/refundment', + routes: [ + { + name: '售后申请', + icon: 'smile', + path: '/refundment/OrderAfterSales', + component: './refundment/OrderAfterSales', + access: 'k28', + }, + ], + }, + { + name: '报表统计', + icon: 'SmileOutlined', + path: '/order', + routes: [ + { + name: '订单汇总', + path: '/order/order-summary-manage', + component: './order/order-summary-manage', + access: 'k29', + }, + { + name: '订单流水', + path: '/order/order-flow-manage', + component: './order/order-flow-manage', + access: 'k30', + }, + { + name: '订单明细', + path: '/order/orderDetail', + component: './order/orderDetail', + access: 'k31', + }, + { + name: '营业日报', + path: '/order/ordersalescountbyday', + component: './order/ordersalescountbyday', + access: 'k32', + }, + { + name: '异常订单信息', + path: '/order/ExOrder', + component: './order/ExOrder', + access: 'k31', + }, + ], + }, + { + name: '库存管理', + icon: 'HddOutlined', + path: '/stockManager', + routes: [ + { + name: '其它物料入库', + path: '/stockManager/stockItem', + component: './stockManager/stockItem', + access: 'k36', + }, + { + name: '库存盘点', + path: '/stockManager/stockInventory', + component: './stockManager/stockInventory', + access: 'k37', + }, + { + name: '库存报表', + path: '/stockManager/stockReports', + component: './stockManager/stockReports', + access: 'k38', + }, + ], + }, + { + name: '财务报表', + icon: 'HddOutlined', + path: '/financereport', + routes: [ + { + name: '财务账单', + path: '/financereport/finance', + component: './financereport/finance', + access: 'k37', + }, + ], + }, + { + path: '/', + redirect: '/welcome', + }, + { + path: '/welcome', + name: 'welcome', + icon: 'smile', + component: './Welcome', + }, + { + name: 'test', + icon: 'HddOutlined', + path: '/test', + routes: [ + { + name: 'test', + path: '/test/update', + component: './test/update', + access: 'k37', + }, + { + name: 'test', + path: '/test', + component: './test', + access: 'k37', + }, + ], + }, + //什么都不要想404直接放最后 + { + component: './404', + }, +]; diff --git a/default.conf b/default.conf new file mode 100644 index 0000000..ad50602 --- /dev/null +++ b/default.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } +} + + + diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..b7f2e44 --- /dev/null +++ b/dockerfile @@ -0,0 +1,4 @@ +FROM nginx:latest +COPY ./dist /usr/share/nginx/html/ +COPY ./default.conf /etc/nginx/conf.d/ +EXPOSE 80 diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..6410cc0 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,10 @@ +module.exports = { + testURL: 'http://localhost:7002/', + testEnvironment: './tests/PuppeteerEnvironment', + verbose: false, + extraSetupFiles: ['./tests/setupTests.js'], + globals: { + ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false, + localStorage: null, + }, +}; diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..f2853d7 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "baseUrl": ".", + "paths": { + "@/*": [ + "./src/*" + ] + } + } +} diff --git a/k8s_kitchenweb.yaml b/k8s_kitchenweb.yaml new file mode 100644 index 0000000..98fdfee --- /dev/null +++ b/k8s_kitchenweb.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kitchenweb + namespace: kube- +spec: + + selector: + matchLabels: + app: kitchenweb + replicas: 1 + template: + metadata: + labels: + app: kitchenweb + spec: + containers: + - image: 10.2.1.24:10242/bpa/kitchenweb: + imagePullPolicy: IfNotPresent + name: kitchenweb + env: + - name: branch + value: + ports: + - containerPort: 80 + protocol: TCP + volumeMounts: + - mountPath: "/etc/localtime" + name: timezone + resources: + requests: + cpu: "100m" + memory: "112Mi" + limits: + cpu: "500m" + memory: "512Mi" + volumes: + - name: timezone + hostPath: + path: /usr/share/zoneinfo/Asia/Shanghai +--- +kind: Service +apiVersion: v1 +metadata: + labels: + app: kitchenweb + name: kitchenweb + namespace: kube- +spec: + type: ClusterIP + ports: + - port: 80 + name: http + selector: + app: kitchenweb diff --git a/mock/listTableList.js b/mock/listTableList.js new file mode 100644 index 0000000..abd0748 --- /dev/null +++ b/mock/listTableList.js @@ -0,0 +1,178 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import moment from 'moment'; +import { parse } from 'url'; // mock tableListDataSource + +const genList = (current, pageSize) => { + const tableListDataSource = []; + + for (let i = 0; i < pageSize; i += 1) { + const index = (current - 1) * 10 + i; + tableListDataSource.push({ + key: index, + disabled: i % 6 === 0, + href: 'https://ant.design', + avatar: [ + 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', + 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', + ][i % 2], + name: `TradeCode ${index}`, + owner: '曲丽丽', + desc: '这是一段描述', + callNo: Math.floor(Math.random() * 1000), + status: Math.floor(Math.random() * 10) % 4, + updatedAt: moment().format('YYYY-MM-DD'), + createdAt: moment().format('YYYY-MM-DD'), + progress: Math.ceil(Math.random() * 100), + }); + } + + tableListDataSource.reverse(); + return tableListDataSource; +}; + +let tableListDataSource = genList(1, 100); + +function getRule(req, res, u) { + let realUrl = u; + + if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') { + realUrl = req.url; + } + + const { current = 1, pageSize = 10 } = req.query; + const params = parse(realUrl, true).query; + let dataSource = [...tableListDataSource].slice((current - 1) * pageSize, current * pageSize); + const sorter = JSON.parse(params.sorter || '{}'); + + if (sorter) { + dataSource = dataSource.sort((prev, next) => { + let sortNumber = 0; + Object.keys(sorter).forEach((key) => { + if (sorter[key] === 'descend') { + if (prev[key] - next[key] > 0) { + sortNumber += -1; + } else { + sortNumber += 1; + } + + return; + } + + if (prev[key] - next[key] > 0) { + sortNumber += 1; + } else { + sortNumber += -1; + } + }); + return sortNumber; + }); + } + + if (params.filter) { + const filter = JSON.parse(params.filter); + + if (Object.keys(filter).length > 0) { + dataSource = dataSource.filter((item) => { + return Object.keys(filter).some((key) => { + if (!filter[key]) { + return true; + } + + if (filter[key].includes(`${item[key]}`)) { + return true; + } + + return false; + }); + }); + } + } + + if (params.name) { + dataSource = dataSource.filter((data) => data?.name?.includes(params.name || '')); + } + + const result = { + data: dataSource, + total: tableListDataSource.length, + success: true, + pageSize, + current: parseInt(`${params.current}`, 10) || 1, + }; + return res.json(result); +} + +function postRule(req, res, u, b) { + let realUrl = u; + + if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') { + realUrl = req.url; + } + + const body = (b && b.body) || req.body; + const { method, name, desc, key } = body; + + switch (method) { + /* eslint no-case-declarations:0 */ + case 'delete': + tableListDataSource = tableListDataSource.filter((item) => key.indexOf(item.key) === -1); + break; + + case 'post': + (() => { + const i = Math.ceil(Math.random() * 10000); + const newRule = { + key: tableListDataSource.length, + href: 'https://ant.design', + avatar: [ + 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', + 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', + ][i % 2], + name, + owner: '曲丽丽', + desc, + callNo: Math.floor(Math.random() * 1000), + status: Math.floor(Math.random() * 10) % 2, + updatedAt: moment().format('YYYY-MM-DD'), + createdAt: moment().format('YYYY-MM-DD'), + progress: Math.ceil(Math.random() * 100), + }; + tableListDataSource.unshift(newRule); + return res.json(newRule); + })(); + + return; + + case 'update': + (() => { + let newRule = {}; + tableListDataSource = tableListDataSource.map((item) => { + if (item.key === key) { + newRule = { ...item, desc, name }; + return { ...item, desc, name }; + } + + return item; + }); + return res.json(newRule); + })(); + + return; + + default: + break; + } + + const result = { + list: tableListDataSource, + pagination: { + total: tableListDataSource.length, + }, + }; + res.json(result); +} + +export default { + 'GET /api/rule': getRule, + 'POST /api/rule': postRule, +}; diff --git a/mock/notices.js b/mock/notices.js new file mode 100644 index 0000000..851e8cd --- /dev/null +++ b/mock/notices.js @@ -0,0 +1,105 @@ +const getNotices = (req, res) => { + res.json({ + data: [ + { + id: '000000001', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '你收到了 14 份新周报', + datetime: '2017-08-09', + type: 'notification', + }, + { + id: '000000002', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', + title: '你推荐的 曲妮妮 已通过第三轮面试', + datetime: '2017-08-08', + type: 'notification', + }, + { + id: '000000003', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', + title: '这种模板可以区分多种通知类型', + datetime: '2017-08-07', + read: true, + type: 'notification', + }, + { + id: '000000004', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + datetime: '2017-08-07', + type: 'notification', + }, + { + id: '000000005', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '内容不要超过两行字,超出时自动截断', + datetime: '2017-08-07', + type: 'notification', + }, + { + id: '000000006', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '曲丽丽 评论了你', + description: '描述信息描述信息描述信息', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000007', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '朱偏右 回复了你', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000008', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '标题', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000009', + title: '任务名称', + description: '任务需要在 2017-01-12 20:00 前启动', + extra: '未开始', + status: 'todo', + type: 'event', + }, + { + id: '000000010', + title: '第三方紧急代码变更', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '马上到期', + status: 'urgent', + type: 'event', + }, + { + id: '000000011', + title: '信息安全考试', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + extra: '已耗时 8 天', + status: 'doing', + type: 'event', + }, + { + id: '000000012', + title: 'ABCD 版本发布', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '进行中', + status: 'processing', + type: 'event', + }, + ], + }); +}; + +export default { + 'GET /kitchen/api/notices': getNotices, +}; diff --git a/mock/route.js b/mock/route.js new file mode 100644 index 0000000..1944341 --- /dev/null +++ b/mock/route.js @@ -0,0 +1,7 @@ +export default { + '/kitchen/api/auth_routes': { + '/form/advanced-form': { + authority: ['admin', 'user'], + }, + }, +}; diff --git a/mock/user.js b/mock/user.js new file mode 100644 index 0000000..436f62d --- /dev/null +++ b/mock/user.js @@ -0,0 +1,207 @@ +const waitTime = (time = 100) => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }, time); + }); +}; + +async function getFakeCaptcha(req, res) { + await waitTime(2000); + return res.json('captcha-xxx'); +} + +const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env; +/** + * 当前用户的权限,如果为空代表没登录 + * current user access, if is '', user need login + * 如果是 pro 的预览,默认是有权限的 + */ + +let access = ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site' ? 'admin' : ''; + +const getAccess = () => { + return access; +}; // 代码中会兼容本地 service mock 以及部署站点的静态数据 + +export default { + // 支持值为 Object 和 Array + 'GET /kitchen/api/currentUser': (req, res) => { + if (!getAccess()) { + res.status(401).send({ + data: { + isLogin: false, + }, + errorCode: '401', + errorMessage: '请先登录!', + success: true, + }); + return; + } + + res.send({ + name: 'Serati Ma', + avatar: 'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + access: getAccess(), + geographic: { + province: { + label: '浙江省', + key: '330000', + }, + city: { + label: '杭州市', + key: '330100', + }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }); + }, + // GET POST 可省略 + 'GET /kitchen/api/users': [ + { + key: '1', + name: 'John Brown', + age: 32, + address: 'New York No. 1 Lake Park', + }, + { + key: '2', + name: 'Jim Green', + age: 42, + address: 'London No. 1 Lake Park', + }, + { + key: '3', + name: 'Joe Black', + age: 32, + address: 'Sidney No. 1 Lake Park', + }, + ], + 'POST /kitchen/api/login/account': async (req, res) => { + const { password, username, type } = req.body; + await waitTime(2000); + + if (password === 'ant.design' && username === 'admin') { + res.send({ + status: 'ok', + type, + currentAuthority: 'admin', + }); + access = 'admin'; + return; + } + + if (password === 'ant.design' && username === 'user') { + res.send({ + status: 'ok', + type, + currentAuthority: 'user', + }); + access = 'user'; + return; + } + + if (type === 'mobile') { + res.send({ + status: 'ok', + type, + currentAuthority: 'admin', + }); + access = 'admin'; + return; + } + + res.send({ + status: 'error', + type, + currentAuthority: 'guest', + }); + access = 'guest'; + }, + 'POST /kitchen/api/login/outLogin': (req, res) => { + access = ''; + res.send({ + data: {}, + success: true, + }); + }, + 'POST /kitchen/api/register': (req, res) => { + res.send({ + status: 'ok', + currentAuthority: 'user', + success: true, + }); + }, + 'GET /kitchen/api/500': (req, res) => { + res.status(500).send({ + timestamp: 1513932555104, + status: 500, + error: 'error', + message: 'error', + path: '/base/category/list', + }); + }, + 'GET /kitchen/api/404': (req, res) => { + res.status(404).send({ + timestamp: 1513932643431, + status: 404, + error: 'Not Found', + message: 'No message available', + path: '/base/category/list/2121212', + }); + }, + 'GET /kitchen/api/403': (req, res) => { + res.status(403).send({ + timestamp: 1513932555104, + status: 403, + error: 'Unauthorized', + message: 'Unauthorized', + path: '/base/category/list', + }); + }, + 'GET /kitchen/api/401': (req, res) => { + res.status(401).send({ + timestamp: 1513932555104, + status: 401, + error: 'Unauthorized', + message: 'Unauthorized', + path: '/base/category/list', + }); + }, + 'GET /kitchen/api/login/captcha': getFakeCaptcha, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..0e8815a --- /dev/null +++ b/package.json @@ -0,0 +1,120 @@ +{ + "name": "ant-design-pro", + "version": "5.0.0", + "private": true, + "description": "An out-of-box UI solution for enterprise applications", + "scripts": { + "analyze": "cross-env ANALYZE=1 umi build", + "build": "umi build", + "deploy": "npm run build && npm run gh-pages", + "dev": "npm run start:dev", + "gh-pages": "gh-pages -d dist", + "i18n-remove": "pro i18n-remove --locale=zh-CN --write", + "postinstall": "umi g tmp", + "lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier", + "lint-staged": "lint-staged", + "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ", + "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style", + "lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src", + "lint:prettier": "prettier -c --write \"src/**/*\" --end-of-line auto", + "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less", + "openapi": "umi openapi", + "precommit": "lint-staged", + "prettier": "prettier -c --write \"src/**/*\"", + "start": "cross-env UMI_ENV=dev umi dev", + "start:umi-ui": "HOST=0.0.0.0 UMI-UI=1 umi dev", + "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev", + "start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev", + "start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev", + "start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev umi dev", + "start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev umi dev", + "pretest": "node ./tests/beforeTest", + "test": "umi test", + "test:all": "node ./tests/run-tests.js", + "test:component": "umi test ./src/components", + "serve": "umi-serve", + "tsc": "tsc --noEmit" + }, + "lint-staged": { + "**/*.less": "stylelint --syntax less", + "**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js", + "**/*.{js,jsx,tsx,ts,less,md,json}": [ + "prettier --write" + ] + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 10" + ], + "dependencies": { + "@ant-design/charts": "^1.2.14", + "@ant-design/icons": "^4.5.0", + "@ant-design/pro-card": "^1.18.0", + "@ant-design/pro-descriptions": "^1.10.0", + "@ant-design/pro-form": "^1.48.0", + "@ant-design/pro-layout": "^6.29.0", + "@ant-design/pro-list": "^1.21.37", + "@ant-design/pro-table": "^2.57.0", + "@ant-design/pro-utils": "^1.28.0", + "@umijs/route-utils": "^2.0.3", + "antd": "^4.17.0", + "axios": "^0.26.1", + "braft-editor": "^2.3.9", + "classnames": "^2.2.6", + "cos-js-sdk-v5": "^1.3.5", + "js-export-excel": "^1.1.4", + "linq": "^4.0.0", + "lodash": "^4.17.11", + "moment": "^2.25.3", + "omit.js": "^2.0.2", + "qrcode.react": "^1.0.1", + "react": "^17.0.0", + "react-dev-inspector": "^1.1.1", + "react-dom": "^17.0.0", + "react-helmet-async": "^1.0.4", + "umi": "^3.5.0", + "umi-serve": "^1.9.10" + }, + "devDependencies": { + "@ant-design/pro-cli": "^2.0.2", + "@types/express": "^4.17.0", + "@types/history": "^4.7.2", + "@types/jest": "^27.0.2", + "@types/lodash": "^4.14.177", + "@types/react": "^17.0.35", + "@types/react-dom": "^17.0.0", + "@types/react-helmet": "^6.1.0", + "@umijs/fabric": "^2.6.2", + "@umijs/openapi": "^1.3.6", + "@umijs/plugin-blocks": "^2.0.5", + "@umijs/plugin-esbuild": "^1.0.1", + "@umijs/plugin-openapi": "^1.2.0", + "@umijs/preset-ant-design-pro": "^1.2.0", + "@umijs/preset-dumi": "^1.1.32", + "@umijs/preset-react": "^1.8.27", + "@umijs/preset-ui": "^2.2.9", + "@umijs/yorkie": "^2.0.3", + "carlo": "^0.9.46", + "cross-env": "^7.0.0", + "cross-port-killer": "^1.1.1", + "detect-installer": "^1.0.1", + "enzyme": "^3.11.0", + "eslint": "^8.2.0", + "express": "^4.17.1", + "gh-pages": "^3.0.0", + "jsdom-global": "^3.0.2", + "lint-staged": "^12.0.2", + "mockjs": "^1.0.1-beta3", + "prettier": "^2.3.2", + "puppeteer-core": "^11.0.0", + "stylelint": "^14.1.0", + "typescript": "^4.2.2" + }, + "engines": { + "node": ">=10.0.0" + }, + "gitHooks": { + "commit-msg": "fabric verify-commit" + } +} diff --git a/public/CNAME b/public/CNAME new file mode 100644 index 0000000..30c2d4d --- /dev/null +++ b/public/CNAME @@ -0,0 +1 @@ +preview.pro.ant.design \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e2e93252988b5bed120ddeb168eb577bf0caa881 GIT binary patch literal 4286 zcmeHLO(?8k6#ga#Gs=ufvobTd=q@y~nOLdYlqL%nQY4WqC`)z}3y~cqOAAF4VkQd~ z^3$wrC}~D1l%!eMp!|gA&U5sN?~b{2>)yNg-s#Lc-+9k_p7Y<=XqqYcDJs(Vt%dBG z=F~Lpdy*pd!Y zozZT}udJ-#| zqiAVq0sT@kAMMobbULxOw+F6{j*egO8CQ?TgTuo^+}_@zrlv;l$*-)e#PRVl?(Xgo zi9`?zg>ZFsh0DuJ)Ya9!von7LPN@OfP9IfH_4tet&&I~a#O{TK1<3*LO-xJ( zZ*Fc5%v&m4#Z&mZySs8{XJ-fV^Yh@{p`ju8d_J)w6+U%`!(qAC+uJK~qg_o+O|QC` zTVg0Y{jSHqzP^^&G0t4^cwF+$`egj?@9$AtTMLuPB>7!lUKY8&zP?xd=H_PM(U;HS ztNi!(_oJes0<5X6tu4{BxVR{FO)_x3UauFkv$I%RTSHe@7dAIHF+4mhc?|>t(!XbCXVQZk z8yje7Xh2R*&WCwdw&?N4$H!4$Uyq)i9_;V$3;y)^-LKhmkv{Z#(CP^-7Wn# zI5-H>z`y`nTU%u=f7Tbh-mg5fPT0G8`Wx6^vD1(>-r0;AFlyjWYC!!D@UQlt)%}4^ literal 0 HcmV?d00001 diff --git a/public/icons/icon-128x128.png b/public/icons/icon-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..48d0e2339a60a637b94319c65e8654289b4f4b6c GIT binary patch literal 1329 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

*C7T$?5!b= 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
@X(Gsd-xA0DVDkE^O8OCi zm*wz*RjPJ7WhuCC_+uPpnP5bulknw=%o*A*FVgxv!erlfikm|nlDEtzF!I0mR_4iH zXlSF*yqAmO#YI~(o_A`!Zr>E}f(Dsma9X3$>bj}k>X)&6yj9gIG9zuYwwzK6RW8O> zHt#u>NARsn`;S3~B?krTuBs%-=~NWw-LBi5b2;~9iR14Xc~|?kl-19Ww|B279J=xRSB4Xt4Xm;yaPTl~)&;ykSx8~Z2Zd)~L@yXy?|H#yXMl9#%y2ibrB2^#B9 z1^Zw%v4xnga>Ggi4MVFg*h9O&8l^VwMSVQ(%*)U=YA18imFa7}RlP7hPLn*UJhgt* z6IoLD3!l8!OB$lf>(LD40s=D#b`u)p|F zf$6pe+pkD48>P<@v~0N0x%7UYLjKH(S}c?ND)vHZsF%Gw`^$l`(e=WaIhks@cNWX_ zr^RNgM!JRVtiCb(5vRi!DsZ?{#U;bLPfO@?O<=nCQo(<|mM(j@qxrI>hUM81T;0ir z8PO{#xt!j^3Hc=cL!ax%^()-DJ%_nV&HB@Dx-LooVu*3g4+>2f>!mVuuZl?1ptgj*qGdOwRuUFp7N``yPmjnBo{S&t z-w}h^h#loR@Opi{D3r1-;&XQff4f6vm_Lh`{O2T>Zh2=-!M|pweaA#x!R5>L^Dsl+ zTbXs7LJGvfG++QF&+nbVrSsN$ar&shX1V|8*rF8TvfS$f>R@l~BxCJ+58BuHlY=XP zd;2rYn?egE<+z&Jfi`1Ed`_Sh^4(MLMzTyafo#0=Li$|T_(O4SeFc01^#YiWr=ov5 zsU1C{pM>0jt+wPGcR!`iRV5KOu6bPxaAj`(Cked5DT8d?r+iaGLpj76eY7l}oMG3Q zGrW+5c$dN0{qc}{4D7*+NPR1Y5@jxdAn;!jix=V=p2(xd?k#$T1=gME&g7@cTm>Xf znoF|2b1z_&K=!vp4k=b-l;kx^Q6+D2SOkonCHOXEp4_|p+n&x@y5c8H8IobkI^z

+VeI@wDx9sL;px2U(&M3y> zlRZjL@@~yQMdw524>Y+7qKb=wgNLucc3j?YFEStG`PqhRFCz)PwW_e|G4n=e#-7`N z%Z`f|u1nDw8C=pdeN&%iY;i!+4D=uIFJy&rH@FLDC=;n2WzzIkndV)H5uX$G^g1u| z^`eTfW-&Jtt2aamF=)BcLGd$m3oD!%XWkcV^idO<(pu<@R?zjL@6X+#f^@~we`!*v zVQZG$@;w**l3^{W(yoDB+Ly7)ITYjhI3|bTz-m&*FX2b`&+GGvG3cLz2|?DNwd=<<)GX2O3SCC)xgR`ck@6tV7MYw_=i3*6NY zT67QzmaGo7nj}D`HI2D`+;6OiP~~A`=BWI?pTTD1ddRKb7P#2DvAyY~`cyup5G5k{ z^fzK+=YvI-Hm5}y_pZb%e~o=a zvEVBU9V+<5LxSSi3YF3r_%~O2le+)^q*$G|(w+W~@A#6l%~9S-&_8fc;D6FBnv%iKc%Igi@>|9WRna5#{olW}ayHjFXmInj dx9Rpaifl!2LSXh(GKviT;4W$@=U=c0`acdVM|A)I literal 0 HcmV?d00001 diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..14d453c --- /dev/null +++ b/public/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/pro_icon.svg b/public/pro_icon.svg new file mode 100644 index 0000000..e075b78 --- /dev/null +++ b/public/pro_icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/access.js b/src/access.js new file mode 100644 index 0000000..530d028 --- /dev/null +++ b/src/access.js @@ -0,0 +1,50 @@ +/** + * 这里是把登录信息拿来做菜单权限控制 + * @see https://umijs.org/zh-CN/plugins/plugin-access + * */ +// permission 按钮权限标志 +// function checkPermission(currentUser:API.CurrentUser,permission:string) +// { +// return currentUser&& currentUser.data.roles.some( +// (roles)=>roles.permissions.map(permission=>permission.name).indexof(permission)>-1) +// } +export default function access(initialState) { + const { currentUser, menuData } = initialState || {}; + + return { + // k1:true, + // k2:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k2'): false, + // k3:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k3'): false, + // k4:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k4'): false, + // k5:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k5'): false, + // k6:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k6'): false, + // k7:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k7'): false, + // k8:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k8'): false, + // k9:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k9'): false, + // k10:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k10'): false, + // k11:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k11'): false, + // k12:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k12'): false, + // k13:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k13'): false, + // k14:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k14'): false, + // k15:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k15'): false, + // k16:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k16'): false, + // k17:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k17'): false, + // k18:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k18'): false, + // k19:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k19'): false, + // k20:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k20'): false, + // k21:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k21'): false, + // k22:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k22'): false, + // k23:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k23'): false, + // k24:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k24'): false, + // k25:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k25'): false, + // k26:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k26'): false, + // k27:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k27'): false, + // k28:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k28'): false, + // k29:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k29'): false, + // k30:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k30'): false, + // k31:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k31'): false, + // k32:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k32'): false, + // k33:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k33'): false, + // k34:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k34'): false, + }; +} diff --git a/src/app.jsx b/src/app.jsx new file mode 100644 index 0000000..97fe035 --- /dev/null +++ b/src/app.jsx @@ -0,0 +1,782 @@ +import React from 'react'; +import { PageLoading } from '@ant-design/pro-layout'; +import { notification } from 'antd'; +import { history, Link, RequestConfig } from 'umi'; +import RightContent from '@/components/RightContent'; +import Footer from '@/components/Footer'; +import * as Icon from '@ant-design/icons'; +import api from '@/services/api'; +const isDev = process.env.NODE_ENV === 'development'; +const loginPath = '/user/login'; +/** 获取用户信息比较慢的时候会展示一个 loading */ + +export const initialStateConfig = { + loading: , +}; +/** + * @see https://umijs.org/zh-CN/plugins/plugin-initial-state + * */ + +export async function getInitialState() { + const fetchUserInfo = async () => { + try { + const currentUser = await api.queryCurrent(); + if (currentUser.data == null) { + history.push(loginPath); + } + return currentUser; + } catch (error) { + const { location } = history; // 如果没有登录,重定向到 login + console.log(location.pathname); + if (location.pathname != loginPath) { + history.push(loginPath); + } + } + + return undefined; + }; + const queryMenuData = async () => { + try { + const data = [ + + { + code:'device', + name: '设备管理', + icon: 'BankFilled', + path: '/device', + routes: [ + { + code:'deviceType', + name: '设备分类', + icon: 'smile', + path: '/device/deviceType', + component: './device/deviceType', + access: 'k12', + }, + { + code:'deviceInfo', + name: '设备信息', + icon: 'smile', + path: '/device/deviceInfo', + component: './device/deviceInfo', + access: 'k14', + }, + { + code:'deviceFood', + name: '设备商品管理', + icon: 'smile', + path: '/device/deviceFood', + component: './device/deviceFood', + access: 'k14', + } + ], + }, + { + code:'integral', + name: '积分管理', + icon: 'BankFilled', + path: '/integral', + routes: [ + { + code:'integralConfigure', + name: '积分规则', + icon: 'smile', + path: '/integral/integralConfigure', + component: './integral/integralConfigure', + access: 'k12', + },] + + }, + { + code:'foodMenu', + name: '菜谱管理', + icon: 'BankFilled', + path: '/foodMenu', + routes: [ + { + code:'foodMenuInfo', + name: '菜谱设置', + icon: 'smile', + path: '/foodMenu/foodMenuInfo', + component: './foodMenu/foodMenuInfo', + access: 'k12', + }, + { + code:'storeFoodMenu', + name: '菜谱关联门店', + icon: 'smile', + path: '/foodMenu/storeFoodMenu', + component: './foodMenu/storeFoodMenu', + access: 'k14', + }, + { + code:'foodMenu', + name: '菜谱关联菜品', + icon: 'smile', + path: '/foodMenu/foodMenu', + component: './foodMenu/foodMenu', + access: 'k14', + } + ] + }, + { + code:'sys', + name: '系统管理', + icon: 'SettingOutlined', + path: '/sys', + routes: [ + { + code:'company', + name: '加盟商管理', + icon: 'smile', + path: '/sys/company', + component: './sys/company', + access: 'k2', + }, + { + code:'Org', + name: '组织管理', + icon: 'smile', + path: '/sys/Org', + component: './sys/Org', + access: 'k2', + }, + { + code:'Log', + name: '操作日志', + icon: 'smile', + path: '/sys/Log', + component: './sys/Log', + access: 'k3', + }, + { + code:'User', + name: '系统用户', + icon: 'smile', + path: '/sys/User', + component: './sys/User', + access: 'k4', + }, + { + code:'Roles', + name: '角色权限', + icon: 'smile', + path: '/sys/Roles', + component: './sys/Roles', + access: 'k5', + }, + { + code:'Menus', + name: '系统菜单', + icon: 'smile', + path: '/sys/Menus', + component: './sys/Menus', + access: 'k6', + }, + { + code:'dictdata', + name: '字典信息', + icon: 'smile', + path: '/sys/dictionary/dictdata', + component: './sys/dictionary/dictdata', + access: 'k6', + }, + { + code:'dicttype', + name: '字典类型', + icon: 'smile', + path: '/sys/dictionary/dicttype', + component: './sys/dictionary/dicttype', + access: 'k6', + }, + { + code:'sysSettings', + name: '系统配置', + icon: 'smile', + path: '/sys/sysSettings', + component: './sys/sysSettings', + access: 'k6', + }, + ], + }, + { + code:'bom', + name: '配方管理', + icon: 'DropboxSquareFilled', + path: '/bom', + routes: [ + { + code:'bommanage', + name: '配方列表', + icon: 'smile', + path: '/bom/manage', + component: './bom/manage', + access: 'k7', + }, + ], + }, + { + code:'erp', + name: '物料管理', + icon: 'DropboxSquareFilled', + path: '/erp', + routes: [ + { + code:'product', + name: '物料信息', + icon: 'smile', + path: '/erp/basic/product', + component: './erp/basic/product', + access: 'k7', + }, + { + code:'unit', + name: '物料单位', + icon: 'smile', + path: '/erp/basic/unit', + component: './erp/basic/unit', + access: 'k8', + }, + { + code:'productType', + name: '物料分类', + icon: 'smile', + path: '/erp/basic/productType', + component: './erp/basic/productType', + access: 'k9', + }, + + ], + }, + { + code:'goods', + name: '商品管理', + icon: 'ProjectFilled', + path: '/goods', + routes: [ + { + code:'newgoods', + name: '商品管理', + icon: 'smile', + path: '/goods/newgoods', + component: './goods/newgoods', + access: 'k10', + }, + { + code:'goods-taste', + name: '商品口味', + icon: 'smile', + path: '/goods/goods-taste', + component: './goods/goods-taste', + access: 'k11', + }, + { + code:'goods-type', + name: '商品小类', + icon: 'smile', + path: '/goods/goods-type-manage', + component: './goods/goods-type-manage', + access: 'k11', + }, + { + code:'goodsbigtype', + name: '商品大类', + icon: 'smile', + path: '/goods/goodsParentTypemanage', + component: './goods/goodsParentTypemanage', + access: 'k11', + }, + { + code:'unit', + name: '商品单位', + icon: 'smile', + path: '/goods/unit', + component: './goods/unit', + access: 'k11', + }, + ], + }, + { + code:'store', + name: '店铺管理', + icon: 'BankFilled', + path: '/store', + routes: [ + { + code:'storeDesktopNumber', + name: '店铺桌面码', + icon: 'smile', + path: '/store/storeDesktopNumber', + component: './store/storeDesktopNumber', + access: 'k12', + }, + { + code:'Printer', + name: '店铺小票打印机', + icon: 'smile', + path: '/store/printer/Printer', + component: './store/printer/Printer', + access: 'k12', + }, + { + code:'printerTemplate', + name: '打印机模板', + icon: 'smile', + path: '/store/printer/printerTemplate', + component: './store/printer/printerTemplate', + access: 'k12', + }, + { + code:'storeGoodsInfo', + name: '店铺商品', + icon: 'smile', + path: '/store/storeGoodsInfo', + component: './store/storeGoodsInfo', + access: 'k14', + }, + { + code:'storeAdvertisement', + name: '店铺广告', + icon: 'smile', + path: '/store/storeAdvertisement', + component: './store/storeAdvertisement', + access: 'k39', + }, + ], + }, + { + code:'member', + name: '会员管理', + icon: 'UserSwitchOutlined', + path: '/member', + routes: [ + { + code:'memberInfo', + name: '会员信息', + icon: 'smile', + path: '/member/memberInfo', + component: './member/memberInfo', + access: 'k17', + }, + { + code:'membertag', + name: '会员标签信息', + icon: 'smile', + path: '/member/membertag', + component: './member/membertag', + access: 'k18', + }, + { + code:'memberAnalysis', + name: '会员数据分析', + icon: 'smile', + path: '/member/memberAnalysis', + component: './member/memberAnalysis', + access: 'k19', + }, + ], + }, + { + code:'activity', + name: '活动管理', + icon: 'CarryOutOutlined', + path: '/activity', + routes: [ + { + code:'activityInfo', + name: '活动信息', + icon: 'smile', + path: '/activity/activityInfo', + component: './crm/activity/activityInfo', + access: 'k20', + }, + { + code:'activityRecord', + name: '活动记录信息', + icon: 'smile', + path: '/activity/activityRecord', + component: './activity/activityRecord', + access: 'k21', + }, + ], + }, + { + code:'Coupon', + name: '优惠券管理', + icon: 'WalletOutlined', + path: '/crm', + routes: [ + { + code:'couponInfo', + name: '优惠卷管理', + icon: 'smile', + path: '/crm/Coupon/couponInfo', + component: './crm/Coupon/couponInfo', + access: 'k22', + }, + { + code:'coupon-Batch', + name: '优惠卷批次信息', + icon: 'smile', + path: '/crm/Coupon/coupon-Batch', + component: './crm/Coupon/coupon-Batch', + access: 'k23', + }, + { + code:'customerCoupon', + name: '优惠卷领取信息', + icon: 'smile', + path: '/crm/Coupon/customerCoupon', + component: './crm/Coupon/customerCoupon', + access: 'k24', + }, + ], + }, + { + code:'split', + name: '分账管理', + icon: 'RedEnvelopeOutlined', + path: '/split', + routes: [ + { + code:'account', + name: '分账账户管理', + icon: 'smile', + path: '/split/account', + component: './split/account', + access: 'k25', + }, + { + code:'FranchiseePlan', + name: '加盟商分账方案', + icon: 'smile', + path: '/split/FranchiseePlan', + component: './split/FranchiseePlan', + access: 'k25', + }, + { + code:'plan', + name: '分账方案管理', + icon: 'smile', + path: '/split/plan', + component: './split/plan', + access: 'k26', + }, + { + code:'splitOrders', + name: '分账订单管理', + icon: 'smile', + path: '/split/splitOrders', + component: './split/splitOrders', + access: 'k27', + }, + ], + }, + { + code:'refundment', + name: '退款操作', + icon: 'AccountBookOutlined', + path: '/refundment', + routes: [ + { + code:'OrderAfterSales', + name: '售后申请', + icon: 'smile', + path: '/refundment/OrderAfterSales', + component: './refundment/OrderAfterSales', + access: 'k28', + }, + ], + }, + { + code:'order', + name: '报表统计', + icon: 'SmileOutlined', + path: '/order', + routes: [ + { + code:'ordersummarymanage', + name: '订单汇总', + path: '/order/order-summary-manage', + component: './order/order-summary-manage', + access: 'k29', + }, + { + code:'orderflowmanage', + name: '订单流水', + path: '/order/order-flow-manage', + component: './order/order-flow-manage', + access: 'k30', + }, + { + code:'orderDetail', + name: '订单明细', + path: '/order/orderDetail', + component: './order/orderDetail', + access: 'k31', + }, + { + code:'ordersalescountbyday', + name: '营业日报', + path: '/order/ordersalescountbyday', + component: './order/ordersalescountbyday', + access: 'k32', + }, + { + code:'ExOrder', + name: '异常订单', + path: '/order/ExOrder', + component: './order/ExOrder', + access: 'k32', + }, + ], + }, + { + code:'stockManager', + name: '库存管理', + icon: 'HddOutlined', + path: '/stockManager', + routes: [ + { + code:'stockItem', + name: '其它物料入库', + path: '/stockManager/stockItem', + component: './stockManager/stockItem', + access: 'k36', + }, + { + code:'stockInventory', + name: '库存盘点', + path: '/stockManager/stockInventory', + component: './stockManager/stockInventory', + access: 'k37', + }, + { + code:'stockReports', + name: '库存报表', + path: '/stockManager/stockReports', + component: './stockManager/stockReports', + access: 'k38', + }, + ], + }, + { + code:'financereport', + name: '财务报表', + icon: 'HddOutlined', + path: '/financereport', + routes: [ + { + code:'finance', + name: '财务账单', + path: '/financereport/finance', + component: './financereport/finance', + access: 'k37', + }, + ], + }, + ]; + // api.queryMenus(); + return data; + } catch (error) { + history.push(loginPath); + } + return []; + }; + // 如果是登录页面,不执行 + + if (history.location.pathname !== loginPath) { + const currentUser = await fetchUserInfo(); + var tempMenu = await queryMenuData(); + //创建菜单 + // await syncMenus(tempMenu); + // if (!isDev) { + // var data = await dymicMenus(currentUser.data.id); + // tempMenu = data.data; + // } + + return { + fetchUserInfo, + currentUser, + menuData: tempMenu, + settings: {}, + }; + } + return { + fetchUserInfo, + settings: {}, + }; +} + +/** + * 同步菜单 + * @param {*} args + * @returns + */ +const syncMenus = async (args) => { + return await api.queryAndSyncMenu({ json: JSON.stringify(args) }); +}; + +/** + * 动态菜单 + * @param {*} userid + * @returns + */ + +const dymicMenus = async (userid) => { + return await api.DymicMenus(userid); +}; + +/** + * + * 动态路由 + * + */ +const loopMenuItem = (menus) => + menus?.map(({ icon, children, ...item }) => { + if (typeof icon != 'undefined' && Icon[icon] != undefined) { + return { + ...item, + icon: icon && React.createElement(Icon[icon]), + children: children && loopMenuItem(children), + }; + } else { + return { + ...item, + children: children && loopMenuItem(children), + }; + } + }); +/** + * 异常处理程序 + 200: '服务器成功返回请求的数据。', + 201: '新建或修改数据成功。', + 202: '一个请求已经进入后台排队(异步任务)。', + 204: '删除数据成功。', + 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', + 401: '用户没有权限(令牌、用户名、密码错误)。', + 403: '用户得到授权,但是访问是被禁止的。', + 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', + 405: '请求方法不被允许。', + 406: '请求的格式不可得。', + 410: '请求的资源被永久删除,且不会再得到的。', + 422: '当创建一个对象时,发生一个验证错误。', + 500: '服务器发生错误,请检查服务器。', + 502: '网关错误。', + 503: '服务不可用,服务器暂时过载或维护。', + 504: '网关超时。', + //-----English + 200: The server successfully returned the requested data. ', + 201: New or modified data is successful. ', + 202: A request has entered the background queue (asynchronous task). ', + 204: Data deleted successfully. ', + 400: 'There was an error in the request sent, and the server did not create or modify data. ', + 401: The user does not have permission (token, username, password error). ', + 403: The user is authorized, but access is forbidden. ', + 404: The request sent was for a record that did not exist. ', + 405: The request method is not allowed. ', + 406: The requested format is not available. ', + 410': + 'The requested resource is permanently deleted and will no longer be available. ', + 422: When creating an object, a validation error occurred. ', + 500: An error occurred on the server, please check the server. ', + 502: Gateway error. ', + 503: The service is unavailable. ', + 504: The gateway timed out. ', + * @see https://beta-pro.ant.design/docs/request-cn + */ +const codeMessage = { + 200: '服务器成功返回请求的数据。', + 201: '新建或修改数据成功。', + 202: '一个请求已经进入后台排队(异步任务)。', + 204: '删除数据成功。', + 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', + 401: '用户没有权限(令牌、用户名、密码错误)。', + 403: '用户得到授权,但是访问是被禁止的。', + 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', + 405: '请求方法不被允许。', + 406: '请求的格式不可得。', + 410: '请求的资源被永久删除,且不会再得到的。', + 422: '当创建一个对象时,发生一个验证错误。', + 500: '服务器发生错误,请检查服务器。', + 502: '网关错误。', + 503: '服务不可用,服务器暂时过载或维护。', + 504: '网关超时。', +}; + +export const request = { + errorHandler: (error) => { + const { response } = error; + if (response && response.status !== 200 && response.status !== 422) { + const errorText = codeMessage[response.status] || response.statusText; + const { status, url } = response; + if (response.status === 401 || response.status === 403) { + notification.error({ + description: '户没有权限(令牌、用户名、密码错误)。', + message: '网络异常', + }); + // history.push('/user/login'); + const { location } = history; // 如果没有登录,重定向到 login + if (!location.pathname.includes(loginPath)) { + history.push(loginPath); + } + } else { + notification.error({ + message: `请求错误 ${status}: ${url}`, + description: errorText, + }); + } + } + if (!response) { + notification.error({ + description: '您的网络发生异常,无法连接服务器', + message: '网络异常', + }); + } + + throw error; + }, + //prefix: `${DOMAIN}`, + requestInterceptors: [ + (url, options) => { + console.log(url); + console.log(options); + url = decodeURI(encodeURI(url).replace(/%E2%80%8B/g, '')); + const newOptions = { ...options }; + const auttoken = localStorage.getItem('token'); + const userid = localStorage.getItem('userid'); + newOptions.headers = { + ...newOptions.headers, + userid: userid, + Authorization: 'Bearer ' + auttoken, + LoginType: 1, + Accept: 'application/json', + 'Content-Type': 'application/json; charset=utf-8', + }; + return { url, options: newOptions }; + }, + ], +}; +// ProLayout 支持的api https://procomponents.ant.design/components/layout + +export const layout = ({ initialState }) => { + return { + rightContentRender: () => , + disableContentMargin: false, + waterMarkProps: { + content: '黑菠萝技术部', + }, + + footerRender: () =>