From 9b55b17b5411643424838acdfbab5b4fc0e0d25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=A8=E6=A0=88=E5=B0=8F=E5=AD=A6=E7=94=9F?= <1518079521@qq.com> Date: Wed, 31 May 2023 11:20:09 +0800 Subject: [PATCH] 1 --- .../views/diy/components/edit-hello-info.vue | 31 - .../views/diy/components/edit-hello-text.vue | 25 +- .../app/adminapi/controller/Index.php | 3 +- .../hello_world/app/dict/diy/components.php | 21 + .../addon/hello_world/app/dict/diy/links.php | 26 + .../addon/hello_world/app/dict/diy/pages.php | 89 + .../hello_world/app/dict/diy/template.php | 12 + .../app/dict/member/account_change_type.php | 18 + .../app/{enum => dict}/menu/admin.php | 1 - .../addon/hello_world/app/dict/menu/site.php | 36 + .../app/{enum => dict}/notice/notice.php | 0 .../app/{enum => dict}/notice/sms.php | 0 .../app/{enum => dict}/notice/weapp.php | 0 .../app/{enum => dict}/notice/wechat.php | 0 .../hello_world/app/enum/diy/components.php | 32 - .../addon/hello_world/app/enum/diy/links.php | 8 - .../addon/hello_world/app/enum/diy/pages.php | 4 - .../addon/hello_world/app/enum/menu/site.php | 18 - .../app/lang/zh-cn/{enum.php => dict.php} | 11 +- .../hello_world/config/uni-app-pages.json | 14 - .../{config => package}/admin-package.json | 0 .../{config => package}/composer.json | 0 .../{config => package}/uni-app-package.json | 0 .../hello_world/package/uni-app-pages.php | 25 + .../{config => package}/web-package.json | 0 niucloud/addon/hello_world/resource/cover.png | Bin 0 -> 131385 bytes .../diy/comp-extend/hello-info/index.vue | 24 - .../diy/comp-extend/hello-text/index.vue | 24 - .../components/diy/comp-extend/index.vue | 20 - .../components/diy/hello-text/index.vue | 34 + niucloud/addon/hello_world/uni-app/pages.json | 43 - .../uni-app/pages/hello_world/info.vue | 166 ++ niucloud/app/ExceptionHandle.php | 8 +- niucloud/app/Request.php | 10 +- .../app/adminapi/controller/addon/Addon.php | 26 +- .../app/adminapi/controller/addon/App.php | 1 - niucloud/app/adminapi/controller/diy/Diy.php | 16 +- .../app/adminapi/controller/diy/DiyRoute.php | 4 +- .../controller/generator/Generator.php | 4 +- .../app/adminapi/controller/login/Config.php | 1 + .../app/adminapi/controller/login/Login.php | 1 + .../adminapi/controller/member/Account.php | 81 +- .../adminapi/controller/member/CashOut.php | 21 +- .../app/adminapi/controller/member/Config.php | 22 + .../app/adminapi/controller/member/Member.php | 32 +- .../app/adminapi/controller/notice/Notice.php | 4 +- .../adminapi/controller/order/Recharge.php | 20 +- .../app/adminapi/controller/order/Refund.php | 12 +- .../adminapi/controller/pay/PayChannel.php | 10 +- .../app/adminapi/controller/site/Site.php | 32 +- .../app/adminapi/controller/site/User.php | 6 +- .../adminapi/controller/sys/Attachment.php | 4 +- .../app/adminapi/controller/sys/Channel.php | 4 +- .../app/adminapi/controller/sys/Config.php | 23 +- niucloud/app/adminapi/controller/sys/Cron.php | 4 +- niucloud/app/adminapi/controller/sys/Menu.php | 14 +- niucloud/app/adminapi/controller/sys/Role.php | 6 +- .../app/adminapi/controller/sys/System.php | 23 + .../adminapi/controller/upload/Storage.php | 4 +- .../adminapi/middleware/AllowCrossDomain.php | 3 +- niucloud/app/adminapi/route/addon.php | 14 +- niucloud/app/adminapi/route/diy.php | 12 +- niucloud/app/adminapi/route/member.php | 16 +- niucloud/app/adminapi/route/order.php | 4 +- niucloud/app/adminapi/route/refund.php | 2 + niucloud/app/adminapi/route/route.php | 4 +- niucloud/app/adminapi/route/site.php | 4 + niucloud/app/adminapi/route/sys.php | 18 +- .../app/api/controller/member/Account.php | 13 +- .../api/controller/member/MemberCashOut.php | 8 +- niucloud/app/api/controller/sys/Config.php | 8 + .../app/api/middleware/AllowCrossDomain.php | 3 +- niucloud/app/api/middleware/ApiCheckToken.php | 6 +- .../app/api/route/dispatch/BindDispatch.php | 6 +- niucloud/app/api/route/route.php | 5 +- niucloud/app/command/Addon/Install.php | 35 + niucloud/app/command/Addon/Uninstall.php | 24 + niucloud/app/command/Schedule.php | 94 + niucloud/app/common.php | 57 +- .../addon/AddonDict.php} | 22 +- .../cash_out/CashOutTypeDict.php} | 4 +- .../channel/CertDict.php} | 4 +- .../channel/ReplyDict.php} | 8 +- .../channel/WechatDict.php} | 10 +- .../common/ChannelDict.php} | 20 +- niucloud/app/dict/common/CommonDict.php | 28 + .../diy/ComponentDict.php} | 40 +- .../LinkEnum.php => dict/diy/LinkDict.php} | 51 +- niucloud/app/dict/diy/PagesDict.php | 898 ++++++++ .../diy/TemplateDict.php} | 24 +- .../member/MemberAccountChangeTypeDict.php | 38 + .../app/dict/member/MemberAccountTypeDict.php | 48 + .../member/MemberCashOutDict.php} | 18 +- .../member/MemberDict.php} | 12 +- .../member/MemberLoginTypeDict.php} | 16 +- .../member/MemberRegisterChannelDict.php} | 12 +- .../member/MemberRegisterTypeDict.php} | 18 +- .../app/dict/member/account_change_type.php | 116 + niucloud/app/{enum => dict}/menu/admin.php | 94 +- niucloud/app/{enum => dict}/menu/site.php | 129 +- .../notice/NoticeDict.php} | 33 +- .../notice/NoticeTypeDict.php} | 10 +- niucloud/app/{enum => dict}/notice/notice.php | 1 + niucloud/app/{enum => dict}/notice/sms.php | 0 niucloud/app/{enum => dict}/notice/weapp.php | 0 niucloud/app/{enum => dict}/notice/wechat.php | 0 .../order/OrderRefundDict.php} | 19 +- .../order/OrderTypeDict.php} | 12 +- .../order/RechargeOrderDict.php} | 24 +- .../pay/OnlinePayDict.php} | 9 +- .../pay/OnlineRefundDict.php} | 4 +- .../pay/PayChannelDict.php} | 12 +- .../pay/PayEnum.php => dict/pay/PayDict.php} | 30 +- .../pay/RefundDict.php} | 20 +- .../pay/TransferDict.php} | 24 +- .../ScanEnum.php => dict/scan/ScanDict.php} | 4 +- niucloud/app/dict/schedule/schedule.php | 22 + .../SiteEnum.php => dict/site/SiteDict.php} | 12 +- .../sys/AgreementDict.php} | 12 +- .../sys/AppTypeDict.php} | 10 +- .../sys/ConfigKeyDict.php} | 4 +- .../CronEnum.php => dict/sys/CronDict.php} | 16 +- .../FileEnum.php => dict/sys/FileDict.php} | 16 +- .../MenuEnum.php => dict/sys/MenuDict.php} | 8 +- .../sys/MenuTypeDict.php} | 10 +- .../sys/MethodDict.php} | 4 +- .../sys/RoleStatusDict.php} | 8 +- .../sys/SmsEnum.php => dict/sys/SmsDict.php} | 14 +- .../sys/StorageDict.php} | 8 +- .../UserEnum.php => dict/sys/UserDict.php} | 8 +- niucloud/app/enum/common/CommonEnum.php | 28 - .../app/enum/member/MemberAccountEnum.php | 74 - niucloud/app/enum/member/fromtypes/system.php | 98 - niucloud/app/event.php | 4 +- niucloud/app/install/controller/Index.php | 94 +- niucloud/app/install/source/database.sql | 1902 +++++++++-------- niucloud/app/install/view/index/step-3.html | 46 +- niucloud/app/install/view/index/step-4.html | 26 +- niucloud/app/job/schedule/OrderClose.php | 32 + niucloud/app/job/schedule/SiteExpireClose.php | 40 + niucloud/app/job/sys/AddonInstall.php | 31 + niucloud/app/job/sys/CheckDeleteJob.php | 29 + niucloud/app/job/sys/CheckJob.php | 31 + niucloud/app/job/sys/Cronexecute.php | 64 - niucloud/app/lang/en.php | 5 +- niucloud/app/lang/en/{system => }/api.php | 0 .../app/lang/en/{system/enum.php => dict.php} | 38 +- .../app/lang/en/{system => }/validate.php | 0 niucloud/app/lang/zh-cn.php | 5 +- niucloud/app/lang/zh-cn/api.php | 29 +- .../app/lang/zh-cn/{enum.php => dict.php} | 81 +- niucloud/app/lang/zh-cn/validate.php | 11 +- niucloud/app/listener/notice/Sms.php | 9 +- niucloud/app/listener/notice/Weapp.php | 14 +- niucloud/app/listener/notice/Wechat.php | 19 +- .../app/listener/pay/PaySuccessListener.php | 2 +- .../listener/pay/TransferSuccessListener.php | 4 +- niucloud/app/listener/scan/ScanListener.php | 8 +- .../listener/site/AddSiteAfterListener.php | 35 + .../app/listener/system/AppManageListener.php | 13 +- niucloud/app/model/addon/Addon.php | 4 +- niucloud/app/model/article/Article.php | 9 +- .../app/model/article/ArticleCategory.php | 8 +- niucloud/app/model/diy/Diy.php | 14 +- niucloud/app/model/member/Member.php | 32 +- .../app/model/member/MemberAccountLog.php | 40 +- niucloud/app/model/member/MemberCashOut.php | 89 +- .../app/model/member/MemberCashOutAccount.php | 4 +- niucloud/app/model/member/MemberLabel.php | 26 + niucloud/app/model/order/Order.php | 75 +- niucloud/app/model/order/OrderItem.php | 7 + niucloud/app/model/order/OrderItemRefund.php | 30 +- niucloud/app/model/pay/Pay.php | 10 +- niucloud/app/model/pay/PayChannel.php | 8 +- niucloud/app/model/pay/Refund.php | 12 +- niucloud/app/model/pay/Transfer.php | 6 +- niucloud/app/model/site/Site.php | 21 +- niucloud/app/model/sys/SysAgreement.php | 4 +- niucloud/app/model/sys/SysCronTask.php | 6 +- niucloud/app/model/sys/SysMenu.php | 20 +- niucloud/app/model/sys/SysNoticeLog.php | 6 +- niucloud/app/model/sys/SysNoticeSmsLog.php | 8 +- niucloud/app/model/sys/SysRole.php | 4 +- niucloud/app/model/sys/SysUser.php | 9 +- niucloud/app/model/wechat/WechatReply.php | 4 +- .../app/service/admin/addon/AddonService.php | 35 +- .../service/admin/addon/TerminalService.php | 341 --- .../admin/article/ArticleCategoryService.php | 4 +- .../service/admin/article/ArticleService.php | 2 +- .../app/service/admin/auth/AuthService.php | 8 +- .../service/admin/auth/AuthSiteService.php | 25 +- .../app/service/admin/auth/ConfigService.php | 6 +- .../app/service/admin/auth/LoginService.php | 25 +- .../app/service/admin/channel/H5Service.php | 4 +- .../app/service/admin/cron/CronService.php | 2 +- .../app/service/admin/diy/DiyRouteService.php | 4 +- niucloud/app/service/admin/diy/DiyService.php | 105 +- .../admin/file/StorageConfigService.php | 8 +- .../app/service/admin/file/UploadService.php | 4 +- .../app/service/admin/generator/Generate.php | 2 +- .../admin/generator/GenerateService.php | 2 +- .../admin/generator/core/BaseGenerator.php | 6 +- .../admin/generator/core/WebApiGenerator.php | 2 +- .../admin/generator/vm/admin_api_route.vm | 8 +- .../service/admin/generator/vm/web_edit.vm | 1 - .../service/admin/generator/vm/web_index.vm | 16 +- .../admin/install/InstallDiyService.php | 329 --- .../admin/install/InstallSystemService.php | 13 +- .../admin/member/MemberAccountService.php | 52 +- .../admin/member/MemberCashOutService.php | 28 +- .../admin/member/MemberConfigService.php | 15 + .../admin/member/MemberLabelService.php | 9 +- .../service/admin/member/MemberService.php | 59 +- .../service/admin/notice/NoticeService.php | 18 +- .../app/service/admin/notice/SmsService.php | 8 +- .../admin/order/RechargeOrderService.php | 38 +- .../app/service/admin/order/RefundService.php | 65 +- .../service/admin/pay/PayChannelService.php | 20 +- .../service/admin/site/SiteGroupService.php | 28 +- .../app/service/admin/site/SiteService.php | 80 +- .../service/admin/site/SiteUserService.php | 6 +- .../service/admin/stat/SiteStatService.php | 29 +- .../app/service/admin/stat/StatService.php | 9 +- .../service/admin/sys/AgreementService.php | 4 +- niucloud/app/service/admin/sys/AppService.php | 6 + .../app/service/admin/sys/AreaService.php | 35 +- .../app/service/admin/sys/ConfigService.php | 35 + .../app/service/admin/sys/MenuService.php | 264 ++- .../app/service/admin/sys/RoleService.php | 57 +- .../app/service/admin/sys/SystemService.php | 88 +- .../service/admin/user/UserRoleService.php | 77 +- .../app/service/admin/user/UserService.php | 4 +- .../admin/weapp/WeappTemplateService.php | 20 +- .../admin/wechat/WechatEventService.php | 4 +- .../admin/wechat/WechatTemplateService.php | 13 +- niucloud/app/service/api/diy/DiyService.php | 36 + .../app/service/api/login/AuthService.php | 23 +- .../app/service/api/login/LoginService.php | 18 +- .../app/service/api/login/RegisterService.php | 24 +- .../api/member/MemberCashOutService.php | 6 +- .../app/service/api/member/MemberService.php | 4 +- .../api/order/RechargeOrderService.php | 4 +- niucloud/app/service/api/pay/PayService.php | 6 +- .../service/api/weapp/WeappAuthService.php | 16 +- .../service/api/wechat/WechatAuthService.php | 12 +- .../core/addon/CoreAddonBaseService.php | 14 +- .../core/addon/CoreAddonConfigService.php | 340 --- .../core/addon/CoreAddonInstallService.php | 528 ++++- .../service/core/addon/CoreAddonService.php | 6 +- .../service/core/addon/CoreDependService.php | 8 +- niucloud/app/service/core/addon/WapTrait.php | 292 ++- .../core/aliapp/CoreAliappConfigService.php | 6 +- .../core/captcha/CoreCaptchaService.php | 1 + .../service/core/channel/CoreH5Service.php | 4 +- .../service/core/diy/CoreDiyConfigService.php | 6 +- .../core/member/CoreMemberAccountService.php | 1 + .../core/member/CoreMemberCashOutService.php | 59 +- .../core/member/CoreMemberConfigService.php | 39 +- .../core/member/CoreMemberLabelService.php | 30 +- .../service/core/member/CoreMemberService.php | 48 + .../app/service/core/menu/CoreMenuService.php | 67 +- .../service/core/notice/CoreNoticeService.php | 18 +- .../service/core/notice/CoreSmsService.php | 10 +- .../app/service/core/notice/NoticeService.php | 2 +- .../core/order/CoreOrderCreateService.php | 6 +- .../core/order/CoreOrderRefundService.php | 4 +- .../service/core/order/CoreOrderService.php | 4 +- .../recharge/CoreRechargeOrderService.php | 10 +- .../recharge/CoreRechargeRefundService.php | 32 +- .../core/pay/CorePayChannelService.php | 4 +- .../service/core/pay/CorePayConfigService.php | 64 +- .../service/core/pay/CorePayEventService.php | 39 +- .../app/service/core/pay/CorePayService.php | 341 ++- .../service/core/pay/CoreRefundService.php | 155 +- .../service/core/pay/CoreTransferService.php | 92 +- .../core/paytype/CoreBalanceService.php | 66 +- .../app/service/core/scan/CoreScanService.php | 4 +- .../{cron => schedule}/CoreCronService.php | 55 +- .../core/schedule/CoreScheduleService.php | 47 + .../app/service/core/site/CoreSiteService.php | 73 +- .../service/core/sys/CoreAgreementService.php | 10 +- .../core/sys/CoreAttachmentService.php | 6 +- .../service/core/upload/CoreFileService.php | 4 +- .../core/upload/CoreStorageService.php | 10 +- .../core/upload/CoreUploadConfigService.php | 6 +- .../service/core/upload/CoreUploadService.php | 12 +- .../core/weapp/CoreWeappConfigService.php | 6 +- .../service/core/weapp/CoreWeappService.php | 8 +- .../core/wechat/CoreWechatConfigService.php | 10 +- .../core/wechat/CoreWechatMessageService.php | 26 +- .../core/wechat/CoreWechatReplyService.php | 44 +- niucloud/app/validate/diy/Diy.php | 4 +- niucloud/app/validate/member/CashOut.php | 10 +- .../app/validate/member/CashOutAccount.php | 4 +- niucloud/app/validate/member/Member.php | 14 +- niucloud/app/validate/member/MemberConfig.php | 36 + niucloud/app/validate/message/AliSms.php | 2 +- niucloud/app/validate/pay/Pay.php | 22 +- niucloud/app/validate/pay/PayTemplate.php | 22 +- niucloud/app/validate/site/Site.php | 2 - .../app/validate/sys/AttachmentCategory.php | 4 +- niucloud/app/validate/sys/Menu.php | 8 +- 302 files changed, 7325 insertions(+), 4198 deletions(-) delete mode 100644 niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-info.vue create mode 100644 niucloud/addon/hello_world/app/dict/diy/components.php create mode 100644 niucloud/addon/hello_world/app/dict/diy/links.php create mode 100644 niucloud/addon/hello_world/app/dict/diy/pages.php create mode 100644 niucloud/addon/hello_world/app/dict/diy/template.php create mode 100644 niucloud/addon/hello_world/app/dict/member/account_change_type.php rename niucloud/addon/hello_world/app/{enum => dict}/menu/admin.php (92%) create mode 100644 niucloud/addon/hello_world/app/dict/menu/site.php rename niucloud/addon/hello_world/app/{enum => dict}/notice/notice.php (100%) rename niucloud/addon/hello_world/app/{enum => dict}/notice/sms.php (100%) rename niucloud/addon/hello_world/app/{enum => dict}/notice/weapp.php (100%) rename niucloud/addon/hello_world/app/{enum => dict}/notice/wechat.php (100%) delete mode 100644 niucloud/addon/hello_world/app/enum/diy/components.php delete mode 100644 niucloud/addon/hello_world/app/enum/diy/links.php delete mode 100644 niucloud/addon/hello_world/app/enum/diy/pages.php delete mode 100644 niucloud/addon/hello_world/app/enum/menu/site.php rename niucloud/addon/hello_world/app/lang/zh-cn/{enum.php => dict.php} (67%) delete mode 100644 niucloud/addon/hello_world/config/uni-app-pages.json rename niucloud/addon/hello_world/{config => package}/admin-package.json (100%) rename niucloud/addon/hello_world/{config => package}/composer.json (100%) rename niucloud/addon/hello_world/{config => package}/uni-app-package.json (100%) create mode 100644 niucloud/addon/hello_world/package/uni-app-pages.php rename niucloud/addon/hello_world/{config => package}/web-package.json (100%) create mode 100644 niucloud/addon/hello_world/resource/cover.png delete mode 100644 niucloud/addon/hello_world/uni-app/components/diy/comp-extend/hello-info/index.vue delete mode 100644 niucloud/addon/hello_world/uni-app/components/diy/comp-extend/hello-text/index.vue delete mode 100644 niucloud/addon/hello_world/uni-app/components/diy/comp-extend/index.vue create mode 100644 niucloud/addon/hello_world/uni-app/components/diy/hello-text/index.vue delete mode 100644 niucloud/addon/hello_world/uni-app/pages.json create mode 100644 niucloud/addon/hello_world/uni-app/pages/hello_world/info.vue create mode 100644 niucloud/app/command/Addon/Install.php create mode 100644 niucloud/app/command/Addon/Uninstall.php create mode 100644 niucloud/app/command/Schedule.php rename niucloud/app/{enum/addon/AddonEnum.php => dict/addon/AddonDict.php} (65%) rename niucloud/app/{enum/cash_out/CashOutTypeEnum.php => dict/cash_out/CashOutTypeDict.php} (93%) rename niucloud/app/{enum/channel/CertEnum.php => dict/channel/CertDict.php} (96%) rename niucloud/app/{enum/channel/ReplyEnum.php => dict/channel/ReplyDict.php} (88%) rename niucloud/app/{enum/channel/WechatEnum.php => dict/channel/WechatDict.php} (90%) rename niucloud/app/{enum/common/ChannelEnum.php => dict/common/ChannelDict.php} (72%) create mode 100644 niucloud/app/dict/common/CommonDict.php rename niucloud/app/{enum/diy/ComponentEnum.php => dict/diy/ComponentDict.php} (91%) rename niucloud/app/{enum/diy/LinkEnum.php => dict/diy/LinkDict.php} (66%) create mode 100644 niucloud/app/dict/diy/PagesDict.php rename niucloud/app/{enum/diy/PageEnum.php => dict/diy/TemplateDict.php} (70%) create mode 100644 niucloud/app/dict/member/MemberAccountChangeTypeDict.php create mode 100644 niucloud/app/dict/member/MemberAccountTypeDict.php rename niucloud/app/{enum/member/MemberCashOutEnum.php => dict/member/MemberCashOutDict.php} (71%) rename niucloud/app/{enum/member/MemberEnum.php => dict/member/MemberDict.php} (76%) rename niucloud/app/{enum/member/MemberLoginTypeEnum.php => dict/member/MemberLoginTypeDict.php} (76%) rename niucloud/app/{enum/member/MemberRegisterChannelEnum.php => dict/member/MemberRegisterChannelDict.php} (76%) rename niucloud/app/{enum/member/MemberRegisterTypeEnum.php => dict/member/MemberRegisterTypeDict.php} (73%) create mode 100644 niucloud/app/dict/member/account_change_type.php rename niucloud/app/{enum => dict}/menu/admin.php (88%) rename niucloud/app/{enum => dict}/menu/site.php (92%) rename niucloud/app/{enum/notice/NoticeEnum.php => dict/notice/NoticeDict.php} (60%) rename niucloud/app/{enum/notice/NoticeTypeEnum.php => dict/notice/NoticeTypeDict.php} (78%) rename niucloud/app/{enum => dict}/notice/notice.php (99%) rename niucloud/app/{enum => dict}/notice/sms.php (100%) rename niucloud/app/{enum => dict}/notice/weapp.php (100%) rename niucloud/app/{enum => dict}/notice/wechat.php (100%) rename niucloud/app/{enum/order/OrderRefundEnum.php => dict/order/OrderRefundDict.php} (74%) rename niucloud/app/{enum/order/OrderTypeEnum.php => dict/order/OrderTypeDict.php} (84%) rename niucloud/app/{enum/order/RechargeOrderEnum.php => dict/order/RechargeOrderDict.php} (87%) rename niucloud/app/{enum/pay/OnlinePayEnum.php => dict/pay/OnlinePayDict.php} (97%) rename niucloud/app/{enum/pay/OnlineRefundEnum.php => dict/pay/OnlineRefundDict.php} (97%) rename niucloud/app/{enum/pay/PayChannelEnum.php => dict/pay/PayChannelDict.php} (84%) rename niucloud/app/{enum/pay/PayEnum.php => dict/pay/PayDict.php} (76%) rename niucloud/app/{enum/pay/RefundEnum.php => dict/pay/RefundDict.php} (70%) rename niucloud/app/{enum/pay/TransferEnum.php => dict/pay/TransferDict.php} (77%) rename niucloud/app/{enum/scan/ScanEnum.php => dict/scan/ScanDict.php} (95%) create mode 100644 niucloud/app/dict/schedule/schedule.php rename niucloud/app/{enum/site/SiteEnum.php => dict/site/SiteDict.php} (73%) rename niucloud/app/{enum/sys/AgreementEnum.php => dict/sys/AgreementDict.php} (80%) rename niucloud/app/{enum/sys/AppTypeEnum.php => dict/sys/AppTypeDict.php} (78%) rename niucloud/app/{enum/sys/ConfigKeyEnum.php => dict/sys/ConfigKeyDict.php} (96%) rename niucloud/app/{enum/sys/CronEnum.php => dict/sys/CronDict.php} (72%) rename niucloud/app/{enum/sys/FileEnum.php => dict/sys/FileDict.php} (79%) rename niucloud/app/{enum/sys/MenuEnum.php => dict/sys/MenuDict.php} (81%) rename niucloud/app/{enum/sys/MenuTypeEnum.php => dict/sys/MenuTypeDict.php} (76%) rename niucloud/app/{enum/sys/MethodEnum.php => dict/sys/MethodDict.php} (95%) rename niucloud/app/{enum/sys/RoleStatusEnum.php => dict/sys/RoleStatusDict.php} (81%) rename niucloud/app/{enum/sys/SmsEnum.php => dict/sys/SmsDict.php} (88%) rename niucloud/app/{enum/sys/StorageEnum.php => dict/sys/StorageDict.php} (96%) rename niucloud/app/{enum/sys/UserEnum.php => dict/sys/UserDict.php} (81%) delete mode 100644 niucloud/app/enum/common/CommonEnum.php delete mode 100644 niucloud/app/enum/member/MemberAccountEnum.php delete mode 100644 niucloud/app/enum/member/fromtypes/system.php create mode 100644 niucloud/app/job/schedule/OrderClose.php create mode 100644 niucloud/app/job/schedule/SiteExpireClose.php create mode 100644 niucloud/app/job/sys/AddonInstall.php create mode 100644 niucloud/app/job/sys/CheckDeleteJob.php create mode 100644 niucloud/app/job/sys/CheckJob.php delete mode 100644 niucloud/app/job/sys/Cronexecute.php rename niucloud/app/lang/en/{system => }/api.php (100%) rename niucloud/app/lang/en/{system/enum.php => dict.php} (89%) rename niucloud/app/lang/en/{system => }/validate.php (100%) rename niucloud/app/lang/zh-cn/{enum.php => dict.php} (81%) create mode 100644 niucloud/app/listener/site/AddSiteAfterListener.php delete mode 100644 niucloud/app/service/admin/addon/TerminalService.php delete mode 100644 niucloud/app/service/admin/install/InstallDiyService.php delete mode 100644 niucloud/app/service/core/addon/CoreAddonConfigService.php rename niucloud/app/service/core/{cron => schedule}/CoreCronService.php (75%) create mode 100644 niucloud/app/service/core/schedule/CoreScheduleService.php create mode 100644 niucloud/app/validate/member/MemberConfig.php diff --git a/niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-info.vue b/niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-info.vue deleted file mode 100644 index 430823048..000000000 --- a/niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-info.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-text.vue b/niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-text.vue index fd0f02e60..24c95da0b 100644 --- a/niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-text.vue +++ b/niucloud/addon/hello_world/admin/src/views/diy/components/edit-hello-text.vue @@ -1,12 +1,20 @@ @@ -16,6 +24,7 @@ import useDiyStore from '@/stores/modules/diy' const diyStore = useDiyStore() + diyStore.editComponent.ignore = []; // 忽略公共属性 defineExpose({}) diff --git a/niucloud/addon/hello_world/app/adminapi/controller/Index.php b/niucloud/addon/hello_world/app/adminapi/controller/Index.php index faba9182e..c36ec5e8b 100644 --- a/niucloud/addon/hello_world/app/adminapi/controller/Index.php +++ b/niucloud/addon/hello_world/app/adminapi/controller/Index.php @@ -11,9 +11,8 @@ namespace addon\hello_world\app\adminapi\controller; -use app\adminapi\controller\BaseAdminController; -use app\service\core\addon\CoreInstallService; +use core\base\BaseAdminController; class Index extends BaseAdminController { diff --git a/niucloud/addon/hello_world/app/dict/diy/components.php b/niucloud/addon/hello_world/app/dict/diy/components.php new file mode 100644 index 000000000..d692c14d9 --- /dev/null +++ b/niucloud/addon/hello_world/app/dict/diy/components.php @@ -0,0 +1,21 @@ + [ + 'title' => get_lang('dict_diy.component_type_basic'), + 'list' => [ + 'HelloText' => [ + 'title' => 'hello文本', + 'icon' => 'iconfont-iconhuiyuanzhongxin', + 'path' => 'edit-hello-text', + 'support_page' => [], + 'uses' => 0, + 'sort' => 10007, + 'value' => [ + 'height' => 20 + ], + ], + ], + ], + +]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/dict/diy/links.php b/niucloud/addon/hello_world/app/dict/diy/links.php new file mode 100644 index 000000000..b263522fe --- /dev/null +++ b/niucloud/addon/hello_world/app/dict/diy/links.php @@ -0,0 +1,26 @@ + [ + 'title' => get_lang('dict_diy.system_link'), + 'child_list' => [ + [ + 'name' => 'HELLO_WORLD_INFO', + 'title' => get_lang('dict_diy.hello_world_info'), + 'url' => '/pages/hello_world/info', + 'is_share' => 1 + ], + ] + ], + 'HELLO_WORLD_LINK' => [ + 'title' => get_lang('dict_diy.hello_world_link'), + 'child_list' => [ + [ + 'name' => 'HELLO_WORLD_INDEX', + 'title' => get_lang('dict_diy.hello_world_index'), + 'url' => '/pages/hello_world/index', + 'is_share' => 1 + ], + ] + ], +]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/dict/diy/pages.php b/niucloud/addon/hello_world/app/dict/diy/pages.php new file mode 100644 index 000000000..1492ee40f --- /dev/null +++ b/niucloud/addon/hello_world/app/dict/diy/pages.php @@ -0,0 +1,89 @@ + [ + 'hello_world_index' => [ // 页面标识 + "title" => "hello world 首页", // 页面名称 + 'cover' => '', // 页面封面图 + 'preview' => '', // 页面预览图 + 'desc' => '', // 页面描述 + // 页面数据源 + "data" => [ + "global" => [ + "title" => "hello world首页页面", + "pageBgColor" => "#F8F8F8", + 'bgUrl' => '', + 'imgWidth' => '', + 'imgHeight' => '', + "bottomTabBarSwitch" => true, + "template" => [ + 'textColor' => "#303133", + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 0 + ] + ], + 'topStatusBar' => [ + 'bgColor' => "#ffffff", + 'isTransparent' => false, + 'isShow' => true, + 'style' => 'style-1', + 'textColor' => "#333333", + 'textAlign' => 'center', + ], + 'popWindow' => [ + 'imgUrl' => "", + 'imgWidth' => '', + 'imgHeight' => '', + 'count' => -1, + 'show' => 0, + 'link' => [ + 'name' => "" + ], + ] + ], + "value" => [ + [ + "path" => "edit-image-ads", + "id" => "4640ld4k1pu0", + "componentName" => "ImageAds", + "componentTitle" => "图片广告", + "uses" => 0, + "list" => [ + [ + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/banner.png", + "imgWidth" => 750, + "imgHeight" => 320, + "id" => "2xuytp7622w0" + ] + ], + "ignore" => [], + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 0 + ] + ] + ] + ] + ] + ] +]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/dict/diy/template.php b/niucloud/addon/hello_world/app/dict/diy/template.php new file mode 100644 index 000000000..98a006df6 --- /dev/null +++ b/niucloud/addon/hello_world/app/dict/diy/template.php @@ -0,0 +1,12 @@ + [ + 'title' => get_lang('dict_diy.page_hello_world_index'), + 'page' => 'pages/hello_world/index', + ], + 'DIY_HELLO_WORLD_INFO' => [ + 'title' => get_lang('dict_diy.page_hello_world_info'), + 'page' => 'pages/hello_world/info', + ], +]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/dict/member/account_change_type.php b/niucloud/addon/hello_world/app/dict/member/account_change_type.php new file mode 100644 index 000000000..6898597fb --- /dev/null +++ b/niucloud/addon/hello_world/app/dict/member/account_change_type.php @@ -0,0 +1,18 @@ + [ + //调整 + 'hello_world_test' => [ + //名称 + 'name' => "hello_world账户变化", + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 1, + ], + + ], +]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/enum/menu/admin.php b/niucloud/addon/hello_world/app/dict/menu/admin.php similarity index 92% rename from niucloud/addon/hello_world/app/enum/menu/admin.php rename to niucloud/addon/hello_world/app/dict/menu/admin.php index 046772870..0bd05e0ce 100644 --- a/niucloud/addon/hello_world/app/enum/menu/admin.php +++ b/niucloud/addon/hello_world/app/dict/menu/admin.php @@ -13,6 +13,5 @@ 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/dict/menu/site.php b/niucloud/addon/hello_world/app/dict/menu/site.php new file mode 100644 index 000000000..23fe8c50c --- /dev/null +++ b/niucloud/addon/hello_world/app/dict/menu/site.php @@ -0,0 +1,36 @@ + '插件站点菜单', + 'menu_key' => 'niucloud_site_hello', + 'menu_type' => 1, + 'icon' => 'iconfont-iconyingyongshichang', + 'api_url' => '', + 'router_path' => 'hello_world', + 'view_path' => 'hello_world/site', + 'methods' => '', + 'sort' => 90, + 'status' => 1, + 'is_show' => 1, + ], +/* [ + 'menu_name' => '会员列表', + 'menu_key' => 'member_list', + 'parent_key' => 'member', + 'menu_type' => 1, + 'icon' => 'iconfont-iconhuiyuanliebiao', + 'api_url' => 'member/member', + 'router_path' => 'hello_world_member_list', + 'view_path' => 'hello_world/member', + 'methods' => 'get', + 'sort' => 100, + 'status' => 1, + 'is_show' => 1, + 'children' => [ + + ] + ], + "delete" => "member" //针对修改系统菜单处理方式,可以删除系统菜单,设置对应key值,也可删除不需要的菜单处理 +*/ + ]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/enum/notice/notice.php b/niucloud/addon/hello_world/app/dict/notice/notice.php similarity index 100% rename from niucloud/addon/hello_world/app/enum/notice/notice.php rename to niucloud/addon/hello_world/app/dict/notice/notice.php diff --git a/niucloud/addon/hello_world/app/enum/notice/sms.php b/niucloud/addon/hello_world/app/dict/notice/sms.php similarity index 100% rename from niucloud/addon/hello_world/app/enum/notice/sms.php rename to niucloud/addon/hello_world/app/dict/notice/sms.php diff --git a/niucloud/addon/hello_world/app/enum/notice/weapp.php b/niucloud/addon/hello_world/app/dict/notice/weapp.php similarity index 100% rename from niucloud/addon/hello_world/app/enum/notice/weapp.php rename to niucloud/addon/hello_world/app/dict/notice/weapp.php diff --git a/niucloud/addon/hello_world/app/enum/notice/wechat.php b/niucloud/addon/hello_world/app/dict/notice/wechat.php similarity index 100% rename from niucloud/addon/hello_world/app/enum/notice/wechat.php rename to niucloud/addon/hello_world/app/dict/notice/wechat.php diff --git a/niucloud/addon/hello_world/app/enum/diy/components.php b/niucloud/addon/hello_world/app/enum/diy/components.php deleted file mode 100644 index 8a6eb19c7..000000000 --- a/niucloud/addon/hello_world/app/enum/diy/components.php +++ /dev/null @@ -1,32 +0,0 @@ - [ - 'title' => get_lang('enum_diy.component_type_basics'), - 'list' => [ - 'TestInfo' => [ - 'title' => '测试信息', - 'icon' => 'iconfont-iconhuiyuanzhongxin', - 'path' => 'edit-hello-info', - 'support_page' => [], - 'max_count' => 0, - 'sort' => 10007, - 'value' => [ - 'height' => 20 - ], - ], - 'TestText' => [ - 'title' => '测试文本', - 'icon' => 'iconfont-iconhuiyuanzhongxin', - 'path' => 'edit-hello-text', - 'support_page' => [], - 'max_count' => 0, - 'sort' => 10007, - 'value' => [ - 'height' => 20 - ], - ], - ], - ], - -]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/enum/diy/links.php b/niucloud/addon/hello_world/app/enum/diy/links.php deleted file mode 100644 index fc96d30db..000000000 --- a/niucloud/addon/hello_world/app/enum/diy/links.php +++ /dev/null @@ -1,8 +0,0 @@ - 'HELLO_WORLD_INDEX', - 'title' => get_lang('enum_hello_world.links_hello_world_index'), - ], -]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/enum/diy/pages.php b/niucloud/addon/hello_world/app/enum/diy/pages.php deleted file mode 100644 index 6dd355233..000000000 --- a/niucloud/addon/hello_world/app/enum/diy/pages.php +++ /dev/null @@ -1,4 +0,0 @@ - '插件站点菜单', - 'menu_key' => 'niucloud_site_hello', - 'menu_type' => 1, - 'icon' => 'iconfont-iconyingyongshichang', - 'api_url' => '', - 'router_path' => 'hello_world', - 'view_path' => 'hello_world/site', - 'methods' => '', - 'sort' => 90, - 'status' => 1, - 'is_show' => 1, - 'en_menu_name' => '', - ], - ]; \ No newline at end of file diff --git a/niucloud/addon/hello_world/app/lang/zh-cn/enum.php b/niucloud/addon/hello_world/app/lang/zh-cn/dict.php similarity index 67% rename from niucloud/addon/hello_world/app/lang/zh-cn/enum.php rename to niucloud/addon/hello_world/app/lang/zh-cn/dict.php index 63dcc4b3d..b05f981a5 100644 --- a/niucloud/addon/hello_world/app/lang/zh-cn/enum.php +++ b/niucloud/addon/hello_world/app/lang/zh-cn/dict.php @@ -13,8 +13,11 @@ * 插件枚举语言 */ return [ - 'enum_hello_world' => [ - //菜单类型 - 'links_hello_world_index' => 'hello world 插件', - ], + 'dict_diy' => [ + 'page_hello_world_index' => 'hello 首页', + 'page_hello_world_info' => 'hello 信息', + 'hello_world_link' => 'hello world链接', + 'hello_world_index' => 'hello world index 插件', + 'hello_world_info' => 'hello world info 插件' + ] ]; diff --git a/niucloud/addon/hello_world/config/uni-app-pages.json b/niucloud/addon/hello_world/config/uni-app-pages.json deleted file mode 100644 index fca712b6e..000000000 --- a/niucloud/addon/hello_world/config/uni-app-pages.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pages": [ // pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages - { - "path": "pages/hello_world/index", - "style": { - // #ifdef H5 - "navigationStyle": "custom", - // #endif - "navigationBarTitleText": "%pages.index.index%" - } - } - ] - -} \ No newline at end of file diff --git a/niucloud/addon/hello_world/config/admin-package.json b/niucloud/addon/hello_world/package/admin-package.json similarity index 100% rename from niucloud/addon/hello_world/config/admin-package.json rename to niucloud/addon/hello_world/package/admin-package.json diff --git a/niucloud/addon/hello_world/config/composer.json b/niucloud/addon/hello_world/package/composer.json similarity index 100% rename from niucloud/addon/hello_world/config/composer.json rename to niucloud/addon/hello_world/package/composer.json diff --git a/niucloud/addon/hello_world/config/uni-app-package.json b/niucloud/addon/hello_world/package/uni-app-package.json similarity index 100% rename from niucloud/addon/hello_world/config/uni-app-package.json rename to niucloud/addon/hello_world/package/uni-app-package.json diff --git a/niucloud/addon/hello_world/package/uni-app-pages.php b/niucloud/addon/hello_world/package/uni-app-pages.php new file mode 100644 index 000000000..c7c079162 --- /dev/null +++ b/niucloud/addon/hello_world/package/uni-app-pages.php @@ -0,0 +1,25 @@ + <<8jP)J00001b5ch_0Itp) z=>PyA07*naRCr$Oy$P@-*;yX=W#0AeuU_p{-PL>bs@5)ngal|`KoT&v!HmJiHW(8# zf$)S3^Rin#ugYY2#_VAwbfF0SGT&Wx~r~4BisGX?t zx0}2?f0QfFQ)jMOBeXL&HqhYADA2Vl6*iXCcXiVksnyS`?Z(fU9Jz7~| zW8hn}MQsb13*RuyXGQZLw6+SifVa$|b>(S4d*ok(g)7syP72E5Wf&#-zuKt^%P($g z$WHQ4O+hb9#)ZnsO7^YV(*~7v>n?d^j8}?Q_b$ZkgRDkt9O-Aq{s$mMmZj`3GWwnX zS;GIO2~rG^rSxowO#D;d(*dHmRk#LZo#pKnd#EyzqzuNGXS@gF{Z!G^(oMSerg-V- z-i!TKDIwATqKdFrF@AeU@(iphf51Yi05o|9UPNTen0f$XaoSN09DKym*S4xLss;|M zrb^%!R*sh$1(Y4k!h%3fz`Ed__H-)$EC^tJivWkQg9evGh;i~`rlm_sFa@KZTw$ST@37U19k6P05gMmVd-y=a95%tz21gtfC;vgHF@ z1#JcVUgU=;45f_n0gtM`X$N`Vw32!OFfK`C{Y-1<~@U5-^^fkY%%v&@v+AF}EK zENa|uMoBoR{jK!1hw zK}jQq$RH#TsRR`SBnHSZWB?+Hx}rRny!po`hk<-!QCGB32qXgbM{bTr$rAvMMqrrZ z&oW})#@~>UO0)q)B_k{EY#0LzU{+>V{(q^1XJYL!yfxJop0yIl?1R)5fo1I*a46)W zCHt^|(Mo_51P2O$L*dRG6KJr3h0#Y*e!l)92}BKWXbojS4@*zb#q=snYFGle1upQV z$f-oK3{l)ct8)T~VnbzO6e3g@52jDImJsOoD`&cF>&xmL@x=%d!5+iX`KP+o1|-~(U& zF$)3?9`2uiWS69xTrgF+b*HiywJ2bmoMl?bY9>~bSyr~k#~@s$RmC&|nCMtk7NauL z^7fBU>fmEm)$`?F5u^4saB~Jo9rh$~C}a}6eKy|;Xfq`#D3jWmFCkq`?4j#DVf&b-_2QG~uI|vRS==T6|V;XUDM&vDBDV0p3vfmX* zBg+Ezh}nu#kXG5;5fjvGV`VMlF0ZmemB7yv!t;-kGJ5mD|JpK>DcHS!G#fzBtGzDV zV@Emjs+2l-_e>Q-tY&=Gq{z2$s>%&nY#uff0I>2CHcI>QgXwQ^2;&Q=zi0&qt+PGa zIaJi4Ux&<@V79(tu{GeL$06fa0vswByUByiQgXY(hYw`gxh9s41AkXKQu#*tb5wvj z-;$}`s|5?KsKJUt+6f%vu?qSdA#TnBQPVT$h6F;`K;%>zhBpQW3(`A-g9q}^AOJxi zC2maFKuR>UQnHZi0q<{RK5mVf%U!6xxamM4aL<;`;5f=CuHfZh{-Xc}H;(}zs+g<; zEh?E%Ni#=F^kQ2YTY75x5zahoI$-7tVdi=lgprw-W)vU{vZumHBS)Ea10#QV6mJY); zB@j&NV0&V4^+n2zClzpDuAD*&VMryKo#WgSqoi?_l7#}!qVstcxKDM%Brk#cX3yMg zFZJvtZ@%H*tYBc2DG&gn9<#sMDvKbobR~EQ=wog05WpBKftGLDZgt?`IdKFs`&-69 zGN8Sjj|LJK4{$Kotuv!Os^i_i-r9?~zQ!&kpuxljHh&KX4S9BL9zx5;EdQ>2oQumE zNzx#}Q6aS~a>Mkjc~yqNJqv6gIA&-fW^o!kWm!g)q{`qb3~l=$Y#>;i2s<_eS7ng> zLmSQR3Ei_oG!t>{NF~SckG(e^tx0njstd2I-A)j=55sp+t@{5wfr2^%6TSK1UvZ|o ze4<`{@Zhx1Php)gr~nVOfrF2jxa|r67XgdCdc3Ovh?ii6GSFP{o_+;^qyPdC&?Y|e zqmFHjco8=XI24@p>i`EE1jq?n5Q_7X>7$lFXaFIl4+2D_5=M0tc6gjzHA+U1br_rrO}4ewjh1 z?tP0SIU2(+I43%Xf`G9I_4N+`AvXm$6pHR$Oe*?r41wFe0=B77puVZ`;=z1f7L0P3 zxy#$-?;LNg01kf8P)(S0ih>RX02Xr?%E!@2NeP+QT!W}$a#+?6&$|+iS87fVYCDenH1RUiECU@ZnvG~oktBV@yLw#xE1`PqY8%Tc8ecu8Hv>2@h8(hYWg;VO zIB*b|3iztEHoR&I4%+klF)wY9@ZPG5e$)XCEHlegN?qLD%M$0NwWy4|+C-}Tocm@JOp1MX<3VV5PHjv{VX{v# z{WHIFYv{XUGZ?y7w-zM7&p zAN-Nh?NTj5uVw&+gwaE3D!nYc^HSA@at0VirYhM{SyS9n1UsyvU ziV(-LzN&>-4GKcSJO=>>wl1s2I&krhtgfgU4>8Jt<(r(Ylm>Yiy5A8qoKbp5YLCDn zw`$ab;&$agMg?fdmsDUo;SQ+C$o~|rICro5iJjf%vNcg+(@?|BP!UP?rMx~rK;ciL zjM|eTO|}eHZ5-Jdc%VuMI7mQ2Dhw`pa3fQa?E@K3Hrj_p1WR5|KA4q!9ssC<>?88M zlyx#}6!Zz)%SKr*zp9~rn}dczCED-u>$RpTbt!dmrWmcWo1SwH- zlcX7b<{fw7;d>9^PoG)FN56apOB;Q(8ga#`xT^nQ4ByKT+?5l=kOLNfP&s?Ba|kTo zH%I=gMxPV|^o>{rkn=4YimzaX8N6GH4H*1=EtWDkrR9K1#9S`Z;RZK|l#&QT0>PyaLIR<{gS-=izy){T zY<7;J**+?y7Dl~ZwS*oQ>(p3ugscP-`Eh0rBmuT0m5k|SkthVvud0Sy@5fzUt;$W< zHEPDnd|m*t|G*)?A?r&Xs+gxsknP`LB&(v1pwoDc6Wb4{j12f&ub9OHCuYz+b^t3$ zgx~+lRebiDB@B~{sWqHTo{25*uM1iV$bX(G1To~mjS?_kBdaTd+F9IdIiRW-&*{0S zZKaHIY{0<}Cg`bwE5tPW=fi5hm8p`|m)jLEAW$xa$gkk4f$=TzQGh|<+LYBP=I75B z1{!RSgj~@=ia{VCP1cYlyV`+4$^WJLLPVvMw{!}Z&4>b1bx!c$RLX`zk69+yuffcH zprH~-$hKCp5}ts9M}>y3zWLIGnrp$^=W&!#HkkWee&9p~Cd&bc{Ra^aw;~Uqv@&A6|63$-PM57TQX6dW? zzMoQufN}9oS9QLTfdj(?0b>$q%o!=wk?u%Q{EbSsTeg(F;(Z@TaGnVav^U`3TSp#= zfz^KFhlv%uK&u3v);(Ez((9HK?K%5-xJg6R92f@gO@cKMANB+dz(0 znQSlh>?LmqpQ>#9{v;T8w~SU=0OHmM4@UR-A90CSE{kjDlZpTPS zbV--*G@F<@Hji{_0-t$i86W@ZRjh0c&}zm8E35)Fc|z`AOZCeMQqu&ERi*T)Xj=uA zU$?EYSpTWo!_ZxD;u&Q1s028u*U#1^DW69RA!Sdju*XG!B46)y94c=6fd6N!eB_(lSIrjqdC>Z^zj8O4}d@T$`yS1xf>vx ziDrXh>YGro99;eR0}g>Z&;vr4q^E$9+K7230N@ zxmI8BCdKS74KT@oFsyV~emIcOK%fXTRC=Vy%AECAZ2vIA6a`8QLjYmD+5_oENTFja zDx|vNH2c>O1|aHzhl<8jh?9dv)s+OKoLRae?P~B)QJzEW9oA4VZ~1ZZjWcb!PAkH% z{p4LZd8CWYr9NIbw~3|2KA0X;5Vr2Y8FUZN;pr>e`28u5UsV}OT-==TgB0vKX`QtXbD0W<;--FA#$|H->>{6L$VFee$V zUg_ca=eM!7HDuC=EX@#iT1>5xOm^{^r#6h^T=yNPlz zVbop7>C56^h|1-}`6Le|&&&~F(Y38M)L~k6(#l##$x|U33t3*8b=FEvF$(2_z`I{V>Dj zYdt)BVFw#K33KVBO&fQcm_2>~!)_a&IkSY%Jhh1J-jD^M%ANQE7=B%k1w9td7ZDdS2Utg#ig6d0zEF=O+Hfkc-@Ek7A9zZ2 zFjr;qxCM=gY@2tw4OnKq_toiKZQ3f7|S$^FxQFk-@IxbojAfU1r8i& z;qJR8F;6Ougm$NpNW>9(y9v%-+{O88J+9Uefp0srq}G_n)$IhIeC#UDTwG^0D78jV z-vTy8KslAbv1nxnlsziI2?Y*j`LW~ZV(}5L5uq4AV;EJv#w!y8XvV)s;NV$mxs#@> zLX5LL+5MiLhyPQCTTHvRLkDpgGWBv^`D9Mk|zE1<)9K>Ou>4($%bIFJPvkg?nkq zh@G#uHuq4801y?-+O6PQO=S^&tTINT3Os}?8*Kh>Xq|oHz*DSkR~ajMuZc` zCUEzuE;?-;A#L`s0kjEhu#u1vtn_wg80es${-J1VZEn2mE$;->! zdkG<&`{vXV(h^@9LjvK85JHqhQBE;x<;1>F@w83}JApM`83YUhm=QOS@R# zm1>O)&51TsYxLVKeCEs|zWB^CdV@3{J0f%&1dLJTyn9z)H7E(*ra|i>q(0qH#@i+5 zcbTL+b}n!*D2xIRA`R!E0kI|&vkd?aF4HfSHsr~lY*QI9$xWeG%_CNVXP<{+f=cr2 zRZWdb(#r_6c;`w1oVhPjLlmng@{C%Jtt*A_m67w1FqwOyszcOJAbKd4Nbt6rpu|i| zl81z@^Qgm4YxBg~8S1siLz_mav6u;ux3p22JzuutZ3_bs6xmGui<*4!*)_5Q9$uA& zSf!ILEgjMgOZ~dtm`Wy63LXN8dk~W-WA^1>qTnqP~nqYsC(5@9mmJzVqOYqF49?mWHFi7|sp_%H;O)?;HWpjW} zef28NUfN{u_)VVy3uz>&LqNISg&Z*dfgq%E9R>p@AU5tH@vw1&*YUTC=Zo(yLuMeb zU?13N?KvuBzIz1@p8RD5N`YmgK@xm;cV2CR<&hn@gKAV%OVXe?VV>b>rdR(XbUVAsX2v5}g9=8U7=S4F1d;=59BOgM zS{100N6Y0lY&@lucDMHasWo_eP8_}em7mHQjcG)2n>6N}xG~G21Zg@1vOdye8_94D zNq-5$-ZdnHC8WbG1}F$jL?}}h`*@W*@D;!J3>@+VBkcZ!VlYx)>fmVuA|_BcG1b72 zKRVBbo&g9Z49YtX#`KqHuci_08d=r#g%p1(J~}< z12aeF&^|DYCoity(_g=i<@G+3MwG72+G;9a|2*q60F;ahZuX+C$hB0olc_Pv+!;OM zdyDmprR`(9UOx{d^6-$<9R9VrxXH-vVYV~McdmU#ArFuYT=vD9>b!ww2s6k7BBzbw zN^0E?_x-5En-MtGRrkctxxFzGMP3u`U=>LzJc8YvVW#K!Z;q<_I+xrFB&v)rH4xxk zamU0%`^>(G1T#;0w=(ME=cE7Rz{C9~CveB17I)bkiv3R#j0AXL zv5zON?qaQ%qQSg1GBhVUm_Km3RT^3&?hLGSu zx7)*LiguVY2KuMnpCSNRTiRfcaLs-1vQ;~~U*zws6YJzI-noE6{8nB%6==ayAK0tH z0zNsF1AD;R;7TY;@AGiiz3dae2Mj~2@ij=X5q>)d1}A{g~Rh z$5s?&k3RHRa|hu@i56{9u1G(6mP6yRWaM3^=X z0l*QKqW~ z@G#6=9ED=EAb7q32+Sp_^4V8wmw^h6EEL4hkKCaV<&*6Lw||hIfIU1?+8~*vXIs~4 zk1zWk^XG~jcX|7S3ThM^edrBOXH5D)OOk;ECOlW)`8)BO7?=enczW98NwSIl)^iwa zpF@`RNqOuvql(a%Gy7^nQc-?wdj-3^`rsje*+%5Hnc?2~Hh$!x86+v?$snvy7=Y*t zAVJfk)fy+H2_@SNbuN|9xiQ?n1Z8`sM)~Wu{pHn zC-KDjHT>CAi&)(raJ7bqu=xpjz-D;a)fEA4WSuLYD*_O%3W9Q&ywCy!zMxP!GOG}P zpQM^ia=-|$*As%;0pL7I5z{xwzN|~uljG%~b{mrE3r1}XYr$L;h;>8SZL_WdW?HbG z&6bwZORuOw^u-G*%Gx33tw73P6jyLFrdzMAZLu!FvT=YBc(j9i7urmMp{y|}%@9ly@%Um7YrTxAJ?L(Y)^rC4ZaaW& z#0*3{`NAq|gB=pPZr`gJaxn1@k~sJXNZ^JJ1UNKau3$}q2hDp0leNHu(GKHOXdw@= zbTj~wYsmo!p)nj(Gs=O31%3n=F={Tc);6HLRYft#$PvJtu18ygcxSF~I{6FV>l`!n z!?Xf+X*@RP%}i~9fD%Aaz@$vD;5I@RZA%bXI!h{{dmf_NaKVC=rvTLOw$V%5O_ixr z`##ndxc6#V2M>1eL-$W(kaAlS1|ZCT1QIe}OGqSa zwFZ{~F_lM};mC9YuRPkt(P_H=SK3E#>af|%@Rh|Lo?9JYKmdj2I*Ks4Fpb$`b9iaB zhtGWNIxa13p%GI^>~Vkx-zE&$m_ch{JY^RH8o{7QjUnud6|a@d(_p?D1mxRgpQxSp zoIYDn!sTC2D62bHWP;W!&G-rB<9{#^fsPCmi4%YN7=*$F$}YS3g%Xu z`MJcnF7pgX?`acB4_1Ay0 zaJ5E|1~Tw8U%8Znqz*R+I4Bkp0ZjrB64fd7g=R{{;K4kxJ8LY*51oD)z`^F4xwA)}Z=$wkxiyF8i zy!r7md{?^R1rnkZ(>>G3S0Je1nZ!#CB#Lb%%=Biv2LoUDYMvr!I#pryQjZ1}YSvLn zr1qNNR%?&jpV0QDh(7qbuQPc!w}Ie5!j?90)rPi_C;$&aB4MdGh`9|`u)FaDvSdfd zfjvuXoZumdk(CeFeyS|oEk;s@S0C=+`|srv2%3foLw8M50>-zfUm1Y|Zd^&8ngk@I z4HGx8)M^bXYpNCF6^Gimf4;@w8%Z(x>YfMdIsx@-kCkU(sEXtsD5CGJIm`O1Ru}C-C~bjP+K}Iiyp^WIxq&x}lm$xi&V2~LsqssuPicaE0wv>RvsF;n3r_C%$ zmNE5(y*8_uYQX-NMT{_qbzw_YYwNwQ(YJa98>w$b9d#O)A&R>MARcGRi5z&y*+fVn zp*=DzpkYcMObG==lo+m~xA7#hbQdsVMg%bovr`q!BZ!d|mscM+4CBoMDV z+QkR%o}JO86&NcLo0-c4BE(sSoea2<0^8ySa4GU+uAofqLEao0j!ic4 z+QS_du!?LcdTE9s#jlSdtoDXDv((4Mjf4Rcwhp2Q(}!j-dvq2rF7M*=PhQ8h8#_#` zVT;y_nXn$^fQA3EOC1E;G*8YhyNZBD%eY|6v^B_eu^2q4V$GAei6x4>Hw#- zo*DI3fQkI;JToug?FCF<+b`sBh5`>pcxtx~;y3Goh)F~7ABsOU=A$-Ps8Mzueps4z z+;xt-ys>qZ7gRMTbf}G*XiwdX=mW3)st}MFl7|v$gsr;JZlC2U4j>(@p|^R4MYQB6 z9QT}2HK?~5c&KQPcOu+AQ(T7(Z#>q;`|g@TKjH970tgo4K^RkV=|jZhaR{jdr6sAs zS_&+u83PBVcv70S5=f!6_sq5M@WBoyn=y9MjHyA$Zi1v3SGN*8v)sq>4!P)(crrt? z)8uN6=`Nmleie^DyNsP)!ed7SfwhV`ec6EnC+t3ngT?4Yf>u)t(fnQl;;HJkr~iVB z%QsprQtjy=V2;@2exgw*aqzTB0}5()m83zV9J451hC~l`o8%bfMxn4OtB2*MFWvZ> z)YCI3&dENHHS&2}M(mducz}pX=-L<{5{y7sf6F6|&JT`|JzI0{@&tKl)>XgEe*Z~_U2tWpaG#pRURyuJ^i68Vu6m!sbsYQfJS^8gSRB%fQNkgFTM5fP({g6wZ)^ zxLc7QVJw?a-)hj$iq=X2${2}&mek=gP0@bUf!vXuFE~GdZ~%jq$aAx$#jK4s3Qk^x zHFAueU8biug8E)izI>cpLrNOqvy%|!QfY)fJE>HBg6AoKR#eqh`F^i;>@~mBz~Hf| z?AX2}DC;d@fM)wBn(gB}9@Gb3`(?wu;|lxb`U40m6`VD}|; zl>6q7?@$lSxRXOn{VgXZ@b*)aOoc&*`)P_hKx9}*6cl)1&$zp+WG?zvl8gn5+DL&* zDgVn=8rn932#X9*b*S6Gg9lq!m}oFb1l^&*LP$iwMlZ#=l>x494!K%`8$n?9$PA{B z%;3ev9enxBB9_;Bj#?vNquo@gLow^}N*zS2udUls%g57Ccw!{4-L@ZDb~L#it0B~ zn;B~p-3rhk2S)P30@X<_xKj>2@OsJsMV{fy4Eb==*32q~u1nY7Jb5jNgyD8sA-2s5(w)PJU0RKVNWb^)bdBock_Y4m|8mGD3jg81X>e!ipbMI^nurWk=sDz z)D}7}1b6Awu_8=^%5nos8GyX)?&M#H@`xceu4CmRZypX*74 zmxdY0>V)308D^#~oFI_ug7*E%nHKJuZ=u_an1Lm=hk0wHz|u~F7gh&Y?HOu~ZVL-1 z=MhhK@Z|F=ICE|Vy?%-Y^VX>NysT0OJr`byyUW z3ICA9LJ(YOHy{q9c0Ob5-Zy8t! z#McquRtiw7*c-590R{pJvxFk)L*d0#nkM*pb}>`;R^=2@gabH0G5Ti!2@?P*<6To) zky~S;90?>$KmlOTN|t8#cEpWo1(~Doea+{E z8>a>lW>iWSJaB7$6HFKq2Ia+J$A&QNCa9Mwi&`mTM3hn+MTG5m;e1AtIs|U^AoW!q$Qk_ImI#Oe=D@%Nto%i@2{b5FsCa9!R3D=?o|QILVvJ1J zDt2Vv++D5@*;c)s)xc|hT?07y3^-kYqG+iBqAItr9|(BuE;I__r3Nj7df=d1>M1&8 zp6H8=AcY;0H3SwKZ~`#p7~+1USQENqYRt<3@@z>vA8{C22|wA#X@2qoyGK_X}oxS8;?J; zgw>5cbNSQ^+GXA$;4fe^j{qFZ?Z+ZZGG=Il1PeHbS3C(<98tbj%ds2O1_+vg`+$Rd z=A2;pJo5SA@*`U&Zu2AAD3ib1I&j`x!-UZ{oF-2%0S+37$n_=&hr7|d)2bh8T;T2> zS&(i}!0eYG3x95}T1w-DJlPOZpxg^Lpp!FKe0v#fa6}75uPiBodFn3_JNTp)J|LmN zL%CXmcbT`{DqH*@&kJt<5H>^gxLDmX>!#nE6k&wg0=mCHr3O?yLXwDq2U1}$iMIw2 zpA|L`S^^>CAZtkjKd)Mn3CnHM1q@RCVaJS6(hL@}pvNxZ$};i?QqpVea*`1v1(BL%?iJz|NXu|i+eUDvWBgO<4Wag+;8P5Q zL}-f0))$5u&JMxcKiSAw_iOOGHRy9>x`o?kn`k$gJH%D4(-vbn!kVz<<+-Vm76Dd1O!Z%LpGMCZbL{QTyG0X z*Xn@TstC~q|04Oic&<*@;uWXCdFCr!bS1%-Jz=&hV(>Wg_2|51dxaOaOeg<(sYC#9 zFh^4liRavIB{YD5msaPc5M}KwUI|5S{LjmPgE>AnGuCD0p1WMTEJ9=fBbN2bHIc&z z&I1=v`aC7^LbZw=;)58oG6XC6)3@tgXBn&}7g1`f*G!9Sk=t%@5 z*zKShx0SfQHN>^e1brr=;CFLO9hk(ylk-^JP4Km6mT+Zpo4KBbg~Sfn5J79e1udSf zDGUx-anj>Of&c{^#GEPH2rYFWH3t1t@XZ1bLi%Df!zVIlhOv^t2;#25gNYn8qEH=? z_n=6fHa}rXa8l&GV1OvkrCFw(M}5%Xxi3cbKM$J9LRWiNL7|ae!I~*dZ>)vf@!emR zFUXY6>T$(1L4zxOP`{l(PM&53fd$8lg3|yIrKdC}V#C z`&zWS784DbW2eB-mK3*R?|B7D}q=T)CJY#_{tl-h_g z4<59HLEA(KMq-7y_FWII4Js+H)L`eL$A;OYz7@bCHw?ELcyQY9EPM(*{k?Zj;gLff z7Rs77YC9q+M8u>KEarpYG|KKl@CYVhkZyiLs3f1U091xlf`f>R*+vlWdu|APK}Zq! zX_t$^nH)-ZYmn4ox*g->OcT@Hm;noFFG(UO-S!~E)r}zo3<5_WZZ>e>IH@(JaPi6( zo_g*EHn#?bG@|Z&7Kt9K%gJp|XY3m+JhkNh@`6i=DhxG+2@sf_2heT{R~gwn21IP; zZJvI0TeL`mO{<{dlvNURE+pnTe5X?rc#!cN%~N3<2cN{j92i4=Q3xEY^zI?VLQ3Lg z9x}019(#&%X}F#nqgMZpugg#j(3Qgy0=)Yvtj(a^Idb!u;iApSw4+G!8O_bLEX*g7 zP!;oq;{yXy!jWrZP8#8lI%!r*k_WPXDF1{q#L#qdIn_&FFSXgD(R1E(U@)$xhQNrZ zfoAKlb)%qCVSLXk|3sWYC9`KNL{K*AzA2yCA+5azmAM-|xxEDG%q>ZTh%+(lT}GO0 z`PCRfC(hypaI4un_<}DHL;m1BQ!F+EeJ5K4rb!^?Eu;}VVuJt+26&)kF*Ca3Iw@{M zNzcqU5)re5U^WpXwaCCcJ+39d$9nvHB|(F{E}TWO6yBTi`+JB;Vsou4g(Ov zt%YA?Zg?L^$%M%tITvKp*ltHWv^C4dpIP-9r+oF?WT1xBL7g@k9T%w`mprw~l}imz zmy%(ukFFc-@kWOpAhE7mL3;r+qWMZOF*W%!i}48|4F#Y+&X3@Jc!Cv6AacCw1!f0T82H z`r0G)1;qfgJ^}mJSr?`JswM~wt$nmM7qxV>S_}I<=Hg1nccho(x;cqPb52nSKBZ#E zzyFn=%6VaMG;9J2DW-NM545!Ms)|zAPNnWhxF^7H9ZCOs-k7qIag;CSZwBx{Js`Ef z_uVsv(+9W&fl;1v3O&LN7Sq$7D4lG@4isrpjc8&st9fzsrX?5aFEgkSx2)Kp-G}5 z!AEs-^MR&v(g8u7Sy?px48>7sadDDV#M|hRscRSS**cNi)Zw#kpVVsyI7r5y0}jEU zfddDDtqgYIQKgt==5T>;_WX7eIwWL5?MUE2!zPFRR#Oz(kEgv z^jd~@jjTq2O{2k<(WY6iv5wSN%d{$U1DgN!F#E3OF9`yc(J;f28^4c6TlLK>j~g}ivF2t3$9r45@LqlAwrL^$;ZValG{UbmjAQ?YkbAw9el_4Y$7YIP~g#^M- zU1;fp^wQvQA;c`Q?-R`kN2Z&YYRAmLk^=^QdfpwTSlUXkzMHbN#NZn31{RLbVrpRu zFJ9TiH_okKduNz4vg9kYfRR|cDW4|yB(R)TTSyNCa4?&|qzY_6Im6=L`4>`Sbh?85 z3ht@Wt8SR@J=})|)s#A@B))qI3?oWm7)SfZGHO%y8a6}ceG(%i0gs_3F(`u}H8AP0 z-$TL#MjAl)P=Y8nKS{jDx@q0`7(+Jd z@k)t!BK|Q?{3fsw8SP}ejV_SU;G#mU;erSQJor>D2^n6K<#oXLdJ+}vX>ZD!tiOsc z`0E%QVC(^#6g9P0k1Gj;1`ZrZaFs(IP}rbAr_&*= zIlHmrKNP!m4ttB@qAi1ptFfwDBxT^CUf$fossJLDY^)N5L05qf2)Z^9U%W!$2T{ z{?T`NxfT<~tB8~wR7mi^V?uB{i8eAkJ0uANj}yV>fc@3iflJjzzAdD4=PQHS+l(TR zeZ=epl}_!8xL6%@<0r7XlVW8zVWF}a@QfnN9hznmiIvShzVX}*+*sR1?B4X5JBw7p zwUMM3WXC}E4C;U`0DzW02zwG4D%t=Pq{d(p40*z5o-v-&y1O(4_%n^)OyHo2zQNd( zenYR1KC?M7q$B3xpsvKhY@-7lia|pWm=GJo#uSC~CYWr3i~xi<)n;P7(2s31=!E%Mn%@vOd;vo-gGa| zGC^V3427i%q1!Gc4=-8e93hLYbx)ZKP{MwcIVvD=*k zcEuPr5it`)FviYR2@K*1%loMaI2Ds>L!Z!;A*JxT;HnElrIAsri40EY!{Pw2DJXDVR!w8&Q%PgMker zq%;3*i$}zE(}zrB*Rgh41m0jQY}?sJb8JT@K)-KFA0*S(YeBX{J+VLnPj3yKV_P7B zgWDIG(f`~y`>FbL#kp^enS-~jg|yJ7i2w2=B@d&}%t_4rk%kP{l7awLgD zo#L%EHgZOzlyQ_10s{889#UOIv2g*ACB2LYKzvlJM5(TjD_%$AjvqQUG5I6x4R2oY|YNdpw) z))6FSx`PpLPb0#dD4PCg>4OFjWdA^t2yzd7VgP({kTRPH<-)0qH(k|*s8gyal!`;Q zRRWLcPK^1923KoPtO=?1pcoYW1S{JqcFA3p{!4+0xh{^}HjgBZarXHYT)Dc%KuXa~ zpScmQ9PcWI!X*%`j&0{a-WlB3Q>!;v>;}P=+2e=+L=5f@su{9slA4eFI&n{siWw+o z!Q0KfS~O?i3?^b$@ie}=E*m&dD(+e0Y%8Ok90>6LnJwgH=ItoBaK&#NDYE1UsIOdi zgUkBNww9Acp9hFN&-#>KGXDkA29sIQcn^mOTdOqpv=2#I#_oQhM#?=)0oR5pTetL& zK(h2YqO{z^*#L^p#F*`6)2$vDBVnx#S$7^tSm4J64W|8r0cN~yi-6r7a^EaBV+dzq zp(#Vt1+ok;N2ysyu8h6r&+UQ`v~bhYFaQy;pf`pQm?kRG`yT#};=CzWH#^@b^@3t$ zf{Ll=l;(BcIq+aeB?_;*iy6Yl)J3HAZ}3Yrjb%LBXoNI>_)xN`)cd zp(X7c(TDEMlZB$3>-+CoWUSP zvl-)|M~>lv2alrDZDHlcHlBUvI-Wnf%m4#{gTWxd+4|3j<0$0p@Wddhf%(Cm^gm=J3Cq zSqLzpz=H-C+Evp89Qu+i75l+*^W=69+SpPCl}eBd*KJRX+!%aofd|P%T5*IQynhDs zok&D_6cPa?iJ+4@r`U~Fj6pv|Lce8jamC2_-4zr&;{GOZXB@GBQS^~6oJ76|Ky(3o zX$brgsW4or2Z0!}S2!IZ-2$@nK-M-vgqA9pAVxAc34jO~P&7*d65VFZfCA0FlvMPF z8P<9!3r0oijwDUd?zV9Fws}mE;kEy9Pc6SC?yuOL$r7h;7e9t|H@Xq%>fcqaj!q%V!8If>i|=E-YHLLn!VuZMh?@?wdEG4?_lr9g)G zBJ(QHDYJN07@nw@qJUunY;S0JMlo9oWt5@m>VkzD<(4nD8k~2OI%^bv%OsU9_k!pt zV#fO)z4xKtRajVq1_2(}f|M6($!A5L8Iyf7X#fBq07*naRL%{ZBCi`0!t1G#B}kG0 zctD50jS>K%C+nLfzJs3s;)O;d+HS=7!TYB%*N%h{rBoO2(Pp<-6pQ7i=nWq^n>O|)a?u|Y(byfwIyC2#lEAY;-9x=2i_ zWTxgOaP;;$W{~;93oBS$q(Ebwndd(tV8YF1=OIQuF%h9FBDHehz&DNp6oyJeK9dZ! zJIU=K*cPLgI!L8BH0A44Ei%+qCL`g3JIPqIWQuAboiqjYQEf9-5Ef7{RU9J%hXQGX z>XA1l1J9(>*ft{GlVon2I0ps^QoMw>+isuddx(bw&8Ka}NRtd-{IiSrPrr8t zn;U&Jn_L>fJ_cjYO9kvSzL*cJ2!$F{k-TUVm>Oef0a+t2HJ^UcUvk|f6-Hjz7s5P4 z((E@-2y8=c#zxKOU7Y*=u)ce9y(US?b57MrbmzSf{Z7Uch?UG%vt$ACd$DJREom?T zM`(a4s)GQ;W&wcsW&sa18JV~osoRL~gQur3)gl#!ebQ&6nF0q6wXnW2!0v8_X1jse z=?0co`fO(_dkNESg7miHCeC|f;8o2C3lYD*n>quouPjak3rGcQ4pR1y8DElX zXCubK(PEze(Iy)T=?bctr?Ga`4&%?vQzCz0UYpD&OMB!Pb4x~TBvzI#yOh;r)RITAX9`S= zAaU>*f~q2=Erd&loLfD48~nBuxvU0rGvDzp6wRw|K8uOtaFDWf_2{ck;_dH#04Gk) zAxUV>*{AGQyMc*?4u)BV-o^mK?I9a)*$lF8pmHV-cF>+_F@TZmCg@Yz9p-M7Hr{ z8o&eri2G+)a3&1~L~I7|XouZyj2nvsMC9R+W|*34ART7d+~raTdASl7cMB;2F==AX z888LlHO&~0lCEFGi};fP@aX|pVF*Ei3Zb3$fb4w{@F8&r>;D5}zaI$zVR(oLe97`# z07g0hYqwBp8-a#)95dU9Hl6s4J2zxBOY+npBTJ^6PBU~S+cP`}LI^?C90IfRF}G(BK!9BYChZ~|0HMG_Oll00UYKeO*OgQJc29$fXlr{H2_&RV ziDgJhr^4+FJKF-x$N^A5fj`i84mSIhY7Td6SgMLb4-#3fJC2&cnD!NxN+h4f+2sZE z7i8z+H}I2ul-fb+GXf8H-+vhI{=ma{;Nhcez4qy9db$}-+mfO^+rs3bE*c#zA?R-n zuzh`(1Bp2DrjZ@$Zw;}tw2Q$e2fGRbhy<-xgQ-Y2b<@{qN2$b3zzbDyGhDE9f7oGv3k!?umg<^)q~WKo@KA^a=#fwDluo z?*y{<3IOrZ2-zortYvtJNT6a}3C@i-Nz$PJg<+$iRV83{5tFT$8Idw+gmDiDxqWU8 zQcw&kI_=T8%p91+(c9;lZu;W+Rc6e_SeKW{m^<5dO3lw9wQX`L!Zb-C*o9dF5SYM0 zfC(mvpzk6LWtfgMGhJ?i`lL4>1mxejo&d&Dm50At`vv?c(IKau+r2MN; zE3`UIeCS7BgSWirG+G8QptUvF9%6^~(J;g0;SO5UEV4@OLut2{chQ2%(Qc( zhwbY-9K{=*ruirJ$BpG}{OZ5?0%KJl1TV%732ZJ&Bwa$E;f-!?oAC` z%qXY4y#!JTtmehm1zak}4u1Ou{hPMSo`qv{KB^cd))Z#Co6KWJAM740nF6 zg^i6Nj~&6D3r`Jh0xP5$HX|pIEPY54v7G^D60Xva_ixCPO*#Oww*uMQg{{ITfaFs^ z+5}<-bmXO3+LnQ@2$U@#ts^h)T(cmfGKH0t<&Ia0=(a?5_k67I=`V4lQ*c6$bs2 zx_>JW5-lTTX{6i6r40O~lsIthp?2StY3T8wpJDxm;0g}&RD|9%R-~#tDuf`3gGWuF zK#@jAim;dxhho5B9QEz5mSLxh5}ZSiLCjoYXzy1^(thmky%n#0%bn$vGf#TzQrcYl z!OjpHFKsg^hq?6FT5H94@!}eOIym9XPJ_*5J+a?%hf$<3XG@vRIVsISBr=Q=S9Wlbk> z`aLz#!NIu>7B{xg?#5WW+Qa;z%7BiZd-H&>aBjw*%RCaFUb!3Gll4HZGk{apCD9C@ebB7IxS*?KY$Xu#!6P zsFkct>K{o_qyeR%mh`R>MVO$=sSLFSgPUmvk}&TM>9Q^!go*%GcdCQC9yp9^S2r1m zuy6P*ATX7ZC%!or4#ntnP5TD{A_SNqLeJtuD9MEIkRkQZlrX$Bf=US<&cUDfKL-t( zVW<6I+?Yr;)4f`$(wlF0?FoAcFK6Qi5Ts zDQxcx13Xxg2O*V6hlZX-(8gM73wIKo-<8b69q_XJ6?Nr`Do#%fk>Wr6SEr}3Fx5f7 zPn;n`Z_vXqOVJ{8yAC<3{(c3Ds+t#)DUPJv#Mv433Mk>T!#k79LY z2bV6c834k^bgJh|gDGHoCc->foRS1Ws47Sj!BiUZuaZtk2?YN;F)7p-h8=>*kNFNF z;K19&fdlKjC4o?(Q=~*jjKT8t6r`J0``C~KXaFEKw$beni9=3QEn`Z!(gp=woZwUD zy0_>|9w6{BarambLFf|Az9>0m5#iQjO9lMhfB7B;Heb%qkU+$RO=RL;7_%*;&iJk0 zcpP8&vll`35%RjMrxsRLJ4Sdl4( zErj_j4=hY61)VG@YLPaetS5OGCwQm_JSs(L6~KiU?ZJr{-+$jUrdlm*ZzdQ-3FBNs zvdwSfOf$?(b+EfT#BRb3Cz*G~Tnj6!eI(-K!k!D_V5?E<|g zLiZ?;zKS!v0n>Viof#9sjYVan7t_daqION(2$^3u9LYGr@{ zUQV~40nHY0-23KqFSP;wxLOiE^)#(6j3T^F(=UG#j_ljU{2H{sH zPNDUqm>*i5A;OoFI%hk>@**ediUFI9S{NFefQ6|q6ta-{Y`z=}9E^I6B6(pJSdot$ zLsF|@?jckcpuQE-!gAmsdzU6Dj+~suKm57xMY|&-qKt(~k5mZRTC86rPctJs1$S#i zOda=&Kl?eXukGesmCg0RdS1Z%`PLC*W7$r~`s~ZLY?X$l0hF4g4+HMx<$OXI)VR{r zALh}3LP&e-w`KGkw_1B>%~71DHKR+$etp+{|JD&gbHXo{lqHSG0|hBraKVKH2*wSZ z3Ru|Sfrm7vW0k<%FPr4y=7I-eGs85-!HG70;65IJhTmtI*anEgMj>uAFx_rpd2?5t z&}XKa==TzA(Y4&%^Us@?g9O7P!Z5JXF(f3o5P_r~h>$)cR2Yu~Z+WDR6A#8141v#n zq>p!OPGG(jV|kF`i_IQ>Y;mENFlha%s!Qwjz z$pZ^htfUeeJje)^WJEb>cw;bl(;BGWhge-q*MRH zue%L@`=7jHbXq>$Ra?>YG{r`0Jv(s+TdsN;byAig15^>i6s}Yjp{W`K_kB13$d??R zmoJ)%wpFT3=yV-pp?d>wIC2KBSXe=lw6KlWqL<#yM_lT`g>3{elDVlai-pi*t~LDh zGSzKjdA)C_F*M^Aa-_Uhgn2m^11LIp6}xjIiICj`WcP9Ao}K|-ce;h6_r%Pw>dXIe zfVXUQG1H6~fcRQ#fFF2d5@g{1^{WH?_LDn|(MstClZv#P>~7F(x5vU-4=6!L1i9)* zEL^UXh$tHlp%x(<36jWg*G{ehxZ|OtxO#a5i&r;Gt^?1{Rh3UWwRvVP#-XEpqcHVF zgTfn&?@FCvf(dOiK>&hzV+hVF{|fqViKVrqL4b)=sC$GoLP=l-8Lqq}LJCuXju(Up z9xCk|T;s?hRfY3ht$6W8gAk1t^4r%qshCXPq`WRrvG7X{MTnhOMH}e)=>%{1?z{1$ zKl9dlbbg;xufMc~{umX;)g$n#p_#^O^-BLPi*OHX2PE(xrN)l*}{sw?0q^8I!t;YCp=X+Xj1+rs+0P zx^6-lUpp8m^sOjbVTX^^OAxd!bYf zU>)#ar@gu0!L6JBCTTz;O7MgC{u)ltUdH5!+i>Lct8wPBlel{2PLP$NROm>l0x^>Y zi=oiQ(&i4ALXa9`wvF}8J~K9?kENavaviD8;7ppkZAym5uL;-Q6s!zNcM8bv5E6*9 z8D4Q`3kOfdEU?Uze>B7!b~~7CL|7fBc)B^n`|s~E(D03=1pnz9)IJBu5D4ftkwr1G zoguPe!t5pzI^j1-%m73~*?uW4(KnEijT!Y>_T|n;jxqJc(lr4f_8@gIC^;LMW)ryW zj+p)BcOwvp;C2xFpW&e)zl+!rWPsV}@KBV}Gl5;CB$k2%RUBt?u`=tEa!%r*y_FOK z5jNH`EM863-lg&s16K^#Hkvf04n`8k5J~_ajY#}nBnA#sCJ_oqxNaXhv3KX0LIW{o zF19EJd6m0Y6*cH5c>Q!f{8TcblC}j%9prQo6K}^o z{J^PSz^lIfQQZ5w??h{&i>E%9;i)goB5rC%ub96u9-Qj75v37Udws@uI;|KBvu#|t z(PN$pWPi|UHPA~^7BfMf>WQN-9Bd(qGOVm7EKDu+MuxwZ=_KRAaUeaxL1c0fIDN8- z`C~B)w|(~W2_EgWSrDwXVTR|M1HA1X4j|4h5An%!JuZQeDizbtq8(#MH@wk0Oeg|r z%7R^yN`vt+l727-D!oZGxDh0VNd)eCk+C)+QrXwhH2eV5w2W2#EA9fE_SZ(SW*ZArYkpg z@QWY*EVe0Nm0{07txyzMs3Td+46q=7%d{$wi8=&m zkz@}r-EN~9#r&qsh}%ER&vvl5y320h?9t7Cag5E~A$G{0!~1D-li|X<+6cmwH@$BE|jvCc1HijbVltn+e{0M~AiJ z{Az;FUf=-2GURMhtOqjCB*2g%i5rL-O+;zJq!Cmub5bQBK?&(9aIxbQh!V!5bRWol zj~v5`6i{k;yVMJ#Qe`3L&YW#BWSpIkaN>3WAebQ~w}+rxoE3mDfCLXb#ibME&PhN* z>kIYTlYzo$zbODAqz?={FoRLLmx0?q(4|=~zQE^@J{mj-IK`_`?<`L%_e5u^C1i(7 zR26(*Y2(Wx;NTB5Wwg&JCr7H>`!qzwK4Mr*eC;;`Oi$dgfWP;z-iJohcZW)zVBYxJ zI+h<>2L(r&x@`gnUpb4;!FCm8t^J;&$gaMyfsBx|!O6)Z<2U~8WBA%vub|azXe}~h z_@1~AM$H!aHf*892G_M1V4gqJ^F$z(3@B}K7R2r<$G}xZP}P6)6_a@Qo*4|MTKMd9 zTlo0b*08#jpdC10W~E__bJV_!n$KvVF{oi}tsK%^g8eF2Rg{qw;tIPxTdkXS-2IED zmP}dd6vcw@#fi{T2d%nrpJ@;x!2<o>cSnC>gXlx+UiqgYqgfPN$}d z#WMnUph|oF4DWes6F>denix*qhDN8u;_iRySC_DHW5_OKa*YuA36_iTInmCTR{}9! z3QTi+VG@@Yx0$B~F|-2{9o*RJvv?AdlMP(E)?*xynA^ca4ZL)j!tKU}JEt&cBo)R1 z`p3N}(k0;7e2j^CVr&tvo=tGqu*t$vZzUP7HB!9hWSh0<()tizVdY8y!DB&W%vwMs)vCb*#`XYida#gdRJ1)IIHIg~02hS9m*0|yTRIEddg z0!!C3T)Rv+k_u*Socz_&^GY3z{wsiCs5$BY2MbB)o#ivaG(nTuK5IX!rumE@?Rk?# zF@GQ{nqOWf?H%&IAOLab*h~;LUU_N*%U|4J_gf5hDavbx+54t(;NclGCymRmf=Vk- zw0V68yGuP4K#CST-Iei$&tAm;`F}jY@5vAjsc(0X?`udIKmPC}Zl8{sYIEx7B$fxjA3VN>$DZG2`yzJ>Z^4k}8E5t0 z_q2F#vpRyrU|bA;T;)^`0NJW-BI#W-0mRSob){4g`nwjKacP7PRB!`Gfut=P2zK5S z`3(C9c_#*)d+DgnK2;O$zBh@Z0VHyg17FEbSz_YzQip(cjR+p7WIAQeb+_;f|LQIr zz5O6I7q6i;J%>O2jSXCVftVscvFrOS>`SX?%uTNgV#b|zlZA-BvB`sSH5&~~#0@m2 zfVK4@dILU#q}n)sqzepUEUxv@WA}HGbABX`SL0Rq;515+{D6w4t6R<5KtnKaRi zBJ3m?ZZuOoe1yBoUE56Y)O8UxQ$?ku(>9N3k;O3*A)a7>fg}wyC5@N|r4pAL$&1D0 z45~m_WIxhs;NFLi;>B~z*jN=r*jW9QQU`IYb|Htkfe0v(9mK*R?TsP91N+OQ5k9pB zzZQIQD(2y?4YNN!pYor!b&vppY)_;Vf^H(E@8_ROu(L(p7q;4f*_cR)goPCh*G;j6 znazZQ)s;F#b~-0%Fg!?dSVSTc+Y^LUXAY|T?$|x}m5(-<(DoymN$R3~^dkR^)EIy1 zZ+#oy^sf7=X(NEG3q4%;*cD`bVCvum;%0=wP9KfQ7zZAi#q7OP++Jr4pJ6Y-8reb^ zA6ico+WMD%?(_TxP<}?RK!E_+*7 z00xs96AAcB4$R_)YQ&_4myV>@YIz){@}4yytLeB?%YMZ*-x{pT0i3ajQ|j; zS|XM#j#Z^2?W0H{gNK2egPI?@Jn+!zOF)XReI?)_&%lZ&@qhkD z3wZc7$FQ}04cluOKJ}3dyIVtX)20seB$PX%9)dg(2BF#4#dq5e8j# zOhhDQ7TF>~BY9j{VYYd&DI#!mQlmH!7oNL;jkR5+!l(icY{TZRpY}5&s%LIK!kzb$ zghZ<@ICzLaf5{6*t2GQT5!1aI6jUnTBJP?gh`*3DaL|x39kh}{Wc=367oMdkA4W_C z0|>C8l9B`;C?b_g0C13upN)jFr*Ij%LFO#5!GEYxl-R-m4}AMLV<9W^7|t25)Xrmu zsB+tz`>~L)N9+Qv+wWPxfBVngrQ9P6Nex{s|3VMD%Y7`JS!EYub*DR+obR%IH0TY` zIoQI&D`%N{V;rBg3!4~_vb6*^mSr^E3{ks*=_8ZqcbfRqr#JBF zGaJmvl7NI#Z(;0~8vx*t67r+WbpZY^PD(I%Rj0DkGe zZ{zTZS)`K-`0A&(@ysXI*eQp*@QLfPjgzZT0BHk7E4~ArRAVema@9pY$*?frM%<6E zwl%ad3-5>f(rmj+WY@V2y>D4#RG-cE-3EG8`r z4>jG$aN8`GCavsdcyXPWp1z0c_&xvtAOJ~3K~!UdMW$@Dkv12QB}1fx8yJ$xf>MbS z21z5xE`-@Z5XV;FL*Fhc-5N+Es4@}6Ym88N@Y7Du=tjLnWql8HvxQiyUdyrBHQU_hkaQ!k}L2cV2n05(@HCs$v z#B7i>R~U49c)DRz5iW7y<7fw|lH15-{t7l22t(#qJI~yj&L+<1mng!wyA6gbk_`t5 zzUPNujkkU9;ZkZ!_6VD2cbPbhcEQ$_9o%?sjWPJixh}f19VBG*I~-#2_AVA4okQn< z|KhDsvQ3wB?OdbaQM%ovdi>vi`Ahi5nd?jiBLM_gL-0PkQU>knX#)*5XI zAlpjn3w?Q3z6W~&3~p)E-pO`^U-|2YaBw!pm5T$sc%jeKx?J^{p*7WJYK_a=DgN_g zYk1}*?s>-4gjRu7Jj7j4HPeSqW^lUV`a>iNb%8_3p(?oPDj^-@b}-mEPXOY7R4NSd zMcF~{^b$Bo*_M=xiRa2albwmR)WT40C^d(87Ll6)vz9CSj1C@TPTn8)#-|tR~^Yizn9{T?|Tq`|DQgD?($iD_P^Y~&;Q(2+&$aGBZu1PHX|a!3nDOs9k(R61MA>{ zLe%{g!rp?7qwq3dUK@0CAxV(vUJVx0A;aM*KA#)?4A-~#T4ASc)qZYIfyNAyXbKo^ zAQ^6QI|z2Sgm7u3tGuP;L5gL~vQnTk(ZanC9l`U@EMkW)A~MuaqN!@Sc-!5X@onP# zGh*nc?u>Ed1WC)J)PW=qVB&3(FqmLMN+gKLkqhYLG&jPek|i-`HY`%|Aa5Z}NQ5jw z1Xpbgh7rE;M1mgaq$SZ5fItHw11QKI3%`2B$PMsd@Nhn|${WM9&g2DIz*^Z$7-MNN zeF;=V8&qBoXmCNC1!^oHA%5hxr(mLPUE;S(V5On<2mZ=y@#c4*E+ja~Zi=nv=^lI0 ze*(_^6eJ~BJHNra*QORG(4K5z*dH(n-Ryl+IPlO68WUBt%wH{!PPt_ct&=;_)>sZzO1WBzxWwzUfkh@q-gd zxkA821w$S4>zH|EL~py}Uq~TW&J#m>XGqY%*aBB!Sir%sk?;WrrN$uD1u?BEmJlx-^Bu)4(GK z+qh$fM#%KCN5nY zV4*pI<-sm993%S-8Lz;ND;hTvFxjRKmzm+|Fs8u7p%(VzP~U9z2ZapI*YwcHc7kQl~D-e=6p! zObRB|823Hc;i{$Lu7}5m746I1o2$oL+Cks57DhO40J>Z~*)#dYYkC}VTL&znt zQb0#-5)TnJ^INZFXA97Se9Qn_hF5;uDZJzR9>MWb^EqNV+)S{2f#NsYuV}9fwuV?e zw~mcVTa2Mk9+*V4(_n^{G1*5vJj3lHL@a|)N}UcG<6?Vj4-CC;C8d^tBPX>Gl$^S|vqSEi(x|-~U@MOCsV6q@<+EF$AXIeu9w+GIYFpLJ?Y*8l5&^}x z0%Y}7E#IH_F`~Df`X4O2UJe>GP!O_YWzACv98CL%oSUaqbC3v%+@i`RV!Yr%4jdDg zTWZ~x2Ru-F`hymJ?5}?w?|#o$@XXil!c=k^(+_?p&OZJh@S7ib7}pnP&}gJMG2LK5 zfd*I@}V*RAe6^^}D{CMKerIcW~GJhj8x9B6fF%Ir_ms3!7_GZQ)yURRn>HOdou- z!9rUrX+x9LIRq3q2prUA`!IVuYge^%Bu^bG>E}67s+C06@`7LN& zB5^1O4tl&zHH8B0X1O_vW{Dp}pNrJHkKzz&!4~v(5J}-DW^*Kgy8wGhDnh#D&WPX8297X)e0+ZA>1S#0xhD_{8Ju zIKS8{i5(F<4Nk(*`&*2dZ~CY~b|iYxvop{~b(CCm0SRoIN*(Z=AaW zZ+y*jc<$NT@K65Hd$=x;T)Sf6uBi_G&d(giy$=lWn;+g}!Cu%&Q!#ozL+tb_Hk%nk zfgYOCCK<3`l8p#+vkhjzM~Htm>S8(Jx<(yNTA9LXy9=j0Y6}ZD%?vr|>TR3xbEyRx zNyf-xP6*Rv$Xq#@S|gqWqBgR03u!h`k`;zY)y<(|KFD@trh_|AAH>Tq zQ8P!mgzH_-CQIUlGBw8CF;1T1#*_paqBz6UL>tEs9mL5ahjHk@0nAKIqTOz>m;>_W zPGT;R2qVA(at#yo`aNuJZQ{n-G8R{su)aw~rBo5Ogs1w*mF|hJ3^5ppxDSGXNs@0e zXDM}1puhzVB9lzV!9;<9WEF65dAvX-D)^LoZ@>}PyCcV=?6mx~4Q}K!t9Zc>bK6tw zZ^=yU>Nry-AThr%iMPD>e!S_O_c4{&U}cD%OLVhs2{9#Gg_P_gwy|<{9fQpwvyGS_ zL(7yriUydveF6)wm_>WOO3KRX8SEz5y1I>IhonuCNbz^Hjz}`~Tfg}@p8VQ1bz7(0 z_iS6K{~4NRd7$?iSn4_$tw@0D*9hbq<32h+2|6n?543iKzxnV4jx02A>drRi=NtUe z8yVRyA|v7yXD<$Lb%oy#ME{FgF{Tf9DHsmEcy0@yd1@0IyNNKetkdw(Sn{|*LQ#vU zzZP9{e%I+K-%_LXx2m4#yKn!eh6+QjM$=_eKaM4X6Irig`n`6^D~op;Eq$c_x9T`H#5!D85GQm8H5l65I1x(Mnr(4&2R1G zKC1MGp&}Mdv_BYNd36~VuDpnA%S+64FOFhdxs>9$rxOuZ!tlUQbU-j&X~SUX0~pqj z9W$6WV@Q_Xz_xQxK*VwRWMk&?a|1YtucAgrwPNEGg$)#BaJIb9VA5+usWx}spiYBE zJ-gDyQGp6^uL^l-oV;@ZZ~y*>@xWcj(O(=2ud#BnNvevZmtyUru#XsIm^?6n&UBj@ zS!Pj++0#>)e{dF!ZgmhVvVYmUx{bj)0T^RYXh~75mCZhW^_RblYgaefdQjqds%GDS#?+ai_-11t*EJF56NE+Hx3*87m{>UV^go`QAT@!cQ*5YB{+1-j# z2MSzS8sfQ^23Xsn{lPt!no}*z9-G9CL55F#eH~{m?y&CLu_Nj;&6@=f3W0;#N%D*C zgOvX66BZb0`lIi@?H?-up#{%k0;NTf00Bk8rIbsjY5%}hIggtiH%P2^6TyQ-Yo!1{ zTP1rZq!xInK<}a~a?zWf*~QQQ!f)f~u?^${)APyEEk@mn8xD?awISL5Vth6fL}G1H29&?Pdgl$T){b_W8mD?>(VA@k}GhL_T~ zkxsuy54Qe4?%o4Rvhz9*{9e_o+*O@>I!w+33_t=zB1j~HNn$V+C~1$pl9!ZZc`Z>A z71lb-vtC&`TFK{V*S5TCdsnnXQLA84BrQ@B10*H@1VE(8GnhQx(>YdESFZQ=-1~?3 zzgMq9_Y4Snn+NQksu%xszyG`6y%+gn1JxRkbrV>2M8!`rhgB%4)HFz!1~VS|ejeBm zphlc)x=frX?Z|`+qe0m*d8a6J59}gwC?OVoNI=tuOKuJ6YSD!xsEMew`Ct;e_YdK< z(+j9m7>G&9>uJym9D}I7b;g7PS89RdZ?^H^-FtD*;X}w}(rhFg1`WhaP@<_C>}Zky zi$*JmL@AV&7zi6~Gy%s=q3QOa>7?K~lsHQWjx9t%rKcBGmT>Os1*{kHICoNLAjm!9 zGv10hGnfJaPPA?Ig9m+__`{^+O~cF>A>h_9T@}8aKLZR8D5yJYkBHHP;XuZFSnqpd z+19TUL@lznqKeMI&^#t#famTDTC#ko>Tp)Kk(N-A~nwH18o4_+27 zE(rvbw^^}{>T?F#iWoLQgVa#)M@AF0j zg_Z|w$EdX#E8X6&>)N(0xDayH$9H~0D&EvAF@F2p6l{VFubPnyf{!x-3>ioW!DJ*t z;Gxri3T#8nXWSz5;6rF#z=L_47Q?b7@X#CcK=-THqqytt8T|Hd{}o3_kWW2E03s&* z>-=MZLleL8_5FC}nPd3a$Nm;;YZ?67ul)q_d7}DV#G@AWci9Ly< z+03HmOrhrNLeouAL-2b?5k<9D!E-0i;tOA#CfIFw8swf`vH^@4Lf8b84N!o<1Ogt+ z5HnJ-4n93ZfVJ?hDS<-}Ahdu9Ioku*Q46LzU9my!o=;8%zYTApal__bV7zGEY5RFf z0B+yp4(y&7!PsPub4R2z6z(j6u5YmjKo{8$<&_G%H7GPQmW&}Ym_jrbLA_Q-obpH9 zokMz}vp$07-OMJ7HhoM4Wtz34`0LM|!_(im#zIaX%V4-|)EcP41y5WLJ(^&HTxJV% z4w_zO;x=Zb8))eEy`MrSPsMmTf{)yhk}2<%3s!hBhWaBourrQ`gL(fYfrM@$Pg9jui(!zS31e2}9RTv;|F$x~h0i?*b5If?qYH;4U zTM5$?V8H(z)oL8?|G+Ewxu5?k8jTq5Fe$$R3FTO=FArZ@Y%<~|Lz>A{@rQr-4t(~n z9%7dU!#HVd`x8+d8n7{vrUgX+31$ooqwaGz_^Ne!3l!5BCQ4O_UIV}^T6e~Df6VDUgU7|GHjap|J9JC za|VXfnB3Eki>H_Pd}BBVCP@2*P4{<;?A`zy6pwD(_{e)6z?+XwAT}nVA}IZK3>(Nc zUPQv0ffZ@WOjDKw4#cIBFhsnTMKm^9{iX{`6uCgt$)arCg-V2KrVGClms4JL@R={1 zz=>Q8Z~Gzn=bf5h-x24Hsx`)t-7n-EIEN%(x{n2r4tam0zdRBQz6He6g^Zs7b}1I4P+gSkj#G z8z=L)GB4UGyg=7BZRu^Z*j*U#9v{zJ$GV-+1IX)kiIDHD$0z?MNmQ#@76c9Aa}PKu zZcG9S?U0kANsj5K!b(y;-u9t781*eM4{8$K3V6_uC~13-`MiDLfhKgd8pB6E@^yUp zM_xeFvC(V*$y5aK1TheTg&_N~x?DrOPT-<}b7yzqH-GEHs8wyAY%01y0SS8V@wAQo z{V}9%sY5ahx(DgZybOkWLb@DCtaWH2g`0~t6bMn!$dn0gM6oRooG5LAVhzk(6^83l zr{U)FwRqBLVIDY<5+}`)>z<0-2&`@VE=?E1V;PL^>c?xR78rym1L+@X-6o9qz7y~y zSIZB*{cgPLEr(I9H;|dM5Y0ppZ_Ht!^kqaXD!fGToGdU9;6Z{0{!Kd|!bLGlq(D}> zVg(o+2j%G9D8=8#0D=rq=_XJrH1O%Cp2Nag9yS-jkVK6RTl2H?(oRde+zK9A-4(4# zppEX2?>xB$C+#M<2yU zY)m{c(lI4AxkU;yr52W(N`8O!OPBD~zq{lKDiy$2OoO3U(oboC2$Q8iv#%G-}wQ|%nZY} zRkT6tJ8~V2sD(Y*C?+#Dqj#F5qIZZn5Pd3`3n5HYfPlr0O8hL5fMPsluX=ih0Mp=w zhR@dhRgL71PnKu;$tGY>n3;Im}Vr(jli>DSta`*SL zQ237#tz(2B(n97qm>A08<3Icu)5rA8iNOdmLz@^}{xjHElZhatNK%0Z#X7JHLrw+K zUy?YCJ3%ZS1Qv*%wVHL5Qcs|qdJxUcI*QXSGY_Y)&Ej*Ms;Xw?12aU7LqB@ zHk$vC@1z>g&_igZ!E`eix}jcxg90_C3qm|ktB|ra>PZ}Dl0RYVb&H$BH)q3uM-P3k zfrNJ~xv7rrnZoE`RsaZj9|ahO$NI46;0SVq8bG zeIpb$>R|NY0rc%ncU&S1q=#6qwU+!|E8{=@{tGCV>WZ7vEMbed(gffE5JB^3Vb(>B zB3DD3?e>BOW%lVAX}#LlAH_dDl9c&r#Ck+J>aqPXEL^FhQYJT{_?(U(>$h=q!WMZW zlv_hC5{ny6oLXpb0y}zYT1)JtjeeOs;@fA7ICH(k8<&;>UE2Z*J&dz9z3X$ccXaJ< z-N5^=z4i0AbB6WU#K$%HB_6=wx&oj+IpFv!X0 z0S`|osX&Hi7}WKo&{2nt8ap8VjKB%yh)7v*^M;U$rp7+1AM6Ysh2Fn-|eccDhAEn47`G3-cx9ohU- zaP7FKbqFvILjNGagQ}vLlIbK3%*`5Ob`$j>Kk`wOmeZ)LQ0i(6m0BHt_~mC%C|AUy zX8;I|52O|Mv?-+%G{p2Djy&vC91?P)fMWA&~) z)O;Yqqs_@c&(E6T$*rtwTQ@c4noXOVLjzI#*x>{-2a3t0u;+(=w2#A=&p%zk;te50 zrvJ!ONgJbmqc#qW+K3S$q1_r3A`M(zY2fTq6D1>eM0zle%vcK3YYjYox`4UW8qcTh zxMBMsAx!hPJ=S6C?aVg%yU0dZkBxtkjAh5i~q_#S27yJ zK#=A6r$7CpICFXeiA0kVO0|NA_RqmcK4M`k6~(TsjRd(hD93>8Uen*GTn`EyXx2bQ zbx2U+C8<(^Nu_@fL&tPs=)aYal9>k!?vMbV&MMHX$*2J8b6xYpgRTmsD8IEyu@Zn7 zo6KTpG{a$>LBr5~_;ns{W?$1a>dhwp@ss!B?Z@{qnBeBKqS)#D5z@|i;kqDjKyHe5 zt_y{y>DF-zR$PkNC|`%d-|WtCP#FFvSX(*(rz}dj(>wp^-#?G(rB#s8Q24PkcnC&q zcmUYP6v&I{7Li5F%qhq~Dx}GRjDrtgD?rk6qCgeue|-A!+=g!?R+68Z=N6VxxvQuuGyG6XsEYu!boR7b5;!@%(z zk|Q!fNQd=ulS+QCs#-7NKuRd}>ML{ji$6KV_Ydy*lrdH;YAc8k%QZ#$Y^-@VZ(V+G z#eiyPsGrZgJ^_fMgHe3=P*O9cgvW?+c<_fZ$c#i;12TQChS$DRMTxRf%EDqa6>~`o zN5^eZf5)R!`KE=6i<1itT+KH{7F^dwBo;w-ER9HC3@5IZ@X~8Vl&V5x*=}rfH{HFr zPwzT~?sx6=h|Yke_h;{RKkL!)k4fjV0uW+0c%VUjE`rV}>`XHa(f}x`vGdKg4<7uD z(L3C&tUDqJM0^frGd;|F=emT=*uEGo(gr{pmYdQ)x+zLW+v(BO2P z9aA|B45e`K%wmrVKyTo|Y*qpdKl$GK@X(Pxs4D;g8{=#L8M(x(a49TRX&ih2Lh2qA z1EJO^IyNoKXBsSoXjBL5gZ~WcOZx#=hJRWX{`~7N;Kss=i2YYC2p*i`eSFM=`b@9g ze(|N+$!X&)FVN0iA-LecJ;cP2mkQBQ_z;MAkYJK26M*RUHkcp(&<=)j$nFk|iJq22 zpOKemXprmTj=fVDk^n+3fby4dbsnE0bUHVX#O_1GAom76PFta+dLf#RqcOxsyJ^F` z7NC;fB&ak=VcHz5NjFA?l254s3r!r$WO9liF&IYKBMe^WW*k(jp8G;HPcJ+3j*E}k zrCPY^U->Nt4R;Pl@dF1E{I}YmkZF1Ahx(8i6p>m)YL_+~TzH{^>5Fx4cOtndjWs>* zWG;&1J7UNsWGtvbgHl1iSC$%BCRYgOjsW6)G4xNQuu%uTeYSwhvlV`4$~GJR)6>Xm z+aRxxOJNqithxXIAOJ~3K~!tc^m>CA0U*MDT6hqDE1SE*P?v)5n%e^pdLjp7!;MAK zyUq3tt(sKk<95fu}hrf-V`I)EiM}PPPzWkMY@q54bpRr>{6|qDV zG22D8n!rzeJN19P>ELI7@~yZ#H^FQK{kV}BvMWzxqWLK}2};AQM3eHj!q%Kn zO5Wb^>RD-7!d$&D{if=q@f}#q{1VEmbWPD!tr2^68Or5OifD7K`bp=2D2HVP2nGLyq*uJ zLwu}v073W9tFTT9=+yK6!GCxWH)rx(eV3lKg^AGON-5qosO?Gxn46ZHlVGz@Zj!dU zq+p|luScHY44+*D8txvk@xlFZuI4LPND6&+@z4jd$P5SoK|h=y2f*C522MX$K{4MH zQK?kOuL;C$;P9}G!^2U;=(%aC%EqYHfm5puoLg(6Dsx9rr)7qdNDn7)WwD0m&la#+ zX!hvV=xxl2+sk>=@szEBf!^-kdX#@edmE7LUe7$w01%yC#{XSdYGBo9-O~p9R-V8+ z1fId?%L#nf!;Zgg18sqMXz$OWi59Fa+Zn`=i1OjLUBD+k@mKi0-}@k*e&!hd)o=YV z_U&0iE*C*84qUl5j9>YMA3?cHku2s)v^DTxJ~z8HEDNKlD92xuB3Xod8pW>Ef}@0& z+VIQbT6#f}t_TuB>P6Pb4_^0bYd4T^0k2Qse=rLg4T8Glwo<;{EA-3a`s# z;|w6$uXUZqOB-6;7%;V36Tkjj@5F(|5H^=c%qERWvx$j?e~-S{2{?Ar%lE+U45fRJ zECfA*!re5MlNKz}LTJP!qFoB(KZVu&{cx#DDlLu;7X!yK`1BXPjq@jFnYLD%0LBgS z|HN<8+{qoJOhKXSpgK+*Dw#wDDkLxoUQ7SmxPA*;;iEIuZq@@Yh8^}fIsLm`6D$OP z13zx-xDOH?;X5GJneu$&Ac=21{Qv=oeLFGOr(75=ETzi{o+tmU-hqGw=_4j~^<(G$ zK_pW)r=Rwt4`I|2!!g8nYz;tE)~nc@FZ;xl#7O=5r%&R{$wj`msd*4%%L6}(T~vUd zKrgv3)|N$;*RY@VyVmXoPuR`Q*%#^#aPO#%@81{aq)>w06r#xo-=9UMpF+NkCnJ0w zw{YgUGS0p%Qtc~bOn89+31zmtd(_5MpPXM!3YF#z@mMIkII-No?51K~9oX?Gvk^|h z#>*Esapr1?Q}DNlEVpQ7{j5Xx_S)j*Zz(19?Pf%{uLT2fYv93b1QG73sLKupwaw1m z1R~zqosEJ2`L|+d1Hfo2?gAM((9^rh25L4V*u8rRpZH(?3x4BY{x~OVI(YvX^rh-Z zB}H9`+36u%_{M#Puuv}gokm(m7Q}l;0usrng&pZA24#v}5t1og6fMTzi;D2aYJ08= zv4JqtUVHf=gg!z=SO{Z4!$UJ5oEcN*eV~~hYB2nLL^LKPkxHdwxO{G@&2H(|zypmZ zN|F69e&b0z{MNm=^7$p!s0bP$ibyq&v8De9eby_K;RmkLLrAv;GZUu%LA@HeF(^3> z?ed&D+-M4=9Y2P(#^Y!dBzS1Li1pi;cw`X2|GQts#q$ds1)`cJ96U&9pjZbJSjfNm z2&HwhG4Y!EK8geev`COV!Uc(0tjQlCBpvFHtxgxGKFdqI05los!$mq`Am*h4_ ziWl+OcQRH4AO`v}T14sFwW)t-Fk$TYB}gV^u(+(=-&bCNjrwbVHv_oP8&~X!J9^G zWNqOpsY!OD>bSU8aByz5i9*fMVZF&*jH5M{HXXchu7I0MHBrl^r-9}jq>51X&fb^+ zsi&K58Eb@sLmrR4up{kn=d;m|j{iaj03R^0UFmvbV)A%0k*K)}gaZqKJ;-Nee&5L$ zbO0z}?|+NTgTAD3o$!ekJ|L*r)xbaPxLg$E(0L%j$MkP#;0ziMm$(n7s!{~%)VD6U>02BO!o(w%jX2!?;v>rMRP&pnC{{Oobe zpU7kJTX_v4NK8rLm$|j4Fi`n2;?}%K97VYf*h)yF!|gzef{>?w&@j0${s_cz%PU(Xp#g~_CNs!9W7go-Fzr-Qs}o0$<<*h7v|41!os zDU4GB2(?Y~m~eTvyk-DQ=*3fsfen4c&{#$Q6*(c|Lt6(BTrIu73x$NI8^nJWzxDI=vEU!=XFW=cgZ z+&LJ=0e&H zJhg%c^SOu_Ae%Roj9@rPDaS>!C_mHS7dZ<$G^Em|6lm)5;W`(;IF{2gBZ3BHqU7_v zq)|$k+1h5|??(V)_kkfUJa+BEib3sm9xL5b+WOBY0Pzby_b48J#{p#TOkwrRCg#4e z4yWoOLP??M9jzFm^>t**FC$ZZ8HwgKM6r$tNS!7Yd{JP_h7(Pr5gS8ekOo>Et2Prf#;JFNK4J)c{Rsw#vB9ka2)cHDx`<|p zo%sAiZi~PCv(q^F%7Tc{QSL@V3*loTRPGB4SXp+lvKVw1RoMQcz3zRV?{BP_Z*aRS`5+_~n+Qk(qB5Q4H^OLQD2O4_>Ab#c7AIF1t?S>n3 zF?3fSs)YuFh~kwB`)Gw*gOX#BU)x30DZqACVY};yf|3V0EWB(+v#=6FNMwdkEGOXF zM4?i&h0uTy>(GBRgW)&jP+P5`I8#PE7sDTX@|(DDat@S%&=W%X_ufJ9pj{lQ0h9nz z_PO*Rh;_Y%b?_oLOvA4Z))+#GE!jXzw}x>)t=!Zu5Ba5XT^OC?`LoqA%5a7EY3ni< z1di=iV87czAI14hC==xr2Kv&{g&{XUYLLo6N}XCUE2VN+XEg<5D-Lb z!f)=O+K&6>?_uV_>k01-f*lfk_XB&9SX`}O@_`dbWGZOXqG;3`h{kJJxw0DzXAg^_ zOkqE_5j?2=QO}o&MKF|%@(taT4K|A;$$-dm z-m223u@1K~P9dn6DBZn>hk2pDere6WI|#H*Z<8&Y>8Mqj_@96CNj&hD-Pl~NBASRG zcQA$ISRBRa3RYe%qIkWEMp3MQqI@^e0ABp2csCb)X$u26u0_gYo(d0d)?GxiQDpa} zF>o{kI~hUYdKuMKa%Wgb??~YHfA=X|y}HD^Oa%;-;pg9yb?^*(z->r%05r{Dgk*a5 zT%riE1Mz_iAN`=t^+cNLIrJu9>L3L1AU@SKIb=UFV9_TUv_-Jz4M~JzQp~B~hfu~h zp_`~6K$UjhU=wI89^E~KL1G{zm8f^{8a(*Hfq5$)+WIkMvL*#2XuLNaF3xq}-Z4zP zdBDr-(c@arRXPh|To7QGpDo~%|LJ8R)|4HsU~6o@oEY4i!~g)GcGcM zO29_*fU-=UJy~NgVQx%ly&@n%XekFKpZxrPSoUnyf{Jc@zw zB%*yWoV#Ae*()VfYmN^2yq&B=Z|hW#gJoNXi9r-((FH5snVkp$5Vs#Zm=u;$+nZF# z|DV8v*?-z-8nh1$mPXx0Jn7)blcy2SR8Uy#hl3K5{dp{1IDnVCxCk9I6GQnl5pp-Ab3PdLE7U-w$*c4g)Zct8O?(0#MudiFvv5NmoDVdp z_Z=DGGTzfy3;?lZ@X+~w^}2(f|A~k3!C$-!OQ#EZmzNl{k=;wV_HEQlO>E9oQM^$_ zd7*}SzKLeVVY-?r>zIYXfd~?*2nr<^WzxV*#xQgs0gS|94+tu@yii4Xu?mM)RsgBd z1YhUh|L#+m;Y3n`fzYjFh$T%{z;sE_oHN0LsNkuPgJ;OqJQM&$=^wnC2~gqB`JjP- z0t?dM3yM?xpI5fSF!%Z%ehA=qm6)T!=p+4S06v6*2H8>u8{my2{|Raw9@#x9M3idq z8pt*XCfIKIk#8t7VQLb{1=WOu>-kl@JGj2lM7}D+)Lj?JYz%{wDHQ51Ub(P|nMIM5^|B3+s@%n-XJ?Yr^1gOt2Bl11ZJhbmbDgO{Fs@#1GlPq>J(RdR_ z-*E;WWuekR(C5=em#pK)X8R zBBggfk|Go=gHgCkyF5f2hy|!O;Gow@7ubJv1l39dGgsFI196+d16_~w8XtN5EqLEQ zzXPdV39Oyj6kR7ni(}a+lA|%sC}>lDep-a;F6!kb>m-`BCgQdz)!rnUnG%JiB5VXm z@6e!<&BX?q#X3qwhkdiu!14YVGP{zP{=x$O;;9#LV}6wlMSJkzu>#zZ+#GVG$);@q z57Nl{?70z1p>C#tg8~V4E031EmeYh&1) z^yZzu;>ex=fCvK#2CJY}QT41-h|XzBZz>n=*gt{w*8^XPR< z;{wsI%2n%q+|8hQ-_uxs&z=}ZOOOFq!fKk!54<%5Kv4S;195s2^UF0HJR);$c%%?7 zCg;vok*BPcGOv_iBD_@D^f!BoEnu=Qf?c@?Y^qseun{EcoGUn(Ei{=Op$Si!bjhWW z9ZulJQVl0B7E#!wEWym%ZPiAH9Dh5maqEwv87KWt-E)E%0K)$g9o6l=XYFDD^lnor zw~gZ^v={dZTxSagv!&^L=LX(uD+a5FU3>7}3c>LrZr++HQ`sS|#Q@^iJI^A~SHY#H z52J5<8o9|O%)WXj)^1E7Vrn3^&=$7}9<-sBf28dQC!iu5#_kJd5~P??(!ecI7l!sh zg>&-`Kw1(tskaIqSh(l{2ksa_saV78br~5UpS8Ei+_gmBP)hETS@7!)IT571w8$nYK3F6rQUg2p;^&p(IWSh$}q-qrOfc zWYWhv$mY^BRHGD6P(`7*n#qt$su&s_!amIzukN9Mh!0l=*9G0#fvML9IP}02kdZ#T zdy*4LX%~hBia}5y{_Wk%BP_)F*1}fE`x9s&0P*aJE6l>xYfYpw2|W13K0N&H{m5h! zp%%cYHnD!KfKw+I@a(s)V`Zf*QdmptD1^;IOQb=B@tu0sS{1l{#R(}s*WU0bfNw58 zYSX}>j`E($@bqdk$cTUc-Z*EY)Br-VpAS6Pk93CeK&Xxr@5KP(ECGlr4jxL%&5Xx_ zkk;z_g(?a~0Y?;gXeSD%XGqx=cK1gxlBOIrK;7|@>=ENIv(dy_MPAEsMIDog6x>7< z=dP4+d8Wd1yq(C>YuWD&fY1qIh;i%(4BD1SjbhmO5U5?H2WIH95()#4>~IYNA?TvR4~$hKBqixXJ!Mm1>eyG=50fjn^M z2#Wa{=B6nVpZL5xc<45!{AzJxAb$D>9>CpW<0zM_IP~M=$nH%cf2oY}VvUnMaX-s6 zx%6j(z(9;bKwVU-Ce5v6@bXD1Fe3(7RJhi4k;vM}?M}hUM6vPAGUiWhA~u}BXP$Wp zSFS7}rWgqAy6~(z8+*QND|j$d^eWeaa&w4Gmi}l6!Cn|z2r~**-a{Y5|CT0(`_f<> zR8#X!6^PIt5;_8}w>gsI&ymzkDB+W-eS|2+KQjUP3xJ%j7w(5^|XfiS0>1_=5> zf$JEogy7q}d80Xg#Xv+{Jp1Yu4KfJ0kSmS~!#(=_hj7osyENORmX9+}&){ocx{Mpw z)_J_C@h;|`C#qEJpXe6J`bjHF8Ub=&%-!_d7j2D6%X%Y@)WAs2+id1XMaKIB z`{G;=!X{?F4g`3&c8+gLPV>W>_ZSl zC{{+`dlv%IgjSHBAV!z z2bt$~8KB=4@X-1U9_tVYS#2?F;@oD_!r;^fjy-W1rS%j}fB7h;-f|KH6C0R*@i^9| zM+AWA@IFDX*78(a03NO5IB+$|BE=#WGBFGE+dnD2$PKmFm?^T=T3|92BGgR{$ZiXd z|NDc-$B4M5xangkcm(AFMjz~AH%`M5GtE>RP%LAJU)P(PY$uZVRO2Q z%5t5x3RD@8zyrNsh1?gkh6Qh_ebi#QMPe3`BQ{by5=acjusL7B;@6hYZ&S{G8_l64 zKKc3QaPGt$k_n-KFc&FB+VQ&wbPAlq%E0S7(n007qG#iFGp3l4+{wGPU-T&OhO*#_ zb!Y_+W@Lp25)7B6_BsW}nR$I&6QUM|-uVU$r^z~K zi)sifeL%vyt1@up!f**dydnXFHp&*74a%A*qKoc(bPp!?^rKR$<2zr!j#rCibH3})+6 zv%TxcR?_X;Lh%IAnQ!s(?&&llm^iwOgKxWz#Y;oD_{?tXfAmFUhZ?x{+?`mP9Yn-e z2cxqA+!}c3wy3s(2lc{C9Kd3I1SO!NBUSDQwWg{?Oow_(35ds9c-L3QwqJlk`pL3z z==dnsmdjY0B>>U35>5yJ4SDxA6Op1Y{@4HG-8hmN!NMzfHu#m58thyIlTQp{^es6= z;}JAAn?Rv~%0?4qssLCg5v8eCm!d-3LL_b>mWi?elhPVfK8f;D6^k#dVdJ$;#L_W# ze^40P#5+cC_D`O{KfHJouhDe@PHe+1Vi;fsVG;}|HX;l>c;9tr9T?zfaA5!xx!@`h znFl7+GkNrYzMt$u`nTGl>vcx6C*q}iy&Ys4)OFNR!Gl{?J$Zn!J<@*~yH*~<01i%# zGk_pNuI9PkWe2Wpx;4UG9G<~aZ^iE%6%0f$)wJ5#HX07QHz-LOMQ$|eP0ln)ZNrac zfC6t3^0N&=5JAV0`{K$a2aXEt>S%m|^E0SbYn_u@GeqKDKD0l9y*Uc&763(o5jN&g z3%e&%*tavq>>GhP`s~!jA{N)GIIu4%z)~RM(lisT>`eMU{Yo z+!_C1Ey}kF9!x_;FX=Zd+cWyF8+ec*KpKtp2p$;GH=>w0 zx`e}Tzm6*}PT|Ih9XRyFOBfh!;L_7~V0~`D&_LWy@X!q%w+9aUA=`GE7;5H2$H%a`xQV5?%?|#@&g~`ypPEN?wT=h@hDsB)jXH+LZ44jJAi5`w^v)y$13i9emm=#Supw1xuqEYMS*l^} z{3bRo6j3i!5sll3_1QxF)o?NP&>-SNHoo=yU&AiD%+&**o~__Ufv8eZxmC|PsR;KO zY>6^7lVG|&Ov7xrD_U3wMiJ62qQOKs>mbfG%5{6*5d-XqCziysp=8&{z{iLvpyYK> z8#hM_CRF7q+jOm;Z{>q%{2h=0LhpLL78V!sohLss!HN2te|uw{j0~+o%#=leXUK(N z9IFhc;@nlFle!-ts+a{0AiQ_f-z$d8Fs!l*vAP0K{)b+xPI?=oRz|hmgb_x`%TVg; zx4=nsELGy%m8IlzG7p42Mr}xlb;)LI9NLq{*kFR6{p6)07B{Lmuv;(?J|G9+!qo~2 zC7H1^z&`jGQ$t)S?kBcJ^#3Z&K9vmLk&YlC-5LZesc-1}^|HgMuT=;tJ$iO1j{Y49 zENwJ!?otUGg$9Ejy$Zc<;Go-@?lr!@U)wHyJ$)ennoG4Xe$l;E@Sq>8C0UgBa;>k~ z$ykZ+RL6DDnL;J$4eqJIlE6bpjAs z$w1r+c<8}^`i4qx;DLvYTmWg@P*O%>B)DX*oV1Q1oTWoKKZHrIhS16#7cHZG>7GaK z8pG0D5z7nh07RE}?>d=96vjuNd<%Z?U%m;ER0LN)yM)SO9jQzNx&8=8T&ykBP*`s; zvp{Z$)L2XuOv>6UtRyCYjwA78b-jVgQXK>yYK0~nmE@p}^rS7Yl8osezNa66lB03ZNKL_t*HHblU*vA?c93_;R~}gUC)06b z2nD3fuyK`(W@;pXBfB%We6x)CjS3F#P795M5lTw$e&Ko|+W^YOADWIz-mmdjzE^dAiguk^UfDYz+% zvxNd(y@P?Cth{kh_$FjNH4;1Ik6 z>HKWAA~Nh#XQxzA8>&Y;PZHsuH2vlNRqk{V&)FEczn>FJEx)pkl^65){L3eBeNJTCoa(dj$W#)OSsN#ptN6}B z4aK^{l~q~uAXxxq%uQW{$u5WoGLlO1dBS80@F2bv!%6tem5#{+7t-CSt|Plvo@(en zjC<+sH$aHk`1x51qx-mxD3!1t+hJ=;m+@r2mwX0Oc&Eg_`zFRPGLZ9YAOe~K1t9#O z#J{=lfe49|1f?xXz7v2@Y=Z}?{Ux^*01($wY=fZ9)idZFxB*hcdH%v#^*V6*fE(`@8^lxRzC9BbJTx60q>}UiVr3OX^ z;}{u;F)P8)=5xeza))(+}N`N~eTb%_SUt6Y`ERWvIhep_zWowzOs~L>Mnz2# za^DQZ@W{?2E5@Inuj15lox{%vNOT4dvTaQ8AcYR5-oX<xDSmCm&OWe0tl0h;IV95c=pxHQW!|Uz|b!!u))8*Y?jKXsxSx* zI)Y4utaPi~9qa-Iu(k?JUkedW8uQU(dV4i0UFNaumv-wWVW}TJn7~NVVgNxu3J`f< zLRIw@2PmVh{!S$$7#~WYFBKI@rCi{(n`IOzL^|N2P=0&Ch6=WTtHK&Ah1N`{b0wR^ zE)IFYzPN?KR0NdQjUzbZTqgI%dd20CPf?zn5Tk{Gu>|Lim|v;k($z9bB(m%^168kG z(cw6c4Y~~%YiHX%0MQ$G&;wdk2h^*Ux6J#EYWsg}CCb1X6k?@mSF!VUf(H$f!UU$< zU>;OUFn~C=gdIm#aPn^s!)Zn_Fqy|4@4Ae0PaVM8%^bTh!stL>FLhvG#Jzeq*sWm$ z5laF#&bqeNU(l2 zqTrkn>G3#nhg0Z3l;%WKR5xMno6A@`T|lBQhSWq7fBB6UapkjF<&p1u(Xj!rB;`M(Qf0qMUttnWoiqAffvSS z&-fTdB?A$_1OB9EK~}=hCz#X2=bvYLA^^mAvvVuIrh~}em9g$mOt?VFQlNF1JVN69aJefo!5yh1oW!#*ra&*bI zM3z1Fiw?W&wq|!)&wKpN+6sVB9pG~(bYKuV?wdOrzs`fzPs;@FV*Yz8gWi8E4OSh) z9&F5801rG7nh{LxTgJ|vOL*>?I}ouPMB@(L`S^=?_2d!E&r%);PJ<@315$|Pd$le` z^A^E_Nkew^hqmcU*@9h$V&FYOuBCH{fRZjnaQOHbr?JkjRX}0C{-18wYw1i$p^7%9 z1W<{ng##H2KmR-LKyEXKrAs9=sty-48h&#hrk)%^YE-15Ce=I%ELq>MQs;Em4a!DI z6?^2u7)@BPGf^Z4Y?-|>#{X7^V(nZWOV6*NvFRX@i?M5C{E=aN@{`}d)eBxZZ(+>E z`_aNnCD|XCh~v$pam<$-eCuWvH#Zv$BB-jkFV}_w5B#}k1D)Se=baYr0yV$+Fm)Yu zj{M!iIw(DcY+mJ3(Y--`_&|+3P+IG3I)xpB{m7(9Vegr6#ySy;6MHQeide}P(P%c? zGhr%EL9m+*RN&F|Qhq`eUU!UQY_Q*>#O3im<}3gn^d${L9~4`9Zodde-8_5ZvfR>o zyKa7pz%}$vJP0D>d-HpGRE2JqTB2lbkfid^r`1;psQA>PXR*?F3)HJk29 z^NRpPE@4Ui01!`E7@LgX+G|u~PP#n}CV|eU^4p{<^4dn^YKX@o*wG)yV!p-zf}2wV z1A`3}3z9zsJ;;6#K$ET`HBJ;jP=JJz;w5asMkH-=qxfqFky~S};;>Fag$4Hw#xXRJ zWQOF@l@d1cqBvSO_UaCh!&+Od+1>lKM|99~SnG310MY4z71bA#NwR0~z$>5kIJW>E z%y$az&^x;jf_5exXms@j-XeGqRwIH~_6Bmfn^>BCtEBuR7~T1G6e0-}S4I%24#94Y zD2bF_R7F|m*B3mPJBF?~7J76+g%8=z#@@WQSP)#q6Hy#FK872Y*HBom8s)qLW6UtN z?Wc>XEGiaL`rmjaiep1Is+A_*^RsWmz30G)C{sq5ohC zHdX4`;!kP5ij|W^EWK2KTW_FmXB@L8{Ts7}lSUrV|oRXC{DRJ3Xx!rT?Ug|LmQ!W_1$ z*QrmFi8#9}s15~?E62qy z0uV#}%mk^=)lObVL73MxBO~N>_?JQz8eNE8u3{jbJ9(K64kvq3Vm@uDJS~LjiqPq) zeQbwhA`F4DEOIN|K^E56TwJ~6cVB4reB0gW?E?*FbE&z^#y4W&M-L}hQ=oJQ1a?Ly zqDaJCT)*06wuXLGR0g%#j&U0+%MH}(A`({ZwAD4#@x;t{*>VMAtw4uzM<_5LHi|~r zXMlas!b;g$%uX1QW_>ZiMvw+fi!3P#l>=;4UF54OcLe2rA(3Sg>HZkz7HhaMT}F)y zbZrkXgxSKa=H%Govek09_1MJ6TNpdT(rcff*oF260zz<#amh}`uS-LQ7%MgR1kJ5( zv-RtEgQx>4za8L#A2EV@YynNHhGcz8Zu4B!VoQib8*orVq&@(_>gNi zFyWuZz7Y_3A1z>1l^Hv+7`GF|7zV)W!PY*c_m3r_ICSSIu3uckW(sR^{4KAh?Nm}fV z=-Zt{dV-Qd*&NbIf=TweG+i{x4(f#l%1d=@&QwsGsiL~l;Dv+Ac9RPuF({7h+m*t^ zJBG3J;yOO{N8iN!`Z@y$@t)!x`TsSJlr%70?8(JgXgQjS;^n0(URtQ3)DS{THsBJ6 zD1*$fiM$tFMO0i@Yu;3%DMKjPk#*2f7_uMas zqo?)efa>qfN`>_irApNkf9g}^GZ;*UG8}5Sm>dTIh^et*>=+#ImGjnYLJ%yd`xscm z2OJC`qdL?B5Ldi((t%JzZUdEFQucHU6Ct%l0$|7rikkM9?hx6pH?Fu?UJ~vLKWp1z zP4IoSeZ$sn<3aC}j9U2NgK^F!LyVu;;k(Q*?A&LgTxeoJJ~w@qNLo00Gy%8fV0ER5 ztFsLe;Urf_6C9{D(#z-JWx+K=$$N2K@HMzgyhMj8qpoHpBse5Cg>*^uBQx0ZdsQ32 zdeuRhQq|M792dzx8zWOGI1vliu9va2Tob+BtNk+isC~b-*!o-lAY?eS1rR=C6|zNp~X;a!T5D#JG`BwQjE84t+pV9ka{o+rg4>y;2~(hdI2yIu?w+u&Q`z`Nn_}2 zsxLr8-*+YX4BjrHQ`XL43$!<|Y66D=nT=v^)<&W3;Np6dEANr8?xRoMi$}kIFLr%s1jTC=%zR~yvriI; zAWKVQjX*`S+C-z`h$K>~w6`?8JdfmdhYU4EVQ^6`1u$swZ@5T~SQvU!79;odqq0=R z%$FANx38YS>@rmx6;eiDxOG5hK?9}f2-n4tp%~sindHP%&(2nGcD2T0H4gn$oE8HI zc}NzQW_I|LkWJq z{Blj+OR*0|HDM{Tq;@CQOfDh9+Lg$XLq$n5Rd-RSx~NIb1dY@F;W!3%B(PCv;`+4` zHfck$1vbJL6}Ww@cT2#c1we!ulU|vJpc(DFE4+Q+LA5~mv$q2Qo@+)J&JI0r+rfi+ zrp|2;1|Gb36;Uu^&G&Yv;iI8FcnH(Ayiwqx+XBP@A|1nlVOQmcRq!3FPafkEr142F3EZ47vn(@aJz($sB}%Hojx9 zBuAF1bqH}+D5gWL1Vzof}2uIIluMUsu7ir`T06`B&JI%?_VT=zCXaHf57oIp) zo!7!hc-L3pM1vG1LIxGki{SYaSESMO@}?*;rD93g=&_-(c$1-TtMmQXpK-znxh1?_Uwrwk&5s!r(dmN zvkopkN8j(;702|=8Y&H$)YBC}gx0|~?Mq{EvBs{0I}GQ5~5~ zBGG4KcCLcCx$XtJ)LP(Y-Fxq|+j*o9K!l1UJ5s~`0n+JTTaCETFWH58@Hd8>Y;v*n zHE`fMVgPJ?a&?aK=!JQ>b?{&UGclM%)I&H13I`8r@|fp!GvK$Ty=V_&#IoKELJPo@ z%EYn%=rAsyTS2AN;78(d>kISqj|vl5(l@k2*wq)sSUSo{nXVTcF6v{Zu_plWv5&qL zhZDotT(4sI-VFAH|3)0zg8!RMe%oPo)?x8M9gE zFqrL=WvFG0p`Ho?06SI;iN+dstbZA!`LDxvHsMBMh`0@u6T2`s^ggWi-A@pRmS)qT z!}lTO3gK@D^5ii5>@k^VgNrwdcp z&dBsKPdgbXdY%4+g&#bS;Q7Y+7GxVJ_kiPANcUM7?2q93)jA+u0|Ho)OCy4bAsd&b zYj7!g!x8R}j?|zZ%1HUwU->p>E-!Q89-#yfH&u(EkbQcpbo~ZuXDa6aiMuA!HXhxX!mex# zXI5)?e!jxtW=bES0Dy8?cz{5*j2Y=^YH*ac!aGc8Kez;Q6vMebjP~acw<(u}X_h^w zuWJ!Vs9~h=493^~2FdyYoJd?Iv=ZRLf+*xrNZ*0k!4II2Jj^jOR5(5OvstNPc_WX_ zO3eo{WS8l6L_G}|po!rjj1PGXg!!oIH~|O(sj{Wv_c0IhM&^P~Z$JRz1p*LqrxrA9 zO8;Oo5#;_-ZVlDj`aBgmY%mdIV9A(XIPIcJ=`(ywb~lh7Ze+H~GITOk^ez;>NwqKt zK$r$t2_}U*LquqBvZ#RTf!=S&hz+;l;O0t`t?5XA6uSmvc;Wmetat>YIU7z5SSX3m zU)5%&Mpm;4vcD9oKzUUrVo6LilQ3ul1&K1!kEP(%A2^J~pSA7$f+3vq(@SvW(JrML8S)Erw zp4b(=-je3w_J9WgAb?CZfxU+Zaq;vrYBd57{_E4OnjB9L=z%!TcfMK#>$m z&Cfe>0uaQ-2AZO@P{q=B3Rr%n0H+G{O~zpNxk!y9F#6B{{`CL+Dwb9^yiiq5olEsP zvl_C5w6P0jorkJqDD5=qBj^G4_uF`6XNrpjeP_OkSC?z3HXW|8Dz%hapsCu{WFeFg zQ&1JAFjE*SCWEX9`ZFRdlafJsUU+X0z<`L7V!%SKd|J9IF7RjM!chJh0T5Li6XzgG!aI2O72T9B#_%#YHO4c6yFP7OJQAvZ|a|I zuno5pG??>)o@zK5!9UucU`X7$gBMJr08Ju7NU^Mnb)j>JHQGNJ$J}CrOKsnGB#jg2 zHc{dMD8}Kwp(L&>R^b>RWHc4S!e&jwPVfFw9PPT8iYGDFOyH$L9!^4{Gy{b2I%}{d z{9J*E8ZXL2ygjWyl+luY$lapEqXZr(i)Dq@4Joorq-=~%C7JPp0BY$k_u@>m}+&A+ZV&s zdq^HGm$s@uBRAeqxKuYgIl@D2Z1yuG=GE$;%y#}Il$R|r+fm|97Pm)MX zB%*q4y)N|;G7p4e6m$fs)J({wf`Np=Iw*smPLj?chg>=>0foUjNX>-MImD2zO=Dv1 z3m7as&n^i!5|@|p!dA7=L;FT#qAb)=w+FD8eG*IAN70D%A?gZ^hx(zhUT-$BTG+%| zag!@tDo|vW#iq8}K`x9T6@?)#BLG2b#>uWg!gOiKCsGW=cTQjB^4wZ**%FE2<%G~o zgyEjx#6_}K1qh*?x-hal-y^{FD=y}5QdP^XnT6L2G?){D)+S0}{egWXpjEWLQGCqU z$&2^$XN{!3l28$`n1#t98*w{=(qhx=^UP2lFHa0g`KQM_p=jWcs) zEIOhvoyjQFT^D;2NenjQcqyL;l46VpL5@!cA^Tcv-c)3a1n>&zNx(q>fFe++z$&{n zWKIe?uhw)q^|e=TLlo%Ru`7j{8)d94R<|Uu+*;3X|7fX!2pWRkK*08yhcLimyhI11 z>mTHu8I0hLyyFhtY(wMz-)ou&@tBO~`1EW6ksp+kUmP_g7{_sC0tB@!3?)D!pO zoj-OE6Ym-UNj*+B zj(`Z|j?nA{QJ4)EnOzC&`QR|u#<=$RIXpLW3aiC+M3f~kD0J=1Rl8GKj3|w+k}Pt5 z03&XJj+4zQe6lVw@d)0sBY}Iz;#jUY3?!xr7^w=M{0h=wt1gki!2}QVSn*g4V*^<( ziA^HSU_J*0W=PXuJ9+F_|0+h;zlxYsfNKeNh3-t9*h(RkK*)!DCJ_Yapd8QgFtHvNEpy0O!J^og>jAnX9R$V zLIVh8cq9mDb!QkNOOwJ^qCFjfA#zHHM-_(n%n1kOQb@X(5Iga@fQAl?2N}(YbQIse z*8mWP5mul=unx*yrx*#zq;h)*7stpz6uX9Ec;Q?Lk%Ujo0G!!MEqPC~cn30fRf|e56;4qWw0tfEMVri*{`PmBVS-O)+-PYypgN3j&LjXjl zU8DcIPXBuSMU$PtgG_tcMkL88QR%xd;bG6zVA<=p*KN^l zklqUO&>qZ^v7gwH!SJpe&YxJ~9VIWE2E#;?lKhQB$p~`sDDpK2OC^UF2%5Nh2P%D$ z9__46FOLlZ5dY%`?&m0s$@dLn?EV~zH>#Nb);ib0U?C$paShJ|FCH}UWt|H(;m8L| z$MUY7sZbe-AqM$SJBbD|un2#Y%<4K1)@ig@yTK24ZMX|rxp9x6JB^he~`RGR^68v+i*LQo=Gdj5UKvREQl z=R#F4?_DzkZ@Kffe}eVs_%BNrMu3vUaz_b<)3OVlJpD|O+xyY z0Fyv$zwVIN1w6Djh%GICo4^C@#HmwF!HwzG=#cF~ZrnOO^Y+0*S9eLv!q$4Psqr)h zCbKwqk^qD&47N;nOxGvD5`l-NYhktQFfFKj^Ky;x2@g%z1y6Fhm!q-qi$D1=j%9{X zT&-Z|yN59O_#l5v(HAQxHn|=K8G5Y+&@_9w!- z^yhPkC0vfecwz2UEbBZF;+ncTquRAOmS_iQTu8yryBRi8GI~S4n4-kFRpt52q%d3I zVk&FnZBr?X_t`kPRKv@Q6>K&fz4Ouf2U++kn@MAw(oZK7GH;3T-r8LeWhGp;d>)f4 zpGU5AMu=V`Qs?7^Q53#THuh zEz{PHi;c|^r^T){8r)t2KzLCY`b`3CLklBefP^66Fo7ODKLLmr&s>-NB>}5Z`+=;V zPe93wnGuF)gm=n`%GO7@Fo=1h(%m<21WR{&j7zww=r*U@7?_TrA^e(TBzN~k@b29) zQHj%JALQR^r%vmb0CYyyPU*tn2%i>4pw-<#_uDfNM+_E96$e)eTAjm#-5{51%%WAon0l{dykHq2X035x}AZC|3!=)sbXD1uBFg3ebpAl zZnyvVf!Z?)L?f!Tt zt~Tbzq*W0P^d=O>`5V9ePV8FkL$%aEd8LNj!6f$nqfw;BL>-LkN}XAW;&hdbf1}vs zqFNk*p?0LK0ThLlC=!FBEK-!Ya&HoSI}_~opr83?*KyK6e zr`lqN2m}`Ws60-SU5Bo!^2Z4rddg7 zd1kc=@(**NE{cRnB)Dz_C4>@;juDnAfr9`EaU|<=7+?J&hVxIe*pWWd(hLO(f((R8 znx#Jv0S~_KBt;@SHR3i=w+FG<_c&Hk52F!D3!$ZnZ^%v65c-JKd=Vo90}LX}oCIbc zn!rH-IdL%)H0aL^*2lYs1v^eI3}PT8dtik2Dg)$!2oE^$XOd;pji=cOaV-`WHeH-K z;i9~0>QmaSRo^|(V75C=jlJ0jp4=7Vowfq)X60T196Ux)yAY(yfWPOBgBTY+5TeD5 z;@ZSsq~j6XGn&S?t`y)P%wH9in!oKN+zq}%7t<#r;VRtAUu?%At1RmNHKnV zG=cjkk|;MEe0#2po0~3&WDaxsX`yrAb~f-j`*kC6#GFlxZu~vQ*1m*zb4>yVo!L_7$2PF3iYHaN2$P-g1R9+F+HDGbMCM)CNZiHwBgl;+48NKU7RuEc zM~-AtXSjR6fX=(!Cfi=%*q+9~_~E!$mcE~4=$UOampO&XwD*I-0ss7#gy6QO+L z0u2jApEj7%`l>YGg*9Gz1;0xN&a2*)H zfL@SY8wRNIfQY|+6!S`TVJMxnPJt~mvyMe$xLT-!3f?gYmrghhAWYW5(4v^G5@kQN zdxH{A#iOj3aw<&*j16jfVk79_hIn?x9Eq%|;<;6B7H)$GF%VhITrXpN)ej&PcxAD4 z=!S5cecduve?>*+B zJ$UjP_26>iYdhWvZkPQCfQLYT-V*cBaxE$aEE2F#{}AhtiA9(Oq*SpLp=Im{9>n4+ z7HyH-MHU-U8*^?37xlV>|NW2Ohld~8gUkPA5ru0N_KkA&&5b%5)h5ytaSR;GVBl~X z>G1?8IaH?~VkRo9brh~wuttffE|wTM$)!QL0BDycsB5A}nT?P}j#H@fBJJrZRKqD7PMc@~5>)Z? z!HE=(?dZqFavUpFVtmAs;Rg@&fep)YFj#yE6Dyxbx_V8xDwsi$NQJZ@u^1w$1T4x8 zQE$L0lct2xplCjsCDV5kNixVB;&QwiAVRq^v@1kJt}sz-MUao*frZSI*tGW|!rBN= zCqTC*H;f&l-DrdLFTBtj6tcpG0vi3ns0baI!WszC7YaD=ra^)L?SfFCTZV&@wezm&FP7!GF1%b4`Wb?N z!gQ$+*0af#3RvV~Y>*C%rz@NY>7>N;Q$k9`gsXAIHYjRg@39)DmE^bbtoqtPsX1T zOi>LCQfz* zKqQ-nMQ)bmO}Mlpr1x()Xy)_6-696G1Sb+TXl6q8um-#V7D853)e#*$2Ka&uBuF2z zn!FE-$wyI(3=1|w(&d?C66s`;$3wNzM77=!E;2a{)aF9ZoB-p%%!K?;9bD{i=h)hDw_u)^UN$dQtBOU8v?N z*KG~xWP1GP5`Z{1M50|AbsoRM9l?g54h`=3TR?=;MJSLUvxypd3A&D_kMQb+Fy1ym zp>`!`!!NUg2DBKe@5Q-d{wUU=RTn|PK>&T4(@aEiA~;d=hWegC1x0f4gG#2*xVCzB zJ7!`3u`I4%DWRAbS$Et0s0|@~&o2CqAaFZSA^aRafG}>VMRz=|f~Me&0}q{d&T@g( z@7iVH8}A$DD)B^?ZJ;0DE_jdj|89AjZGtW}z_bfuo8W<)NuH~U+W38H-4>491s>Xu zC)3?Rd04n0lze6a4}|JlMrWWs^rUaunRw}h1&|PV0*FSW5K&?v2tcq2Y`R!{p@5|q z3hb&-p`4^|P~SJ}R8UJsVWXzRyZhQ?+*JWvwJ`b~#3*&HwrC1C@bNN-2K{DZ z+C(inh^6EsSc%_%_)EGR_eF^GwAFtXo$KQVjcyOKAC_-wyUSH zFqn=|*M($13=k3~GOi)9j+x^G-aQ$)# zn^b$J+j6WnztTha-H6uk07M%jWTr^=p1-}}@bCCLym8M)&%1`22tFgXO(SgfMkk#` z%TC`1%)h(fK@3(=HB{?qdTz%M1Q}>MwbKs@O50#h@8iHTY>jyc2M-E3h-VSEqDqst z6%jr~y>m83Wt$o1X&+4gsJD|b{hmDDEf@8wga7S6y$A35z(L>ZQ@ZNqmkU@wUqZbg zd?qZC^pYit&*WM9G1VUo1VkhTrMM=?6Oc`gidvuO?>rpe~XQ^0%Z{J+!Ts= zpdF5MYtRA}k61W9lmY>W(@PaxS*!EHMQZc=$C9A+^!d38W(!R()i*_INYSG(kgh1R z-JiwiKo&7wW?L02Q?^{_9BikIk^DC}{dA(f$e&TQO*3M`iboOMJpd~eXO{(K(XnhB zNW?goZ}a+^5Mq)$qf~}dmid<%B&diB*`fyX;8osK8VGp;H@umwA^;*-pvfdTO3|HI zNIs5@=n*e*1 zMgxtV1W6EFM1qSfN~A5vNE0F@jTURhk~P{qvd6My(aYHKOw2gOo*(0hi5LfIQL?C& z6e&>)DJ~*F5(EfgBZ#%Tf$m0culseswf4%KIOp7R^X6JvuN#zA5kSAH%F4WX@6CI@ z`!j-fc}um#%r4UL^O+`6=IA;7PyGD%eXfZu8X8rLmBLls*Tb)hq9>%SXeCc zl|Tf6MRub){pqqB)w+*kw@>4h6K!;8(=x%(2(v*BCs=b>u!WRj(zlpX!MT`z@lUJfWxbbpyeJJA+aTN6~_DgTX_J zii=%aph?8Kj|UHS?2OAosb8fdc|lg;lyTG3ZlKc{;zxh_4fvn`mv?49TvUy7^W`o! zPj}RkO$oNhWkFg9LlfUJSHrz~TDZ79#5XQp&!lt2i00bWpOHiR;Lm3A>K@vwVTG7JOpxB(CXVayI$LwlXF z*48D$O)+zRj)U+Ce?xe=-~(M`Su?Q?Y*MIgit zv&>>5T(&adYH^|}cwDPf2nHPtMniu7hz+6sru6oluZ7yq5lsTx*@Y7i++tu+Z}_=L zjz(5uS)`2d=gAhb|9kiH6h8Ku4`SCI@&D(&D0FkMHbQT0$XbVCn_L;9h9~z0MPZOG zqCQ_ieX)l6tVy0!aLxxm`vjhS{2A=oTQ>m05!VHjDKo@et%AFkh+XjT&6O@L(;~w{ zO92}kjbVJOzPPcdg)_!rp1I3|{AabgE znsp9KTi+08hsoz4;31x{-=C|)pKh=ZnEk-?uL~l`l`#Ud5WFiR7NXZj(Cb9CE3Df> z4S&LqqV5Ww^aeaAu+aDH21zp!dOQ{63j7wfrr(OK=?5^XEW!(i0tOvGNbkw5K|n%c z`DFktXpFr#eXkRYvUN6yfjGkn&_uHmv0z$AOHLc*^>FnMBIt9)eA2%5Ht^&(M&i;+ zzB0D0VpwEv6x)y#&T?5*@?S;kjcmZ!z?%pgPV&_7@cP{qu8d1B8`i0=1?#$SMU+{t z3)xnXwt(jEkN@yA_U!f0?}m8vu|B@?Xdm0%5H-r$q%4Dp;x0**EQW?Jwp z4=L{)Jn-(#?55-XN)b@n-JQY+Uf^W6(d!QJ{XcRSKK$?AJLz+EUB_QIdj-G!|9zf? ze+LdpbxvX+sEMPI_)%|}Z{Xl`4X>>Caq{Yb-8!r$H(4nqtW&{+@!e9WX%J%XR26UA z*T9MO5v~O-?46&L1WS&hQUN>bH7G1|xQ2b#{v3PPK96d+WvXSWL_xuWF)|cs(Wvr& z2m%w4F2W4ClO>dYW@viq z+FG-UC!RaQ0$mmL((|fVggqFplHYxA1ecZ_+ioOsT0U*vM#@#jvBI<4dR z^!Uy}gLaz=LMgOVW{CW&+Ji$gKJM97!F*k!G_=qZuYoEqjkzw8nu#bCbfp6P*axSv zdqMh@cK;VwM)>?gT|D>lkeL8FCRz(j#z-^1`gsH%B8HONl?5Km^q}8T{usKjS0Q~+ z6Cp_7)5T~s5O<80wb2l3hk1zD7Rg`HnyTRF@hO~qejEK>hNEDDRYvUz{Y1xMf}iIe znhPM((NTS#&Yxn5ZxV}`c_6b&YNzK?0^p8y z3d-?T;m&d8Mn!FRdd4=eh>0?II!UHzS2P^qr~c9X_{m?q|3*A-W6yE<;yQlsBVWSR z%Tzwt$G!sE$blcgMbL~ z(xjXUK0z4G6Cfa8N9HyH-zW41@_|SW&uxH6Q z!biY!r-%61XSealvy_C#W4n-k?$Y zeifbi9oTF>fPQ7a0TG5$FhGI&Zb15o-jHi5SeJ+E&M?NU)*uE#qA;x3(z+xfU@MU| zGIK0oNF@w8znTG!L(ihS=0%~tHt_&Igs zxYY1)*HRUGr#xG&QW=^UgJ>Cy2t3gDG<|;LduOm~UO;!W{sYa1htGbci!Z*|1^R$b zh3zVmJ0fyjIH8^jUeuM5!9K9d!s>;Lj)Fii0SO9ErvG@V))=uTD8ylIaxihj8j+I}v41h@N>vXqE_kTVq#?UeF>4NR3svWKlc%I z2?UUOkX#rXgKJrd$gM$OqKeV#wp0*e!JCh;-#21Pmw9mX5BfYfE(iewuGWD%-2n+! z6XAjltxHbh$uYMvKtbju@TRcccq29&_haPEMfr#mVoK3RNajJFg*NxT&AHTs?5^Y={@0aicFL0}jdOpVMp`%~>u;&$xt`!iXs; z$0(+4g6bp=&-%D+!AGm&*_s*Fz*=pDQ^3lkc&BOj!ylNzuDJw&plMhIzVL7lU#@mB z+6D9<4N=|nP@_nVOxHv_=Yw@M84U^b6>~{WCP_UH=ToB38PHR-1-Y$AbV6a;^o;gQ z{tMByFj!2?r`fqG4jygc#Iswb1blhJUgk(@8?6tt4DW=EV8%r>5P9rFVy28Sgqe{F zbSDMBQ=~0=ik&eSWq(%;9=M_T{aymR=&qK|l2xE9i;~Y54wmox8wDN+vG<1|Za-YZ zkAKfJ-gR$NsJ19(G7jnKv8#F5+6wW>2Rr!0gKeyB2B_DQ<+{uRVvxE|i+*lb-+1t# zjdm9RH}b*_;}rbhL;>&)R{W16lcnj-*YCl1f8Xu+j`!Y#gGc7dJgcc=NMG^tia~E%De*0~nU#13L`dN* z0T7g@AVAn3hM$Ccp|5UbY^thd>f!6BYx1t>B>w_WPKumC}>n+oN$U?Jh| z(9ap&y6z2!c~JKT|4U#(83_T3l(>6XS;A)her#3mMu0jCEp@u+0JA=#Pl>2hAHfPc z{+a;9lh2C=f(?cNc~Kn*O?o8OBsO0S!lkh#4~P!SG_Xon001BWNklqqCX|(LI7PU(mqvC7jJv=o3DMkJ91s|l5pqCr+s9+-LR-hsN z;qRKo(kuZ8r|1m>2oIlsw1bBRU5t(agLNP{19%rh)B=y$h^WsKIUk%T5i+_A63x66 zcak1YIUPKNlrW0LlkzMGkO(Bt2ZL0KbRseCD2l*v39JB^TdZRL;TBFjx5XgjwR%Nv zjVNTk=vuDZ%X{~Me`;Hn9%|>45(bnXCKXv`X2golrvqQg@3vFdMdEjHLtAX9VjWoW z-t~+Tka7)W{Cb5ECP^SuaQzzr9#rSBXWqvL-!qN>=7A|pO;I+byh)n`Hv}YnoIO9p zZ+y0mFFn~~#7qw?qit6ZnyS^|_VjB99u&N}ndBmEgfh>ffe;$nSXs^)VDdZ|fhE(D zL4d_wE!=wNF5L5`ef%$hiG`&WT2nPqd~+7T5dGc|+gp8HyRwaQXVw`woOrn*PkIMht7)BR)_mN*w}GQ`RXl!afYs^{%Lh!%B|l__9uXgluqrkwjwF?$+gO;M z!JgSU)T>n%qgg{>@DaQA{VFI5Vb{i^IB@0DnC_opFhLv#pTyBOsQngwgc&z;j7RPb zW+8-q;G7mzFM|LCZJ`Nd7zTn_24XAfRa6!i;1Ph>*u-e%S_B}7g&-XS10Dw~zGm%fd!*(2emNRS+Tns~zIztS3l$7v8z0JX;^B*rcks}57o&Z^pe^$|+ya6NA$*D^ra5eMQ?8g(bqUlb zygE2h7p}&NA4!_`G`<8PIBA#-KM~f!fGw)c!W;*=>>T!iuO9&OyJ}cI*ucqWx1-FY zlcI?Hom%Wn%0|#kC=yvF!A1dq$O8{aIGR2A#E1%_iKsADyvm{+4jz=~wBQWT03$nO}SG5RHwqP#eRm;8znp>wAd^G>Zmf0$HT!KNfEpQ55-J z8?6dvW*eB9t)bB*HbJh_?+qA44ErNqRLItn3xpzBXxGEFF3e+fe4&Q>mm9d;3GnE} z9#<8eneuS#cqLY!MR1PR$IzH>88=GHymxM%!!v~zkJqk{5*QR}MmmQVap=mYFu(n@ z+*3uOKCIRu1t1~;Wdtxxhj2nIJK(}f&^o|O0@qxRxiTtqbMU5GqI;)5K*M)CG|tvW&3`igX0j#% zV>d_4*sx&7A4Y70x-|qqoaHR1mg?5|X91wYLKt93>jjZt%TqqyvfRL2-NzG```Ek$ z+}o+*$<-nL;6xvr14<~Cd|)R74N3dYkp+ZWJW3-UXBNqoM(cdl_X~_p-u25^LisJV zfiUNhSsypeR`_oMHq5kHcZN(C>Z_%>3clm^CT`wCngbIm%K*p27oKY4Yn$T27<3$# zhunVa0M4qBq?)`)&PU=oD})aGf2N9fMHx16t+tY0&h-a;fSTs*SX;K z2!V{n-F58U-(VMpA%t$M5F%p;@WC*Sda#QY1N~0i8vP#dCl7b<@h`M->1u!mxixZs{_O(~Znvde8isy| z2#Cm)A#InPx0_~w$I<~7WEw~_!6@F7#6GpE&*5bB8G#1^3@ke4bFt~cQnP}09B6X! zs;^({;q2Ck@fg_y0t&~DS1~hdl>RnUFe)5GW7(|LuxD-_^HWl0Tc0-t1k%frMY7qy zgafO8f<0>wp@JUk9QYn}C|unk{Y+gK2|!`FbeZ6C4!UVFHinG|M?&>0bHR4F)r3Dg zYgh?MEEQ~bFj~DTAVe7ryK?I9)%a_pGNLgQ*+^rgFJd_%#C5^Rw#+d$du65zgU+Gu z4gnY(OzTlB{}i?=cVPo}VHi%+lf}2n%{HWuxCTd@h4As`&$1|&H=gQuS67A`!fCJ* z8Ls(y1^4Z(L5L?G4-i}fe)P@;4$t`b-Iw}!Y-PwplAqrp=ON7f zSiYck5SvmX5a@Z#uy8>;vty618rKgRlB0+Q`qrT(K&p1cJRwT|XTAs&#SAJZq$dbX5 zfZD8ZUj`660}p0F&1rD@1D^PuY6$8+uB-<5?Jsojr;l{d=}FjU@nVyh zjn~0i#O^0`YtaW{Xe0lpS=v+0lsXW`P@0O7p3z5;(PPYDJq;o6Vu&_nduY;K+rLEv z$@K6W_SSLFt{Prg8{tV)vw}Xi27lyX?|vVLj`)yV9P*89&;wLi=P-+1GgM}~VoOr< zi0WJ<1VB8vB#efL`5(G@Rc8a%v4cvpR;ARA%dodaa0}8mszK?I6 zx_~PiZBA{>{1`=y^w)rzY9F_)e%UiN|^ut zy;c0ctqq*r3h=ux_HelqBGUQp3^ce80G)vhB-L1qIm;WTiNHqU`Bywi zQ5r|*e6*@0Hg+;uI$}t2Va&FCyzS-|?%dblNT$Ddb{k*c=pvW}2Hog)qB-%Hef76J z__GzXuMXfFSFCRS6r{-JBVvnUc_X-As9hm5jy%q$uZR)hJ(?A9JBi4gjv)qO_i_V^ zyXrVe0K&d@+RtOrMd|=*KWjaFseGKd^1sK?K&Zis+FG>O7u<*$bU}?`m7yG!{qaB`5q*2cZ(r7e++wPJm z2cUX1X%erNKUG!#?o2NDpBEguZ7%9DODztA~A93+_TYST<8g zD{s=RRlkvpq1>v`NhzkamIzJlwvkhI^K3SS451g+4B~Dc!idXxJ{i z8sh240~7V+p&tMHE{3l3jXZ$01uuck)GhQ*ee%Lmo|9m*Kil*$eI7UFN~um;N@XdvMn* zYV+QG4a_apI1}Z!^Tl>sqjBh-O)^1V(h_6i#Q{WOU~?IO@diAKE{JyA^tdaiC=A&w zq~OP2TRZ#PC7R3vTrvn^bdnl~bOt!*o^}cz*uc4c6a7s{oD}%)y0^j66*nKQ3FBbn zq{{+?tZ8h1Ys7AGP-rX}bw-Vp$-tLP*ypJWBW5EaU>k44w;Mb}b4KY*vA_v>E~4p4 zTxrF90yU`n*-fD~&9Dgcon*ih5!g)KV-eiJ*((0(@&G5+4DD>oSR1B8!@EpAhvRqo zn4Ocwe5TpNzJ+NR5KyU+!P*DfxoxbcLO59`!J8110Kv`uU|6B3 z@}}NIhKMp5%1MG$bz^Asg##dB`60~rqK6RRAi4<3n<1ZxyQGSCco=KL+t3@$!3!nx zWTook%GFJq!g^!7hs$eiboylIg#o*Hu7)@6siQXv@Qn+7yt+y0$z@p7*wLjZdDOYH zA{EgWt@-2~p<-1Zyp_%Y{N77_oTkVq>Aut}e?uY%vxdi%H5c&UtScO85HhG3pWU$h zx?R>-stahY?y<0Rz9DQxECsdM=@T%Us{3eGd|a)J(5r> zM@6ux59r@E=Z5EJn7Y7aE$#K_+Ot5|1j1F$WG(C)9nT4)M7P2H>bNhm?w1Vs@_`0s z=BhaLLc75ITei2#9mj2?C?Dfq)nDamAR+)!7Ch)GlhGinOci2_v<}(EJW3@>gKl^s*6HVkcugj|0*LPYy@jH5^My!J$Sb|g^l4+toM&#G^(>Z>+-ctiRm|h zn*@rh>m3ZbeFl}3k@1O(eVkmAdK;{Paf}>UBTA9+^@m32(oWe*Q zabVhKAt}2x9F2)=Tuu4&3NUH`eM%D7H=lEKgoMvl2Oj*H3Ihn3820od^GVjg_K`K=pT7St+yFfXKz+7~5RdqX4+@SFxo%(V1??l?4yU>lK(6 zb8Q&}xtGW&78~eTSWIl-lGiKS?l^e3{YVY}{%003O|jIeu*~ZO4+;wGb~Oh)*wHXx zgYL8L;VX~#@UMS^%2hi{L*bJ$4hTBmrx9MkoJcy;l0Zb>+ol;yJ>uQ4=omyFVJJQ) zQiFHYpcK?T-oC%iO#Q)t=@Qo=kUkgN> z8=K^_x{Nh@gy?7Bm>4M!dcS5Y~Y~ zHAIK1=(0pda;f-34}QzH41^Tc3K3Fd25DE?0X$=DG5d&8b83*nx-Ho~{A4NVdnS;UJ%nK^n69+nrTaLc|0%udy@d<>Bvhs%1b~>(7o}MEJsD?{bc$RxoHIgEp1Mzx41?j5ZNuD< zO;;CTe&;5XG9jIwhISe~gar^Bo+By1qyGrtR2f7Nd(s^(;q>L*xV9I=kmrZIjF%BcZr-F420T7YcQCJB6uN$HolDRYfN%AAA#X-~4Oi^uP zey>O_mxDL8n6)}{vLm?n2EWu@L2V!Jf=XYU0quJZ{IbDk=70$pfSBQ=hs0jP{i_I& zIE|ukHWh26jA%LVAnR2g07)1bw?8IeT;jl81SV`un00VRxjcB#Csi2?TC}ZUx(=Z! ziSyonq=jGo!CeS%_2GpBU|W62MYFM>?ZS~e+s#-<7Ef{dE!ny08n98p`LA{GQ=eW% ze_RUlR38+K@dV%@eV2((67xcp)pS%0t(*SPU+d22$XpfoFW0a!Aa}(O8@#hLjJ#9n zROvwVbTidTbueZcIKF=Yd*;R95cR#V>|ysI$DhJFhZ?3kXK>{5r?7kDQTP~{ERqRU zfEuX(m0=$Y7>a%q&jBHF0tZ0wxlLwD7d#lSA}BG6q;P=)g9#TzP!&wx78>^kmHy@w z*F)(Xb`uyE0_Th{ksb!kNVJSxm{ssL4AX~KZ^ENI7@XvaMym) bKlJA1tAy0Gqy zEC3x_&!v~JmIhVp;oay65zcPjfz)}6H3NRoePsvm31RzYL1&L8vzww7r0K%xW1LKIDE9luCOzwI!=jz@xL8+1YMpPCaxVaY0t*b9tRK; zfCn|4M6Jemj`2xQY|!HXLO>#gj>v8_zg&3wcRL0T{KImf!##=z!DLF!PQzUiKxBXy ztzSSIlJaz5`W_fS+|R|lmCfF=!o^3lov?WEvA-PXKW&KNWOh&C-VHIH=;yP7^8 zUm4)^7Nww$yDRi~eVA#!b4l$W#8jh(WBcZDWRH`6+W1-PEf0rommCWO9O|QW9K7;b z99aDe)PhX`4(d~~H`Wd=a7M5MA0d<|pNjmswj6zbA& zKm?s&L=}&mIvXUiB)~+5pRtf0Z-9iYp5)w2)DQt3Q*-beQ_Nscy5V4JgNq(Tu8k}( z;YMFL87iH~3}ziz51~;R^e;uaRN=8`)qL+u#nC~~z@^oBTv(YxzfbqCRD^L=fOf69ti45%zJY88&Eq>3D|r7+HC*e4_>)%#Tw{fpGMl!# z&;sQFhxF%>TcfDf!i@tBSul!NfmT(La81`J|BbK)92Mx~V=(rV83|$`f~qGjjA&RQ zHiFhGb&Htq>0TwpxPWB+od6bTnY~^q00A61)?!!J*_R1G6xow;kRkeB0Ti!CH{hHl z0YubzF`N>K&W5wV_)ZEQ~% zz8u0kIRNL{sR9?b0{nw7t}%d+JRv4ug8lhlKX|a};~1cIA6T8Q(v8O#tGH{ahO?U^ zJiR((*@>ny(7TD>mAs=6Ihs#Lm*;SNKUK@D+LX7kc@+W&Zm(i$Ho)F%U&E1=KgM+L zRRq>qfs#w!^qKVoZeoj&vlE zxRMPnbH3DpR3e-r9Gu$BRDROx9gO>c8m|&^7ZI`R!-LnHhS#7ZTSm7)p{x|^zOl}c z4%~mlH(O-ovJXc85OZPZd6boKv=0m<6hIJoAQnP_L=|3z{;QzVZ{Xa8X{=nXOVf>F zpBWY2pm^x?M_9Sm#zv=yr=JLL`c&F|kqsQOjSd+)5^Fwipo-V+s<6oN8!ICQ7uglT z%Y%lbDPw!VJFRT@Y#Q=khoQ{zxv0;6w&r1Z+UI*$k)`S)Qu>IB$JJG-uMGKPK>@9$ zyc!z)iUzZB1PB+flO$UT7|IGK-M%1~)sb6T7!E_6JDmd{%KMlk=@z*JX&t)(z`<@C ztqY^XF5DVUjZ-f$WIF>75rB~K5f=fyqKF35^cxNy;@3{=I3#q3MUtuAa!F%aT5A%y zV&X0mbDa`nMRyYe5K=$ZI_kp1Rp1T^of`mKge;=G1$H8r5=rJf@N~Jlhp<%xRscLd zfVXARU2|7^%s>!;=nh2#k?#&F9-H(|tQ-(@0c(U=qTgD7uubZeUhafJ0Mn#z+)D*= zfX6Qnu-cJCQc2Jd4P6|R?^~F{Z3h=IH%*4bNj+^Y$w_V)So_#JwSot{|AeLfvk3h< zLJo1va93EiA?|vx+6TpijNIb6A1nyqhtEk6WxN&>X^qvcw>A8%4fkB4`YN(DuI>xKi;WcL>*N18q2t@RH2&gW$adU`y zpv^%g0u`jWa7C8v%5cLs>DY*cVAjEa2w@*Y4Rc0gT^|>B+ad;zGmY0ppqFTi3PLsHnrenDH9Z!U(#+t%i)02+WgRG*gK}ONU?5u@5nK`j zkzz2+xN+uDc3)`0t>_xb6(sY$5py2BwS`_U!1=S?>tYMiBFXCjX^93415vo6P5Swr zi{}`!Vm2Vzf;{6JeV#I+iT3VD_n?bUWI3FMrT2)|tx)K)DH@o>ccqydX%#^f$iBF>_aF=8Aj&F~A?hB&z{ z9i5~H(=#d>4eIWLyJm3vp#{veYLdZ@6OQT3HsFDk?j8>8tKgk`p2Ez@-+@0k15jcn zRm(#Dl6>nXx;<>9MeC5IrP#6qm>&v2T7`FsN&-I!O)|2FC`{{j5! zI#8uN9~q*?L}W!Q`hvQF4SNJQgz&N*001BWNklq2yk=DVc+ zLPNw{_l0$LB)|i=$%J*f;z}~iBxh%YW-=r3>ZQNeuuat|$c+*Epu2x|lUU;}Ab`FL z2ZI<3Asu2s0cD@G?1O3?tpvFm} z&Yv2fM|lT`$)fC&Cqk^8kt(;nL4a3QI(X%B7rlY0y%L*h@%e2TfK1;v89Q+3<98me zVzJ@lFV78eVm+?iDPvIb)iAHPU;fbuy2xH+(EJ5%eGHj~pf< zayu9u1c5D+o|qmt<51Wo$pP=K&Y;Y#%r=@ znsOuT9+dzP(WEQXAe1(M1qf*j>ydXWR)fJl>7v9XWv`uWbkuJ~&9q|9lCFb7Bwo7j z5@&IKXQNdtiqF1R0ubMQQw#t6t@A7%l2-=kU>+|3maFjYuAwqD0=7u)?z%PdjWa{_ z0Lef$zov(f$}*n`5x!(ZnjB`9Hq(Bq_5!$N@HT()Gc2hc+l%mBu%bx zmGwU!izM$_s~$^uc5u|Dz9Qil{A+(JR!O0uQZPp70f=jj?os~*B<2f!Moax(@;cZd38=R67^e(p=Efyf5{sxx5Vk(umd z=iq@0kaEVqV%9+y=c98K4ugAjE5NDs5o=RLBpGkRq~IY&=7d1M7hrkU6u$rO-imu) zzXyxE8&WkeD+Y`V4his1d<~7KK7wlJDaokAhSFgQr~@_Kfi^IueTXv(78&t9s#idx zDKhjA$)r*ewi1CWM^C}PAjxLfJmBtk<{VPW)J{dOO2)Tl;t)ry8Sq#?Vo(to=w=IE zvk6p%h2XTr+dbA4SXRO?5}W~(TzT|fX&L@oT_KTJGL}%v>K)P{oL2Lot_x3?28zy* z91)bu!u-pB*WeK-q>P+i6&KG8@x&K4asI@}fQQ69Gi%h<%>kZ!wT-pyp`D7k20HEc zi_KpW4o+2px9_jwrdc14UK-)qtHw2FFQ320jsp%cfTJOWw3K94_AEBGv^F#d0Mvl< z+ayHJismY?2TmX@0SFRW5*QISLh>8M@<&ietx43SV1vIm?6`i$Fow?&6&zFMh1anX z;gh%AF^y}h16;W@9zfW0o5XfyV8SHhly^RdfiQU(2)*&nKBv>irlSQ5HbNcjGppRZ?+(BftYc2l4C0QS?sQY~r_F7mIUJ0ub*r0D{nY?4>h2 z!}ww70WA;y9d%R>dGNXepl1qu=)9mcb*6$*r-I?LBjDoDs_?TXTU?|`MwcG=pU(sk z*>l2bVPcEK&cOp0Am#Z^1}=MxC9D9^yFPAPtg%&2ayWY4P zKl1Z;;VthvfZ??vHcoXg*c!=hJa4Ly3!~dX^_kD0{^D<-621yF(r%4Z_-0A>MNIo( zf1{BXhN;NVPS`dpxQGD?*X5zE5yvHABRwJzA<-HtSTsO@Q~eo`O#hHupjHQ}WRT5H zpKEXs*zyo;b>LCN1*gY0E``yE(`XApt)M{xgcH8W1-A6P5qN4I2%8VW5lve6g)kok z8W=!W;7}7?2fHz9@Tzr;!WJ&Q65=mEc@>vV4^XQ~dhFzjqc#AntPk+wIf~TalyvO= zN>lh56DMbrD9i;FeDm?neHE%Fg|D0+VYMqpI{nlY8|ln7A+aH3k)?I9lsg~id+FI{MZ-r?I-y z$Li&NrVE4aQaAh@tdtuHUj|O>>=*_RN^@oV)}0fV-a(f&hRMM$_q*iujm5SWrR*v& z;KB+E^_4OuxxXu#sEO}h1Mr{^in0;(-W48_3xfc}hu<>K^qzg`laLwCW7=)>5m>6A za(4~Yr4SxDN||-=Fd9`bJP{x~WkNx-dH-@;lEgA`X-Rl7l&SmK#B!Bn*Lo@i$Pu+nJ zeCQTVW2>)V7@~cyhpkt82zr4Or^@<$1n;u>capA0T)hKr*%gVYY_=1HKIdE0@E1Ff;d^W-0YK%YePaXHRMx; zkcL*_G=d5)G~z)*G0AAt&YxTa1R}!02w{5==@ks?zyN|HUg$pqE{qmJ=o{5TXblW= z9nD0k$GTyg8300b55%6R{(&-Z66-L9ZhHou)f$E!5ACfXUU+5$r=H)!h_nvG?kP#+ zdAPPcz)R;l3?QQN(uTt4Lks3f37bLBK-HscsueEMMIy_muL$!-pHKWM_>CrNb48v- z=U0Yhs^(*{S-}bwytDQ=oeftk`zu_mxtrBV8CHQI2GV<6o-@2T3I74X2l_#X4Te&PRuw|;niBEr1{81 zU&!vC07N(l#Erm)zlyNmx6v5c07Ak$wX}Dne~9ZUL_C=Y+vErh0u9nG8XsXH=zRnI z!93dQGw5$f%>{KCQAE$`r5?WZ#5&GXP5=%q3~};e7iX_@Mc+gszZmO~@!U;p@Z}uz z+z|6dSsmZDuZp_w;gL&2T-YY#S7N_kc-?e6#~DUWh-L1T`i5}!T;0cIiXxljRS0I} zzGwr{H0}ll30lj-bd0T6;;<7gTT#>;VK^kbHOUqc4!-5iXER{8{V@A^^ zF5T+~0+V!`d#v}a1HTfMD*RM>2R%6eam-r!K1zZIJ%`l>6uKc)>ycL6$2YVEhOv+) zbADHvwMp9UonKo*r6|tZ!~2f3@Xzj_L!VXvRjX&tmLd=!PYxL@3m3RJ{21^M9i6%& z8Der_{NjUaT#<4t2#pVnJ)eR`WzW*HPd=gJ=wW4sDWVTj?V?+ps(HA1w!)eDUfvjC zol5-j?dFeb-gTo3xWAQ8X`!J7@NM6D5I^+OcjC5tmP$Xz{k0)BU+JQEjePb6bqk2H zABCu#{3`0teFU|^H-RR_{hQnojs}9eh5l!awt3H=8z#ZgFhq%?a@-f3aWcU^Fngd; z7EU;*Wf@c)=~nm@Kw&i#F(6?=Jyq|a8VF`8suI3QRY=)Y;UOFjOn7LW-v`@$?h6%G zhNBTe%4e+Mo7@>D--B^&2n(X1LzxH{Ksdm`6;B%Xg}7e~kf_!$3K!7XT10ofilCpJ zA(ktzjzV0#(8ZU(x{AN}@?{1QQ~{HVx>@$I7&wf#HQDPo&3)Bj-!|{#b-OE^Gvdk1 z0dG_?39;OZl{0vehJ&725i5>}D%N{7?i&ISvo#-Ax?=#u_?u5{hSaUm^r@~*oL!Jg zyb0HaQ*T2b<}zA?+E}ZRQ;~KdxnN8iz) zc7_4I^KcXY{LOP1aH6PkzfDI@6iv(Q`%AYwehvi?|A+xZ@`{Oe=70yiMkFXr=gCmr zgk)fIom25^&_Y0qAXP8i-4Z(VVmruGwofLQ%)b``5RGOPKl9-?;{88xZ1QKHiZ5O2 zWAjWG!!r7aP8-!{{}_!|eiIe{yyzonPAEVq1P@stA%lUSa~UuYF&6q;CnCdjg;+7A zMwX~9BGN)gc&NHOl3|FA%HG4JsLY|;+k?*f6h>TpG#fk^ ze1PVz8WwMDp&bPHv)@0DPyG5>TzIvEsi|sq*zpbvV!0DB%lOe=gv!~xX-^f4O%G39 z9^uTUq}R^h4e!K4QB;KN(A7vK{rvPf0SJnWy3&_hf-*|2EZZ7O8L!XQcPk*r^lI>U}!7fEB0Z(Ive>5i@)2W52c?O}kw zb-0NSzj+RQ4#_Mt(~9n)2)33vxBi~`9~>t3j~`l30Eo%JLv%(#=l#)$AF!%l;lHUL z>J{2yW{(AZPxFGpxF{J^KL~MllXg{_^QgE#(sx||sM3>+vrY~N0q%Y4Ui{cE+=Dm1 zeR<*sJQ#%7ezk|~b3Fu1$>)p(^+AR75f@N<=HsYe{xtmNmdPLCrl3yf9}Hn2$-pAO zp?^!5rIRR(H~Y#oIH8@c`@#hc3=Z7?G?#_USrJV-0!#g^o66d_G#Dso8EsPQ&# zg@9NH7V8mU@DX$j<3J1nd;}Dy#~{R{sLUHtw>&fs&Oyo7FhgnC0YK?OqF z)a=Td!Q-E0jW#$q_Owwg1`r+tn$_MocgjxN6K^F| zG1Yr?g_V&eBI~ZoUz=ST72vkJr*Zyt59@0~(dSk2>IF@_WMurHeEVV;O#z{;y5<;J|JBC#9%m#2R{d@1Z7s`Mx>y znfg;pkT>CW3LX;uSvVKvO9c@B89LtnA61tb0#&Xihz*ZtL&C#tSD@=RDJi3y0tIT zu8&OdWYT>Rb6q&@3)#+^91sdF6j-PhLJRqs2J&x6qo9V}G4LE}X?Fh{4aJ|G&sPF1^4@Zu-@XCocy6u2nRpVbfxc2yy79QcflgoK$C1o8WMfXrNkDR_N=_Vlth!}`p`U)`+85)RGSGyl%8*;j} z{*Z)n!Z1+=xJsphTEcaqU9iv~cZG+|KCsdmVH89aGhch~5Q$n9OpwvO8N+@EO_ccG){gLweVTdM=%YaNFe1# zS*X!>fkiTWGfV%Vf-fhW)8>KD^T%>SkkNI(g8>ziSHcwD;%V&ECg=IbjTf<_HU37k zVA4#J)xnD>Gr;6^L3J;>!z1jj z2)gE3%verT7~9%c$Lvi_RGMWBhfI#Ieenu@|08E{;#*rW(Vaf+c?@J3AAQWwn|3Qz zuf~(A&)&1E!l2@r)e(bn9!__v#~0|#SzYMoH*0!aMCk&E>o=n1`$M!xdPQX*GH+^v zW^qVn4WL9)XHIspwKe4Ex}xm36D$uohfdHy=M3I^4*qHw^Ao!Upnyuh{+tg54Zcp- z1>GO*IwdVJxlSX%kaT0D?NpwjDhVD^AS7w*ZZOa?J6Wx?Cig0@!3cQw!3O?`1rX*7 zee&&MYnK>fHz%1)WkE;$oD3k^0e(3PK`O8SG+iyR4SQNb z_mb9us)1&e=(f*EYCa~P!F+I&-V#aHI_uOmep3Z3v=|R5#4rHf^p0hG=qGQ-{SWNt zbjB0CLZE%Ik1f(iY?sI%(cVVwg-@e#{^O|BE=2hwj6Jq)3bD;rY{^{{(=#~VB?Oew zIWlrT(6I~_G!)cfA9$;0K4)N}#k16%Vt_y-=CCdZ&h@|ys{s&f{Hww+utLs=ABlxv z*M|rorFKl5frtYVWgoPlmiw=qgW4I?meBW(p}o0;;kK68%os`YRbz?V6;0IVIlO72 z7r8M$_J6;EPyUy)oEAN*$C92qGNsFzN@gMS8AwqQiY6p)1P$ZOa}>Sgp zwe)uuN1!*U3N`}nErq3ELa-&T6l<=j?^+NHP&F$%9JkhwhTn)43 zqYzV572JCJ6kdL*gKmekSSkW9a%1e|?k8+&;&28K`WdNtH6cYhu};*u>jw`BgOys3 z%U&zH!?bE>QOyWfWND2@0btsh>!Kuha34@JrQ=T!8tb2d-)tk~`WhO6;kYTNp;pu2uoW7mVUtA}e^s9T zA*FqY!Z~ej37Zo_M3z<)!EI1*p&B29aEyk*BNl<@y9yzzTr7(l&k-9&vp_5aM=BXW zLBKA^Vj!H)wB|)3H8u}obryr#E$DO(ptnJQL_~(Em(e*?rz^}jw3dw4F^(>L0bysL2sRAaG?u^zCs$oHCG1htkhl1y4vP`a~WejbZV^W^*F{74$PTtsZ z%?#P>OtpL*J>J5p7dz;YIFyqHN3Qq^xo{?!Bd^t=F#w_Sfq;b2z;3{}f~x`}60D~^{ z_;}w<4IG}W;aV@m=g;);+|>auB<_Zt&OTM8qB-D&hQcx_#jNhaa>xDK1RgYQe0sKu z-TS66HB)8drb9!SDgBy#sD_bHO0ipu$C z&^Yl?)cRk8KSe*FRM2Apgbn}92;Wpd!C)ZCS{O!xjhzD^lI{y-AGjSFkrC-34AK$T z15KvTmz34~o}wzqjTxn*mY{w*mjMm5g(e`OMYQ;LQ9TS{APj(rMPeu$K`crWqsCEm zhqs`+-omI)F1768BAtU@_gUjGeW<}>Jn8G3kFB%*;i*TiF-ukDL{oAe-6T~j?pj{3 z%-Q83qa8v+WZ@tF%z^>~D6~ez{wa?c33@(Ht_L8Z$7*~{?FeECB}%F&r-A4ls09R0 z=s#i(HwTgwj=(ql$59#y5%GAqRHENY91?ZTL@2*ce0zm4%Y<%0h(Y!eQ6u>L5%y2 zEgVMZH)TZ28q{xJ$R^YBjKZ}@QM`@%z$k$D#W&7603v7ntXm_`vgGx{IK_AN^#nkK z`0&>@B#~6=ve{!tU}LW4;qTtuzz1)e!osww?tyMU#Gky}#qYh?#ih=O6W)+wdamI! z)k(miGf>7tLq2o*rk&ZJ1pEs%iC*$6)EaxefPkA0v%cfV7S<*_**a}5utHv+7*$x zb0x2UowLy~;hGB#NiR(dBFk2s+fcU#eMC%Tae}2WhPSj`E`4AMfaPgDXepkWso==5 zCQd%z#(-QiiOZh<6@r;D3690*Hd~6OK&& z(_LVM26LxTF}lyc9)TZXApZHoCJG~VX!>`QMcem6ymNmIKYr&Fjx9+6DG9eTFKTzi z!^+kOAAi1$2hR^U-7fXn_CR9E^=LPnouK%{dEDudy8EJjOdg!Cd0^A!d)R+?2J=gG z-c=}gP+=OK&DCd&h9QQ-0C(QI#JMBxe8bYjndr#l)4ABg)|nnCa${_LjqOd;PJ9~8 zE5CzkYXu>v#TG*@cw0j?qv(w62#knbh@w1{eb5LDJ)axC8AV@+sM4?x7IbJbDGG@s zmVxH72X$j@Yj>mFK8V34 zwIN~IbV`^4O{8y_J=y~49VUHsJ0m>w*(>iP4$pT&8m2H_iFz4nn-NHbOTLfL~<1=o}P)u-Nc8 z2Lo*alFzbxzb-I|XLr02fMMrgAvw-eQCEzAG9AD4+steQhi-1-#B*&y=GrKc`XJI2O9W?3?R~mEsYQ8yhNQFw+0u@DFS~b!Idm!u?DCM z<6nGz6Fn1RD+k1nqfk`RFWk9UVc_ug1C;#8Y|ZoBD0K3QhZk1|_|H$b@%4*+W^1BI zsOTEvdrhGD*jy~=x776~0T0sGyh$a0?qZ!;h(@Er_e;+l2PB$MHC>Eb(^V|&YOvv; z>3{QW^LXd`4&uVpxM~*;a`0f^^?DaX8TX!Pj?Yko5uB& z01zBv=jtMiUc!yAh`BKw0i|UwOy)^-SC}Y`nErtQgfJ139WnwBk^929Fbr@ANmOav z8&)K#IUh9Y!hj7190o8%p`og!pgPdA7&h-lXK)<7jT(YMj=Ms24pSA(9BH7nuaWOU z%30HC{Ga^#HGJ+5FW}ti4u||w?UdD(9@>;d%mRoE7Q%U?WRqkJmt(y7km!HXimd2~ z*k|U%&SzGfngkLW<`{%HFztiV#9!)wYs<)xf=xD1aEYwgcks%_2z91Q<89S!cQlT!5G&p40x*@HSg|}0v;ainu{bNiiO0#OS@p57yMd)W zE!1lj$(l&(I3*LRSFo_F3DQZ>bW<+}=_9C8<30E7#@oO10E3H3U#yRKrHk(668ea+ zipqtj(LD3(sN)fMEfcxm>Lbbk2$mB#870*Z2O5|; z+=O2*zc}kSo<6aSKl_6Vc=m~PHau1G#}T-sriZ}h`T$o~2I4Ds>XBuUYP4?C-Z!eh zpuDnam)pDyfuy#{)jY%wQ!rscg`AMC#}z`k5S?g}4$V-10ek{Fy$9@y3N z7$jfmg}fHfnI>aA9pNFlaB|Cq>s^%@n=;3wpFk0EOH^RK08-9P4B^~j75fi0n1LYB zQRby$@#1TgIaB##3IK#_bfdr3ts!i2VuyaiT^Dh~nhe3r2O;?jecW~w7z8IglCBe_ z4^2#<*T{9jid$2rJD2q-WNk!fNC4vJ?sY|!$@Ujb7PVAHb!V=}XUGGP4hWDlXFqTX zApTVhK*+Jw?pD>u`)_LChi_|Q&n$@wUB!3N7-ZZ}#luE7z#qKS#ivj9u+a~=NKT6F zpk0y?V#SJPW!{Girjpk*3xQo_UB7S=Jn)jip<6WO6oyKviHVJvnXjQ*^)Wl&!0bYu zGtp_~Kijv47AJkg%zOj)Kd_AZ-mx63OR%V=Kw7;24|fF?0R z8fr<#KaYV>5v7UFaDKxUgk2P(m0(uE3Ms|aVe>yQ_=p$?*@7GJz-C6>7cQtEM!|fp zkr?XIupyhg{EEB7{44B(fSs^;6Z-Z0(AnCD!4?;Y$(-W+u?IAF*D!OmiQ3HMI)`gl z`uO}GUBuVFw95HG2t<V^nF zjA0+53(BZO{&;7Ho@-2t208v+9%UX?+Dy{w`3yj^)APYY($K}*6u(yoG?nhN#Bh!2 zC#4y!NHS{#$AAYm#6gI+?`z`c@14mOQI-Y)g5;TQ*Es#$8CVR;^k)hn{`I5EK#;3K z7NWN<*YM+av~VY-?lpeY1rChIcuQB?@HO32` z)xsp_?~MTuytsrxY&S^vOOz$q!h=Ud|Zp}G0{s7_yDw}uKFMKl>jT*QlL z8Os-QYq${_hUK(jo{?zM7S&?+g%i2KVn_iIypFi82~a9~NB@usAk6nM06~!)RJ3F_ zhOIZF-MbaNbsv<7Ds$?o&SAF7z<~h7q_4psz*CQ`;j^DmcZDCz147Xj3UFiDyaB9U z>SOhCKXPesBaK@l_GrpVt71HQlk~?6D2UH}1q%F?{?E}w==|i(-YBlwQar8t2ucR3 z*YKdg8o&|4{eh${DeBwukolvigX#Xq@>iG>4yqKhsA@IVIS3DWhPbFl-p710XDjNB{`y z;&9yVo+vV}>v;$@p29(3YfL-22n>nih zqSGGX>PjE~KE1U&bguJYK!?*v7dY@7cR+)UyfDXeeHU9bQ`{6T zu%I`z%QkWh``v7fKrq$taY8+F*2-A_6=I6?mzu2U#%6bnUndetW<`S(gCOdcU3;t8 zwWo#?&v)X?&lvoaoL9V#F^Ex-<-|*YS@p6n?0wg<{}>MY7ae{$eqfoTQMAs-4PRo0 z=C!$C7tN(xtw>VqS7e;1BoK(*Rqk&R1|nmYT0oPVYodT~%KIqFvDSu(PR@Q6VhM^b10HmB%>WN(C8cMD=C;+>kY73oSwOjKxy7NH zG_Ew)7*dd1rRHO9v4OeyCU3fV445Jo!%Sg(L~*knG^;g5YtUzRzJ7__8Wbiv>1(hx z!WQWxu9VbATzm@63m-$H_E+$y2{cg^N;k41`a51g%gI7%^F1U(JKbuWPUMA6pe782 zA@*ZpNl6}MLVi{2pe#i4U+O=HtphIc4BA(zMKx#Yeik0vrbJ2 z7~*3Q{g~Z`_>b>dl!8XNuNwg#65~y~&!&fe@wE+n^>p9pBD4X~^{hBa zOX;SX89!Ff;8MW6R2d-|t(okeGUG|YxW!!}o+N=BhjT{Db+mg62q=)4vVrLtqQ*r~ zN8o{Wt65Yhx1ID6b2YB?`MNjnMxCl3P5A1r4j4%EH^%3W2>V0SUj0k7)_x1M=~L9` zgj*x8`ld1v>b`K92fAGXNSZi`9tF)psiFWEKv3_B-a)hs5j!Caj)}%_nFqCCt)m#U z-huYkQS>(obPneD=90K8>T{EaWo~Z`@z_JFc=C}obh`m+CYe-h9bq9i(C-J>xHd$4 zi>fn{_h^7?t9?*tFAMV&I5-5M3nq*w!!ScK0qo3m3TZ{5fx?bCQ_<#yP#~fI5_3R> zu4qhDbZ+o38)@BhFoxzinfI*UXwXoIHe%Tw^F@}$=U`xEvfa|(rCbIDrzDWLcYh6Y z3ssyV01;b;$G0W#(RPKL;{~Pp3xuAB=MMo0?tp+&W}b#g0&gbQWB@`tGAf~6ARNjt zgqlf`7e>3QCj5nkP+Bs7-?P$iCOCLCZFrWz@(FAeI~W zX$BCcp?Umkd^yPwKj!oeyEQZnE9;mf2$6dv1A3`F!oU3523~(_9sk!4Eh0Pvcw1(d z7dutryoLAR_F=L;=Dl$#V4f29d-yk>*ua;c?4fQm0cQVBXkIGN<$^s2Jn#b$U7xaD z>PMqs#Jfkywr7qrX?qVInPGN;D-9YQh&4i>*m81JoO*r>n;VpM zm7+1sZxu)B^Jtg_>%vGTnGyt>ir&=S(VQT#sP}3Cgn)AVC^R8Q@OOAd+ti%1w zb^L>S41h2@l?!y_!oHJT3O97hs$95j|#0RCAHK8W|n04*%L|G%x%%n*JBz z&kTTy$>l+vXrn2d0$c1Za@-Xvq_m&uZrg|`d28*k5DE|?6=zgglXE?|>8%OXO(U3n zGrD*iI%~5Sb%|whkf3v8w#@b+Q)Zh}M^E;8_2o9c@s+E%a8`DglqiUVlj@$3$JBXX z3^wX_15l&|70sft?skV*UnPA6>0cx%S<-#M=Q5`Ow3AE~B9s>~Ei5OwfIgK#rx+o#X z=HwV1K3YU$sbo(HBf$Q!P#RX@xNG;7H^GXp>)NdN>B@nQ+&1KB802_YvysTzX?~X$ z<`peIiSH(GU1<9iK>XA_)8fJ?%|4VE19Q*rLuj=TS-?o`rKaKbeO&Ga_+K9(08zz% z_?dZmh-qzVd+^Qy-W8fahJ8-VoAFOcVyqdl0pUI$I6$Qx$WO*74!`#6E`TTina)>| z$o%81GJ{9TtsVjUUsxX8p+~IL)U0l&}`Mj z{xMpR?zZ&}6fO&4*#{}470%p+ ze*HaYZ|n!%4`oTn);S19p<-8@e!5j=mm2TUwbecz`|4Gkcy<${pREx1Fl#XZu|6eA zGFb;@s)@dZa(!%E8(?c=C?LbIST)Wm5wggVzGsF@#g#5_aG3||Iy1NF%<1^@;D{u6 zu4@7$S=&+~Nd*u55Yzk;K@nlcg<1E@JWoL@p zF%B%`wL_o#NuSFy_o&CHpp+iDyhstzPe`${WKN_MfRI%@z@T>?!Du6c%64w2Bnu$I zLt1P}(Jli*%b)DDL~NoDOsShMdEMBs=Ke+=)a+Nj5qE#%P7nbJfn*vpJEl00as{C! z0mKf#1KkgShBq(Q@soGYfWxVCUj^+b4LTGdL^Qjr1XpmOJ4><)S2_XyH)bFVfN)e) zOct#B@LmPHbxp5b_EB=~N8JcZ9&ngK8bYosVO=Ds+BB?cbkI?752U2uOTP_zaC5k4ww z%xznQwI?7!;>tID$6mbdzTM1hO!^{$CFPG8kUl~)NoJj-Qb*Vupnma7XtjSA_1V)1 zNgqK*U&Di0K&ff1HP?f&h9>gDvRtZxVDR8*99U&)-t+v8A}dVD3edU8GE5Yz^Oh>>4`T0Sh4QnqlUZz9&5cC4{1NgvN(J1A&7f z)r+xof-G6I>1{NHHmBcE-iS7pZg=u?@##%eh9w|l8VNH{+79P=XOO_m1LdEPsEOWS z$Ze}vtCA&E!!?=0SItQrIEX7lj-|?y1S0G!cj+m)CYPS9e3+gr!qR|X<;Bn$d;Qt;rcMY3oJKqMP33t4pk)Gq`e{`YTW00@0ZXgwNv z2(NhX&I2A5;h_^1K0gtV;S0}r2o8DhmP|pKq*2WT5J}*e?6`QJ35utMn-)p=E)t)m zt+@R}3lAB$hI}rS_GlMQRW}dbG=tW3O%h0{K7uY0oy3O88B&4)1f|AqG^lj78$&1e z;rg(|Fsv_v4m3g$h{6&b20j{-99jKxMXxahTdc znQa=67oXX{V_#jx>SfV6XtBQJ`lRpGBe=Cb#LD@u00J8&;D%0^L{$VJC@+M;U{^1T zurdM>qN|8u4>t6F0D^94G`I!=67gWv@)`tp znuH!1HHv*FTDOv*OiBQVF)jqXR;t@dG8XYE?VP3Hx_O9`24JA|-MJ1!N%u_BI_`*l zkhUv;_=&q`n1W2d3P9iv!9#4k$>^ChYMw7y^z@|w;{V755N_X#;4bJ=`A)#6sYrB6 z=0;hcdH{6~;Q=354&l|bOmjvTFo4*~*FdBvlXDXJQv8V{78lWr9y+OE;TUgY^j+{E zzjeagj9Q&^4wM6eTox3DxwxyzB1;A+R>fwaKs+YjgwE0Ci1ZP}E>JehWH=o+)Bz%N zUKX}_z%92MeZ+yC=_9B}SNlSb({qp4N4$d8>hGahe+d4}kZW#m7$(gXS0CZL7Z-;C z2g)$GK*G8#%rPPP3t9;0-imJZJ?N}0Vb~rNhGqJ->npQO`i4gzT*cX!w@t!KgM6*N z!FrK}AuvlS<$Ksz8*u&y60P=n0eYkd(xgg>=aLAVX47Xk$NJSiGZs9w#?27}4+YufL3T9|*?NdxALz8xl_g6vz@-pvkog@ZeoF+i}|jlX!|)i`_oLLx4A>?uvp3H3c9N;3eLe6nIc^kyOL; zS+}5z4M$wqzI1_t@eeEfFk#EoHKcJM@Ibz7!k@zAgzUmt+|%N4O!X}@{BUrg$Rib4 zc#=P&>VYCQW@c-Wq*2{B3GkqcI6b3ej3_6?J@=75Vp*;^;fwVVFL%&gRfCpu0>6rI zho-RRp9;Es=Kq zOnP6F9zWqkO&qRT2)ZYGuO&p5r2qtjh*2BE-dWjEPOzi5`Ug(DBtSu@scHjg;gc{( z`8Mc)?{6@E5vR!(Dk{*$`iQMD`6DPTcE69> zu3H94AR&za;RiH}@Gt|rEIT`VW0u{S5scW~j|FyMk%qxLF={{v5RwoQ@=~{2YDsO? z-dC5+tgK4&{M+x3IB}1;=iGN+RuwR>zv|3<*PVMz#D60Gh#2(?!ZP94=Q7(<)IzEF z2|viuaL*Uk=__}x)7IHO)#{>PTzo5%&rj-v`GRViXEu5a+(f}U@InwM&u<(@1O`Xa zRERdu_BnNRy*8xglx$Ae^TXkU)@_kRySiKmFFM0E)Lr_VD9D7CD%XLz8CYH;Q^Ej| zHq80qMaa`tNWuO;fS|J*xHcx=ccUyX3~10{FCq@g+7_N$oOn3N`%H4~gp;!5=|xGV zEXmSjvJ6CNX#l|jZP=z>=UEz!lm(MkUKSi^n23kDomVqC!s6{kf7!ip5=}ea4imEU% z@n?VkEPdiDJ)cBb03MViDd50{PrBR!1qYfUSVMNhbMTnC#ijuS7AP=xBs&3qJwjE+iMQc z71!;KAF*|$!=aypar}r%lPX*5Gt<#uG&?W%$Mdz|meNSX+hZ*no)y9v z8)M>?b%g;0T)oqjm&ZH9-6ho}0o%l_0U*KP!Tiqii|1yAxer^Lp<%PEtVziPcc!K` zp2b=;wCwufip7Lt6bZvS#-bDAPo4CAOCo@ArzJLoN(fB@A$#K#pqdCkuq+z&sMm%i zBC|!Ar`XOB_k=ZlxfTn5!2Ay7n&w%41n1a43hRU4){HgHyFjpVjeDYGTeC2rm|J64 z;KA%vvb828%3Jm{>3fqd4F8(lxJhsajJ52nj1c!GbbQeu&i>@~fPU%jExPH7CjG*X zEe25oMc~g)Id?--8Kyy4evQew^*Yhd{=pV~k}VMC`UH4@uu!2XC3z#2HPw3H*wVOQ z7VjDjb30Sq@=Lv0rJ30}XPFet;DQGkBiCBNr-1d|sL{&aDRxmX*FZsoW8Dal91D2p zV1#@wEH-(koK^UY&}1?o)Q9jNF~Rb-*IvW~&q+T34@g3_eY88CA3+VOZ9GL&8}Fs* z={u-81It#^*zF?)w166G4H_-oO5K?^(asrE%j_2O98hNaq87~_YEf+$(I-ehedi}n z(vuHwirnJ(c#B`PT4rX4Fd(7VLu%??mQm8HTcJ~%ZzcCr0Dwpg4%s~2r+#<@QH!EQtauZMvYgA?nr%v*K6p;(=g zEZ0vV*M$OzNfl}8{DS)w9?BmS9+Ln9nDC2@u=e^i;F$CsCtXct-OTy>>btV+8T+pG zdUel2)MTmFH527T%^wY@3rj?hD?&<8i!#YVGlP*x0|@DG_a2#f=pVxRPyhs2ahL=_ z>K}1;Z~y=x07*naRQt~QuVh>Ocdc4eSYdy;qg1d%H}?R5cp(79btO0uj=)MOTl>9^ zmGTgrIuR^*G8B`XRuFV+J45=#FP^3AF00co{_~|QO|I|8nq(oC039NdvvxJ$!uZ2Y z`s6(ZK;#}LU%26#Zsd?=hUD?g{udGyn<9+24MjHPxg*J<03fg%$6V%&l?FH{kU-vtwNsPMk_kb>gn+?qjbv98j#@r5 zV;T7)(JGRS(uRCa`o_8QOS_WCJ;}a9@w<+@j~rJQ4(s?`0SLa$hHMX@t`97Z`0g6_>f-UmW^JuKr2qV-ExP`)2L1dG z&xruCKux~|0?``zn4d_q&chfJQKL@ujz8L>PXR!1Vjlk;vP_Z{2jr<{H-J~K$Ow(- zfAfdy8c?MIOB>b?hk80Z2c{QQD;$OiPyiyOo7&nXOnT9oCM^W43b06k@4$t)QL|O znEVmd2J<7DYoDf>;rppEe~d;okV%I`GZ)if^_ysiZlw;=Pmc-9Y%B=RVK-&AVF9@R z?$h+e&z+((>s@|l@wlq;w*W%ngaWVj_K<-CvPS0I6ApOS(Gf8K(?5!3p~|KZ74>_2 z4-*n!LmdqX0hX{%!-LR(7S9SHBxZGGD2NkzBmVu&T9&!eEO=#$l>;Q$ZNWK3Br_vG z1d|Yr`(k5#M4M;J@UkZa4ZaEpR_=JkkM{uZ;Y}c06!kOi+W2wJOo7V(qz^HFoy^LO?{f^E`EX8zz%vNJ8^paGdoad=&^V$sGY?2gTyvuVA<* zumad;roe-pr4Xc&x;0U0?Hr!VW+kI7*ryhcQ#8#j2Lxb&xOq>L-g<2eKm`3)h<4>% z+1-lOLBhmJrs0lk1tGuyAb$1B+iZb&#}6+EC{c}9c<)ehr28Yk#QbjnAb$ScTlA^> z{6tdl+e$QrnR|(`^(+vq$n#~p)gt3sD0C;lgg4oW+Hg!`9YCFnsVPHxG(tNERx(gv z=4MU!5lgF6)L?#uB|5kOLc&MQxH5Oe;YYLtfT(LjTBmcs`Z;j#VSmKADsFq-MRfR@ zg^8uns6V2NAJG|;KLTm7x7KLt^oMAA`twvd^a^TEeFN=mED6t{DE&0bY#*GWnTvN< zX8XxUHrZYA{4?94ptXj8qx@x7n)$_b!79{g4{76ckG3|2uTZZU0<{y)DVHb+5id=z zGo-bX$UZ5ljFniKO+zPQ0^cDU>B^oeA>DPiGY}#r_@^1MQiEEI)xq%s@%-aR5J{XQ z%G9oHowovj-G3%G39M))VhBIGeW~dJATbl7qutlSN(PKq_?HVW)f3o(6r- zHM5B@PSby7z=N?mz~UgnEST8-Ah;b9oudLEM)Yf6-lA&{)#*R|(7eOYwyu%5a7ny> zZZd?A&R+)r@qhjC7Jd5uE;UVE0|{RJkSm(30kiP~{nHc6B^2k%_z__Lr;7ZriM&R&!5ON|FVJASC@j+{ zvwdiaYE$DBMZVc6bOqq>=mTfCf3dT-(=15rHq8>a4L}YNkLO~mDiiBAzsnUsn zs3K$@JcmA=MrvyAR~rh=&(+~@00gEE_y#jGa5+f+2)00&wAR9la5)h+%?7^b93bGV zaa2J*bk%ixc>rRlY1jow06Zw~fvpk4A?<8cX#IrWPqvq1$}yoZlV4A!U@d1sa$3Yc zlif2l*^vjRJjwF>JkxDUMv^oZmWdZ-i3`pPfWUJG-BZ->JC3d-cnGC@5uEe|x8zqC zQJqt(x(m6CA}<;s=U4y)T=#;8q2~HEr+^C-oR3tTwPde>Xvvc-_0%He>Axcbh}8yt zcM*UX3m#-=E9TQgbV;sj$G^V^6Tr=R=51xFX-dPzdXJBpk&V*LH{b3bgP z{0#u{f4^soK68JU8a40~vGyN|b6}{tYuoeglEbyI6!~!|fb5F448vbp= zk5JMh6Zaj!;s6MXYewvrK-lN(T+@bidVGznq1+#s@34+En{`@RcJfC=s)V`(O}3!* zz>lcWEic={{0LZ3CjE3b`W*JzSsTNT;E+KRt{Xf=h<-$^6>(P}Jaf{|&h~)r{@f`J z%|z%VtT`@@bomY<(KMd}F=#+o<`A!-OU7Ae>=NSaw6=;SzCseH^^+)QILvqsE)OCH zAdD3Q$)`3q2h?m5?cFEfB(p%c;2|SbN>y04I*cTPDia3{XyaMsO#93Nky#%MaB!>+ z8iB!<2m>bYPDhR)M0LdB$?>eiF}dc-^OTC8OyOFvt|ZC0JeYKz_~Ja@raZ}VvUcyL zJ@I!Hxpuxk=M6xx@ae5lzlRD)K0|a;*F|`}`{Eh~spLhkOLnEmgHAQ~5HhFDv=)@d z^2gy^tq(!FwZGIFVTqarlRg3jpbT$ZZPGuzT3r}{WC+G7cqvxk=!c2}*v#PCQw!&$ zf6)C4!UQgi|8mbZU2~{GZ~uN+AR@wqt9+sj{ti9Y4w*EG^^xwkMuX@VZr`F$-rJ#C zP23e}LFeDc1rU3BN%9MA{Tvo)HTMH?jy zGkcy3Aj~asjHxOnR8;s8sIOu3Lnz}F_rfj|XCu*@QYfYzeuP*>9E*$ht9dVE?duO| zWwk{wd(8p5>1$TAU3+QaHBx>A@<&K2=Tfqdeeok|%t`v`>3xXWDE(AE5gdXC@7bWc zK7EqbPIjnXmpTx>QuU)1cr$}GZx1+&BjptrVaV%9-d0MaHeHdm_9)XIC`kwtcJagp(s| zXeoDuJVV_GaiZpAb2NXpeUI}&lANS9=M_Nk0_>lrUhhQKhWwzXcXalmB6KLnG)KFp z4Ho^8x_8k;agLem?e5Afg}k9jMUaqHvTntP?t0lS^Sj0X)FP zfwauHx0iIvzOwB;Gf&lhA$$iR__Es~_fO`)`Wn$O)UYw#;48O?`yer7lLH3>W|brf ziy{cGlcGs?0!;uGQu8h&GIIEMDw$yH>hW{A3`uhQT_#;IbS_aC>4%|;XOHV=STn0x zQo%*38B+u@++*Tr!>3-WJJVyl@Xxge#bQioCf7W7e1U}%?>vDP?U>ZF*hH-F8WKti z0K^Te4f>9&;v~wjmt=?OkR-WB3;NPKRJPA$Rxp6*jOaJ++or28t<%3}08tF|WH*oT zhM;wYb4h?0%s#v;+!nv|-W~ef1O1Exk)NyOmYynB*D~Q-AY1^E86Gm?XvQ(%kWa~_ z0!xDwVKW&3Gcv2mUOCsGMhl62+$?{JI?!&L?i!!~iWdBc<$Y5$ztEtOK`27n)xga# z5t!^Mp^$LR{8H0Ii1=pF3`96q3M3rDb=TgsM7O>60IlwunpjHp!H;;VO*_ZBY+-Qu z5fZsVY;E8&+cT5%98i4f^PfCP58b!Hpv9)2Hb6;NfwRsqf5H7Ydq#+kQfAwkIi`fW z5rWw}Ly?0{1<(Ml1GoYl`CvFR8Obu+580dzI1^w6RtIEu3?nkIe&*(htq|xV;XxQ{ zgjyXcBWgBkS=n#R8{uZF)HY}Q8jm<>fP=~Rpe_sWjTuM`Y#xYbo(!We1bp^~1DkIl z!F8Ej+52lWBMx#{<>Yh1AiyzmwVYfCZ;~ciPIf<8-PXDR>&}HO@|Ew7^KOCAB{Upt zQm^}bpni&gfz!AWO4+@W*44;LXeUT-k=N(1FbEv&VaRM@bU``mLs@=1+ZjN3Tc8{;fHIXVhhcO@$uXO-&mlKXcSrP__ifWvm)7Zj z|K1`15%ifxYpB$7r;azs@i7rIyhwZyCx7|9+Xg^b7#H??RFdclHU|{|#Q}syXNXer z5<{8$xB$Yq@i|>KUboJqI~9aBj1I%k{D^rWJ&NwO5f&Ce*yn2w6YwMU9hhN$1Sg@& z5>Vv~4Zh840ddVyHaYoEZKi$)YAF&Qf zzw~2ksZMi9KfOHp{W|RdefiEc`qCY1oYbkt)iQIeY&)|}?gdPp&CNcOB(pNx25ZQS z6W4{ylhCf%Iy0cPlU;UOX!L`CbZlTW_kx=uS;8@4t=QTe68H}M4CYUmUdX1oROLK$ zxI(QKToanodPJj&`Kb4MfE z*(Q4YQ30MYKaz57!YqjA3LJdS!Q{0}#$=E>Pdoxy|C+d}OeV`1wBR}<10-w|&Q_^U zDN9PJJIPExw=mAggH)oxkJ{g+UJpgMLIOtt(n^8{enYJ@oGaI!E{pUa5 zraK1aQNem7rgJDxvAPM&thX4FhgI4!UGZ1mBwmK9CZwZED8n6|ji7JvPw58xdON_XsMw|+sc1+B?c4}O> zL`hg2#QGqX6%+YPM~{r?`R5`_GZ=2Q6yROU@1FB>Mt9FZ`|=Rvp0Q@ zkYri*X{eBjcSXM?BbLfE?HtcJ{{TWXlr#%&fx$KnI!A07V)uBg@e^7fJcVdTV*mwM zoUxE3eIyGrlX@@Z{@5LOaNa-ne!=u8Wqn91G>91h330jP$w>eZ*R9m)TdtTUlaV&t z9kIaYFeBspE(ljNgXzkY0sv8N2`GU0-TSxc%1i3>@7`JjAl%3KV2a6L<{gSSFyfjq zWK5^u0U&<$ecN>BSG%l8{7?E_d;lTmWt)Hf%WwtMjUfuzt;8u$^W7XSxze=8XmXp$ z(uDSz?=4?Jcn+`(w5CPLu&>$x4pB_P{&(9e{D=zI)?j`F3VIok;Pr=tDAXU0uAD`E zjTP`CP>nImUm087{2lWnh9f$}{D=c|=!(ht5y_j6Iez&*PjaI|q!r4qK_Fi2_(df{O$k374;s4~15%h2VPtxy`LUb&#r> zU3LOC4=VJ?gG1Wha>GvJ1B3Re63r)c3a^Q+N67*iCrK7ehC+}`}KuENJWWH3A zqzqRYsAOZLh9vJ)U!i+4*dJW^%ghUQVRT0Hdk+YJ_&499Bue+9qBc3lShz`^4lNgM z9%M}O5{i(o)d5yG(f{`s+w}Rb_6cdN?PolA(ASA2it-XQX`Th`W8cG&<#F)BH{I>O zTa^=04m@@S2$;2|r)%a)t?r4USv)^X0yK>n$lNFy2oc2&D+K3{Sj5iWq}dK4OLQFV zGbQ^Wu7Nd!OObo#i?~P{^d+74buU<=TVHd4R`#O$=7sqnI^wQRouK=_w9ZihAhCI? z%Zs#-u}9ZJDWZ7Q*)x)UT5z@n9qO)7`NM}{0U8oVWB@#9`f2Odut30-TZZbwQ57I$ z_IqL>W!Gx0?xb0EDtelikT6miFStUkzP3hlb9KXku%N*M5QZqqRtZizr3vDEfTCa# zmM04!eBc1C3xf%~_Xg3!5172@iDeX%t*S)ft{WdMA##jUXcGvbg>iDGn^SB0T$Sqh z>&KrV5{olqX63@|RhEFMgwWVJDf5)`yS^?AfG|rl3vJ`-x>CtA`N<)|l8ULoVxhiX zj0mg|`Zq{vdsZ4sFKHv=8bJrSu@v|p6Hv{+^ z%5lm@*_|3r`Rc9BKAlB-O$(MWNpiP@(DSsO!rNQ`03nlGXb&Q&G`%m} z8U4-?-OmKGt7!LUkNNtm+%-V)n3QNovs$-`vjDV|BTj}&vuNr#$IjLIP+)$8s{+b} zWBIAd0OA`jZ?OOpcSV>GDyH}o{hCIZm^qr*d6yN{^pjHNcstd)=jeP$qKVr|mDZ2GF`|0`@E@$D1yOn*9K6r-1GLJsD z%^|UtZz0cD5TLD5Uvhg#cn;tl;F#~FQ0s$(I=ISam3a|sCpug(OXQwSK`mAb^IVHW z#9c9v91=dyfuEeYEYMz97NqD?jVpgDkdTan_+B;-8jW$)wc@&9z)(jthWwOT87{D} z;6Zancz{VOY!2ZrFgzLt4;5}ZEJ})a|#@DmAkrvl2CO4DX~LB@V)c zl+P()&N}a);XD9_LYGNSE%O(h-heGo07>Am{A2uF003c@Ci>j14Pg9pqro2{m$8VA}K5CRXP-|qamaj%XSD- zfJTsv;N*>820{E^0U#b$05KVOhyw_lURn@?V{I^?+CYX3Rpc!XzSY9BLS(KGu^_m~ z)zEq<6Ry{SWK#-KU>#^wIiCZPLy6%e27t6BvJ1f4!F8yuvAinfzuo#8Zm+r)3bYrm zifWyUOW;Rn+3>J`{lDQRfRecE%6WRl>-N*Z!*dhM&EwDS(C0pWf*$+o8J0nuep+|` z?kqBoW>sAU&jI-yx}4BS+n<389!3QK_CgR=aUIHR;~%1CG%tfo`4E+wlpt?3 zD%5ILsMV0)H6lail_Y}dF-X9CFkzf*d2s##GmVH&93Rnx_ldQnjK#qYZfxCE*rYEm zoN89YFiDa;ufX9PK|^W45Py!6BmoLB2F!CS8);E$#Y_U~(l@+70K%R0VuDpG1PjjL z4)xj&h)4nfdmsNdXIqd{Fjipuc@yOOEZ0LdUR|+JsTWu*k{T-1To=V|3D`UARh zp+et$#Vm>(BxXShJOn*n2p&>mAOs-xZ!8D^h(CU4hc3UUM*s3VQUIb@;pmekyJ9~1 z6+na-!$OyhTnPdC8z0!AFEW5A3m*KwN#}a7WCv08jvFI$b>uTrX1y6Ck&^G-``FwM zc=v8!-jx~cZjB6mmbo87{ASdxksXs?`0kz?MxKHD!wP{s4)co*13;X9aI6v*NJz8@ z6gVsy;7DNi8BntimqI-VZ^m&0A3K2G=Cwa&$;aJ|*Sc5GEA zGjQM{Qp6kwgk?fWdMTY9ONCejj50@Fg%NlTCjE2=z`>8I&WMtZGS#RJq^m}yO@I$o z_@=QDqNK}tkWka^U?4m6YL!}b$Es?;5Z>wHgB7~;pnxZ}I8b%OKw){lPJ3ZpTCCIj zOr55us#LFwOHVU@a*d4Ph`J~l-X74#R-e|8Zu{(jw%bE?UvL#p10?V}zyp#;IYxsq z>MRZ%^dcPXVl&j20%23uOz4bl>=CU@_s7LYxVvZIG}} zM3sEaZF}fNx2`gX2|q~abl=@;^!ZPpq>Z(1Rzyk^v&bD!0;oY^M6AT!^wXJ@!Ca7C zY3`-B!*y%NyL^2H09>zz`&>i1WOoI!YisCZXGq7^y7bhs4xK#Hqd{Nh&(0Rn-FJ@IjWK=$UJM*$3Yv1;oVigf5R#Es z(r?E<^yXcnvDw#_5Nbj*BM(=82uB!3`61(;a{iB>e*obxRWqUO z&WlN5EC(wz>~B%8>vAH}yG`#%0z7DvrBqm>ZJOMT2hBtyNV)I=v)it$4}r4zd$2x0 zd7vU5D-){Fm5X(H<7HCv9WlyH@=C{8oSl=xuCaC}H_?}3OcZp7hAsC7avu#qyN=tZCo z*i;O^xJ$&;^ylEh05rK)5^V#z14?IRw$7wUyq8)BT;-p&*=T%Db6%}*4hTeSAhV?z z3a7K(mvoa@5pyvBB$O=aa!B%^T9gyQDEI7d(QU8YPuJbNl=c0Sk8aZEK6Z?bJSAne zv$W1mKVyTC%?<+|xXd=fGEMqv(f4vzZiXB1fO~g3k_hVTX{oZQ&+|FDP6bWoN5JiX zyrfxT?w8DDw?1>IN@bnIC zYz^r7XNVrWH&31%udwsd$VOy1BuTS|B=W*7iuI2LG)&qK=@}(SDrr)_P2VeJrSSXt z@8_=z1R!iCHoGsgz#%h3Adyr5EcLt3o41WCr(9P?0EDJTg&>V5Bykm@{~QsvAgdsm zR07!+SUl20m3n4b?n9^yQiWLIHXY+Ld1gNh464KFA=esn8&*S z5Rtx90P&{=K>WnF!~jGdxZvsHuFx>la7UT~K4ww!P8(uafCtDfuG|bjVptfR7NeCsh`g_q3QW zneijSZVW6989!n{`4JK!Ws#NMK-xMqe5nz#sg8&)zj~f-e#tUD_TX9i>b<8qyb{m0 za#ywj+I_mEBQ{Vwp0Gt72 zyzFcZm@{Cl6=ob<_XdAuK#ciaHeABWhr2=vg&x4jYE4K=Y>7;$vg_f->l*YuZ(5*> zR+@wv!zyrtWY*b%*;5m>5WU zbE?ozdr0>@u|Q}n`8lWS}+KOzGg zqBtRBxeSss|D_0+^c~l&@TQ9e585->6X5;1ZpDTu@~i}dXBG5sB{@YW@2{4zy>QJW!out{(z0|54p=z}!;Th-UQ2`MD{F@3$lg8f^ zvp~AVwTv?2B1Xs);1Eh(-h%;_P}Znh0e%F)QPemP7z~6%fv5|^kC=fu$1mh%SEX-~ zz;(?g+!{@qMcxUMiID@5qh;L9owBaZpn^C1)R?%lg|N&nwcFT(i#3Apn{ZjMlCM_T z<#6hF$0@U|V8t0_kG~-91`t3uHwUz@M)b=4b(*SG=z)zP-Mc=dHmoK3+z621XERU~ zuqbA2fMtK}sO*e^7xX8Hl0WwPWx8~wL5;mcjX7A2YBbY-kmkFerCPN^BaZO|P*Bhy zzyTHr?mI1`4mpb)A|RM@!-(3|YiP6iDzQeO_QmlLwU3SH_B%G|i%)df#h3rY7p0oy zGiyQ#;NafdS}lY>P-Om3iiHbiY4D$zd)HkkZMh@_QiwK0aX`a`DSO|-_a1+f3jiPl zI|~EHFr`ckwCm2uI>C8?LGJ|hd+T}9Qzl~#*f2?SlI5+v_YS5^V8O8B+dogZ1PC93 zOT;yil>rdxXPyu1LyWr-PAWFN!`wSxqt`_ML^cOUQp88{CO}ZBgS2S!`0tnetH5%D zLz~?Zz3;I$9o%21AN|G|v-@-erQz~10g`v2wt!Gs;gnx&F31oPlbM=q55tB7s$o9}!!hrhUz6DbzJR4PU-vk%&ruf36tTANLAg z85tb`96)rG`D6P4zX_1=?*S`Fw>#px6&t5}Vy1U1MkXu|TxD|zBH@662Pa%2qS;1; zUbxzzs~4-x`T6qNke=R@#8mohwMeMAgw+A-m&P; z8*ZMZc6UUrMWU&F4Vr2{NK2a^FfIxM9H4I<0Ks5FT^RZ-j16AKL|s$>B>FwtY1~9- zXWz)c;>=@18g__IZx896e{+VmI^r&gDLegENrCuVN{g2V9Wm(ycb$MPSfj(a5nI10 zIFW=I<27o+P2!Uz;}Kz#$+Z009Ek;MgbDeK_h*S$nBbHP03cMb*(56B^OV^rn=%<7 z{+>^_1J>&tBa{P=O+8!t0m9F9SQibruP|)iglaE;56%E*8mYq8@7od+&=XK4+Zj$m z=N=ibVXj9C*hn8k?_CA}aY>7~YA}DoHi!^nbFtasYP3e+x^`YYwK(0r4xbhDw*e4; z`FMv8?yJ!czj-IC0r?cW?zx2qyEf_#*RA2M-f+x~s^!E?Bj!24Wg$F=*t`_$ z8(u@*LGY_@toJ$nG%{F9Wm;c;IJ#R_lR4gLk7(;`pE)NM7*q&WK)m%OvsJofwN6W| z3O#vtK=-W=>8$Y{$UUW|gP7x00gBAbnvl6a%W@n}1p=qV%)MmY?VC~kY7wQKVrLfd5A2RwiLXbu-h;5qoPncTB5m>y=HgeXCTP$C3V zie}jn@Y)c#aBvKXt0aE}(pw`BgtbNDE({!uMZf|I@EgF7Xwck()PZpM5#G!S(oe(c z0HUMr?A_^-w*YcEHclaZ`ecuzB&>JC^rcs2Q)izjcDS){Ey6PKx2M$2+QnTEE7PnJ zU9(i9YZt539aZST^#MJ-g)F(?B#DK|k|Ygy(CMB64;hG&w!*`3$x5Am;v1GNb*NIO z<;6#7@A~gZ2$2gO6fAhI3*)}P^v@=m$ymm&3;`3BUYFYQFQsGsZ>OE3h~9uDp+a{& z+@U|cb1Uk`@JW)f1aD=5L;O7b)^imw!8Uc@vd{ArNhxh>Ns{VXNz23J4GRHJx)~U@ zb0b-ndc_M+&YPdB#7Wg3?y@yX!f+#4pqK?M7J5LjAVj3X<^Lma+Zl0BXRcCS} zz=LUR{1(nN7!a=CZW8sB;xPn+U+Nl9+KJ#+#yv96Swx)%P$7VLbp{}cK$ktn8xE5S zIrP7lUWf(#&3$ex5FY@5*ju9?c;hsOpN_C)VqqyJP2X4^TYzN+K>Xd=h4IlgEzeZx z9Y3{5)D|DFIQ}JfL{{tBn=c=3>O%p~0Iqe5OqE)4(r3ODUoPU}}LCb6-4K>dn`Cl+%_6rOvHX`lzka-TL zH@bYT-Ll);{sKwQ6cGbH9J-WROBRd%~qG_ zgHLwolD##0+v}%<(8*`afZ4RkO*PFVNz}E_y!RPUz&+fImDvpg zfT3*?tARe)a~wqZ3vzDe9&<>RZp4M=wg8Y&egwdPEP2z$U=Da#3G1c?enf*7R~ww( zy2{((;*SC(kJK0UyE#4?Kqb5nXfDH2v_`F4B;bRbl2-sX01H2RDC#s+BfJT?lc~@Ex+S zO^v*8To~E~>c%j*8X&teXw$~Rx6#qFZ=}jl0T|J}YeV||51t{7tj(+eHEUsUdUo9K zo8$4d9{n~@#D1j0`1v+@+w2vk!%Hs!Snxa2?->Sf2)mw?WI1MZE+_}W#Mxy#0>Kcr z)VJkE=;AQ@O>>T^wI0!*KGvpp-m^okOkM@Pd`GilaZAx0vomuo3}HTrkl)~NB7E+H z^pmw<*a!^`W0f;pfFo80&SYt_-RVs{5MpkOc?uAKOp)M6WFI$&gvB&wE=iH3saBo# z?44pjVAER{kGssl3e7GwIGy(PR-evp^f|j@ev>Ena#bvYgb^{|SU=fe_k&w4Q~LwJ zougH>(xbsf-Hv3DwC)j~Um?~I`&^gXrS25X>40;q)jG{LDs;tSl@3hT=uB@!kDnRR zTE`f^Om}3i7?%$bgtltmBe~NpFP*0!`^FX8`06%QOk~lhQm4H;e?rTfAE04lN`MxF z2+jKd;O($T|Z`_Ep?Yr8L*Q-z?Lg*)t~0kXc% zy9I*pYC(c)h0q4O1Rx(o$dYH%wXs+X`WrOp9(7(Yr5M6KNGWss{iN0hSK#9JOxQ9n zK^fCJ%S%2d;BwgL4_h23Kf3Wg2q!Hp5SIc#T+}Lv%MT`^_ow{>K=e7jV>`Hg(H!yL7ksk!e6mfeeE|?XWt-1b zsd~6dwS6P1D5YNOVXKoIx2o4@uwJ3z6GNg6iM59x_)i{g)4T55p;pFWvWi;go#b>F zaGnEB&1>d7D{GhQ5Vb_;D@&Sc-z#F?(QMsa5D_A+IF~_Fy^HnB&mAEgjqK@+t18r- zLgA(c)wyU^e#T<0z%9n)QYMB7CYzoXegsI9*=y%6_s0xY5!?d966%a_O^Z&K>%mok zyMoJXvu7%pCoUP$)Pdlp_L1^>NB|I-Pt8dHB`!A$Rjk4n1f!5blHFm`f$&(%ZGrU$ z?u^5WH3ANMetSgEZVjn3kQ5D}<-wJoVOOE>)y+4}($D@(U%d{!3V=ORnEXC*5!Z3N;impI=0pdBM z={b@tFARX-es+O?2pO?2$coBaA3{ZD+#N8Z_fOHFcS<$0Gm5EhN+~p7C6%*2gla7R z%q$;+@mq&dt&H`-BS{v8-Dw7PXXIcwxVnSybb%fq?$g&ve)V@w2a(qdsFK1Ay`SN|owY zR;a#UtPy-1AqG_%wCmJ+oQRHbia{-)NUd6hZhxdrzkc5iyD)r(D)$zDuv8gTkGAUt z5D+1~Cchg1;%IK)HDS(E>zyw({k4;EAuP~{0TA6S<6^ah<)4Xr2w@YP0;I&AnXO6w z2q)r06sMbi!U8IE_uPDgR`!|n)+VQf5hHnvPf`My_c2PFB?!__w+FO#qAO7urk$aG z!eeO}LjrgXXV3O&Ypd_M5yPks4Xw4)*FXlNxOJleFxEg}3I|k(oD?wCs8;CG`6}(7 zsW5nWZcD5Y44AU197Ki$It|%TZ@g-n-u_F6X=h_V&;0c%lQmOZ8P&>wmbX7hOJ_eo z)xl}5?>*9}3{wlki@?a{+mI@QKIf9?E!{$=SKdlzPG3T!PLJOQ;9=&{79D=`3VrDI z6Z9+ZI!?3GVQSaitl5ZhQQI`e;t;BP_wUlKhTKgQ4oXNg7x^+f`n2pSYDpZFl)a)% zkH+q$78CqLsqnbijqC)ng=6~R{97Pwsamx}C>hSciUJ_v@FdJ`Oe`3P>3)VrgPjuK zAyD`USH!tmAHqSAtZ|a4213G;sEUR-BuN?ud|MN2IWw)83h zi1&WBOUu0q{m0uBKsfi5$U>@JT%*R}3e{Rf!+wRjPY-GEBx)R2s1mTe0U-Y5(Kh|& z{cvGu-UeBW@IwOqyBwMXUF&Nyn;q8ff8J9|WRXi-UDxcojBPGrOcp{?3iu zu;HMv93Y$-36LzwGFWG9G!a5HigSVR*qWBmO(qtL+s>^N;w{C^-u`*4RDRtp<5P_75{1JnJ03@#LYcfJ+YkREA z0zgqXG>{1zQDoo9t*2r(Rzx)4tk9)%Rhp?+XuUI{qdOz&fTQS;GxL2RcLfLHhHIzk zr+@NdTE2OX&OX(q=l*t`Mu-w&cSeOql?Js&M`&T^Q#8Bt1*-RsP-WDXtdp8NN=_9s zcePH#<`VVhucz&Wucfo2o2h#S={+UJdDtJ(+!a%F@J%b!dA3cT{N!1B*KeM5s@s-P zbNO?kSC!sijF$^oCjbEKibFB73GU4#Nn^#}2%)kXzd*vJZc(Q9;@8Hm)RxLmsikA~ zZ6@uz7kZQJejKZ#v$MHC76_erZV0DX6pYx*+!UU<&p|i3kTdWx8c?_Wq=_NQ3oqM& zL8na$Aaavvyb^LTGVeBchaPcj1d~Th*ro=DYf36LkpuM_xds5@;@KL#bbpLQ8T6rd zyS#u8dmLxDX6b6qYU1AmN(lczqT}L56{77P(Z`;knryHDQ^yAA%51b5FV6_95p) zF_Af0LMx}?UeYWsQa9lI5lf3LYE8*bRMXe{V-U`h5htHo+0&whCK4H|o>*SM5AwS&|htk9qh z5!{nGhpd{@Roe5?dD{Duc{=;p4h`0O^u@<}^eex7l*hl^rv!K?B@>IDmR7?Wso>Y7 zh@TJ31wbJ-K;>(2xa}Gb2gaW<$^F#fsOC(y3mTy!E0a;PoZ$cr4?O5m-QdW5E)amQ z!bkZGp%uc~@f^NH=3q3}8$YAEJBEWTLXHUeq`KMpzFhzNR4a0%h#rqVjNp(wU?g%Yp=I$CflEdRp*w9QwetqKE zF702b(s#Vt0*GR9;*M`xkoxl@y(EEq{_>6vE%mDOGerPG-5RRQ^p=WrO%g5$UZli+ z?_(YMT>~IAlVqbR5ex1|xjt6G%6t+K;aU`8xg7F49}66;IN-Ui@_0su<5D+ehmQTKGRu*uxe9*6F}LdlgC>$=4-Tg%?#~% z$voAkt91IoE$W=^)9iAcK7W6k{@-6XM$OhZRagQzaF@mIGw$BGiBcfRIu*7XEPn2(t^5A69TF$%sW_ z#(@YCs^v|1*Jp9v73z17(}2@mr#|BW#QAk!1XIA7SP(?YXxD0M_#29yi{oVHrrPYj zV_NyACNlucf!R8}c;6TR;k`n7O8ZCr_GCZ-=6)zjV;zwBM@H5h~K{)j&L8~{X( zzV%foJrw&CfS$s3j|WRQ13TQmx)TboSxIL9laq7Sh>RF%mA06rBcYvGfdRoX1|;}7u0ZsFi;pVQ zGGWteixTDV=8+%0foJo*O?V~O*O;vZMYGalu8JH4%hi2NF8|F8H6HOt^X0vJglhZ8a=1LCT9A$=Lt^AOJ~3K~!npGz^8; zBIVVM+rhb!U8^=slh4yO%2h^ZTHe@PvqFna9%Rm7x!FSwjT~i^GhtqTNt53Gt5?w0 zu^#nzL}5(rZP3CMQ&gX+(e|+}Z9KBW7KzR&IS1B+q#Yi$wi;Ci4bumjv~cAVEgYVv zTB|}^&vj_?X#pg-!Jg}8=>5NUf`02gr#Tbp_%&^YCpr!Oet<)0Y3n+X3Rt@U4&_OQ z#gL#JU?_K%w+UBi;SsJbto4Cs>iOqD=u9x35UGP9AVR=J_Pbd)b{?g#@3xRS6!QuE>wfoS9mMvsuErz-3olFp!f0(kD!OtX61grNR7& zx~UY3XCfB^m)Smr?30py+BZ&`mFTQ3RpLkj1*-$B52b*E0T=EA*y3U;W`fb~7IR|G zg7Z#E@L=Yms#0mHxze;7-2`tK!afli+!+V}=cpm)82}L1?rYHh^5gsI!0VRj)R#An zg<3*ZTPt;%xwu7BD^j$q-yTx;be}pKed?nx+Cu>Y6{32p$}WoLLYOVAu7|&vsq??AHkc9 zDq9`WpK}EbWdVbo7iPlxE{DvQ$wI()N#v0CxmzDDAb?Ploi(v$Q5Xg|WM(NfNqEA; zUN2q2m^=d;qd`ab5V=nZK$HLv+#3lcn{<~r0~%cK0s!4WBEJZL2fOR6u=T+eCfREw z0Yo^#ocAfX1{R3@GgZ1}uS=o~+w68?!E?O6j`uUhiQN^d6->yU^hGE*Dzwud(Py6T z(!S*yebcS2i26v4M>z0B=Oq@W={Ep~4}PIbi~TD7^owHvB6WSxkETf&=T>DzfAK_@ ze($S0G}}N1)wu8pb*C-Ot=2nxhUjv~w5)$?wNG6rj!5x|lM#MI@*WXVSVYk)hes`n zAd`7jVXX}~8!&l~3N@M)uH4zwL>ZBDL(?^O_sBD_41NUXfsn9F<~bPUo*OMs8Oz3n zc@CQc>UPD|;9KzQ?mtt_dJhkT$Wbnk3R}AmN$#${v_;?hk{LSqEvvL}c!t*Q-J}8D6=Xj{D1r5$f&O2t z@lUuRstr?MOXsqwz&U6SslPR#?na-wX9f%)xH6|952CemmrpS`dGt4r(3hVZ(7Qje z9RP^@I?9h#Y^{}5uIG4O(Ak=JN#_6n1jf~02I*&>E2N0(wp_9kw>56)Qpjge+2Mc& ze!w{Hg9;Vg&s>{rDvT}i{97Qtxli&g)F64F@p;BCN zYDwq~B^xA19ONt-7W~LP1g~p-4YexRw+Sr?=7_P>Ac0j6+iwla43=y*3(WiBM<4kd zHV2%(8V&HnF@0-+5j}P-IQPNYVnU@ulEjJZ#$ke;1&ywJ6Dx<@(&CyBEEI)l%Ejmc zU=XB@hE)RH03!&DjIcmlcc?`_`09CTZ}jMj@7_mC*UZw!L)+9oi7-}C{GvND6R@~^ zkm8ynvyBXAkKBlBUoh~{d>4vE;jWph(c;xJOrdz_caBhHYeWyUEA;yxIBNjJe_z0X zEe`|8F#&^UJ$MmalMY&4(M6J~SdK-+T=FX=@hIX90E1o3&gR0)(jsSg)`vXkkZ*j8 zgt;*L-bRPvJbUg1a$y*xoz*gMYa00ZAfo1GU93*-2toPMp(1Zb)Z2N2Mng$r;@zjf z6;TdAlv6^$&5$z`@p$_^D7MpAj2-F{~^y^FK3cJW+EM5MCLu5GTF!=Zuote%Mn z9xS>EEDhtqgMCZeN=~X}umGYkZhp}${m`rCY3F#4+Gl!n@z*WUrC+~7{jDKwKGmkq zdM|TRaQodM3dScprW;%XKmZ(OFKN-tMNQgxbekS~&oQEYg-Mi;G#m7;|9XN+v+gIl z8gp{5NcN1qTWk_U^m+anAxYA=Hpuy$G1ehj7DIuu?-9F;0S=7J^>{h(V4;9o3|xhu z2MT4tgIwiDUns!1006?ESEKB8tKsg5tP*!<(#Di1#7mV98QU@!0*dz;_P40ljYMTk zYJG?Z^l+g@W}*L;c_x#~Owt@b_B{YOY#}gdgW2>MCSB3nrxPFHUOAsb2^fym+>CYbN@bCJu$)iH$E9ZoK zfZX5N+7JLD$E{#dAmLdb93pdew&P+7azAOMILzigg<>PPm`vmZIlZi$^! zU7Ffkr-T1wl~!(;qfvh(;9{-EyoX^I?`0-n4nT-iqFS#oAELF?ps9TgYRuKBeX>i> z{Oua^ET$HleBSCc)ASJ4=ojDqycdO$d$s7xmQlK8&PmLgLu>4hKSnrnos&;P%^3({Sh{m?}WDlUpB(#aA{BjDm!Kt&tL` zVxl0f;E*>0$QBd0IPI&wzBr6X&Vvx!GhL&bRwDqSaN;}9@m@pkE1{VR2J!+qwWzQg zmwXUNhus@h7(lEpR_PmF+;lFA_fuY*q|Pf^$o@5u7k~GaE-ehI^b2(d*owZb-QEy>~yor-Bh}kAI&F1R#vSbAW&qXQ2y2g=1cj zYGR%+hXe}{GXTT>CiObcIqNH~RFdFWqK9k5CNg@_2Q?J$pS8-Tf@8*fHXJmlfd}Xb9@`VpPTtK2oz&}Gd zJT_})D&wB0bhoY9@0=S#ct7=VRb}}Wx=BF(2muoH2EOyrH`=80qRx^XlL8W z=b+*!Yn0y0n(uSc$GBes062#j=6hH>!-x*oqAJ7dzyppn5g$6vYu0U++8D42CQCSZ zl83bo;6Plnr%wO&KU_+yU$a1u-+r97p6d!h5>-fd2Gltt>8Gdm)M@U}6wMu+qUpU& zYAn{u>%+#qlFL_M>Ish~-d&??Kuhi&|{{7SR zN1xiJ*=CS0;euKn$^i%MKv)qlFPp}il(&i%OA%gAurhI^hUA9GlPu$F-}}}rJQ73t zxs~f$7woEbA%t9lZ$j{3&M!Dr#VMQZma}7Wh6;1H=dgs_6xA& zKlW^o{_=@5fRHs%p*VsS^Aq%Z+ipg)R#Ip3$ z;%4BDes*ST?#H(jVnGH_7WX0pJmsxuI~_42cL`Eb>+$Tda$K?)4)}g$qR|L)tjb)F{3j(_-7|N2 zPJw(BlH`E7DM()(lNafy=8xbTfMWm&dDpiQs=Ce|vsS7dANOP6Qsz zb5qub?6zS7stW}mSiu{LwQ)ma0LIA)kqJvd0;b=Bhz<98v#3-^y22JEzlVeENX9Z( z)Fh_GF02n|awcFWsCy9=28jtK{&J}p7y6LPSRb%3aQ(_um97l|L<#VqYE&5avU|$v zUL>y%#Y7xDD4=W)Ms&}KKF!aJ=(R6wP_+^&7U%lpstymtPmH+=&{|LzK7GFch#$N` z0fbIRWvh#TtsrY?w0fQY%x0xZA3xHi_lE!?0akqzc^L93_YU($$aiUZlUap=lk%51 zZO=%OP@Et%I!fNXFfdryzV$5;G0PO!)nFiM0J5WG^#^lxq zer!U?B_=wv&_||z1*dSc9dsABY={VPIBuCz#p! z1(Hi#7Y1nPF;}J-1;B?gx0Ao&QL6(hPL8I@&siUQs7=D2XF-cQi`>TQ9gy8m5>PQf z&gNE3RNMDLW=rrQP^hcXs?wl0VuEBBVVP)nskNBT`=HWCxJU@Y6!4@s^!1WFBve3Q zNT|UM*&KC`W32F;cxYh3y3vN(yXHC!B+3`uJVQTl+Z=75=n~b5uKJ$+v~a~V=Wf_| zc!$>S-(t7M0QnruUQa4;<|UYHW(}}F#7v_?Q+pb;c9*7J&%PtJ1z6ZUNlLLqe+!rxr?t+g(jz!8pT+$Vxp>uh2YB(Kzp|2K*s}>yq z;rZm_!b;s07zZu{OgO?PMw~>e6}Z@36(Jb$G_%tW=6mnC79^xQOs>;4RWZb4 zHC|@J=71vCV#y$?==TqHBh$>Af3z~y1zMY~h`9CI#Crju**eDjyw*Z$9196ZdI zPuK7Ei`(~_{@PnBwllo$Ov#&GcSJ9K7}XsJUF{kj-DENel(FXypDbl@H9wg+zgBLbutq-ZBQJICpn4(xGUzjM2 z5D3T)N%pU@Q^;E%f(}-9hk?kRKQp+#-#JEu!A4%NnQxNHy`=SlcT0}%HhYkBeL3qx zCUK0mNlmJ}Qj`K*PWVu6LgudlfLLx->B=PsKzNVzufg~X211g=BDbU z^g4%B{1SBsBYMC9h}&+kVVn#KO&$$)n?%TKs;+${l@bYQ;RFD2=ReDDQ+ehInPtRw#ab9@C488qV z57VRXIl-AD;c7?j2UsKaym+4WzifeKF7m^s;i4OMMw}l)`4HebfE)>{gZt?r1L!?x z>DcEsXy<5;rk0uvG)BD64$@q<8-6ajvSWmSf%Y%DW0*jg>l^K4K}&{W+bR z`GuP=AvbdLi-Hw%gLKc80Wf-#GIHA{T(f+a_)4_zW{wvE2ktHB607*-%K$`}d*wg} zg9is>c;Vm$)`#r&lAZDb00>!3nFS%>F%$y{HKREei12!2op5&~J%n97kRyhqvIfdC(X z^u$bgKWn7duSo!sTJXWUm_PBOI~>th*ZQ6v85CDsL-|hYV`JByMn6IReJpP6Kq)k2pIN>IvYJ2_J=gRzd;LE&9G}@ z=0KC{T_6G@{J`x2zyK@7*{65d1+w{cn}*#HwH6vos>C@UQyzHrA|1GOp5F5xo}u@A ze48_6n$2qNrw|W?fDQ$#=dlVbvP=}LW%Q!BhLC?FPiTyIj3B>8L=cwF!nyzwF#rQx8aRj3T!XmUs4#fg_wofg`q4G|$oo#yU*6Ltl{)~V&L7k9O!)7 zt>wY4|9G~^G-Cl$Fxc~q$Uy~~EfuMw9X3`kK>WsNQ>^)E1 z74D?<%p!$tk3p|Oc0Ih_r-j)nz4&TLY7;QwvTq=4&|W23swFFTjniO$S|LybIcz|8 zKQ^GnN}ay_$|>rX7FsSy_1g{5aM!Uued4(u@4{Sl@2ig#2y?ZT{auKM;#ZY?BSrUC z93hbj3PRW)402a2Xv_r+&b@P8;!lb|BRXNGF(ZVIXcB+Q0VP>-{sn$lALRJl1AmM6C54Pxg zUp7ti*G|(F-?@*INFDvu8Ct(@OR8rANH`G~oZAF>(Kx!orjyO;W0=rSRwWQBrpOi= zI(uo0E_%%phj6alw@J^w?<76AS)sqUYlrJ}$Tc=C0U~PnZ$4l+Y{Lq-susaSh3u+{Vav<^qBiAyKU9U0SStd%EggCde^8|JKI}&yku*WBHUqnfg zMS^l-01;OT`Kc6F3Pqut;zKr(A%Xh=8<KBmqPz@Sx&P z?-+k)RbD5zhje^=T z)~sONIYAvBbTD!(Ye}x#i$R^g-V4q(hqNkW=*y4Y2bXlZBf9?j7X8Sp=4tzQmzHjt zp~K(4kF5_Vzm2rhXCB?5-Wd~t0Rv2~1bQHqjG|X?0c*wVrA=CS;T$bpJHx|%;)`eK zslPhK5i*YqtMq3d-Q+M%0S^+zk%0%jU+@zy4gAA~hC_&PTrE%$!+=4azDtoemJHWA9R2s3##DyL4Sk#oujpcR59icK`@t zP>?7Wo_Br7y?wVuHp3iQ zfDA^vaxScQBRv+pwoM)aFOy^rfW*sZv*Wc0JbRBWJI0QDw>N!&UGY_81>m2O|3TA(lCGd6eo|u2mFX6w)l{o(JN;M^TN z-;i)hEe~7>btJ{Vq$n!?8xD=z#8@LR#v;dji-pc#2E_xU2>0vC6w0uOD#*Ty%Ga{M zfmv51+z*l> z*<{dD#lj_j+3rYtryI0qy20i}>A4hum=rvug`%2EI|HIqJ44!J;2=+iU|F20&LR+;9V3Gih8JEbUNJbk#hSaDTyh4`Y()ferwc_uT-!%COUysM4F7)jj z3uiF3L* z@|xD)8ZZz*wN5UqH4wKKh?n3+AoLT}H(|xlPj{nF$M4$UBC^$bESQvoe9tW4BKjdf)NuzE!Tv}Qi?haJFb+SJG!vO~X97xj1 zz(d{*;S5R6Qs53(#C>7Tmm_hjgxtZmVx%n(dam^~xps}r_jF-Mlo(1?4>HBYEg_Rq zEDkVF$vLuC@jtoFJtiwe$d_Io2$*Ht&(UzO74>lg7;wqq3>f%JnFVZCZrjgIA7At- zWm;h6NcpErn#DcEUWzZ_3nmRugR<%13q=^D`B?@$vvbcmt6JR_u;JEfP-dg-|?WH)Yf!H^FXQlYeQ|P<=ky z^1w4g0`-AabgjfXE;*Nj zxsk&s`MH$=sgaOCxmE|FY4}|wH2T_ob$Z8dTuD2p`t-~P*CgvCvO;bmZS{br4>W1{ z##vgrdWL_m7h)xY4FfK^y*?r8ljT@n(v)+^t&;Gg6FLP_os-YW z;$ZI&4%Ot~A=bYU#qXUK0S-7`8g0ye)H`KYTF51G`=GfH{GyRs>9hKrfgi0d~K*|WA zBK|}CdJ%n{L0^biwJJ^3EyqBo!fd@t%TraFGR1R}Z7Icn@W+A8%Oj%A{)mACtPgot zs|66(A94UhZW!WY>?&q1jgC@;T-XMQZmL}P3*R9uQ(PS(|ER)kdhppk&5Ww_bqAZ) z0ukMF|*&?;jMcg0Sx%W`6>(cm4bziTKlw-csx ze$%AuA_kD`Ov+@<1i(4jLmB@-LOwN5b^R{SEpb-?~Cq|G-6b@(X9_$j45zdjjN1 ze7FV%A~2A9W2Q>2l{&SS8=O@Ve*Ja&Qxk(DI!rx`rR!$s z&|6k%?XENQ@%Nsj&m8L!sJd$T@&Lp@ToxIiz~2BG3@}h=&w>rypxqr%yDJ=)>4rpW z$($S$@);Z4^8_5E5eTuK)bd~&l|$bN7e@&u?Ei%kuLpEK@gMyL^ z03cLK8=9}M9W(BOEH_;(N(ELdU~;7!>qM4N!d%ajf3QXU&XEXs@E5W?Q7Zw8>6*nq zmu}UaOG+{2#Ezp|<2xn)ih}!=vL-msm_YDq8#KO z4B?kb1CkW^8&_a$cluaVL@kWB;q;6^I)r7mKcX8CHtG9cI!mj!&eOp+t}@r*$lsl& z?dQ83#>oY>%;RB*9U`MA%6OYn-mVvqvr*QoT&i2I!*S*>^aX(IyLEy8AwR@pzju_L z91wl_>9&c&(0Ve4L@b@b+_lFdN&Of zU0F28%`BQ={L}K>s7{z)*!oc7xw!?OS}&Poj)(~FWuq}0**Z*+B}E77eN-ccmJb_+ zBWL@Ti!g-r0ssg*n7WWPVuDT94r!9VHwwp-T!tN$U2j0gaMUFf&dSItiJft{0O79C zf>2PXw&Zr1#UE}B&H+H|LNS%IKG;6@Y798Lt*oRlKn2Iw+Xxtp14>XYG^;d=vcC?~ zzK}p>22GNTi#Mq^Bs$X_(Pr2196XDSyDp?3@$A{@DqVAl!(s5cJT*qKg^O^-0d;yE zc4?q$=u~~$@EyWME7zlWk3K)7>0yOlb@4a=QD(k?*jb^ko*vLWC;M#qifZMYh#0SI z{XoKkdI}&F8-IBb$M&W@dL@Gwq^74(~jCDQFewo1HfvsR^-xs;E(`pje9r)T}BI)_~gqF@^HHIBg8^OAYC zV4Qh;haUNZqtt5E=;C94xh9Xws;jY|lNQq~9m`f>mQic>P{!N)J*tmYFa;~2>jr|9&Z zs#O?Bw76QIUphL4wslNFjy&5Ho zL$BXs;Mk}&O>rc5!C3(D#L*#54J&jT1Bfz$rGWba@>zxGk&OY}cM5Z_jKWQWRKLXr zbeW_%TpHWS+Gx8?W+!&&$jXP0W}NiJT0wti()@wgYLsV?ZWK^+0kaF7q3JyuqOej&d!dm|CJ^BLk2A~K7-sE?6a%%+O zLA#EDlqqeCL_Nw6k#Ui+nyFW4zE!i?OMiqMbfjVI?8~^yqA}Ka1 z6*k>IwlSdl*FfY=C{^zvagZ7V4>kpJys}^{aaKmMWcI#VdJ2@E+nf{_E;QYae;;`_ zdtMTpmBN#Dc z2#lD(gb@T0Oc($W5JWHl%z!Xqn{Wie7B;qISyif1sU($3sz$%+SNHq>UwgZAh?Ti> z_xs#^?|V-Y{D`Xe-o0m^b9R@xcIL`VoZNrquRcKk|x8(XRkNw(Z zdg9j~;D`y`d-FR><~RUIfbYQdFgOZ>xDEzf6yr5nt}&oO zN{4ehnRW|A@EP1W;7v%vG4H^$!JKt~QO0^M35bb`(2Do}!m4by%(|BzP8`;p%;F92DYm{6xA zK0Z1PF50CKu^NOm#;5IQv-6)d0qDyfHtVbpd2T}>{k=7uDnI}!KE)w#e56<~ zEyHHOE{$^|q%8`^2X|Yv9qlcM03h6G<&{U+d-oTF%ekEaee|&~3^P_R34q{bro>73 zNd3f8snUiuN-Z>g4H1m-+c(4l@e7ZQdni#AbI+FufOzwMOW(bNv0VosqIHouHQ@^7 zwP63GWrF=_E&~IY`!&^XDgAlqn(qVYH9#xeGoe6@S481{-gs!O2yx5wSGf%O3Vwj6 zs!M`>JKjS^P86S2+MB6G3u_hDBUp|e+(9BZ;=C!hk3o)h=4vrC!vY~PcRp|F*Z#@_ z^w0kF$2o;HToy=A4dr`$drma$#P#smi(Cg|d~scQZ8uurNgTX;Ot-&vKsUd!NAufD znm#b$)Yh7DRpX^4zwh9Fq{@SR_G`Ji^BAQtOhPdta{w(-8uQ-RXdy zeiRN_e{q)-p?nTy0=@&HD^!_;x;IUKjO~GT027++4r6@nMoW`!KtK1W;Xq_Hj1M3R zD#*M5K*JCAI{Mz-4FN>K)bD2_l)kQ4wz;*X>mBBB0A}!kl6wU@u73{lqmbV->9rMr z%v?+XI%0`>1@sbo|$Y2RlEDCCk9eJ0rTX zE2YG49<_9ThP@}?LGqO#2EbV#7(mQc3?Tmbzxf1L)_ms=Zqc1@A4(mJAqr}BwAf#A zUI-+Jnm#<{GTpmZCNy~fQ5ZuLh0)n44Ajv${9wkJESLK&lPaf|$6P;yt9ULtnm#eWyjtD>(b75S-E(`s1$m*4F8G0+$$IE zlPrzU)w)ocE?*u|c>fCb1#gQErv{>@t_%tK%M0czds-*Y7ESs05tRm`P zi{PPWp2HUiWoiZYVcmFIO9D*PiPgc$jH2u}sl0`Jh;Uxt8sS=i$$)MjOS*Ts2gMyA)&_B3sP)05e5Q_1^S^EY1n;l5qw9ZupRWJKo>b+8 z4}`13513fVA)Uu7iNs*bhBuOYmNN;Z;LhA>q&>vCsfU5rxcu>5dg`w|$YG%P_s!>T z(f|DK@6r$eg26%~RtJCp10X<LsO7*cJ*g|Xf1+mqpHYTIKIaS`u>bk)UoEx`fTvhND-yG?*YfJ|bShG(hR20Soe zmAB{IOlJZhjAF4o2vf^K>Ua!Ss=VqSx%W4LZ}Nv?Ni`+1sI>e!qGB5WMr}gpTK5!EN!;B z{>IPn#kQ_>fQSb#HgtYRuMY3+xC}@tlgl#dr6IIyDyLT53fVty>BhYU%@++lc417P zdgufI!kaG$t#|iZdh5Q_aVUp+l>sIzPU>iCtU_x|@YOzF2m1g7@f>U!Kj~7sk9y|0 z1R#pwAsmk)anMxFbXtp9f z^yK-5-GlG$3%5vI6apRq9GHm63548tBKA6(&szHB&tIm0`R_j&3=4yBiTpD^m#XD10Y-}?wTl!!~$V*KC~@DHsAKf z*G(YDJFk|!eZXG`OSf(hAoO84`Qem{(wiEDX~fwjfN% zPv=;9qI(A|9UME$%LCH^J@?3tbGzAY#_OrHzTCKAJ-&a?($zgNpO^oo0K$!Z%TY^TD4!M;D&i3DR3@ z%Rl~u_vods-lS#-;D8WJAxkb6D+UPz8c}CHXRCyUb9xpCWS@jp!iIMSJP0!$Cd;Kg z6lY3+V|+1Y0LWaRt7kXLSMC7Qb#v-gM_Y0#);`Ew5WP{+-Qigdf+@1*fOO)5SMV$m zrvx5&w9du?VNQcV8E%L|hZfa3A#%n|noic6+ldlHN#_L^^_d8Yb>>iavzil? z$z%zVC8tgm($?99Z-xR2Hcv?`-dRfx@0=oPavs1b3xLqBbvj# zcg0$XlqHnj2Zt?P>jeclhEQ7WYiu~$VjN=NV{U;T05Y>>OViPiK6-gXPn{od z{*)iw@91!8(q0&Ag9Q-AeZiIpqY7CqcmRSOzpIY^#lQUo{mK^}D2@-@7sxIN%f!(Q ziNZil4DcB^*8|G&p%%tY!=M3$w00jG)6Sz48tujeR`;0M@rr)?-@Q(ELD)p;K3Eo3 z9fJpI;jS3*K7_?VLNw*4@*kWPBFYb;075ws9N8gU2>jE^&9VOFv2G>d801QsLleo? z4lbR8Jn^yjP*4jT%*6Fx?t_bh#X&mnfsq&@Rk|$rKDp;9K#`vcUG<4)1R&gGIH2HI z{31Bi=(^Y?<$buo%yL&k3dC zG^YK=U9cx$VZqpGMLJKrdk-!t@RE@2Q|I1yk?Q0ip9$j4{H=>G%gkEUHiq)v?R$K zi@pww1Z$$gon!kND3<;;ncst@y%vqP5qI2InDA*pk6#$k#~+YTX+-T@KjQk;*5E0w z3bB&qEfB^EVcpUq zh?sHD34%Zf?F&`w11#$SL?4vM(x4lf&`n3AWa|N}5Pn8V5GhRvCoB<~?i%Y*BRBl2o|>4-=(0>QsZ`2Aj?ET0 zoPqZv?(g8tj=$R@ab1)M;*liTerQY9g7A)c(7?Sm7v}C0yEc3af|GoCtAn|Bkdq<> z4{Y~28yAMRnKE@S*v?>phW$O76j&gZs{=!l^s*}!l||1cDGHPdf#?fpPTC}yFoOhD z$%3j8s3Gw2m5F2A$4j#$$l?>A-!9*#2q4x7U*}dSkSvS*hxLF*h=a(QsL8DiU@)$* zoymZ9Cj;V?72cjn_z&!^AUZ-V4v^3S!fqt!jR1k~`Kj}viv*_?RPqE73*n;vmbD|C zQFs6lw~srzUIY*WCNBagLWt#akW>PQtrTwQr0t%GD;&uZZWX_3ZO^)_v_5EZtEAj^ zrSdNlQ!B?K3_cbY68z<&SV|Ro`xJ3upP?G9N0R*5bNwG>;gR-WDuwl?bt^}d-H~-cn^bh{=N9mG@kl0??^|$=`S8mZ4fA@Wk zte^pQabqGZT+%2>AmwsE*lL_?l|aZoTstNQL=b@?;o@;JDa`|sw?6cPCLvkM-sT)Q zd^rHylG^27FYCsQ#7Tfztn^O`8Zv-F2PSKED7h@^!2^%j*#HR5Ss%JBeBj{hbp8oS zCj`kwZqRIY)1>P4vn!Sq;u!&mKq1OATsmmYWEm-?Ft)I;^Ne!zvO=oO(A*%iaN7JdW~fW!`JcHrx1esB#c62fI+ zQ);gPc<2xETs(d*O*o_>p9~t~Y!z~KHQ>F4RN43;iW6IzR02zv94A5vpXLSZE4;&uX3qTPO6_1`D z(`O$UaW={C-9dy7@|c9B?ZcJgR`iLVK1YA=AO1uy zCt_P*aqIew{_uZ%NH0Hsmj+GC(H#h-M|h^_FU>^Rm^9V`1aMMd3j+UalKc;@HU^SN z<-vod-%bIqh|CYT@2;yaeeu6D5}Q5Vr#Tx*5gb^yJ0WlKW_90bpcED@1wBZMky znJBqS!kQW}=RqtMuI(8B2uuz`1=B^%>i}V@E(|Otxkl!RHGxoJK$L@-u3gX)wJ#DW zw;_P&RfrV=Ap;H3_)}jr z*~&#>CQDbU*}l>m>jRS{p`1q&cAcETD!^+Z4}xiq*K2h5AT|J`b|LhLE_|-eKcYi^namQhsq03Lw z#&f8p1rmnz$+ay23^Zl6vpm?MT3+r4%|yvO3NH&~2p;NygIlk%H?`Ktc(9;BCvNiu zq!wj^gKuQZ}$;24wV9iE} zQZ#~OHNQ@)rRIT%g>^W|XUTtXTRdGw@Rze6n-xox*)JndoiYJQ5U!9g-$WgN=n<5` zS2X~l1RgS*$lrP1@8Cu-$#OWh{_=FB!gmoL`-%y%&gxQ9bY;OXM7d#;Jsphh{J+9| z&HP|JjvJzfck(68{k4U@f{z2UXJgZUr%K@NjOcJF0f@G*oXE&ioJEDZjr*ccc$WI_ z@4P- zBJdXqRe=xj6VL9@&;Rlz`s^=Wq>p`Kmma<{=_Ol&%dmHENguvHqc^^LK(D^CPw%{W zNU&}UM;#53rPf5M>4DI#n8tty;c$=^)M7HERN2&oQE^31o4(paTPS$YqFSDX-sXQO z-z!!0?TpS);BnP)o_fd*U?SR4w#fv@YaIz->Evpgu* z=4>qxSWV)9wpBPqE$N7B@Ue`P01nfJcR@>wqie4ES&x7?Jpd6eH1~I3{s*-ta9s^` zLu3>LI224y^HMMe)V>NIa*^DVEaZ~_hWrJ#)y5$!Qyw~gq2Ca^7k*?3_zrc zXgdG_%RDs0p>F`e4p#;$k(Lt;iRA=gfMBV+x)k#4`AWj@;0k7NsVx6oCdn%I#Yq)r z4={)nW&-48S7yZ+Guk^ZyJMj*xDInJWXzsZZ>91-P3}YgDbw{Ea|kyZ)^(c6GQ19< znGc;C(dQnY(9;(O^xB=4tqv%=o#!(40XH9GD4|jm1ULZ-AT%R{J&m(06=lK4H9SH^ zZKLEwSPY0RUK-NFSH|@4qhosL;W3@RFr?8$B;D+|rGxzy-Mh1(Teptra33lEhcq5H z)C^mqM$+H2)dATpjYZkYNqp#8ywwuH?u$+$F%&fTrMzR{;8*dK$O{=4XMI?w!TZ1i zLptU?fIQjj9xE~<);(Y6F|oNRJS^iL*VFXct$;&-IAjzPvSf5kUNp$Gl%9#LM@^{4kJOp@eoyvV_Zri#cg_#p3(+ z_17D@s`u@=S4QcHHDW+0YmT2~U<%WxG07uu#9+v^LFVkwF=t2uEx9!)j*lwTtJME-ks?Pe5?vSXjJl~>~d2hEZ9WGWh zZW?;-%7lLLu_4`?cl6Z{R_wMI@j5E~>)B61*Nx0Ha#M+wngc>~04En#R)le%87;%< ztBnXnHf!?-fQGn}r9D2zcTy3cWw3z%M)k@BkgtF7B8ysGN_g`P7R_z@ZN}6s!fot>ll? zEn+T8l2T>v*#{o1i6?I7o_hus2pyELD3-ng7E2PbIs}_MbCr2E`gSm1@(B~bNNbAVwCyUK zdV9kD+NV+~gjiMI`@oaGllq>w9+)Ut0Jj1Cb_uD3VC(PwtjOG|FTN?aYhN--VQ{zybyXBwOOB5avZo!8+!wjD~Dc>quO$usVzpUyV;R z^}WfQDzB?!h(cKg{1~f=)Wi@l5C8|0*TEIbGT=c|Xsce7E^X$vNS3jCzjkq#I!+l- zlMcTJ#P;EV-tX49FRDO;85I7p&K(kSA#6O4drJ>gdLLSFYLLs>MPb-F7`&FkpegMt zf69eW%%b)e9lJ9u)Zp-%#r%EhP*Roud5X7$?>DwSL;`nX0HN4hirXA5=e)U~MB)2& z)0!7hKT`gKnWyyvZ9Ra%6_{JNYmOHSw#1wpPXc8UO<|pdCEA2_>8sbjZ@RaQz(YxM z8MO;! zJa&M>?u_j6KWzY!u}&l(xexLr%o>YB9$>ipc@Iro7TVS;_id~br*DB^tAWiVWr>u^ z=&=?E6`+g}JhbWo3XR{lUF$kpEpC_sTW0|v;)Pf7jObK@7S@%))gBu*>0@&yB+D2G z6_iSq`y!S{h0|8pL+`JxPJ#LM_>>vlpU( z$;`YrXT&p-24R0p2sIW6a9nI+q>?l`34l07_eHAM3xF#?Ss{4P912q1w6VEc{Cp;L zR>EWvdrvJ0?#i(UpWmlo%Kg{9eT3{})X+~oG@>s&fpyT(pM6O5#yv6btHr7pH1%0S z{IRawm&zSeSB8idRS%|5rn;u(M<{@>KLH?Qjf;x|5lxaC1A7-~+0tN?KJzFU6d+}`$+T&TVkuDIYb?jZSQ`TUR|jmn+eAHINdT3`0C^o z-Z#JLD?p=pwk1iTuc$?CdMn%jGY01KVBU)J+{Z--I=^1ACeqUfd)~D7DzcKGcArZY z$CO~m#6wH6{9%zN%ZkNU=91yjh)&Z4e?#$y#m~a~!8LQdZ0WJ{WBTh)Pw8Wq2lV{) zmj3kGjP@5O!wo`Vh07+fHq^+k4Z)Qmm?iqj1Hr~HVat14i-fsm$rc81AWV*guBGGU zoR$B%ovB^(nz?m4o;dk#^qUU~lHWBPQ|H5`?w0wn`q8`BMkL2|hm>|k%f+o;;$$8K z_5qkpp+t%xwgU|wpa@=}SItt8d{I)KZARV$ulF5JVUe zto7Z^H3B}wGp$Yy_~MrH8`N>Zlfu8El36bpeFeAfB!Rn$;#87kJ|}|u#~IOcie#67 z>Hi1*19Lr$GC^3YthW$gDajJ2mwdVK8lV@GO)KUzAQ0A_VERtY;^&9rL?+2J0Tp^K z$`vlGy70|@Yrv)eqGucfEK$0yJf`@DLmUmSB^To8lPsmK#+X-os?ciYyJx;CfTWHq zo{f|6q#4k|y92ti19y`E2ZY>yct~^uRWO;mAkXBz%_PYsO@XTFY!c$}V;Gm^1 zzO$tF4kQGa_x2L*x&ckb=xf~?>s5#qeUnvDI3W1#lh<)B3m@qQkfeTmuz*xzJ?~urnSms9^>;(_#QbVix zO{upOlnhu84&2Jv6fDHo_d^A_+TSsDAfg-P%oqlN`JM@TuXR=jeXd-`ZW#{3Z6J#KFEy_-$(xDG`pNsNr;C&(XQ;S@!qb|Y+bh2)bua) zUt7h=$-k5&Syq7fCakh4X5OsTvetacTWeFL8z2TdklVN~@a~+w579K^Nihw#KlVrm zj(Rp+jLlykRsD!T=w?6)41Xjn!h1u}KXqY9&s-i5%D3Zh`0!C;1w0r0yLsHvH*dD| z?g1PVlHMAjxu1AwLcjIwgf348^oQ@P=%t$|y5@j}>Nf_BD+3ynJR$n-74x^n8c%hm z4=fCc$9!bJQIe+*9L$j86~IwouEVfl@L+j{NYTydpqH{2jHS&OK4hO;Kp~(&0f7S# z9QWZx5~_U2S?6m3SFG-6MXvmQ$``i^7kYc5D z?6OF&Jp%wCBphBmzAM6vR~&_rSRgcKM5(>8PS_K>xenFSR*PGXWZ5g6DilZsfN&|T zahmqZUH6!%eZeZg!_xmr-G*>uFdcOW%b>N|A90M#-xwg#A zaRdU~a|#5iTyEy@V8##Il~1kM$7cv2031L9eB!}|p1#u1Ll+x*XlFp}(SUB>YH6_` znvBVS2LJ)2rN>^B_kH=sg1-9xoGwmB^qbF2=$9THGO+mKJ1b684)77WrDTvWqS(`t zBH8P!w{P4==uwJWj7@O29z|%siX%ik5P_GseHf1zK!h9E@2ga>WosN~b(1RvFc?ta zStl%z@YcHm34MmOs3&qKR=j<3Fq|W|zXk;E16SNMRM%cOkX`3}fTjjq6o5h4@#sct zz(l5PmL$pZVk{KF6WnLEoizic;Nfhlaq5KgPIB2OWm`IgsZkm-H#!;ar-Bg8W@+6X z2FaG%ua@_CaS+J~*KO&pL2S8|PalF%{F~YFQL>{Z~0TT^zY6+F7|6UbBK0SJ5 z`+hP25x$3YMQ|b+=i@FuBN(5sf1DqJT_0t4K+vK}xb`UH3dQFubKey)?8!b^Hb=X6 zvAHlfMRK3Nyda=9?t3Ui!)aK*ws3`zBo}PGgtG#3a@p(rS5^TINX9Y^E5=y1)I!=Q2)4e(j9`gm?deBp%{) z&|DWI?^7?E%U)N#HuRkc>wS?GA~KRz$z^#)6KPl3;A}ag~$2^tDW&4lz^B9EZRn+)`V# zH|`1zMP?p{rLtA5Z8P?|UNldJswLY$E9-szU2*>`h};4^Al*10GVgfYhjk!e-S;Jg zyXog8u%P$pcWo4{4Lk|jHh#v2R)^qTXTgE6ZVTt%61j&-&`1pBFhpiCL#{Nm2kRdb zzgw6y!nr=e&7u|y`4r$|L9j}+%ln*5qUMws6DUP-3Tezm7la!)G-s9;Tz+F~_BKB0 zt(Gj-)8bNn&s(pw(>K~2K*;I2rHM(`Er$mmXvG_*M&O3m=xHBj{%pY||I}oGV{W5v z3LwG}LJDRv%Z8SM`sk4mNIQM#Dd&|@&PiVj>!%7l)UA^~z~Z}H{1fHoYdqzV*im61 zB^-kWmW^?o{ygqSG{!dFA+0EI(S)S3|PwBj|=bT`x*a{#AKoQ`{uh*hEB=V}zB}d`R+2&7#X<}aS5BKv4^D=Ck1Dy2v+kgkT%X0RC z;mmC+151El6M(S}B>2yWt}VDXwg(Q323#h~!0I61xqtaWTxV{9Py(dBiseA4r65oU znT3_9qah$xt_?U8=AN>@T_lKZRxoa1k!Y6()O8W*vS2|#TdO!V1+&uz-T;>tqrV`^ z0K&g2a1R9a12$L4c{SGeuHk0DUz};MU0*OPZCU7haADXd{H4(<>_d)9XxCXE`jlu{ zAWL5*)1Z(fJzk5`eEB&qT1?7gZTqU}plx4&v;YFapGlJJQp#5-jV(`ZP~5xsMlX4e zcqJYpb0_|DVyk8x43V)TdiL>#e)ZF^9*9cOcMDG>ovVMh+zT!V5mqW?$M4ePA|8RYW+o@hT z>)w`vVQOWI`_|u|l6*lc^b_H{Jg=M!yVimh@84K)m&ZS~v&yy7R}>UGpr*ZLc57*U z<(^*}hZ3mR=JPthplUx*?(yS#Ee;MGRB;_t(b{K-)q?f#*+gNORHUn{u zr(nr;=SY@y03zP(WhJhn0*rblgmySJ`F-{ALZ5K15VQsNiQm^EaH$r)J?~glbn*p* zr=_G|-!=_*jr$_D;wX^vPpx5OPP}BoKH|jt;Kc!b{xc&wzXNLo5+5N{+PEwjI5Y$r zg0)68Ej5D`jmJZpOh@#>*OzqlYRg;+fCmN<3?xt&h3M_Qj=uap62e8wr3yT_Hquvf zLhnpiWRX*{eoZA;Q~?li3nT0lU>(sF4k-5Tl{`@N=f}0jZ;&0ch4-AIdp3WMR1I$q z9&nEtDx`KD4ZC|pEh;?YKK{E_0E9~SXBj&5SRZ=HlXAx}=reP#;2t?wMF}|Q=b1Li zdwCX%vjGsgY;-~-=YyuJ7QE0Hh3zYPY3F|@%2CLdK^_Qey$FGVT<-3@NqbIdx&n|m zrgnKm$KXytnGC~n+qn%?XWESfkH2`=DV7%GB>zObjY2ML(1O5mR*)#dBt|Sn7e+ym z1^cv4A^SNO%KVU$0Ez`pDkwA=5}%aV;!_YNC*(hrfTe#@cc=fzb#hVwQBZVvwq}yV zC7iEe%QW0F0~JEKFpg*$kSuc+plBRWxD24+bDtd2BbT83VR-;}0C5pNJs>f{_Z(zSY)gm9|g6pLiVPbpd(9AHp)L}+nHzgMUth$V7i#2^MGD9+3R zVcZOX^}uW%{jBH@v;Iv#ag-@>6o+wUPTYt1VE&3s~i;Z$>-jyVjQA( z4atnILTa6Vx)1#5yVMC}|9SWw^9(Lbz(1%|4mCtu|9Q%|mr~W0WX9r2tO7h#0wEzD z3ZW4eC@adMXCvkDPkm%aAAL-o4PXGv!vw%!B;-gCCh-}7!?0;-IuVkjx;4O!*qIFI z^|xAj>6=TMa(Jh2iNO7c!#DrrUDyQ8zj%7907NPu-vN=31;^>G27rrM;Wn#CyN;cS5}H*y@0}+Ce7G zrlHmHfcX!0k5u;2O?RJcKN)tY1`GO_UeK^DaL{&flt^fGaNy!h00ahE88xmhhPohF ze%OuX#<&G$#z(OUELVQ>%`X&<{d$@Y& zIUks}0E+=Y1fS~R%79BltPVJVPGNOmSB8KJacKz1K+b|c{_=wM_d5X|rihv*n*xY< z;d;yN46b4w4DaR#2Oo!6LMgI4!X#1wM#2MlKcLM=g7hfvsyXi4ciwjia3`9hp2#51 zlTkZ{@$iJem3byh%(u^}8F1n#L}0{nU*0s9r6oXc79gU>wUGb@9~{K**kduUU+FIe z7e|HFL7pn@&)fpRk1}DHm?U3;+pJ|VayBjsOO#a5VO=2-z0up=11iqqp@7Cje;Aw- zpW1v2h7Ofg)|Rso10^R8%IyIx%*62z42*Hk=-*~B<4-MUBje{HR^ammNKvkaT}BF2 z*g}H)u83L#WEk)O?93SS*tdmJHff2={`d9Pmj07SUXhjA*!fNBN2_QOt~_5M|Go@B zY+v)qtLlhD{iP=bC@^>cAkgfRCUkQEolGab=nj5#;p!GH*#TsfT(y?M2z zmtI-X)Z9}n5kjm)80YM6WfJ9ufG4kV`W3sk5&2grJ|ycxM%R!~8n3wsVq~lj zc(S^Lge2*#Z0WoDd$ev|Hnl#;GhHhj2AE`N<~2WlX}?2kCHKSsImBEoESyflxKz{!hJ|UY7!j#43_WK6OR_!c3_L z1oZVR88Se85uDd0(bqoNF!7={+zXF@$!}%unS|rn&vn&ld$>+;8aFVc&|dRhxW(;p zH%uFL!uap)-Amwzh+Tv2?C;L{5w+iXrHXr|T^-V5ai12;eHsmrB&U>S`6K|M1Rna7 za2Y_jt-c-%sK8=Hj1EPAw8Ka``j0J z6O91i5Lr%$mF}6fO0eQ&DkEAmjx|6?-cm!H@fY6z;%-AvKRV=Wl1z5=b3JfrY0UVN z{p~PePXHL;$}qeLwLoyhh9Ozvci`f=2 zt58L22h=KkO*z#&f~9X-l2g339fW=>FB_$scMpV^=lO~_DDV}Be@1{s-*?mY4n(;A zDkyN9vLsNHY-%jT0qF2IUf=0pYec~t49QiHe2eSsh8oQKE3XvGr;!qX=u=+n0fevo zlueG@8N&uAR3EMiaKK3n$!+qvCEW8iSA2c*ae4qkfF*JXAU_4T0Xbott}Ovil1UO{ zwiA#fE0mk=4J*snE1~VIIR1hwDnuG!Ed(-Xz&q4?ip!?&V*#C zk6x4V`t&UjtoU3;NSlh1^KKv_Wu7C8{5>uWY{d1IDB zIMD)xNKujpoWq~7EW=Or}b_|LU z3d-XPj0EJB@b?QzCp@jE+aB0cf-~oz)#Ut;o@PSAM zl$>=GhCB7kCi4}dSRVYc%qlJnF;bPV!6E^FLP19aJ_7Ql=els>$ZXc6oqq1z6i$h| z=nvBYGncxs%-xM8#exv~{8D?p4NE>5su*Nx_$n{@@Ohgq$<43tID_YMc7q6HQ7h8D zJN=jd2)}Ot4725&P0tWA=O()}ZpK>ECo>G8fY@C5l>|(UP%iTyf)_0)7+6*~MRF9G zgFZNtq?DKT0f@WzhCry-eCsQiO+i?ykgyf--?HmubI`N7Y>gFje1{M~q{=;n6Yj5q zwSga3`YyVAMapacUZ-z?;5lrGFxqB@pF-@J`|(2r*Y1a3VU_ z<02@CNlx;iuvf67OV&O=06hia>t)WA{^qS3MgMcQy;r_G0A1TH-OXBcY>imWZ-vbg zBwrFL{@7Mr(-VOay+A6jXh4g0N&7Qo8trJ*jOoJkyp#(s%C8E=r)%0tZSUFJ1Beu? zY^Hc|H5127p(_r%9Y~TQ&Ljz!PL%DieB#=^AMsk=9E8bmq6ikkGO@J4HF*5ofS$S3 z(1Yh1R^)Iqs2gHBY8Xgdy+5aK-<)&lybC*Hn!+04ktrQFLP(b4>X7hG01gWx%T-h`{5&w)_^&?-#)PIZE0iO8H4gF=|?>qwGy%Daa9 zU{vz@^bw+ruF1{B($-bGa-S^M1< zX*g$;QJNo-cV~o8H`nxVENV!S?pf*mnErn@c_30n9+M|i>qCl!xs7p$xJi_7o20#h z7CY+(IB0wOy=JTQO^1$fsdFQs#sQa@LlG{1uf3VyYFH!6WE|Jfzsn(yDb43wHRbFo^`?s%8UhO@<-`42neDUC`= zi2`;`jRG&sVKS^CD9w%fdh@AiwMNO{J`lFz!jWW9HVt=x-}+8hrvo6i;Xk1CHWd5Q zk0PpKNRK}#)`n(9w120g#eT=3oU;}9EJ(2}386-`WEaLk+tAmqFX{G?SR-~#o(Hs% zB3dEIl3g1NAWY5(%@<*S1-K9UM?`=6;)8HAX?LQ@zt*?!ea|ZQRD6e%^s5g5xcj27NNk6-wL6&zC^q_Ry>f4a z|A6Y79G9_ft}^{uBXZ^Ib#hr=crEK8dqE9g@b2DA%*;TP4XqCD4rc-&CW;~e4}m)()84aSIF5t5!gSKzXdL#PH)`+saGgcN zL{W%;BfFtHr&ZB3eC4D){Pj00i!Wyb$p9kHB>pjxC8& zqi3L4G2}^MtZ3tJcXF-}+NZ>SFvu;KJUpF~e=U)J#8_-Q0TG;@xCkIhl$5@%2M==9a(0bYi@TN8H*+~e2pE0Nv^Uo#oDuFO+HA0x zx5Ei*Td_-H;anPJp%T68DFO)G%9`(yBY_K1<&$5z{0|FG2_CYwJ@B}3=waVn_?kO^ zU6lo5je-f1O_?;@B6Js=AWPB)s~Xr0w8hG!#>CwR!u07J7;VZwfAS+k`i;+y=<@l2 zB#Z)hm`D~$bcfvyQzQW*dhHuCx_5m^`>TeImkmcrup43sf+ZCCfd2gbCCxy7A=Itt z#2UebO3w;mzyos|j9UZuVD|{D5+k@V8v4$gD|+)9DpWR6YHMSa7&P?yz1ET`!;Mn` z(5k?LQkL%NhVt`TRf!3ow#?b(}er zlf7|Yk&zbwQCv9L!*;NbJDMN9#r2MCU#i_J6@6VREjPKK25ETLVxD}kGg29u`Bne)? zB$`-xo+VkDG}Rj`xXMTpU&-{1AwUBNh?8N%!F10)(a^6vH|AUpoPK(2Drnj&no@RK zcniqtI-u9SL3Hm{N4E}JCdnedgOVV3#{;^4)Y0?TVU22NFu*lSF4K)fQet(``>92u zu{k6JJP3%`84u{@y^db^4ziwxBuaiCCQ}aR-kj*Idu;|=ofd#Fb7{B_AQjpKQ$`Nq z3Xm)jl>qZTuJLwGVbj;G(Qs}n6>1eQD(@ZPJ}f2dTB~>(ouCJY*?hqV2IPH6YqvQ0 zjBLU4!`GQeSv-7g1t?BWmiFH%a$giNhWlbOYl8WwW_obk0ZG}`R1QgVXuw7mc zAaI2gj{?gZmJ3%b?MwhfPvpY376`n%mXkENP~>e#Nk(F;1M*h88oTZ#}=Hd-q$qeSq39 zz6$~o3Pj(&y`neoVSL0*0T2N&0hfl-loR^NYnz1c74FP}460Vf z>D_D?D(diX{fe?Rg?T?qkXQi_;kwkrKsfdwP|lCuG;`zRbgz`muJyB)xqX&`(%Y^9 z4W6RUvo9hSMr6^*TOGnSrw<@vVeUm07*!aAbEYSHy@4uKLxwaT2d4cvA(T&~^gu%1 zbz&5>AJvd)&nMrk>m(Ht4iGru;DC!_58vXVol>}CxF0-F?lb-U$Hn^KFX!d_7PX5T z-bW_^5C!mH#)G*Gh%OjSyz;~T+pGr=!Mm?oj@m$;h+ZFZ@kCV;D&FU(1R!unq&SAq zM6#Xmeb!i?6kG`(DTI#2`XbWg8#_F2>EHjy^b)oDkuGA`c9li0lU%FySKy z#*Qf{7O0WJn#3Jl7^Kt?*}l4J9ulQ}^tXQ{c#4i4Hvhv26;h2WGFVFKI>RU8!Z8_U zlY9^;pmp0sV1$R&D)1ib?OqUlf`ePp6%pSvXBo&mH@IKUWU&Qsuwdke0w6s1Lr(Gg zr})x|-aCyO8$gmr!VR5=Eb*%e1=BNuw&&{u_d{mG8@Gt6ZyqYVgvwy3xm@~1LzPEF&s5CnGk*d+bg>I){^cViQqt z_*ODWg0BO2MC6Jq$c%XJ$e4lmqh-6zm?4?m>;qaJzfVl4>0RaVyY{T*QmW*_kc$B`F7^<0ugC60vdjH%@9O*eK*7AlSZvL>MddZLtD)~59(-n{5G{K zkEj$2(hUKGJzW@AL#Q|_6ke72-N8hF6qrMqc<7(ddrh(x?@>6lRGokZqD;hcU`S)x zStx)oUq^UGTp?K^-Ls|*-o783xGxZ{`OIStSI@+-NOC8MqTsaAP0RnWs{!OkLuec! zm9rMV0+1LJE#^coeRV-M?!!gXF@Rvj&ejMin)MeSuITOp7AsA4ElM9Cq3z(-A=;ge zxwJQahx_9v9~yE9>E67f>xV7fyifG<8!H=mq1FnxGaQf*E5sd>nKB!yy++a6^=?R# z05>5iID&ZSjA(vzRdU#HF~S!#+Pn??QO%;BY$KXGYoA~W=puxY!`@Y6i z5rC4&VqxFoOu{(b!tqbj4pM|+oY~FhneUzT!DVzzb4XZKYcPj<#_6>8tPp&Xb77!G zw?(8tovS9S{b2!v2RZ_hs2ModXD?OwsV(4>-w6337RNt`GM<$LLP6nq8(dN_gCx17 z$-PQgq(UhnXZ8x}3L&!vfWTcPH8)CGgA}Kk2P>Xe5W+dYvQdfWDkW1^ET|y+;Kc!b z>gl14e9+TB+za43?2H>a$H|}!uYrFmvC`D7Ff}VCQ=%WdzM}7aZ$}9NMwIC`TnIczeLovD*B*gby z>zdF88DNodlVmv#mB2wRI}-qbi7{G_xdWnY)p}s2+4R(y>GdzI7$->}0@7p5V-WC_ zws-vx6GpjQ3UL%g2zZkA1_<=G*TpM~Ql?Md*t$<59)-Wb4eANPT=fn?d%gKt`QkR* z0P*E5r@lsHhTHDBUrQ%6jF?0hAl%ZGA6}P4D*L=G0fZ=TM?8eEbw1=+cvUF$EdT^U zF!2s}c34@k;&~eY2-{av0vV?^U9-9MnO`33PlhcG=-hO`c^(j=sR~*OUm-nnOVi1i z-3qW406@T{f!{SU!={@aHB!@JG@!+zqpyE$K{xMrv}nbR!63p^&;$s0;l_&YElg!i z&F7%$sZB%%K*Y~n8PKy2O=vI#z!AO$_zkPUfd0#0%;}Bm2H zr$Z`lmZK+PeZPK<<=k+bwe$FO8g$3zhW+3pS>HcOIh!c_l7&IvI%kbAVSiD_P6IgD zm2fs;oH9`=`2EwfJBb@?As2>9$0%FdUe&RU!Vp3X-?!904&4j@i6PWjvq<>-fQJx( z06z*N21;&o^|qIhG5`5MDbwDJOG=*X+XyE_0Viy}JiaDHYivK$UrPW2C+;x1z}#gk zf$5D=g^0qzEljIj9_3~(@R4FCs3L_nE4YlK)Rrjr4^_T44D z^@Eo7=OA5b^-OUupv?zI9ewkb;X*VLvZ?8;@e_OXqYpIn=|^B0G}RzMvShah@=^@w zo$D?A=NIOL3=9@945Hi+h8unT$Tz|j_Nf_5F}IsyP)P~uP;Ccy+G<_sj)b*DYfZp) zw4P)c_M#sY`76#BCCYgW4LfXaRX+Xa-m9hA{;Sk=$eyb*H@64+gx(s^zKtkO z+z;{d*MSAreqN)pdqOV?tsT+*le`e|^W|^O3LX4A6AOelK^_p$M+bQo?BK_fYc@|` z`(zWvGwISx2i6aB&k|^HM=)*AX>VL<@j`o-|H1X&awn|yAqvOz?j>-+==I=EY z2z~}C3z{_40oP+IMd1UddH^Bsp=G~e1@QXXdlGZc^M$**`A|Lc;meZr36=*a?bcM% zMByvA4}@3XMMP+FCj{Nw_%rqZ`ndzO|q~e;-^3x#!q$AZ(^fQ@`V2 zA%(tVRMK^aPY_Mx2!FBFA-|3`2M~RlO+h0vxUMHzRso1)jmT=ya@!2XDl6iK!xle% z{a#k61mG}d0HIl0dt^jmzShggO%X&5ILJLUuhflZ&%S0aXb?nT+LbvDCEy?p&kR7g zd=4@%zG#sF_f7LQBcxq9PI;>$wVN^P3ee4JCezC#Y1>DNKYOZA6uR7(?^@B`Pa>tu zNoP*dB*8e3Lmb-ZM=Yq4cVp$a6nUkR zuY4J_Pa+!pFv=6QSK#7h&J4H{){PP_-WYf&xU%jZ&0raEK2BTlpW6LUKKJk~bAHe1 zS`eu~l0+h)5si_iHY)^-irZLVMw@<1^Sc5FH!cHC5zQsEN0W%3VBwB;d0zN9cDzaO zlw^|J7C^-P_TSw9uJn5dB{*SK+i~T`kc*M_6?aq%1BW*nz5o>Upy}A^U~@2-?2?*? zLCBQGI^cy>G9l9PAtY0!hi3B#0xPXHv#c0ey&U(%wL z6x!;#c;Z4sKmCXa6E)xk&*RLKoW!c525y!~L#x@4zJ0BwKY0(F4F?X?rJ)uNa3fHE z1jNo2!pY501tiJQ$gd_)*mgbV{*CuT3=zZiNsTtuSUqAz1@7YOD{LYu4n6SZiruJdm?8F*bdAmPKzZj2>)G;>eg`6-fEn> zVC1I)A7KLfQ6MgQBn{z2Lk><43Xu739u8mS0SKR0T*p5qU##XgX|=c=$OiO42#OHG zlH{f)4rP{t|erlGcNIr;&U?<_2}inz3PEB0s>7@&;zKFtok8;wrQ z{o*Dy;NTPlZ)HNMGD}*v#!6lIBg6R-Ne{v?x{6_t80ua97x5Pt)-sP+)fmv583oaNm1fg^lX5l)Q z$>{>ebLpEW_2nt(85fL`r z(u7j_wJXL$$Aw^Sgo)IEi{a}puV{Z?*4i;bE)55Q%XT-Y;z{%^Q#li(^plr|^ze?B z^;XaTq9!a7V!2RD1Q*;IcC>eUL9gFx>G_)t-`^L*m}(aRA^-+%prd6=-2fH`FB9TP z07QmsunvHP-}i%S3y>G6HPh0$=~S#wRvD#m0^@KvpYwR&P~g@_{ALxPMnrZNU~NXA z98kO5quC(fivySpf)sg2#i1t5aGp zhkvS$CRr7+7Y1sTeXhNN7M-NHz5PB6@6>w+t`_Uhb-*LFc=#*bSsi3X)E^wRH{;?f zA^Au^ik&WPuTdv~>*9xmhPPboezWE5ecr@4#Uk4y6ekiQ6$M&hqyM-92+TxCJVafM zyrSUBf=t8|u19$ceA&6#Ni`6Z0hWl@%!cSpC&xdCNt4F%5QJHpYqXe_adT+(O|?G28gXvg&>L^J^ybwSp`aFA7EGwL zStZ3n@amn8?$0}V^8A1v-8IRqjGIHP910rvC)^pvVuCE0;JMzpy`V2%ozr0pen^_# z5a5YW_I|Zw-~Tx-_5|W2LOkKt*xZ5;>eHIJ^JP=Kk^2FJm4`%hG@sMqY)g>quVEgRxG+lKEqA-}yPu`xHL5)G zLKSY0jX;CdGA95Iat~h0rys`YN^z^wwaPhgD~KXbEC^QdJK|!{K6ZV?8!~S1SulK1 zqizukO3c)$yTGGycovDU*jLW2VA~tq>+>1(`7TkX51`DO7%n@fY6~s4-iRmyqMFu$&LdEX00B~kIc!ernL5tCxD3i z3gz*M=GuiRMC3-2G%WHhAR@x+KyIW(Xy1Hi+j-5seqYTO&l#aI#Do;#;% zEPG0z@<#z6A|a1Z!8b-7sq6!e+BIU-8;sj)UVaFMq-c;Lgl a%l`%Pqpm2!H;pm?0000 - - 演示插件信息——自定义组件 - - - - - - \ No newline at end of file diff --git a/niucloud/addon/hello_world/uni-app/components/diy/comp-extend/hello-text/index.vue b/niucloud/addon/hello_world/uni-app/components/diy/comp-extend/hello-text/index.vue deleted file mode 100644 index 675230e9e..000000000 --- a/niucloud/addon/hello_world/uni-app/components/diy/comp-extend/hello-text/index.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - \ No newline at end of file diff --git a/niucloud/addon/hello_world/uni-app/components/diy/comp-extend/index.vue b/niucloud/addon/hello_world/uni-app/components/diy/comp-extend/index.vue deleted file mode 100644 index c123926f4..000000000 --- a/niucloud/addon/hello_world/uni-app/components/diy/comp-extend/index.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/niucloud/addon/hello_world/uni-app/components/diy/hello-text/index.vue b/niucloud/addon/hello_world/uni-app/components/diy/hello-text/index.vue new file mode 100644 index 000000000..687e82f7c --- /dev/null +++ b/niucloud/addon/hello_world/uni-app/components/diy/hello-text/index.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/niucloud/addon/hello_world/uni-app/pages.json b/niucloud/addon/hello_world/uni-app/pages.json deleted file mode 100644 index 75f858400..000000000 --- a/niucloud/addon/hello_world/uni-app/pages.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "pages" : [ // pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages - { - "path": "pages/hello_world/index", - "style": { - // #ifdef H5 - "navigationStyle": "custom", - // #endif - "navigationBarTitleText": "%pages.hello_world.index%" - } - } - ], - "globalStyle": { - "navigationBarTextStyle": "black", - "navigationBarTitleText": "", - "navigationBarBackgroundColor": "#ffffff", - "backgroundColor": "#F8F8F8", - "backgroundColorTop": "#F8F8F8", - "backgroundColorBottom": "#F8F8F8" - }, - "tabBar": { - "list": [ - { - "pagePath": "pages/index/index" - }, - { - "pagePath": "pages/article/list" - }, - { - "pagePath": "pages/member/index" - } - ] - }, - "uniIdRouter": {}, - "easycom": { - "custom": { - "^u-(.*)": "uview-plus/components/u-$1/u-$1.vue", - "diy-system-(\W.*)": "@/components/diy/system/$1/index.vue", - "diy-core-(\W.*)": "@/components/diy/core/$1/index.vue", - "diy-(\W.*)": "@/components/diy/$1/index.vue" - } - } -} diff --git a/niucloud/addon/hello_world/uni-app/pages/hello_world/info.vue b/niucloud/addon/hello_world/uni-app/pages/hello_world/info.vue new file mode 100644 index 000000000..85165f697 --- /dev/null +++ b/niucloud/addon/hello_world/uni-app/pages/hello_world/info.vue @@ -0,0 +1,166 @@ + + + + + \ No newline at end of file diff --git a/niucloud/app/ExceptionHandle.php b/niucloud/app/ExceptionHandle.php index a7a9337db..d27b4dc29 100644 --- a/niucloud/app/ExceptionHandle.php +++ b/niucloud/app/ExceptionHandle.php @@ -1,9 +1,10 @@ rootUrl()) : $app_type; //写入日志内容 $log = [ - '服务主体:'.($app_type == AppTypeEnum::ADMIN ? request()->uid() : request()->memberId()),//服务发起者 //用户ID + '服务主体:'.($app_type == AppTypeDict::ADMIN ? request()->uid() : request()->memberId()),//服务发起者 //用户ID 'IP:'.request()->ip(),//ip '耗时(毫秒):'.ceil((microtime(true) * 1000) - (request()->time(true) * 1000)),//耗时(毫秒) '请求类型:'.request()->method(),//请求类型 @@ -102,8 +103,9 @@ class ExceptionHandle extends Handle } else if($e instanceof UnexpectedValueException){ return fail($e->getMessage(), [], 401); }else if($e instanceof AuthException || $e instanceof AdminException){ - return fail($e->getMessage(), [], $e->getCode() ?: 400); + }else if($e instanceof ServerException){ + return fail($e->getMessage(), [], http_code:$e->getCode()); }else { return fail($e->getMessage(), $massageData); } diff --git a/niucloud/app/Request.php b/niucloud/app/Request.php index e6fd28691..4670f5e45 100644 --- a/niucloud/app/Request.php +++ b/niucloud/app/Request.php @@ -1,7 +1,7 @@ 0) { static::$site_id = (int)$site_id; } else { - return static::$site_id ?? $this->getDefaultSiteId(); + return static::$site_id ?? $this->defaultSiteId(); } } @@ -165,7 +165,7 @@ class Request extends \think\Request * @return array|string */ public function getChannel(){ - return $this->header(system_name('channel_name'), ChannelEnum::H5); + return $this->header(system_name('channel_name'), ChannelDict::H5); } /** @@ -173,7 +173,7 @@ class Request extends \think\Request * @return int */ public function defaultSiteId(){ - return 1; + return 0; } /** diff --git a/niucloud/app/adminapi/controller/addon/Addon.php b/niucloud/app/adminapi/controller/addon/Addon.php index 48a61b8dc..621a8dbb7 100644 --- a/niucloud/app/adminapi/controller/addon/Addon.php +++ b/niucloud/app/adminapi/controller/addon/Addon.php @@ -13,7 +13,6 @@ namespace app\adminapi\controller\addon; use app\service\admin\addon\AddonService; use app\service\core\addon\CoreAddonService; -use app\service\core\addon\CoreInstallService; use core\base\BaseAdminController; use think\Response; @@ -34,17 +33,34 @@ class Addon extends BaseAdminController */ public function install($addon) { - ( new AddonService() )->install($addon); - return success('ADDON_INSTALL_SUCCESS'); + return ( new AddonService() )->install($addon); + } + + /** + * 执行安装 + * @param $addon + * @return void + */ + public function execute($addon) { + return ( new AddonService() )->executeInstall($addon); + } + + /** + * 插件安装环境检测 + * @param $addon + * @return mixed + */ + public function installCheck($addon){ + return ( new AddonService() )->installCheck($addon); } /** * 查询插件安装状态 * @param $addon */ - public function getInstallState($addon) + public function getInstallState($addon, $key) { - return success(( new AddonService() )->getInstallState($addon)); + return success(( new AddonService() )->getInstallState($addon, $key)); } /** diff --git a/niucloud/app/adminapi/controller/addon/App.php b/niucloud/app/adminapi/controller/addon/App.php index 6e98f6190..2a9402d53 100644 --- a/niucloud/app/adminapi/controller/addon/App.php +++ b/niucloud/app/adminapi/controller/addon/App.php @@ -12,7 +12,6 @@ namespace app\adminapi\controller\addon; use app\service\core\addon\CoreAddonService; -use app\service\core\addon\CoreInstallService; use core\base\BaseAdminController; diff --git a/niucloud/app/adminapi/controller/diy/Diy.php b/niucloud/app/adminapi/controller/diy/Diy.php index dd2597776..bcdbce201 100644 --- a/niucloud/app/adminapi/controller/diy/Diy.php +++ b/niucloud/app/adminapi/controller/diy/Diy.php @@ -11,7 +11,6 @@ namespace app\adminapi\controller\diy; -use app\enum\diy\PageEnum; use app\service\admin\diy\DiyService; use core\base\BaseAdminController; @@ -67,7 +66,7 @@ class Diy extends BaseAdminController /** * 自定义页面编辑 - * @param $id 自定义页面id + * @param $id * @return \think\Response */ public function edit($id) @@ -84,7 +83,7 @@ class Diy extends BaseAdminController /** * 自定义页面删除 - * @param $id 自定义页面id + * @param $id * @return \think\Response */ public function del(int $id) @@ -114,7 +113,8 @@ class Diy extends BaseAdminController $params = $this->request->params([ [ 'id', "" ], [ "name", "" ], - [ "type", "" ], + [ "template", "" ], + [ 'template_name', '' ], [ "title", "" ], ]); @@ -132,16 +132,16 @@ class Diy extends BaseAdminController } /** - * 获取页面类型 + * 获取页面模板 * @return \think\Response */ - public function getPageType() + public function getTemplate() { $params = $this->request->params([ [ 'type', "" ], ]); - $page_type = PageEnum::getPageType($params[ 'type' ]); - return success($page_type); + $diy_service = new DiyService(); + return success($diy_service->getTemplate($params[ 'type' ])); } /** diff --git a/niucloud/app/adminapi/controller/diy/DiyRoute.php b/niucloud/app/adminapi/controller/diy/DiyRoute.php index c718f4cf4..f3cd0cb4e 100644 --- a/niucloud/app/adminapi/controller/diy/DiyRoute.php +++ b/niucloud/app/adminapi/controller/diy/DiyRoute.php @@ -73,7 +73,7 @@ class DiyRoute extends BaseAdminController /** * 自定义路由表编辑 - * @param $id 自定义路由表id + * @param $id * @return \think\Response */ public function edit($id) @@ -92,7 +92,7 @@ class DiyRoute extends BaseAdminController /** * 自定义路由表删除 - * @param $id 自定义路由表id + * @param $id * @return \think\Response */ public function del(int $id) diff --git a/niucloud/app/adminapi/controller/generator/Generator.php b/niucloud/app/adminapi/controller/generator/Generator.php index de406e92a..b378720ac 100644 --- a/niucloud/app/adminapi/controller/generator/Generator.php +++ b/niucloud/app/adminapi/controller/generator/Generator.php @@ -55,7 +55,7 @@ class Generator extends BaseController $data = $this->request->params([ [ "table_name", "" ], ], false); - $this->validate($data, 'app\validate\generator\generator.add'); + $this->validate($data, 'app\validate\generator\Generator.add'); $id = ( new GenerateService() )->add($data); return success('ADD_SUCCESS', [ 'id' => $id ]); } @@ -75,7 +75,7 @@ class Generator extends BaseController [ "edit_type", "1" ], [ "table_column", "" ], ], false); - $this->validate($data, 'app\validate\generator\generator.edit'); + $this->validate($data, 'app\validate\generator\Generator.edit'); ( new GenerateService() )->edit($id, $data); return success('MODIFY_SUCCESS'); } diff --git a/niucloud/app/adminapi/controller/login/Config.php b/niucloud/app/adminapi/controller/login/Config.php index 615a461d2..9e238a55a 100644 --- a/niucloud/app/adminapi/controller/login/Config.php +++ b/niucloud/app/adminapi/controller/login/Config.php @@ -15,6 +15,7 @@ use app\service\admin\auth\ConfigService; use core\base\BaseAdminController; use think\Response; + class Config extends BaseAdminController { diff --git a/niucloud/app/adminapi/controller/login/Login.php b/niucloud/app/adminapi/controller/login/Login.php index 1aa47a756..e6d41cd0e 100644 --- a/niucloud/app/adminapi/controller/login/Login.php +++ b/niucloud/app/adminapi/controller/login/Login.php @@ -13,6 +13,7 @@ namespace app\adminapi\controller\login; use app\service\admin\auth\ConfigService; use app\service\admin\auth\LoginService; +use app\service\core\addon\CoreAddonInstallService; use core\base\BaseAdminController; use think\Response; diff --git a/niucloud/app/adminapi/controller/member/Account.php b/niucloud/app/adminapi/controller/member/Account.php index bff428abd..a92806efd 100644 --- a/niucloud/app/adminapi/controller/member/Account.php +++ b/niucloud/app/adminapi/controller/member/Account.php @@ -11,9 +11,12 @@ namespace app\adminapi\controller\member; -use app\enum\member\MemberAccountEnum; +use app\dict\member\MemberAccountTypeDict; use app\service\admin\member\MemberAccountService; +use app\service\admin\member\MemberCashOutService; +use app\service\admin\member\MemberService; use core\base\BaseAdminController; +use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use think\Response; class Account extends BaseAdminController @@ -28,11 +31,40 @@ class Account extends BaseAdminController [ 'member_id', '' ], [ 'from_type', '' ], [ 'create_time', [] ], + [ 'keywords', '' ], ]); $data[ 'account_type' ] = 'point'; return success(( new MemberAccountService() )->getPage($data)); } + /** + * 会员积分统计(用于会员积分统计窗口) + */ + public function sumPoint() + { + $data = $this->request->params([ + [ 'member_id', '' ], + ]); + $member_account_service = new MemberAccountService(); + $member_service = new MemberService(); + + if(empty($data['member_id'])) + { + $commission_data = [ + 'point_get' => $member_service->getSum('point_get'),//累计 + 'point_use' => abs($member_account_service->getExpensesSumAccount(MemberAccountTypeDict::POINT)), + ]; + return success($commission_data); + }else{ + $info = $member_account_service->getMemberAccountInfo($data['member_id']); + $commission_data = [ + 'point_get' => $info['point_get'], + 'point_use' => abs($member_account_service->getExpensesSumAccount(MemberAccountTypeDict::POINT,$data['member_id'])), + ]; + return success($commission_data); + } + } + /** * 余额流水 * @return Response @@ -43,6 +75,7 @@ class Account extends BaseAdminController [ 'member_id', '' ], [ 'from_type', '' ], [ 'create_time', [] ], + [ 'keywords', '' ], ]); $data[ 'account_type' ] = 'balance'; return success(( new MemberAccountService() )->getPage($data)); @@ -58,6 +91,7 @@ class Account extends BaseAdminController [ 'member_id', '' ], [ 'from_type', '' ], [ 'create_time', [] ], + [ 'keywords', '' ], ]); $data[ 'account_type' ] = 'money'; return success(( new MemberAccountService() )->getPage($data)); @@ -74,7 +108,7 @@ class Account extends BaseAdminController [ 'memo', '' ], ]); $res = ( new MemberAccountService() )->adjustPoint($data); - return success('ADD_SUCCESS', [ 'id' => $res ]); + return success('SUCCESS', [ 'id' => $res ]); } /** @@ -88,7 +122,7 @@ class Account extends BaseAdminController [ 'memo', '' ], ]); $res = ( new MemberAccountService() )->adjustBalance($data); - return success('ADD_SUCCESS', [ 'id' => $res ]); + return success('SUCCESS', [ 'id' => $res ]); } /** @@ -103,7 +137,7 @@ class Account extends BaseAdminController [ 'memo', '' ], ]); $res = ( new MemberAccountService() )->adjustMoney($data); - return success('ADD_SUCCESS', [ 'id' => $res ]); + return success('SUCCESS', [ 'id' => $res ]); } /** @@ -116,11 +150,44 @@ class Account extends BaseAdminController [ 'member_id', '' ], [ 'from_type', '' ], [ 'create_time', [] ], + [ 'keywords', '' ], ]); $data[ 'account_type' ] = 'commission'; return success(( new MemberAccountService() )->getPage($data)); } + /** + * 会员佣金统计(用于会员账户统计窗口) + */ + public function sumCommission() + { + $data = $this->request->params([ + [ 'member_id', '' ], + ]); + $member_account_service = new MemberAccountService(); + $member_service = new MemberService(); + + if(empty($data['member_id'])) + { + $commission_data = [ + 'total_commission' => $member_service->getSum('commission_get'),//累计 + 'commission' => $member_service->getSum('commission'),//未提现 + 'withdrawn_commission' => $member_account_service->getWithdrawnCommission(),//已提现 + 'commission_cash_outing' => $member_service->getSum('commission_cash_outing'),//提现中 + ]; + return success($commission_data); + }else{ + $info = $member_account_service->getMemberAccountInfo($data['member_id']); + $commission_data = [ + 'commission' => $info['commission'], + 'commission_cash_outing' => $info['commission_cash_outing'], + 'withdrawn_commission' => $member_account_service->getWithdrawnCommission($data['member_id']),//已提现 + 'total_commission' => $info['commission_get'], + ]; + return success($commission_data); + } + } + /** * 会员余额统计(用于会员账户统计窗口) */ @@ -134,8 +201,8 @@ class Account extends BaseAdminController { $balance_data = [ - MemberAccountEnum::BALANCE => $member_account_service->getSumAccount(MemberAccountEnum::BALANCE), - MemberAccountEnum::MONEY => $member_account_service->getSumAccount(MemberAccountEnum::MONEY), + MemberAccountTypeDict::BALANCE => number_format($member_account_service->getSumAccount(MemberAccountTypeDict::BALANCE), 2), + MemberAccountTypeDict::MONEY => number_format($member_account_service->getSumAccount(MemberAccountTypeDict::MONEY), 2), ]; return success($balance_data); }else{ @@ -158,7 +225,7 @@ class Account extends BaseAdminController */ public function accountType() { - return success(MemberAccountEnum::getType()); + return success(MemberAccountTypeDict::getType()); } diff --git a/niucloud/app/adminapi/controller/member/CashOut.php b/niucloud/app/adminapi/controller/member/CashOut.php index c0272185e..f7b0ccd96 100644 --- a/niucloud/app/adminapi/controller/member/CashOut.php +++ b/niucloud/app/adminapi/controller/member/CashOut.php @@ -11,8 +11,8 @@ namespace app\adminapi\controller\member; -use app\enum\member\MemberCashOutEnum; -use app\enum\pay\TransferEnum; +use app\dict\member\MemberCashOutDict; +use app\dict\pay\TransferDict; use app\service\admin\member\MemberCashOutService; use core\base\BaseAdminController; use think\Response; @@ -28,7 +28,12 @@ class CashOut extends BaseAdminController $data = $this->request->params([ ['member_id', ''], ['status', ''], + ['transfer_type', ''], ['create_time', []], + ['audit_time', []], + ['transfer_time', []], + ['cash_out_no', ''], + ['keywords', ''] ]); return success((new MemberCashOutService())->getPage($data)); } @@ -58,7 +63,7 @@ class CashOut extends BaseAdminController */ public function getTransferType() { - return success(TransferEnum::getTransferType([], false)); + return success(TransferDict::getTransferType([], false)); } /** @@ -82,6 +87,14 @@ class CashOut extends BaseAdminController * @return Response */ public function getStatusList(){ - return success(MemberCashOutEnum::getStatus()); + return success(MemberCashOutDict::getStatus()); + } + + /** + * 统计数据 + */ + public function stat() + { + return success((new MemberCashOutService())->stat()); } } diff --git a/niucloud/app/adminapi/controller/member/Config.php b/niucloud/app/adminapi/controller/member/Config.php index 736d660c1..50f8cfa18 100644 --- a/niucloud/app/adminapi/controller/member/Config.php +++ b/niucloud/app/adminapi/controller/member/Config.php @@ -37,6 +37,7 @@ class Config extends BaseAdminController [ 'is_mobile', 0 ], [ 'is_auth_register', 1 ], [ 'is_bind_mobile', 0 ], + [ 'agreement_show', 0 ] ]); $this->validate($data, 'app\validate\member\LoginConfig.set'); ( new MemberConfigService() )->setLoginConfig($data); @@ -71,4 +72,25 @@ class Config extends BaseAdminController return success('SET_SUCCESS'); } + /** + * 获取会员配置 + * @return Response + */ + public function getMemberConfig(){ + return success(( new MemberConfigService() )->getMemberConfig()); + } + + /** + * 设置会员配置 + * @return Response + */ + public function setMemberConfig(){ + $data = $this->request->params([ + [ 'prefix', '' ], + [ 'length', 10 ] + ]); + $this->validate($data, 'app\validate\member\MemberConfig.set'); + ( new MemberConfigService() )->setMemberConfig($data); + return success('MODIFY_SUCCESS'); + } } diff --git a/niucloud/app/adminapi/controller/member/Member.php b/niucloud/app/adminapi/controller/member/Member.php index fd3bca923..7a6ce885f 100644 --- a/niucloud/app/adminapi/controller/member/Member.php +++ b/niucloud/app/adminapi/controller/member/Member.php @@ -11,9 +11,9 @@ namespace app\adminapi\controller\member; -use app\enum\member\MemberEnum; -use app\enum\member\MemberRegisterChannelEnum; -use app\enum\member\MemberRegisterTypeEnum; +use app\dict\member\MemberDict; +use app\dict\member\MemberRegisterChannelDict; +use app\dict\member\MemberRegisterTypeDict; use app\service\admin\member\MemberService; use core\base\BaseAdminController; use think\Response; @@ -55,7 +55,8 @@ class Member extends BaseAdminController $data = $this->request->params([ ['nickname', ''], ['mobile', ''], - ['username', ''], + ['member_no', ''], + ['init_member_no', ''], ['password', ''], ['headimg', ''], ['member_label', []], @@ -104,13 +105,19 @@ class Member extends BaseAdminController return success('EDIT_SUCCESS'); } + public function del($member_id) + { + $res = (new MemberService())->deleteMember($member_id); + return success('DELETE_SUCCESS'); + } + /** * 会员使用场景 * @return array|mixed|string */ public function getMemberRegisterType() { - return success(MemberRegisterTypeEnum::getType()); + return success(MemberRegisterTypeDict::getType()); } /** @@ -131,7 +138,7 @@ class Member extends BaseAdminController */ public function getMemberRegisterChannelType() { - return success(MemberRegisterChannelEnum::getType()); + return success(MemberRegisterChannelDict::getType()); } /** @@ -154,6 +161,17 @@ class Member extends BaseAdminController * @return Response */ public function getStatusList(){ - return success(MemberEnum::getStatus()); + return success(MemberDict::getStatus()); } + + /** + * 获取会员编码 + * @return Response + */ + public function getMemberNo(){ + $member_no = (new MemberService())->getMemberNo(); + return success('SUCCESS', $member_no); + } + + } diff --git a/niucloud/app/adminapi/controller/notice/Notice.php b/niucloud/app/adminapi/controller/notice/Notice.php index 57810a25c..d3d5dae3e 100644 --- a/niucloud/app/adminapi/controller/notice/Notice.php +++ b/niucloud/app/adminapi/controller/notice/Notice.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\notice; -use app\enum\sys\SmsEnum; +use app\dict\sys\SmsDict; use app\service\admin\notice\NoticeService; use app\service\admin\notice\SmsService; use core\base\BaseAdminController; @@ -78,7 +78,7 @@ class Notice extends BaseAdminController public function editSms($sms_type) { //参数获取 - $sms_type_list = SmsEnum::getType(); + $sms_type_list = SmsDict::getType(); if(!array_key_exists($sms_type, $sms_type_list)) throw new AdminException('SMS_TYPE_NOT_EXIST'); //数据验证 $data = [ diff --git a/niucloud/app/adminapi/controller/order/Recharge.php b/niucloud/app/adminapi/controller/order/Recharge.php index feda40cb8..4ae5b09bb 100644 --- a/niucloud/app/adminapi/controller/order/Recharge.php +++ b/niucloud/app/adminapi/controller/order/Recharge.php @@ -25,10 +25,14 @@ class Recharge extends BaseAdminController public function lists() { $data = $this->request->params([ + ['order_no', ''], ['order_status', ''], ['order_from', ''], ['create_time', []], - ['member_id', ''] + ['pay_time', []], + ['member_id', ''], + ['start_money', 0], + ['end_money', 0] ]); return success((new RechargeOrderService())->getPage($data)); } @@ -55,4 +59,18 @@ class Recharge extends BaseAdminController return fail($res); } + + /** + * 充值统计 + */ + public function stat() + { + $data = $this->request->params([ + [ 'member_id', '' ], + ]); + $res = (new RechargeOrderService())->stat($data); + return success($res); + } + + } diff --git a/niucloud/app/adminapi/controller/order/Refund.php b/niucloud/app/adminapi/controller/order/Refund.php index 2d5ed8650..42e755e3d 100644 --- a/niucloud/app/adminapi/controller/order/Refund.php +++ b/niucloud/app/adminapi/controller/order/Refund.php @@ -27,7 +27,9 @@ class Refund extends BaseAdminController ['create_time', []], ['member_id', ''], ['refund_no', ''], - ['status', ''] + ['status', ''], + ['keywords', ''], + ['order_no', ''], ]); return success((new RefundService())->getPage($data)); } @@ -54,4 +56,12 @@ class Refund extends BaseAdminController ]); return success((new RefundService())->getStatus($data['type'])); } + + /** + * 退款统计 + */ + public function stat() + { + return success((new RefundService())->stat()); + } } diff --git a/niucloud/app/adminapi/controller/pay/PayChannel.php b/niucloud/app/adminapi/controller/pay/PayChannel.php index 12a48c458..288529d49 100644 --- a/niucloud/app/adminapi/controller/pay/PayChannel.php +++ b/niucloud/app/adminapi/controller/pay/PayChannel.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\pay; -use app\enum\pay\PayEnum; +use app\dict\pay\PayDict; use app\model\pay\PayConfigTemplate; use app\service\admin\pay\PayChannelService; use app\service\admin\pay\PayConfigTemplateService; @@ -68,8 +68,8 @@ class PayChannel extends BaseAdminController ['wechatpay_config', []], ['alipay_config', []], ]); - $this->validate(array_merge($data['wechatpay_config'], ['type' => PayEnum::WECHATPAY]), 'app\validate\pay\Pay.set'); - $this->validate(array_merge($data['alipay_config'], ['type' => PayEnum::ALIPAY]), 'app\validate\pay\Pay.set'); + $this->validate(array_merge($data['wechatpay_config'], ['type' => PayDict::WECHATPAY]), 'app\validate\pay\Pay.set'); + $this->validate(array_merge($data['alipay_config'], ['type' => PayDict::ALIPAY]), 'app\validate\pay\Pay.set'); (new PayChannelService())->setTransfer($data); return success('SET_SUCCESS'); } @@ -82,8 +82,8 @@ class PayChannel extends BaseAdminController $data = $this->request->params([ ['config', []], ]); -// $this->validate(array_merge($data['wechatpay_config'], ['type' => PayEnum::WECHATPAY]), 'app\validate\pay\Pay.set'); -// $this->validate(array_merge($data['alipay_config'], ['type' => PayEnum::ALIPAY]), 'app\validate\pay\Pay.set'); +// $this->validate(array_merge($data['wechatpay_config'], ['type' => PayDict::WECHATPAY]), 'app\validate\pay\Pay.set'); +// $this->validate(array_merge($data['alipay_config'], ['type' => PayDict::ALIPAY]), 'app\validate\pay\Pay.set'); (new PayChannelService())->setAll($data['config']); return success('SET_SUCCESS'); } diff --git a/niucloud/app/adminapi/controller/site/Site.php b/niucloud/app/adminapi/controller/site/Site.php index 54cf399bc..8c41c6594 100644 --- a/niucloud/app/adminapi/controller/site/Site.php +++ b/niucloud/app/adminapi/controller/site/Site.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\site; -use app\enum\site\SiteEnum; +use app\dict\site\SiteDict; use app\service\admin\auth\AuthSiteService; use app\service\admin\site\SiteService; use core\base\BaseAdminController; @@ -27,8 +27,10 @@ class Site extends BaseAdminController { $data = $this->request->params([ ['keywords', ''], - ['status', 1], + ['status', ""], ['group_id', 0], + ['create_time', []], + ['expire_time', []], ]); return success((new SiteService())->getPage($data)); } @@ -84,7 +86,7 @@ class Site extends BaseAdminController */ public function getStatuList() { - return success(SiteEnum::getStatus()); + return success(SiteDict::getStatus()); } /** @@ -94,4 +96,28 @@ class Site extends BaseAdminController public function menu(){ return success((new AuthSiteService())->getMenuList(1, 'all')); } + + /** + * 关闭站点 + */ + public function closeSite($id) + { + $data = $this->request->params([ + ['status', SiteDict::CLOSE], + ]); + (new SiteService())->edit($id, $data); + return success('SUCCESS'); + } + + /** + * 开启站点 + */ + public function openSite($id) + { + $data = $this->request->params([ + ['status', SiteDict::ON], + ]); + (new SiteService())->edit($id, $data); + return success('SUCCESS'); + } } diff --git a/niucloud/app/adminapi/controller/site/User.php b/niucloud/app/adminapi/controller/site/User.php index 30576fffd..d01e3c812 100644 --- a/niucloud/app/adminapi/controller/site/User.php +++ b/niucloud/app/adminapi/controller/site/User.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\site; -use app\enum\sys\UserEnum; +use app\dict\sys\UserDict; use app\service\admin\site\SiteUserService; use app\service\admin\user\UserService; use core\base\BaseAdminController; @@ -55,7 +55,7 @@ class User extends BaseAdminController ['password', ''], ['real_name', ''], ['head_img', ''], - ['status', UserEnum::ON], + ['status', UserDict::ON], ['role_ids', []] ]); $this->validate($data, 'app\validate\sys\User.add'); @@ -71,7 +71,7 @@ class User extends BaseAdminController $data = $this->request->params([ ['real_name', ''], ['head_img', ''], - ['status', UserEnum::ON], + ['status', UserDict::ON], ['role_ids', []], ['password', ''] ]); diff --git a/niucloud/app/adminapi/controller/sys/Attachment.php b/niucloud/app/adminapi/controller/sys/Attachment.php index 95055648a..ca51b1f63 100644 --- a/niucloud/app/adminapi/controller/sys/Attachment.php +++ b/niucloud/app/adminapi/controller/sys/Attachment.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\sys; -use app\enum\sys\FileEnum; +use app\dict\sys\FileDict; use app\service\admin\sys\AttachmentService; use core\base\BaseAdminController; use think\Response; @@ -63,7 +63,7 @@ class Attachment extends BaseAdminController public function addCategory() { $data = $this->request->params([ - ['type', FileEnum::IMAGE], + ['type', FileDict::IMAGE], ['name', ''] ]); $this->validate($data, 'app\validate\sys\AttachmentCategory.add'); diff --git a/niucloud/app/adminapi/controller/sys/Channel.php b/niucloud/app/adminapi/controller/sys/Channel.php index b9a8bae82..f1479e124 100644 --- a/niucloud/app/adminapi/controller/sys/Channel.php +++ b/niucloud/app/adminapi/controller/sys/Channel.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\sys; -use app\enum\common\ChannelEnum; +use app\dict\common\ChannelDict; use core\base\BaseAdminController; class Channel extends BaseAdminController @@ -24,6 +24,6 @@ class Channel extends BaseAdminController */ public function getChannelType() { - return success(ChannelEnum::getType()); + return success(ChannelDict::getType()); } } diff --git a/niucloud/app/adminapi/controller/sys/Config.php b/niucloud/app/adminapi/controller/sys/Config.php index 07a5dfa29..7e027f947 100644 --- a/niucloud/app/adminapi/controller/sys/Config.php +++ b/niucloud/app/adminapi/controller/sys/Config.php @@ -44,9 +44,22 @@ class Config extends BaseAdminController ["full_address",""], ["phone",""], ["business_hours",""], + ["site_name",""], + ["logo",""], + ["front_end_name", ""], + ["front_end_logo", ""], + ["icon", ""] ]); - $this->validate($data, 'app\validate\site\site.edit'); + $this->validate($data, 'app\validate\site\Site.edit'); (new ConfigService())->setWebSite($data); + + $service_data = $this->request->params([ + ["wechat_code",""], + ["enterprise_wechat",""], + ["tel",""], + ]); + (new ConfigService())->setService($service_data); + return success(); } @@ -83,4 +96,12 @@ class Config extends BaseAdminController public function getSceneDomain(){ return success((new ConfigService())->getSceneDomain()); } + + /** + * 获取服务信息 + * @return Response + */ + public function getServiceInfo(){ + return success((new ConfigService())->getService()); + } } diff --git a/niucloud/app/adminapi/controller/sys/Cron.php b/niucloud/app/adminapi/controller/sys/Cron.php index 345f8d4bc..cf20b7552 100644 --- a/niucloud/app/adminapi/controller/sys/Cron.php +++ b/niucloud/app/adminapi/controller/sys/Cron.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\sys; -use app\enum\sys\CronEnum; +use app\dict\sys\CronDict; use app\service\admin\cron\CronService; use core\base\BaseAdminController; @@ -51,6 +51,6 @@ class Cron extends BaseAdminController * @return \think\Response */ public function getType(){ - return success((new CronEnum())->getType()); + return success((new CronDict())->getType()); } } diff --git a/niucloud/app/adminapi/controller/sys/Menu.php b/niucloud/app/adminapi/controller/sys/Menu.php index a58d6c863..5f3b668e2 100644 --- a/niucloud/app/adminapi/controller/sys/Menu.php +++ b/niucloud/app/adminapi/controller/sys/Menu.php @@ -11,9 +11,9 @@ namespace app\adminapi\controller\sys; -use app\enum\sys\MenuEnum; -use app\enum\sys\MenuTypeEnum; -use app\enum\sys\MethodEnum; +use app\dict\sys\MenuDict; +use app\dict\sys\MenuTypeDict; +use app\dict\sys\MethodDict; use app\service\admin\install\InstallSystemService; use app\service\admin\sys\MenuService; use core\base\BaseAdminController; @@ -60,7 +60,7 @@ class Menu extends BaseAdminController ['methods', ''], ['sort', 0], - ['status', MenuEnum::ON], + ['status', MenuDict::ON], ['is_show', 0], ]); $this->validate($data, 'app\validate\sys\Menu.add'); @@ -85,7 +85,7 @@ class Menu extends BaseAdminController ['methods', ''], ['sort', 0], - ['status', MenuEnum::ON], + ['status', MenuDict::ON], ['is_show', 0], ]); $this->validate($data, 'app\validate\sys\Menu.edit'); @@ -99,7 +99,7 @@ class Menu extends BaseAdminController * @return Response */ public function getMenuType(){ - return success(MenuTypeEnum::getMenuType()); + return success(MenuTypeDict::getMenuType()); } /** @@ -107,7 +107,7 @@ class Menu extends BaseAdminController * @return Response */ public function getMethodType(){ - return success(MethodEnum::getMethodType()); + return success(MethodDict::getMethodType()); } /** diff --git a/niucloud/app/adminapi/controller/sys/Role.php b/niucloud/app/adminapi/controller/sys/Role.php index 7561c997b..ca925d440 100644 --- a/niucloud/app/adminapi/controller/sys/Role.php +++ b/niucloud/app/adminapi/controller/sys/Role.php @@ -11,7 +11,7 @@ namespace app\adminapi\controller\sys; -use app\enum\sys\RoleStatusEnum; +use app\dict\sys\RoleStatusDict; use app\service\admin\sys\RoleService; use core\base\BaseAdminController; use think\Response; @@ -51,7 +51,7 @@ class Role extends BaseAdminController $data = $this->request->params([ ['role_name', ''], ['rules', []], - ['status', RoleStatusEnum::ON], + ['status', RoleStatusDict::ON], ]); $this->validate($data, 'app\validate\sys\Role.add'); (new RoleService())->add($data); @@ -66,7 +66,7 @@ class Role extends BaseAdminController $data = $this->request->params([ ['role_name', ''], ['rules', []], - ['status', RoleStatusEnum::ON], + ['status', RoleStatusDict::ON], ]); $this->validate($data, 'app\validate\sys\Role.edit'); (new RoleService())->edit($role_id, $data); diff --git a/niucloud/app/adminapi/controller/sys/System.php b/niucloud/app/adminapi/controller/sys/System.php index 563393b03..377ff5cf8 100644 --- a/niucloud/app/adminapi/controller/sys/System.php +++ b/niucloud/app/adminapi/controller/sys/System.php @@ -47,4 +47,27 @@ class System extends BaseAdminController return success((new SystemService())->getSystemInfo()); } + /** + * 清理缓存,更新菜单 + */ + public function schemaCache(){ + + return success((new SystemService())->schemaCache()); + } + + /** + * 校验消息队列是否正常运行 + * @return \think\Response + */ + public function checkJob(){ + return success(data:(new SystemService())->checkJob()); + } + + /** + * 校验计划任务是否正常运行 + * @return \think\Response + */ + public function checkSchedule(){ + return success(data:(new SystemService())->checkSchedule()); + } } diff --git a/niucloud/app/adminapi/controller/upload/Storage.php b/niucloud/app/adminapi/controller/upload/Storage.php index 7d26bff6a..9a6432fc9 100644 --- a/niucloud/app/adminapi/controller/upload/Storage.php +++ b/niucloud/app/adminapi/controller/upload/Storage.php @@ -12,7 +12,7 @@ namespace app\adminapi\controller\upload; use app\adminapi\controller\sys\AdminException; -use app\enum\sys\StorageEnum; +use app\dict\sys\StorageDict; use app\service\admin\file\StorageConfigService; use core\base\BaseAdminController; use think\Response; @@ -47,7 +47,7 @@ class Storage extends BaseAdminController public function editStorage($storage_type) { //参数获取 - $storage_type_list = StorageEnum::getType(); + $storage_type_list = StorageDict::getType(); if (!array_key_exists($storage_type, $storage_type_list)) throw new AdminException('OSS_TYPE_NOT_EXIST'); //数据验证 $data = [ diff --git a/niucloud/app/adminapi/middleware/AllowCrossDomain.php b/niucloud/app/adminapi/middleware/AllowCrossDomain.php index 5a0cb96d1..769ebf9cf 100644 --- a/niucloud/app/adminapi/middleware/AllowCrossDomain.php +++ b/niucloud/app/adminapi/middleware/AllowCrossDomain.php @@ -14,6 +14,7 @@ namespace app\adminapi\middleware; use app\Request; use Closure; use core\exception\AdminException; +use core\exception\ServerException; /** * http跨域请求中间件 @@ -54,7 +55,7 @@ class AllowCrossDomain header('Access-Control-Allow-Origin: *'); }else{ header('Access-Control-Allow-Origin: *'); - throw new AdminException('SERVER_CROSS_REQUEST_FAIL'); + throw new ServerException('SERVER_CROSS_REQUEST_FAIL', 409); } return $next($request); diff --git a/niucloud/app/adminapi/route/addon.php b/niucloud/app/adminapi/route/addon.php index 770cebf7f..74f64b886 100644 --- a/niucloud/app/adminapi/route/addon.php +++ b/niucloud/app/adminapi/route/addon.php @@ -15,7 +15,7 @@ use app\adminapi\middleware\AdminLog; use think\facade\Route; /** - * 路由 + * 应用插件相关路由 */ Route::group(function () { //获取本地插件 @@ -28,19 +28,21 @@ Route::group(function () { Route::put('addon/status/:id/:status', 'addon.Addon/setStatus'); //安装插件 Route::post('addon/install/:addon', 'addon.Addon/install'); + //插件安装检测安装环境 + Route::get('addon/install/check/:addon', 'addon.Addon/installCheck'); + // 执行安装 + Route::post('addon/install/execute/:addon', 'addon.Addon/execute'); + //插件安装状态 + Route::get('addon/install/:addon/status/:key', 'addon.Addon/getInstallState'); //卸载插件 Route::post('addon/uninstall/:addon', 'addon.Addon/uninstall'); - //插件状态 - Route::get('addon/install/status/:addon', 'addon.Addon/uninstall'); //卸载插件 Route::post('addon/edit/:addon', 'addon.Addon/edit'); - - //应用列表(...) Route::get('app/list', 'addon.App/getAppList'); })->middleware([ AdminCheckToken::class, AdminCheckRole::class, AdminLog::class -]);; +]); diff --git a/niucloud/app/adminapi/route/diy.php b/niucloud/app/adminapi/route/diy.php index 3cb0f8e2d..5e6e8068e 100644 --- a/niucloud/app/adminapi/route/diy.php +++ b/niucloud/app/adminapi/route/diy.php @@ -1,12 +1,12 @@ +// | Author: Niucloud Team // +---------------------------------------------------------------------- use app\adminapi\middleware\AdminCheckRole; @@ -45,8 +45,8 @@ Route::group('diy', function() { // 设为使用 Route::put('use', 'diy.Diy/setUse'); - // 获取页面类型 - Route::get('type', 'diy.Diy/getPageType'); + // 获取页面模板 + Route::get('template', 'diy.Diy/getTemplate'); // 自定义路由列表 Route::get('route', 'diy.DiyRoute/lists'); diff --git a/niucloud/app/adminapi/route/member.php b/niucloud/app/adminapi/route/member.php index 2b2fee8f3..6538683c9 100644 --- a/niucloud/app/adminapi/route/member.php +++ b/niucloud/app/adminapi/route/member.php @@ -26,8 +26,13 @@ Route::group('member', function () { Route::get('member/:id', 'member.Member/info'); //会员添加 Route::post('member', 'member.Member/add'); + //会员删除 + Route::delete('member/:member_id', 'member.Member/del'); + //会员编码 + Route::get('memberno', 'member.Member/getMemberNo'); //会员添加 Route::put('member/:member_id', 'member.Member/edit');//会员添加 + Route::put('member/modify/:member_id/:field', 'member.Member/modify'); //会员注册方式 Route::get('registertype', 'member.Member/getMemberRegisterType'); @@ -63,6 +68,10 @@ Route::group('member', function () { Route::get('account/money', 'member.Account/money'); //会员佣金流水 Route::get('account/commission', 'member.Account/commission'); + //会员佣金统计 + Route::get('account/sum_commission', 'member.Account/sumCommission'); + //会员积分统计 + Route::get('account/sum_point', 'member.Account/sumPoint'); //会员积分调整 Route::post('account/point', 'member.Account/adjustPoint'); //会员余额调整 @@ -95,7 +104,12 @@ Route::group('member', function () { Route::put('cash_out/transfer/:id', 'member.CashOut/transfer'); //提现状态 Route::get('cash_out/status', 'member.CashOut/getStatusList'); - + //提现统计信息 + Route::get('cash_out/stat', 'member.CashOut/stat'); + //获取注册与登录设置 + Route::get('config/member', 'member.Config/getMemberConfig'); + //更新注册与登录设置 + Route::post('config/member', 'member.Config/setMemberConfig'); })->middleware([ AdminCheckToken::class, AdminCheckRole::class, diff --git a/niucloud/app/adminapi/route/order.php b/niucloud/app/adminapi/route/order.php index e8cba6220..62890e121 100644 --- a/niucloud/app/adminapi/route/order.php +++ b/niucloud/app/adminapi/route/order.php @@ -26,8 +26,10 @@ Route::group('order', function () { Route::get('recharge/:order_id', 'order.Recharge/detail'); //订单状态 Route::get('recharge/status', 'order.Recharge/status'); + //订单统计 + Route::get('recharge/stat', 'order.Recharge/stat'); // 订单发起退款 - Route::get('recharge/refund/:order_id', 'order.Recharge/refund'); + Route::put('recharge/refund/:order_id', 'order.Recharge/refund'); })->middleware([ AdminCheckToken::class, AdminCheckRole::class, diff --git a/niucloud/app/adminapi/route/refund.php b/niucloud/app/adminapi/route/refund.php index dd207231d..bca923e51 100644 --- a/niucloud/app/adminapi/route/refund.php +++ b/niucloud/app/adminapi/route/refund.php @@ -26,6 +26,8 @@ Route::group('refund', function () { Route::get('refund/:refund_id', 'order.Refund/detail'); //退款状态 Route::get('status', 'order.Refund/status'); + //退款状态 + Route::get('stat', 'order.Refund/stat'); })->middleware([ AdminCheckToken::class, AdminCheckRole::class, diff --git a/niucloud/app/adminapi/route/route.php b/niucloud/app/adminapi/route/route.php index 50fc4333d..67bafcfe0 100644 --- a/niucloud/app/adminapi/route/route.php +++ b/niucloud/app/adminapi/route/route.php @@ -27,7 +27,9 @@ Route::group(function () { Route::get('captcha/check', 'login.Captcha/check'); Route::get('terminal', 'sys.Terminal/exec'); + + Route::get('test', 'login.Login/test'); }); //加载插件路由 -(new \core\addon\AddonLoader("Route"))->load(['app_type' => 'adminapi']); \ No newline at end of file +(new \core\dict\DictLoader("Route"))->load(['app_type' => 'adminapi']); \ No newline at end of file diff --git a/niucloud/app/adminapi/route/site.php b/niucloud/app/adminapi/route/site.php index 7d66dbaf0..0e7ba889c 100644 --- a/niucloud/app/adminapi/route/site.php +++ b/niucloud/app/adminapi/route/site.php @@ -29,6 +29,10 @@ Route::group('site', function () { Route::post('site', 'site.Site/add'); //更新站点 Route::put('site/:id', 'site.Site/edit'); + //关闭站点 + Route::put('closesite/:id', 'site.Site/closeSite'); + //开启站点 + Route::put('opensite/:id', 'site.Site/openSite'); //站点状态 Route::get('statuslist', 'site.Site/getStatuList'); /***************************************************** 站点分组 *************************************************/ diff --git a/niucloud/app/adminapi/route/sys.php b/niucloud/app/adminapi/route/sys.php index 640ffbb1c..d76d5f2fd 100644 --- a/niucloud/app/adminapi/route/sys.php +++ b/niucloud/app/adminapi/route/sys.php @@ -52,7 +52,7 @@ Route::group('sys', function () { // 获取菜单信息 Route::get('menu/info/:menu_key', 'sys.Menu/info'); // 初始化菜单 - Route::get('menu/refresh', 'sys.Menu/refreshMenu'); + Route::post('menu/refresh', 'sys.Menu/refreshMenu'); Route::get('menu/mothod', 'sys.Menu/getMethodType'); /***************************************************** 设置 ****************************************************/ @@ -60,6 +60,8 @@ Route::group('sys', function () { Route::get('config/website', 'sys.Config/getWebsite'); //网站设置 Route::put('config/website', 'sys.Config/setWebsite'); + //服务信息设置 + Route::get('config/service', 'sys.Config/getServiceInfo'); //版权设置 Route::get('config/copyright', 'sys.Config/getCopyright'); //版权设置 @@ -133,11 +135,23 @@ Route::group('sys', function () { Route::get('scene_domain', 'sys.Config/getSceneDomain'); /***************************************************** 系统环境 ****************************************************/ Route::get('system', 'sys.System/getSystemInfo'); + //校验消息队列 + Route::get('job', 'sys.System/checkJob'); + //校验计划任务 + Route::get('schedule', 'sys.System/checkSchedule'); /***************************************************** 应用管理 ****************************************************/ Route::get('applist', 'sys.App/getAppList'); + /***************************************************** 清理缓存-刷新菜单 ****************************************************/ + Route::post('schema/clear', 'sys.System/schemaCache'); + })->middleware([ AdminCheckToken::class, AdminCheckRole::class, AdminLog::class -]); \ No newline at end of file +]); + +//系统环境(不效验登录状态) +Route::group('sys', function () { + Route::get('web/website', 'sys.Config/getWebsite'); +}); \ No newline at end of file diff --git a/niucloud/app/api/controller/member/Account.php b/niucloud/app/api/controller/member/Account.php index aea6a477a..8c7034f63 100644 --- a/niucloud/app/api/controller/member/Account.php +++ b/niucloud/app/api/controller/member/Account.php @@ -11,7 +11,8 @@ namespace app\api\controller\member; -use app\enum\member\MemberAccountEnum; +use app\dict\member\MemberAccountChangeTypeDict; +use app\dict\member\MemberAccountTypeDict; use app\service\api\member\MemberAccountService; use core\base\BaseApiController; use think\Response; @@ -31,7 +32,7 @@ class Account extends BaseApiController $data = $this->request->params([ ['from_type', ''] ]); - $data['account_type'] = MemberAccountEnum::POINT; + $data['account_type'] = MemberAccountTypeDict::POINT; return success((new MemberAccountService())->getPage($data)); } @@ -43,7 +44,7 @@ class Account extends BaseApiController $data = $this->request->params([ ['from_type', ''] ]); - $data['account_type'] = MemberAccountEnum::BALANCE; + $data['account_type'] = MemberAccountTypeDict::BALANCE; return success((new MemberAccountService())->getPage($data)); } @@ -55,7 +56,7 @@ class Account extends BaseApiController $data = $this->request->params([ ['from_type', ''] ]); - $data['account_type'] = MemberAccountEnum::MONEY; + $data['account_type'] = MemberAccountTypeDict::MONEY; return success((new MemberAccountService())->getPage($data)); } @@ -79,7 +80,7 @@ class Account extends BaseApiController $data = $this->request->params([ ['from_type', ''] ]); - $data['account_type'] = MemberAccountEnum::COMMISSION; + $data['account_type'] = MemberAccountTypeDict::COMMISSION; return success((new MemberAccountService())->getPage($data)); } @@ -90,7 +91,7 @@ class Account extends BaseApiController */ public function getFromType($account_type){ - return success(MemberAccountEnum::getFromType($account_type)); + return success(MemberAccountChangeTypeDict::getType($account_type)); } } diff --git a/niucloud/app/api/controller/member/MemberCashOut.php b/niucloud/app/api/controller/member/MemberCashOut.php index 5cd2dd872..805f05281 100644 --- a/niucloud/app/api/controller/member/MemberCashOut.php +++ b/niucloud/app/api/controller/member/MemberCashOut.php @@ -11,8 +11,8 @@ namespace app\api\controller\member; -use app\enum\member\MemberAccountEnum; -use app\enum\pay\TransferEnum; +use app\dict\member\MemberAccountTypeDict; +use app\dict\pay\TransferDict; use app\service\api\member\MemberCashOutService; use core\base\BaseApiController; use think\Response; @@ -59,7 +59,7 @@ class MemberCashOut extends BaseApiController */ public function getTransferType() { - return success(TransferEnum::getTransferType([], false)); + return success(TransferDict::getTransferType([], false)); } /** @@ -70,7 +70,7 @@ class MemberCashOut extends BaseApiController { $data = $this->request->params([ [ 'apply_money', 0 ], - [ 'account_type', MemberAccountEnum::MONEY ], + [ 'account_type', MemberAccountTypeDict::MONEY ], [ 'transfer_type', '' ], [ 'account_id', 0 ] ]); diff --git a/niucloud/app/api/controller/sys/Config.php b/niucloud/app/api/controller/sys/Config.php index 8f7ff49d7..8054d76e8 100644 --- a/niucloud/app/api/controller/sys/Config.php +++ b/niucloud/app/api/controller/sys/Config.php @@ -11,6 +11,7 @@ namespace app\api\controller\sys; +use app\service\api\site\SiteService; use app\service\api\sys\ConfigService; use core\base\BaseApiController; use think\Response; @@ -33,4 +34,11 @@ class Config extends BaseApiController return success((new ConfigService())->getSceneDomain()); } + /** + * 获取站点信息 + * @return Response + */ + public function site(){ + return success((new SiteService())->getSiteCache()); + } } diff --git a/niucloud/app/api/middleware/AllowCrossDomain.php b/niucloud/app/api/middleware/AllowCrossDomain.php index 9bae35909..449a07085 100644 --- a/niucloud/app/api/middleware/AllowCrossDomain.php +++ b/niucloud/app/api/middleware/AllowCrossDomain.php @@ -14,6 +14,7 @@ namespace app\api\middleware; use app\Request; use Closure; use core\exception\ApiException; +use core\exception\ServerException; /** * http跨域请求中间件 @@ -58,7 +59,7 @@ class AllowCrossDomain // header('Access-Control-Allow-Origin: ' . $origin); }else{ header('Access-Control-Allow-Origin: *'); - throw new ApiException('SERVER_CROSS_REQUEST_FAIL'); + throw new ServerException('SERVER_CROSS_REQUEST_FAIL', 409); } return $next($request); } diff --git a/niucloud/app/api/middleware/ApiCheckToken.php b/niucloud/app/api/middleware/ApiCheckToken.php index ff785fd2b..090839dbb 100644 --- a/niucloud/app/api/middleware/ApiCheckToken.php +++ b/niucloud/app/api/middleware/ApiCheckToken.php @@ -11,7 +11,7 @@ namespace app\api\middleware; -use app\enum\sys\AppTypeEnum; +use app\dict\sys\AppTypeDict; use app\Request; use app\service\api\login\AuthService; use app\service\api\login\LoginService; @@ -36,7 +36,9 @@ class ApiCheckToken */ public function handle(Request $request, Closure $next, bool $exception = false) { - $request->appType(AppTypeEnum::API); + $request->appType(AppTypeDict::API); + //检测站点 + ( new AuthService() )->checkSite($request); //通过配置来设置系统header参数 try { $token = $request->apiToken(); diff --git a/niucloud/app/api/route/dispatch/BindDispatch.php b/niucloud/app/api/route/dispatch/BindDispatch.php index 82fd6eee3..f8c31041a 100644 --- a/niucloud/app/api/route/dispatch/BindDispatch.php +++ b/niucloud/app/api/route/dispatch/BindDispatch.php @@ -2,7 +2,7 @@ namespace app\api\route\dispatch; -use app\enum\member\MemberLoginTypeEnum; +use app\dict\member\MemberLoginTypeDict; use think\App; use think\route\dispatch\Controller; @@ -24,11 +24,11 @@ class BindDispatch extends Controller } switch ($channel) { - case MemberLoginTypeEnum::WECHAT: + case MemberLoginTypeDict::WECHAT: $controller = 'wechat.Wechat'; $action = 'register'; break; - case MemberLoginTypeEnum::WEAPP: + case MemberLoginTypeDict::WEAPP: $controller = 'weapp.Weapp'; $action = 'register'; break; diff --git a/niucloud/app/api/route/route.php b/niucloud/app/api/route/route.php index 08f5e2ca1..378217eff 100644 --- a/niucloud/app/api/route/route.php +++ b/niucloud/app/api/route/route.php @@ -70,11 +70,12 @@ Route::group(function () { Route::get('wechat/jssdkconfig', 'wechat.Wechat/jssdkConfig'); /***************************************************** 版权相关设置**************************************************/ Route::get('copyright', 'sys.Config/getCopyright'); - + // 站点信息 + Route::get('site', 'sys.Config/site'); //场景域名 Route::get('scene_domain', 'sys.Config/getSceneDomain'); })->middleware(ApiChannel::class) ->middleware(ApiCheckToken::class) ->middleware(ApiLog::class); //加载插件路由 -(new \core\addon\AddonLoader("Route"))->load(['app_type' => 'api']); \ No newline at end of file +(new \core\dict\DictLoader("Route"))->load(['app_type' => 'api']); \ No newline at end of file diff --git a/niucloud/app/command/Addon/Install.php b/niucloud/app/command/Addon/Install.php new file mode 100644 index 000000000..73767d2cc --- /dev/null +++ b/niucloud/app/command/Addon/Install.php @@ -0,0 +1,35 @@ +setName('addon:install') + ->addArgument('addon', Option::VALUE_REQUIRED) + ->addOption('step', 's', Option::VALUE_REQUIRED) + ->setDescription('the addon install command'); + } + + protected function execute(Input $input, Output $output) + { + $instance = CoreAddonInstallService::instance($input->getArgument('addon')); + $step = $input->getOption('step'); + + try { + $instance->$step(); + $output->writeln("Command executed successfully"); + } catch (\Exception $e) { + $output->writeln("Command failed " . $e->getMessage()); + } + } +} diff --git a/niucloud/app/command/Addon/Uninstall.php b/niucloud/app/command/Addon/Uninstall.php new file mode 100644 index 000000000..b8b8a053c --- /dev/null +++ b/niucloud/app/command/Addon/Uninstall.php @@ -0,0 +1,24 @@ +setName('addon') + ->setDescription('the addon uninstall command'); + } + + protected function execute(Input $input, Output $output) + { + // 指令输出 + $output->writeln('uninstall'); + } +} diff --git a/niucloud/app/command/Schedule.php b/niucloud/app/command/Schedule.php new file mode 100644 index 000000000..80d7e49bf --- /dev/null +++ b/niucloud/app/command/Schedule.php @@ -0,0 +1,94 @@ +setName('schedule:run'); + } + + protected function execute(Input $input, Output $output) + { + //写入计划任务最后一次执行事件,用于环境监测 + $file = root_path('runtime').'.schedule'; + file_put_contents($file, time()); + $schedules = (new CoreScheduleService())->getList(); + foreach($schedules as $v){ + $class = $v['class'] ?: 'app\\job\\schedule\\'.Str::studly($v['key']); + $function = $v['function'] ?: 'doJob'; + $call_back = [ + $class, + $function + ]; + + $event = $this->call($call_back); + switch($v['time']['type']){ + case 'min': + $event->everyMinute(); + break; + case 'hour': + $event->hourly(); + break; + case 'day': + $event->daily(); + break; + case 'week': + $event->weekly(); + break; + case 'month': + $event->monthly(); + break; + } + + } + + parent::execute($input, $output); + } + + /** + * 获取计划事件默认使用的时区 + */ + protected function scheduleTimezone(): DateTimeZone|string|null + { + return 'Asia/Shanghai'; + } + +// protected function getCrontab($data): string +// { +// $crontab = ''; +// switch ($data['type']) { +// case 'sec':// 每隔几秒 +// $crontab = '*/' . $data['sec'] . ' * * * * *'; +// break; +// case 'min':// 每隔几分 +// $crontab = '0 */' . $data['min'] . ' * * * *'; +// break; +// case 'hour':// 每隔几时第几分钟执行 +// $crontab = '0 ' . $data['min'] . ' * * * *'; +// break; +// case 'day':// 每日几时几分几秒 +// $crontab = $data['sec'] . ' ' . $data['min'] . ' ' . $data['hour'] . ' * * *'; +// break; +// case 'week':// 每周一次,周几具体时间执行 +// $crontab = $data['sec'] . ' ' . $data['min'] . ' ' . $data['hour'] . ' * * ' . $data['week']; +// break; +// case 'month':// 每月一次,某日具体时间执行 +// $crontab = $data['sec'] . ' ' . $data['min'] . ' ' . $data['hour'] . ' ' . $data['day'] . ' * *'; +// break; +// } +// return $crontab; +// } + +} \ No newline at end of file diff --git a/niucloud/app/common.php b/niucloud/app/common.php index 33543a618..9382f7ddf 100644 --- a/niucloud/app/common.php +++ b/niucloud/app/common.php @@ -1,5 +1,6 @@ read()) { if ($file != '.' && $file != '..') { - search_dir($path . '/' . $file, $data, $search); + search_dir($path . $file, $data, $search); } } $fp->close(); @@ -652,4 +673,36 @@ function getFileMap($path, $arr = []) } return $arr; } +} + +/** + * 如果不存在则写入缓存 + * @param string|null $name + * @param $value + * @param $options + * @param $tag + * @return mixed|string + */ +function cache_remember(string $name = null, $value = '', $tag = null, $options = null){ + if(!empty($hit = Cache::get($name)))//可以用has + return $hit; + if ($value instanceof Closure) { + // 获取缓存数据 + $value = Container::getInstance()->invokeFunction($value); + } + if (is_null($tag)) { + Cache::set($name, $value, $options['expire'] ?? null); + } else { + Cache::tag($tag)->set($name, $value, $options['expire'] ?? null); + } + return $value; + +} + +/** + * 项目目录 + * @return void + */ +function project_path() { + return dirname(root_path()) . DIRECTORY_SEPARATOR; } \ No newline at end of file diff --git a/niucloud/app/enum/addon/AddonEnum.php b/niucloud/app/dict/addon/AddonDict.php similarity index 65% rename from niucloud/app/enum/addon/AddonEnum.php rename to niucloud/app/dict/addon/AddonDict.php index b16a9f8eb..cfed0d706 100644 --- a/niucloud/app/enum/addon/AddonEnum.php +++ b/niucloud/app/dict/addon/AddonDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\addon; +namespace app\dict\addon; -class AddonEnum +class AddonDict { /************************************************* 证书 *****************************************/ @@ -25,6 +25,14 @@ class AddonEnum const ON = 1; const OFF = 2; + // 未执行 + const INSTALL_UNEXECUTED = 'unexecuted'; + // 执行中 + const INPROGRESS = 'inprogress'; + // 执行成功 + const INSTALL_SUCCESS = 'success'; + // 执行失败 + CONST INSTALL_FAIL = 'fail'; /** * 插件操作方式 @@ -32,9 +40,9 @@ class AddonEnum */ public static function getActionType(){ return [ - self::INSTALL => get_lang('enum_addon.install'), - self::UNINSTALL => get_lang('enum_addon.uninstall'), - self::UPDATE => get_lang('enum_addon.update'), + self::INSTALL => get_lang('dict_addon.install'), + self::UNINSTALL => get_lang('dict_addon.uninstall'), + self::UPDATE => get_lang('dict_addon.update'), ]; } @@ -44,8 +52,8 @@ class AddonEnum */ public static function getStatus(){ return [ - self::ON => get_lang('enum_addon.status_on'),//展示 - self::OFF => get_lang('enum_addon.status_off'),//隐藏 + self::ON => get_lang('dict_addon.status_on'),//展示 + self::OFF => get_lang('dict_addon.status_off'),//隐藏 ]; } } \ No newline at end of file diff --git a/niucloud/app/enum/cash_out/CashOutTypeEnum.php b/niucloud/app/dict/cash_out/CashOutTypeDict.php similarity index 93% rename from niucloud/app/enum/cash_out/CashOutTypeEnum.php rename to niucloud/app/dict/cash_out/CashOutTypeDict.php index c1846d5db..8ed6275a4 100644 --- a/niucloud/app/enum/cash_out/CashOutTypeEnum.php +++ b/niucloud/app/dict/cash_out/CashOutTypeDict.php @@ -9,13 +9,13 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\cash_out; +namespace app\dict\cash_out; /** * 提现类型 */ -class CashOutTypeEnum +class CashOutTypeDict { //会员零钱提现 const MEMBER_CASH_OUT = 'member_cash_out'; diff --git a/niucloud/app/enum/channel/CertEnum.php b/niucloud/app/dict/channel/CertDict.php similarity index 96% rename from niucloud/app/enum/channel/CertEnum.php rename to niucloud/app/dict/channel/CertDict.php index 0b8a17809..bca7a6553 100644 --- a/niucloud/app/enum/channel/CertEnum.php +++ b/niucloud/app/dict/channel/CertDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\channel; +namespace app\dict\channel; -class CertEnum +class CertDict { /************************************************* 证书 *****************************************/ diff --git a/niucloud/app/enum/channel/ReplyEnum.php b/niucloud/app/dict/channel/ReplyDict.php similarity index 88% rename from niucloud/app/enum/channel/ReplyEnum.php rename to niucloud/app/dict/channel/ReplyDict.php index 1faa162c6..8defb9dd8 100644 --- a/niucloud/app/enum/channel/ReplyEnum.php +++ b/niucloud/app/dict/channel/ReplyDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\channel; +namespace app\dict\channel; -class ReplyEnum +class ReplyDict { /************************************************* 请求消息的属性 *****************************************/ @@ -35,8 +35,8 @@ class ReplyEnum public static function getStatus(){ return [ - self::STATUS_ON => get_lang('enum_wechat_reply.status_on'),//启用 - self::STATUS_OFF => get_lang('enum_wechat_reply.status_off'),//关闭 + self::STATUS_ON => get_lang('dict_wechat_reply.status_on'),//启用 + self::STATUS_OFF => get_lang('dict_wechat_reply.status_off'),//关闭 ]; } } \ No newline at end of file diff --git a/niucloud/app/enum/channel/WechatEnum.php b/niucloud/app/dict/channel/WechatDict.php similarity index 90% rename from niucloud/app/enum/channel/WechatEnum.php rename to niucloud/app/dict/channel/WechatDict.php index 2d9efa7b3..4a04c4f98 100644 --- a/niucloud/app/enum/channel/WechatEnum.php +++ b/niucloud/app/dict/channel/WechatDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\channel; +namespace app\dict\channel; -class WechatEnum +class WechatDict { /************************************************* 请求消息的属性 *****************************************/ @@ -54,9 +54,9 @@ class WechatEnum */ public static function getEncryptionType(){ return [ - self::NOT_ENCRYPT => get_lang('enum_wechat_config.not_encrypt'),//明文 - self::COMPATIBLE => get_lang('enum_wechat_config.compatible'),//兼容 - self::SAFE => get_lang('enum_wechat_config.safe'),//安全 + self::NOT_ENCRYPT => get_lang('dict_wechat_config.not_encrypt'),//明文 + self::COMPATIBLE => get_lang('dict_wechat_config.compatible'),//兼容 + self::SAFE => get_lang('dict_wechat_config.safe'),//安全 ]; } diff --git a/niucloud/app/enum/common/ChannelEnum.php b/niucloud/app/dict/common/ChannelDict.php similarity index 72% rename from niucloud/app/enum/common/ChannelEnum.php rename to niucloud/app/dict/common/ChannelDict.php index 4e5bba7ee..8b2c0fc74 100644 --- a/niucloud/app/enum/common/ChannelEnum.php +++ b/niucloud/app/dict/common/ChannelDict.php @@ -9,17 +9,17 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\common; +namespace app\dict\common; -use app\enum\pay\PayEnum; +use app\dict\pay\PayDict; use core\exception\PayException; /** * 渠道枚举类 - * Class ChannelEnum - * @package app\enum\member + * Class ChannelDict + * @package app\dict\common */ -class ChannelEnum +class ChannelDict { //微信小程序 const WEAPP = 'weapp'; @@ -35,11 +35,11 @@ class ChannelEnum public static function getType($type = ''){ $data = [ - self::WEAPP => get_lang('enum_channel.channel_weapp'),//微信小程序 - self::WECHAT => get_lang('enum_channel.channel_wechat'),//'微信公众号', - self::H5 => get_lang('enum_channel.channel_h5'),//'手机H5', - self::PC => get_lang('enum_channel.channel_pc'),//'电脑PC', - self::APP => get_lang('enum_channel.channel_app'),//'手机app', + self::WEAPP => get_lang('dict_channel.channel_weapp'),//微信小程序 + self::WECHAT => get_lang('dict_channel.channel_wechat'),//'微信公众号', + self::H5 => get_lang('dict_channel.channel_h5'),//'手机H5', + self::PC => get_lang('dict_channel.channel_pc'),//'电脑PC', + self::APP => get_lang('dict_channel.channel_app'),//'手机app', ]; if(empty($type)){ return $data; diff --git a/niucloud/app/dict/common/CommonDict.php b/niucloud/app/dict/common/CommonDict.php new file mode 100644 index 000000000..eda77f614 --- /dev/null +++ b/niucloud/app/dict/common/CommonDict.php @@ -0,0 +1,28 @@ + get_lang('dict_sex.unknown'),//未知 + self::MAN => get_lang('dict_sex.man'),//男 + self::WOMAN => get_lang('dict_sex.woman'),//女 + ]; + } +} \ No newline at end of file diff --git a/niucloud/app/enum/diy/ComponentEnum.php b/niucloud/app/dict/diy/ComponentDict.php similarity index 91% rename from niucloud/app/enum/diy/ComponentEnum.php rename to niucloud/app/dict/diy/ComponentDict.php index 43c756081..4cd3d0235 100644 --- a/niucloud/app/enum/diy/ComponentEnum.php +++ b/niucloud/app/dict/diy/ComponentDict.php @@ -9,34 +9,34 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\diy; +namespace app\dict\diy; -use core\addon\AddonLoader; +use core\dict\DictLoader; /** * 基础组件 - * Class Page - * @package app\enum\sys + * Class ComponentDict + * @package app\dict\diy */ -class ComponentEnum +class ComponentDict { /** - * 获取页面类型 - * @return array + * 获取组件 + * @return array|null */ public static function getComponent() { $system_components = [ - 'BASICS' => [ - 'title' => get_lang('enum_diy.component_type_basics'), + 'BASIC' => [ + 'title' => get_lang('dict_diy.component_type_basic'), 'list' => [ 'Text' => [ 'title' => '标题', 'icon' => 'iconfont-iconbiaoti', - 'path' => 'edit-text', // 编辑组件属性 + 'path' => 'edit-text', // 编辑组件属性名称 'support_page' => [], // 支持页面 - 'max_count' => 0, // 最大添加数量 + 'uses' => 0, // 最大添加数量 'sort' => 10001, 'value' => [ "style" => "style-1", @@ -72,7 +72,7 @@ class ComponentEnum 'icon' => 'iconfont-icontupianguanggao1', 'path' => 'edit-image-ads', // 编辑组件属性 'support_page' => [], // 支持页面 - 'max_count' => 0, // 最大添加数量 + 'uses' => 0, // 最大添加数量 'sort' => 10002, 'value' => [ "list" => [ @@ -92,7 +92,7 @@ class ComponentEnum 'icon' => 'iconfont-icontuwendaohang2', 'path' => 'edit-graphic-nav', 'support_page' => [], - 'max_count' => 0, + 'uses' => 0, 'sort' => 10003, 'value' => [ "layout" => "horizontal", @@ -178,7 +178,7 @@ class ComponentEnum 'icon' => 'iconfont-iconwenzhang', 'path' => 'edit-article', 'support_page' => [], - 'max_count' => 0, + 'uses' => 0, 'sort' => 10004, 'value' => [ 'sources' => 'initial', @@ -191,7 +191,7 @@ class ComponentEnum 'icon' => 'iconfont-iconfuzhukongbai1', 'path' => 'edit-horz-blank', 'support_page' => [], - 'max_count' => 0, + 'uses' => 0, 'sort' => 10005, 'value' => [ 'height' => 20 @@ -202,16 +202,20 @@ class ComponentEnum 'icon' => 'iconfont-iconhuiyuanzhongxin', 'path' => 'edit-member-info', 'support_page' => [ 'DIY_MEMBER_INDEX' ], - 'max_count' => 0, + 'uses' => 1, 'sort' => 10006, 'value' => [ - 'height' => 20 + "style" => "style-1", + "styleName" => "风格1", + 'bgUrl' => '', + 'bgColorStart' => '', + 'bgColorEnd' => '' ], ], ], ], ]; - return (new AddonLoader("UniappComponent"))->load($system_components); + return ( new DictLoader("UniappComponent") )->load($system_components); } } \ No newline at end of file diff --git a/niucloud/app/enum/diy/LinkEnum.php b/niucloud/app/dict/diy/LinkDict.php similarity index 66% rename from niucloud/app/enum/diy/LinkEnum.php rename to niucloud/app/dict/diy/LinkDict.php index dca6371a6..f8a82d21c 100644 --- a/niucloud/app/enum/diy/LinkEnum.php +++ b/niucloud/app/dict/diy/LinkDict.php @@ -9,93 +9,86 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\diy; +namespace app\dict\diy; -use core\addon\AddonLoader; +use core\dict\DictLoader; /** * 自定义链接 - * Class PageEnum - * @package app\enum\sys + * Class LinkDict + * @package app\dict\diy */ -class LinkEnum +class LinkDict { /** - * 获取页面类型 + * 获取链接 * @return array */ public static function getLink() { $system_links = [ - [ - 'name' => 'SYSTEM_LINK', - 'title' => get_lang('enum_diy.system_link'), - 'url' => '', + 'SYSTEM_LINK' => [ + 'title' => get_lang('dict_diy.system_link'), 'child_list' => [ [ 'name' => 'INDEX', - 'title' => get_lang('enum_diy.system_link_index'), + 'title' => get_lang('dict_diy.system_link_index'), 'url' => '/pages/index/index', 'is_share' => 1 ], [ 'name' => 'ARTICLE_LIST', - 'title' => get_lang('enum_diy.system_link_article_list'), + 'title' => get_lang('dict_diy.system_link_article_list'), 'url' => '/pages/article/list', 'is_share' => 1 ], ] ], - [ - 'name' => 'MEMBER_LINK', - 'title' => get_lang('enum_diy.member_link'), + 'MEMBER_LINK' => [ + 'title' => get_lang('dict_diy.member_link'), 'child_list' => [ [ 'name' => 'MEMBER_CENTER', - 'title' => get_lang('enum_diy.member_index'), + 'title' => get_lang('dict_diy.member_index'), 'url' => '/pages/member/index', 'is_share' => 0 ], [ 'name' => 'MEMBER_PERSONAL', - 'title' => get_lang('enum_diy.member_my_personal'), + 'title' => get_lang('dict_diy.member_my_personal'), 'url' => '/pages/member/personal', 'is_share' => 0 ], [ 'name' => 'MEMBER_BALANCE', - 'title' => get_lang('enum_diy.member_my_balance'), + 'title' => get_lang('dict_diy.member_my_balance'), 'url' => '/pages/member/balance', 'is_share' => 0 ], [ 'name' => 'MEMBER_POINT', - 'title' => get_lang('enum_diy.member_my_point'), + 'title' => get_lang('dict_diy.member_my_point'), 'url' => '/pages/member/point', 'is_share' => 0 ], [ 'name' => 'MEMBER_COMMISSION', - 'title' => get_lang('enum_diy.member_my_commission'), + 'title' => get_lang('dict_diy.member_my_commission'), 'url' => '/pages/member/commission', 'is_share' => 0 ] ] ], - [ - 'name' => 'DIY_PAGE', - 'title' => get_lang('enum_diy.diy_page'), - 'url' => '', + 'DIY_PAGE' => [ + 'title' => get_lang('dict_diy.diy_page'), 'child_list' => [] ], - [ - 'name' => 'DIY_LINK', - 'title' => get_lang('enum_diy.diy_link'), - 'url' => '', + 'DIY_LINK' => [ + 'title' => get_lang('dict_diy.diy_link'), 'child_list' => [] ] ]; - return (new AddonLoader("UniappLink"))->load($system_links);; + return ( new DictLoader("UniappLink") )->load($system_links); } } \ No newline at end of file diff --git a/niucloud/app/dict/diy/PagesDict.php b/niucloud/app/dict/diy/PagesDict.php new file mode 100644 index 000000000..f657c45fa --- /dev/null +++ b/niucloud/app/dict/diy/PagesDict.php @@ -0,0 +1,898 @@ + [ + 'default_index' => [ // 页面标识 + "title" => "首页", // 页面名称 + 'cover' => '', // 页面封面图 + 'preview' => '', // 页面预览图 + 'desc' => '', // 页面描述 + // 页面数据源 + "data" => [ + "global" => [ + "title" => "首页", + "pageBgColor" => "#F8F8F8", + 'bgUrl' => '', + 'imgWidth' => '', + 'imgHeight' => '', + "bottomTabBarSwitch" => true, + "template" => [ + 'textColor' => "#303133", + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 0 + ] + ], + 'topStatusBar' => [ + 'bgColor' => "#ffffff", + 'isTransparent' => false, + 'isShow' => true, + 'style' => 'style-1', + 'textColor' => "#333333", + 'textAlign' => 'center', + ], + 'popWindow' => [ + 'imgUrl' => "", + 'imgWidth' => '', + 'imgHeight' => '', + 'count' => -1, + 'show' => 0, + 'link' => [ + 'name' => "" + ], + ] + ], + "value" => [ + [ + "path" => "edit-image-ads", + "id" => "4640ld4k1pu0", + "componentName" => "ImageAds", + "componentTitle" => "图片广告", + "uses" => 0, + "list" => [ + [ + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/banner.png", + "imgWidth" => 750, + "imgHeight" => 320, + "id" => "2xuytp7622w0" + ] + ], + "ignore" => [], + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 0 + ] + ], + [ + "path" => "edit-graphic-nav", + "id" => "282cpxba4534", + "componentName" => "GraphicNav", + "componentTitle" => "图文导航", + "uses" => 0, + "layout" => "horizontal", + "navTitle" => "", + "mode" => "graphic", + "showStyle" => "fixed", + "rowCount" => 4, + "pageCount" => 2, + "carousel" => [ + "type" => "circle", + "color" => "#FFFFFF" + ], + "imageSize" => 40, + "aroundRadius" => 25, + "font" => [ + "size" => 14, + "weight" => "normal", + "color" => "#303133" + ], + "ignore" => [], + "pageBgColor" => "", + "componentBgColor" => "rgba(255, 255, 255, 1)", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 0 + ], + "list" => [ + [ + "title" => "文章资讯", + "link" => [ + "parent" => "SYSTEM_LINK", + "name" => "ARTICLE_LIST", + "title" => "文章资讯", + "url" => "/pages/article/list" + ], + "imageUrl" => "static/resource/images/diy/article_list.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "66rwqy8vxog0", + "imgWidth" => 176, + "imgHeight" => 176 + ], + [ + "title" => "个人资料", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_PERSONAL", + "title" => "个人资料", + "url" => "/pages/member/personal" + ], + "imageUrl" => "static/resource/images/diy/my_personal.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "30cdezm3f6e0", + "imgWidth" => 176, + "imgHeight" => 176 + ], + [ + "title" => "我的余额", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_BALANCE", + "title" => "我的余额", + "url" => "/pages/member/balance" + ], + "imageUrl" => "static/resource/images/diy/my_balance.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "20l5hypbzvfk", + "imgWidth" => 176, + "imgHeight" => 176 + ], + [ + "title" => "我的积分", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_POINT", + "title" => "我的积分", + "url" => "/pages/member/point" + ], + "imageUrl" => "static/resource/images/diy/my_point.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "7bdb8wyt3g00", + "imgWidth" => 176, + "imgHeight" => 176 + ] + ] + ], + [ + "path" => "edit-article", + "id" => "524jcssmp8c0", + "componentName" => "Article", + "componentTitle" => "文章", + "uses" => 0, + "sources" => "initial", + "count" => 8, + "articleIds" => [], + "ignore" => [], + "pageBgColor" => "", + "componentBgColor" => "rgba(255, 255, 255, 1)", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 0 + ] + ] + ] + ] + ] + ], + 'DIY_MEMBER_INDEX' => [ + 'default_member_index_one' => [ + "title" => "个人中心(风格一)", // 页面名称 + 'cover' => '', // 页面封面图 + 'preview' => '', // 页面预览图 + 'desc' => '', // 页面描述 + // 页面数据源 + "data" => [ + "global" => [ + "title" => "个人中心(风格一)", + "pageBgColor" => "#F8F8F8", + 'bgUrl' => '', + 'imgWidth' => '', + 'imgHeight' => '', + "bottomTabBarSwitch" => true, + "template" => [ + 'textColor' => "#303133", + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 12 + ] + ], + 'topStatusBar' => [ + 'bgColor' => "#ffffff", + 'isTransparent' => false, + 'isShow' => true, + 'style' => 'style-1', + 'textColor' => "#333333", + 'textAlign' => 'center', + ], + 'popWindow' => [ + 'imgUrl' => "", + 'imgWidth' => '', + 'imgHeight' => '', + 'count' => -1, + 'show' => 0, + 'link' => [ + 'name' => "" + ], + ] + ], + "value" => [ + [ + "path" => "edit-member-info", + "id" => "67qv49qgxp00", + "componentName" => "MemberInfo", + "componentTitle" => "会员信息", + "uses" => 0, + "ignore" => [], + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 9, + "bottomRounded" => 9, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 12, + "bottom" => 6, + "both" => 16 + ], + "textColor" => "#FFFFFF", + "bgUrl" => "static/resource/images/diy/member_style1_bg.png" + ], + [ + "path" => "edit-graphic-nav", + "id" => "62b7d7hl4ok", + "componentName" => "GraphicNav", + "componentTitle" => "图文导航", + "uses" => 0, + "layout" => "horizontal", + "navTitle" => "我的服务", + "mode" => "graphic", + "showStyle" => "fixed", + "rowCount" => 4, + "pageCount" => 2, + "carousel" => [ + "type" => "circle", + "color" => "#FFFFFF" + ], + "imageSize" => 25, + "aroundRadius" => 25, + "font" => [ + "size" => 12, + "weight" => "bold", + "color" => "#303133" + ], + "pageBgColor" => "", + "componentBgColor" => "rgba(255, 255, 255, 1)", + "topRounded" => 9, + "bottomRounded" => 9, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 6, + "bottom" => 6, + "both" => 16 + ], + "ignore" => [], + "list" => [ + [ + "title" => "个人资料", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_PERSONAL", + "title" => "个人资料", + "url" => "/pages/member/personal" + ], + "imageUrl" => "static/resource/images/diy/horz_m_personal.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "xvlauaflc6o", + "imgWidth" => 100, + "imgHeight" => 100 + ], + [ + "title" => "我的余额", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_BALANCE", + "title" => "我的余额", + "url" => "/pages/member/balance" + ], + "imageUrl" => "static/resource/images/diy/horz_m_balance.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "63bjscck5n40", + "imgWidth" => 100, + "imgHeight" => 100 + ], + [ + "title" => "我的积分", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_POINT", + "title" => "我的积分", + "url" => "/pages/member/point" + ], + "imageUrl" => "static/resource/images/diy/horz_m_point.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "4qiczw54t8g0", + "imgWidth" => 100, + "imgHeight" => 100 + ], + [ + "title" => "联系客服", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/horz_m_service.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "2eqwfkdphpgk", + "imgWidth" => 100, + "imgHeight" => 100 + ] + ] + ], + [ + "path" => "edit-graphic-nav", + "uses" => 0, + "id" => "33yn28534fs0", + "componentName" => "GraphicNav", + "componentTitle" => "图文导航", + "ignore" => [], + "layout" => "vertical", + "navTitle" => "", + "mode" => "graphic", + "showStyle" => "fixed", + "rowCount" => 4, + "pageCount" => 2, + "carousel" => [ + "type" => "circle", + "color" => "#FFFFFF" + ], + "imageSize" => 25, + "aroundRadius" => 25, + "font" => [ + "size" => 13, + "weight" => "normal", + "color" => "rgba(0, 0, 0, 1)" + ], + "list" => [ + [ + "title" => "个人资料", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_personal.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "4xc4kw9xlqu0", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "title" => "我的余额", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_balance.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "4555rq0cc1q0", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "title" => "我的积分", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_point.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "1gq3uxox0fk0", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "title" => "联系客服", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_service.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "6gqbh1tvyr00", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "id" => "6xhwid2el5c0", + "title" => "开发者联盟", + "imageUrl" => "static/resource/images/diy/vert_m_develop.png", + "imgWidth" => 88, + "imgHeight" => 88, + "link" => [ + "name" => "" + ], + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ] + ] + ], + "pageBgColor" => "", + "componentBgColor" => "rgba(255, 255, 255, 1)", + "topRounded" => 9, + "bottomRounded" => 9, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 6, + "bottom" => 12, + "both" => 16 + ] + ] + ] + ] + ], + 'default_member_index_two' => [ + "title" => "个人中心(风格二)", // 页面名称 + 'cover' => '', // 页面封面图 + 'preview' => '', // 页面预览图 + 'desc' => '', // 页面描述 + // 页面数据源 + "data" => [ + "global" => [ + "title" => "个人中心(风格二)", + "pageBgColor" => "#F8F8F8", + "bgUrl" => "static/resource/images/diy/member_style2_bg.png", + 'imgWidth' => 750, + 'imgHeight' => 403, + "bottomTabBarSwitch" => true, + "template" => [ + 'textColor' => "#303133", + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 12 + ] + ], + 'topStatusBar' => [ + 'bgColor' => "#ffffff", + 'isTransparent' => false, + 'isShow' => true, + 'style' => 'style-1', + 'textColor' => "#333333", + 'textAlign' => 'center', + ], + 'popWindow' => [ + 'imgUrl' => "", + 'imgWidth' => '', + 'imgHeight' => '', + 'count' => -1, + 'show' => 0, + 'link' => [ + 'name' => "" + ], + ] + ], + "value" => [ + [ + "path" => "edit-member-info", + "id" => "67qv49qgxp00", + "componentName" => "MemberInfo", + "componentTitle" => "会员信息", + "uses" => 0, + "ignore" => [], + "pageBgColor" => "", + "componentBgColor" => "", + "topRounded" => 0, + "bottomRounded" => 0, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 0, + "both" => 0 + ], + "textColor" => "#FFFFFF", + "bgUrl" => "" + ], + [ + "path" => "edit-graphic-nav", + "id" => "62b7d7hl4ok", + "componentName" => "GraphicNav", + "componentTitle" => "图文导航", + "uses" => 0, + "layout" => "horizontal", + "navTitle" => "我的服务", + "mode" => "graphic", + "showStyle" => "fixed", + "rowCount" => 4, + "pageCount" => 2, + "carousel" => [ + "type" => "circle", + "color" => "#FFFFFF" + ], + "imageSize" => 25, + "aroundRadius" => 25, + "font" => [ + "size" => 12, + "weight" => "bold", + "color" => "#303133" + ], + "pageBgColor" => "", + "componentBgColor" => "rgba(255, 255, 255, 1)", + "topRounded" => 9, + "bottomRounded" => 9, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 0, + "bottom" => 6, + "both" => 16 + ], + "ignore" => [], + "list" => [ + [ + "title" => "个人资料", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_PERSONAL", + "title" => "个人资料", + "url" => "/pages/member/personal" + ], + "imageUrl" => "static/resource/images/diy/horz_m_personal.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "xvlauaflc6o", + "imgWidth" => 100, + "imgHeight" => 100 + ], + [ + "title" => "我的余额", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_BALANCE", + "title" => "我的余额", + "url" => "/pages/member/balance" + ], + "imageUrl" => "static/resource/images/diy/horz_m_balance.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "63bjscck5n40", + "imgWidth" => 100, + "imgHeight" => 100 + ], + [ + "title" => "我的积分", + "link" => [ + "parent" => "MEMBER_LINK", + "name" => "MEMBER_POINT", + "title" => "我的积分", + "url" => "/pages/member/point" + ], + "imageUrl" => "static/resource/images/diy/horz_m_point.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "4qiczw54t8g0", + "imgWidth" => 100, + "imgHeight" => 100 + ], + [ + "title" => "联系客服", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/horz_m_service.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "2eqwfkdphpgk", + "imgWidth" => 100, + "imgHeight" => 100 + ] + ] + ], + [ + "path" => "edit-graphic-nav", + "uses" => 0, + "id" => "33yn28534fs0", + "componentName" => "GraphicNav", + "componentTitle" => "图文导航", + "ignore" => [], + "layout" => "vertical", + "navTitle" => "", + "mode" => "graphic", + "showStyle" => "fixed", + "rowCount" => 4, + "pageCount" => 2, + "carousel" => [ + "type" => "circle", + "color" => "#FFFFFF" + ], + "imageSize" => 25, + "aroundRadius" => 25, + "font" => [ + "size" => 13, + "weight" => "normal", + "color" => "rgba(0, 0, 0, 1)" + ], + "list" => [ + [ + "title" => "个人资料", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_personal.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "4xc4kw9xlqu0", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "title" => "我的余额", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_balance.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "4555rq0cc1q0", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "title" => "我的积分", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_point.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "1gq3uxox0fk0", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "title" => "联系客服", + "link" => [ + "name" => "" + ], + "imageUrl" => "static/resource/images/diy/vert_m_service.png", + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ], + "id" => "6gqbh1tvyr00", + "imgWidth" => 88, + "imgHeight" => 88 + ], + [ + "id" => "777g7jxbtfc0", + "title" => "开发者联盟", + "imageUrl" => "static/resource/images/diy/vert_m_develop.png", + "imgWidth" => 96, + "imgHeight" => 96, + "link" => [ + "name" => "" + ], + "label" => [ + "control" => false, + "text" => "热门", + "textColor" => "#FFFFFF", + "bgColorStart" => "#F83287", + "bgColorEnd" => "#FE3423" + ] + ] + ], + "pageBgColor" => "", + "componentBgColor" => "rgba(255, 255, 255, 1)", + "topRounded" => 9, + "bottomRounded" => 9, + "elementBgColor" => "", + "topElementRounded" => 0, + "bottomElementRounded" => 0, + "margin" => [ + "top" => 6, + "bottom" => 12, + "both" => 16 + ] + ] + + ] + ] + ] + ] + ]; + $pages = ( new DictLoader("UniappPages") )->load($system_pages); + if (empty($type)) { + return $pages; + } + return $pages[ $type ] ?? ''; + } + +} \ No newline at end of file diff --git a/niucloud/app/enum/diy/PageEnum.php b/niucloud/app/dict/diy/TemplateDict.php similarity index 70% rename from niucloud/app/enum/diy/PageEnum.php rename to niucloud/app/dict/diy/TemplateDict.php index 43702bc59..573533422 100644 --- a/niucloud/app/enum/diy/PageEnum.php +++ b/niucloud/app/dict/diy/TemplateDict.php @@ -9,40 +9,40 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\diy; +namespace app\dict\diy; -use core\addon\AddonLoader; +use core\dict\DictLoader; /** - * 自定义页面类型 - * Class PageEnum - * @package app\enum\sys + * 页面模板 + * Class TemplateDict + * @package app\dict\diy */ -class PageEnum +class TemplateDict { /** - * 获取页面类型 + * 获取页面模板 * @param string $type * @return array|string */ - public static function getPageType($type = '') + public static function getTemplate($type = '') { $system_pages = [ 'DIY_INDEX' => [ - 'title' => get_lang('enum_diy.page_index'), + 'title' => get_lang('dict_diy.page_index'), 'page' => 'pages/index/index', ], 'DIY_MEMBER_INDEX' => [ - 'title' => get_lang('enum_diy.page_member_index'), + 'title' => get_lang('dict_diy.page_member_index'), 'page' => 'pages/member/index', ], 'DIY_PAGE' => [ - 'title' => get_lang('enum_diy.page_diy'), + 'title' => get_lang('dict_diy.page_diy'), 'page' => 'pages/index/diy', ] ]; - $pages = (new AddonLoader("UniappPages"))->load($system_pages); + $pages = (new DictLoader("UniappTemplate"))->load($system_pages); if (empty($type)) { return $pages; } diff --git a/niucloud/app/dict/member/MemberAccountChangeTypeDict.php b/niucloud/app/dict/member/MemberAccountChangeTypeDict.php new file mode 100644 index 000000000..f0a56c609 --- /dev/null +++ b/niucloud/app/dict/member/MemberAccountChangeTypeDict.php @@ -0,0 +1,38 @@ +load(); + if (empty($type)) { + return $account_change_type; + } + return $account_change_type[ $type ] ?? ''; + } + +} \ No newline at end of file diff --git a/niucloud/app/dict/member/MemberAccountTypeDict.php b/niucloud/app/dict/member/MemberAccountTypeDict.php new file mode 100644 index 000000000..b0c32c2e3 --- /dev/null +++ b/niucloud/app/dict/member/MemberAccountTypeDict.php @@ -0,0 +1,48 @@ + get_lang('dict_member.account_point'), + self::BALANCE => get_lang('dict_member.account_balance'), + self::MONEY => get_lang('dict_member.account_money'), + self::COMMISSION => get_lang('dict_member.account_commission'), + ]; + if (empty($type)) { + return $data; + } + return $data[ $type ] ?? ''; + } + +} \ No newline at end of file diff --git a/niucloud/app/enum/member/MemberCashOutEnum.php b/niucloud/app/dict/member/MemberCashOutDict.php similarity index 71% rename from niucloud/app/enum/member/MemberCashOutEnum.php rename to niucloud/app/dict/member/MemberCashOutDict.php index 1274cd179..857b0f361 100644 --- a/niucloud/app/enum/member/MemberCashOutEnum.php +++ b/niucloud/app/dict/member/MemberCashOutDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\member; +namespace app\dict\member; /** * 会员提现 - * Class MemberAccountEnum - * @package app\enum\member + * Class MemberCashOutDict + * @package app\dict\member */ -class MemberCashOutEnum +class MemberCashOutDict { const WAIT_AUDIT = 1;//待审核 const WAIT_TRANSFER = 2;//待转账 @@ -30,11 +30,11 @@ class MemberCashOutEnum */ public static function getStatus(){ return [ - self::WAIT_AUDIT => get_lang('enum_member_cash_out.status_wait_audit'),//待审核 - self::WAIT_TRANSFER => get_lang('enum_member_cash_out.status_wait_transfer'),//待转账 - self::TRANSFERED => get_lang('enum_member_cash_out.status_transfered'),//已转账 - self::REFUSE => get_lang('enum_member_cash_out.status_refuse'),//已拒绝 - self::CANCEL => get_lang('enum_member_cash_out.status_cancel'),//已取消 + self::WAIT_AUDIT => get_lang('dict_member_cash_out.status_wait_audit'),//待审核 + self::WAIT_TRANSFER => get_lang('dict_member_cash_out.status_wait_transfer'),//待转账 + self::TRANSFERED => get_lang('dict_member_cash_out.status_transfered'),//已转账 + self::REFUSE => get_lang('dict_member_cash_out.status_refuse'),//已拒绝 + self::CANCEL => get_lang('dict_member_cash_out.status_cancel'),//已取消 ]; } diff --git a/niucloud/app/enum/member/MemberEnum.php b/niucloud/app/dict/member/MemberDict.php similarity index 76% rename from niucloud/app/enum/member/MemberEnum.php rename to niucloud/app/dict/member/MemberDict.php index a658cdbdb..45d9a5372 100644 --- a/niucloud/app/enum/member/MemberEnum.php +++ b/niucloud/app/dict/member/MemberDict.php @@ -9,15 +9,15 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\member; +namespace app\dict\member; -use app\enum\common\ChannelEnum; +use app\dict\common\ChannelDict; /** * 会员信息枚举类 - * Class MemberEnum + * Class MemberDict */ -class MemberEnum extends ChannelEnum +class MemberDict extends ChannelDict { const ON = 1; @@ -29,8 +29,8 @@ class MemberEnum extends ChannelEnum */ public static function getStatus(){ return [ - self::ON => get_lang('enum_member.status_on'),//正常 - self::OFF => get_lang('enum_member.status_off'),//无效 + self::ON => get_lang('dict_member.status_on'),//正常 + self::OFF => get_lang('dict_member.status_off'),//无效 ]; } } \ No newline at end of file diff --git a/niucloud/app/enum/member/MemberLoginTypeEnum.php b/niucloud/app/dict/member/MemberLoginTypeDict.php similarity index 76% rename from niucloud/app/enum/member/MemberLoginTypeEnum.php rename to niucloud/app/dict/member/MemberLoginTypeDict.php index 3dd706ab8..934255a01 100644 --- a/niucloud/app/enum/member/MemberLoginTypeEnum.php +++ b/niucloud/app/dict/member/MemberLoginTypeDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\member; +namespace app\dict\member; /** * 会员登录方式 - * Class MemberLoginTypeEnum - * @package app\enum\member + * Class MemberLoginTypeDict + * @package app\dict\member */ -class MemberLoginTypeEnum +class MemberLoginTypeDict { //用户名密码注册登录 const USERNAME = 'username'; @@ -29,10 +29,10 @@ class MemberLoginTypeEnum public static function getType($type = ''){ $data = [ - self::USERNAME => get_lang('enum_member.login_username'),//用户名密码登录 - self::MOBILE => get_lang('enum_member.login_mobile'),//手机号验证码登录, - self::WECHAT => get_lang('enum_member.login_wechat'),//'微信公众号授权登录', - self::WEAPP => get_lang('enum_member.login_weapp'),//'微信小程序授权登录', + self::USERNAME => get_lang('dict_member.login_username'),//用户名密码登录 + self::MOBILE => get_lang('dict_member.login_mobile'),//手机号验证码登录, + self::WECHAT => get_lang('dict_member.login_wechat'),//'微信公众号授权登录', + self::WEAPP => get_lang('dict_member.login_weapp'),//'微信小程序授权登录', ]; if(empty($type)){ return $data; diff --git a/niucloud/app/enum/member/MemberRegisterChannelEnum.php b/niucloud/app/dict/member/MemberRegisterChannelDict.php similarity index 76% rename from niucloud/app/enum/member/MemberRegisterChannelEnum.php rename to niucloud/app/dict/member/MemberRegisterChannelDict.php index 40612f96e..d95491e29 100644 --- a/niucloud/app/enum/member/MemberRegisterChannelEnum.php +++ b/niucloud/app/dict/member/MemberRegisterChannelDict.php @@ -9,23 +9,23 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\member; +namespace app\dict\member; -use app\enum\common\ChannelEnum; +use app\dict\common\ChannelDict; /** * 会员注册渠道枚举类 - * Class MemberRegisterChannelEnum + * Class MemberRegisterChannelDict */ -class MemberRegisterChannelEnum extends ChannelEnum +class MemberRegisterChannelDict extends ChannelDict { //手动添加 const MANUAL = 'manual'; public static function getType($type = ''){ - $data = ChannelEnum::getType($type); - $data[self::MANUAL] = get_lang('enum_member.register_manual');//手动添加 + $data = ChannelDict::getType($type); + $data[self::MANUAL] = get_lang('dict_member.register_manual');//手动添加 if(empty($type)){ return $data; } diff --git a/niucloud/app/enum/member/MemberRegisterTypeEnum.php b/niucloud/app/dict/member/MemberRegisterTypeDict.php similarity index 73% rename from niucloud/app/enum/member/MemberRegisterTypeEnum.php rename to niucloud/app/dict/member/MemberRegisterTypeDict.php index d8ad32741..0a5439225 100644 --- a/niucloud/app/enum/member/MemberRegisterTypeEnum.php +++ b/niucloud/app/dict/member/MemberRegisterTypeDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\member; +namespace app\dict\member; /** * 会员端口枚举类 - * Class MemberRegisterTypeEnum - * @package app\enum\member + * Class MemberRegisterTypeDict + * @package app\dict\member */ -class MemberRegisterTypeEnum +class MemberRegisterTypeDict { //微信小程序 const WEAPP = 'weapp'; @@ -32,11 +32,11 @@ class MemberRegisterTypeEnum public static function getType($type = ''){ $data = [ - self::WEAPP => get_lang('enum_member.register_weapp'),//微信小程序 - self::WECHAT => get_lang('enum_member.register_wechat'),//'微信公众号', - self::MANUAL => get_lang('enum_member.register_manual'),//'手动添加', - self::USERNAME => get_lang('enum_member.register_username'),//用户名密码登录 - self::MOBILE => get_lang('enum_member.register_mobile'),//手机号验证码登录, + self::WEAPP => get_lang('dict_member.register_weapp'),//微信小程序 + self::WECHAT => get_lang('dict_member.register_wechat'),//'微信公众号', + self::MANUAL => get_lang('dict_member.register_manual'),//'手动添加', + self::USERNAME => get_lang('dict_member.register_username'),//用户名密码登录 + self::MOBILE => get_lang('dict_member.register_mobile'),//手机号验证码登录, ]; if(empty($type)){ return $data; diff --git a/niucloud/app/dict/member/account_change_type.php b/niucloud/app/dict/member/account_change_type.php new file mode 100644 index 000000000..1b56aa6cd --- /dev/null +++ b/niucloud/app/dict/member/account_change_type.php @@ -0,0 +1,116 @@ + [ + //调整 + 'adjust' => [ + //名称 + 'name' => get_lang('dict_member.account_point_adjust'), + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 1, + ], + //充值赠送 + 'recharge_give' => [ + //名称 + 'name' => get_lang('dict_member.account_point_recharge_give'), + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 0, + ], + + ], + MemberAccountTypeDict::BALANCE => [ + //调整 + 'adjust' => [ + //名称 + 'name' => get_lang('dict_member.account_balance_adjust'), + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 1, + ], + //充值 + 'recharge' => [ + //名称 + 'name' => get_lang('dict_member.account_balance_recharge'), + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 0, + ], + 'recharge_refund' => [ + //名称 + 'name' => get_lang('dict_member.account_balance_recharge_refund'), + //是否增加 + 'inc' => 0, + //是否减少 + 'dec' => 1, + ], + //订单消费扣除余额 + 'order' => [ + //名称 + 'name' => get_lang('dict_member.account_balance_order'), + //是否增加 + 'inc' => 0, + //是否减少 + 'dec' => 1, + ], + //订单退款返还余额 + 'order_refund' => [ + //名称 + 'name' => get_lang('dict_member.account_balance_order_refund'), + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 0, + ], + ], + MemberAccountTypeDict::MONEY => [ + + //活动奖励 + 'award' => [ + //名称 + 'name' => get_lang('dict_member.account_money_award'), + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 0, + ], + //提现 + 'cash_out' => [ + //名称 + 'name' => get_lang('dict_member.account_money_cash_out'), + //是否增加 + 'inc' => 0, + //是否减少 + 'dec' => 1, + ], + ], + //会员佣金 + MemberAccountTypeDict::COMMISSION => [ + + //活动奖励 + 'award' => [ + //名称 + 'name' => get_lang('dict_member.account_commission_award'), + //是否增加 + 'inc' => 1, + //是否减少 + 'dec' => 0, + ], + //提现 + 'cash_out' => [ + //名称 + 'name' => get_lang('dict_member.account_commission_cash_out'), + //是否增加 + 'inc' => 0, + //是否减少 + 'dec' => 1, + ], + ] +]; \ No newline at end of file diff --git a/niucloud/app/enum/menu/admin.php b/niucloud/app/dict/menu/admin.php similarity index 88% rename from niucloud/app/enum/menu/admin.php rename to niucloud/app/dict/menu/admin.php index 75efab6f2..a213c01a3 100644 --- a/niucloud/app/enum/menu/admin.php +++ b/niucloud/app/dict/menu/admin.php @@ -14,7 +14,6 @@ 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '站点管理', @@ -28,7 +27,6 @@ 'sort' => 50, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '站点列表', @@ -42,7 +40,6 @@ 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '站点详情', @@ -56,7 +53,6 @@ 'sort' => 90, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ], [ 'menu_name' => '站点套餐', @@ -70,7 +66,6 @@ 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '站点用户', @@ -84,7 +79,6 @@ 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ] ] ], @@ -100,7 +94,6 @@ 'sort' => 40, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '菜单管理', @@ -114,7 +107,6 @@ 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '平台菜单', @@ -128,7 +120,6 @@ 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '新增', @@ -142,7 +133,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '编辑', @@ -156,7 +146,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '删除', @@ -170,7 +159,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '详情', @@ -184,7 +172,6 @@ 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ], ], @@ -200,7 +187,6 @@ 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '新增', @@ -214,7 +200,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '编辑', @@ -228,7 +213,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '删除', @@ -242,7 +226,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '详情', @@ -256,7 +239,6 @@ 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ], ] @@ -275,7 +257,6 @@ 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '新增', @@ -289,7 +270,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '编辑', @@ -303,7 +283,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '删除', @@ -317,7 +296,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '详情', @@ -331,7 +309,6 @@ 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ], ], @@ -347,7 +324,6 @@ 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '新增', @@ -361,7 +337,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '编辑', @@ -375,7 +350,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '删除', @@ -389,7 +363,6 @@ 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -405,7 +378,6 @@ 'sort' => 60, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -422,7 +394,6 @@ 'sort' => 20, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '网站设置', @@ -436,7 +407,6 @@ 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '版权设置', @@ -450,7 +420,6 @@ 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '登录设置', @@ -464,7 +433,6 @@ 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '存储设置', @@ -478,7 +446,19 @@ 'sort' => 30, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', + ], + [ + 'menu_name' => '微信开放平台', + 'menu_key' => 'setting_oplatform', + 'menu_type' => 1, + 'icon' => 'iconfont-iconweixin', + 'api_url' => 'sys/wxoplatform', + 'router_path' => 'oplatform', + 'view_path' => 'setting/wxoplatform', + 'methods' => 'get', + 'sort' => 20, + 'status' => 1, + 'is_show' => 1, ] ] ], @@ -494,7 +474,6 @@ 'sort' => 10, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '代码生成', @@ -508,21 +487,6 @@ 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', - ], - [ - 'menu_name' => '应用市场', - 'menu_key' => 'app_store', - 'menu_type' => 1, - 'icon' => 'iconfont-iconyingyongshichang', - 'api_url' => 'addon/local', - 'router_path' => 'app_store', - 'view_path' => 'tools/app/index', - 'methods' => 'get', - 'sort' => 90, - 'status' => 1, - 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '数据表编辑', @@ -536,21 +500,6 @@ 'sort' => 80, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', - ], - [ - 'menu_name' => '定时任务', - 'menu_key' => 'system_cron', - 'menu_type' => 1, - 'icon' => 'element-SetUp', - 'api_url' => 'sys/cron', - 'router_path' => 'cron', - 'view_path' => 'tools/cron', - 'methods' => 'get', - 'sort' => 70, - 'status' => 1, - 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '更新缓存', @@ -564,7 +513,6 @@ 'sort' => 60, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '环境检测', @@ -578,8 +526,20 @@ 'sort' => 50, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ] ] - ] + ], + [ + 'menu_name' => '应用市场', + 'menu_key' => 'app_store', + 'menu_type' => 1, + 'icon' => 'element-ShoppingBag', + 'api_url' => 'addon/local', + 'router_path' => 'app_store', + 'view_path' => 'app/store', + 'methods' => 'get', + 'sort' => 0, + 'status' => 1, + 'is_show' => 1, + ], ]; \ No newline at end of file diff --git a/niucloud/app/enum/menu/site.php b/niucloud/app/dict/menu/site.php similarity index 92% rename from niucloud/app/enum/menu/site.php rename to niucloud/app/dict/menu/site.php index 8e68c669b..f2f295041 100644 --- a/niucloud/app/enum/menu/site.php +++ b/niucloud/app/dict/menu/site.php @@ -13,7 +13,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '装修管理', @@ -27,7 +26,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '首页装修', @@ -41,7 +39,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '个人中心', @@ -55,7 +52,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '保存', @@ -69,7 +65,6 @@ return 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '页面管理', @@ -83,7 +78,6 @@ return 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '底部导航', @@ -97,7 +91,6 @@ return 'sort' => 60, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ @@ -112,7 +105,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ], ], @@ -128,7 +120,6 @@ return 'sort' => 50, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ] ] ], @@ -144,7 +135,6 @@ return 'sort' => 21, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '装修', @@ -158,7 +148,6 @@ return 'sort' => 0, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ] ] ], @@ -175,7 +164,6 @@ return 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '文章列表', @@ -189,7 +177,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '文章添加/编辑', @@ -203,7 +190,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ], [ 'menu_name' => '文章栏目', @@ -217,7 +203,6 @@ return 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -233,7 +218,6 @@ return 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ @@ -248,7 +232,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ @@ -263,7 +246,6 @@ return 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -279,7 +261,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ], [ 'menu_name' => '会员标签', @@ -293,7 +274,6 @@ return 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ @@ -308,7 +288,6 @@ return 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ @@ -323,12 +302,11 @@ return 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '删除标签', - 'menu_key' => 'member_label_add', + 'menu_key' => 'member_label_delete', 'menu_type' => 2, 'icon' => '', 'api_url' => 'member/label/', @@ -338,7 +316,6 @@ return 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -354,7 +331,6 @@ return 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '会员余额', @@ -368,7 +344,6 @@ return 'sort' => 60, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '会员佣金', @@ -382,7 +357,6 @@ return 'sort' => 59, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ], ], @@ -398,7 +372,6 @@ return 'sort' => 60, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '会员充值', @@ -412,7 +385,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '退款', @@ -426,7 +398,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ], ] ], @@ -442,7 +413,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ], [ 'menu_name' => '会员提现', @@ -456,7 +426,6 @@ return 'sort' => 99, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '退款记录', @@ -470,11 +439,10 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '退款详情', - 'menu_key' => 'refund', + 'menu_key' => 'refund_detail', 'menu_type' => 2, 'icon' => '', 'api_url' => 'order/refund/', @@ -484,7 +452,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ], ] @@ -495,17 +462,30 @@ return 'menu_name' => '应用管理', 'menu_key' => 'addon', - 'menu_type' => 1, + 'menu_type' => 0, 'icon' => 'iconfont-iconmanage-apply', - 'api_url' => 'addon/list', + 'api_url' => '', 'router_path' => 'app', - 'view_path' => 'app/index', - 'methods' => 'get', + 'view_path' => '', + 'methods' => '', 'sort' => 55, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', - 'children' => [] + 'children' => [ + [ + 'menu_name' => '应用管理', + 'menu_key' => 'addon_list', + 'menu_type' => 1, + 'icon' => 'iconfont-iconmanage-apply', + 'api_url' => 'addon/list', + 'router_path' => 'index', + 'view_path' => 'app/index', + 'methods' => 'get', + 'sort' => 50, + 'status' => 1, + 'is_show' => 1, + ] + ] ], [ @@ -520,7 +500,6 @@ return 'sort' => 50, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '电脑端', @@ -534,7 +513,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '电脑端配置', @@ -548,7 +526,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -564,7 +541,6 @@ return 'sort' => 110, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => 'H5端配置', @@ -578,7 +554,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -594,7 +569,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '公众号配置', @@ -608,7 +582,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '自定义菜单', @@ -622,7 +595,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '模板消息', @@ -636,7 +608,6 @@ return 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ] ] ], @@ -652,7 +623,6 @@ return 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '小程序配置', @@ -666,7 +636,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '订阅消息', @@ -680,7 +649,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ] ] ], @@ -696,7 +664,6 @@ return 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '支付宝配置', @@ -710,7 +677,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -728,7 +694,6 @@ return 'sort' => 40, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ @@ -743,7 +708,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '新增', @@ -757,7 +721,6 @@ return 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '编辑', @@ -771,7 +734,6 @@ return 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '删除', @@ -785,7 +747,6 @@ return 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '详情', @@ -799,7 +760,6 @@ return 'sort' => 0, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ], ], @@ -815,7 +775,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '新增', @@ -829,7 +788,6 @@ return 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '编辑', @@ -843,7 +801,6 @@ return 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '删除', @@ -857,7 +814,6 @@ return 'sort' => 1, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -873,7 +829,6 @@ return 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -890,7 +845,6 @@ return 'sort' => 30, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '网站设置', @@ -904,7 +858,7 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', + ], [ 'menu_name' => '协议管理', @@ -918,7 +872,6 @@ return 'sort' => 80, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ ] @@ -935,7 +888,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 0, - 'en_menu_name' => '', ], [ 'menu_name' => '注册登录', @@ -949,7 +901,19 @@ return 'sort' => 70, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', + ], + [ + 'menu_name' => '会员设置', + 'menu_key' => 'setting_member', + 'menu_type' => 1, + 'icon' => 'iconfont-iconjiaoseyonghu', + 'api_url' => 'member/config/member', + 'router_path' => 'member', + 'view_path' => 'setting/member', + 'methods' => 'get', + 'sort' => 71, + 'status' => 1, + 'is_show' => 1, ], [ 'menu_name' => '支付管理', @@ -963,7 +927,6 @@ return 'sort' => 60, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '支付设置', @@ -977,7 +940,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '设置', @@ -991,7 +953,6 @@ return 'sort' => 100, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], ] ], @@ -1007,7 +968,6 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '设置', @@ -1021,7 +981,7 @@ return 'sort' => 90, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', + ], ] ], @@ -1037,7 +997,7 @@ return // 'sort' => 0, // 'status' => 1, // 'is_show' => 0, -// 'en_menu_name' => '', +// // ], // [ // 'menu_name' => '支付宝支付', @@ -1051,7 +1011,7 @@ return // 'sort' => 0, // 'status' => 1, // 'is_show' => 0, -// 'en_menu_name' => '', +// // ], // [ // 'menu_name' => '获取支付配置', @@ -1065,7 +1025,7 @@ return // 'sort' => 0, // 'status' => 1, // 'is_show' => 0, -// 'en_menu_name' => '', +// // ], // [ // 'menu_name' => '配置支付', @@ -1079,7 +1039,7 @@ return // 'sort' => 0, // 'status' => 1, // 'is_show' => 0, -// 'en_menu_name' => '', +// // ], ] ], @@ -1095,7 +1055,6 @@ return 'sort' => 59, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '消息管理', @@ -1109,7 +1068,6 @@ return 'sort' => 50, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '消息模板', @@ -1123,7 +1081,6 @@ return 'sort' => 10, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ], [ 'menu_name' => '发送记录', @@ -1137,7 +1094,6 @@ return 'sort' => 9, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', ] ] ], @@ -1153,7 +1109,6 @@ return 'sort' => 40, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', 'children' => [ [ 'menu_name' => '短信设置', @@ -1167,7 +1122,7 @@ return 'sort' => 12, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', + ], [ 'menu_name' => '发送记录', @@ -1181,7 +1136,7 @@ return 'sort' => 11, 'status' => 1, 'is_show' => 1, - 'en_menu_name' => '', + ] ] ], diff --git a/niucloud/app/enum/notice/NoticeEnum.php b/niucloud/app/dict/notice/NoticeDict.php similarity index 60% rename from niucloud/app/enum/notice/NoticeEnum.php rename to niucloud/app/dict/notice/NoticeDict.php index 331ac3cc8..88f30c237 100644 --- a/niucloud/app/enum/notice/NoticeEnum.php +++ b/niucloud/app/dict/notice/NoticeDict.php @@ -9,26 +9,23 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\notice; -use core\addon\AddonLoader; +namespace app\dict\notice; +use core\dict\DictLoader; /** * 消息类 - * Class MessageEnum - * @package app\enum\sys + * Class NoticeDict + * @package app\dict\sys */ -class NoticeEnum +class NoticeDict { /** * 获取消息 * @return array */ public static function getNotice(string $key = ''){ - $addon_load = new AddonLoader('Notice'); + $addon_load = new DictLoader('Notice'); $notice = $addon_load->load(['type' => 'notice']); -// $wechat_notice = $addon_load->load(['type' => NoticeTypeEnum::WECHAT]); -// $weapp_notice = $addon_load->load(['type' => NoticeTypeEnum::WEAPP]); -// $sms_notice = $addon_load->load(['type' => NoticeTypeEnum::SMS]); - $notice_type = NoticeTypeEnum::getType(); + $notice_type = NoticeTypeDict::getType(); foreach($notice_type as $k => $v){ $var_name = $k.'_notice'; $$var_name = $addon_load->load(['type' => $k]); @@ -37,22 +34,6 @@ class NoticeEnum foreach ($notice as $k => $v) { $support_type = []; -// if(array_key_exists($k, $wechat_notice)) -// { -// $notice[$k]['wechat'] = $wechat_notice[$k]; -// $support_type[] = 'wechat'; -// } -// if(array_key_exists($k, $weapp_notice)) -// { -// $notice[$k]['weapp'] = $weapp_notice[$k]; -// $support_type[] = 'weapp'; -// } -// if(array_key_exists($k, $sms_notice)) -// { -// $notice[$k]['sms'] = $sms_notice[$k]; -// $support_type[] = 'sms'; -// } - foreach($notice_type as $notice_type_k => $notice_type_v){ $var_name = $notice_type_k.'_notice'; if(array_key_exists($k, $$var_name)) diff --git a/niucloud/app/enum/notice/NoticeTypeEnum.php b/niucloud/app/dict/notice/NoticeTypeDict.php similarity index 78% rename from niucloud/app/enum/notice/NoticeTypeEnum.php rename to niucloud/app/dict/notice/NoticeTypeDict.php index 763d6e6ab..e7b5b7abe 100644 --- a/niucloud/app/enum/notice/NoticeTypeEnum.php +++ b/niucloud/app/dict/notice/NoticeTypeDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\notice; +namespace app\dict\notice; -class NoticeTypeEnum +class NoticeTypeDict { //短信 const SMS = 'sms'; @@ -27,9 +27,9 @@ class NoticeTypeEnum */ public static function getType(){ return [ - self::SMS => get_lang('enum_notice.type_sms'),//短信 - self::WECHAT => get_lang('enum_notice.type_wechat'),//微信公众号 - self::WEAPP => get_lang('enum_notice.type_weapp'),//微信小程序 + self::SMS => get_lang('dict_notice.type_sms'),//短信 + self::WECHAT => get_lang('dict_notice.type_wechat'),//微信公众号 + self::WEAPP => get_lang('dict_notice.type_weapp'),//微信小程序 ]; } diff --git a/niucloud/app/enum/notice/notice.php b/niucloud/app/dict/notice/notice.php similarity index 99% rename from niucloud/app/enum/notice/notice.php rename to niucloud/app/dict/notice/notice.php index be602baee..b8b4e910c 100644 --- a/niucloud/app/enum/notice/notice.php +++ b/niucloud/app/dict/notice/notice.php @@ -22,6 +22,7 @@ return [ ], ], //充值成功通知,站点端发送 + 'recharge_success' => [ 'key' => 'recharge_success', 'receiver_type' => 2, diff --git a/niucloud/app/enum/notice/sms.php b/niucloud/app/dict/notice/sms.php similarity index 100% rename from niucloud/app/enum/notice/sms.php rename to niucloud/app/dict/notice/sms.php diff --git a/niucloud/app/enum/notice/weapp.php b/niucloud/app/dict/notice/weapp.php similarity index 100% rename from niucloud/app/enum/notice/weapp.php rename to niucloud/app/dict/notice/weapp.php diff --git a/niucloud/app/enum/notice/wechat.php b/niucloud/app/dict/notice/wechat.php similarity index 100% rename from niucloud/app/enum/notice/wechat.php rename to niucloud/app/dict/notice/wechat.php diff --git a/niucloud/app/enum/order/OrderRefundEnum.php b/niucloud/app/dict/order/OrderRefundDict.php similarity index 74% rename from niucloud/app/enum/order/OrderRefundEnum.php rename to niucloud/app/dict/order/OrderRefundDict.php index 8f1c21b1b..0bf00a240 100644 --- a/niucloud/app/enum/order/OrderRefundEnum.php +++ b/niucloud/app/dict/order/OrderRefundDict.php @@ -9,18 +9,19 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\order; +namespace app\dict\order; /** * 订单类型整体功能 - * Class OrderTypeEnum - * @package app\enum\member + * Class OrderRefundDict + * @package app\dict\order */ -class OrderRefundEnum +class OrderRefundDict { const WAIT = '1';//待审核 const WAIT_TRANSFER = '2';//待退款 const SUCCESS = '3';//退款成功 + const FAIL = '-1';//退款失败 /** * 退款状态 @@ -30,17 +31,21 @@ class OrderRefundEnum public static function getStatus($status = []){ $list = [ self::WAIT => [ - 'name' => get_lang('enum_refund.wait'), + 'name' => get_lang('dict_refund.wait'), 'key' => self::WAIT, ], self::WAIT_TRANSFER => [ - 'name' => get_lang('enum_refund.wait_transfer'), + 'name' => get_lang('dict_refund.wait_transfer'), 'key' => self::WAIT, ], self::SUCCESS => [ - 'name' => get_lang('enum_refund.success'), + 'name' => get_lang('dict_refund.success'), 'key' => self::WAIT, ], + self::FAIL => [ + 'name' => get_lang('dict_refund.fail'), + 'key' => self::FAIL, + ] ]; foreach($list as $k => $v){ if(!empty($status) && !in_array($k, $status)) unset($list[$k]); diff --git a/niucloud/app/enum/order/OrderTypeEnum.php b/niucloud/app/dict/order/OrderTypeDict.php similarity index 84% rename from niucloud/app/enum/order/OrderTypeEnum.php rename to niucloud/app/dict/order/OrderTypeDict.php index 6b23dbf6d..d9d380e05 100644 --- a/niucloud/app/enum/order/OrderTypeEnum.php +++ b/niucloud/app/dict/order/OrderTypeDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\order; +namespace app\dict\order; /** * 订单类型整体功能 - * Class OrderTypeEnum - * @package app\enum\member + * Class OrderTypeDict + * @package app\dict\member */ -class OrderTypeEnum +class OrderTypeDict { /** @@ -25,8 +25,8 @@ class OrderTypeEnum * @return void */ public static function getAllowPayType($type){ - /** @var RechargeOrderEnum $class */ - $class = __NAMESPACE__ . '\\' . ucfirst(strtolower($type)).'OrderEnum'; + /** @var RechargeOrderDict $class */ + $class = __NAMESPACE__ . '\\' . ucfirst(strtolower($type)).'OrderDict'; return $class::ALLOW_PAY; } } \ No newline at end of file diff --git a/niucloud/app/enum/order/RechargeOrderEnum.php b/niucloud/app/dict/order/RechargeOrderDict.php similarity index 87% rename from niucloud/app/enum/order/RechargeOrderEnum.php rename to niucloud/app/dict/order/RechargeOrderDict.php index 6a5b34eb4..4848ea87e 100644 --- a/niucloud/app/enum/order/RechargeOrderEnum.php +++ b/niucloud/app/dict/order/RechargeOrderDict.php @@ -9,16 +9,16 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\order; +namespace app\dict\order; -use app\enum\pay\PayEnum; +use app\dict\pay\PayDict; /** *充值订单相关枚举类 - * Class RechargeOrderEnum - * @package app\enum\order + * Class RechargeOrderDict + * @package app\dict\order */ -class RechargeOrderEnum +class RechargeOrderDict { //订单状态 //待支付 @@ -44,9 +44,9 @@ class RechargeOrderEnum * 当前订单支持的支付方式 */ const ALLOW_PAY = [ - PayEnum::WECHATPAY, - PayEnum::ALIPAY, - PayEnum::OFFLINEPAY, + PayDict::WECHATPAY, + PayDict::ALIPAY, + PayDict::OFFLINEPAY, ]; /** @@ -57,7 +57,7 @@ class RechargeOrderEnum { return [ 'type' => 'recharge', - 'name' => get_lang('enum_order.order_type_recharge') + 'name' => get_lang('dict_order.order_type_recharge') ]; } @@ -119,15 +119,15 @@ class RechargeOrderEnum public static function getRefundStatus(int|string $status = '') { $data = [ self::REFUNDING => [ - 'name' => get_lang('enum_order_refund.refunding'), + 'name' => get_lang('dict_order_refund.refunding'), 'status' => self::REFUNDING ], self::REFUND_COMPLETED => [ - 'name' => get_lang('enum_order_refund.refund_complete'), + 'name' => get_lang('dict_order_refund.refund_complete'), 'status' => self::REFUND_COMPLETED ], self::REFUND_FAIL => [ - 'name' => get_lang('enum_order_refund.refund_fail'), + 'name' => get_lang('dict_order_refund.refund_fail'), 'status' => self::REFUND_FAIL ] ]; diff --git a/niucloud/app/enum/pay/OnlinePayEnum.php b/niucloud/app/dict/pay/OnlinePayDict.php similarity index 97% rename from niucloud/app/enum/pay/OnlinePayEnum.php rename to niucloud/app/dict/pay/OnlinePayDict.php index c49e83a0c..e783f3d3d 100644 --- a/niucloud/app/enum/pay/OnlinePayEnum.php +++ b/niucloud/app/dict/pay/OnlinePayDict.php @@ -9,24 +9,19 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\pay; +namespace app\dict\pay; -class OnlinePayEnum +class OnlinePayDict { //上传方式 图片 const SUCCESS = 'SUCCESS';//支付成功 //上传方式 视频 const REFUND = 'REFUND';//转入退款 - const NOTPAY = 'NOTPAY';//未支付 const CLOSED = 'CLOSED';//已关闭 - const REVOKED = 'REVOKED';//已撤销(仅付款码支付会返回) - const USERPAYING = 'USERPAYING';//用户支付中(仅付款码支付会返回) - const PAYERROR = 'PAYERROR';//支付失败(仅付款码支付会返回) - const TRADE_FINISHED = 'TRADE_FINISHED'; diff --git a/niucloud/app/enum/pay/OnlineRefundEnum.php b/niucloud/app/dict/pay/OnlineRefundDict.php similarity index 97% rename from niucloud/app/enum/pay/OnlineRefundEnum.php rename to niucloud/app/dict/pay/OnlineRefundDict.php index 31bb72607..09c26b755 100644 --- a/niucloud/app/enum/pay/OnlineRefundEnum.php +++ b/niucloud/app/dict/pay/OnlineRefundDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\pay; +namespace app\dict\pay; -class OnlineRefundEnum +class OnlineRefundDict { const SUCCESS = 'SUCCESS';//退款成功 diff --git a/niucloud/app/enum/pay/PayChannelEnum.php b/niucloud/app/dict/pay/PayChannelDict.php similarity index 84% rename from niucloud/app/enum/pay/PayChannelEnum.php rename to niucloud/app/dict/pay/PayChannelDict.php index a46772f62..7af1d98b7 100644 --- a/niucloud/app/enum/pay/PayChannelEnum.php +++ b/niucloud/app/dict/pay/PayChannelDict.php @@ -9,11 +9,11 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\pay; +namespace app\dict\pay; -use app\enum\common\ChannelEnum; +use app\dict\common\ChannelDict; -class PayChannelEnum +class PayChannelDict { @@ -22,11 +22,11 @@ class PayChannelEnum * @return array */ public static function getPayChannel(array $types = []){ - $channel = ChannelEnum::getType(); + $channel = ChannelDict::getType(); $list = []; - $pay_type = PayEnum::getPayType(); + $pay_type = PayDict::getPayType(); // foreach($pay_type as $k => $v){ -// if($k == PayEnum::BALANCEPAY){ +// if($k == PayDict::BALANCEPAY){ // $pay_type[$k]['is_template'] = false; // }else{ // $pay_type[$k]['is_template'] = true; diff --git a/niucloud/app/enum/pay/PayEnum.php b/niucloud/app/dict/pay/PayDict.php similarity index 76% rename from niucloud/app/enum/pay/PayEnum.php rename to niucloud/app/dict/pay/PayDict.php index 54cc55f77..e0c47832f 100644 --- a/niucloud/app/enum/pay/PayEnum.php +++ b/niucloud/app/dict/pay/PayDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\pay; +namespace app\dict\pay; -class PayEnum +class PayDict { //上传方式 图片 const WECHATPAY = 'wechatpay';//微信支付 @@ -48,34 +48,34 @@ class PayEnum public static function getPayType(array $types = []){ $list = [ self::WECHATPAY => [ - 'name' => get_lang('enum_pay.type_wechatpay'), + 'name' => get_lang('dict_pay.type_wechatpay'), 'key' => self::WECHATPAY, 'icon' => self::WECHATPAY_ICON, ],//微信支付 self::ALIPAY => [ - 'name' => get_lang('enum_pay.type_alipay'), + 'name' => get_lang('dict_pay.type_alipay'), 'key' => self::ALIPAY, 'icon' => self::ALIPAY_ICON, ],//支付宝支付 // self::UNIPAY => [ -// 'name' => get_lang('enum_pay.type_unipay'), +// 'name' => get_lang('dict_pay.type_unipay'), // 'key' => self::UNIPAY, // 'icon' => self::UNIPAY_ICON // ],//银联支付 // self::OFFLINEPAY => [ -// 'name' => get_lang('enum_pay.type_offline'), +// 'name' => get_lang('dict_pay.type_offline'), // 'key' => self::OFFLINEPAY, // 'icon' => self::OFFLINEPAY_ICON // ],//线下支付 self::BALANCEPAY => [ - 'name' => get_lang('enum_pay.type_balancepay'), + 'name' => get_lang('dict_pay.type_balancepay'), 'key' => self::BALANCEPAY, 'icon' => self::BALANCEPAY_ICON, ],//微信支付 -// self::ALIPAY => get_lang('enum_pay.type_alipay'),//支付宝支付 -// self::UNIPAY => get_lang('enum_pay.type_unipay'),//银联 -// self::OFFLINEPAY => get_lang('enum_pay.type_offline'),//线下支付 -// self::BALANCEPAY => get_lang('enum_pay.type_balancepay'),//余额支付 +// self::ALIPAY => get_lang('dict_pay.type_alipay'),//支付宝支付 +// self::UNIPAY => get_lang('dict_pay.type_unipay'),//银联 +// self::OFFLINEPAY => get_lang('dict_pay.type_offline'),//线下支付 +// self::BALANCEPAY => get_lang('dict_pay.type_balancepay'),//余额支付 ]; if(!empty($types)){ foreach($list as $k => $v){ @@ -93,10 +93,10 @@ class PayEnum */ public static function getStatus(){ $list = [ - self::STATUS_WAIT => get_lang('enum_pay.status_wait'), - self::STATUS_ING => get_lang('enum_pay.status_ing'), - self::STATUS_ED => get_lang('enum_pay.status_ed'), - self::STATUS_CALCLE => get_lang('enum_pay.status_cancle'), + self::STATUS_WAIT => get_lang('dict_pay.status_wait'), + self::STATUS_ING => get_lang('dict_pay.status_ing'), + self::STATUS_ED => get_lang('dict_pay.status_ed'), + self::STATUS_CALCLE => get_lang('dict_pay.status_cancle'), ]; return $list; } diff --git a/niucloud/app/enum/pay/RefundEnum.php b/niucloud/app/dict/pay/RefundDict.php similarity index 70% rename from niucloud/app/enum/pay/RefundEnum.php rename to niucloud/app/dict/pay/RefundDict.php index 1d3f384e2..2c2545dfa 100644 --- a/niucloud/app/enum/pay/RefundEnum.php +++ b/niucloud/app/dict/pay/RefundDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\pay; +namespace app\dict\pay; -class RefundEnum +class RefundDict { //转账状态 const SUCCESS = 'success';//退款成功 @@ -31,10 +31,10 @@ class RefundEnum */ public static function getStatus(){ $list = [ - self::WAIT => get_lang('enum_pay_refund.status_wait'), - self::DEALING => get_lang('enum_pay_refund.status_dealing'), - self::SUCCESS => get_lang('enum_pay_refund.status_success'), - self::FAIL => get_lang('enum_pay_refund.status_fail'), + self::WAIT => get_lang('dict_pay_refund.status_wait'), + self::DEALING => get_lang('dict_pay_refund.status_dealing'), + self::SUCCESS => get_lang('dict_pay_refund.status_success'), + self::FAIL => get_lang('dict_pay_refund.status_fail'), ]; return $list; } @@ -45,10 +45,10 @@ class RefundEnum */ public static function getType(){ return [ - self::WECHATPAY => get_lang('enum_pay_refund.wechatpay'), - self::ALIPAY => get_lang('enum_pay_refund.alipay'), - self::OFFLINE => get_lang('enum_pay_refund.offline'), - self::BALANCE => get_lang('enum_pay_refund.balance') + self::WECHATPAY => get_lang('dict_pay_refund.wechatpay'), + self::ALIPAY => get_lang('dict_pay_refund.alipay'), + self::OFFLINE => get_lang('dict_pay_refund.offline'), + self::BALANCE => get_lang('dict_pay_refund.balance') ]; } } \ No newline at end of file diff --git a/niucloud/app/enum/pay/TransferEnum.php b/niucloud/app/dict/pay/TransferDict.php similarity index 77% rename from niucloud/app/enum/pay/TransferEnum.php rename to niucloud/app/dict/pay/TransferDict.php index e8f491bdc..421db169e 100644 --- a/niucloud/app/enum/pay/TransferEnum.php +++ b/niucloud/app/dict/pay/TransferDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\pay; +namespace app\dict\pay; -class TransferEnum +class TransferDict { const WECHAT = 'wechat';//微信支付 @@ -34,8 +34,8 @@ class TransferEnum public static function getPayTypeByTransfer(string $type = ''){ $list = array( - self::WECHAT => PayEnum::WECHATPAY, - self::ALIPAY => PayEnum::ALIPAY, + self::WECHAT => PayDict::WECHATPAY, + self::ALIPAY => PayDict::ALIPAY, ); if(empty($type)) return $list; @@ -49,24 +49,24 @@ class TransferEnum public static function getTransferType(array $types = [], $is_all = true){ $list = [ self::WECHAT => [ - 'name' => get_lang('enum_transfer.type_wechat'), + 'name' => get_lang('dict_transfer.type_wechat'), 'key' => self::WECHAT, 'is_online' => true ],//微信 self::ALIPAY => [ - 'name' => get_lang('enum_transfer.type_ali'), + 'name' => get_lang('dict_transfer.type_ali'), 'key' => self::ALIPAY, 'is_online' => false ],//支付宝 self::BANK => [ - 'name' => get_lang('enum_transfer.type_bank'), + 'name' => get_lang('dict_transfer.type_bank'), 'key' => self::BANK, 'is_online' => false ],//银行卡 ]; if($is_all){ $list[self::OFFLINE] = [ - 'name' => get_lang('enum_transfer.type_offline'), + 'name' => get_lang('dict_transfer.type_offline'), 'key' => self::OFFLINE, 'is_online' => false ]; @@ -87,10 +87,10 @@ class TransferEnum */ public static function getStatus(){ $list = [ - self::WAIT => get_lang('enum_transfer.status_wait'), - self::DEALING => get_lang('enum_transfer.status_dealing'), - self::SUCCESS => get_lang('enum_transfer.status_success'), - self::FAIL => get_lang('enum_transfer.status_fail'), + self::WAIT => get_lang('dict_transfer.status_wait'), + self::DEALING => get_lang('dict_transfer.status_dealing'), + self::SUCCESS => get_lang('dict_transfer.status_success'), + self::FAIL => get_lang('dict_transfer.status_fail'), ]; return $list; } diff --git a/niucloud/app/enum/scan/ScanEnum.php b/niucloud/app/dict/scan/ScanDict.php similarity index 95% rename from niucloud/app/enum/scan/ScanEnum.php rename to niucloud/app/dict/scan/ScanDict.php index 463bef160..f6b5e9ba7 100644 --- a/niucloud/app/enum/scan/ScanEnum.php +++ b/niucloud/app/dict/scan/ScanDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\scan; +namespace app\dict\scan; -class ScanEnum +class ScanDict { /************************************************* 请求消息的属性 *****************************************/ diff --git a/niucloud/app/dict/schedule/schedule.php b/niucloud/app/dict/schedule/schedule.php new file mode 100644 index 000000000..2219e0181 --- /dev/null +++ b/niucloud/app/dict/schedule/schedule.php @@ -0,0 +1,22 @@ + 'order_close', + 'name' => '未支付订单自动关闭', + 'time' => [ + 'type' => 'min', + ], + 'class' => '', + 'function' => '' + ], + [ + 'key' => 'site_expire_close', + 'name' => '站点到期自动关闭', + 'time' => [ + 'type' => 'min', + ], + 'class' => '', + 'function' => '' + ] +]; diff --git a/niucloud/app/enum/site/SiteEnum.php b/niucloud/app/dict/site/SiteDict.php similarity index 73% rename from niucloud/app/enum/site/SiteEnum.php rename to niucloud/app/dict/site/SiteDict.php index b0e5d90a4..b6afdcae2 100644 --- a/niucloud/app/enum/site/SiteEnum.php +++ b/niucloud/app/dict/site/SiteDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\site; +namespace app\dict\site; -class SiteEnum +class SiteDict { const EXPIRE = 2;//过期 const ON = 1;//正常 - const EXPERIENCE = 0;//体验期 + const CLOSE = 3;//停止 /** @@ -25,9 +25,9 @@ class SiteEnum */ public static function getStatus(){ return [ - self::ON => get_lang('enum_site.status_on'),//正常 - self::EXPERIENCE => get_lang('enum_site.status_experience'),//体验期 - self::EXPIRE => get_lang('enum_site.status_expire'),//过期 + self::ON => get_lang('dict_site.status_on'),//正常 + self::EXPIRE => get_lang('dict_site.status_expire'),//过期 + self::CLOSE => get_lang('dict_site.status_close'),//停止 ]; } diff --git a/niucloud/app/enum/sys/AgreementEnum.php b/niucloud/app/dict/sys/AgreementDict.php similarity index 80% rename from niucloud/app/enum/sys/AgreementEnum.php rename to niucloud/app/dict/sys/AgreementDict.php index 1b043a014..1457743fe 100644 --- a/niucloud/app/enum/sys/AgreementEnum.php +++ b/niucloud/app/dict/sys/AgreementDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; /** * 协议相关枚举类 - * Class AgreementEnum - * @package app\enum\sys + * Class AgreementDict + * @package app\dict\sys */ -class AgreementEnum +class AgreementDict { //服务协议 const SERVICE = 'service'; @@ -29,8 +29,8 @@ class AgreementEnum */ public static function getType(){ return [ - self::SERVICE => get_lang('enum_agreement.service'),//服务协议, - self::PRIVACY => get_lang('enum_agreement.privacy'),//隐私协议 + self::SERVICE => get_lang('dict_agreement.service'),//服务协议, + self::PRIVACY => get_lang('dict_agreement.privacy'),//隐私协议 ]; } diff --git a/niucloud/app/enum/sys/AppTypeEnum.php b/niucloud/app/dict/sys/AppTypeDict.php similarity index 78% rename from niucloud/app/enum/sys/AppTypeEnum.php rename to niucloud/app/dict/sys/AppTypeDict.php index 59f4ef726..538d295cf 100644 --- a/niucloud/app/enum/sys/AppTypeEnum.php +++ b/niucloud/app/dict/sys/AppTypeDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class AppTypeEnum +class AppTypeDict { const ADMIN = 'admin';//平台管理端 @@ -25,9 +25,9 @@ class AppTypeEnum */ public static function getAppType(){ return [ - self::ADMIN => get_lang('enum_app.type_admin'),//平台管理端 - self::SITE => get_lang('enum_app.type_site'),//站点管理端 - self::API => get_lang('enum_app.type_api'),//客户端 + self::ADMIN => get_lang('dict_app.type_admin'),//平台管理端 + self::SITE => get_lang('dict_app.type_site'),//站点管理端 + self::API => get_lang('dict_app.type_api'),//客户端 ]; } diff --git a/niucloud/app/enum/sys/ConfigKeyEnum.php b/niucloud/app/dict/sys/ConfigKeyDict.php similarity index 96% rename from niucloud/app/enum/sys/ConfigKeyEnum.php rename to niucloud/app/dict/sys/ConfigKeyDict.php index bb5aea9f8..a8b433b00 100644 --- a/niucloud/app/enum/sys/ConfigKeyEnum.php +++ b/niucloud/app/dict/sys/ConfigKeyDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class ConfigKeyEnum +class ConfigKeyDict { const WECHAT = 'WECHAT';//微信公众号 diff --git a/niucloud/app/enum/sys/CronEnum.php b/niucloud/app/dict/sys/CronDict.php similarity index 72% rename from niucloud/app/enum/sys/CronEnum.php rename to niucloud/app/dict/sys/CronDict.php index 63bd8275f..dd297b76d 100644 --- a/niucloud/app/enum/sys/CronEnum.php +++ b/niucloud/app/dict/sys/CronDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class CronEnum +class CronDict { const CRON = 'cron';//定时任务 @@ -28,8 +28,8 @@ class CronEnum */ public static function getType(){ return [ - self::CRON => get_lang('enum_cron.type_cron'),//定时任务 - self::CROND => get_lang('enum_cron.type_crond'),//周期任务 + self::CRON => get_lang('dict_cron.type_cron'),//定时任务 + self::CROND => get_lang('dict_cron.type_crond'),//周期任务 ]; } /** @@ -38,10 +38,10 @@ class CronEnum */ public static function getCrondType(){ return [ - self::MINUTE => get_lang('enum_cron.type_minute'),//分钟 - self::DAY => get_lang('enum_cron.type_day'),//天 - self::WEEK => get_lang('enum_cron.type_week'),//星期 - self::MONTH => get_lang('enum_cron.type_month'),//月份 + self::MINUTE => get_lang('dict_cron.type_minute'),//分钟 + self::DAY => get_lang('dict_cron.type_day'),//天 + self::WEEK => get_lang('dict_cron.type_week'),//星期 + self::MONTH => get_lang('dict_cron.type_month'),//月份 ]; } diff --git a/niucloud/app/enum/sys/FileEnum.php b/niucloud/app/dict/sys/FileDict.php similarity index 79% rename from niucloud/app/enum/sys/FileEnum.php rename to niucloud/app/dict/sys/FileDict.php index 4fc692b9e..4cd2f4668 100644 --- a/niucloud/app/enum/sys/FileEnum.php +++ b/niucloud/app/dict/sys/FileDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class FileEnum +class FileDict { //上传方式 图片 const IMAGE = 'image'; @@ -30,8 +30,8 @@ class FileEnum */ public static function getType(){ return [ - self::IMAGE => get_lang('enum_file.type_image'),//图片 - self::VIDEO => get_lang('enum_file.type_video'),//视频 + self::IMAGE => get_lang('dict_file.type_image'),//图片 + self::VIDEO => get_lang('dict_file.type_video'),//视频 ]; } @@ -41,10 +41,10 @@ class FileEnum */ public static function getStorageType(){ return [ - self::LOCAL => get_lang('enum_file.storage_type_local'),//本地存储 - self::QINIU => get_lang('enum_file.storage_type_qiniu'),//七牛云 - self::ALIYUN => get_lang('enum_file.storage_type_image'),//阿里云 - self::QCLOUD => get_lang('enum_file.storage_type_qcloud'),//腾讯云 + self::LOCAL => get_lang('dict_file.storage_type_local'),//本地存储 + self::QINIU => get_lang('dict_file.storage_type_qiniu'),//七牛云 + self::ALIYUN => get_lang('dict_file.storage_type_image'),//阿里云 + self::QCLOUD => get_lang('dict_file.storage_type_qcloud'),//腾讯云 ]; } diff --git a/niucloud/app/enum/sys/MenuEnum.php b/niucloud/app/dict/sys/MenuDict.php similarity index 81% rename from niucloud/app/enum/sys/MenuEnum.php rename to niucloud/app/dict/sys/MenuDict.php index 2faf2d4d2..496655a01 100644 --- a/niucloud/app/enum/sys/MenuEnum.php +++ b/niucloud/app/dict/sys/MenuDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class MenuEnum +class MenuDict { const ON = 1; @@ -24,8 +24,8 @@ class MenuEnum */ public static function getStatus(){ return [ - self::ON => get_lang('enum_menu.status_on'),//展示 - self::OFF => get_lang('enum_menu.status_off'),//隐藏 + self::ON => get_lang('dict_menu.status_on'),//展示 + self::OFF => get_lang('dict_menu.status_off'),//隐藏 ]; } diff --git a/niucloud/app/enum/sys/MenuTypeEnum.php b/niucloud/app/dict/sys/MenuTypeDict.php similarity index 76% rename from niucloud/app/enum/sys/MenuTypeEnum.php rename to niucloud/app/dict/sys/MenuTypeDict.php index 9572b0e0e..bf409ccc1 100644 --- a/niucloud/app/enum/sys/MenuTypeEnum.php +++ b/niucloud/app/dict/sys/MenuTypeDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class MenuTypeEnum +class MenuTypeDict { const LIST = '0'; @@ -20,9 +20,9 @@ class MenuTypeEnum public static function getMenuType(){ return [ - self::LIST => get_lang('enum_menu.type_list'),//目录 - self::MENU => get_lang('enum_menu.type_menu'),//菜单 - self::BUTTON => get_lang('enum_menu.type_button'),//接口 + self::LIST => get_lang('dict_menu.type_list'),//目录 + self::MENU => get_lang('dict_menu.type_menu'),//菜单 + self::BUTTON => get_lang('dict_menu.type_button'),//接口 ]; } diff --git a/niucloud/app/enum/sys/MethodEnum.php b/niucloud/app/dict/sys/MethodDict.php similarity index 95% rename from niucloud/app/enum/sys/MethodEnum.php rename to niucloud/app/dict/sys/MethodDict.php index c91ea18a3..1b901f938 100644 --- a/niucloud/app/enum/sys/MethodEnum.php +++ b/niucloud/app/dict/sys/MethodDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class MethodEnum +class MethodDict { const GET = 'get'; diff --git a/niucloud/app/enum/sys/RoleStatusEnum.php b/niucloud/app/dict/sys/RoleStatusDict.php similarity index 81% rename from niucloud/app/enum/sys/RoleStatusEnum.php rename to niucloud/app/dict/sys/RoleStatusDict.php index 5019c58e9..c2e3e4d09 100644 --- a/niucloud/app/enum/sys/RoleStatusEnum.php +++ b/niucloud/app/dict/sys/RoleStatusDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class RoleStatusEnum +class RoleStatusDict { const ON = 1; @@ -24,8 +24,8 @@ class RoleStatusEnum */ public static function getStatus(){ return [ - self::ON => get_lang('enum_role.status_on'),//启用 - self::OFF => get_lang('enum_role.status_off'),//关闭 + self::ON => get_lang('dict_role.status_on'),//启用 + self::OFF => get_lang('dict_role.status_off'),//关闭 ]; } diff --git a/niucloud/app/enum/sys/SmsEnum.php b/niucloud/app/dict/sys/SmsDict.php similarity index 88% rename from niucloud/app/enum/sys/SmsEnum.php rename to niucloud/app/dict/sys/SmsDict.php index b277e3a64..6b8996a04 100644 --- a/niucloud/app/enum/sys/SmsEnum.php +++ b/niucloud/app/dict/sys/SmsDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; /** * 短信枚举类 - * Class SmsEnum - * @package app\enum\sys + * Class SmsDict + * @package app\dict\sys */ -class SmsEnum +class SmsDict { //阿里云短信 const ALISMS = 'ali'; @@ -55,9 +55,9 @@ class SmsEnum public function getStatusType(){ return [ - self::SENDING => 'enum_sms.status_sending', - self::SUCCESS => 'enum_sms.status_success', - self::FAIL => 'enum_sms.status_fail', + self::SENDING => 'dict_sms.status_sending', + self::SUCCESS => 'dict_sms.status_success', + self::FAIL => 'dict_sms.status_fail', ]; } diff --git a/niucloud/app/enum/sys/StorageEnum.php b/niucloud/app/dict/sys/StorageDict.php similarity index 96% rename from niucloud/app/enum/sys/StorageEnum.php rename to niucloud/app/dict/sys/StorageDict.php index ccdcde826..ef231054f 100644 --- a/niucloud/app/enum/sys/StorageEnum.php +++ b/niucloud/app/dict/sys/StorageDict.php @@ -9,14 +9,14 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; /** * 云存储枚举类 - * Class UploadEnum - * @package app\enum\sys + * Class StorageDict + * @package app\dict\sys */ -class StorageEnum +class StorageDict { //本地存储 const LOCAL = 'local'; diff --git a/niucloud/app/enum/sys/UserEnum.php b/niucloud/app/dict/sys/UserDict.php similarity index 81% rename from niucloud/app/enum/sys/UserEnum.php rename to niucloud/app/dict/sys/UserDict.php index a8d91051a..876286a93 100644 --- a/niucloud/app/enum/sys/UserEnum.php +++ b/niucloud/app/dict/sys/UserDict.php @@ -9,9 +9,9 @@ // | Author: Niucloud Team // +---------------------------------------------------------------------- -namespace app\enum\sys; +namespace app\dict\sys; -class UserEnum +class UserDict { const ON = 1; @@ -23,8 +23,8 @@ class UserEnum */ public static function getStatus(){ return [ - self::ON => get_lang('enum_user.status_on'),//正常 - self::OFF => get_lang('enum_user.status_off'),//无效 + self::ON => get_lang('dict_user.status_on'),//正常 + self::OFF => get_lang('dict_user.status_off'),//无效 ]; } diff --git a/niucloud/app/enum/common/CommonEnum.php b/niucloud/app/enum/common/CommonEnum.php deleted file mode 100644 index 23c776b92..000000000 --- a/niucloud/app/enum/common/CommonEnum.php +++ /dev/null @@ -1,28 +0,0 @@ - get_lang('enum_sex.unknown'),//未知 - self::MAN => get_lang('enum_sex.man'),//男 - self::WOMAN => get_lang('enum_sex.woman'),//女 - ]; - } -} \ No newline at end of file diff --git a/niucloud/app/enum/member/MemberAccountEnum.php b/niucloud/app/enum/member/MemberAccountEnum.php deleted file mode 100644 index 0edb05676..000000000 --- a/niucloud/app/enum/member/MemberAccountEnum.php +++ /dev/null @@ -1,74 +0,0 @@ - get_lang('enum_member.account_point'), - self::BALANCE => get_lang('enum_member.account_balance'), - self::MONEY => get_lang('enum_member.account_money'), - self::COMMISSION => get_lang('enum_member.account_commission'), - ]; - if (empty($type)) { - return $data; - } - return $data[ $type ] ?? ''; - } - - /** - * 获取账户变动方式 - * @param string $type - * @return array|mixed|string - */ - public static function getFromType($type = '') - { - $type_util = new ConfigUtil(root_path() . str_replace('/', DIRECTORY_SEPARATOR, "app/enum/member/fromtypes")); - $file_data = $type_util->loadFiles(); - $types = []; - foreach ($file_data as $data) { - $types = empty($types) ? $data : array_merge2($types, $data); - } - - if (empty($type)) { - return $types; - } - return $types[ $type ] ?? ''; - } - -} \ No newline at end of file diff --git a/niucloud/app/enum/member/fromtypes/system.php b/niucloud/app/enum/member/fromtypes/system.php deleted file mode 100644 index 319a86ce5..000000000 --- a/niucloud/app/enum/member/fromtypes/system.php +++ /dev/null @@ -1,98 +0,0 @@ - [ - //调整 - 'adjust' => [ - //名称 - 'name' => get_lang('enum_member.account_point_adjust'), - //是否增加 - MemberAccountEnum::INC => 1, - //是否减少 - MemberAccountEnum::DEC => 1, - ], - //充值赠送 - 'recharge_give' => [ - //名称 - 'name' => get_lang('enum_member.account_point_recharge_give'), - //是否增加 - MemberAccountEnum::INC => 1, - //是否减少 - MemberAccountEnum::DEC => 0, - ], - - ], - MemberAccountEnum::BALANCE => [ - //调整 - 'adjust' => [ - //名称 - 'name' => get_lang('enum_member.account_balance_adjust'), - //是否增加 - MemberAccountEnum::INC => 1, - //是否减少 - MemberAccountEnum::DEC => 1, - ], - //充值 - 'recharge' => [ - //名称 - 'name' => get_lang('enum_member.account_balance_recharge'), - //是否增加 - MemberAccountEnum::INC => 1, - //是否减少 - MemberAccountEnum::DEC => 0, - ], - 'recharge_refund' => [ - //名称 - 'name' => get_lang('enum_member.account_balance_recharge_refund'), - //是否增加 - MemberAccountEnum::INC => 0, - //是否减少 - MemberAccountEnum::DEC => 1, - ] - ], - MemberAccountEnum::MONEY => [ - - //活动奖励 - 'award' => [ - //名称 - 'name' => get_lang('enum_member.account_money_award'), - //是否增加 - MemberAccountEnum::INC => 1, - //是否减少 - MemberAccountEnum::DEC => 0, - ], - //提现 - 'cash_out' => [ - //名称 - 'name' => get_lang('enum_member.account_money_cash_out'), - //是否增加 - MemberAccountEnum::INC => 0, - //是否减少 - MemberAccountEnum::DEC => 1, - ], - ], - //会员佣金 - MemberAccountEnum::COMMISSION => [ - - //活动奖励 - 'award' => [ - //名称 - 'name' => get_lang('enum_member.account_commission_award'), - //是否增加 - MemberAccountEnum::INC => 1, - //是否减少 - MemberAccountEnum::DEC => 0, - ], - //提现 - 'cash_out' => [ - //名称 - 'name' => get_lang('enum_member.account_commission_cash_out'), - //是否增加 - MemberAccountEnum::INC => 0, - //是否减少 - MemberAccountEnum::DEC => 1, - ], - ] -]; \ No newline at end of file diff --git a/niucloud/app/event.php b/niucloud/app/event.php index 8fb1c1ba6..8fe66ddfd 100644 --- a/niucloud/app/event.php +++ b/niucloud/app/event.php @@ -1,4 +1,5 @@ [ 'app\listener\member\MemberAccountListener' ], //扫码事件 'scan' => [ 'app\listener\scan\ScanListener' ], + 'addSiteAfter' => [ 'app\listener\site\AddSiteAfterListener' ], /** * 消息相关事件 @@ -64,4 +66,4 @@ $system_event = [ 'subscribe' => [ ], ]; -return (new \core\addon\AddonLoader("Event"))->load($system_event); +return (new DictLoader("Event"))->load($system_event); diff --git a/niucloud/app/install/controller/Index.php b/niucloud/app/install/controller/Index.php index 52529906a..45a44429d 100644 --- a/niucloud/app/install/controller/Index.php +++ b/niucloud/app/install/controller/Index.php @@ -5,10 +5,11 @@ namespace app\install\controller; use app\model\site\Site; use app\model\sys\SysUser; -use app\service\admin\install\InstallArticleService; -use app\service\admin\install\InstallDiyService; use app\service\admin\install\InstallSystemService; +use app\service\admin\site\SiteGroupService; +use app\service\admin\site\SiteService; use think\facade\Cache; +use think\facade\Db; use think\facade\View; @@ -206,44 +207,62 @@ class Index extends BaseInstall public function install() { + + set_time_limit(300); Cache::delete('install_data'); Cache::set('install_status', 0);//进行中 $check = $this->testDb()->getData(); - if ($check[ 'code' ] != 200) { + if ($check[ 'code' ] != 1) { $this->setSuccessLog([ $check[ 'data' ][ 'message' ], 'error' ]); return fail($check[ 'data' ][ 'message' ]); } - $site_name = input('site_name', ""); + $admin_name = input('admin_name', ""); $username = input('username', ""); $password = input('password', ""); $password2 = input('password2', ""); - if ($site_name == '' || $username == '' || $password == '') { + $site_name = input('site_name', ""); + $site_username = input('site_username', ""); + $site_password = input('site_password', ""); + $site_password2 = input('site_password2', ""); + + if ($admin_name == '' || $username == '' || $password == '') { $this->setSuccessLog([ '平台信息不能为空', 'error' ]); return fail('平台信息不能为空!'); } if ($password != $password2) { - $this->setSuccessLog([ '两次密码输入不一样,请重新输入', 'error' ]); - return fail('两次密码输入不一样,请重新输入'); + $this->setSuccessLog([ '平台两次密码输入不一样,请重新输入', 'error' ]); + return fail('平台两次密码输入不一样,请重新输入'); + } + + if ($site_name == '' || $site_username == '' || $site_password == '') { + $this->setSuccessLog([ '平台信息不能为空', 'error' ]); + return fail('平台信息不能为空!'); + } + + if ($site_password != $site_password2) { + $this->setSuccessLog([ '站点两次密码输入不一样,请重新输入', 'error' ]); + return fail('站点两次密码输入不一样,请重新输入'); } try { //配置写入 $res = $this->installConfig(input())->getData(); - if ($res[ 'code' ] != 200) { + if ($res[ 'code' ] != 1) { $this->setSuccessLog([ $res[ 'msg' ], 'error' ]); return fail($res[ 'msg' ]); } //数据库 $res = $this->installSql(input())->getData(); - if ($res[ 'code' ] != 200) { + if ($res[ 'code' ] != 1) { $this->setSuccessLog([ $res[ 'msg' ], 'error' ]); return fail($res[ 'msg' ]); } + Cache::set('install_status', 1);//成功 return success(); } catch (\Exception $e) { @@ -255,16 +274,29 @@ class Index extends BaseInstall public function initData() { $this->checkLock(); - $site_name = input('site_name', ""); + $admin_name = input('admin_name', ""); $username = input('username', ""); $password = input('password', ""); $password2 = input('password2', ""); - if ($site_name == '' || $username == '' || $password == '') { + + $site_name = input('site_name', ""); + $site_username = input('site_username', ""); + $site_password = input('site_password', ""); + $site_password2 = input('site_password2', ""); + if ($admin_name == '' || $username == '' || $password == '') { return fail('平台信息不能为空!'); } if ($password != $password2) { - return fail('两次密码输入不一样,请重新输入'); + return fail('平台两次密码输入不一样,请重新输入'); + } + + if ($site_name == '' || $site_username == '' || $site_password == '') { + return fail('平台信息不能为空!'); + } + + if ($site_password != $site_password2) { + return fail('站点两次密码输入不一样,请重新输入'); } try { @@ -282,28 +314,27 @@ class Index extends BaseInstall 'password' => create_password($password), ]); } - - $site = ( new Site() )->where([ [ 'site_id', '=', 1 ] ])->findOrEmpty(); + ( new Site() )->where([ [ 'site_id', '=', 1 ] ])->update(['site_id' => 0]); + $site = ( new Site() )->where([ [ 'site_id', '=', 0 ] ])->findOrEmpty(); if (!$site->isEmpty()) { - $user->save([ - 'site_name' => $site_name, + $site->save([ + 'site_name' => $admin_name, ]); } + //修改自增主键默认值 + Db::execute("alter table ".env('database.prefix', '')."site auto_increment = 1"); + //获取默认套餐 + $group_id = (new SiteGroupService())->addAllMenuGroup(); - // 初始化自定义页面数据 - $res = ( new InstallDiyService() )->install([ 'site_id' => $site->site_id ]); - if (!$res) { - $this->setSuccessLog([ '自定义页面初始化失败', 'error' ]); - return fail('自定义页面初始化失败'); - } - - // 初始化文章数据 - $res = ( new InstallArticleService() )->install([ 'site_id' => $site->site_id ]); - if (!$res) { - $this->setSuccessLog([ '文章初始化失败', 'error' ]); - return fail('文章初始化失败'); - } - + $data = [ + 'site_name' => $site_name, + 'real_name' => '', + 'group_id' => $group_id, + 'expire_time' => 0, + 'username' => $site_username, + 'password' => $site_password, + ]; + (new SiteService())->add($data); $fp = fopen($this->lock_file, "w"); if ($fp == false) { $this->setSuccessLog([ "写入失败,请检查目录" . dirname(dirname(__FILE__)) . "是否可写入!'", 'error' ]); @@ -313,6 +344,7 @@ class Index extends BaseInstall fwrite($fp, '已安装'); fclose($fp); Cache::set('install_status', 2);//成功 +// Cache::tag(MenuService::$cache_tag_name)->clear(); return success(); } catch (\Exception $e) { $this->setSuccessLog([ '安装失败' . $e->getMessage(), 'error' ]); @@ -368,7 +400,7 @@ class Index extends BaseInstall //导入SQL并执行。 $get_sql_data = file_get_contents($file_name); $sql_query = $this->getSqlQuery($get_sql_data); - @mysqli_query($conn, "SET NAMES utf8"); + @mysqli_query($conn, "SET NAMES utf8mb4"); $query_count = count($sql_query); for ($i = 0; $i < $query_count; $i++) { diff --git a/niucloud/app/install/source/database.sql b/niucloud/app/install/source/database.sql index 04fc24658..103663038 100644 --- a/niucloud/app/install/source/database.sql +++ b/niucloud/app/install/source/database.sql @@ -1,5 +1,4 @@ - -SET NAMES 'utf8'; +SET NAMES 'utf8mb4'; DROP TABLE IF EXISTS addon; @@ -35,7 +34,7 @@ DROP TABLE IF EXISTS member_label; DROP TABLE IF EXISTS member_level; -DROP TABLE IF EXISTS order; +DROP TABLE IF EXISTS `order`; DROP TABLE IF EXISTS order_item; @@ -89,31 +88,37 @@ DROP TABLE IF EXISTS wechat_media; DROP TABLE IF EXISTS wechat_reply; - +-- +-- `ns_wechat_reply` +-- CREATE TABLE wechat_reply ( id int(10) UNSIGNED NOT NULL AUTO_INCREMENT, name varchar(64) NOT NULL DEFAULT '' COMMENT '规则名称', site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', keyword varchar(64) NOT NULL DEFAULT '' COMMENT '关键词', reply_type tinyint(4) NOT NULL COMMENT '回复类型 subscribe-关注回复 keyword-关键字回复 default-默认回复', - matching_type tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '匹配方式:1-全匹配;2-模糊匹配', - content_type tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '内容类型:1-文本', + matching_type tinyint(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT '匹配方式:1-全匹配;2-模糊匹配', + content_type tinyint(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT '内容类型:1-文本', content text NOT NULL COMMENT '回复内容', - status tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '启动状态:1-启动;0-关闭', - sort int(11) UNSIGNED NOT NULL DEFAULT 50 COMMENT '排序', + status tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '启动状态:1-启动;0-关闭', + sort int(10) UNSIGNED NOT NULL DEFAULT 50 COMMENT '排序', create_time int(11) NOT NULL COMMENT '创建时间', update_time int(11) NOT NULL COMMENT '更新时间', delete_time int(11) NOT NULL COMMENT '删除时间', PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 16384, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '公众号消息回调表'; -ALTER TABLE wechat_reply ADD INDEX keyword (keyword, reply_type); - +ALTER TABLE wechat_reply +ADD INDEX keyword (keyword, reply_type); +-- +-- `ns_wechat_media` +-- CREATE TABLE wechat_media ( id int(11) NOT NULL AUTO_INCREMENT, site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', @@ -125,13 +130,17 @@ CREATE TABLE wechat_media ( PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 1872, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '微信素材表'; -ALTER TABLE wechat_media ADD INDEX type (type, site_id); - +ALTER TABLE wechat_media +ADD INDEX type (type, site_id); +-- +-- `ns_wechat_fans` +-- CREATE TABLE wechat_fans ( fans_id int(11) NOT NULL AUTO_INCREMENT COMMENT '粉丝ID', site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', @@ -156,15 +165,20 @@ CREATE TABLE wechat_fans ( PRIMARY KEY (fans_id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 5461, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '微信粉丝列表'; -ALTER TABLE wechat_fans ADD INDEX openid (openid, site_id); - -ALTER TABLE wechat_fans ADD INDEX unionid (unionid, site_id); +ALTER TABLE wechat_fans +ADD INDEX openid (openid, site_id); +ALTER TABLE wechat_fans +ADD INDEX unionid (unionid, site_id); +-- +-- `ns_sys_user_role` +-- CREATE TABLE sys_user_role ( id int(11) NOT NULL AUTO_INCREMENT, uid int(11) NOT NULL DEFAULT 0 COMMENT '用户id', @@ -175,177 +189,216 @@ CREATE TABLE sys_user_role ( PRIMARY KEY (id) ) ENGINE = INNODB, -AUTO_INCREMENT = 2, +AVG_ROW_LENGTH = 481, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '用户权限表'; -ALTER TABLE sys_user_role ADD INDEX create_time (create_time); +ALTER TABLE sys_user_role +ADD INDEX create_time (create_time); -ALTER TABLE sys_user_role ADD INDEX site_id (site_id); - -ALTER TABLE sys_user_role ADD INDEX uid (uid); +ALTER TABLE sys_user_role +ADD INDEX site_id (site_id); +ALTER TABLE sys_user_role +ADD INDEX uid (uid); +-- +-- `ns_sys_user_log` +-- CREATE TABLE sys_user_log ( id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '管理员操作记录ID', ip varchar(16) NOT NULL DEFAULT '' COMMENT '登录IP', site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - uid int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '管理员id', + uid int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '管理员id', username varchar(64) NOT NULL DEFAULT '' COMMENT '管理员姓名', url varchar(128) NOT NULL DEFAULT '' COMMENT '链接', params text DEFAULT NULL COMMENT '参数', type varchar(32) NOT NULL DEFAULT '' COMMENT '请求方式', - create_time int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '操作时间', + create_time int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '操作时间', PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 857, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '管理员操作记录表', ROW_FORMAT = COMPACT; -ALTER TABLE sys_user_log ADD INDEX create_time (create_time); +ALTER TABLE sys_user_log +ADD INDEX create_time (create_time); -ALTER TABLE sys_user_log ADD INDEX site_id (site_id); - -ALTER TABLE sys_user_log ADD INDEX uid (uid); +ALTER TABLE sys_user_log +ADD INDEX site_id (site_id); +ALTER TABLE sys_user_log +ADD INDEX uid (uid); +-- +-- `ns_sys_user` +-- CREATE TABLE sys_user ( - uid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '系统用户ID', + uid smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '系统用户ID', username varchar(255) NOT NULL DEFAULT '' COMMENT '用户账号', head_img varchar(255) NOT NULL DEFAULT '', password varchar(100) NOT NULL DEFAULT '' COMMENT '用户密码', real_name varchar(16) NOT NULL DEFAULT '' COMMENT '实际姓名', last_ip varchar(16) NOT NULL DEFAULT '' COMMENT '最后一次登录ip', - last_time int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最后一次登录时间', - create_time int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '添加时间', - login_count int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '登录次数', - status tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '后台管理员状态 1有效0无效', - is_del tinyint(4) UNSIGNED NOT NULL DEFAULT 0, + last_time int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最后一次登录时间', + create_time int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '添加时间', + login_count int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '登录次数', + status tinyint(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT '后台管理员状态 1有效0无效', + is_del tinyint(3) UNSIGNED NOT NULL DEFAULT 0, delete_time tinyint(4) NOT NULL DEFAULT 0 COMMENT '删除时间', update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', PRIMARY KEY (uid), INDEX uid (uid) ) ENGINE = INNODB, -AUTO_INCREMENT = 2, +AVG_ROW_LENGTH = 372, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '后台管理员表', ROW_FORMAT = COMPACT; -ALTER TABLE sys_user ADD INDEX delete_time (delete_time); +ALTER TABLE sys_user +ADD INDEX delete_time (delete_time); -ALTER TABLE sys_user ADD INDEX is_del (is_del); +ALTER TABLE sys_user +ADD INDEX is_del (is_del); -ALTER TABLE sys_user ADD INDEX password (password); +ALTER TABLE sys_user +ADD INDEX password (password); -ALTER TABLE sys_user ADD INDEX update_time (update_time); - -ALTER TABLE sys_user ADD INDEX username (username (191)); +ALTER TABLE sys_user +ADD INDEX update_time (update_time); +ALTER TABLE sys_user +ADD INDEX username (username (191)); +-- +-- `ns_sys_role` +-- CREATE TABLE sys_role ( - role_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '角色id', + role_id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '角色id', site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', role_name varchar(255) NOT NULL DEFAULT '' COMMENT '角色名称', rules text DEFAULT NULL COMMENT '角色权限(menus_id)', - status tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态', + status tinyint(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态', create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', update_time int(11) NOT NULL DEFAULT 0 COMMENT '最后修改时间', PRIMARY KEY (role_id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 1638, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '角色表', ROW_FORMAT = COMPACT; -ALTER TABLE sys_role ADD INDEX site_id (site_id); - -ALTER TABLE sys_role ADD INDEX status (status); +ALTER TABLE sys_role +ADD INDEX site_id (site_id); +ALTER TABLE sys_role +ADD INDEX status (status); +-- +-- `ns_sys_notice_sms_log` +-- CREATE TABLE sys_notice_sms_log ( - id INT(11) NOT NULL AUTO_INCREMENT COMMENT 'id', - site_id INT(11) NOT NULL DEFAULT 0, - mobile VARCHAR(11) NOT NULL DEFAULT '' COMMENT '手机号码', - sms_type VARCHAR(32) NOT NULL DEFAULT '' COMMENT '发送关键字(注册、找回密码)', - `key` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '发送关键字(注册、找回密码)', - template_id VARCHAR(50) NOT NULL DEFAULT '', - content VARCHAR(255) NOT NULL DEFAULT '' COMMENT '发送内容', - params VARCHAR(255) NOT NULL DEFAULT '' COMMENT '数据参数', - status VARCHAR(32) NOT NULL DEFAULT 'sending' COMMENT '发送状态:sending-发送中;success-发送成功;fail-发送失败', - result TEXT DEFAULT NULL COMMENT '短信结果', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - send_time INT(11) NOT NULL DEFAULT 0 COMMENT '发送时间', - update_time INT(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - delete_time INT(11) NOT NULL DEFAULT 0 COMMENT '删除时间', + id int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', + site_id int(11) NOT NULL DEFAULT 0, + mobile varchar(11) NOT NULL DEFAULT '' COMMENT '手机号码', + sms_type varchar(32) NOT NULL DEFAULT '' COMMENT '发送关键字(注册、找回密码)', + `key` varchar(32) NOT NULL DEFAULT '' COMMENT '发送关键字(注册、找回密码)', + template_id varchar(50) NOT NULL DEFAULT '', + content varchar(255) NOT NULL DEFAULT '' COMMENT '发送内容', + params varchar(255) NOT NULL DEFAULT '' COMMENT '数据参数', + status varchar(32) NOT NULL DEFAULT 'sending' COMMENT '发送状态:sending-发送中;success-发送成功;fail-发送失败', + result text DEFAULT NULL COMMENT '短信结果', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + send_time int(11) NOT NULL DEFAULT 0 COMMENT '发送时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + delete_time int(11) NOT NULL DEFAULT 0 COMMENT '删除时间', PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 496, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '短信发送表'; - +-- +-- `ns_sys_notice_log` +-- CREATE TABLE sys_notice_log ( - id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '通知记录ID', - site_id INT(11) NOT NULL DEFAULT 0 COMMENT '站点id', - `key` VARCHAR(255) DEFAULT '' COMMENT '消息key', - notice_type VARCHAR(50) DEFAULT 'sms' COMMENT '消息类型(sms,wechat.weapp)', - uid INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '通知的用户id', - member_id INT(11) NOT NULL DEFAULT 0 COMMENT '消息的会员id', - nickname VARCHAR(255) NOT NULL DEFAULT '' COMMENT '接收人用户昵称或姓名', - receiver VARCHAR(255) NOT NULL DEFAULT '' COMMENT '接收人(对应手机号,openid)', - content TEXT DEFAULT NULL COMMENT '消息数据', - is_click TINYINT(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '点击次数', - is_visit TINYINT(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '访问次数', - visit_time INT(11) NOT NULL DEFAULT 0 COMMENT '访问时间', - create_time INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '消息时间', - result VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '结果', - params TEXT DEFAULT NULL, + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '通知记录ID', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + `key` varchar(255) DEFAULT '' COMMENT '消息key', + notice_type varchar(50) DEFAULT 'sms' COMMENT '消息类型(sms,wechat.weapp)', + uid int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '通知的用户id', + member_id int(11) NOT NULL DEFAULT 0 COMMENT '消息的会员id', + nickname varchar(255) NOT NULL DEFAULT '' COMMENT '接收人用户昵称或姓名', + receiver varchar(255) NOT NULL DEFAULT '' COMMENT '接收人(对应手机号,openid)', + content text DEFAULT NULL COMMENT '消息数据', + is_click tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '点击次数', + is_visit tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '访问次数', + visit_time int(11) NOT NULL DEFAULT 0 COMMENT '访问时间', + create_time int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '消息时间', + result varchar(1000) NOT NULL DEFAULT '' COMMENT '结果', + params text DEFAULT NULL, PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 712, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, -COMMENT = '通知记录表'; +COMMENT = '通知记录表', +ROW_FORMAT = COMPACT; -ALTER TABLE sys_notice_log ADD INDEX member_id(member_id); +ALTER TABLE sys_notice_log +ADD INDEX member_id (member_id); -ALTER TABLE sys_notice_log ADD INDEX message_key(`key`(191)); - -ALTER TABLE sys_notice_log ADD INDEX uid(uid); +ALTER TABLE sys_notice_log +ADD INDEX message_key (`key` (191)); +ALTER TABLE sys_notice_log +ADD INDEX uid (uid); +-- +-- `ns_sys_notice` +-- CREATE TABLE sys_notice ( - id INT(11) NOT NULL AUTO_INCREMENT, - site_id INT(11) NOT NULL DEFAULT 0 COMMENT '站点ID', - `key` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '标识', - sms_content TEXT DEFAULT NULL COMMENT '短信配置参数', - is_wechat TINYINT(4) NOT NULL DEFAULT 0 COMMENT '公众号模板消息(0:关闭,1:开启)', - is_weapp TINYINT(4) NOT NULL DEFAULT 0 COMMENT '小程序订阅消息(0:关闭,1:开启)', - is_sms TINYINT(4) NOT NULL DEFAULT 0 COMMENT '发送短信(0:关闭,1:开启)', - wechat_template_id VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信模版消息id', - weapp_template_id VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信小程序订阅消息id', - sms_id VARCHAR(255) NOT NULL DEFAULT '' COMMENT '短信id(对应短信配置)', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '添加时间', - wechat_first VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信头部', - wechat_remark VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信说明', + id int(11) NOT NULL AUTO_INCREMENT, + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点ID', + `key` varchar(50) NOT NULL DEFAULT '' COMMENT '标识', + sms_content text DEFAULT NULL COMMENT '短信配置参数', + is_wechat tinyint(4) NOT NULL DEFAULT 0 COMMENT '公众号模板消息(0:关闭,1:开启)', + is_weapp tinyint(4) NOT NULL DEFAULT 0 COMMENT '小程序订阅消息(0:关闭,1:开启)', + is_sms tinyint(4) NOT NULL DEFAULT 0 COMMENT '发送短信(0:关闭,1:开启)', + wechat_template_id varchar(255) NOT NULL DEFAULT '' COMMENT '微信模版消息id', + weapp_template_id varchar(255) NOT NULL DEFAULT '' COMMENT '微信小程序订阅消息id', + sms_id varchar(255) NOT NULL DEFAULT '' COMMENT '短信id(对应短信配置)', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', + wechat_first varchar(255) NOT NULL DEFAULT '' COMMENT '微信头部', + wechat_remark varchar(255) NOT NULL DEFAULT '' COMMENT '微信说明', PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 2048, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, -COMMENT = '通知模型'; +COMMENT = '通知模型', +ROW_FORMAT = COMPACT; -ALTER TABLE sys_notice ADD INDEX message_key(`key`, site_id); +ALTER TABLE sys_notice +ADD INDEX message_key (`key`, site_id); +-- +-- `ns_sys_menu` +-- CREATE TABLE sys_menu ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '菜单ID', + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '菜单ID', app_type varchar(255) NOT NULL DEFAULT 'admin' COMMENT '应用类型', menu_name varchar(32) NOT NULL DEFAULT '' COMMENT '菜单名称', menu_key varchar(255) NOT NULL DEFAULT '' COMMENT '菜单标识(菜单输入,接口自动生成)', @@ -357,26 +410,32 @@ CREATE TABLE sys_menu ( view_path varchar(255) NOT NULL DEFAULT '' COMMENT '菜单文件地址', methods varchar(10) NOT NULL DEFAULT '' COMMENT '提交方式POST GET PUT DELETE', sort tinyint(4) NOT NULL DEFAULT 1 COMMENT '排序', - status tinyint(4) UNSIGNED NOT NULL DEFAULT 1 COMMENT '正常,禁用(禁用后不允许访问)', + status tinyint(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT '正常,禁用(禁用后不允许访问)', is_show tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否显示', create_time int(11) NOT NULL DEFAULT 0, delete_time int(11) NOT NULL DEFAULT 0, - addon VARCHAR(255) NOT NULL DEFAULT '' COMMENT '所属插件', + addon varchar(255) NOT NULL DEFAULT '' COMMENT '所属插件', PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 406, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '菜单表', ROW_FORMAT = COMPACT; -ALTER TABLE sys_menu ADD INDEX is_show (is_show); +ALTER TABLE sys_menu +ADD INDEX is_show (is_show); -ALTER TABLE sys_menu ADD INDEX menu_key (menu_key (191), app_type (191)); - -ALTER TABLE sys_menu ADD INDEX parent_key (parent_key (191)); +ALTER TABLE sys_menu +ADD INDEX menu_key (menu_key (191), app_type (191)); +ALTER TABLE sys_menu +ADD INDEX parent_key (parent_key (191)); +-- +-- `ns_sys_cron_task` +-- CREATE TABLE sys_cron_task ( id int(11) NOT NULL AUTO_INCREMENT, site_id int(11) NOT NULL DEFAULT 0, @@ -398,31 +457,38 @@ CREATE TABLE sys_cron_task ( PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 8192, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = ' 系统任务'; - +-- +-- `ns_sys_config` +-- CREATE TABLE sys_config ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', config_key varchar(255) NOT NULL DEFAULT '' COMMENT '配置项关键字', value text DEFAULT NULL COMMENT '配置值json', status tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否启用 1启用 0不启用', create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', update_time int(11) NOT NULL DEFAULT 0 COMMENT '修改时间', - addon VARCHAR(255) NOT NULL DEFAULT '' COMMENT '所属插件', + addon varchar(255) NOT NULL DEFAULT '' COMMENT '所属插件', PRIMARY KEY (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 910, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '系统配置表', ROW_FORMAT = COMPACT; -ALTER TABLE sys_config ADD INDEX config_key (config_key (191), site_id); - +ALTER TABLE sys_config +ADD INDEX config_key (config_key (191), site_id); +-- +-- `ns_sys_attachment_category` +-- CREATE TABLE sys_attachment_category ( id int(11) NOT NULL AUTO_INCREMENT, site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', @@ -435,16 +501,21 @@ CREATE TABLE sys_attachment_category ( UNIQUE INDEX id (id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 3276, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '附件分类表', ROW_FORMAT = COMPACT; -ALTER TABLE sys_attachment_category ADD INDEX pid (pid); - -ALTER TABLE sys_attachment_category ADD INDEX sort (sort); +ALTER TABLE sys_attachment_category +ADD INDEX pid (pid); +ALTER TABLE sys_attachment_category +ADD INDEX sort (sort); +-- +-- `ns_sys_attachment` +-- CREATE TABLE sys_attachment ( att_id int(11) NOT NULL AUTO_INCREMENT, site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', @@ -462,20 +533,26 @@ CREATE TABLE sys_attachment ( PRIMARY KEY (att_id) ) ENGINE = INNODB, +AVG_ROW_LENGTH = 702, CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '附件管理表', ROW_FORMAT = COMPACT; -ALTER TABLE sys_attachment ADD INDEX cate_id (cate_id); +ALTER TABLE sys_attachment +ADD INDEX cate_id (cate_id); -ALTER TABLE sys_attachment ADD INDEX create_time (create_time); - -ALTER TABLE sys_attachment ADD INDEX site_id (site_id); +ALTER TABLE sys_attachment +ADD INDEX create_time (create_time); +ALTER TABLE sys_attachment +ADD INDEX site_id (site_id); +-- +-- `ns_sys_area` +-- CREATE TABLE sys_area ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT, pid int(11) NOT NULL DEFAULT 0 COMMENT '父级', name varchar(50) NOT NULL DEFAULT '' COMMENT '名称', shortname varchar(30) NOT NULL DEFAULT '' COMMENT '简称', @@ -493,15 +570,869 @@ CHARACTER SET utf8mb4, COLLATE utf8mb4_general_ci, COMMENT = '地址表'; -ALTER TABLE sys_area ADD INDEX area (name, shortname); +ALTER TABLE sys_area +ADD INDEX area (name, shortname); -ALTER TABLE sys_area ADD INDEX level (level, sort, status); +ALTER TABLE sys_area +ADD INDEX level (level, sort, status); -ALTER TABLE sys_area ADD INDEX longitude (longitude, latitude); +ALTER TABLE sys_area +ADD INDEX longitude (longitude, latitude); -ALTER TABLE sys_area ADD INDEX pid (pid); +ALTER TABLE sys_area +ADD INDEX pid (pid); +-- +-- `ns_sys_agreement` +-- +CREATE TABLE sys_agreement ( + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + agreement_key varchar(255) NOT NULL DEFAULT '' COMMENT '协议关键字', + title varchar(255) NOT NULL DEFAULT '' COMMENT '协议标题', + content text DEFAULT NULL COMMENT '协议内容', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '修改时间', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 6553, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '协议表'; +ALTER TABLE sys_agreement +ADD INDEX agreement_key (agreement_key); + +ALTER TABLE sys_agreement +ADD INDEX site_id (site_id); + +-- +-- `ns_site_group` +-- +CREATE TABLE site_group ( + group_id int(11) NOT NULL AUTO_INCREMENT COMMENT '分组ID', + group_name varchar(255) NOT NULL DEFAULT '' COMMENT '分组名称', + group_desc text DEFAULT NULL COMMENT '分组介绍', + group_roles text DEFAULT NULL COMMENT '分组权限', + app_type varchar(255) NOT NULL DEFAULT '' COMMENT '应用类型', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + PRIMARY KEY (group_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 2048, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '店铺分组(分组权限)'; + +-- +-- `ns_site` +-- +CREATE TABLE site ( + site_id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + site_name varchar(50) NOT NULL DEFAULT '' COMMENT '站点名称', + group_id int(11) NOT NULL DEFAULT 0 COMMENT '分组ID(0:不限制)', + keywords varchar(255) NOT NULL DEFAULT '' COMMENT '关键字', + app_type varchar(50) NOT NULL DEFAULT 'admin' COMMENT '站点类型', + logo varchar(255) NOT NULL DEFAULT '' COMMENT '站点logo', + `desc` varchar(255) NOT NULL DEFAULT '' COMMENT '简介', + status tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态 1-正常 0-体验期 2-已到期', + latitude varchar(255) NOT NULL DEFAULT '' COMMENT '纬度', + longitude varchar(255) NOT NULL DEFAULT '' COMMENT '经度', + province_id int(11) NOT NULL DEFAULT 0 COMMENT '省', + city_id int(11) NOT NULL DEFAULT 0 COMMENT '市', + district_id int(11) NOT NULL DEFAULT 0 COMMENT '区', + address varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址', + full_address varchar(255) NOT NULL DEFAULT '' COMMENT '完整地址', + phone varchar(255) NOT NULL DEFAULT '' COMMENT '客服电话', + business_hours varchar(255) NOT NULL DEFAULT '' COMMENT '营业时间', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + expire_time int(11) NOT NULL DEFAULT 0 COMMENT '到期时间(如果是0 无限期)', + front_end_name varchar(50) NOT NULL DEFAULT '' COMMENT '前台名称', + front_end_logo varchar(255) NOT NULL DEFAULT '' COMMENT '前台logo', + icon varchar(255) NOT NULL DEFAULT '' COMMENT '网站图标', + member_no varchar(255) NOT NULL DEFAULT '0' COMMENT '最大会员码值', + PRIMARY KEY (site_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 1365, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '站点表', +ROW_FORMAT = COMPACT; + +ALTER TABLE site +ADD INDEX create_time (create_time); + +ALTER TABLE site +ADD INDEX group_id (group_id); + +-- +-- `ns_pay_transfer` +-- +CREATE TABLE pay_transfer ( + id int(11) NOT NULL AUTO_INCREMENT, + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + trade_type varchar(255) NOT NULL DEFAULT '' COMMENT '业务类型', + transfer_no varchar(50) NOT NULL DEFAULT '' COMMENT '转账单号', + main_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', + main_type varchar(255) NOT NULL DEFAULT '' COMMENT '主体类型', + transfer_type varchar(20) NOT NULL DEFAULT '0' COMMENT '转账类型', + transfer_realname varchar(50) NOT NULL DEFAULT '' COMMENT '联系人名称', + transfer_mobile varchar(11) NOT NULL DEFAULT '' COMMENT '手机号', + transfer_bank varchar(255) NOT NULL DEFAULT '' COMMENT '银行名称', + transfer_account varchar(255) NOT NULL DEFAULT '' COMMENT '收款账号', + transfer_voucher varchar(255) NOT NULL DEFAULT '' COMMENT '凭证', + transfer_remark varchar(255) NOT NULL DEFAULT '' COMMENT '凭证说明', + transfer_fail_reason varchar(255) NOT NULL DEFAULT '' COMMENT '失败原因', + transfer_status varchar(20) NOT NULL DEFAULT '' COMMENT '转账状态', + money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '转账金额', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '申请时间', + transfer_time int(11) NOT NULL DEFAULT 0 COMMENT '转账时间', + update_time int(11) NOT NULL DEFAULT 0, + openid varchar(50) NOT NULL DEFAULT '', + remark varchar(255) NOT NULL, + batch_id varchar(500) NOT NULL DEFAULT '' COMMENT '转账批次id', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 3276, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '转账表'; + +ALTER TABLE pay_transfer +ADD INDEX member_withdraw_apply_time (create_time); + +ALTER TABLE pay_transfer +ADD INDEX member_withdraw_audit_time (transfer_time); + +ALTER TABLE pay_transfer +ADD INDEX member_withdraw_site_id (site_id, main_id); + +ALTER TABLE pay_transfer +ADD INDEX member_withdraw_status (transfer_status); + +-- +-- `ns_pay_refund` +-- +CREATE TABLE pay_refund ( + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + refund_no varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '退款单号', + out_trade_no varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付流水号', + type varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付方式', + channel varchar(50) NOT NULL DEFAULT '' COMMENT '支付渠道', + money decimal(10, 2) NOT NULL COMMENT '支付金额', + reason varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '退款原因', + status varchar(255) NOT NULL DEFAULT '0' COMMENT '支付状态(0.待退款 1. 退款中中 2. 已退款 -1已关闭)', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + refund_time int(11) NOT NULL DEFAULT 0 COMMENT '支付时间', + close_time int(11) NOT NULL DEFAULT 0 COMMENT '关闭时间', + fail_reason varchar(255) NOT NULL COMMENT '失败原因', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 5461, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '支付记录表'; + +-- +-- `ns_pay_channel` +-- +CREATE TABLE pay_channel ( + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + type varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付类型', + channel varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付渠道', + config text NOT NULL COMMENT '支付配置', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '修改时间', + status int(11) NOT NULL DEFAULT 0 COMMENT '是否启用', + sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 496, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '支付渠道配置表'; + +-- +-- `ns_pay` +-- +CREATE TABLE pay ( + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + main_id int(11) NOT NULL DEFAULT 0 COMMENT '支付会员id', + out_trade_no varchar(255) NOT NULL DEFAULT '' COMMENT '支付流水号', + trade_type varchar(255) NOT NULL DEFAULT '' COMMENT '业务类型', + trade_no varchar(255) NOT NULL DEFAULT '' COMMENT '交易单号', + body varchar(1000) NOT NULL DEFAULT '' COMMENT '支付主体', + money decimal(10, 2) NOT NULL COMMENT '支付金额', + voucher varchar(255) NOT NULL DEFAULT '' COMMENT '支付票据', + status int(11) NOT NULL DEFAULT 0 COMMENT '支付状态(0.待支付 1. 支付中 2. 已支付 -1已取消)', + json varchar(255) NOT NULL DEFAULT '' COMMENT '支付扩展用支付信息', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + pay_time int(11) NOT NULL DEFAULT 0 COMMENT '支付时间', + cancel_time int(11) NOT NULL DEFAULT 0 COMMENT '关闭时间', + type varchar(255) NOT NULL DEFAULT '' COMMENT '支付方式', + mch_id varchar(50) NOT NULL DEFAULT '' COMMENT '商户收款账号', + main_type varchar(255) NOT NULL DEFAULT '', + channel varchar(50) NOT NULL DEFAULT '' COMMENT '支付渠道', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 16384, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '支付记录表'; + +ALTER TABLE pay +ADD UNIQUE INDEX UK_ns_pay_out_trade_no (out_trade_no); + +-- +-- `ns_order_log` +-- +CREATE TABLE order_log ( + id int(11) NOT NULL AUTO_INCREMENT, + order_id int(11) NOT NULL DEFAULT 0 COMMENT '订单id', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + action varchar(255) NOT NULL DEFAULT '' COMMENT '操作内容', + uid int(11) NOT NULL DEFAULT 0 COMMENT '操作人id', + nick_name varchar(50) NOT NULL DEFAULT '' COMMENT '操作人名称', + order_status int(11) NOT NULL DEFAULT 0 COMMENT '订单状态,操作后', + action_way bigint(20) NOT NULL DEFAULT 2 COMMENT '操作类型1买家2卖家 3 系统任务', + order_status_name varchar(255) NOT NULL DEFAULT '' COMMENT '订单状态名称,操作后', + action_time int(11) NOT NULL DEFAULT 0 COMMENT '操作时间', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 223, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '订单操作记录表', +ROW_FORMAT = COMPACT; + +-- +-- `ns_order_item_refund` +-- +CREATE TABLE order_item_refund ( + refund_id int(11) NOT NULL AUTO_INCREMENT, + order_item_id int(11) NOT NULL DEFAULT 0 COMMENT '订单id', + order_id int(11) NOT NULL DEFAULT 0 COMMENT '订单id', + order_no varchar(255) NOT NULL DEFAULT '' COMMENT '订单编号', + refund_no varchar(255) NOT NULL DEFAULT '0' COMMENT '退款单号', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + member_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', + num decimal(10, 3) NOT NULL DEFAULT 0.000 COMMENT '退货数量', + money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '总退款', + status int(11) NOT NULL DEFAULT 0 COMMENT '退款状态', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + audit_time int(11) NOT NULL DEFAULT 0 COMMENT '审核时间', + transfer_time int(11) NOT NULL DEFAULT 0 COMMENT '转账时间', + item_type varchar(255) NOT NULL DEFAULT '' COMMENT '项目类型', + PRIMARY KEY (refund_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 16384, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '订单退款表', +ROW_FORMAT = COMPACT; + +-- +-- `ns_order_item` +-- +CREATE TABLE order_item ( + order_item_id int(11) NOT NULL AUTO_INCREMENT, + order_id int(11) NOT NULL DEFAULT 0 COMMENT '订单id', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + member_id int(11) NOT NULL DEFAULT 0 COMMENT '购买会员id', + item_id int(11) NOT NULL DEFAULT 0 COMMENT '项目id', + item_type varchar(255) NOT NULL DEFAULT '' COMMENT '项目类型', + item_name varchar(400) NOT NULL DEFAULT '' COMMENT '项目名称', + item_image varchar(2000) NOT NULL DEFAULT '' COMMENT '项目图片', + price decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '项目单价', + num decimal(10, 3) NOT NULL DEFAULT 0.000 COMMENT '购买数量', + item_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '项目总价', + is_refund int(11) NOT NULL DEFAULT 0 COMMENT '是否退款', + refund_no varchar(255) NOT NULL DEFAULT '' COMMENT '退款编号', + refund_status int(11) NOT NULL DEFAULT 0 COMMENT '退款状态', + create_time int(11) NOT NULL DEFAULT 0, + PRIMARY KEY (order_item_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 16384, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '订单商品表', +ROW_FORMAT = COMPACT; + +-- +-- `ns_order` +-- +CREATE TABLE `order` ( + order_id int(11) NOT NULL AUTO_INCREMENT, + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + order_no varchar(50) NOT NULL DEFAULT '' COMMENT '订单编号', + order_from varchar(55) NOT NULL DEFAULT '' COMMENT '订单来源', + order_type varchar(50) NOT NULL DEFAULT '' COMMENT '订单类型', + out_trade_no varchar(50) NOT NULL DEFAULT '' COMMENT '支付流水号', + order_status int(11) NOT NULL DEFAULT 0 COMMENT '订单状态', + refund_status int(11) NOT NULL DEFAULT 0 COMMENT '退款状态', + member_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', + ip varchar(20) NOT NULL DEFAULT '' COMMENT '会员ip', + member_message varchar(50) NOT NULL DEFAULT '' COMMENT '会员留言信息', + order_item_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '订单项目金额', + order_discount_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '订单优惠金额', + order_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '订单金额', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + pay_time int(11) NOT NULL DEFAULT 0 COMMENT '订单支付时间', + close_time int(11) NOT NULL DEFAULT 0 COMMENT '订单关闭时间', + is_delete int(11) NOT NULL DEFAULT 0 COMMENT '是否删除(针对后台)', + is_enable_refund int(11) NOT NULL DEFAULT 0 COMMENT '是否允许退款', + remark varchar(255) NOT NULL DEFAULT '' COMMENT '商家留言', + invoice_id int(11) NOT NULL DEFAULT 0 COMMENT '发票id,0表示不开发票', + close_reason varchar(255) NOT NULL DEFAULT '' COMMENT '关闭原因', + PRIMARY KEY (order_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 16384, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '订单表', +ROW_FORMAT = COMPACT; + +-- +-- `ns_member_level` +-- +CREATE TABLE member_level ( + level_id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '会员等级', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + level_name varchar(50) NOT NULL DEFAULT '' COMMENT '等级名称', + growth decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '所需成长值', + remark varchar(255) NOT NULL DEFAULT '' COMMENT '备注', + status int(11) NOT NULL DEFAULT 1 COMMENT '状态 0已禁用1已启用', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + PRIMARY KEY (level_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 16384, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '会员等级', +ROW_FORMAT = COMPACT; + +ALTER TABLE member_level +ADD INDEX site_id (site_id); + +ALTER TABLE member_level +ADD INDEX status (status); + +-- +-- `ns_member_label` +-- +CREATE TABLE member_label ( + label_id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '标签id', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + label_name varchar(50) NOT NULL DEFAULT '' COMMENT '标签名称', + memo varchar(1000) NOT NULL DEFAULT '' COMMENT '备注', + sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + PRIMARY KEY (label_id), + INDEX label_id (label_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 8192, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '会员标签', +ROW_FORMAT = COMPACT; + +ALTER TABLE member_label +ADD INDEX site_id (site_id); + +ALTER TABLE member_label +ADD INDEX sort (sort); + +-- +-- `ns_member_cash_out_account` +-- +CREATE TABLE member_cash_out_account ( + account_id int(11) NOT NULL AUTO_INCREMENT, + site_id int(11) NOT NULL COMMENT '站点id', + member_id int(11) NOT NULL COMMENT '会员id', + account_type varchar(255) NOT NULL DEFAULT '' COMMENT '账户类型', + bank_name varchar(255) NOT NULL DEFAULT '' COMMENT '银行名称', + realname varchar(255) NOT NULL DEFAULT '' COMMENT '真实名称', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '修改时间', + account_no varchar(255) NOT NULL DEFAULT '' COMMENT '提现账户', + PRIMARY KEY (account_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 8192, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '会员提现账户'; + +-- +-- `ns_member_cash_out` +-- +CREATE TABLE member_cash_out ( + id int(11) NOT NULL AUTO_INCREMENT, + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + cash_out_no varchar(50) NOT NULL DEFAULT '' COMMENT '提现交易号', + member_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', + account_type varchar(255) NOT NULL DEFAULT 'money' COMMENT '提现账户类型', + transfer_type varchar(20) NOT NULL DEFAULT '0' COMMENT '转账提现类型', + transfer_realname varchar(50) NOT NULL DEFAULT '' COMMENT '联系人名称', + transfer_mobile varchar(11) NOT NULL DEFAULT '' COMMENT '手机号', + transfer_bank varchar(255) NOT NULL DEFAULT '' COMMENT '银行名称', + transfer_account varchar(255) NOT NULL DEFAULT '' COMMENT '收款账号', + transfer_fail_reason varchar(255) NOT NULL DEFAULT '' COMMENT '失败原因', + transfer_status varchar(20) NOT NULL DEFAULT '' COMMENT '转账状态', + transfer_time int(11) NOT NULL DEFAULT 0 COMMENT '转账时间', + apply_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现申请金额', + rate decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现手续费比率', + service_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现手续费', + money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现到账金额', + audit_time int(11) NOT NULL DEFAULT 0 COMMENT '审核时间', + status int(11) NOT NULL DEFAULT 0 COMMENT '状态1待审核2.待转账3已转账 -1拒绝 -2 已取消', + remark varchar(100) NOT NULL DEFAULT '' COMMENT '备注', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '申请时间', + refuse_reason varchar(100) NOT NULL DEFAULT '' COMMENT '拒绝理由', + update_time int(11) NOT NULL DEFAULT 0, + transfer_no varchar(50) NOT NULL DEFAULT '' COMMENT '转账单号', + cancel_time int(11) NOT NULL DEFAULT 0 COMMENT '取消时间', + final_transfer_type varchar(255) NOT NULL DEFAULT '' COMMENT '转账方式', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 297, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '会员提现表'; + +ALTER TABLE member_cash_out +ADD INDEX member_withdraw_apply_time (create_time); + +ALTER TABLE member_cash_out +ADD INDEX member_withdraw_audit_time (audit_time); + +ALTER TABLE member_cash_out +ADD INDEX member_withdraw_site_id (site_id, member_id); + +ALTER TABLE member_cash_out +ADD INDEX member_withdraw_status (status); + +ALTER TABLE member_cash_out +ADD INDEX member_withdraw_withdraw_no (cash_out_no); + +-- +-- `ns_member_address` +-- +CREATE TABLE member_address ( + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + member_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + name varchar(255) NOT NULL DEFAULT '' COMMENT '用户姓名', + mobile varchar(255) NOT NULL DEFAULT '' COMMENT '手机', + telephone varchar(255) NOT NULL DEFAULT '' COMMENT '联系电话', + province_id int(11) NOT NULL DEFAULT 0 COMMENT '省id', + city_id int(11) NOT NULL DEFAULT 0 COMMENT '市id', + district_id int(11) NOT NULL DEFAULT 0 COMMENT '区县id', + community_id int(11) NOT NULL DEFAULT 0 COMMENT '社区id', + address varchar(255) NOT NULL DEFAULT '' COMMENT '地址信息', + full_address varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址信息', + longitude varchar(255) NOT NULL DEFAULT '' COMMENT '经度', + latitude varchar(255) NOT NULL DEFAULT '' COMMENT '纬度', + is_default tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否是默认地址', + type int(11) NOT NULL DEFAULT 1 COMMENT '地址类型 1 普通地址 2 定位地址', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 16384, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '会员收货地址', +ROW_FORMAT = COMPACT; + +ALTER TABLE member_address +ADD INDEX IDX_member_address (member_id, site_id); + +-- +-- `ns_member_account_log` +-- +CREATE TABLE member_account_log ( + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + member_id int(11) NOT NULL DEFAULT 0 COMMENT '用户id', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + account_type varchar(255) NOT NULL DEFAULT 'point' COMMENT '账户类型', + account_data decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '账户数据', + account_sum decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '变动后的账户余额', + from_type varchar(255) NOT NULL DEFAULT '' COMMENT '来源类型', + related_id int(11) NOT NULL DEFAULT 0 COMMENT '关联Id', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + memo varchar(255) NOT NULL DEFAULT '' COMMENT '备注信息', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 4096, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '会员账单表', +ROW_FORMAT = COMPACT; + +ALTER TABLE member_account_log +ADD INDEX account_type (account_type (191)); + +ALTER TABLE member_account_log +ADD INDEX create_time (create_time); + +ALTER TABLE member_account_log +ADD INDEX from_type (from_type (191)); + +ALTER TABLE member_account_log +ADD INDEX member_id (member_id); + +-- +-- `ns_member` +-- +CREATE TABLE member ( + member_id int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', + member_no varchar(255) NOT NULL DEFAULT '' COMMENT '会员编码', + pid int(11) NOT NULL DEFAULT 0 COMMENT '推广会员id', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + username varchar(255) DEFAULT '' COMMENT '会员用户名', + mobile varchar(20) NOT NULL DEFAULT '' COMMENT '手机号', + password varchar(255) NOT NULL DEFAULT '' COMMENT '会员密码', + nickname varchar(50) NOT NULL DEFAULT '' COMMENT '会员昵称', + headimg varchar(1000) NOT NULL DEFAULT '' COMMENT '会员头像', + member_level int(11) NOT NULL DEFAULT 0 COMMENT '会员等级', + member_label varchar(255) NOT NULL DEFAULT '' COMMENT '会员标签', + wx_openid varchar(255) NOT NULL DEFAULT '' COMMENT '微信用户openid', + weapp_openid varchar(255) NOT NULL DEFAULT '' COMMENT '微信小程序openid', + wx_unionid varchar(255) NOT NULL DEFAULT '' COMMENT '微信unionid', + ali_openid varchar(255) NOT NULL DEFAULT '' COMMENT '支付宝账户id', + douyin_openid varchar(255) NOT NULL DEFAULT '' COMMENT '抖音小程序openid', + register_channel varchar(255) NOT NULL DEFAULT 'H5' COMMENT '注册来源', + register_type varchar(255) NOT NULL DEFAULT '' COMMENT '注册方式', + login_ip varchar(255) NOT NULL DEFAULT '' COMMENT '当前登录ip', + login_type varchar(255) NOT NULL DEFAULT 'h5' COMMENT '当前登录的操作终端类型', + login_channel varchar(255) NOT NULL DEFAULT '', + login_count int(11) NOT NULL DEFAULT 0 COMMENT '登录次数', + login_time int(11) NOT NULL DEFAULT 0 COMMENT '当前登录时间', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '注册时间', + last_visit_time int(11) NOT NULL DEFAULT 0 COMMENT '最后访问时间', + last_consum_time int(11) NOT NULL DEFAULT 0 COMMENT '最后消费时间', + sex tinyint(4) NOT NULL DEFAULT 0 COMMENT '性别 0保密 1男 2女', + status tinyint(4) NOT NULL DEFAULT 1 COMMENT '用户状态 用户状态默认为1', + birthday varchar(20) NOT NULL DEFAULT '' COMMENT '出生日期', + point int(11) NOT NULL DEFAULT 0 COMMENT '可用积分', + point_get int(11) NOT NULL DEFAULT 0 COMMENT '累计获取积分', + balance decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '可用余额', + balance_get decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '累计获取余额', + money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '可用余额(可提现)', + money_get decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '累计获取余额(可提现)', + money_cash_outing decimal(10, 2) NOT NULL COMMENT '提现中余额(可提现)', + growth int(11) NOT NULL DEFAULT 0 COMMENT '成长值', + growth_get int(11) NOT NULL DEFAULT 0 COMMENT '累计获得成长值', + commission decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '当前佣金', + commission_get decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '佣金获取', + commission_cash_outing decimal(10, 2) NOT NULL COMMENT '提现中佣金', + is_member tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否是会员', + member_time int(11) NOT NULL DEFAULT 0 COMMENT '成为会员时间', + is_del tinyint(4) NOT NULL DEFAULT 0 COMMENT '0正常 1已删除', + province_id int(11) NOT NULL DEFAULT 0 COMMENT '省id', + city_id int(11) NOT NULL DEFAULT 0 COMMENT '市id', + district_id int(11) NOT NULL DEFAULT 0 COMMENT '区县id', + address varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址', + location varchar(255) NOT NULL DEFAULT '' COMMENT '定位地址', + delete_time int(11) NOT NULL DEFAULT 0 COMMENT '删除时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '修改时间', + PRIMARY KEY (member_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 4096, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '会员表', +ROW_FORMAT = COMPACT; + +ALTER TABLE member +ADD INDEX mobile (mobile); + +ALTER TABLE member +ADD INDEX password (password (191)); + +ALTER TABLE member +ADD INDEX site_id (site_id); + +ALTER TABLE member +ADD INDEX username (username (191)); + +ALTER TABLE member +ADD INDEX weapp_openid (weapp_openid (191)); + +ALTER TABLE member +ADD INDEX wx_openid (wx_openid (191)); + +ALTER TABLE member +ADD INDEX wx_unionid (wx_unionid (191)); + +-- +-- `ns_jobs_failed` +-- +CREATE TABLE jobs_failed ( + id int(11) NOT NULL AUTO_INCREMENT, + `connection` text NOT NULL, + queue text NOT NULL, + payload longtext NOT NULL, + exception longtext NOT NULL, + fail_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) +ENGINE = INNODB, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '消息队列任务失败记录表'; + +-- +-- `ns_jobs` +-- +CREATE TABLE jobs ( + id int(11) NOT NULL AUTO_INCREMENT, + queue varchar(255) NOT NULL, + payload longtext NOT NULL, + attempts tinyint(3) UNSIGNED NOT NULL, + reserved tinyint(3) UNSIGNED NOT NULL, + reserve_time int(10) UNSIGNED DEFAULT NULL, + available_time int(10) UNSIGNED NOT NULL, + create_time int(10) UNSIGNED NOT NULL, + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 5461, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '消息队列任务表'; + +-- +-- `ns_generate_table` +-- +CREATE TABLE generate_table ( + id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + table_name varchar(255) NOT NULL DEFAULT '' COMMENT '表名', + table_content varchar(255) NOT NULL DEFAULT '' COMMENT '描述前缀', + module_name varchar(255) NOT NULL DEFAULT '' COMMENT '模块名', + class_name varchar(255) NOT NULL DEFAULT '' COMMENT '类名前缀', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', + edit_type int(11) NOT NULL DEFAULT 1 COMMENT '编辑方式 1-弹框 2-新页面', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 780, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '代码生成表'; + +-- +-- `ns_generate_column` +-- +CREATE TABLE generate_column ( + id int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', + table_id int(11) NOT NULL DEFAULT 0 COMMENT '表id', + column_name varchar(100) NOT NULL DEFAULT '' COMMENT '字段名称', + column_comment varchar(300) NOT NULL DEFAULT '' COMMENT '字段描述', + column_type varchar(100) NOT NULL DEFAULT '' COMMENT '字段类型', + is_required tinyint(4) DEFAULT 0 COMMENT '是否必填 0-非必填 1-必填', + is_pk tinyint(4) DEFAULT 0 COMMENT '是否为主键 0-不是 1-是', + is_insert tinyint(4) DEFAULT 0 COMMENT '是否为插入字段 0-不是 1-是', + is_update tinyint(4) DEFAULT 0 COMMENT '是否为更新字段 0-不是 1-是', + is_lists tinyint(4) DEFAULT 1 COMMENT '是否为列表字段 0-不是 1-是', + is_query tinyint(4) DEFAULT 1 COMMENT '是否为查询字段 0-不是 1-是', + is_search tinyint(4) DEFAULT 1 COMMENT '是否搜索字段', + query_type varchar(100) DEFAULT '=' COMMENT '查询类型', + view_type varchar(100) DEFAULT 'input' COMMENT '显示类型', + dict_type varchar(255) DEFAULT '' COMMENT '字典类型', + create_time int(11) NOT NULL COMMENT '创建时间', + update_time int(11) DEFAULT NULL COMMENT '修改时间', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 321, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '代码生成表字段信息表'; + +-- +-- `ns_diy_route` +-- +CREATE TABLE diy_route ( + id int(11) NOT NULL AUTO_INCREMENT, + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + title varchar(255) NOT NULL DEFAULT '' COMMENT '页面名称', + name varchar(255) NOT NULL DEFAULT '' COMMENT '页面标识', + page varchar(255) NOT NULL DEFAULT '' COMMENT '页面路径', + share varchar(1000) NOT NULL DEFAULT '' COMMENT '分享内容', + is_share int(11) NOT NULL DEFAULT 0 COMMENT '是否支持分享', + sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 2730, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '自定义路由'; + +-- +-- `ns_diy_page` +-- +CREATE TABLE diy_page ( + id int(11) NOT NULL AUTO_INCREMENT, + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', + title varchar(255) NOT NULL DEFAULT '' COMMENT '页面名称', + name varchar(255) NOT NULL DEFAULT '' COMMENT '页面标识', + type varchar(255) NOT NULL DEFAULT '' COMMENT '页面模板', + value longtext DEFAULT NULL COMMENT '页面数据,json格式', + is_default int(11) NOT NULL DEFAULT 0 COMMENT '是否默认页面,1:是,0:否', + share varchar(1000) NOT NULL DEFAULT '' COMMENT '分享内容', + visit_count int(11) NOT NULL DEFAULT 0 COMMENT '访问量', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 5461, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '自定义页面'; + +-- +-- `ns_article_category` +-- +CREATE TABLE article_category ( + category_id int(11) NOT NULL AUTO_INCREMENT COMMENT '文章分类id', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点ID', + name varchar(255) NOT NULL DEFAULT '' COMMENT '分类名称', + sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', + is_show tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否显示:1-是;0-否', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + PRIMARY KEY (category_id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 8192, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '文章分类表'; + +ALTER TABLE article_category +ADD INDEX create_time (create_time); + +ALTER TABLE article_category +ADD INDEX is_show (is_show); + +ALTER TABLE article_category +ADD INDEX site_id (site_id); + +ALTER TABLE article_category +ADD INDEX sort (sort); + +-- +-- `ns_article` +-- +CREATE TABLE article ( + id int(11) NOT NULL AUTO_INCREMENT COMMENT '文章id', + category_id int(11) NOT NULL COMMENT '文章分类', + site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点ID', + title varchar(255) NOT NULL COMMENT '文章标题', + intro varchar(255) NOT NULL DEFAULT '' COMMENT '简介', + summary varchar(255) NOT NULL DEFAULT '' COMMENT '文章摘要', + image varchar(128) NOT NULL DEFAULT '' COMMENT '文章图片', + author varchar(255) NOT NULL DEFAULT '' COMMENT '作者', + content text DEFAULT NULL COMMENT '文章内容', + visit int(11) NOT NULL DEFAULT 0 COMMENT '实际浏览量', + visit_virtual int(11) NOT NULL DEFAULT 0 COMMENT '虚拟浏览量', + is_show tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否显示:1-是.0-否', + sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + PRIMARY KEY (id) +) +ENGINE = INNODB, +AVG_ROW_LENGTH = 5461, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '文章表'; + +ALTER TABLE article +ADD INDEX IDX_article_category_id (category_id); + +ALTER TABLE article +ADD INDEX IDX_article_create_time (create_time); + +ALTER TABLE article +ADD INDEX IDX_article_is_show (is_show); + +ALTER TABLE article +ADD INDEX IDX_article_site_id (site_id); + +ALTER TABLE article +ADD INDEX IDX_ns_article_sort (sort); + +-- +-- `ns_addon_log` +-- +CREATE TABLE addon_log ( + id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + action varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '操作类型 install 安装 uninstall 卸载 update 更新', + `key` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件标识', + from_version varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '升级前的版本号', + to_version varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '升级后的版本号', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + PRIMARY KEY (id) +) +ENGINE = INNODB, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '插件日志表'; + +-- +-- `ns_addon` +-- +CREATE TABLE addon ( + id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + title varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件名称', + icon varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件图标', + `key` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件标识', + `desc` text CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '插件描述', + status tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态', + author varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '作者', + version varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '版本号', + create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', + install_time int(11) NOT NULL DEFAULT 0 COMMENT '安装时间', + update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', + cover varchar(255) NOT NULL DEFAULT '' COMMENT '封面', + PRIMARY KEY (id) +) +ENGINE = INNODB, +CHARACTER SET utf8mb4, +COLLATE utf8mb4_general_ci, +COMMENT = '插件表'; + +ALTER TABLE addon +ADD UNIQUE INDEX UK_title (title); + +-- +-- Dumping data for table ns_sys_area +-- INSERT INTO sys_area VALUES (110000, 0, '北京市', '北京', '116.40529', '39.904987', 1, 0, 1), (110100, 110000, '北京市', '北京', '116.40529', '39.904987', 2, 0, 1), @@ -4149,733 +5080,10 @@ INSERT INTO sys_area VALUES (460400499, 460400, '洋浦经济开发区', '洋浦经济开发区', '109.202064', '19.736941', 3, 0, 1), (460400500, 460400, '华南热作学院', '华南热作学院', '109.494073', '19.505382', 3, 0, 1); +INSERT INTO sys_user_role(id, uid, site_id, is_admin) VALUE +(1, 1, 0, 1); -CREATE TABLE sys_agreement ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - agreement_key varchar(255) NOT NULL DEFAULT '' COMMENT '协议关键字', - title varchar(255) NOT NULL DEFAULT '' COMMENT '协议标题', - content text DEFAULT NULL COMMENT '协议内容', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', - update_time int(11) NOT NULL DEFAULT 0 COMMENT '修改时间', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '协议表'; - -ALTER TABLE sys_agreement ADD INDEX agreement_key (agreement_key); - -ALTER TABLE sys_agreement ADD INDEX site_id (site_id); - - -CREATE TABLE site_group ( - group_id int(11) NOT NULL AUTO_INCREMENT COMMENT '分组ID', - group_name varchar(255) NOT NULL DEFAULT '' COMMENT '分组名称', - group_desc text DEFAULT NULL COMMENT '分组介绍', - group_roles text DEFAULT NULL COMMENT '分组权限', - app_type varchar(255) NOT NULL DEFAULT '' COMMENT '应用类型', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', - update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - PRIMARY KEY (group_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '店铺分组(分组权限)'; - - -CREATE TABLE site ( - site_id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - site_name varchar(50) NOT NULL DEFAULT '' COMMENT '站点名称', - group_id int(11) NOT NULL DEFAULT 0 COMMENT '分组ID(0:不限制)', - keywords varchar(255) NOT NULL DEFAULT '' COMMENT '关键字', - app_type varchar(50) NOT NULL DEFAULT 'admin' COMMENT '站点类型', - logo varchar(255) NOT NULL DEFAULT '' COMMENT '站点logo', - `desc` varchar(255) NOT NULL DEFAULT '' COMMENT '简介', - status tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态 1-正常 0-体验期 2-已到期', - latitude varchar(255) NOT NULL DEFAULT '' COMMENT '纬度', - longitude varchar(255) NOT NULL DEFAULT '' COMMENT '经度', - province_id int(11) NOT NULL DEFAULT 0 COMMENT '省', - city_id int(11) NOT NULL DEFAULT 0 COMMENT '市', - district_id int(11) NOT NULL DEFAULT 0 COMMENT '区', - address varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址', - full_address varchar(255) NOT NULL DEFAULT '' COMMENT '完整地址', - phone varchar(255) NOT NULL DEFAULT '' COMMENT '客服电话', - business_hours varchar(255) NOT NULL DEFAULT '' COMMENT '营业时间', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - expire_time int(11) NOT NULL DEFAULT 0 COMMENT '到期时间(如果是0 无限期)', - front_end_name VARCHAR(50) NOT NULL DEFAULT '' COMMENT '前台名称', - front_end_logo VARCHAR(255) NOT NULL DEFAULT '' COMMENT '前台logo', - icon VARCHAR(255) NOT NULL DEFAULT '' COMMENT '网站图标', - member_no VARCHAR(255) NOT NULL DEFAULT '0' COMMENT '最大会员码值', - PRIMARY KEY (site_id) -) -ENGINE = INNODB, -AUTO_INCREMENT = 2, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '站点表', -ROW_FORMAT = COMPACT; - -ALTER TABLE site ADD INDEX create_time (create_time); - -ALTER TABLE site ADD INDEX group_id (group_id); - - -CREATE TABLE pay_transfer ( - id int(11) NOT NULL AUTO_INCREMENT, - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - trade_type varchar(255) NOT NULL DEFAULT '' COMMENT '业务类型', - transfer_no varchar(50) NOT NULL DEFAULT '' COMMENT '转账单号', - main_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', - main_type varchar(255) NOT NULL DEFAULT '' COMMENT '主体类型', - transfer_type varchar(20) NOT NULL DEFAULT '0' COMMENT '转账类型', - transfer_realname varchar(50) NOT NULL DEFAULT '' COMMENT '联系人名称', - transfer_mobile varchar(11) NOT NULL DEFAULT '' COMMENT '手机号', - transfer_bank varchar(255) NOT NULL DEFAULT '' COMMENT '银行名称', - transfer_account varchar(255) NOT NULL DEFAULT '' COMMENT '收款账号', - transfer_voucher varchar(255) NOT NULL DEFAULT '' COMMENT '凭证', - transfer_remark varchar(255) NOT NULL DEFAULT '' COMMENT '凭证说明', - transfer_fail_reason varchar(255) NOT NULL DEFAULT '' COMMENT '失败原因', - transfer_status varchar(20) NOT NULL DEFAULT '' COMMENT '转账状态', - money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '转账金额', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '申请时间', - transfer_time int(11) NOT NULL DEFAULT 0 COMMENT '转账时间', - update_time int(11) NOT NULL DEFAULT 0, - openid varchar(50) NOT NULL DEFAULT '', - remark varchar(255) NOT NULL, - batch_id varchar(500) NOT NULL DEFAULT '' COMMENT '转账批次id', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '转账表'; - -ALTER TABLE pay_transfer ADD INDEX member_withdraw_apply_time (create_time); - -ALTER TABLE pay_transfer ADD INDEX member_withdraw_audit_time (transfer_time); - -ALTER TABLE pay_transfer ADD INDEX member_withdraw_site_id (site_id, main_id); - -ALTER TABLE pay_transfer ADD INDEX member_withdraw_status (transfer_status); - - -CREATE TABLE pay_refund ( - id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', - site_id INT(11) NOT NULL DEFAULT 0 COMMENT '站点id', - refund_no VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '退款单号', - out_trade_no VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付流水号', - type VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付方式', - channel VARCHAR(50) NOT NULL DEFAULT '' COMMENT '支付渠道', - money DECIMAL(10, 2) NOT NULL COMMENT '支付金额', - reason VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '退款原因', - status VARCHAR(255) NOT NULL DEFAULT '0' COMMENT '支付状态(0.待退款 1. 退款中中 2. 已退款 -1已关闭)', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - refund_time INT(11) NOT NULL DEFAULT 0 COMMENT '支付时间', - close_time INT(11) NOT NULL DEFAULT 0 COMMENT '关闭时间', - fail_reason VARCHAR(255) NOT NULL COMMENT '失败原因', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '支付记录表'; - - -CREATE TABLE pay_channel ( - id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', - site_id INT(11) NOT NULL DEFAULT 0 COMMENT '站点id', - type VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付类型', - channel VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '支付渠道', - config TEXT NOT NULL COMMENT '支付配置', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - update_time INT(11) NOT NULL DEFAULT 0 COMMENT '修改时间', - status INT(11) NOT NULL DEFAULT 0 COMMENT '是否启用', - sort INT(11) NOT NULL DEFAULT 0 COMMENT '排序', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '支付渠道配置表'; - -CREATE TABLE pay ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - main_id int(11) NOT NULL DEFAULT 0 COMMENT '支付会员id', - out_trade_no varchar(255) NOT NULL DEFAULT '' COMMENT '支付流水号', - trade_type varchar(255) NOT NULL DEFAULT '' COMMENT '业务类型', - trade_no varchar(255) NOT NULL DEFAULT '' COMMENT '交易单号', - body varchar(1000) NOT NULL DEFAULT '' COMMENT '支付主体', - money decimal(10, 2) NOT NULL COMMENT '支付金额', - voucher varchar(255) NOT NULL DEFAULT '' COMMENT '支付票据', - status int(11) NOT NULL DEFAULT 0 COMMENT '支付状态(0.待支付 1. 支付中 2. 已支付 -1已取消)', - json varchar(255) NOT NULL DEFAULT '' COMMENT '支付扩展用支付信息', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - pay_time int(11) NOT NULL DEFAULT 0 COMMENT '支付时间', - cancel_time int(11) NOT NULL DEFAULT 0 COMMENT '关闭时间', - type varchar(255) NOT NULL DEFAULT '' COMMENT '支付方式', - mch_id varchar(50) NOT NULL DEFAULT '' COMMENT '商户收款账号', - main_type varchar(255) NOT NULL DEFAULT '', - channel varchar(50) NOT NULL DEFAULT '' COMMENT '支付渠道', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8, -COLLATE utf8_general_ci, -COMMENT = '支付记录表'; - -ALTER TABLE pay -ADD UNIQUE INDEX UK_ns_pay_out_trade_no (out_trade_no); - - -CREATE TABLE order_log ( - id int(11) NOT NULL AUTO_INCREMENT, - order_id int(11) NOT NULL DEFAULT 0 COMMENT '订单id', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - action varchar(255) NOT NULL DEFAULT '' COMMENT '操作内容', - uid int(11) NOT NULL DEFAULT 0 COMMENT '操作人id', - nick_name varchar(50) NOT NULL DEFAULT '' COMMENT '操作人名称', - order_status int(11) NOT NULL DEFAULT 0 COMMENT '订单状态,操作后', - action_way bigint(20) NOT NULL DEFAULT 2 COMMENT '操作类型1买家2卖家 3 系统任务', - order_status_name varchar(255) NOT NULL DEFAULT '' COMMENT '订单状态名称,操作后', - action_time int(11) NOT NULL DEFAULT 0 COMMENT '操作时间', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '订单操作记录表', -ROW_FORMAT = COMPACT; - - -CREATE TABLE order_item_refund ( - refund_id INT(11) NOT NULL AUTO_INCREMENT, - order_item_id INT(11) NOT NULL DEFAULT 0 COMMENT '订单id', - order_id INT(11) NOT NULL DEFAULT 0 COMMENT '订单id', - order_no VARCHAR(255) NOT NULL DEFAULT '' COMMENT '订单编号', - refund_no VARCHAR(255) NOT NULL DEFAULT '0' COMMENT '退款单号', - site_id INT(11) NOT NULL DEFAULT 0 COMMENT '站点id', - member_id INT(11) NOT NULL DEFAULT 0 COMMENT '会员id', - num DECIMAL(10, 3) NOT NULL DEFAULT 0.000 COMMENT '退货数量', - money DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '总退款', - status INT(11) NOT NULL DEFAULT 0 COMMENT '退款状态', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - audit_time INT(11) NOT NULL DEFAULT 0 COMMENT '审核时间', - transfer_time INT(11) NOT NULL DEFAULT 0 COMMENT '转账时间', - item_type VARCHAR(255) NOT NULL DEFAULT '' COMMENT '项目类型', - PRIMARY KEY (refund_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '订单退款表'; - -CREATE TABLE order_item ( - order_item_id int(11) NOT NULL AUTO_INCREMENT, - order_id int(11) NOT NULL DEFAULT 0 COMMENT '订单id', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - member_id int(11) NOT NULL DEFAULT 0 COMMENT '购买会员id', - item_id int(11) NOT NULL DEFAULT 0 COMMENT '项目id', - item_type VARCHAR(255) NOT NULL DEFAULT '' COMMENT '项目类型', - item_name varchar(400) NOT NULL DEFAULT '' COMMENT '项目名称', - item_image varchar(2000) NOT NULL DEFAULT '' COMMENT '项目图片', - price decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '项目单价', - num decimal(10, 3) NOT NULL DEFAULT 0.000 COMMENT '购买数量', - item_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '项目总价', - is_refund int(11) NOT NULL DEFAULT 0 COMMENT '是否退款', - refund_no VARCHAR(255) NOT NULL DEFAULT '' COMMENT '退款编号', - refund_status int(11) NOT NULL DEFAULT 0 COMMENT '退款状态', - create_time int(11) NOT NULL DEFAULT 0, - PRIMARY KEY (order_item_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '订单商品表', -ROW_FORMAT = COMPACT; - - -CREATE TABLE `order` ( - order_id int(11) NOT NULL AUTO_INCREMENT, - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - order_no varchar(50) NOT NULL DEFAULT '' COMMENT '订单编号', - order_from varchar(55) NOT NULL DEFAULT '' COMMENT '订单来源', - order_type varchar(50) NOT NULL DEFAULT '' COMMENT '订单类型', - out_trade_no varchar(50) NOT NULL DEFAULT '' COMMENT '支付流水号', - order_status int(11) NOT NULL DEFAULT 0 COMMENT '订单状态', - refund_status int(11) NOT NULL DEFAULT 0 COMMENT '退款状态', - member_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', - ip varchar(20) NOT NULL DEFAULT '' COMMENT '会员ip', - member_message varchar(50) NOT NULL DEFAULT '' COMMENT '会员留言信息', - order_item_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '订单项目金额', - order_discount_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '订单优惠金额', - order_money decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '订单金额', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - pay_time int(11) NOT NULL DEFAULT 0 COMMENT '订单支付时间', - close_time int(11) NOT NULL DEFAULT 0 COMMENT '订单关闭时间', - is_delete int(11) NOT NULL DEFAULT 0 COMMENT '是否删除(针对后台)', - is_enable_refund int(11) NOT NULL DEFAULT 0 COMMENT '是否允许退款', - remark varchar(255) NOT NULL DEFAULT '' COMMENT '商家留言', - invoice_id int(11) NOT NULL DEFAULT 0 COMMENT '发票id,0表示不开发票', - close_reason varchar(255) NOT NULL DEFAULT '' COMMENT '关闭原因', - PRIMARY KEY (order_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '订单表', -ROW_FORMAT = COMPACT; - - -CREATE TABLE member_level ( - level_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '会员等级', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - level_name varchar(50) NOT NULL DEFAULT '' COMMENT '等级名称', - growth decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '所需成长值', - remark varchar(255) NOT NULL DEFAULT '' COMMENT '备注', - status int(11) NOT NULL DEFAULT 1 COMMENT '状态 0已禁用1已启用', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', - update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - PRIMARY KEY (level_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '会员等级', -ROW_FORMAT = COMPACT; - -ALTER TABLE member_level ADD INDEX site_id (site_id); - -ALTER TABLE member_level ADD INDEX status (status); - - -CREATE TABLE member_label ( - label_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '标签id', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - label_name varchar(50) NOT NULL DEFAULT '' COMMENT '标签名称', - memo varchar(1000) NOT NULL DEFAULT '' COMMENT '备注', - sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', - update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - PRIMARY KEY (label_id), - INDEX label_id (label_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '会员标签', -ROW_FORMAT = COMPACT; - -ALTER TABLE member_label ADD INDEX site_id (site_id); - -ALTER TABLE member_label ADD INDEX sort (sort); - - -CREATE TABLE member_cash_out_account ( - account_id INT(11) NOT NULL AUTO_INCREMENT, - site_id INT(11) NOT NULL COMMENT '站点id', - member_id INT(11) NOT NULL COMMENT '会员id', - account_type VARCHAR(255) NOT NULL DEFAULT '' COMMENT '账户类型', - bank_name VARCHAR(255) NOT NULL DEFAULT '' COMMENT '银行名称', - realname VARCHAR(255) NOT NULL DEFAULT '' COMMENT '真实名称', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - update_time INT(11) NOT NULL DEFAULT 0 COMMENT '修改时间', - account_no VARCHAR(255) NOT NULL DEFAULT '' COMMENT '提现账户', - PRIMARY KEY (account_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '会员提现账户'; - - -CREATE TABLE member_cash_out ( - id INT(11) NOT NULL AUTO_INCREMENT, - site_id INT(11) NOT NULL DEFAULT 0 COMMENT '站点id', - cash_out_no VARCHAR(50) NOT NULL DEFAULT '' COMMENT '提现交易号', - member_id INT(11) NOT NULL DEFAULT 0 COMMENT '会员id', - account_type VARCHAR(255) NOT NULL DEFAULT 'money' COMMENT '提现账户类型', - transfer_type VARCHAR(20) NOT NULL DEFAULT '0' COMMENT '转账提现类型', - transfer_realname VARCHAR(50) NOT NULL DEFAULT '' COMMENT '联系人名称', - transfer_mobile VARCHAR(11) NOT NULL DEFAULT '' COMMENT '手机号', - transfer_bank VARCHAR(255) NOT NULL DEFAULT '' COMMENT '银行名称', - transfer_account VARCHAR(255) NOT NULL DEFAULT '' COMMENT '收款账号', - transfer_fail_reason VARCHAR(255) NOT NULL DEFAULT '' COMMENT '失败原因', - transfer_status VARCHAR(20) NOT NULL DEFAULT '' COMMENT '转账状态', - transfer_time INT(11) NOT NULL DEFAULT 0 COMMENT '转账时间', - apply_money DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现申请金额', - rate DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现手续费比率', - service_money DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现手续费', - money DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '提现到账金额', - audit_time INT(11) NOT NULL DEFAULT 0 COMMENT '审核时间', - status INT(11) NOT NULL DEFAULT 0 COMMENT '状态1待审核2.待转账3已转账 -1拒绝 -2 已取消', - remark VARCHAR(100) NOT NULL DEFAULT '' COMMENT '备注', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '申请时间', - refuse_reason VARCHAR(100) NOT NULL DEFAULT '' COMMENT '拒绝理由', - update_time INT(11) NOT NULL DEFAULT 0, - transfer_no VARCHAR(50) NOT NULL DEFAULT '' COMMENT '转账单号', - cancel_time INT(11) NOT NULL DEFAULT 0 COMMENT '取消时间', - final_transfer_type VARCHAR(255) NOT NULL DEFAULT '' COMMENT '转账方式', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '会员提现表'; - -ALTER TABLE member_cash_out ADD INDEX member_withdraw_apply_time(create_time); - -ALTER TABLE member_cash_out ADD INDEX member_withdraw_audit_time(audit_time); - -ALTER TABLE member_cash_out ADD INDEX member_withdraw_site_id(site_id, member_id); - -ALTER TABLE member_cash_out ADD INDEX member_withdraw_status(status); - -ALTER TABLE member_cash_out ADD INDEX member_withdraw_withdraw_no(cash_out_no); - -CREATE TABLE member_address ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - member_id int(11) NOT NULL DEFAULT 0 COMMENT '会员id', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - name varchar(255) NOT NULL DEFAULT '' COMMENT '用户姓名', - mobile varchar(255) NOT NULL DEFAULT '' COMMENT '手机', - telephone varchar(255) NOT NULL DEFAULT '' COMMENT '联系电话', - province_id int(11) NOT NULL DEFAULT 0 COMMENT '省id', - city_id int(11) NOT NULL DEFAULT 0 COMMENT '市id', - district_id int(11) NOT NULL DEFAULT 0 COMMENT '区县id', - community_id int(11) NOT NULL DEFAULT 0 COMMENT '社区id', - address varchar(255) NOT NULL DEFAULT '' COMMENT '地址信息', - full_address varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址信息', - longitude varchar(255) NOT NULL DEFAULT '' COMMENT '经度', - latitude varchar(255) NOT NULL DEFAULT '' COMMENT '纬度', - is_default tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否是默认地址', - type int(11) NOT NULL DEFAULT 1 COMMENT '地址类型 1 普通地址 2 定位地址', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '会员收货地址', -ROW_FORMAT = COMPACT; - -ALTER TABLE member_address ADD INDEX IDX_member_address (member_id, site_id); - - -CREATE TABLE member_account_log ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - member_id int(11) NOT NULL DEFAULT 0 COMMENT '用户id', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - account_type varchar(255) NOT NULL DEFAULT 'point' COMMENT '账户类型', - account_data decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '账户数据', - account_sum DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '变动后的账户余额', - from_type varchar(255) NOT NULL DEFAULT '' COMMENT '来源类型', - related_id int(11) NOT NULL DEFAULT 0 COMMENT '关联Id', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - memo varchar(255) NOT NULL DEFAULT '' COMMENT '备注信息', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '会员账单表', -ROW_FORMAT = COMPACT; - -ALTER TABLE member_account_log ADD INDEX account_type (account_type (191)); - -ALTER TABLE member_account_log ADD INDEX create_time (create_time); - -ALTER TABLE member_account_log ADD INDEX from_type (from_type (191)); - -ALTER TABLE member_account_log ADD INDEX member_id (member_id); - - -CREATE TABLE member ( - member_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键', - member_no VARCHAR(255) NOT NULL DEFAULT '' COMMENT '会员编码', - pid int(11) NOT NULL DEFAULT 0 COMMENT '推广会员id', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - username varchar(255) DEFAULT '' COMMENT '会员用户名', - mobile varchar(20) NOT NULL DEFAULT '' COMMENT '手机号', - password varchar(255) NOT NULL DEFAULT '' COMMENT '会员密码', - nickname varchar(50) NOT NULL DEFAULT '' COMMENT '会员昵称', - headimg varchar(1000) NOT NULL DEFAULT '' COMMENT '会员头像', - member_level int(11) NOT NULL DEFAULT 0 COMMENT '会员等级', - member_label varchar(255) NOT NULL DEFAULT '' COMMENT '会员标签', - wx_openid varchar(255) NOT NULL DEFAULT '' COMMENT '微信用户openid', - weapp_openid varchar(255) NOT NULL DEFAULT '' COMMENT '微信小程序openid', - wx_unionid varchar(255) NOT NULL DEFAULT '' COMMENT '微信unionid', - ali_openid varchar(255) NOT NULL DEFAULT '' COMMENT '支付宝账户id', - douyin_openid varchar(255) NOT NULL DEFAULT '' COMMENT '抖音小程序openid', - register_channel varchar(255) NOT NULL DEFAULT 'H5' COMMENT '注册来源', - register_type varchar(255) NOT NULL DEFAULT '' COMMENT '注册方式', - login_ip varchar(255) NOT NULL DEFAULT '' COMMENT '当前登录ip', - login_type varchar(255) NOT NULL DEFAULT 'h5' COMMENT '当前登录的操作终端类型', - login_channel varchar(255) NOT NULL DEFAULT '', - login_count int(11) NOT NULL DEFAULT 0 COMMENT '登录次数', - login_time int(11) NOT NULL DEFAULT 0 COMMENT '当前登录时间', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '注册时间', - last_visit_time int(11) NOT NULL DEFAULT 0 COMMENT '最后访问时间', - last_consum_time int(11) NOT NULL DEFAULT 0 COMMENT '最后消费时间', - sex tinyint(4) NOT NULL DEFAULT 0 COMMENT '性别 0保密 1男 2女', - status tinyint(4) NOT NULL DEFAULT 1 COMMENT '用户状态 用户状态默认为1', - birthday varchar(20) NOT NULL DEFAULT '' COMMENT '出生日期', - point int(11) NOT NULL DEFAULT 0 COMMENT '可用积分', - point_get int(11) NOT NULL DEFAULT 0 COMMENT '累计获取积分', - balance decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '可用余额', - balance_get decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '累计获取余额', - money DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '可用余额(可提现)', - money_get DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '累计获取余额(可提现)', - money_cash_outing DECIMAL(10, 2) NOT NULL COMMENT '提现中余额(可提现)', - growth int(11) NOT NULL DEFAULT 0 COMMENT '成长值', - growth_get int(11) NOT NULL DEFAULT 0 COMMENT '累计获得成长值', - commission DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '当前佣金', - commission_get DECIMAL(10, 2) NOT NULL DEFAULT 0.00 COMMENT '佣金获取', - commission_cash_outing DECIMAL(10, 2) NOT NULL COMMENT '提现中佣金', - is_member tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否是会员', - member_time int(11) NOT NULL DEFAULT 0 COMMENT '成为会员时间', - is_del tinyint(4) NOT NULL DEFAULT 0 COMMENT '0正常 1已删除', - province_id int(11) NOT NULL DEFAULT 0 COMMENT '省id', - city_id int(11) NOT NULL DEFAULT 0 COMMENT '市id', - district_id int(11) NOT NULL DEFAULT 0 COMMENT '区县id', - address varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址', - location varchar(255) NOT NULL DEFAULT '' COMMENT '定位地址', - delete_time int(11) NOT NULL DEFAULT 0 COMMENT '删除时间', - update_time INT(11) NOT NULL DEFAULT 0 COMMENT '修改时间', - PRIMARY KEY (member_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '会员表', -ROW_FORMAT = COMPACT; - -ALTER TABLE member ADD INDEX mobile (mobile); - -ALTER TABLE member ADD INDEX password (password (191)); - -ALTER TABLE member ADD INDEX site_id (site_id); - -ALTER TABLE member ADD INDEX username (username (191)); - -ALTER TABLE member ADD INDEX weapp_openid (weapp_openid (191)); - -ALTER TABLE member ADD INDEX wx_openid (wx_openid (191)); - -ALTER TABLE member ADD INDEX wx_unionid (wx_unionid (191)); - - -CREATE TABLE jobs_failed ( - id INT(11) NOT NULL AUTO_INCREMENT, - `connection` TEXT NOT NULL, - queue TEXT NOT NULL, - payload LONGTEXT NOT NULL, - exception LONGTEXT NOT NULL, - fail_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '消息队列任务失败记录表'; - -CREATE TABLE jobs ( - id INT(11) NOT NULL AUTO_INCREMENT, - queue VARCHAR(255) NOT NULL, - payload LONGTEXT NOT NULL, - attempts TINYINT(4) UNSIGNED NOT NULL, - reserved TINYINT(4) UNSIGNED NOT NULL, - reserve_time INT(11) UNSIGNED DEFAULT NULL, - available_time INT(11) UNSIGNED NOT NULL, - create_time INT(11) UNSIGNED NOT NULL, - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '消息队列任务表'; - -CREATE TABLE generate_table ( - id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - table_name varchar(255) NOT NULL DEFAULT '' COMMENT '表名', - table_content varchar(255) NOT NULL DEFAULT '' COMMENT '描述前缀', - module_name varchar(255) NOT NULL DEFAULT '' COMMENT '模块名', - class_name varchar(255) NOT NULL DEFAULT '' COMMENT '类名前缀', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '添加时间', - edit_type int(11) NOT NULL DEFAULT 1 COMMENT '编辑方式 1-弹框 2-新页面', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '代码生成表'; - - -CREATE TABLE generate_column ( - id int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', - table_id int(11) NOT NULL DEFAULT 0 COMMENT '表id', - column_name varchar(100) NOT NULL DEFAULT '' COMMENT '字段名称', - column_comment varchar(300) NOT NULL DEFAULT '' COMMENT '字段描述', - column_type varchar(100) NOT NULL DEFAULT '' COMMENT '字段类型', - is_required tinyint(1) DEFAULT 0 COMMENT '是否必填 0-非必填 1-必填', - is_pk tinyint(1) DEFAULT 0 COMMENT '是否为主键 0-不是 1-是', - is_insert tinyint(1) DEFAULT 0 COMMENT '是否为插入字段 0-不是 1-是', - is_update tinyint(1) DEFAULT 0 COMMENT '是否为更新字段 0-不是 1-是', - is_lists tinyint(1) DEFAULT 1 COMMENT '是否为列表字段 0-不是 1-是', - is_query tinyint(1) DEFAULT 1 COMMENT '是否为查询字段 0-不是 1-是', - is_search tinyint(1) DEFAULT 1 COMMENT '是否搜索字段', - query_type varchar(100) DEFAULT '=' COMMENT '查询类型', - view_type varchar(100) DEFAULT 'input' COMMENT '显示类型', - dict_type varchar(255) DEFAULT '' COMMENT '字典类型', - create_time int(11) NOT NULL COMMENT '创建时间', - update_time int(11) DEFAULT NULL COMMENT '修改时间', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '代码生成表字段信息表'; - - -CREATE TABLE diy_route ( - id int(11) NOT NULL AUTO_INCREMENT, - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - title varchar(255) NOT NULL DEFAULT '' COMMENT '页面名称', - name varchar(255) NOT NULL DEFAULT '' COMMENT '页面标识', - page varchar(255) NOT NULL DEFAULT '' COMMENT '页面路径', - share varchar(1000) NOT NULL DEFAULT '' COMMENT '分享内容', - is_share int(11) NOT NULL DEFAULT 0 COMMENT '是否支持分享', - sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '自定义路由'; - - -CREATE TABLE diy_page ( - id int(11) NOT NULL AUTO_INCREMENT, - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点id', - title varchar(255) NOT NULL DEFAULT '' COMMENT '页面名称', - name varchar(255) NOT NULL DEFAULT '' COMMENT '页面标识', - type varchar(255) NOT NULL DEFAULT '' COMMENT '页面模板', - value longtext DEFAULT NULL COMMENT '页面数据,json格式', - is_default int(11) NOT NULL DEFAULT 0 COMMENT '是否默认页面,1:是,0:否', - share varchar(1000) NOT NULL DEFAULT '' COMMENT '分享内容', - visit_count int(11) NOT NULL DEFAULT 0 COMMENT '访问量', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '自定义页面'; - - -CREATE TABLE article_category ( - category_id int(11) NOT NULL AUTO_INCREMENT COMMENT '文章分类id', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点ID', - name varchar(255) NOT NULL DEFAULT '' COMMENT '分类名称', - sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', - is_show tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否显示:1-是;0-否', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - PRIMARY KEY (category_id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '文章分类表'; - -ALTER TABLE article_category ADD INDEX create_time (create_time); - -ALTER TABLE article_category ADD INDEX is_show (is_show); - -ALTER TABLE article_category ADD INDEX site_id (site_id); - -ALTER TABLE article_category ADD INDEX sort (sort); - - -CREATE TABLE article ( - id int(11) NOT NULL AUTO_INCREMENT COMMENT '文章id', - category_id int(11) NOT NULL COMMENT '文章分类', - site_id int(11) NOT NULL DEFAULT 0 COMMENT '站点ID', - title varchar(255) NOT NULL COMMENT '文章标题', - intro varchar(255) NOT NULL DEFAULT '' COMMENT '简介', - summary varchar(255) NOT NULL DEFAULT '' COMMENT '文章摘要', - image varchar(128) NOT NULL DEFAULT '' COMMENT '文章图片', - author varchar(255) NOT NULL DEFAULT '' COMMENT '作者', - content text DEFAULT NULL COMMENT '文章内容', - visit int(11) NOT NULL DEFAULT 0 COMMENT '实际浏览量', - visit_virtual int(11) NOT NULL DEFAULT 0 COMMENT '虚拟浏览量', - is_show tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否显示:1-是.0-否', - sort int(11) NOT NULL DEFAULT 0 COMMENT '排序', - create_time int(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - update_time int(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '文章表'; - -ALTER TABLE article ADD INDEX IDX_article_category_id (category_id); - -ALTER TABLE article ADD INDEX IDX_article_create_time (create_time); - -ALTER TABLE article ADD INDEX IDX_article_is_show (is_show); - -ALTER TABLE article ADD INDEX IDX_article_site_id (site_id); - -ALTER TABLE article ADD INDEX IDX_ns_article_sort (sort); - - -CREATE TABLE addon_log ( - id INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - action VARCHAR(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '操作类型 install 安装 uninstall 卸载 update 更新', - `key` VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件标识', - from_version VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '升级前的版本号', - to_version VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '升级后的版本号', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '插件日志表'; - -CREATE TABLE addon ( - id INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - title VARCHAR(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件名称', - icon VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件图标', - `key` VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '插件标识', - `desc` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '插件描述', - status TINYINT(4) NOT NULL DEFAULT 1 COMMENT '状态', - author VARCHAR(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '作者', - version VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '版本号', - create_time INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间', - install_time INT(11) NOT NULL DEFAULT 0 COMMENT '安装时间', - update_time INT(11) NOT NULL DEFAULT 0 COMMENT '更新时间', - cover VARCHAR(255) NOT NULL DEFAULT '' COMMENT '封面', - PRIMARY KEY (id) -) -ENGINE = INNODB, -CHARACTER SET utf8mb4, -COLLATE utf8mb4_general_ci, -COMMENT = '插件表'; - -ALTER TABLE addon ADD UNIQUE INDEX UK_title(title); - -INSERT INTO sys_user_role VALUES -(1, 1, 1, '', 0, 1); - -INSERT INTO sys_user VALUES -(1, '', '', '', '', '', 0, 0, 0, 1, 0, 0, 0); - -INSERT INTO site VALUES -(1, 'niucloud-admin', 0, '', 'admin', '', '', 1, '', '', 0, 0, 0, '', '', '', '', 0, 0); +INSERT INTO sys_user(uid, username) VALUE +(1, ''); +INSERT INTO site(site_id, site_name, app_type) VALUE +(1, 'niucloud-admin', 'admin'); diff --git a/niucloud/app/install/view/index/step-3.html b/niucloud/app/install/view/index/step-3.html index 8e199a506..3ccdf23f9 100644 --- a/niucloud/app/install/view/index/step-3.html +++ b/niucloud/app/install/view/index/step-3.html @@ -24,7 +24,7 @@
-

数据库设定

+

数据库设置

@@ -79,12 +79,12 @@
*数据库主机:
-

网站设定

+

网站设置

- + @@ -101,7 +101,35 @@ - +
*网站标题: - 网站标题 必填 + 网站标题 必填
*管理员用户名: 确认密码 必填
+

默认站点

+ + + + + + + + + +
+
+ + + + + + + + + +
*站点名称: + 站点名称 必填
*站点管理员: + + 站点管理员 必填 +
请不要和网站管理员相同
*管理员密码: + 管理员密码 必填
*确认密码: + 确认密码 必填
@@ -220,9 +248,9 @@ $.ajax({ url: "{$root_url}/install.php/index/getInstallInfo", dataType: 'json', - type: 'post', + type: 'get', success : function(data) { - if(data.code == 200) { + if(data.code == 1) { $(data.data.log).each(function (i, e){ if($('.log-'+i).length == 0) { let html = `
@@ -263,14 +291,14 @@ type: 'post', success : function(res) { layer.close(index); - if(res.code == 200){ + if(res.code == 1){ $.ajax({ url: "{$root_url}/install.php/index/initData", data: data, dataType: 'json', type: 'post', success : function(data) { - if(data.code == 200){ + if(data.code == 1){ window.location.href = '{$root_url}/install.php/index/installSuccess'; } } diff --git a/niucloud/app/install/view/index/step-4.html b/niucloud/app/install/view/index/step-4.html index 3f8a46ed4..df7639b81 100644 --- a/niucloud/app/install/view/index/step-4.html +++ b/niucloud/app/install/view/index/step-4.html @@ -32,24 +32,36 @@
diff --git a/niucloud/app/job/schedule/OrderClose.php b/niucloud/app/job/schedule/OrderClose.php new file mode 100644 index 000000000..5c0a41b44 --- /dev/null +++ b/niucloud/app/job/schedule/OrderClose.php @@ -0,0 +1,32 @@ +getExpireSiteList(); + if(!empty($list)){ + foreach($list as $k => $v){ + $core_site_service->expire($v['site_id']); + } + } +// Log::write('站点到期自动关闭'.date('Y-m-d h:i:s')); + return true; + } +} diff --git a/niucloud/app/job/sys/AddonInstall.php b/niucloud/app/job/sys/AddonInstall.php new file mode 100644 index 000000000..fbf421e2d --- /dev/null +++ b/niucloud/app/job/sys/AddonInstall.php @@ -0,0 +1,31 @@ +executeTask($task); + } + + public function failed($data){ + + } +} diff --git a/niucloud/app/job/sys/CheckDeleteJob.php b/niucloud/app/job/sys/CheckDeleteJob.php new file mode 100644 index 000000000..92a681b57 --- /dev/null +++ b/niucloud/app/job/sys/CheckDeleteJob.php @@ -0,0 +1,29 @@ + $file], secs:8); + return true; + } +} diff --git a/niucloud/app/job/sys/Cronexecute.php b/niucloud/app/job/sys/Cronexecute.php deleted file mode 100644 index 9a08738c7..000000000 --- a/niucloud/app/job/sys/Cronexecute.php +++ /dev/null @@ -1,64 +0,0 @@ -attempts() > 3) { -// //通过这个方法可以检查这个任务已经重试了几次了 -// } -// -// -// //如果任务执行成功后 记得删除任务,不然这个任务会重复执行,直到达到最大重试次数后失败后,执行failed方法 -// $job->delete(); -// -// // 也可以重新发布这个任务 -// $job->release($delay ?? 0); //$delay为延迟时间 - - - $res = event($data[ 'event' ], $data['data'] ); - //根据结果来判断下一步 - - $cron_task_model = new CoreCronService(); - //定义最新的执行时间或错误 - $cron_task_model->after($data); - $job->delete(); - - - - } - - - /** - * 失败后的解决方案或提示 - * @param $data - * @return void - */ - public function failed($data){ - - // ...任务达到最大重试次数后,失败了 - } - -} diff --git a/niucloud/app/lang/en.php b/niucloud/app/lang/en.php index b389a5004..c95e49f77 100644 --- a/niucloud/app/lang/en.php +++ b/niucloud/app/lang/en.php @@ -12,10 +12,11 @@ * 语言包说明: * 系统相关system: * 返回值语言文件: exception.php - * 枚举相关文件:enum.php + * 枚举相关文件:dict.php * 验证语言文件:validate.php * * 扩展开发相关plugin * */ -return (new \core\addon\AddonLoader("Lang"))->load(["lang_type" =>"en"]); +use core\dict\DictLoader; +return (new DictLoader("Lang"))->load(["lang_type" =>"en"]); diff --git a/niucloud/app/lang/en/system/api.php b/niucloud/app/lang/en/api.php similarity index 100% rename from niucloud/app/lang/en/system/api.php rename to niucloud/app/lang/en/api.php diff --git a/niucloud/app/lang/en/system/enum.php b/niucloud/app/lang/en/dict.php similarity index 89% rename from niucloud/app/lang/en/system/enum.php rename to niucloud/app/lang/en/dict.php index fe6025413..76415025e 100644 --- a/niucloud/app/lang/en/system/enum.php +++ b/niucloud/app/lang/en/dict.php @@ -11,12 +11,12 @@ return [ //端口管理 - 'enum_app' => [ + 'dict_app' => [ 'type_admin' => 'admin', 'type_site' => 'site', 'type_api' => 'api', ], - 'enum_menu' => [ + 'dict_menu' => [ //菜单类型 'type_list' => 'list', 'type_menu' => 'menu', @@ -25,25 +25,25 @@ return [ 'status_on' => 'on', 'status_off' => 'off' ], - 'enum_user' => [ + 'dict_user' => [ //用户状态 'status_on' => 'on', 'status_off' => 'off' ], - 'enum_role' => [ + 'dict_role' => [ //角色状态 'status_on' => 'on', 'status_off' => 'off' ], // 站点 - 'enum_site' => [ + 'dict_site' => [ //站点类型 'type_cms' => 'cms', 'status_on' => 'on', 'status_experience' => 'experience', 'status_expire' => 'expire' ], - 'enum_notice' => [ + 'dict_notice' => [ 'type_sms' => 'sms', 'type_wechat' => 'wechat', 'type_weapp' => 'weapp', @@ -55,7 +55,7 @@ return [ 'var_point' => 'point', ], //上传附件相关 - 'enum_file' => [ + 'dict_file' => [ //上传附件类型 'type_image' => 'image', 'type_video' => 'video', @@ -66,7 +66,7 @@ return [ 'storage_type_qcloud' => 'tencent', ], - 'enum_member' => [ + 'dict_member' => [ //会员端口 'terminal_wechat' => 'wechat', 'terminal_weapp' => 'weapp', @@ -86,19 +86,19 @@ return [ 'account_balance_recharge' => 'recharge', ], - 'enum_order' => [ + 'dict_order' => [ //订单类型 'order_type_recharge' => 'recharge order', ], //微信回复 - 'enum_wechat_reply' => [ + 'dict_wechat_reply' => [ //微信回复状态 'status_on' => 'on', 'status_off' => 'off' ], //自动任务时间间隔 - 'enum_cron' => [ + 'dict_cron' => [ 'type_minute' => 'minute', 'type_day' => 'day', 'type_week' => 'week', @@ -108,38 +108,38 @@ return [ 'type_crond' => 'period work' ], //支付相关 - 'enum_pay' => [ + 'dict_pay' => [ 'type_wechatpay' => 'wechatpay', 'type_alipay' => 'alipay', 'type_unipay' => 'unipay', 'type_offline' => 'offlinepay', ], - 'enum_agreement' => [ + 'dict_agreement' => [ //菜单类型 'service' => 'service agreement', 'privacy' => 'privacy agreement', ], //微信配置 - 'enum_wechat_config' => [ + 'dict_wechat_config' => [ 'not_encrypt' => 'not encrypt', 'compatible' => 'compatible', 'safe' => 'safe' ], //性别 - 'enum_sex' => [ + 'dict_sex' => [ 'unknown' => 'unknown', 'man' => 'man', 'woman' => 'woman' ], - // 自定义页面类型 - 'enum_diy' => [ + // 自定义页面 + 'dict_diy' => [ 'page_index' => 'index', 'page_member_index' => 'member index', 'page_diy' => 'diy page', - 'component_type_basics' => 'base component' + 'component_type_basic' => 'base component' ], //短信相关 - 'enum_sms' => [ + 'dict_sms' => [ 'status_sending' => 'sending', 'status_success' => 'success', 'status_fail' => 'fail', diff --git a/niucloud/app/lang/en/system/validate.php b/niucloud/app/lang/en/validate.php similarity index 100% rename from niucloud/app/lang/en/system/validate.php rename to niucloud/app/lang/en/validate.php diff --git a/niucloud/app/lang/zh-cn.php b/niucloud/app/lang/zh-cn.php index bcf182573..6097fedec 100644 --- a/niucloud/app/lang/zh-cn.php +++ b/niucloud/app/lang/zh-cn.php @@ -12,10 +12,11 @@ * 语言包说明: * 系统相关system: * 返回值语言文件: api.php - * 枚举相关文件:enum.php + * 枚举相关文件:dict.php * 验证语言文件:validate.php * * 扩展开发相关addon * */ -return (new \core\addon\AddonLoader("Lang"))->load(["lang_type" =>"zh-cn"]); +use core\dict\DictLoader; +return (new DictLoader("Lang"))->load(["lang_type" =>"zh-cn"]); \ No newline at end of file diff --git a/niucloud/app/lang/zh-cn/api.php b/niucloud/app/lang/zh-cn/api.php index 9240674d7..3b0cd093b 100644 --- a/niucloud/app/lang/zh-cn/api.php +++ b/niucloud/app/lang/zh-cn/api.php @@ -35,7 +35,9 @@ return [ 'ADDON_UNINSTALL_SUCCESS' => '插件卸载成功', 'DATA_GET_FAIL' => '数据获取失败', 'SERVER_CROSS_REQUEST_FAIL' => '服务器跨域请求异常', - + 'ADDON_INSTALL_NOT_EXIST' => '未找到插件安装任务', + 'ADDON_INSTALL_EXECUTED' => '插件安装任务已执行', + 'INSTALL_CHECK_NOT_PASS' => '安装校验未通过', //登录注册重置账号.... @@ -43,7 +45,7 @@ return [ 'MUST_LOGIN' => '请登录', 'LOGIN_EXPIRE' => '登录过期,请重新登录', 'LOGIN_STATE_ERROR' => '登录状态有误,请重新登录', - 'USER_LOCK' => '账号被限制', + 'USER_LOCK' => '账号被锁定', 'USER_ERROR' => '账号或密码错误', 'NO_SITE_PERMISSION' => '您没有当前站点的访问权限', 'SITE_NOT_EXIST' => '站点不存在', @@ -114,6 +116,7 @@ return [ 'MEMBER_LOGOUT' => '账号退出', 'MEMBER_TYPE_NOT_EXIST' => '账户类型不存在', 'MEMBER_IS_EXIST' => '账号已存在', + 'MEMBER_NO_IS_EXIST' => '会员编号已存在', 'REG_CHANNEL_NOT_EXIST' => '无效的注册渠道', 'MEMBER_USERNAME_LOGIN_NOT_OPEN' => '未开始账号登录注册', 'AUTH_LOGIN_NOT_OPEN' => '未开启第三方登录注册', @@ -158,7 +161,9 @@ return [ //站点相关 'SITE_GROUP_IS_EXIST' => '当前套餐存在站点,请调整站点对应套餐后重试', - + 'SITE_EXPIRE' => '站点已过期', + 'SITE_EXPIRE_NOT_ALLOW' => '站点已打烊,续费后可继续使用此项功能', + 'SITE_CLOSE_NOT_ALLOW' => '站点已停止', //支付相关(todo 注意:7段不共享) 'ALIPAY_TRANSACTION_NO_NOT_EXIST' => '无效的支付交易号', @@ -178,14 +183,26 @@ return [ 'CHANNEL_MARK_INVALID' => '无效的渠道标识', 'TEMPLATE_NOT_EXIST' => '模板不存在', 'IS_EXIST_TEMPLATE_NOT_MODIFY' => '已存在的支付模板不支持修改支付类型', - + //退款相关 + 'REFUND_NOT_EXIST' => '退款单据不存在', //订单相关 8*** 'ORDER_NOT_EXIST' => '订单不存在', 'ORDER_CLOSED' => '订单已关闭', // 退款相关 - 'NOT_ALLOW_APPLY_REFUND' => '当前订单不允许退款', + 'NOT_ALLOW_APPLY_REFUND' => '该订单不允许退款', 'ITEM_REFUND_NOT_EXIST' => '退款单不存在', 'REFUND_STATUS_ABNORMAL' => '退款单状态异常', - 'NO_REFUNDABLE_AMOUNT' => '会员账户金额为0不允许进行退款' + 'NO_REFUNDABLE_AMOUNT' => '会员账户金额为0不允许进行退款', + 'REFUND_HAD_APPLIED' => '订单已申请退款', + 'ORDER_UNPAID_NOT_ALLOW_APPLY_REFUND' => '订单尚未支付不能进行退款', + + + // 缓存相关 + 'CLEAR_MYSQL_CACHE_SUCCESS' => '数据表缓存清除成功', + + //任务队列相关 + 'JOB_NOT_EXISTS' => '任务类不存在', + 'JOB_CREATE_FAIL' => '任务创建失败', + ]; diff --git a/niucloud/app/lang/zh-cn/enum.php b/niucloud/app/lang/zh-cn/dict.php similarity index 81% rename from niucloud/app/lang/zh-cn/enum.php rename to niucloud/app/lang/zh-cn/dict.php index 37e395c74..aa64e5d45 100644 --- a/niucloud/app/lang/zh-cn/enum.php +++ b/niucloud/app/lang/zh-cn/dict.php @@ -11,12 +11,12 @@ return [ //端口管理 - 'enum_app' => [ + 'dict_app' => [ 'type_admin' => '平台管理端', 'type_site' => '站点管理端', 'type_api' => '客户端', ], - 'enum_menu' => [ + 'dict_menu' => [ //菜单类型 'type_list' => '目录', 'type_menu' => '菜单', @@ -25,25 +25,26 @@ return [ 'status_on' => '正常', 'status_off' => '停用' ], - 'enum_user' => [ + 'dict_user' => [ //用户状态 'status_on' => '正常', 'status_off' => '锁定' ], - 'enum_role' => [ + 'dict_role' => [ //角色状态 'status_on' => '启用', 'status_off' => '停用' ], // 站点 - 'enum_site' => [ + 'dict_site' => [ //站点类型 'type_cms' => 'cms', 'status_on' => '正常', 'status_experience' => '体验期', - 'status_expire' => '已到期' + 'status_expire' => '已到期', + 'status_close' => '已停止' ], - 'enum_notice' => [ + 'dict_notice' => [ 'type_sms' => '短信', 'type_wechat' => '微信公众号', 'type_weapp' => '微信小程序', @@ -55,7 +56,7 @@ return [ 'var_point' => '会员积分', ], //上传附件相关 - 'enum_file' => [ + 'dict_file' => [ //上传附件类型 'type_image' => '图片', 'type_video' => '视频', @@ -66,7 +67,7 @@ return [ 'storage_type_qcloud' => '腾讯云', ], - 'enum_member' => [ + 'dict_member' => [ //会员端口 'register_wechat' => '公众号', 'register_weapp' => '微信小程序', @@ -95,28 +96,36 @@ return [ 'account_commission_cash_out' => '佣金提现', 'status_on' => '正常', 'status_off' => '锁定', - 'account_balance_recharge_refund' => '充值订单退款' + 'account_balance_recharge_refund' => '充值订单退款', + 'account_balance_order' => '订单消费', + 'account_balance_order_refund' => '订单退款', ], - 'enum_order' => [ + 'dict_order' => [ //订单类型 'order_type_recharge' => '充值订单', 'trade_type_recharge' => '会员充值', ], - 'enum_refund' => [ + 'dict_refund' => [ //订单类型 'order_type_recharge' => '充值订单', 'trade_type_recharge' => '会员充值', + 'wait' => '待审核', + 'wait_transfer' => "待转账", + "success" => "退款成功", + "fail" => "退款失败", + 'all' => '累计退款', + 'have' => '退款中金额', ], //微信回复 - 'enum_wechat_reply' => [ + 'dict_wechat_reply' => [ //微信回复状态 'status_on' => '启用', 'status_off' => '停用' ], //自动任务时间间隔 - 'enum_cron' => [ + 'dict_cron' => [ 'type_minute' => '分钟', 'type_day' => '天', 'type_week' => '星期', @@ -126,7 +135,7 @@ return [ 'type_crond' => '周期任务' ], //支付相关 - 'enum_pay' => [ + 'dict_pay' => [ 'type_wechatpay' => '微信支付', 'type_alipay' => '支付宝支付', 'type_unipay' => '银联支付', @@ -139,7 +148,7 @@ return [ 'status_cancle' => '已取消', ], //转账相关 - 'enum_transfer' => [ + 'dict_transfer' => [ 'type_wechat' => '微信', 'type_ali' => '支付宝', 'type_bank' => '银行卡', @@ -150,29 +159,29 @@ return [ 'status_success' => '转账成功', 'status_fail' => '转账失败', ], - 'enum_agreement' => [ + 'dict_agreement' => [ //菜单类型 'service' => '服务协议', 'privacy' => '隐私协议', ], //微信配置 - 'enum_wechat_config' => [ + 'dict_wechat_config' => [ 'not_encrypt' => '明文', 'compatible' => '兼容', 'safe' => '安全' ], //性别 - 'enum_sex' => [ + 'dict_sex' => [ 'unknown' => '未知', 'man' => '男', 'woman' => '女' ], - // 自定义页面类型 - 'enum_diy' => [ + // 自定义页面 + 'dict_diy' => [ 'page_index' => '首页', 'page_member_index' => '个人中心', 'page_diy' => '自定义页面', - 'component_type_basics' => '基础组件', + 'component_type_basic' => '基础组件', 'system_link' => '系统页面', 'system_link_index' => '首页', @@ -189,13 +198,13 @@ return [ 'diy_link' => '自定义链接' ], //短信相关 - 'enum_sms' => [ + 'dict_sms' => [ 'status_sending' => '发送中', 'status_success' => '成功', 'status_fail' => '失败', ], //渠道 - 'enum_channel' => [ + 'dict_channel' => [ //渠道端口 'channel_wechat' => '公众号', 'channel_weapp' => '微信小程序', @@ -205,7 +214,7 @@ return [ ], //会员提现 - 'enum_member_cash_out' => [ + 'dict_member_cash_out' => [ //状态 'status_wait_audit' => '待审核', 'status_wait_transfer' => '待转账', @@ -215,7 +224,7 @@ return [ ], //插件操作 - 'enum_addon' => [ + 'dict_addon' => [ //状态 'install' => '安装', 'uninstall' => '卸载', @@ -224,7 +233,7 @@ return [ 'status_off' => '关闭', ], // 退款支付状态 - 'enum_pay_refund' => [ + 'dict_pay_refund' => [ 'success' => '退款成功', 'dealing' => '退款中', 'wait' => '待退款', @@ -235,9 +244,25 @@ return [ 'offline' => '线下退款', 'balance' => '退款到余额', ], - 'enum_order_refund' => [ + 'dict_order_refund' => [ 'refunding' => '退款中', 'refund_complete' => '退款完成', 'refund_fail' => '退款失败' + ], + 'dict_app_manage' => [ + 'system_app' => '基础应用', + 'message_manage' => '消息管理', + 'member_recharge' => '会员充值', + ], + 'dict_setting' => [ + 'server_system' => '服务器系统', + 'server_setting' => '服务器web环境', + 'php_version' => 'PHP版本', + 'mysql_version' => 'mysql版本', + 'php_ask' => '大于等于8.0.0', + 'mysql_ask' => '大于等于5.7', + 'php_authority_ask' => '开启', + 'file_authority_ask' => '可读可写' ] + ]; diff --git a/niucloud/app/lang/zh-cn/validate.php b/niucloud/app/lang/zh-cn/validate.php index d477c9540..e7cd59c76 100644 --- a/niucloud/app/lang/zh-cn/validate.php +++ b/niucloud/app/lang/zh-cn/validate.php @@ -47,7 +47,9 @@ return [ 'expire_time_number' => '到期时间必须是时间戳', 'group_name_require' => '站点分组名称必须填写', 'group_name_max' => '站点分组名称不能超过20字符', - 'group_roles_require' => '分组权限必须填写' + 'group_roles_require' => '分组权限必须填写', + 'front_end_name_require' => '前台名称必须填写', + 'front_end_name_max' => '前台名称最多不能超过20个字符', ], //附件 'validate_attachment' => [ @@ -85,6 +87,11 @@ return [ 'status_require' => '会员状态必须填写', 'not_exit_status' => '不存在的会员状态' ], + 'validate_member_config' => [ + 'length_number' => '会员编码必须是整数', + 'length_min' => '会员编码长度不能小于10', + 'length_max' => '会员编码长度不能大于于20', + ], 'validate_article' => [ 'title_require' => '文章标题必须填写', 'title_max' => '文章标题不能超过20个字符', @@ -149,7 +156,7 @@ return [ ], // 自定义 'validate_diy' => [ - 'type_not_exist' => '不存在的页面类型', + 'type_not_exist' => '不存在的页面模板', ], // 会员提现账号 'validate_member_cash_out_account' => [ diff --git a/niucloud/app/listener/notice/Sms.php b/niucloud/app/listener/notice/Sms.php index c90dd53be..32b61941b 100644 --- a/niucloud/app/listener/notice/Sms.php +++ b/niucloud/app/listener/notice/Sms.php @@ -2,8 +2,7 @@ namespace app\listener\notice; -use app\enum\notice\NoticeTypeEnum; -use app\enum\sys\MessageTypeEnum; +use app\dict\notice\NoticeTypeDict; use app\service\core\member\CoreMemberService; use app\service\core\notice\CoreNoticeLogService; use app\service\core\notice\CoreSmsService; @@ -14,7 +13,6 @@ class Sms public function handle(array $data) { - return true; $site_id = $data['site_id']; $template = $data['template'];//模板 $vars = $data['vars'];//模板变量 @@ -23,7 +21,6 @@ class Sms $mobile = $to['mobile'] ?? ''; //完全信任消息的设置, 不再依赖support_type if (!$template['is_sms']) { - try { $sms_id = $template['sms_id'];//发送模板id $content = $template['sms_content']; $member_id = $to['member_id'] ?? 0; @@ -36,12 +33,14 @@ class Sms $nickname = $info['nickname'] ?? ''; } } + + try{ if (empty($mobile)) throw new NoticeException('NOTICE_SMS_EMPTY');//没有手机号不能发送短信 $core_sms_service = new CoreSmsService(); //消息日志 $log_data = array( 'key' => $key, - 'message_type' => NoticeTypeEnum::SMS, + 'message_type' => NoticeTypeDict::SMS, 'uid' => $uid ?? 0, 'member_id' => $member_id ?? 0, 'nickname' => $nickname ?? '', diff --git a/niucloud/app/listener/notice/Weapp.php b/niucloud/app/listener/notice/Weapp.php index 2a3833697..709b6f612 100644 --- a/niucloud/app/listener/notice/Weapp.php +++ b/niucloud/app/listener/notice/Weapp.php @@ -2,8 +2,8 @@ namespace app\listener\notice; -use app\enum\notice\NoticeTypeEnum; -use app\enum\sys\MessageTypeEnum; +use app\dict\notice\NoticeTypeDict; +use app\dict\sys\MessageTypeDict; use app\service\core\member\CoreMemberService; use app\service\core\notice\CoreNoticeLogService; use core\exception\NoticeException; @@ -30,8 +30,8 @@ class Weapp } if(!empty($openid)) { $weapp_template_id = $template['weapp_template_id']; - $weapp_json = $template['weapp']; - $weapp_content = $weapp_json['content']; + $weapp = $template['weapp']; + $weapp_content = $weapp['content']; $weapp_data = []; foreach($weapp_content as $k => $v){ $search_content = $v[1]; @@ -47,16 +47,16 @@ class Weapp } $log_data = array( 'key' => $key, - 'message_type' => NoticeTypeEnum::WEAPP, + 'message_type' => NoticeTypeDict::WEAPP, 'uid' => $data['uid'] ?? 0, 'member_id' => $member_id, 'nickname' => $nickname ?? '', 'receiver' => $openid, 'params' => $data, - 'content' => $weapp_json + 'content' => $weapp ); try { - (new TemplateLoader(NoticeTypeEnum::WEAPP, ['site_id' => $site_id]))->send( + (new TemplateLoader(NoticeTypeDict::WEAPP, ['site_id' => $site_id]))->send( [ 'template_id' => $weapp_template_id, 'data' => $weapp_data, diff --git a/niucloud/app/listener/notice/Wechat.php b/niucloud/app/listener/notice/Wechat.php index 2bdcd2ea3..0dd8bde45 100644 --- a/niucloud/app/listener/notice/Wechat.php +++ b/niucloud/app/listener/notice/Wechat.php @@ -2,8 +2,8 @@ namespace app\listener\notice; -use app\enum\notice\NoticeTypeEnum; -use app\enum\sys\MessageTypeEnum; +use app\dict\notice\NoticeTypeDict; +use app\dict\sys\MessageTypeDict; use app\service\core\member\CoreMemberService; use app\service\core\notice\CoreNoticeLogService; use core\exception\NoticeException; @@ -14,7 +14,6 @@ class Wechat public function handle(array $data) { - return true; $site_id = $data['site_id']; $template = $data['template'];//模板 $vars = $data['vars'];//模板变量 @@ -33,8 +32,8 @@ class Wechat //或者还有用户的 if(!empty($openid)){ $wechat_template_id = $template['wechat_template_id']; - $wechat_json = $template['wechat']; - $wechat_content = $wechat_json['content']; + $wechat = $template['wechat']; + $wechat_content = $wechat['content']; $wechat_data = []; foreach($wechat_content as $k => $v){ $search_content = $v[1]; @@ -43,8 +42,8 @@ class Wechat } $wechat_data[$v[2]] = $search_content; } - $first = $wechat_json['wechat_first'] ?? ''; - $remark = $wechat_json['wechat_remark'] ?? ''; + $first = $wechat['wechat_first'] ?? ''; + $remark = $wechat['wechat_remark'] ?? ''; if(!empty($first)) $vars['first'] = $first; if(!empty($remark)) $vars['remark'] = $remark; $url = ''; @@ -55,17 +54,17 @@ class Wechat //消息日志 $log_data = array( 'key' => $key, - 'message_type' => NoticeTypeEnum::WECHAT, + 'message_type' => NoticeTypeDict::WECHAT, 'uid' => $data['uid'] ?? 0, 'member_id' => $member_id, 'nickname' => $nickname ?? '', 'receiver' => $openid, 'params' => $vars, - 'content' => $wechat_json + 'content' => $wechat ); try{ - (new TemplateLoader(NoticeTypeEnum::WECHAT, ['site_id' => $site_id]))->send( + (new TemplateLoader(NoticeTypeDict::WECHAT, ['site_id' => $site_id]))->send( [ 'template_id' => $wechat_template_id, 'first' => $remark, diff --git a/niucloud/app/listener/pay/PaySuccessListener.php b/niucloud/app/listener/pay/PaySuccessListener.php index 691bb93d3..e92a5e1aa 100644 --- a/niucloud/app/listener/pay/PaySuccessListener.php +++ b/niucloud/app/listener/pay/PaySuccessListener.php @@ -21,7 +21,7 @@ class PaySuccessListener { public function handle(array $pay_info) { - $class = "app\\enum\\order\\". $pay_info['trade_type']."\\".ucfirst($pay_info['trade_type']).'OrderService'; + $class = "app\\dict\\order\\". $pay_info['trade_type']."\\".ucfirst($pay_info['trade_type']).'OrderService'; return (new $class)->pay($pay_info); } diff --git a/niucloud/app/listener/pay/TransferSuccessListener.php b/niucloud/app/listener/pay/TransferSuccessListener.php index fe94a6a0c..6e68b05b5 100644 --- a/niucloud/app/listener/pay/TransferSuccessListener.php +++ b/niucloud/app/listener/pay/TransferSuccessListener.php @@ -11,7 +11,7 @@ namespace app\listener\pay; -use app\enum\cash_out\CashOutTypeEnum; +use app\dict\cash_out\CashOutTypeDict; use app\service\core\member\CoreMemberCashOutService; /** @@ -22,7 +22,7 @@ class TransferSuccessListener public function handle(array $info) { //会员零钱提现 - if($info['trade_type'] == CashOutTypeEnum::MEMBER_CASH_OUT) + if($info['trade_type'] == CashOutTypeDict::MEMBER_CASH_OUT) { return (new CoreMemberCashOutService())->transferFinish($info['site_id'], $info['transfer_no']); } diff --git a/niucloud/app/listener/scan/ScanListener.php b/niucloud/app/listener/scan/ScanListener.php index 7daadd631..f4ca97e04 100644 --- a/niucloud/app/listener/scan/ScanListener.php +++ b/niucloud/app/listener/scan/ScanListener.php @@ -11,7 +11,7 @@ namespace app\listener\scan; -use app\enum\scan\ScanEnum; +use app\dict\scan\ScanDict; use app\service\api\wechat\WechatAuthService; use app\service\core\order\recharge\CoreRechargeOrderService; @@ -26,13 +26,13 @@ class ScanListener { $action = $data['action']; switch($action){ - case ScanEnum::WECHAT_LOGIN: + case ScanDict::WECHAT_LOGIN: try { $wechat_auth_service = new WechatAuthService(); $data['login_data'] = $wechat_auth_service->login($data['openid']); - $data['status'] = ScanEnum::SUCCESS; + $data['status'] = ScanDict::SUCCESS; }catch(\Throwable $e){ - $data['status'] = ScanEnum::FAIL; + $data['status'] = ScanDict::FAIL; $data['fail_reason'] = get_lang($e->getMessage()); } unset($data['openid']); diff --git a/niucloud/app/listener/site/AddSiteAfterListener.php b/niucloud/app/listener/site/AddSiteAfterListener.php new file mode 100644 index 000000000..9896e8a5e --- /dev/null +++ b/niucloud/app/listener/site/AddSiteAfterListener.php @@ -0,0 +1,35 @@ +install([ 'site_id' => $data[ 'site_id' ] ]); + //加载插件语言包 + return; + } +} \ No newline at end of file diff --git a/niucloud/app/listener/system/AppManageListener.php b/niucloud/app/listener/system/AppManageListener.php index e9c20af7f..36dc283c2 100644 --- a/niucloud/app/listener/system/AppManageListener.php +++ b/niucloud/app/listener/system/AppManageListener.php @@ -25,23 +25,24 @@ class AppManageListener [ "key" => "basic", - "name" => "系统应用" + "name" => get_lang('dict_app_manage.system_app'), + "sort" => 10 ] ], [ "addon" => "", - "title" => "消息管理", + "title" => get_lang('dict_app_manage.message_manage'), "category" => "basic", - "desc" => "消息管理", + "desc" => get_lang('dict_app_manage.message_manage'), "icon" => "static/resource/images/app/message_icon.png", "cover" => "static/resource/images/app/message_cover.png", - "url" => "/setting/message/template" + "url" => "/setting/notice/template" ], [ "addon" => "", - "title" => "会员充值", + "title" => get_lang('dict_app_manage.member_recharge'), "category" => "basic", - "desc" => "会员充值", + "desc" => get_lang('dict_app_manage.member_recharge'), "icon" => "static/resource/images/app/recharge_icon.png", "cover" => "static/resource/images/app/recharge_cover.png", "url" => "/finance/recharge" diff --git a/niucloud/app/model/addon/Addon.php b/niucloud/app/model/addon/Addon.php index ae8d740c8..deb6bbabd 100644 --- a/niucloud/app/model/addon/Addon.php +++ b/niucloud/app/model/addon/Addon.php @@ -11,7 +11,7 @@ namespace app\model\addon; -use app\enum\addon\AddonEnum; +use app\dict\addon\AddonDict; use core\base\BaseModel; /** @@ -45,7 +45,7 @@ class Addon extends BaseModel */ public function getStatusNameAttr($value, $data) { - return AddonEnum::getStatus()[ $data[ 'status' ] ?? '' ] ?? ''; + return AddonDict::getStatus()[ $data[ 'status' ] ?? '' ] ?? ''; } /** * 插件名称搜索器 diff --git a/niucloud/app/model/article/Article.php b/niucloud/app/model/article/Article.php index 6e6a0057f..da01e4b59 100644 --- a/niucloud/app/model/article/Article.php +++ b/niucloud/app/model/article/Article.php @@ -98,6 +98,13 @@ class Article extends BaseModel } } - + public function getArticleUrlAttr($value, $data) { + $site_tag = '/s' . $data['site_id']; + $data = [ + 'wap_url' => ( !empty(env("system.wap_domain")) ? env("system.wap_domain") : request()->domain() ) . "/wap" . $site_tag . "/pages/article/detail?id={$data['id']}", + 'web_url' => ( !empty(env("system.web_domain")) ? env("system.web_domain") : request()->domain() ) . "/web" . $site_tag . "/article/detail?id={$data['id']}" + ]; + return $data; + } } diff --git a/niucloud/app/model/article/ArticleCategory.php b/niucloud/app/model/article/ArticleCategory.php index 30d5e2206..e6e8e3079 100644 --- a/niucloud/app/model/article/ArticleCategory.php +++ b/niucloud/app/model/article/ArticleCategory.php @@ -41,9 +41,15 @@ class ArticleCategory extends BaseModel public function searchNameAttr($query, $value, $data) { if ($value) { - $query->where('name', $value); + $query->where([ ['name', 'like', "%$value%" ]]); } } + public function getArticleNumAttr($value, $data) + { + return (new Article())->where([['category_id', '=', $data['category_id']]])->count(); + } + + } diff --git a/niucloud/app/model/diy/Diy.php b/niucloud/app/model/diy/Diy.php index 9c622afe8..295c2107f 100644 --- a/niucloud/app/model/diy/Diy.php +++ b/niucloud/app/model/diy/Diy.php @@ -11,7 +11,7 @@ namespace app\model\diy; -use app\enum\diy\PageEnum; +use app\dict\diy\TemplateDict; use core\base\BaseModel; @@ -47,7 +47,7 @@ class Diy extends BaseModel */ public function getTypeNameAttr($value, $data) { - return PageEnum::getPageType($data[ 'type' ] ?? '')[ 'title' ] ?? ''; + return TemplateDict::getTemplate($data[ 'type' ] ?? '')[ 'title' ] ?? ''; } /** @@ -98,19 +98,19 @@ class Diy extends BaseModel } /** - * 搜索器:自定义页面页面名称 + * 搜索器:自定义页面名称 * @param $value * @param $data */ public function searchTitleAttr($query, $value, $data) { if ($value) { - $query->where("title", $value); + $query->where("title", 'like', '%' . $value . '%'); } } /** - * 搜索器:自定义页面页面标识 + * 搜索器:自定义页面标识 * @param $value * @param $data */ @@ -122,7 +122,7 @@ class Diy extends BaseModel } /** - * 搜索器:自定义页面页面类型 + * 搜索器:自定义页面模板 * @param $value * @param $data */ @@ -134,7 +134,7 @@ class Diy extends BaseModel } /** - * 搜索器:自定义页面页面数据,json格式 + * 搜索器:自定义页面数据,json格式 * @param $value * @param $data */ diff --git a/niucloud/app/model/member/Member.php b/niucloud/app/model/member/Member.php index e1419c645..b3e2f6540 100644 --- a/niucloud/app/model/member/Member.php +++ b/niucloud/app/model/member/Member.php @@ -11,12 +11,12 @@ namespace app\model\member; -use app\enum\common\ChannelEnum; -use app\enum\common\CommonEnum; -use app\enum\member\MemberEnum; -use app\enum\member\MemberLoginTypeEnum; -use app\enum\member\MemberRegisterChannelEnum; -use app\enum\member\MemberRegisterTypeEnum; +use app\dict\common\ChannelDict; +use app\dict\common\CommonDict; +use app\dict\member\MemberDict; +use app\dict\member\MemberLoginTypeDict; +use app\dict\member\MemberRegisterChannelDict; +use app\dict\member\MemberRegisterTypeDict; use core\base\BaseModel; use think\db\Query; use think\model\concern\SoftDelete; @@ -72,7 +72,7 @@ class Member extends BaseModel */ public function getStatusNameAttr($value, $data) { - return MemberEnum::getStatus()[$data['status'] ?? ''] ?? ''; + return MemberDict::getStatus()[$data['status'] ?? ''] ?? ''; } /** * 注册来源字段转化 @@ -81,7 +81,7 @@ class Member extends BaseModel */ public function getRegisterChannelNameAttr($value, $data) { - return MemberRegisterChannelEnum::getType()[ $data[ 'register_channel' ] ?? '' ] ?? ''; + return MemberRegisterChannelDict::getType()[ $data[ 'register_channel' ] ?? '' ] ?? ''; } /** @@ -91,7 +91,7 @@ class Member extends BaseModel */ public function getRegisterTypeNameAttr($value, $data) { - return MemberRegisterTypeEnum::getType()[ $data[ 'register_type' ] ?? '' ] ?? ''; + return MemberRegisterTypeDict::getType()[ $data[ 'register_type' ] ?? '' ] ?? ''; } /** @@ -101,7 +101,7 @@ class Member extends BaseModel */ public function getLoginChannelNameAttr($value, $data) { - return ChannelEnum::getType()[ $data[ 'login_channel' ] ?? '' ] ?? ''; + return ChannelDict::getType()[ $data[ 'login_channel' ] ?? '' ] ?? ''; } /** @@ -111,7 +111,7 @@ class Member extends BaseModel */ public function getLoginTypeNameAttr($value, $data) { - return MemberLoginTypeEnum::getType()[ $data[ 'login_type' ] ?? '' ] ?? ''; + return MemberLoginTypeDict::getType()[ $data[ 'login_type' ] ?? '' ] ?? ''; } /** @@ -122,7 +122,7 @@ class Member extends BaseModel */ public function getSexNameAttr($value, $data) { - return CommonEnum::getSexType()[ $data[ 'sex' ] ?? '' ] ?? ''; + return CommonDict::getSexType()[ $data[ 'sex' ] ?? '' ] ?? ''; } /** @@ -143,7 +143,7 @@ class Member extends BaseModel public function searchKeywordAttr($query, $value, $data) { if ($value) { - $query->where('username|nickname|mobile', 'like', '%' . $value . '%'); + $query->where('member_no|username|nickname|mobile', 'like', '%' . $value . '%'); } } @@ -197,11 +197,11 @@ class Member extends BaseModel $start_time = empty($value[ 0 ]) ? 0 : strtotime($value[ 0 ]); $end_time = empty($value[ 1 ]) ? 0 : strtotime($value[ 1 ]); if ($start_time > 0 && $end_time > 0) { - $query->whereBetweenTime('create_time', $start_time, $end_time); + $query->whereBetweenTime('member.create_time', $start_time, $end_time); } else if ($start_time > 0 && $end_time == 0) { - $query->where([ [ 'create_time', '>=', $start_time ] ]); + $query->where([ [ 'member.create_time', '>=', $start_time ] ]); } else if ($start_time == 0 && $end_time > 0) { - $query->where([ [ 'create_time', '<=', $end_time ] ]); + $query->where([ [ 'member.create_time', '<=', $end_time ] ]); } } diff --git a/niucloud/app/model/member/MemberAccountLog.php b/niucloud/app/model/member/MemberAccountLog.php index 4073b031d..fb23eeb2a 100644 --- a/niucloud/app/model/member/MemberAccountLog.php +++ b/niucloud/app/model/member/MemberAccountLog.php @@ -11,7 +11,8 @@ namespace app\model\member; -use app\enum\member\MemberAccountEnum; +use app\dict\member\MemberAccountChangeTypeDict; +use app\dict\member\MemberAccountTypeDict; use core\base\BaseModel; /** @@ -43,7 +44,7 @@ class MemberAccountLog extends BaseModel */ public function getAccountTypeNameAttr($value,$data) { - return MemberAccountEnum::getType()[$data['account_type'] ?? ''] ?? ''; + return MemberAccountTypeDict::getType()[$data['account_type'] ?? ''] ?? ''; } /** @@ -53,10 +54,19 @@ class MemberAccountLog extends BaseModel public function memberInfo() { return $this->hasOne( Member::class, 'member_id', 'member_id')->joinType('left') - ->withField('member_id, username, mobile, nickname, headimg') + ->withField('member_id,member_no, username, mobile, nickname, headimg') ->bind(['username', 'mobile', 'nickname', 'headimg']); } + /** + * 会员关联 + * @return \think\model\relation\HasOne + */ + public function member() + { + return $this->hasOne( Member::class, 'member_id', 'member_id')->withField('member_id, member_no, username, mobile, nickname, headimg')->joinType('left'); + } + /** * 获取account_data * @param $value @@ -71,6 +81,20 @@ class MemberAccountLog extends BaseModel return $data['account_data']; } + /** + * 获取account_sum + * @param $value + * @param $data + * @return int + */ + public function getAccountSumAttr($value,$data) + { + if($data['account_type'] == 'point'|| $data['account_type'] == 'growth') + return (int)$data['account_sum']; + else + return $data['account_sum']; + } + /** * 获取账户变动类型名称 * @param $value @@ -80,7 +104,7 @@ class MemberAccountLog extends BaseModel public function getFromTypeNameAttr($value,$data) { if(isset($data['from_type'])&& isset($data['account_type'])) - return MemberAccountEnum::getFromType($data['account_type'])[$data['from_type']]['name']; + return MemberAccountChangeTypeDict::getType($data['account_type'])[$data['from_type']]['name']; else return ''; } @@ -92,7 +116,7 @@ class MemberAccountLog extends BaseModel public function searchMemberIdAttr($query, $value, $data) { if ($value) { - $query->where('member_id', $value); + $query->where('member_account_log.member_id', $value); } } @@ -127,11 +151,11 @@ class MemberAccountLog extends BaseModel $start_time = empty($value[0]) ? 0 : strtotime($value[0]) ; $end_time = empty($value[1]) ? 0 : strtotime($value[1]) ; if($start_time > 0 && $end_time > 0){ - $query->whereBetweenTime('create_time', $start_time, $end_time); + $query->whereBetweenTime('member_account_log.create_time', $start_time, $end_time); }else if($start_time > 0 && $end_time == 0){ - $query->where([['create_time', '>=', $start_time]]); + $query->where([['member_account_log.create_time', '>=', $start_time]]); }else if($start_time == 0 && $end_time > 0){ - $query->where([['create_time', '<=', $end_time]]); + $query->where([['member_account_log.create_time', '<=', $end_time]]); } } diff --git a/niucloud/app/model/member/MemberCashOut.php b/niucloud/app/model/member/MemberCashOut.php index 5cdf39ffb..c57958650 100644 --- a/niucloud/app/model/member/MemberCashOut.php +++ b/niucloud/app/model/member/MemberCashOut.php @@ -11,9 +11,9 @@ namespace app\model\member; -use app\enum\member\MemberAccountEnum; -use app\enum\member\MemberCashOutEnum; -use app\enum\pay\TransferEnum; +use app\dict\member\MemberAccountTypeDict; +use app\dict\member\MemberCashOutDict; +use app\dict\pay\TransferDict; use app\model\pay\Transfer; use core\base\BaseModel; @@ -34,6 +34,10 @@ class MemberCashOut extends BaseModel * @var string */ protected $name = 'member_cash_out'; + protected $type = [ + 'audit_time' => 'timestamp', + 'transfer_time' => 'timestamp', + ]; /** * 会员信息 @@ -42,8 +46,17 @@ class MemberCashOut extends BaseModel public function memberInfo() { return $this->hasOne( Member::class, 'member_id', 'member_id')->joinType('left') - ->withField('member_id, username, mobile, nickname, headimg') - ->bind(['username', 'mobile', 'nickname', 'headimg']); + ->withField('member_id, member_no, username, mobile, nickname, headimg') + ->bind(['username', 'mobile', 'nickname', 'headimg', 'member_no']); + } + + /** + * 会员信息关联列表查询 + * @return \think\model\relation\HasOne + */ + public function member() + { + return $this->hasOne( Member::class, 'member_id', 'member_id')->joinType('left'); } /** @@ -63,7 +76,7 @@ class MemberCashOut extends BaseModel * @return mixed|string */ public function getAccountTypeNameAttr($value, $data){ - return MemberAccountEnum::getType()[ $data[ 'account_type' ] ?? '' ] ?? ''; + return MemberAccountTypeDict::getType()[ $data[ 'account_type' ] ?? '' ] ?? ''; } /** * 提现状态名称 @@ -72,7 +85,7 @@ class MemberCashOut extends BaseModel * @return mixed|string */ public function getStatusNameAttr($value, $data){ - return MemberCashOutEnum::getStatus()[ $data[ 'status' ] ?? '' ] ?? ''; + return MemberCashOutDict::getStatus()[ $data[ 'status' ] ?? '' ] ?? ''; } /** * 转账方式名称 @@ -82,7 +95,7 @@ class MemberCashOut extends BaseModel */ public function getTransferTypeNameAttr($value, $data) { - return TransferEnum::getTransferType()[ $data[ 'transfer_type' ] ?? '' ]['name'] ?? ''; + return TransferDict::getTransferType()[ $data[ 'transfer_type' ] ?? '' ]['name'] ?? ''; } /** @@ -92,7 +105,7 @@ class MemberCashOut extends BaseModel * @return mixed|string */ public function getTransferStatusNameAttr($value, $data){ - return TransferEnum::getStatus()[ $data[ 'transfer_status' ] ?? '' ] ?? ''; + return TransferDict::getStatus()[ $data[ 'transfer_status' ] ?? '' ] ?? ''; } /** * 会员搜索 @@ -118,6 +131,30 @@ class MemberCashOut extends BaseModel } } + /** + * + * @param $value + * @param $data + */ + public function searchCashOutNoAttr($query, $value, $data) + { + if ($value) { + $query->where('cash_out_no', $value); + } + } + + /** + * + * @param $value + * @param $data + */ + public function searchTransferTypeAttr($query, $value, $data) + { + if ($value) { + $query->where('transfer_type', $value); + } + } + /** * 创建时间搜索器 * @param $value @@ -135,4 +172,38 @@ class MemberCashOut extends BaseModel } } + /** + * 审核时间搜索器 + * @param $value + */ + public function searchAuditTimeAttr($query, $value, $data) + { + $start_time = empty($value[0]) ? 0 : strtotime($value[0]) ; + $end_time = empty($value[1]) ? 0 : strtotime($value[1]) ; + if($start_time > 0 && $end_time > 0){ + $query->whereBetweenTime('audit_time', $start_time, $end_time); + }else if($start_time > 0 && $end_time == 0){ + $query->where([['audit_time', '>=', $start_time]]); + }else if($start_time == 0 && $end_time > 0){ + $query->where([['audit_time', '<=', $end_time]]); + } + } + + /** + * 审核时间搜索器 + * @param $value + */ + public function searchTransferTimeAttr($query, $value, $data) + { + $start_time = empty($value[0]) ? 0 : strtotime($value[0]) ; + $end_time = empty($value[1]) ? 0 : strtotime($value[1]) ; + if($start_time > 0 && $end_time > 0){ + $query->whereBetweenTime('transfer_time', $start_time, $end_time); + }else if($start_time > 0 && $end_time == 0){ + $query->where([['transfer_time', '>=', $start_time]]); + }else if($start_time == 0 && $end_time > 0){ + $query->where([['transfer_time', '<=', $end_time]]); + } + } + } diff --git a/niucloud/app/model/member/MemberCashOutAccount.php b/niucloud/app/model/member/MemberCashOutAccount.php index 3928d4923..5f099c1ab 100644 --- a/niucloud/app/model/member/MemberCashOutAccount.php +++ b/niucloud/app/model/member/MemberCashOutAccount.php @@ -11,7 +11,7 @@ namespace app\model\member; -use app\enum\pay\TransferEnum; +use app\dict\pay\TransferDict; use core\base\BaseModel; /** @@ -39,7 +39,7 @@ class MemberCashOutAccount extends BaseModel * @return mixed|string */ public function getAccountTypeNameAttr($value, $data){ - return TransferEnum::getTransferType()[ $data[ 'transfer_type' ] ?? '' ] ?? ''; + return TransferDict::getTransferType()[ $data[ 'transfer_type' ] ?? '' ] ?? ''; } /** diff --git a/niucloud/app/model/member/MemberLabel.php b/niucloud/app/model/member/MemberLabel.php index be08889bf..a0b8d2bdc 100644 --- a/niucloud/app/model/member/MemberLabel.php +++ b/niucloud/app/model/member/MemberLabel.php @@ -33,4 +33,30 @@ class MemberLabel extends BaseModel */ protected $name = 'member_label'; + /** + * 获取对应标签的会员数量 + * @param $value + * @return mixed + */ + public function getMemberNumAttr($value, $data) + { + if(isset($data['label_id'])) + { + return (new Member())->where([['member_label', 'like', '%"' . $data['label_id'] . '"%' ]])->count(); + }else + return 0; + } + + /** + * 会员标签 + * @param $value + * @param $data + */ + public function searchLabelNameAttr($query, $value, $data) + { + if ($value) { + $query->where('label_name','like', '%'.$value.'%'); + } + } + } diff --git a/niucloud/app/model/order/Order.php b/niucloud/app/model/order/Order.php index 5514abcb1..c3926def8 100644 --- a/niucloud/app/model/order/Order.php +++ b/niucloud/app/model/order/Order.php @@ -11,7 +11,7 @@ namespace app\model\order; -use app\enum\common\ChannelEnum; +use app\dict\common\ChannelDict; use app\model\member\Member; use core\base\BaseModel; @@ -51,12 +51,28 @@ class Order extends BaseModel { if(isset($data['order_type']) && isset($data['order_status'])) { - $class = "app\\enum\\order\\". ucfirst($data['order_type']).'OrderEnum'; + $class = "app\\dict\\order\\". ucfirst($data['order_type']).'OrderDict'; return $class::getStatus($data['order_status']); }else return []; } + /** + * 获取退款状态 + * @param $value + * @param $data + * @return void + */ + public function getRefundStatusNameAttr($value, $data) { + if(isset($data['order_type']) && isset($data['refund_status'])) + { + $class = "app\\dict\\order\\". ucfirst($data['order_type']).'OrderDict'; + return $class::getRefundStatus($data['refund_status'])['name'] ?? ''; + } else { + return ''; + } + } + /** * 登录渠道字段转化 * @param $value @@ -66,7 +82,7 @@ class Order extends BaseModel { if(isset($data['order_from'])) { - return ChannelEnum::getType()[$data['order_from']] ?? ''; + return ChannelDict::getType()[$data['order_from']] ?? ''; } } @@ -123,6 +139,39 @@ class Order extends BaseModel } } + /** + * 订单号 + * @param $query + * @param $value + * @param $data + */ + public function searchOrderNoAttr($query, $value, $data) + { + if ($value) { + $query->where('order_no', '=', $value); + } + } + + /** + * 订单金额 + * @param $query + * @param $value + * @param $data + * @return void + */ + public function searchOrderMoneyAttr($query, $value, $data) + { + if (!empty($data['start_money']) && !empty($data['end_money'])) { + $money = [ $data['start_money'], $data['end_money'] ]; + sort($money); + $query->where('order_money', 'between', $money); + } else if (!empty($data['start_money'])) { + $query->where('order_money', '>=', $data['start_money']); + } else if (!empty($data['end_money'])) { + $query->where('order_money', '<=', $data['end_money']); + } + } + /** * 订单状态 * @param $query @@ -152,6 +201,26 @@ class Order extends BaseModel } } + /** + * 支付时间筛选 + * @param $query + * @param $value + * @param $data + * @return void + */ + public function searchPayTimeAttr($query, $value, $data) + { + $start_time = empty($value[0]) ? 0 : strtotime($value[0]) ; + $end_time = empty($value[1]) ? 0 : strtotime($value[1]) ; + if($start_time > 0 && $end_time > 0){ + $query->whereBetweenTime('pay_time', $start_time, $end_time); + }else if($start_time > 0 && $end_time == 0){ + $query->where([['pay_time', '>=', $start_time]]); + }else if($start_time == 0 && $end_time > 0){ + $query->where([['pay_time', '<=', $end_time]]); + } + } + /** * 订单项目 * @return \think\model\relation\HasMany diff --git a/niucloud/app/model/order/OrderItem.php b/niucloud/app/model/order/OrderItem.php index cc1b697a5..7ab4235f4 100644 --- a/niucloud/app/model/order/OrderItem.php +++ b/niucloud/app/model/order/OrderItem.php @@ -33,6 +33,13 @@ class OrderItem extends BaseModel */ protected $name = 'order_item'; + /** + * @return HasOne + */ + public function orderNo() + { + return $this->hasOne(Order::class, 'order_id', 'order_id')->joinType('left')->withField('order_id, order_no')->bind(['order_no' => 'order_no']); + } /** * 数量字段处理 * @param $value diff --git a/niucloud/app/model/order/OrderItemRefund.php b/niucloud/app/model/order/OrderItemRefund.php index b12947d8f..20a78ce7c 100644 --- a/niucloud/app/model/order/OrderItemRefund.php +++ b/niucloud/app/model/order/OrderItemRefund.php @@ -11,7 +11,7 @@ namespace app\model\order; -use app\enum\pay\PayRefundEnum; +use app\dict\pay\PayRefundDict; use app\model\member\Member; use app\model\pay\Refund; use core\base\BaseModel; @@ -49,7 +49,7 @@ class OrderItemRefund extends BaseModel */ public function getStatusNameAttr($value, $data) { - $class = "\\app\\enum\\order\\" . ucfirst($data['item_type']). "OrderEnum"; + $class = "\\app\\dict\\order\\" . ucfirst($data['item_type']). "OrderDict"; if (!class_exists($class)) return ''; return $class::getRefundStatus()[$data['status'] ?? '']['name'] ?? ''; } @@ -68,7 +68,7 @@ class OrderItemRefund extends BaseModel */ public function member() { - return $this->hasOne(Member::class,'member_id', 'member_id'); + return $this->hasOne( Member::class, 'member_id', 'member_id')->withField('member_id, username, mobile, nickname, headimg')->joinType('left'); } /** @@ -92,6 +92,20 @@ class OrderItemRefund extends BaseModel } } + + /** + * 订单号搜索 + * @param $query + * @param $value + * @param $data + */ + public function searchOrderNoAttr($query, $value, $data) + { + if ($value) { + $query->where('order_item_refund.order_no', '=', $value); + } + } + /** * 会员id搜索 * @param $query @@ -101,7 +115,7 @@ class OrderItemRefund extends BaseModel public function searchMemberIdAttr($query, $value, $data) { if ($value) { - $query->where('member_id', '=', $value); + $query->where('order_item_refund.member_id', '=', $value); } } @@ -114,7 +128,7 @@ class OrderItemRefund extends BaseModel public function searchStatusAttr($query, $value, $data) { if ($value != '') { - $query->where('status', '=', $value); + $query->where('order_item_refund.status', '=', $value); } } @@ -127,11 +141,11 @@ class OrderItemRefund extends BaseModel $start_time = empty($value[0]) ? 0 : strtotime($value[0]) ; $end_time = empty($value[1]) ? 0 : strtotime($value[1]) ; if($start_time > 0 && $end_time > 0){ - $query->whereBetweenTime('create_time', $start_time, $end_time); + $query->whereBetweenTime('order_item_refund.create_time', $start_time, $end_time); }else if($start_time > 0 && $end_time == 0){ - $query->where([['create_time', '>=', $start_time]]); + $query->where([['order_item_refund.create_time', '>=', $start_time]]); }else if($start_time == 0 && $end_time > 0){ - $query->where([['create_time', '<=', $end_time]]); + $query->where([['order_item_refund.create_time', '<=', $end_time]]); } } } diff --git a/niucloud/app/model/pay/Pay.php b/niucloud/app/model/pay/Pay.php index d30e004e8..a4f1cdcc7 100644 --- a/niucloud/app/model/pay/Pay.php +++ b/niucloud/app/model/pay/Pay.php @@ -11,8 +11,8 @@ namespace app\model\pay; -use app\enum\order\OrderTypeEnum; -use app\enum\pay\PayEnum; +use app\dict\order\OrderTypeDict; +use app\dict\pay\PayDict; use core\base\BaseModel; /** @@ -54,7 +54,7 @@ class Pay extends BaseModel */ public function getStatusNameAttr($value, $data) { - return PayEnum::getStatus()[$data['status'] ?? ''] ?? ''; + return PayDict::getStatus()[$data['status'] ?? ''] ?? ''; } /** @@ -64,7 +64,7 @@ class Pay extends BaseModel * @return void */ public function getPayTypeListAttr($value, $data){ - return OrderTypeEnum::getAllowPayType($data['trade_type']); + return OrderTypeDict::getAllowPayType($data['trade_type']); } /** * 支付方式字段转化 @@ -73,7 +73,7 @@ class Pay extends BaseModel */ public function getTypeNameAttr($value, $data) { - return PayEnum::getPayType()[$data['type'] ?? '']['name'] ?? ''; + return PayDict::getPayType()[$data['type'] ?? '']['name'] ?? ''; } } diff --git a/niucloud/app/model/pay/PayChannel.php b/niucloud/app/model/pay/PayChannel.php index 58fb2b66b..a745f3389 100644 --- a/niucloud/app/model/pay/PayChannel.php +++ b/niucloud/app/model/pay/PayChannel.php @@ -11,8 +11,8 @@ namespace app\model\pay; -use app\enum\common\ChannelEnum; -use app\enum\pay\PayEnum; +use app\dict\common\ChannelDict; +use app\dict\pay\PayDict; use core\base\BaseModel; /** @@ -47,7 +47,7 @@ class PayChannel extends BaseModel */ public function getTypeNameAttr($value, $data) { - return PayEnum::getPayType()[$data['type'] ?? '']['name'] ?? ''; + return PayDict::getPayType()[$data['type'] ?? '']['name'] ?? ''; } /** @@ -57,7 +57,7 @@ class PayChannel extends BaseModel */ public function getChannelNameAttr($value, $data) { - return ChannelEnum::getType()[$data['channel'] ?? ''] ?? ''; + return ChannelDict::getType()[$data['channel'] ?? ''] ?? ''; } } diff --git a/niucloud/app/model/pay/Refund.php b/niucloud/app/model/pay/Refund.php index e39cebdc9..8210b937c 100644 --- a/niucloud/app/model/pay/Refund.php +++ b/niucloud/app/model/pay/Refund.php @@ -11,10 +11,10 @@ namespace app\model\pay; -use app\enum\order\OrderTypeEnum; -use app\enum\pay\PayEnum; -use app\enum\pay\PayRefundEnum; -use app\enum\pay\RefundEnum; +use app\dict\order\OrderTypeDict; +use app\dict\pay\PayDict; +use app\dict\pay\PayRefundDict; +use app\dict\pay\RefundDict; use core\base\BaseModel; /** @@ -50,7 +50,7 @@ class Refund extends BaseModel */ public function getStatusNameAttr($value, $data) { - return RefundEnum::getStatus()[$data['status'] ?? ''] ?? ''; + return RefundDict::getStatus()[$data['status'] ?? ''] ?? ''; } /** @@ -60,7 +60,7 @@ class Refund extends BaseModel */ public function getTypeNameAttr($value, $data) { - return RefundEnum::getType()[$data['type'] ?? ''] ?? ''; + return RefundDict::getType()[$data['type'] ?? ''] ?? ''; } } diff --git a/niucloud/app/model/pay/Transfer.php b/niucloud/app/model/pay/Transfer.php index 8a1b02741..9d88c91d6 100644 --- a/niucloud/app/model/pay/Transfer.php +++ b/niucloud/app/model/pay/Transfer.php @@ -11,7 +11,7 @@ namespace app\model\pay; -use app\enum\pay\TransferEnum; +use app\dict\pay\TransferDict; use core\base\BaseModel; /** @@ -48,7 +48,7 @@ class Transfer extends BaseModel */ public function getTransferStatusNameAttr($value, $data) { - return TransferEnum::getStatus()[$data['transfer_status'] ?? ''] ?? ''; + return TransferDict::getStatus()[$data['transfer_status'] ?? ''] ?? ''; } @@ -59,7 +59,7 @@ class Transfer extends BaseModel */ public function getTransferTypeNameAttr($value, $data) { - return TransferEnum::getTransferType()[$data['transfer_type'] ?? '']['name'] ?? ''; + return TransferDict::getTransferType()[$data['transfer_type'] ?? '']['name'] ?? ''; } } diff --git a/niucloud/app/model/site/Site.php b/niucloud/app/model/site/Site.php index 712ce8d9f..4bbe2ad74 100644 --- a/niucloud/app/model/site/Site.php +++ b/niucloud/app/model/site/Site.php @@ -11,7 +11,7 @@ namespace app\model\site; -use app\enum\site\SiteEnum; +use app\dict\site\SiteDict; use core\base\BaseModel; use think\db\Query; @@ -46,7 +46,7 @@ class Site extends BaseModel */ public function getStatusNameAttr($value, $data) { - return SiteEnum::getStatus()[$data['status'] ?? ''] ?? ''; + return SiteDict::getStatus()[$data['status'] ?? ''] ?? ''; } /** * 关键字搜索 @@ -114,5 +114,22 @@ class Site extends BaseModel } } + /** + * 到期时间搜索器 + * @param $value + */ + public function searchExpireTimeAttr(Query $query, $value, $data) + { + $start_time = empty($value[ 0 ]) ? 0 : strtotime($value[ 0 ]); + $end_time = empty($value[ 1 ]) ? 0 : strtotime($value[ 1 ]); + if ($start_time > 0 && $end_time > 0) { + $query->whereBetweenTime('expire_time', $start_time, $end_time); + } else if ($start_time > 0 && $end_time == 0) { + $query->where([ [ 'expire_time', '>=', $start_time ] ]); + } else if ($start_time == 0 && $end_time > 0) { + $query->where([ [ 'expire_time', '<=', $end_time ] ]); + } + } + } diff --git a/niucloud/app/model/sys/SysAgreement.php b/niucloud/app/model/sys/SysAgreement.php index f744b34a6..f1e9b4aa5 100644 --- a/niucloud/app/model/sys/SysAgreement.php +++ b/niucloud/app/model/sys/SysAgreement.php @@ -11,7 +11,7 @@ namespace app\model\sys; -use app\enum\sys\AgreementEnum; +use app\dict\sys\AgreementDict; use core\base\BaseModel; /** @@ -45,6 +45,6 @@ class SysAgreement extends BaseModel */ public function getAgreementKeyNameAttr($value, $data) { - return AgreementEnum::getType()[$data['agreement_key'] ?? ''] ?? ''; + return AgreementDict::getType()[$data['agreement_key'] ?? ''] ?? ''; } } diff --git a/niucloud/app/model/sys/SysCronTask.php b/niucloud/app/model/sys/SysCronTask.php index 885599fa0..61baf4d3c 100644 --- a/niucloud/app/model/sys/SysCronTask.php +++ b/niucloud/app/model/sys/SysCronTask.php @@ -11,7 +11,7 @@ namespace app\model\sys; -use app\enum\sys\CronEnum; +use app\dict\sys\CronDict; use core\base\BaseModel; use think\db\Query; @@ -52,7 +52,7 @@ class SysCronTask extends BaseModel */ public function getTypeNameAttr($value, $data) { - return CronEnum::getType()[$data['type'] ?? ''] ?? ''; + return CronDict::getType()[$data['type'] ?? ''] ?? ''; } /** @@ -62,7 +62,7 @@ class SysCronTask extends BaseModel */ public function getCrondTypeNameAttr($value, $data) { - return CronEnum::getCrondType()[$data['crond_type'] ?? ''] ?? ''; + return CronDict::getCrondType()[$data['crond_type'] ?? ''] ?? ''; } /** * 任务名称搜索器 diff --git a/niucloud/app/model/sys/SysMenu.php b/niucloud/app/model/sys/SysMenu.php index 11337e4cb..b6c34306a 100644 --- a/niucloud/app/model/sys/SysMenu.php +++ b/niucloud/app/model/sys/SysMenu.php @@ -11,8 +11,8 @@ namespace app\model\sys; -use app\enum\sys\MenuEnum; -use app\enum\sys\MenuTypeEnum; +use app\dict\sys\MenuDict; +use app\dict\sys\MenuTypeDict; use core\base\BaseModel; /** @@ -38,6 +38,18 @@ class SysMenu extends BaseModel * @var array */ protected $append = ['status_name', 'menu_type_name']; + + /** + * 定义软删除标记字段 + * @var string + */ + protected $deleteTime = 'delete_time'; + /** + * 定义软删除字段的默认值 + * @var int + */ + protected $defaultSoftDelete = 0; + /** * 菜单类型 * @param $value @@ -46,7 +58,7 @@ class SysMenu extends BaseModel */ public function getMenuTypeNameAttr($value,$data) { - return MenuTypeEnum::getMenuType()[$data['menu_type'] ?? ''] ?? ''; + return MenuTypeDict::getMenuType()[$data['menu_type'] ?? ''] ?? ''; } /** @@ -57,6 +69,6 @@ class SysMenu extends BaseModel */ public function getStatusNameAttr($value,$data) { - return MenuEnum::getStatus()[$data['status'] ?? ''] ?? ''; + return MenuDict::getStatus()[$data['status'] ?? ''] ?? ''; } } diff --git a/niucloud/app/model/sys/SysNoticeLog.php b/niucloud/app/model/sys/SysNoticeLog.php index 78be21be6..87050ba0a 100644 --- a/niucloud/app/model/sys/SysNoticeLog.php +++ b/niucloud/app/model/sys/SysNoticeLog.php @@ -11,7 +11,7 @@ namespace app\model\sys; -use app\enum\notice\NoticeTypeEnum; +use app\dict\notice\NoticeTypeDict; use core\base\BaseModel; use think\db\Query; @@ -66,7 +66,7 @@ class SysNoticeLog extends BaseModel */ public function getNameAttr($value,$data) { - $temp = \app\enum\notice\NoticeEnum::getNotice()[$data['key'] ?? ''] ?? ''; + $temp = \app\dict\notice\NoticeDict::getNotice()[$data['key'] ?? ''] ?? ''; return $temp['name'] ?? ''; } @@ -78,7 +78,7 @@ class SysNoticeLog extends BaseModel */ public function getNoticeTypeNameAttr($value,$data) { - $temp = NoticeTypeEnum::getType()[$data['notice_type'] ?? ''] ?? ''; + $temp = NoticeTypeDict::getType()[$data['notice_type'] ?? ''] ?? ''; return $temp['name'] ?? ''; } /** diff --git a/niucloud/app/model/sys/SysNoticeSmsLog.php b/niucloud/app/model/sys/SysNoticeSmsLog.php index 7f880ce84..3ca06646a 100644 --- a/niucloud/app/model/sys/SysNoticeSmsLog.php +++ b/niucloud/app/model/sys/SysNoticeSmsLog.php @@ -11,7 +11,7 @@ namespace app\model\sys; -use app\enum\sys\SmsEnum; +use app\dict\sys\SmsDict; use core\base\BaseModel; /** @@ -65,7 +65,7 @@ class SysNoticeSmsLog extends BaseModel */ public function getNameAttr($value,$data) { - $temp = \app\enum\notice\NoticeEnum::getNotice()[$data['key'] ?? '']; + $temp = \app\dict\notice\NoticeDict::getNotice()[$data['key'] ?? '']; return $temp['name'] ?? ''; } @@ -77,7 +77,7 @@ class SysNoticeSmsLog extends BaseModel */ public function getStatusNameAttr($value,$data) { - return SmsEnum::getStatusType()[$data['status'] ?? ''] ?? ''; + return SmsDict::getStatusType()[$data['status'] ?? ''] ?? ''; } /** @@ -88,7 +88,7 @@ class SysNoticeSmsLog extends BaseModel */ public function getSmsTypesNameAttr($value,$data) { - $temp = SmsEnum::getType()[$data['sms_type'] ?? ''] ?? []; + $temp = SmsDict::getType()[$data['sms_type'] ?? ''] ?? []; return $temp['name'] ?? ''; } /** diff --git a/niucloud/app/model/sys/SysRole.php b/niucloud/app/model/sys/SysRole.php index 33eab4be1..9d6bdbd7a 100644 --- a/niucloud/app/model/sys/SysRole.php +++ b/niucloud/app/model/sys/SysRole.php @@ -11,7 +11,7 @@ namespace app\model\sys; -use app\enum\sys\RoleStatusEnum; +use app\dict\sys\RoleStatusDict; use core\base\BaseModel; /** @@ -45,7 +45,7 @@ class SysRole extends BaseModel * @return string */ public function getStatusNameAttr($value, $data){ - return RoleStatusEnum::getStatus()[$data['status'] ?? ''] ?? ''; + return RoleStatusDict::getStatus()[$data['status'] ?? ''] ?? ''; } diff --git a/niucloud/app/model/sys/SysUser.php b/niucloud/app/model/sys/SysUser.php index 582ebd75f..56236aad8 100644 --- a/niucloud/app/model/sys/SysUser.php +++ b/niucloud/app/model/sys/SysUser.php @@ -11,7 +11,7 @@ namespace app\model\sys; -use app\enum\sys\UserEnum; +use app\dict\sys\UserDict; use core\base\BaseModel; use think\model\concern\SoftDelete; @@ -72,7 +72,12 @@ class SysUser extends BaseModel */ public function getStatusNameAttr($value, $data) { - return UserEnum::getStatus()[$data['status'] ?? ''] ?? ''; + return UserDict::getStatus()[$data['status'] ?? ''] ?? ''; + } + + public function getCreateTimeAttr($value, $data) + { + return $data['create_time'] ? get_date_by_time($data['create_time']) : ''; } /** diff --git a/niucloud/app/model/wechat/WechatReply.php b/niucloud/app/model/wechat/WechatReply.php index df0f1a275..c55263837 100644 --- a/niucloud/app/model/wechat/WechatReply.php +++ b/niucloud/app/model/wechat/WechatReply.php @@ -11,7 +11,7 @@ namespace app\model\wechat; -use app\enum\channel\ReplyEnum; +use app\dict\channel\ReplyDict; use core\base\BaseModel; /** @@ -44,7 +44,7 @@ class WechatReply extends BaseModel public function getContentAttr($value,$data) { - return $data['content_type'] == ReplyEnum::CONTENT_TYPE_TEXT ? $value : json_decode($value, true); + return $data['content_type'] == ReplyDict::CONTENT_TYPE_TEXT ? $value : json_decode($value, true); } } diff --git a/niucloud/app/service/admin/addon/AddonService.php b/niucloud/app/service/admin/addon/AddonService.php index d3cc8342e..f7e67a1d8 100644 --- a/niucloud/app/service/admin/addon/AddonService.php +++ b/niucloud/app/service/admin/addon/AddonService.php @@ -44,7 +44,36 @@ class AddonService extends BaseAdminService */ public function install(string $addon) { - return CoreAddonInstallService::instance($addon)->install(); + try { + $data = (new CoreAddonInstallService($addon))->install(); + return success('SUCCESS', $data); + } catch (\Exception $e) { + return fail($e->getMessage()); + } + } + + /** + * 执行安装 + * @param string $addon + * @return \think\Response + */ + public function executeInstall(string $addon) { + try { + $data = (new CoreAddonInstallService($addon))->executeInstall(); + return success('SUCCESS', $data); + } catch (\Exception $e) { + return fail($e->getMessage()); + } + } + + /** + * 安装插件检测安装环境 + * @param string $addon + * @return \think\Response + */ + public function installCheck(string $addon) { + $data = (new CoreAddonInstallService($addon))->installCheck(); + return success('SUCCESS', $data); } /** @@ -52,9 +81,9 @@ class AddonService extends BaseAdminService * @param string $addon * @return mixed */ - public function getInstallState(string $addon) + public function getInstallState(string $addon, string $key) { - return CoreAddonInstallService::instance($addon)->getInstallState(); + return CoreAddonInstallService::instance($addon)->getInstallState($key); } /** diff --git a/niucloud/app/service/admin/addon/TerminalService.php b/niucloud/app/service/admin/addon/TerminalService.php deleted file mode 100644 index c8db550af..000000000 --- a/niucloud/app/service/admin/addon/TerminalService.php +++ /dev/null @@ -1,341 +0,0 @@ - 'command-link-success', - // 执行成功 - 'exec-success' => 'command-exec-success', - // 执行完成 - 'exec-completed' => 'command-exec-completed', - // 执行出错 - 'exec-error' => 'command-exec-error', - ]; - - - - /** - * 初始化 - */ - public static function instance() - { - if (is_null(self::$instance)) { - self::$instance = new static(); - } - return self::$instance; - } - - /** - * 构造函数 - */ - public function __construct() - { - // 初始化日志文件 - $outputDir = root_path() . 'runtime' . DIRECTORY_SEPARATOR . 'terminal'; - $this->outputFile = $outputDir . DIRECTORY_SEPARATOR . 'exec.log'; - if (!is_dir($outputDir)) { - mkdir($outputDir, 0755, true); - } - file_put_contents($this->outputFile, ''); - - /** - * 命令执行结果输出到文件而不是管道 - * 因为输出到管道时有延迟,而文件虽然需要频繁读取和对比内容,但是输出实时的 - */ - $this->descriptorsPec = [0 => ['pipe', 'r'], 1 => ['file', $this->outputFile, 'w'], 2 => ['file', $this->outputFile, 'w']]; - } - - /** - * 获取命令 - * @param string $key 命令key - * @return array|false - */ - public static function getCommand(string $key) - { - if (!$key) { - return false; - } - - $commands = Config::get('terminal.commands'); - if (stripos($key, '.')) { - $key = explode('.', $key); - if (!array_key_exists($key[0], $commands) || !is_array($commands[$key[0]]) || !array_key_exists($key[1], $commands[$key[0]])) { - return false; - } - $command = $commands[$key[0]][$key[1]]; - } else { - if (!array_key_exists($key, $commands)) { - return false; - } - $command = $commands[$key]; - } - if (!is_array($command)) { - $command = [ - 'cwd' => dirname(root_path()) . DIRECTORY_SEPARATOR, - 'command' => $command, - ]; - } else { - $command = [ - 'cwd' => dirname(root_path()) . DIRECTORY_SEPARATOR . $command['cwd'], - 'command' => $command['command'], - ]; - } - $command['cwd'] = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $command['cwd']); - return $command; - } - - public function exec(array $commands = []) - { - header('Content-Type: text/event-stream'); - header('Cache-Control: no-cache'); - - if (ob_get_level()) ob_end_clean(); - if (!ob_get_level()) ob_start(); - - $command = self::getCommand($this->commandKey); - if (!$command) { - $this->execError('The command was not allowed to be executed', true); - } - - $this->beforeExecution(); - $this->outputFlag('link-success'); - $this->output('> ' . $command['command'], false); - - $this->process = proc_open($command['command'], $this->descriptorsPec, $this->pipes, $command['cwd']); - if (!is_resource($this->process)) { - $this->execError('Failed to execute', true); - } - while ($this->getProcStatus()) { - $contents = file_get_contents($this->outputFile); - if (strlen($contents) && $this->outputContent != $contents) { - $newOutput = str_replace($this->outputContent, '', $contents); - if (preg_match('/\r\n|\r|\n/', $newOutput)) { - $this->output($newOutput); - $this->outputContent = $contents; - } - } - usleep(500000); - } - foreach ($this->pipes as $pipe) { - fclose($pipe); - } - proc_close($this->process); - $this->outputFlag('exec-completed'); - } - - public function getProcStatus(): bool - { - $status = proc_get_status($this->process); - if ($status['running']) { - $this->procStatus = 1; - return true; - } elseif ($this->procStatus === 1) { - $this->procStatus = 0; - $this->output('exitcode: ' . $status['exitcode']); - if ($status['exitcode'] === 0) { - if ($this->successCallback()) { - $this->outputFlag('exec-success'); - } else { - $this->output('Error: Command execution succeeded, but callback execution failed'); - $this->outputFlag('exec-error'); - } - } else { - $this->outputFlag('exec-error'); - } - return true; - } else { - return false; - } - } - - /** - * 输出 EventSource 数据 - * @param string $data - * @param bool $callback - */ - public function output(string $data, bool $callback = true) - { - $data = self::outputFilter($data); - $data = [ - 'data' => $data, - 'uuid' => $this->uuid, - 'extend' => $this->extend, - 'key' => $this->commandKey, - ]; - $data = json_encode($data, JSON_UNESCAPED_UNICODE); - if ($data) { - echo 'data: ' . $data . "\n\n"; - if ($callback) $this->outputCallback($data); - @ob_flush();// 刷新浏览器缓冲区 - } - } - - /** - * 输出状态标记 - * @param string $flag - */ - public function outputFlag(string $flag) - { - $this->output($this->flag[$flag], false); - } - - /** - * 输出后回调 - */ - public function outputCallback($data) - { - - } - - /** - * 成功后回调 - * @return bool - */ - public function successCallback(): bool - { - if (stripos($this->commandKey, '.')) { - $commandKeyArr = explode('.', $this->commandKey); - $commandPKey = $commandKeyArr[0] ?? ''; - } else { - $commandPKey = $this->commandKey; - } - return true; - } - - /** - * 执行前埋点 - */ - public function beforeExecution() - { -/* if ($this->commandKey == 'test.pnpm') { - @unlink(root_path() . 'public' . DIRECTORY_SEPARATOR . 'npm-install-test' . DIRECTORY_SEPARATOR . 'pnpm-lock.yaml'); - } elseif ($this->commandKey == 'web-install.pnpm') { - @unlink(root_path() . 'web' . DIRECTORY_SEPARATOR . 'pnpm-lock.yaml'); - }*/ - } - - /** - * 输出过滤 - */ - public static function outputFilter($str) - { - $str = trim($str); - $preg = '/\[(.*?)m/i'; - $str = preg_replace($preg, '', $str); - $str = str_replace(["\r\n", "\r", "\n"], "", $str); - return mb_convert_encoding($str, 'UTF-8', 'UTF-8,GBK,GB2312,BIG5'); - } - - /** - * 执行错误 - */ - public function execError($error, $break = false) - { - $this->output('Error:' . $error); - $this->outputFlag('exec-error'); - if ($break) $this->break(); - } - - /** - * 退出执行 - */ - public function break() - { - throw new CommonException(Response::create()->contentType('text/event-stream')); - } - - /** - * 执行一个命令并以字符串的方式返回执行输出 - * 代替 exec 使用,这样就只需要解除 proc_open 的函数禁用了 - * @param $commandKey - * @return string | bool - */ - public static function getOutputFromProc($commandKey) - { - if (!function_exists('proc_open') || !function_exists('proc_close')) { - return false; - } - $command = self::getCommand($commandKey); - if (!$command) { - return false; - } - $descriptorsPec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; - $process = proc_open($command['command'], $descriptorsPec, $pipes, null, null); - if (is_resource($process)) { - $info = stream_get_contents($pipes[1]); - $info .= stream_get_contents($pipes[2]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - return self::outputFilter($info); - } - return ''; - } -} \ No newline at end of file diff --git a/niucloud/app/service/admin/article/ArticleCategoryService.php b/niucloud/app/service/admin/article/ArticleCategoryService.php index 406c1c62e..f99b5e648 100644 --- a/niucloud/app/service/admin/article/ArticleCategoryService.php +++ b/niucloud/app/service/admin/article/ArticleCategoryService.php @@ -37,7 +37,7 @@ class ArticleCategoryService extends BaseAdminService $field = 'category_id, site_id, name, sort, is_show, create_time, update_time'; $order = 'create_time desc'; - $search_model = $this->model->where([['site_id', '=', $this->site_id]])->withSearch(['name'], $where)->field($field)->order($order); + $search_model = $this->model->where([['site_id', '=', $this->site_id]])->withSearch(['name'], $where)->field($field)->order($order)->append(["article_num"]); $list = $this->pageQuery($search_model); return $list; } @@ -62,7 +62,7 @@ class ArticleCategoryService extends BaseAdminService { $field = 'category_id, site_id, name, sort, is_show, create_time, update_time'; - $info = $this->model->field($field)->where([['category_id', '=', $id], ['site_id', '=', $this->site_id]])->findOrEmpty()->toArray(); + $info = $this->model->field($field)->where([['category_id', '=', $id], ['site_id', '=', $this->site_id]])->append(["article_num"])->findOrEmpty()->toArray(); return $info; } diff --git a/niucloud/app/service/admin/article/ArticleService.php b/niucloud/app/service/admin/article/ArticleService.php index 81fd60e92..e7babdc85 100644 --- a/niucloud/app/service/admin/article/ArticleService.php +++ b/niucloud/app/service/admin/article/ArticleService.php @@ -38,7 +38,7 @@ class ArticleService extends BaseAdminService $where[] = [ 'site_id', '=', $this->site_id ]; $field = 'id, category_id, site_id, title, intro, summary, image, author, content, visit, visit_virtual, is_show, sort, create_time, update_time'; $order = 'create_time desc'; - $search_model = $this->model->where([ [ 'site_id', '=', $this->site_id ] ])->withSearch([ 'title', 'category_id', 'is_show'], $where)->with('articleCategory')->field($field)->order($order); + $search_model = $this->model->where([ [ 'site_id', '=', $this->site_id ] ])->withSearch([ 'title', 'category_id', 'is_show'], $where)->with('articleCategory')->field($field)->order($order)->append(['article_url']); $list = $this->pageQuery($search_model); return $list; } diff --git a/niucloud/app/service/admin/auth/AuthService.php b/niucloud/app/service/admin/auth/AuthService.php index 6713cceef..ab25ad248 100644 --- a/niucloud/app/service/admin/auth/AuthService.php +++ b/niucloud/app/service/admin/auth/AuthService.php @@ -11,6 +11,7 @@ namespace app\service\admin\auth; +use app\dict\site\SiteDict; use app\Request; use app\service\admin\site\SiteService; use app\service\admin\site\SiteUserService; @@ -66,6 +67,12 @@ class AuthService extends BaseAdminService $rule = trim(strtolower($request->rule()->getRule())); $method = trim(strtolower($request->method())); + $site_info = (new AuthSiteService())->getSiteInfo(); + if($method != 'get'){ + if($site_info['status'] == SiteDict::EXPIRE) throw new AuthException('SITE_EXPIRE_NOT_ALLOW'); + if($site_info['status'] == SiteDict::CLOSE) throw new AuthException('SITE_CLOSE_NOT_ALLOW'); + } + $menu_service = new MenuService(); $all_menu_list = $menu_service->getAllApiList($this->app_type); //先判断当前访问的接口是否收到权限的限制 @@ -104,7 +111,6 @@ class AuthService extends BaseAdminService if($is_admin){//查询全部启用的权限 //获取站点信息 return (new AuthSiteService())->getApiList(1); -// return $menu_service->getAllApiList($this->app_type, 1); }else{ $user_role_ids = $user_role_info['role_ids']; $role_service = new RoleService(); diff --git a/niucloud/app/service/admin/auth/AuthSiteService.php b/niucloud/app/service/admin/auth/AuthSiteService.php index 6ff51200e..3063ff1a8 100644 --- a/niucloud/app/service/admin/auth/AuthSiteService.php +++ b/niucloud/app/service/admin/auth/AuthSiteService.php @@ -44,13 +44,24 @@ class AuthSiteService extends BaseAdminService public function getSiteList(){ //通过用户id获取 $cache_name = 'site_list'.'_'.$this->uid; - return Cache::tag(SiteService::$cache_tag_name)->remember($cache_name, function (){ - $auth_service = new AuthService(); - $user_role_list = $auth_service->getAuthSiteRoleList(); - $site_ids = array_column($user_role_list, 'site_id'); - $site_list = $this->model->where([['site_id', 'in', $site_ids]])->field('app_type,site_name,logo')->column('site_id, site_name, logo, app_type'); - return $site_list; - }); + return cache_remember( + $cache_name, + function (){ + $auth_service = new AuthService(); + $user_role_list = $auth_service->getAuthSiteRoleList(); + $site_ids = array_column($user_role_list, 'site_id'); + $site_list = $this->model->where([['site_id', 'in', $site_ids]])->field('app_type,site_name,logo')->column('site_id, site_name, logo, app_type'); + return $site_list; + }, + SiteService::$cache_tag_name + ); +// return Cache::tag(SiteService::$cache_tag_name)->remember($cache_name, function (){ +// $auth_service = new AuthService(); +// $user_role_list = $auth_service->getAuthSiteRoleList(); +// $site_ids = array_column($user_role_list, 'site_id'); +// $site_list = $this->model->where([['site_id', 'in', $site_ids]])->field('app_type,site_name,logo')->column('site_id, site_name, logo, app_type'); +// return $site_list; +// }); } /** diff --git a/niucloud/app/service/admin/auth/ConfigService.php b/niucloud/app/service/admin/auth/ConfigService.php index e8a467c3e..df339059c 100644 --- a/niucloud/app/service/admin/auth/ConfigService.php +++ b/niucloud/app/service/admin/auth/ConfigService.php @@ -11,7 +11,7 @@ namespace app\service\admin\auth; -use app\enum\sys\ConfigKeyEnum; +use app\dict\sys\ConfigKeyDict; use app\model\sys\SysConfig; use app\service\core\sys\CoreConfigService; use core\base\BaseAdminService; @@ -36,7 +36,7 @@ class ConfigService extends BaseAdminService */ public function getConfig() { - $info = (new CoreConfigService())->getConfig($this->request->defaultSiteId(), ConfigKeyEnum::ADMIN_LOGIN)['value'] ?? []; + $info = (new CoreConfigService())->getConfig($this->request->defaultSiteId(), ConfigKeyDict::ADMIN_LOGIN)['value'] ?? []; $config = [ 'is_captcha' => $info['is_captcha'] ?? 0,//是否启用验证码 'is_site_captcha' => $info['is_site_captcha'] ?? 0,//是否启用站点验证码 @@ -60,7 +60,7 @@ class ConfigService extends BaseAdminService 'bg' => $data['bg'] ?? '',//平台登录端 背景 'site_bg' => $data['site_bg'] ?? '',//站点登录端 背景 ]; - (new CoreConfigService())->setConfig($this->site_id, ConfigKeyEnum::ADMIN_LOGIN, $config); + (new CoreConfigService())->setConfig($this->site_id, ConfigKeyDict::ADMIN_LOGIN, $config); return true; } diff --git a/niucloud/app/service/admin/auth/LoginService.php b/niucloud/app/service/admin/auth/LoginService.php index 69260ad45..ffd924ab6 100644 --- a/niucloud/app/service/admin/auth/LoginService.php +++ b/niucloud/app/service/admin/auth/LoginService.php @@ -11,7 +11,7 @@ namespace app\service\admin\auth; -use app\enum\sys\AppTypeEnum; +use app\dict\sys\AppTypeDict; use app\model\sys\SysUser; use app\service\admin\captcha\CaptchaService; use app\service\admin\site\SiteService; @@ -46,14 +46,14 @@ class LoginService extends BaseAdminService public function login(string $username, string $password, string $app_type) { - if(!in_array($app_type, array_keys(AppTypeEnum::getAppType()))) throw new AuthException('APP_TYPE_NOT_EXIST'); + if(!in_array($app_type, array_keys(AppTypeDict::getAppType()))) throw new AuthException('APP_TYPE_NOT_EXIST'); $config = (new ConfigService())->getConfig(); switch($app_type){ - case AppTypeEnum::SITE: + case AppTypeDict::SITE: $is_captcha = $config['is_site_captcha']; break; - case AppTypeEnum::ADMIN: + case AppTypeDict::ADMIN: $is_captcha = $config['is_captcha']; break; } @@ -71,15 +71,14 @@ class LoginService extends BaseAdminService } - if($app_type == AppTypeEnum::ADMIN){ + if($app_type == AppTypeDict::ADMIN){ $default_site_id = $this->request->defaultSiteId(); $userrole = (new UserRoleService())->getUserRole($default_site_id, $userinfo->uid); if(empty($userrole)) throw new AuthException('SITE_USER_CAN_NOT_LOGIN_IN_ADMIN'); - }else if($app_type == AppTypeEnum::SITE){ + }else if($app_type == AppTypeDict::SITE){ $default_site_id = (new UserRoleService())->getUserDefaultSiteId($userinfo->uid); - if(!($default_site_id > 0)){ - if(empty($userrole)) throw new AuthException('ADMIN_USER_CAN_NOT_LOGIN_IN_SITE'); - } + if(!($default_site_id > 0)) throw new AuthException('ADMIN_USER_CAN_NOT_LOGIN_IN_SITE'); + } //修改用户登录信息 $userinfo->last_time = time(); @@ -121,7 +120,7 @@ class LoginService extends BaseAdminService public function createToken(SysUser $userinfo, string $app_type) { $expire_time = env('system.admin_token_expire_time') ?? 3600; - $token_info = TokenAuth::createToken($userinfo->uid, AppTypeEnum::ADMIN, ['uid' => $userinfo->uid, 'username' => $userinfo->username], $expire_time); + $token_info = TokenAuth::createToken($userinfo->uid, AppTypeDict::ADMIN, ['uid' => $userinfo->uid, 'username' => $userinfo->username], $expire_time); return $token_info; } @@ -133,8 +132,8 @@ class LoginService extends BaseAdminService public static function clearToken(int $uid, ?string $type = '', ?string $token = '') { if (empty($type)) { - TokenAuth::clearToken($uid, AppTypeEnum::ADMIN, $token);//清除平台管理端的token -// TokenAuth::clearToken($uid, AppTypeEnum::SITE, $token);//清除站点管理端的token + TokenAuth::clearToken($uid, AppTypeDict::ADMIN, $token);//清除平台管理端的token +// TokenAuth::clearToken($uid, AppTypeDict::SITE, $token);//清除站点管理端的token } else { TokenAuth::clearToken($uid, $type, $token); } @@ -155,7 +154,7 @@ class LoginService extends BaseAdminService } //暴力操作,截停所有异常覆盖为token失效 try { - $token_info = TokenAuth::parseToken($token, AppTypeEnum::ADMIN); + $token_info = TokenAuth::parseToken($token, AppTypeDict::ADMIN); } catch ( \Throwable $e ) { // if(env('app_debug', false)){ // throw new AuthException($e->getMessage(), 401); diff --git a/niucloud/app/service/admin/channel/H5Service.php b/niucloud/app/service/admin/channel/H5Service.php index d068771ea..cd3cf3160 100644 --- a/niucloud/app/service/admin/channel/H5Service.php +++ b/niucloud/app/service/admin/channel/H5Service.php @@ -11,7 +11,7 @@ namespace app\service\admin\channel; -use app\enum\sys\ConfigKeyEnum; +use app\dict\sys\ConfigKeyDict; use app\service\core\channel\CoreH5Service; use app\service\core\sys\CoreConfigService; use core\base\BaseAdminService; @@ -42,7 +42,7 @@ class H5Service extends BaseAdminService $data = [ 'is_open' => $value['is_open'] ]; - $res = $this->core_config_service->setConfig($this->site_id,ConfigKeyEnum::H5, $data); + $res = $this->core_config_service->setConfig($this->site_id,ConfigKeyDict::H5, $data); return $res; } diff --git a/niucloud/app/service/admin/cron/CronService.php b/niucloud/app/service/admin/cron/CronService.php index 82c7d80c9..e4fe5ee95 100644 --- a/niucloud/app/service/admin/cron/CronService.php +++ b/niucloud/app/service/admin/cron/CronService.php @@ -11,7 +11,7 @@ namespace app\service\admin\cron; -use app\service\core\cron\CoreCronService; +use app\service\core\schedule\CoreCronService; use core\base\BaseAdminService; /** diff --git a/niucloud/app/service/admin/diy/DiyRouteService.php b/niucloud/app/service/admin/diy/DiyRouteService.php index de2608cfe..84adeea48 100644 --- a/niucloud/app/service/admin/diy/DiyRouteService.php +++ b/niucloud/app/service/admin/diy/DiyRouteService.php @@ -11,7 +11,7 @@ namespace app\service\admin\diy; -use app\enum\diy\LinkEnum; +use app\dict\diy\LinkDict; use app\model\diy\DiyRoute; use core\base\BaseAdminService; @@ -36,7 +36,7 @@ class DiyRouteService extends BaseAdminService */ public function getList(array $where = []) { - $link = LinkEnum::getLink(); + $link = LinkDict::getLink(); $diy_route_list = []; $sort = 0; foreach ($link as $k => $v) { diff --git a/niucloud/app/service/admin/diy/DiyService.php b/niucloud/app/service/admin/diy/DiyService.php index 1250cf897..776740e8f 100644 --- a/niucloud/app/service/admin/diy/DiyService.php +++ b/niucloud/app/service/admin/diy/DiyService.php @@ -11,9 +11,10 @@ namespace app\service\admin\diy; -use app\enum\diy\ComponentEnum; -use app\enum\diy\LinkEnum; -use app\enum\diy\PageEnum; +use app\dict\diy\ComponentDict; +use app\dict\diy\LinkDict; +use app\dict\diy\PagesDict; +use app\dict\diy\TemplateDict; use app\model\diy\Diy; use app\service\admin\sys\SystemService; use core\base\BaseAdminService; @@ -162,7 +163,7 @@ class DiyService extends BaseAdminService */ public function getInit(array $params = []) { - $page_type = PageEnum::getPageType(); + $page_template = TemplateDict::getTemplate(); $time = time(); $data = []; @@ -173,23 +174,32 @@ class DiyService extends BaseAdminService } if (!empty($data)) { - if (isset($page_type[ $data[ 'type' ] ])) { - $page = $page_type[ $data[ 'type' ] ]; + // 编辑赋值 + if (isset($page_template[ $data[ 'type' ] ])) { + $page = $page_template[ $data[ 'type' ] ]; $data[ 'type_name' ] = $page[ 'title' ]; $data[ 'page' ] = $page[ 'page' ]; } } else { - // 空页面赋值 + // 新页面赋值 $type = 'DIY_PAGE'; $type_name = ''; $name = $params[ 'name' ]; $page_route = ''; - if (isset($page_type[ $params[ 'type' ] ])) { - $page = $page_type[ $params[ 'type' ] ]; - $name = $params[ 'type' ] == 'DIY_PAGE' ? 'DIY_PAGE_RANDOM_' . $time : $params[ 'type' ]; - $type = $params[ 'type' ]; + $value = ''; + if (isset($page_template[ $params[ 'template' ] ])) { + $page = $page_template[ $params[ 'template' ] ]; + $name = $params[ 'template' ] == 'DIY_PAGE' ? 'DIY_PAGE_RANDOM_' . $time : $params[ 'template' ]; + $type = $params[ 'template' ]; $type_name = $page[ 'title' ]; $page_route = $page[ 'page' ]; + + // 查询指定页面数据 + $page_data = $this->getPageData($params[ 'template' ], $params[ 'template_name' ]); + if (!empty($page_data)) { + $value = json_encode($page_data[ 'data' ], JSON_UNESCAPED_UNICODE); + } + } $data = [ 'name' => $name, @@ -197,15 +207,24 @@ class DiyService extends BaseAdminService 'type' => $type, 'type_name' => $type_name, 'page' => $page_route, - 'value' => '', + 'value' => $value, + 'is_default' => 0 ]; - if (isset($page_type[ $params[ 'name' ] ])) { - $page = $page_type[ $params[ 'name' ] ]; - $data[ 'name' ] = $params[ 'type' ]; + if (isset($page_template[ $params[ 'name' ] ])) { + $page = $page_template[ $params[ 'name' ] ]; + $data[ 'name' ] = $params[ 'template' ] ? $params[ 'template' ] : $params[ 'name' ]; + $data[ 'type' ] = $data[ 'name' ]; $data[ 'title' ] = $page[ 'title' ]; $data[ 'type_name' ] = $page[ 'title' ]; $data[ 'page' ] = $page[ 'page' ]; + + // 查询默认页面数据 + $page_data = $this->getFirstPageData($data[ 'name' ]); + if (!empty($page_data)) { + $data[ 'value' ] = json_encode($page_data[ 'data' ], JSON_UNESCAPED_UNICODE); + $data[ 'is_default' ] = 1; + } } } $data[ 'component' ] = $this->getComponentList($data[ 'name' ]); @@ -220,7 +239,7 @@ class DiyService extends BaseAdminService */ public function getComponentList(string $name = '') { - $data = ComponentEnum::getComponent(); + $data = ComponentDict::getComponent(); foreach ($data as $k => $v) { // 查询组件支持的页面 $sort_arr = []; @@ -247,16 +266,17 @@ class DiyService extends BaseAdminService */ public function getLink() { - $link = LinkEnum::getLink(); + $link = LinkDict::getLink(); foreach ($link as $k => $v) { + $link[ $k ][ 'name' ] = $k; if (!empty($v[ 'child_list' ])) { foreach ($v[ 'child_list' ] as $ck => $cv) { - $link[ $k ][ 'child_list' ][ $ck ][ 'parent' ] = $v[ 'name' ]; + $link[ $k ][ 'child_list' ][ $ck ][ 'parent' ] = $k; } } // 查询自定义页面 - if ($v[ 'name' ] == 'DIY_PAGE') { + if ($k == 'DIY_PAGE') { $diy_service = new DiyService(); $list = $diy_service->getList([ [ 'type', '=', 'DIY_PAGE' ] ]); foreach ($list as $ck => $cv) { @@ -269,7 +289,7 @@ class DiyService extends BaseAdminService } - if ($v[ 'name' ] == 'DIY_LINK') { + if ($k == 'DIY_LINK') { $link[ $k ][ 'parent' ] = 'DIY_LINK'; } @@ -289,5 +309,50 @@ class DiyService extends BaseAdminService return true; } + /** + * 获取页面模板 + * @param string $type + * @return array|string + */ + public function getTemplate(string $type) + { + $page_template = TemplateDict::getTemplate($type); + foreach ($page_template as $k => $v) { + // 查询页面数据 + $page_template[ $k ][ 'template' ] = PagesDict::getPages($k); + } + return $page_template; + } + + /** + * 获取页面数据 + * @param $template + * @param $name + * @return array + */ + public function getPageData($template, $name) + { + $pages = PagesDict::getPages($template); + if (isset($pages[ $name ])) { + return $pages[ $name ]; + } + return []; + } + + /** + * 获取默认页面数据 + * @param $template + * @return array|mixed + */ + public function getFirstPageData($template) + { + $pages = PagesDict::getPages($template); + if (!empty($pages)) { + $page = array_shift($pages); + $page[ 'template' ] = $template; + return $page; + } + return []; + } } \ No newline at end of file diff --git a/niucloud/app/service/admin/file/StorageConfigService.php b/niucloud/app/service/admin/file/StorageConfigService.php index 121317c77..326dda844 100644 --- a/niucloud/app/service/admin/file/StorageConfigService.php +++ b/niucloud/app/service/admin/file/StorageConfigService.php @@ -11,7 +11,7 @@ namespace app\service\admin\file; -use app\enum\sys\StorageEnum; +use app\dict\sys\StorageDict; use app\service\core\upload\CoreStorageService; use app\service\core\sys\CoreConfigService; use core\base\BaseAdminService; @@ -46,7 +46,7 @@ class StorageConfigService extends BaseAdminService */ public function getStorageConfig(string $storage_type) { - $storage_type_list = StorageEnum::getType(); + $storage_type_list = StorageDict::getType(); if(!array_key_exists($storage_type, $storage_type_list)) throw new AdminException('OSS_TYPE_NOT_EXIST'); $info = (new CoreConfigService())->getConfig($this->site_id, 'STORAGE'); if(empty($info)) @@ -57,7 +57,7 @@ class StorageConfigService extends BaseAdminService $data = [ 'storage_type' => $storage_type, - 'is_use' => $storage_type == $config_type['default'] ? StorageEnum::ON : StorageEnum::OFF, + 'is_use' => $storage_type == $config_type['default'] ? StorageDict::ON : StorageDict::OFF, 'name' => $storage_type_list[$storage_type]['name'], ]; foreach ($storage_type_list[$storage_type]['params'] as $k_param => $v_param) @@ -79,7 +79,7 @@ class StorageConfigService extends BaseAdminService */ public function setStorageConfig(string $storage_type, array $data) { - $storage_type_list = StorageEnum::getType(); + $storage_type_list = StorageDict::getType(); if(!array_key_exists($storage_type, $storage_type_list)) throw new AdminException('OSS_TYPE_NOT_EXIST'); $info = (new CoreConfigService())->getConfig($this->site_id, 'STORAGE'); if(empty($info)) diff --git a/niucloud/app/service/admin/file/UploadService.php b/niucloud/app/service/admin/file/UploadService.php index 91b608f50..e6ba3dac5 100644 --- a/niucloud/app/service/admin/file/UploadService.php +++ b/niucloud/app/service/admin/file/UploadService.php @@ -11,7 +11,7 @@ namespace app\service\admin\file; -use app\enum\sys\FileEnum; +use app\dict\sys\FileDict; use app\service\core\upload\CoreUploadService; use core\base\BaseAdminService; use core\exception\UploadFileException; @@ -58,7 +58,7 @@ class UploadService extends BaseAdminService * @return array */ public function document($file, string $type,bool $is_local = false){ - if(!in_array($type, FileEnum::getSceneType())) + if(!in_array($type, FileDict::getSceneType())) throw new UploadFileException('CERT_TYPE_ERROR'); $dir = $this->root_path.'/document/'.$type.'/'.$this->site_id.'/'.date('Ym').'/'.date('d'); $core_upload_service = new CoreUploadService(); diff --git a/niucloud/app/service/admin/generator/Generate.php b/niucloud/app/service/admin/generator/Generate.php index 7015bd08c..9fb04403e 100644 --- a/niucloud/app/service/admin/generator/Generate.php +++ b/niucloud/app/service/admin/generator/Generate.php @@ -63,7 +63,7 @@ class Generate public function delOutFiles() { // 删除runtime目录制定文件夹 - !is_dir($this->outPath) && mkdir($this->outPath, 0755, true); + !is_dir($this->outPath) && mkdirs($this->outPath, 0777, true); del_target_dir($this->outPath, false); } diff --git a/niucloud/app/service/admin/generator/GenerateService.php b/niucloud/app/service/admin/generator/GenerateService.php index 0d86c2713..bd24e3676 100644 --- a/niucloud/app/service/admin/generator/GenerateService.php +++ b/niucloud/app/service/admin/generator/GenerateService.php @@ -272,7 +272,7 @@ class GenerateService extends BaseAdminService */ public static function getDbFieldType(string $type): string { - if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { + if (0 === strpos($type, 'set') || 0 === strpos($type, 'dict')) { $result = 'string'; } elseif (preg_match('/(double|float|decimal|real|numeric)/is', $type)) { $result = 'float'; diff --git a/niucloud/app/service/admin/generator/core/BaseGenerator.php b/niucloud/app/service/admin/generator/core/BaseGenerator.php index 450f26668..6647e00fc 100644 --- a/niucloud/app/service/admin/generator/core/BaseGenerator.php +++ b/niucloud/app/service/admin/generator/core/BaseGenerator.php @@ -171,7 +171,7 @@ abstract class BaseGenerator */ public function checkDir(string $path) { - !is_dir($path) && mkdirs($path, 0755, true); + !is_dir($path) && mkdir($path, 0777, true); } /** @@ -316,7 +316,7 @@ abstract class BaseGenerator */ public function getDefault(string $type) { - if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { + if (0 === strpos($type, 'set') || 0 === strpos($type, 'dict')) { $result = '""'; } elseif (preg_match('/(int|serial|bit)/is', $type)) { $result = '0'; @@ -342,7 +342,7 @@ abstract class BaseGenerator */ public function getAuthor() { - return empty($this->table['author']) ? 'Niushop team' : $this->table['author']; + return empty($this->table['author']) ? 'Niucloud team' : $this->table['author']; } diff --git a/niucloud/app/service/admin/generator/core/WebApiGenerator.php b/niucloud/app/service/admin/generator/core/WebApiGenerator.php index 49c2162c8..8e7626b9c 100644 --- a/niucloud/app/service/admin/generator/core/WebApiGenerator.php +++ b/niucloud/app/service/admin/generator/core/WebApiGenerator.php @@ -61,7 +61,7 @@ class WebApiGenerator extends BaseGenerator */ public function getModuleOutDir() { - $dir = dirname(app()->getRootPath()) . '/admin-niushop/src/api/'; + $dir = dirname(app()->getRootPath()) . '/admin/src/api/'; $this->checkDir($dir); return $dir; } diff --git a/niucloud/app/service/admin/generator/vm/admin_api_route.vm b/niucloud/app/service/admin/generator/vm/admin_api_route.vm index 36b472d43..af5842563 100644 --- a/niucloud/app/service/admin/generator/vm/admin_api_route.vm +++ b/niucloud/app/service/admin/generator/vm/admin_api_route.vm @@ -1,12 +1,12 @@ +// | Author: Niucloud Team // +---------------------------------------------------------------------- use think\facade\Route; diff --git a/niucloud/app/service/admin/generator/vm/web_edit.vm b/niucloud/app/service/admin/generator/vm/web_edit.vm index c4c56b8ae..d3a12e836 100644 --- a/niucloud/app/service/admin/generator/vm/web_edit.vm +++ b/niucloud/app/service/admin/generator/vm/web_edit.vm @@ -64,7 +64,6 @@ const confirm = async (formEl: FormInstance | undefined) => { emit('complete') }).catch(err => { loading.value = false - showDialog.value = false }) } }) diff --git a/niucloud/app/service/admin/generator/vm/web_index.vm b/niucloud/app/service/admin/generator/vm/web_index.vm index 266f54010..719e14797 100644 --- a/niucloud/app/service/admin/generator/vm/web_index.vm +++ b/niucloud/app/service/admin/generator/vm/web_index.vm @@ -1,14 +1,15 @@