From 11e840028f3774ddd40c593903d54b063e26996c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E5=9B=BD?= <854933521@qq.com> Date: Mon, 14 Oct 2024 15:36:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 11 + .env.production | 14 + .env.staging | 12 + .gitignore | 23 + .npmrc | 5 + LICENSE | 20 + README.md | 109 ++ bin/build.bat | 12 + bin/package.bat | 12 + bin/run-web.bat | 12 + dist-electron/main.js | 40 + html/ie.html | 46 + index.html | 219 ++++ package.json | 86 ++ public/app.ico | Bin 0 -> 40522 bytes public/favicon.ico | Bin 0 -> 5663 bytes public/properties.js | 15 + server/index.js | 21 + src-electron/main.js | 57 + src/App.vue | 15 + src/api/login.js | 60 + src/api/menu.js | 9 + src/api/monitor/cache.js | 57 + src/api/monitor/job.js | 71 ++ src/api/monitor/jobLog.js | 26 + src/api/monitor/logininfor.js | 34 + src/api/monitor/online.js | 18 + src/api/monitor/operlog.js | 26 + src/api/monitor/server.js | 9 + src/api/system/config.js | 60 + src/api/system/dept.js | 52 + src/api/system/dict/data.js | 52 + src/api/system/dict/type.js | 60 + src/api/system/menu.js | 60 + src/api/system/notice.js | 44 + src/api/system/post.js | 44 + src/api/system/role.js | 119 ++ src/api/system/user.js | 136 ++ src/api/tool/gen.js | 85 ++ src/assets/401_images/401.gif | Bin 0 -> 164227 bytes src/assets/404_images/404.png | Bin 0 -> 98071 bytes src/assets/404_images/404_cloud.png | Bin 0 -> 4766 bytes src/assets/icons/svg/404.svg | 1 + src/assets/icons/svg/bug.svg | 1 + src/assets/icons/svg/build.svg | 1 + src/assets/icons/svg/button.svg | 1 + src/assets/icons/svg/cascader.svg | 1 + src/assets/icons/svg/chart.svg | 1 + src/assets/icons/svg/checkbox.svg | 1 + src/assets/icons/svg/clipboard.svg | 1 + src/assets/icons/svg/code.svg | 1 + src/assets/icons/svg/color.svg | 1 + src/assets/icons/svg/component.svg | 1 + src/assets/icons/svg/dashboard.svg | 1 + src/assets/icons/svg/date-range.svg | 1 + src/assets/icons/svg/date.svg | 1 + src/assets/icons/svg/dict.svg | 1 + src/assets/icons/svg/documentation.svg | 1 + src/assets/icons/svg/download.svg | 1 + src/assets/icons/svg/drag.svg | 1 + src/assets/icons/svg/druid.svg | 1 + src/assets/icons/svg/edit.svg | 1 + src/assets/icons/svg/education.svg | 1 + src/assets/icons/svg/email.svg | 1 + src/assets/icons/svg/example.svg | 1 + src/assets/icons/svg/excel.svg | 1 + src/assets/icons/svg/exit-fullscreen.svg | 1 + src/assets/icons/svg/eye-open.svg | 1 + src/assets/icons/svg/eye.svg | 1 + src/assets/icons/svg/form.svg | 1 + src/assets/icons/svg/fullscreen.svg | 1 + src/assets/icons/svg/github.svg | 1 + src/assets/icons/svg/guide.svg | 1 + src/assets/icons/svg/icon.svg | 1 + src/assets/icons/svg/input.svg | 1 + src/assets/icons/svg/international.svg | 1 + src/assets/icons/svg/job.svg | 1 + src/assets/icons/svg/language.svg | 1 + src/assets/icons/svg/link.svg | 1 + src/assets/icons/svg/list.svg | 1 + src/assets/icons/svg/lock.svg | 1 + src/assets/icons/svg/log.svg | 1 + src/assets/icons/svg/logininfor.svg | 1 + src/assets/icons/svg/message.svg | 1 + src/assets/icons/svg/money.svg | 1 + src/assets/icons/svg/monitor.svg | 2 + src/assets/icons/svg/nested.svg | 1 + src/assets/icons/svg/number.svg | 1 + src/assets/icons/svg/online.svg | 1 + src/assets/icons/svg/password.svg | 1 + src/assets/icons/svg/pdf.svg | 1 + src/assets/icons/svg/people.svg | 1 + src/assets/icons/svg/peoples.svg | 1 + src/assets/icons/svg/phone.svg | 1 + src/assets/icons/svg/post.svg | 1 + src/assets/icons/svg/qq.svg | 1 + src/assets/icons/svg/question.svg | 1 + src/assets/icons/svg/radio.svg | 1 + src/assets/icons/svg/rate.svg | 1 + src/assets/icons/svg/redis-list.svg | 2 + src/assets/icons/svg/redis.svg | 1 + src/assets/icons/svg/row.svg | 1 + src/assets/icons/svg/search.svg | 1 + src/assets/icons/svg/select.svg | 1 + src/assets/icons/svg/server.svg | 1 + src/assets/icons/svg/shopping.svg | 1 + src/assets/icons/svg/size.svg | 1 + src/assets/icons/svg/skill.svg | 1 + src/assets/icons/svg/slider.svg | 1 + src/assets/icons/svg/star.svg | 1 + src/assets/icons/svg/swagger.svg | 1 + src/assets/icons/svg/switch.svg | 1 + src/assets/icons/svg/system.svg | 2 + src/assets/icons/svg/tab.svg | 1 + src/assets/icons/svg/table.svg | 1 + src/assets/icons/svg/textarea.svg | 1 + src/assets/icons/svg/theme.svg | 1 + src/assets/icons/svg/time-range.svg | 1 + src/assets/icons/svg/time.svg | 1 + src/assets/icons/svg/tool.svg | 1 + src/assets/icons/svg/tree-table.svg | 1 + src/assets/icons/svg/tree.svg | 1 + src/assets/icons/svg/upload.svg | 1 + src/assets/icons/svg/user.svg | 1 + src/assets/icons/svg/validCode.svg | 1 + src/assets/icons/svg/wechat.svg | 1 + src/assets/icons/svg/zip.svg | 1 + src/assets/images/dark.svg | 39 + src/assets/images/light.svg | 39 + src/assets/images/login-background.jpg | Bin 0 -> 521275 bytes src/assets/images/pay.png | Bin 0 -> 140720 bytes src/assets/images/profile.jpg | Bin 0 -> 81131 bytes src/assets/logo/logo.png | Bin 0 -> 5663 bytes src/assets/styles/btn.scss | 99 ++ src/assets/styles/element-ui.scss | 96 ++ src/assets/styles/index.scss | 184 +++ src/assets/styles/mixin.scss | 66 + src/assets/styles/ruoyi.scss | 281 +++++ src/assets/styles/sidebar.scss | 238 ++++ src/assets/styles/transition.scss | 49 + src/assets/styles/variables.module.scss | 65 + src/components/Breadcrumb/index.vue | 66 + src/components/Crontab/day.vue | 174 +++ src/components/Crontab/hour.vue | 133 ++ src/components/Crontab/index.vue | 310 +++++ src/components/Crontab/min.vue | 126 ++ src/components/Crontab/month.vue | 141 +++ src/components/Crontab/result.vue | 540 ++++++++ src/components/Crontab/second.vue | 128 ++ src/components/Crontab/week.vue | 197 +++ src/components/Crontab/year.vue | 149 +++ src/components/DictTag/index.vue | 82 ++ src/components/Editor/index.vue | 251 ++++ src/components/FileUpload/index.vue | 207 ++++ src/components/Hamburger/index.vue | 41 + src/components/HeaderSearch/index.vue | 187 +++ src/components/IconSelect/index.vue | 111 ++ src/components/IconSelect/requireIcons.js | 8 + src/components/ImagePreview/index.vue | 92 ++ src/components/ImageUpload/index.vue | 213 ++++ src/components/Pagination/index.vue | 105 ++ src/components/ParentView/index.vue | 3 + src/components/RightToolbar/index.vue | 134 ++ src/components/RuoYi/Doc/index.vue | 13 + src/components/RuoYi/Git/index.vue | 13 + src/components/Screenfull/index.vue | 22 + src/components/SizeSelect/index.vue | 45 + src/components/SvgIcon/index.vue | 53 + src/components/SvgIcon/svgicon.js | 10 + src/components/TopNav/index.vue | 214 ++++ src/components/TreeSelect/index.vue | 156 +++ src/components/iFrame/index.vue | 31 + src/directive/common/copyText.js | 66 + src/directive/index.js | 9 + src/directive/permission/hasPermi.js | 28 + src/directive/permission/hasRole.js | 28 + src/layout/components/AppMain.vue | 68 + src/layout/components/IframeToggle/index.vue | 25 + src/layout/components/InnerLink/index.vue | 24 + src/layout/components/Navbar.vue | 191 +++ src/layout/components/Settings/index.vue | 209 ++++ src/layout/components/Sidebar/Link.vue | 40 + src/layout/components/Sidebar/Logo.vue | 81 ++ src/layout/components/Sidebar/SidebarItem.vue | 102 ++ src/layout/components/Sidebar/index.vue | 54 + src/layout/components/TagsView/ScrollPane.vue | 107 ++ src/layout/components/TagsView/index.vue | 358 ++++++ src/layout/components/index.js | 4 + src/layout/index.vue | 114 ++ src/main.js | 84 ++ src/permission.js | 65 + src/plugins/auth.js | 60 + src/plugins/cache.js | 77 ++ src/plugins/download.js | 79 ++ src/plugins/index.js | 18 + src/plugins/modal.js | 82 ++ src/plugins/tab.js | 69 ++ src/router/index.js | 175 +++ src/settings.js | 47 + src/store/index.js | 3 + src/store/modules/app.js | 46 + src/store/modules/dict.js | 57 + src/store/modules/permission.js | 142 +++ src/store/modules/settings.js | 38 + src/store/modules/socket.js | 11 + src/store/modules/tagsView.js | 182 +++ src/store/modules/user.js | 72 ++ src/utils/auth.js | 15 + src/utils/dict.js | 24 + src/utils/dynamicTitle.js | 15 + src/utils/errorCode.js | 6 + src/utils/index.js | 390 ++++++ src/utils/jsencrypt.js | 30 + src/utils/permission.js | 51 + src/utils/request.js | 152 +++ src/utils/ruoyi.js | 246 ++++ src/utils/scroll-to.js | 58 + src/utils/socketUtil.js | 17 + src/utils/theme.js | 49 + src/utils/validate.js | 93 ++ src/utils/websocket.js | 163 +++ src/views/error/401.vue | 82 ++ src/views/error/404.vue | 227 ++++ src/views/index.vue | 1092 +++++++++++++++++ src/views/login.vue | 252 ++++ src/views/monitor/cache/index.vue | 132 ++ src/views/monitor/cache/list.vue | 246 ++++ src/views/monitor/druid/index.vue | 13 + src/views/monitor/job/index.vue | 501 ++++++++ src/views/monitor/job/log.vue | 283 +++++ src/views/monitor/logininfor/index.vue | 233 ++++ src/views/monitor/online/index.vue | 109 ++ src/views/monitor/operlog/index.vue | 310 +++++ src/views/monitor/server/index.vue | 187 +++ src/views/redirect/index.vue | 14 + src/views/register.vue | 218 ++++ src/views/system/config/index.vue | 316 +++++ src/views/system/dept/index.vue | 283 +++++ src/views/system/dict/data.vue | 362 ++++++ src/views/system/dict/index.vue | 323 +++++ src/views/system/menu/index.vue | 452 +++++++ src/views/system/notice/index.vue | 292 +++++ src/views/system/post/index.vue | 287 +++++ src/views/system/role/authUser.vue | 179 +++ src/views/system/role/index.vue | 584 +++++++++ src/views/system/role/selectUser.vue | 144 +++ src/views/system/user/authRole.vue | 116 ++ src/views/system/user/index.vue | 635 ++++++++++ src/views/system/user/profile/index.vue | 87 ++ src/views/system/user/profile/resetPwd.vue | 59 + src/views/system/user/profile/userAvatar.vue | 180 +++ src/views/system/user/profile/userInfo.vue | 67 + src/views/tool/build/index.vue | 3 + src/views/tool/gen/basicInfoForm.vue | 48 + src/views/tool/gen/createTable.vue | 46 + src/views/tool/gen/editTable.vue | 200 +++ src/views/tool/gen/genInfoForm.vue | 306 +++++ src/views/tool/gen/importTable.vue | 126 ++ src/views/tool/gen/index.vue | 310 +++++ src/views/tool/swagger/index.vue | 9 + vite.config.js | 66 + vite/plugins/auto-import.js | 12 + vite/plugins/compression.js | 28 + vite/plugins/index.js | 15 + vite/plugins/setup-extend.js | 5 + vite/plugins/svg-icon.js | 10 + 266 files changed, 20523 insertions(+) create mode 100644 .env.development create mode 100644 .env.production create mode 100644 .env.staging create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 LICENSE create mode 100644 README.md create mode 100644 bin/build.bat create mode 100644 bin/package.bat create mode 100644 bin/run-web.bat create mode 100644 dist-electron/main.js create mode 100644 html/ie.html create mode 100644 index.html create mode 100644 package.json create mode 100644 public/app.ico create mode 100644 public/favicon.ico create mode 100644 public/properties.js create mode 100644 server/index.js create mode 100644 src-electron/main.js create mode 100644 src/App.vue create mode 100644 src/api/login.js create mode 100644 src/api/menu.js create mode 100644 src/api/monitor/cache.js create mode 100644 src/api/monitor/job.js create mode 100644 src/api/monitor/jobLog.js create mode 100644 src/api/monitor/logininfor.js create mode 100644 src/api/monitor/online.js create mode 100644 src/api/monitor/operlog.js create mode 100644 src/api/monitor/server.js create mode 100644 src/api/system/config.js create mode 100644 src/api/system/dept.js create mode 100644 src/api/system/dict/data.js create mode 100644 src/api/system/dict/type.js create mode 100644 src/api/system/menu.js create mode 100644 src/api/system/notice.js create mode 100644 src/api/system/post.js create mode 100644 src/api/system/role.js create mode 100644 src/api/system/user.js create mode 100644 src/api/tool/gen.js create mode 100644 src/assets/401_images/401.gif create mode 100644 src/assets/404_images/404.png create mode 100644 src/assets/404_images/404_cloud.png create mode 100644 src/assets/icons/svg/404.svg create mode 100644 src/assets/icons/svg/bug.svg create mode 100644 src/assets/icons/svg/build.svg create mode 100644 src/assets/icons/svg/button.svg create mode 100644 src/assets/icons/svg/cascader.svg create mode 100644 src/assets/icons/svg/chart.svg create mode 100644 src/assets/icons/svg/checkbox.svg create mode 100644 src/assets/icons/svg/clipboard.svg create mode 100644 src/assets/icons/svg/code.svg create mode 100644 src/assets/icons/svg/color.svg create mode 100644 src/assets/icons/svg/component.svg create mode 100644 src/assets/icons/svg/dashboard.svg create mode 100644 src/assets/icons/svg/date-range.svg create mode 100644 src/assets/icons/svg/date.svg create mode 100644 src/assets/icons/svg/dict.svg create mode 100644 src/assets/icons/svg/documentation.svg create mode 100644 src/assets/icons/svg/download.svg create mode 100644 src/assets/icons/svg/drag.svg create mode 100644 src/assets/icons/svg/druid.svg create mode 100644 src/assets/icons/svg/edit.svg create mode 100644 src/assets/icons/svg/education.svg create mode 100644 src/assets/icons/svg/email.svg create mode 100644 src/assets/icons/svg/example.svg create mode 100644 src/assets/icons/svg/excel.svg create mode 100644 src/assets/icons/svg/exit-fullscreen.svg create mode 100644 src/assets/icons/svg/eye-open.svg create mode 100644 src/assets/icons/svg/eye.svg create mode 100644 src/assets/icons/svg/form.svg create mode 100644 src/assets/icons/svg/fullscreen.svg create mode 100644 src/assets/icons/svg/github.svg create mode 100644 src/assets/icons/svg/guide.svg create mode 100644 src/assets/icons/svg/icon.svg create mode 100644 src/assets/icons/svg/input.svg create mode 100644 src/assets/icons/svg/international.svg create mode 100644 src/assets/icons/svg/job.svg create mode 100644 src/assets/icons/svg/language.svg create mode 100644 src/assets/icons/svg/link.svg create mode 100644 src/assets/icons/svg/list.svg create mode 100644 src/assets/icons/svg/lock.svg create mode 100644 src/assets/icons/svg/log.svg create mode 100644 src/assets/icons/svg/logininfor.svg create mode 100644 src/assets/icons/svg/message.svg create mode 100644 src/assets/icons/svg/money.svg create mode 100644 src/assets/icons/svg/monitor.svg create mode 100644 src/assets/icons/svg/nested.svg create mode 100644 src/assets/icons/svg/number.svg create mode 100644 src/assets/icons/svg/online.svg create mode 100644 src/assets/icons/svg/password.svg create mode 100644 src/assets/icons/svg/pdf.svg create mode 100644 src/assets/icons/svg/people.svg create mode 100644 src/assets/icons/svg/peoples.svg create mode 100644 src/assets/icons/svg/phone.svg create mode 100644 src/assets/icons/svg/post.svg create mode 100644 src/assets/icons/svg/qq.svg create mode 100644 src/assets/icons/svg/question.svg create mode 100644 src/assets/icons/svg/radio.svg create mode 100644 src/assets/icons/svg/rate.svg create mode 100644 src/assets/icons/svg/redis-list.svg create mode 100644 src/assets/icons/svg/redis.svg create mode 100644 src/assets/icons/svg/row.svg create mode 100644 src/assets/icons/svg/search.svg create mode 100644 src/assets/icons/svg/select.svg create mode 100644 src/assets/icons/svg/server.svg create mode 100644 src/assets/icons/svg/shopping.svg create mode 100644 src/assets/icons/svg/size.svg create mode 100644 src/assets/icons/svg/skill.svg create mode 100644 src/assets/icons/svg/slider.svg create mode 100644 src/assets/icons/svg/star.svg create mode 100644 src/assets/icons/svg/swagger.svg create mode 100644 src/assets/icons/svg/switch.svg create mode 100644 src/assets/icons/svg/system.svg create mode 100644 src/assets/icons/svg/tab.svg create mode 100644 src/assets/icons/svg/table.svg create mode 100644 src/assets/icons/svg/textarea.svg create mode 100644 src/assets/icons/svg/theme.svg create mode 100644 src/assets/icons/svg/time-range.svg create mode 100644 src/assets/icons/svg/time.svg create mode 100644 src/assets/icons/svg/tool.svg create mode 100644 src/assets/icons/svg/tree-table.svg create mode 100644 src/assets/icons/svg/tree.svg create mode 100644 src/assets/icons/svg/upload.svg create mode 100644 src/assets/icons/svg/user.svg create mode 100644 src/assets/icons/svg/validCode.svg create mode 100644 src/assets/icons/svg/wechat.svg create mode 100644 src/assets/icons/svg/zip.svg create mode 100644 src/assets/images/dark.svg create mode 100644 src/assets/images/light.svg create mode 100644 src/assets/images/login-background.jpg create mode 100644 src/assets/images/pay.png create mode 100644 src/assets/images/profile.jpg create mode 100644 src/assets/logo/logo.png create mode 100644 src/assets/styles/btn.scss create mode 100644 src/assets/styles/element-ui.scss create mode 100644 src/assets/styles/index.scss create mode 100644 src/assets/styles/mixin.scss create mode 100644 src/assets/styles/ruoyi.scss create mode 100644 src/assets/styles/sidebar.scss create mode 100644 src/assets/styles/transition.scss create mode 100644 src/assets/styles/variables.module.scss create mode 100644 src/components/Breadcrumb/index.vue create mode 100644 src/components/Crontab/day.vue create mode 100644 src/components/Crontab/hour.vue create mode 100644 src/components/Crontab/index.vue create mode 100644 src/components/Crontab/min.vue create mode 100644 src/components/Crontab/month.vue create mode 100644 src/components/Crontab/result.vue create mode 100644 src/components/Crontab/second.vue create mode 100644 src/components/Crontab/week.vue create mode 100644 src/components/Crontab/year.vue create mode 100644 src/components/DictTag/index.vue create mode 100644 src/components/Editor/index.vue create mode 100644 src/components/FileUpload/index.vue create mode 100644 src/components/Hamburger/index.vue create mode 100644 src/components/HeaderSearch/index.vue create mode 100644 src/components/IconSelect/index.vue create mode 100644 src/components/IconSelect/requireIcons.js create mode 100644 src/components/ImagePreview/index.vue create mode 100644 src/components/ImageUpload/index.vue create mode 100644 src/components/Pagination/index.vue create mode 100644 src/components/ParentView/index.vue create mode 100644 src/components/RightToolbar/index.vue create mode 100644 src/components/RuoYi/Doc/index.vue create mode 100644 src/components/RuoYi/Git/index.vue create mode 100644 src/components/Screenfull/index.vue create mode 100644 src/components/SizeSelect/index.vue create mode 100644 src/components/SvgIcon/index.vue create mode 100644 src/components/SvgIcon/svgicon.js create mode 100644 src/components/TopNav/index.vue create mode 100644 src/components/TreeSelect/index.vue create mode 100644 src/components/iFrame/index.vue create mode 100644 src/directive/common/copyText.js create mode 100644 src/directive/index.js create mode 100644 src/directive/permission/hasPermi.js create mode 100644 src/directive/permission/hasRole.js create mode 100644 src/layout/components/AppMain.vue create mode 100644 src/layout/components/IframeToggle/index.vue create mode 100644 src/layout/components/InnerLink/index.vue create mode 100644 src/layout/components/Navbar.vue create mode 100644 src/layout/components/Settings/index.vue create mode 100644 src/layout/components/Sidebar/Link.vue create mode 100644 src/layout/components/Sidebar/Logo.vue create mode 100644 src/layout/components/Sidebar/SidebarItem.vue create mode 100644 src/layout/components/Sidebar/index.vue create mode 100644 src/layout/components/TagsView/ScrollPane.vue create mode 100644 src/layout/components/TagsView/index.vue create mode 100644 src/layout/components/index.js create mode 100644 src/layout/index.vue create mode 100644 src/main.js create mode 100644 src/permission.js create mode 100644 src/plugins/auth.js create mode 100644 src/plugins/cache.js create mode 100644 src/plugins/download.js create mode 100644 src/plugins/index.js create mode 100644 src/plugins/modal.js create mode 100644 src/plugins/tab.js create mode 100644 src/router/index.js create mode 100644 src/settings.js create mode 100644 src/store/index.js create mode 100644 src/store/modules/app.js create mode 100644 src/store/modules/dict.js create mode 100644 src/store/modules/permission.js create mode 100644 src/store/modules/settings.js create mode 100644 src/store/modules/socket.js create mode 100644 src/store/modules/tagsView.js create mode 100644 src/store/modules/user.js create mode 100644 src/utils/auth.js create mode 100644 src/utils/dict.js create mode 100644 src/utils/dynamicTitle.js create mode 100644 src/utils/errorCode.js create mode 100644 src/utils/index.js create mode 100644 src/utils/jsencrypt.js create mode 100644 src/utils/permission.js create mode 100644 src/utils/request.js create mode 100644 src/utils/ruoyi.js create mode 100644 src/utils/scroll-to.js create mode 100644 src/utils/socketUtil.js create mode 100644 src/utils/theme.js create mode 100644 src/utils/validate.js create mode 100644 src/utils/websocket.js create mode 100644 src/views/error/401.vue create mode 100644 src/views/error/404.vue create mode 100644 src/views/index.vue create mode 100644 src/views/login.vue create mode 100644 src/views/monitor/cache/index.vue create mode 100644 src/views/monitor/cache/list.vue create mode 100644 src/views/monitor/druid/index.vue create mode 100644 src/views/monitor/job/index.vue create mode 100644 src/views/monitor/job/log.vue create mode 100644 src/views/monitor/logininfor/index.vue create mode 100644 src/views/monitor/online/index.vue create mode 100644 src/views/monitor/operlog/index.vue create mode 100644 src/views/monitor/server/index.vue create mode 100644 src/views/redirect/index.vue create mode 100644 src/views/register.vue create mode 100644 src/views/system/config/index.vue create mode 100644 src/views/system/dept/index.vue create mode 100644 src/views/system/dict/data.vue create mode 100644 src/views/system/dict/index.vue create mode 100644 src/views/system/menu/index.vue create mode 100644 src/views/system/notice/index.vue create mode 100644 src/views/system/post/index.vue create mode 100644 src/views/system/role/authUser.vue create mode 100644 src/views/system/role/index.vue create mode 100644 src/views/system/role/selectUser.vue create mode 100644 src/views/system/user/authRole.vue create mode 100644 src/views/system/user/index.vue create mode 100644 src/views/system/user/profile/index.vue create mode 100644 src/views/system/user/profile/resetPwd.vue create mode 100644 src/views/system/user/profile/userAvatar.vue create mode 100644 src/views/system/user/profile/userInfo.vue create mode 100644 src/views/tool/build/index.vue create mode 100644 src/views/tool/gen/basicInfoForm.vue create mode 100644 src/views/tool/gen/createTable.vue create mode 100644 src/views/tool/gen/editTable.vue create mode 100644 src/views/tool/gen/genInfoForm.vue create mode 100644 src/views/tool/gen/importTable.vue create mode 100644 src/views/tool/gen/index.vue create mode 100644 src/views/tool/swagger/index.vue create mode 100644 vite.config.js create mode 100644 vite/plugins/auto-import.js create mode 100644 vite/plugins/compression.js create mode 100644 vite/plugins/index.js create mode 100644 vite/plugins/setup-extend.js create mode 100644 vite/plugins/svg-icon.js diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..4bb8ad3 --- /dev/null +++ b/.env.development @@ -0,0 +1,11 @@ +# 页面标题 +VITE_APP_TITLE = 若依管理系统 + +# 开发环境配置 +VITE_APP_ENV = 'development' + +# 若依管理系统/开发环境 +VITE_APP_BASE_API = '/dev-api' + +# WebSocket地址 +VITE_DEV_SERVER_URL = 'ws://127.0.0.1:8080' diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..72c57d9 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +# 页面标题 +VITE_APP_TITLE = 若依管理系统 + +# 生产环境配置 +VITE_APP_ENV = 'production' + +# 若依管理系统/生产环境 +VITE_APP_BASE_API = '/prod-api' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip + +# WebSocket地址 +VUE_APP_WS_API = 'http://172.28.112.2' \ No newline at end of file diff --git a/.env.staging b/.env.staging new file mode 100644 index 0000000..8032d79 --- /dev/null +++ b/.env.staging @@ -0,0 +1,12 @@ +# 页面标题 +VITE_APP_TITLE = 若依管理系统 + +# 生产环境配置 +VITE_APP_ENV = 'staging' + +# 若依管理系统/生产环境 +VITE_APP_BASE_API = '/stage-api' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78a752d --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..605377f --- /dev/null +++ b/.npmrc @@ -0,0 +1,5 @@ +strict-ssl=false +registry=https://registry.npmmirror.com/ +electron_mirror=https://registry.npmmirror.com/-/binary/electron/ +electron_builder_binaries_mirror=https://registry.npmmirror.com/-/binary/electron-builder-binaries/ +# ELECTRON_BUILDER_BINARIES_MIRROR=https://mirrors.huaweicloud.com/electron-builder-binaries/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8564f29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 RuoYi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..2a5ff70 --- /dev/null +++ b/README.md @@ -0,0 +1,109 @@ +
+
+
![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。
+自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明 。
+推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。
+ +UNBTTLrjM(q3Fvv*vTw+>Xxj}CdSGJj;RRW#l?;< z1hno^B9!X1>t`nnjtEb&lp5EzFQ9qv65`?cWgbE_+19;XV@LlsbN^ zim}kR0i5E7h5P(ocJ({^4UnH`#?ZHcU5^KwVmC@ArdfQs zouj(+G#>6wo_fFoQgAKLe})S%<%ns)UOC%bz7iV)Yy@3T0D|^e-C+4bTuTh uZ9r{H&wP;qx;Q zh_3E<)@Pi@ug1YQyV`0KdRr%MHub99bE6D6J^h_xhzAq}K^Y {ph%G3VdxWD0B6eg$BShNg*9=*D9|uNU-@#hNHKe$oV<;7fw~7 z+>87>2NA6 r4hl;~mX;AF>eE zY7SA!_pqvu#_NDk6*@`2fd^$mGo DS_nUoW1ZXS zGouK4WkARqC%*#UuXh<(*Zs`0*POJq^1sl$EkFM4^l+@V8N_h-%p-nn2KZ$ktMM+Z zAV?APrbqMQpO8Pib5tP^%5>A^X)$Rh)-VApkeZVYx89a$AWWUlxSO4e2f|B+K^KPE zXRj!U@azM!-jr{sm%gA!#>&Qv98Mi-6z9feqMnCGJI{>#=e4DaKo>Dxw~u<6DtB20 z?7u$#(pf;@VZ!}|^Sx$VOSbJNTR&bYAPa&lS3qkH=ZWlx+zxC+$B-DV{JEo0RmRMz z=4wtY3IRhmp@D#)1D>|Wej+h;@HS^qJ6aIwO?+68Tts@6mGAPf@1#A)^|9u1(_V%g z1zfPR N5)#50GRY)Nme_PXiKPyz;ozPH;qYM^a3<-ei VG`l=O*7L%eZcI>bXYOW5-tBfBQ 86MXIj0#SomK#^^mtw%pAFLY HXhKkE;v+I(*zV zcjpT95`bfci309A;0@!FQD=X?cY>Vz@+xBvAO$)zCw;TQeN=RA+Qi)!-4fjjR{3g% z9k#VmV?>FyxWu1-v{*^qQrU-h>46)9p{>C>xn4B??G<|h)e~s4g^AmZ`qWvo*jBgx z^A*grwD`6;voA1_grHr@39rZX6^d7n`lHlwkwP0o@zyV=8<#86#S3@Wi2&zaA~vMY zOK=;1RB9g}_H0mveR1xp+_w6)km-q*=86&kmP=)wG#XI)^fc4gB(xo^3c;53qkNE9 zAb?bE5Nv;}XYI%Nv}Y{%bZZ7?ef|pmcd>0etZ93%Z1!|2-BVrb$xBLKdAZ^g81!Jl zKk0Rk3wp!Eg~>m{W&En6CJIX Mxs+JEp( zJq_}?MUQuF;QaWYJ=$om+M}E*%K!%p-B<6)DX_zN!!&C3OQI7d#iGY!C`%94i}Y50 z=mt`spjqz4z|z=t0^&8`REdMLj*jY3#~~7_2zx`a9U;x299iPLD_^o&rR jh 01+@iXO#XcjBEeQ$CLHP}WLKu1?zdJ9=fwG*A@oPdN)Crxn>7OVe@)A`gu> z6AtCGa4B>$q;6>`2=y`HQ`Ph+S#KL;b!Im$M}|-dIH?gViM-nhML3XKFDpTmE|L9? zhZIwVV_1^@r>J?eWe&*;{ffzRB0zI;0%4EkZ&hU%Bh99s_l5PJ<2a_3jRq}R+RGv? za`mgOqRR1Xw-A?agsTab)0rhKXd3JZXdt4`^ag~jRZ~!D{XeI8*BO6gqhW?5?Fls4 z#$r9eS=QN)&)^?Y{S`u7x+~&VS$XLte(!rpA>$d=t7kv`_)@ET&r!_eldHf(_?>;n zkY+BX&|W$ jigG>pftSHO#C4mdwdB(U;>$N?ZeaSPbCADwJ3XDIqr# zA40G{eZt#Gx;}({;CFr5B%^WG$$ojaRXKWd=;cmzl dlPE#SROf`Jyl%$9oe=-k@mu{i(+m~j zIVkM_v?U6E2Q-3Hh8zsS$vU4yl7-M^Quvb49S%~2v^3 oQ!AXVo9s zlQwzw_cg_ZD;rE?#1i!=mif;3Da}ohhCW&(&hfepPaQ9P@O#-!zdfG29sj}Ws;bY^ zfj@ BRIFKu!3kV|?-XQua(f$+bsM!{`ZkNedL-|Gvj`m!;&6W5>F zI@2mic(}p}Owh;^wfrZ3`B?r&o;q3O^5+%C0emNN%y0hYig8c^t~+)W#ae%oNnq2L z)AHkQEUPwSA!YdS-Ag#upon<5eBdiBRem) M-to zW7=Bu>EGZI>7sW019+=$5mLr}aQSr~R?u~?_cjg|`|I=Ndz2Zj1>!Xlw)k{-7eWq^ z1qlx^JIHWSRX*ghVI{e)zl=*uS4gl*S (~(FYBbLPC6MA8|Wb7Sn}UO82G2yd3Tb~otX9bN1WO02FJ*MIliq_ zZ7EYv!F=KuW#s7%ZR<1c>NBqJYeKi?s6AeS-n@HLza~ZHB1Ix+xw354f>WJ&!vSF_ zz=yk6^R~&kYWy3^GtCDqIMmR0xUdReJepo;2|K?I->WV#H>@h#sx~jbey!obPiQ3& z*ZLc$d5I;RSWgmnj((eY+Jwag%ka20w>@fg^xr^>zZX72k2uB}ktV5dzbKlfdcv3! zNHL#&ofkf~Z$!87%74fEvXMud9Smzd^v$LX&TQFym4xDwbc>2f(iQw7+DaDq(Fr2! zSEf3e$P&|~G{?93@Xi1B!PBl0N)m#Ay|ai!1W`04OJhggp8f6|=E6I5Ioe6Y{RJ7{ zCVq5nD|n5(aqXR(PIh-^YAv73$97dYUXM%@$q@S$v(oV4H3TRi?NwSYIMKI$vP}4f zQkBstY~DejT
Y%-F-?UoH4YiYZ3
zeb_ZvURbXB9wgIU7T5vwp4liC~$Ys#x)~YlBxgDzQX6!V~Cr}(T2VfHzx(@ zO$z?5UCg01S=S(KhJ&EgY4FP>4TBNLd|#7UCOduidmm97z@Wy)@s-xCq* ;+rX>oy*wAx9;w!z(DTjfds|#QBP`4a(|1N{TwaGbBfg2JCTNmto=4k z&k*|El56~rdfF>za4(jwA)QpMBx#0-def?-Xd@d`G*gpJSE=V&ozA#vHzLrCO@UPS zXuVJgDh&3#_{u|{qT(eE{Y=-loEG{bbvFhIRIHkkfK@T~;HgDv0v3zEWeerV?++^0 z(!Y$-utJbybobL6Q;H52ME9^O&NE*nMWyQ)I?2lj8BVdJTb~JOPO+qXV3rsjMN{P{ z#aKm`^RTAFezNJ9@?WXUnr&qmH}~t{E8Bc#*hl#SrigAy1yeL%AIssR;6ZBjv#dW$ z*(KOR#?NX^)+NdFCj>V?K5jT$3Bp2El$5%0BtTQ6hFWyxtH`v&l7AUd+^b*WyIx$q zIiGqx<@1sb9*kba1otoF(Tb;WQbq)~QfbIHBf!qrgj~mKw|m;wJ6fdOgzAI}`Ae!9 z^SA4GZ-E7FLHX1;UDAfb5-)sHA%2UZbP#@sY3vaFw8poS?i@XiSWPyO|3KL>a#`l4 zYcVAA6D9=HNIs#tIez@FC+Vw*-D=ZHWf?4?Fr27TE_btSn{q^~ilmU2Xji@(A0nUs zyMMh`Ru_Psl9gbYg2Zbno{sE?k$H_anR?CEmSSt%_%kPws0j@gXRLj3GA%Q%F|Mk^ zieiGdxN$7!>*VaxSg}O9eJn6~oS4)3CvV*bL;f|s#s4TpIg=Z!A{vHaQLuyOw(Pa` z^m=|YW^CqAd6S~>p4Ckx?1mdy(8;xxBtO>S{$0@UWj|IeAg?mvovvqIv94?0^G#&B zEC@iKh9guja!je@hGw3Flu~1Pm##EROIS-Qj>Z7TyPG_S5x@NI0ah z`AS_At%RQ*G?_|w=+K1VB{ 1HCZ`ZSPtKV^W=r&q2NbjqFesLBQwblWLX X^|K?=jHGswpS%a#@N?a?iXpR zr{u4C1IaL;-GfjgKv3x@P#MW-JPgqjy%bQY$ARo4d9QN>`K)bULtJ3T%blRUogZ48 zTlv1i8 wiSK(W_;C&OCTw%TeT;JPg-sic*CYu~4@ z!*qB*4i)yO;sznip@Bet=!>_E0?mHEqisi8YHVj9H-8)6`56gekvJCdH~5%wbokPS zAXerhUgeeOwnk&EIVFsgrr#X;CkM^(^*53Q3%bJ1kNJ1ZEPEv)81R61+%fu4uaK2C z8&g6Rpo$IL8e9ir!2Xs8i!AdEtK3RqwJLOen(h6|0_tEQo; vi`vZC+$Q)#0_eou4kz&dYbF$H)So2WRC~dxU{`h=hpiFrp*|q! u_M*F)$;yhOXKO{(0-(e9rz8|1z4M z2mL1|@m~pk+o}#Bt6bCI`@Hb@(7|Mrl}cFxl%-Y&6K*K(yZ_KSe3PcCWeYYTao4Wf z7c{DsO_27(C~!RbEWlRUL)o#74W4F>=F3CW?o!ZgFRBKs5(K wc0Dus99tS}gss3I)ei)JUd?j$^ZJmY@$Z@L9U*O65Bh4@?I{ zvnMn{A3YO?<{Z)Yfz>r8fUR8LpJ(@Xt@1=1#(( $Z)b9$2P4BOV#?ETQy*DMxJ88!7SpC^|Q1GEF`~r*!!gv zO@OU%YptkzKk1LsOvxBCA=dwN#kZ<82~2Nk@hbl?Xk1Q4zT=M1hHCXbXd5=4lx`qC z89LBpmwcDW0+-7iDLu0xt*MVyqVxUoTOo$VJL6OXY {xK R}$$Oqyi8i>s80C0Vl?cS3>CS#bXaP#d;}R69P09EJe2*t4gTYJ;zuP;#p% zUcExNRhdLI{;RIsMKmX3?u*mF->fEozWKt3`GlF^MDsR%-vf0ctn0cG&$-*)WQ3s= zAxG(Nz5p0@yHu(73BywrR2Mypg7w3|G}H3tUXD84L!!+l;TI7|=QT&!tqHZInl0Eg zi6~FxdauJS32iqz7y9;#g(ke=`<$b5a0SojJyIJ+HB>lh-ZUFX0Q%iwc5=CC=Bzoh zBvllCzk&j(R2$~&_r^`%Pr|>HnvW-wD~LSur9wR1FqK*kJV#&&5=^W`a9)0+5HmYq z0^iylA5*0V9hnz ^*J0*lv8$J4kToVgH0>iv%onM_Q`V}MPT8jN6@Ydcy z!ayhOCj$GZmrW8{QFM{G&&?Oy=K;vuDA$dHYt5Lf%Tbw3S&PxR2bS@A1i?Np89o7V zeD
`pz_;-??V-1?(tv;zwqm$)U)Q|&CN7m$*?yy56LYgczXcs^ zU3ecBp}O1s0K*yd#^uTk(*>(=j1S{oR1+y|x7L{-)FS(qGkm__Pl(*hgNig=*~@8S z@K1htP1k gO$xY zQVn*Kq1_zK*+5MM#bVx_EAyXQh+1 ZWKmQtvDl-o~{3O zCYnMa5~GDDE7;(dbBz!xDtvhOQA{2~cJ|1xQqD?>-0lmO^5w?*J<|lF5u>yxTV1n( z)?YoVUk&wD5;GnviVQcm)vBc|$A~**phWlI&c4HO&ODW6pt!9-L(V+B%9ISK4t`1Y zQ`ab)Bzh%)#rJpm=|vCr!5g@IoDX-gf NwKn8>fcfDS`sI(1%EeD&ogT!~H#RM1N}xEroS#=>=W zB&X$mV_RANDEtcx5TwV9evJ~utWw!(7cZYXfcVQE?OA%novk>t@dtsvo|&byiZ;qa zA KW}NdqV1_T%{@r`n0uQN(o-8i2q)4y>9WI}rqS^Y6J78!uka_gb}iTr z-3d1p5^zaxcwqbQYmUh6&6jWMlB0{JQ}V>zYKZEnS~!gKk{WmjvV0$vvGpGfNRE4b z#JK 0O>SW^J=G;XE7s*VRu9h}dyC4liiwo3t4tdd)({YeD@o4?82Qwz(HjDAx{ zzZ!%#&0Lohu^qAnk!&e9T^`#B0_vm;koNp#(&&pFr1InuBo#Fy{LBK8Z#PpOXv~ua z{0d?29R8h);!7-J!a={%Qu%t4qtMJJskOqj&SQZqsb#Xr(|C-RYse|o1f$&tyI;pT z5|I`tM1@`faQwH>EDIW@F~(1HdIx?1R=Df$Mb-;PEx(s*CfyhnRuiS9O09BRG@XbQ z;UrOwcn!63s_X0S{-t4)S&$MnVgC`GjtP||9h~*6YW<1Ds18MPD>|E`W;)6zP@##B zK~bwvfHq30zn(5iX#y9)hHs(tjZHi07-;6= !;p+rq?z4U zFyOvSt(q(t-`f=`63-%QY2x{vpgc_>lZOOpO@-Fyj;40=tHFi;M?IH}(G^cM@)UGE z?q8KJZQ^KuC?m1Q-}GEguc#N1-B-T6Dj2vUn$P&dig9<&m_4N7$`Ad+U#4ooAk5|W z#2$yko_EBX56!YQIeLT|#d{9Z)~84D=4F=eH%JgpG2xM{m|Ez*c^3Ynusy3%*WzZS z$hgI#ZMw72N#gyGmHST;@mB`Ukf5YM8KB=2Yf~Mxoae;&YrLxF*TBzS0tpHY!s(Ab zgo)qCFut&_ B&et|lk1I80EOs0vVCg{RJ9RZ|!cf!oH>lDn6UITCx=v^_?|9Nlvqo-lp z)uL&^bl4WT_2hoK5=af}{<_@ffmCHQH1-CC{%EpjHq+J^ZLLzSE{tm%(IhJ5N~pC3 zv!kqE%{njm^n!;-W4Ce`9ZGqH@eS8;b4#dm_o-o8EKbxVd+Vd_4aY0;Itu^eB(c@! zps3*&MEyV`f1UDyY<}vFc`ktlTagh{u843z^Xqo~l)HUipWhmtDt;py!whW@$+CZe z42S$ekwM>v>*Pj3-&9S+b(NsrbV*mx#sQU@blCidQaD*xf={saxsQo%DxA6eI3YF^ zn`LcWiV^B)V2`N5xjZ}C)PP%oBHY{A>$GhA)8|#Jro7*=@?7yPCo}9o_T4R_;ogG? zeLg|#aD5Ar`>W~XS#DHrC@p8I0JB1WtiUwOC(~El&m)*SNn9*ZNjY*(Qk}xZExd*6 z@8?ZP=S(Pm*{h)xF>YlA{jx!0k;P%I)lv3HC7kBP%#2M-D8nt1go!p}ziiFx$V1w~ zYNG*NqnW@P|1cQ%rCfetcOlv4KL=#M-Tm}Y*gUDE+Q(~UDv3z|QC7nasvK^3fjMy0 zU;ua5+v#))eby)D5<&;&{fy Pdl=nxRACU>3isD|n}ebpE@lTGMz)%Bn0Q5P zt;%*4>P>uN1#EfQ w34jrDQ((3;CVk^LpA_~;ZFc(bjtrf{F1C*}vY{a~uG z?D9o8Mm3Jno@vLClMSDxW0)e iGCYYczx zXIAVWBw_vi!RK2_q%NREMIJ5+W`|u%_n<#@rrCj3L--m3t O$4|0 ziQ7%w{#iT}1G%|T_pU~1;3QTS!8ltvoIPa6M{mzb#Ju9<*&|E?(@i^n@A&- Bvka63^1*BiWV=emTX=$wk=r&2By~3U_QOpf^aJR z0iguE;nd#=t$z-Mh##yve64xSc(Wf|nBs;F>a(UCA(viSaM}fb-eR9l5}w83#BjFZ zO%s-T(ukyhzl}p{(v;_QE^IP4dU?+|KBHk+ERrP %ShNDJk+T8BOaxs 8U4#~rGw*yyjPYaM+QL9cin+8qYM0!HQMFM-?$=R7 zi5II>nZe2>cHVYyjUU0VL+^P33-q0*&a`!`e+hCD*z9R;Chu R_u=zEzredJO;PIo2?nfVe)77E{lI)>)jNAMED0re!qylPt;9gojDzkly z+@QzDTa>%Iv_F3g_BXn{&o|c1d7X=N{DGPJBydbu5huR*auuQOrrlfzwCVC}-d?n! z{&HFY7D &R%FH)ad>6EKVU}c*wdUC4SL?QDwzr!a{j`u|8r%Mae_G- z$LemkS^B7(->-dvb3?)IHO@; }0?+=Rstvddc?WUoN zro{f#u=avy?OA6x1SRNrEAYUwRdR^%B~~UlR9(LH5xM^?H{;%o|IazH- &wJIAelW=7v=g{l+i-NZVzsdQtDvmjWRWc%a|Lf;g-Y#E##VD{(BmHOMRZZ$ z^+TQDfQ{7V24C4kET@RPj$c#5@Y$0*+f(P=j)0AmQ!W*gCg0GR@|OVlqv0*;DOUP| z1A`kOL`Cah1a%@tF00&)iX^c7T0W{fzBa&DHYknG%9NM`%@hYwLwTJ{Lo+g%X=me* zskFfH`+mu-+XV(qKyH}8mAXYJihbw-eo$7D&G )Y3w1fJUvTI756O;;xvHN9LfL~C5f;U1^Rb?cjDK;cyFWW3g%7+>xIgja) zVLAFW;w;z-Y-r+$hdBPYkYcMPCYmF$uekDrYL~b7{S=(~D30^YN%MFZz89$lu-ShP z9aJ}-3fblV*^^3lUW?MXJmkj3$3=LNZZlPkKj)A(h^ualsbOZQt?ugmR@0qeB#gQm z4)LhfZUg^#WUrDX4kXP@IXBF|PQR%4_{WiZzV#0~!u}jr4|~Ybo#eCXSObnX(3*qJ z9aJk X=apAka7#QpX9`?7-^s `rF3U!oK3(}!A#|=iJclyK%mHM6u#r>GpTk@aZYhY_;%%7ai*{kRq zt}w=U-rWUYJef2*+PDfxFEPU=fd9^G7)pppqgD0u0s=%H9hL~pwXfozH a&UULT`1yyk}E8cm|oSmGeV8u+F-A!{g=DV>;DCOGij-Hj7A02+N$ zh)T{8P_sJ^N GVsFo9b*f9Eptjyo_{V>4MEp)mMPsecXUiZH@-m zqA11ptx|4+$KY}^kEPaqCQi8egcI4q2!Z$oF0u$_Ae2fZ)4^J+yZdw;&8Js-SS^>5 zGZ@E=N|OHV)nfEE5H;5}6n`H!q+D=S!x2%O9_f!NY@XdW;CLuX9iv99r;52lxPsw4 zh6g+Q H$I>!CWmxY~eP()F8+5{Zj{Hm)YYvg3Xj{O3b!%Q2aIO2jrYv&OAG ztuG#mfi8njLoOVq9ev{~cd@b8`g46T =WYCowlhxSCx z(s^4htjFmuE^}+RkxB$i>$;K;?fZQ(ul$^+nmUWns9!Yj>$ e)&<>@-9RM{BZ=H|YOp@9{l$wX2zF+$(zEVT?fI8ahjT_wo_IN+4e zb{d`}s-c?#fS8zfM_dh#^n&%sk9i$mW{-?V7!!z;fWJSa+pyO!h;BtWr{AlH0-ypL zwWKC(EqAuDBlNzlw64xWYwOq~c6m(PC*l)#+52vH4ArK~`#Y&*)vnICj7Qu(&7t1H zP=hVT`qB~A$yYabrYR2$RIU-GVX5eJ7^xISYleS-n)9%!sh8$K;Ki%YFV Jue;RP`d zCT*KQMphCo&gBLz!dvLA-Wg(l2;1`rK)QJg7kPp=Hjvv{Q{Q?8KLpjSYX9%?Tk=_I z(D%OVe;Zxv(77KIw1+KMERGbU;bm*+9HjX73B2<`8a`-R_l=m%pi`@{HKC6){u|vX z*nJ&n{39Ul_S$G9_E9*a1X|Ra-(P)=R7#LH#O?^tYe3jxgn&_Bgf4~kYq#1r#^>Lm z_JW3t#j}_Jhaz#q5vi#zrU6IrIohsk?Ft_iQ0Qq1 y2D3w%dpQ(rnx2o7Angr09&RU758N zt#hTC_BQflu_ZkFs;YXYrfQL3G-5e%5VO}+wY8gurj#nV!BKQJqNWa&Wt9$`!U{>Z zS75bS`^d`h9e2|!@L&guaCr#H?`OMdB9JfP4`tQ2 AIe z&WIv%c9(E{=%$tSZMIz2RA$dVj1yjJjG4apW*FYXi}m|DlVDGhsxWeV6 )> )KQgfz%fsCb;qTdH<@tsVr*e&Aue` CHBm8Igp9Sw(s1E8<3RaW%jT!2!ULH+L!NwZdp3)5?{qRMAsu2t4tc@4lRMdgTe znLYZ1&fZJeDg?G>xQA0a7Y+%{-=)H(OpBV`e?Y0}p#9_my?PTK5P)yYh1d@^6<0p9 z^tq1TMbz2-5tNr~XZY{#%V|9Mj%U)ZWuKF1Aq$ v0^k>6w<3Qq8F^F)3lT5tQ;KTVcJMM#C6ExQp_F{ z8xoeUz|G|M+0Ok5a)J?k;{2p^>JoOVftouS295^A++)swDhe5R4hxb6_AQF`hWlA2 z6fMO4vo ;ehq`cM|Mr7DQKFLswUB?PGh#h@eO9-u%I^LyBt( z30X;#K!9=!vU@d7fzsVWm qlP_6uZ)(vBT;QUR^yfX !srV6p`+W`KKO zniz{*h-D?ihuMOMU)NM!>WO-$q(MR{45ex0!O&oi-gyBO#iJ`H`N-Lo%v_CAoK5#i zh0Bklm3F=n6N1~m{o|jJ{*fUs4BQyNiJ&x(*?Rnnf&&tS &b;1C( zIbI812mHkC5*BnqY8aGcv>Hv1h!0z6QNt52WNm)RlRFjc$(p4kTl2HS(MpqdjEAlL zg_{l@xA&l486D0*#p~kb+)^YHRL2|%Rn Z$aIg_sy%Y4XrGiPyHGkRma#C zod+Xa`o{6n(LGsTYggGi8o9Txh9lIPMBdl}KuqZ4U3A$@FfyEvc(J$-6|+Z%o((nG zZ`?@1+*II1RbcZ S(t{%JAPnE7tF;Y!3X&NyU4K2sH09%9l8n^`~J( zqd$}sdx$yOh}`a|f6J4ie(9#lrR73haZX)BPg6@U3d>FWpt#40D*4bCPI&st)>w5~ z`T7J3iK=}X+(j;zCrw Pk)TsF1kj^xNwU}e8jOd=9M_)Hy^Txr?v#H*q%)Xo zwwoU%!&<4yK&A7gOQ;JeBHGTsM%^tqpGi;+wLMhQLmU;h5-Fci#A8fl(3dg~c%b;0 z@<=eLH^rpG3KU1isq{n8)omSX%&4j1liMYXjaVB&`AHhiQJlHEsN3&ZwY3v4KF8g& zAxIystox%ik0Fz`b6?>aXC$#GRH%0ZWB~L>e83uQgKQGbUc?Np>bjbc=Zzdz{)f?5 z$#=0xFyMTIFevb&2w-=iJqeAD=-gWA_XcgcR-~7}lPZp_XiZ19q worbU9 XD2IX3={~QOGvp#Q}E`Pg~EgZ~4<%Q{YI2 z&ryeGZQzo^=(g6S!);u)C}f;rs>Axz(UJP< pwvp$#&NlU<1gPhbfW zT8(AYAcZcT2z`WkDtbbrBVpw*-0%N-NvC__Z-%EA?6k+I#Z<)wzY+>RVGL6nJ>&AX z;R{X8eU7CY8AXJR$6%&X+0TT@1Zr=x>P9}dXDF-xVUNkCeyfQ4Mtq6281v|Y`?Is_ z<;0gEd1;(VK$Ioa4yLrA>vCc { qv1uS%uV@hpXb59XV9N+%qsGbluCns@<0HJ1)FB4uf?jj@b`NCOK zo-4;rw6&2;V@EY-b4IK5G3s#8JUsy8*|9KYG`Dms+?qi5K=}Yf3DthRuGrh4zIdLb z{>P80;bD_uhiprJYBD~F9fvcqI@^~sOxi1&{pA-NN90);S*=m9bd^p2=%5SS3FB5} zIp0f@8D4Fvqv#mGnf4i1@=L&U7z}#-c==4V$sSW;WcIuQ^|&h7duU21s|0*&e4vri zB)~(ER8DP;`b5=*GT;8Q^-j+pl5OS`fQtfGg3F}nJoZ!hgqbrp+x@mbs>M}};CSr$ zt!mGVy9~h4F;KOWlW*vUOOGNNcMwssA+}z!JN(wt#YEk^y?fSxgH}~YoDMk>;Hx*5 zz*$CVgeAAT=ZRD7Kn!ctit-=?CbZqhO|s8>`>2o9zZXs0lJVv91hkSAJk%Uq88PI5 zyT2Dz4W_UKbePMH#5yzNHR!|k@Z2@|mf2$N0^PcATUL=+JYNM|RX+~|k|MO~iar0S zE2z{qyn>DYrWk(~&kVu4PxEn|ya}})Z36t^i`pyL-=q_{Dy4Az45JNRue(#eE*zMd zO*_zo2Cy01E1J}i&5{l`s-bkff%NY5986^yU?RUHUAaI9nNDH9Sjk+@EMy#R*gBwu z#gsqX^_T=#B+h5VT(x{x-+VgqU8YhpT)wowhCqUnDpPUA_^9_X 3O{ra&|U0^Sah_jgqGT zB=-R||B$GRj6z^{w(`yKO0SQD{yTo;V`C8VoTqGk&@AA!RBr>-x281BP6%vH2=qAq zd2{GIv;tLPe5Zyj$bkty5F`72`q Ubpx1Om*sEe$)ee5{4yjo $n)dOtZ7_)+>Yj+ZDQJdB_U$$Qxub3qX EU*`C#pk&uX8`V?)v{oI?Jf4 zx~>h=U5D;Qx OcXyog?dSc*;17Qoz&d;FwdTC9 zYg$D2B)MDg@BQ%`Qx?d>3gxPXGXDOUg{--&4E{tJw2eC8p1G%2H6p%ZMS8~F=O!|a zrFf=YQ;$M+{5ae}O&Qd%jMkmW%|+EeeE`> 6l2 J0Qj=tmf+DW`P&i}41DKuoCf6
X|*P1jh{-?d(>97}-Ye;2Il;O8ni5L#vn4-(9Q*6+L#Eu{SI75$F{OM40i zEy&7D`=U9jg%^b10>^j+94d2V12#Y9Fvjs_PI6BUrPJqf&1V0K(eh-{@1U}S?a*UN zkS#vcm?E&(2-XRawdYe#HD>5i?{g5SdDc|l1)(%cWKQ(brYPiR(YlMH^k0CV=fKB= zwG7)2j6Wttrwz*Yd4U6dY{X`?nW#8+pAN7r#h$N=wa;%QvOe%Pa1PPndSWOnp#<93 za0Op9Jab(wc4o9`L4t2q!(5)$;R*DV2g>laONxs9rTPEJX3p+V3x>5|7?4Uycngk< zt(ohXKU)#n_o85Re7R$)6@sVzB|DF>t?u7D*fJU*UDo^;aRi<9<{YcPL_oY7F0u)C zhr-Z-2yhT+Y=h_xKh2bDhJzb3Bi}lDFM !34@|h2(CEek zUe0PLK8ZhX6M-SY5rLN2l6sGq18E^#Z0!Uj!zGns24MVFmVR99(c_cV15xj2a9AXZ z9LFg({JnfLwJg3t8?^Z;g=^Hl@g4nSvS9UxIdvA2p|+M-{xvpf^h>vR?_i{jzw&=TLRC9 i!Y+y+pd)+R*#?Jv$$D4Hb9W&@{rx zi+X9KWB7aLk65Q)UKV=!V?i* }s3UH$jbA3_#3{&qJps|I(ehG9%~i zFP-7< ~iPQKRSD2pf%8}7EZ!}5DQ%1OZMGnz>!K`7t}cCaw4^su$hWzmg=`9 z#FI@efG@HnuoO5DsLyfq0#Vw1W81^7shfsJ1&WVG{jQeFTm4z@2oFj~g)q>C*I;wb zm4YQA7_8pcI|j2I!xv$}-WxI@!XV4XE%KOQoqD~nc|LsaKb55GHmB=BvSNMM5BDEJ zDi&{j5exYr1Q9#-I;9RYwRgq06Om=_X+B{q>Mjq)T$BWFAVCmEMAjSVe#Lj%E3gEG zrcz1Dm?PfeQG?-bc?~sA-YFo|-w;Y**%9{qV=**)9}TWfa|>j!DtPE*hrA(wNLA&p z)nE0fc89X-{@46!Tw&~cqhgq+Z;)HnR8ZEUI0>O}X}XHfL@ AjNb#SHZ$8Zeu zlzyGjB`^rRdNjSD=Kc{G9n#S-rim)mV&tbcxf76i^C)TJu$T&itD$a;FW{~S=4W)O zE;gZ%{d_jOT8%Wbx*U5H4`0Brn33k8h|5O)35KlP-AES7xam#P4qu3U&49%el=;I& z{hzF%$P%^%9%~>P{N3%j2vyU0r(mVqpP>=Qg?0S@J{c?S@}dk!f{4-J%Tg(V3#YjJ zNo>CH=|+e|1*d`%g!r(>x6JC8hz6mw3i`gdkx&74!XKvhtK&bW0qPjEUtGLs-exz_ zx_9EBzcQI3^{b!=$P*34zF3HiU`R@J_{jKK=P!CrfC0f^TyW&N08Qk0 y5WUa^t2^q+Fo5u~Ps0 z@xXxhJ-}xDLsa57r$O6K@JH`Uv^A)|wFR*)8>PgQkF% ;F!O` zqYNZ*u~F%j`-WLB?e`#c#%~o8!rOs0zY%-?_O96ZSUagf0F{tL{Yxg}fQVzgFylF5 zol051nz$b#G089Vur|f4WUgzy=EZHpVCqaZ;8|kyUlGOolc|&z+B%hC1J=z<$I@Z_ zcNDBw7g-S1t3Pzz^yvW#xxSsmzJ}2c&ePn}h`Q8S+IOK6H MlReGwmp=&P>bBi!L(k$Rxf PWHgw)N`W8x|0Z~KioH#>x;?r|fxOPXsOtUGOdm*o${T9`im zOvi2QQ-w9@?F^EWMD%0h^TmD?i|IN}CJv^0H|Kv7*)mTl=_7kCUyegv@$^PmDPYx| zq)#%Z4q!RV_6#=RWmhIWi{{?MNeBEPcfBQiT)m@=!4>N_Vi%*_p9Ne;;L~4r+Ij8c zynEJvYqt%Kt+-DCEV_x9#QvXW>!{5ShSA_hQvaV!`RQ50I*x47DV6BGdYv#D%})n5 zM2`mZMQ^g68EHaqaUHOi$V fe!0wY2$>#3s;P)xY iEpr->N?G}T3bEAzOXxt&y9BM@y52afuwN6GM9ZH4AWpslzI^f z@AO8h-anNuj;aOgoeugkC)-&6wSF*5M^F*`2)CXCjlbM1`iw;ThBYF5_^$SyWw(9T zQy1D~;ck(KRkgEmCl#Wy5t {lmy1toek<3eoOypH@pYgx#lpyz^6O!jFXR@78s?M6_oCbfVC?dN6c zW3=?%cDwJV9}`;mGgJ}Q;UWQqYM+BYZfnAi!6H&?(-Sv8(s~3RiK4sEH5%`Q^ADW0 z;Qk}`WoE*{{A*i>PLO%t$hi^vyF$}vz;s%4!1r$ou0EQi4 cUJfsC{=#4;43Ts3~xy4IHq zD;*yQF49RL<@Y}BhNwYkj1vSq@5);ok((nk!dbtF79CS1L`E;@2<9+~ru5yl3H=od zfwk{F(;J2dub2iwX5GObV}J&3exSRL*s=&;9DEP8iMxj>-VTzL#hcH7q!&X66I8T5 z1%(S%%3D|bW;As)kh==TEf+&37?F~7i}uVZ(cNe|@!o_(=e0J+90+)4x{XEXkIgmS z6Hj2qVQ$ekcZ(#df3Pvs-?!0sjRQqTdiIstZJlSBMSh2_S9QHZ1hcPsWB=@sld{hC zmHQ#U?6cV{aU_%0;r9XLZyR@-V=szKSbH$X&IHRgST9C+%=ksbj^`sVDDuLtt_rFt zQmElXA=;?f%yC?ru7Pgu2n5!D=h0;yZ}Y@-5icmZzs&i5nO1lIECcDOReLJv)v!D~ zi7mOMhzh6J7{>hy#eF11QeFv6Wqi2ZGc*m_ mi5EgDfjxLzza-*A`Oe*8m|$C6s@s8z&Ia+J{5iM@=h)a zZC7~7sQ%H8;Z4R$5XZgu#*Go7hn-bM)<-$Sepu%q^KI>>9q$TBe+N2DJaa%A;e5BP z;z?DUwH>Kq9 ^$p+V%a_OljNhc;kT(C~8#RyasH+mR{KmmXu;P{yOQ;?bfJ}Nn z&^F)G)~{0B36P{NwT=I5cm9N|!w7qW8YV!~+6MxP;B)VRR(z~K=C hVTQ|0ve-@ARE= z=`DTkA@aFdbdSl7DNi8c_62E(h#ma?9{Zqd`L#Hu9NzQw&xoS383`#R?#}cmA1}k0 zAa-jPp2v=9C=i5OT4@-{um6JGPLH?w?HC?k5(i-(F$?m9<71$=L6C^af~ZLqIZp>) z-_JdIns^YWl{tHY4 !K1QPPx^U|v*P_3eXdAI$ z9mMi^ayZ2DhW#8Oe3E~2+9`=cFD-s~mCpA+IH(T!+GEHAv>Nc6w|WU|E$D~#(WmeK z!3zJQya$25D0i1hxuW|QoMBU7s=tT1x%x^qj~ZFOt _e(f2@&Fc)FJ8o6jueC{cO4QZKBVrtY(KAu<9L)X )Nb;b$^4TE`MoF<0tDV~4H3DzhmOg`ae;rk2 znbC*M$?JJ*ulBvY=*~~+PqF%0_G=sr9yljJgd#v7B929%lM! cFH|p1XP61|&@*N!A7oI~r+zTzbR%#KA(ztRz7zcr z-+LT1rIo_+lg(}!tOFC}_md4SN|c&ORO)usDmX%M&Ehe%=cq&*Xwv0*8ajmTbkU7l z{h_U+H*fMfu7?KGn^VAv7E}6U5}M7|zWG{67WFMDN}Zqm29$|Q=Mex(U~fTr3?hh0 zTBd{?5YOzuAEXO t|1p2)%-%pI`?k3dd;y!ObcP3oyQ`hlp*F zjw-6;VwxJs$iOOWZi51Kkf2ElGK#Dg_d^dGe5ZG5>fFXS@ImQIalmsRl1F`|!NWEd zHH7{9Q1my5&n3xLt+Qq_R~_n!l{6z7w26AYH&^>OCqq=kL_XlwJ4L;{o-1~K&Ty+B zkD6-m27}G~6T8mzd; heZ2K$pxEcK~hSd_2>apB7DYhE6t5X ztOj= lsTYz4Vw z3PJ$JiCMutK!nHJUsZq`(MoRIZLeA$=+4jn?Qg8dFOkWs@(56X?_tt<2FD~e-~mMv z6h1IoW|G3}X>3{zEUpdvw^sI`UYEbUh@~gCDDEN%BDA?ftwJnt5{y?49#>)2DQvT^ z&-#GM`mq3E!|;84{+@ENox5s$J_n6_VqPj{o+?5aj?{Mf5gW273@h@!oNTV#r(EOg zOVxdryiplBDvKvO7n!bvG|-PurA)@d;8Bt0PuW(=<}ZRngG+@JzVoOb)JKK?`vWFT zlH;_Fmngzk|HZd;IDYO0!2HVQ$0FU~QtSqiub-VaU4kHVF@LvyI^`gzUKw;-@(%vj zgbUJ6#Uz;h{?LaB%87g=5B-J7-To7k4N>eZ`$=% 4*jf3WmvRd*FSI7%$PHq&?2u2l{1rPdb?Gg8%OlvY09Sxkh ziHYjk|FBc% ^A4-W2H)K>76iyVvj z4-Pv!(%1Jn!FJb@LZ`6gNq$uXHiHn?jJGWwUy%O5njIKNuxOs?h) _9(^vKp(T&A>Le`5kehrZi*Tyh~IRj5#L6#qiFQ;9s{Z0l}etj*s3pzmRb$- ze)R~0=~@{Ue<^IG!J+pik@Qt(59XF8i-Xhh{zdE_N$i?7cRg< *hX99hi%p)42_4K)+8s2s}lLPjN<&~Bv@C_jp_WKAamT<4K?;>{v6ezBj zU8{laPYgGN1Z*C1r|%^cDOuA#I&P?!OuW3Af6#lEE^^I2LHCF-NBF)Aj_+d8VIfv$ z`csy5+^-lw#c=*#Oq7N45Y%hZ!SSt%unsR?Mtx|lW~gf6B>B{fLJD6KF8Em)HVi+U zG0G$b{S!BN<6)T0c4;kZE7L2IMCo?lLH^SKD@@bB>;rBQ|BBPos-!))JFu}Q4w}}X z(b4X0d$?LbU>K5sYdlG1Wi9cW;y6?>no8X$^2XBkit6ePZ Vqc? 1RO?t4Upn!)kWX}mMo
(=eNgOTvfzE zQKC17JC8o}cI0m$bRUUrkjAf7^;{dA7egn(4exVCQ5#s+m3GVY8}#@I5>JQ)-~JIV zuaYfE&bF6zZIg*cg-%!Bx`~C@^6b!*9*t0bK-e}kI%iR#AjV3eZ81Ho$6y{0Vv8ri z`WN#}EfwgJRN}&2b2-QH`UaF)K|8hKu$N2aNVwGhoyMmU$B7gg!Oyq(7}_ eVTy}4HBcL-i9|o$p*cY)p( pq69X_je&OVh7Ps26Fb@qMF+G;zI+~AD=kBM0-k|ifc z=oU95z!vOW=J$DSkr4Xc_NoUqKxgo)2+FUlo@-VKUf+|dnjLbJ?(Dh-JY3!N@fyhS zhR?2$sA4X2?xep2YRD#2Jm3ZsN9rsd8<+HuXVhO5KT{r;5e>Q9i$Sjd4zncVXV>4` zcn35MkI{1CtQ?U${jz;Jg`;RKdF;8!y@+F1tnH-}k;5#2C}D$1?_8SI5XAHJV=~CU zfD-tUBcWh|l2kO+uW}exbq;T)pG)XOwMOAdV+6dPh$TLF?h4ELu#odmN(^qks%otn zLuh60_m=DqH+u8_+5C7rP@4#Ood$zu=*lK@Wpkt81j+sXW8^jU;5zyrd=Y3(;GbX$ z+J#O*sw9#7oa+|x=3wjfUV4uhUIqPK>WnL#zu$9qgc0;GsKUpzhoyt4(Jl=K pn&A#~{xBC!E z-Fn9gJOGS9quz{ u@&;RNnRO4_;PWd;WD?F?NEG%>iHOt6&mN%a_`9t`7_ z@&)gJ_+Zk|Ad&|C9tp>${Wz*6IG&CZ&kMOCz;(x_dZV-7$MS~r__Rm+H-w$6g94H9 z6Qt~4B&*L0U_Wy72CzT%))uk`iSptrl=!jZ#UF;wFdKS%A7}&ccEu_OThRYt5756o z vOUfur zs)w`waN?SZ^?sVpD}r@(O=!65%;WSfP0RBk);C^yT3f`fO>b%G*~;OV^!XoExJgf% zYnA0rTMHF0IWj?Hgnh#lO 24wxg>l&SCC6dYL{kyoV zIoHQ%vscIIQ|&x$jjTTWx#Z5-%{UbJ&99)RkCn=oq?aJQH{yMg?452Dv*OWoKJV3a zrQ!knp|Tx75}w+w7X_iuG>xIFZo%+}w`e^W(Xks~=t?*M6=+3wbx}_4r<=N@+4^Ht zQzt|*Zeoz%%KoC{gU_R+yC+I7#B^Tk8krPHBaZu5npXhL?AH5ESF|`~bUr}?6F=MV z!OtT78?Y{qLmeNh*VKsZ2oGM`IiZI=9JQ~D{4*DD8wgL|B41#>DCj-N9YU8S{P{Ol zc*?tlhc7#K+n9oYPF_s`+GO#(sGK!zzgH6dV)QSc4S#5LInc^o)V+JR;OH7mLey*( zhtcN`2zNT;E80uveY2G8JHr?|^Ct&AoQuo_(UgW^?aKw-@yp6#Q!!2-(g47&(U>kf z##JiVHai88%7CTC%;R#| p9Tb+ z`oH}pudpy1MYrg1LEC)R@6TByW^7; Wehmd*VyUR0+Sq@OGlT4v5ba1P6BbsiZ8u&7K6LDz)bw TTOD*SKd^O H)T%-c-F#}3z9U=#< zfhP>k8~^C1x8X-6irVukm;oagi*5N%3iOyW(>gBeL+X(Rt2S2gIpk|c&tU)3M!)NG z58`uo pV%v;`5Mvq* B?{a6{>>;UoJG#Ii7 npk7j8B&klK{%CK5X|R=Y&J}P}ETHa@)E`{^ z_wnF d!B0Y20I!Dz)I@6fel~1oP#*I%Zen9JlQJ~oeNJR46@#-|alk3g7 zjq`ffAiX0w%$uazbJ?x1P@2Fyz`}1oILrn@*SBAZZS!jB1ESVzQhYhzg+y>+-s!LG ze^~1M4aV#&0K~N29)ZTOhJ3Y4{}20_Pu%Qhfm@!-qCLJ6T+x~DW?y{RNwh7;weV;Z zD6K&7_}Sa_7HO*Y%jn}+{Ka)2AIXw)s)@<;Xnn#KlX=q0fy{S5g;WL%B$d ^SFSV-IV^xZngG@FzfR@HuX`2+eoFXAbYBJ1v-V?8)qdC`|OvbPimUl^x9(rmZ7 z?Vve2dbb8ViT$UWp`>biXtbfh?{zCwKF91#bMfcI)4LD)2UwRkmA@JwW~6>@ey{>Q zTK^N9r928Pq;aRAD~@{XO?mx*FiA$?TCwu49Pz~-J%|8HG5b006W_Z*C1>^up~J!B zVU8_TRPxle!o1>d&;Eb+iKr*ZR+ojQn?yL>PS)jsV?EQDE7pxmX_x$ITPsk&{3_kT zAMq-(-}j%ygA2t^3vfAk7ngr9^ny|ay}mn4^$_lKFER^&zKoZA4X0uTL=xTCDLsCh z5C3xzXW4DaeW_u3tVXdqK&dO-6y8S^EJflZe4l0Rf>SSnrnr5*6iX%f8^7?2F+;^T zLxq?Pn3!udegvH%0hdwP2q|Wmy}5be`%a9!Rfq?JTk@7{6-yB86#cf4I)Sn4Rm$G< z0ULN!=7wP*mZ*NtZ0{|r<`NQXu(bRk=NH5QaT6hAreT$%wUc{m+fSL5*)H#EHb1p4 zybIj@HyU4N9gaSsBdgngP;EW%!4B1i-@%%9n$lc?_qtIoOEy61zNi5FAQcm5vRb*z z c88sf4cA4#$e5 zJ*{_89dtR?aFe!Re-1?K2Ve<;><^=@or!?zkgkkXYM2M+zPJ @VYJH2u{f0PohJ%Et?%94W zx{vz$GaO@a86td?X5pF<;S^Yx`|xFTbH8i6(|d>izXy69g0}t2cVZ@RDr+$cv}42P zlYxG`d;uTP>C$>0<{h!!(5!^A)A2bdLJ+}s*fJ35htj9f(eG`(;DZa%9zV#=82V2b zN_yJlUd0rUs;~4JlnZkmuzbclU omsUT9JV>Cv8GhZDt4W!B1|DPw*^U0yTG`9NmKYPE3P|2+ z4HX1apP0@4p0De%c~enmDH7m2GXMO&r!zez6I%)PHV6HgR+|`fU~jhjV-!$Abw2}n z&VX|da7W-MJRXRmVoGR{fZ+L6cb*Z}Br=qq+2|u+l}+Rx#dS{R-ubzCDZ3l#1Auyh zpLbS;-Lki{8KbVtcuGHN))Ys}s-eD0S|OHu=;uT~%#{yZXgPyFUQE+HzuAbl-tjED z^b9VX3wM9f8OK)rE}jWYjOmI|Il+7HN8(n>*Z`TB4K%o2HMLn;1S=||i-p#CXdQh; z>m*JENPj@#X6?5_Fd~VyA7AmZJ4h&ZNSVj&bDtqyq2=!B5%W+h@R>I|41b-jJPbdQ zIDYff-|eATm7tlUTl@FJvKDcI67a3M7%hL-d$Ao9^Lf+2XcuDDdo?D|Hwe#$&q2h~ z`io0#Q^z+>$5^3=N1dN3$tKI`m(N8Yz(Jrd{B%X#qY&V-$%gtG>A53y!^V1pPIP~J ze|FE^W8t=os0TCGu^nWXl1`U>RPr9;Tb&p1Rmd(0adq8^Yn1leTbL3Jy|XmEP)JK3 z{%>6G^W85UX>L;u-GOQPj+W6)znTbL?6&bc@c3;vXQ-ozl#i87_&Z!y<^|$`MXthu zK`ufoXdKPSQCsi27hZJkobXu{mAom^rR(lbYAT8Wtd_t)99vIj#whg>bS-ete=SUz zoPl`qCmJk8*{H{%*j5ZUXn&E9nIa W`558Y|;8r)D2l5@2OJm)Xm zQUVike@!m3L*EJ9Y!5E=tktEq{uggk8%MiP;JJG^7q0}H?0qs7me`+1w|)DuLko$+ zIbe&QiBy4mm{9_A*ODUC6C#{rrKSh|{0~P3YC?AdoN~QrBP^c+E_((aVYicP148!W z6(R+JkuV%pYAo7GVU;LM*GPDrgFH0J !U9vAzz z>nc?UAw+|8GogfemQ&XU^H7R|75y%}aO}hQmDTmO-UpX}Fl=WN8*r_xRv5C~D{7eD z!T(T$kHj8<3f{epqBuKVk q7FQ^o@z@(y9@o!xz23+oen=LU*3SM5)SfzLZVW51eo35)`$ zSMlfBi`qK3ET%EH>izPT_Ez0PDO7A<1cIYO=`k5L$lr0H;>b|yZ+*3s9W4_59aP;@ zFN>zOj*g+Dg>JR$X8cY~WDJ1$)}@ngH)WE$>KnLz(kus0_k{7D4|kg0Q-K*69QIm4 zJUfie$XN&%Nvo0CrWs}vLzgcC=HOqa`_e2~d@6Yd7XKL;I%34+>gl0+6fQ-YL`dVi z4C6AOWU1t)on*)Deeqc{6*hK=_=2Kq9SeYyxY+C(_4EQNZBnS1DilUwe !0R(5E_3CX) $_1)M OT>^dSJF-S4k zBNsSwKXgBE1N67=-MqIT7(xhOmt1VNLTASjq@)!>oBPR<<`Nyk8keGO2%g$C>$iJ- zc^VE^B_*tzp+PxY!r;sGVV{cugEqGpT;M8PU)}?~tQ0vg_hdeZFgpVVc+j;2te=Ej z87O>Bzt5aJ!JW!V1AeKJGWKa~Fq#%v0i0PRS1nl%c$Em~#`kS$V2f$YLaf>?jHMn< z$PBGDat)O8x$7sc39(eB<|MNng?GsfVjaDSJUi1H`vX!SSr=JYy!dl;`+euLa6w=u zJpwC%@IN2zA93F{54u8pr(v-Ckg%V9fwvoY;c0PyD_RfNg>+|;tlR5B!yQ@<{+y&S zBIwj0V6?Szmi7p|o_C%n$8TR$kl%y9GGUGPRdU(|++IflF51f5`trtSe1f2{U{vXc z`|W~5iA-Yfo=tvM@#6O#% %r8H30!Qdwh-1^E6<5 A%0~}XBxO_dkR8iYxNJuNs3(mNUk|u+xTV<{! zzZJyU+) `GIp}x7&g(UI<`-9KIga(9nfKn*wVTI2!hQqkNk3~qMqT)a3 zrcS&+w+b`iH1@<)EY2XH1Ea$=8!(^${4~ -t2# zfl;-Spw^2VP;FE=3{jWH;-A~+R0|3-3_y3%t6J=xztCyG< b$|2%9o&?#}>S_bH9LCz0uYmAz-?H zevdSu6~Pvd9TKpg=?~n|O~oa)tPH*ZZ`s<_QC64TWgBTnnLj7HeC68LAWf ^tV<0(y%aO1Q@>nIG! zJLzsDn!+krei@pCu=YKp^o|L(m|22+K+DE?_T+5F8M~NL3MW}%G9@bz3eS7N=q8`{ z$0jpx!+htT%%93W*HsJe*8YWaq?Tq5_nRp>=k@Lp*Ci?0y4fUN4GxsgQv=W1Qz@~i zHKycO&qax|UH-n$snA+MhDuvhuMdb-@=y8h=E%1;AYas5nVFA4X0N|%;4a5|UYG6s zvo)xJhecB@b15dMqL*RfEmMEQQHB8MIWXwJXq~}|#+O!(q0%S*F4OwNzw2DFDMHn_ zydJOVnM?{&lx7kFkz}I(iQrRPS~lJDdJwIscqpdq`}0S QFJ+5SpZ+R}=V9iKhGTgHx^aIL6MemETbb_U)Hp?L)^z>Q>kH#@qT zDygzR>j5-oVY2PSO8&=7D{N*j0jTPoS&!g#2s2D3tqIas66;u*OJYWSu*-X8znttM zFAI3;TsviXcA-U8<*B=g*e|~dGw4uAfs~IgrPgDDv~(xJ;~%Z(1h*BqWQgnct5!W< z1Sfq1FT?XQ{nlX1XIF)wtX!hW+s>34@I9q6m3A_X90~VS=I!wK=QAhQmvuzv^|q1N ze`$vgX_}tIKcgs550HVujr?dFmA0LM_Je?eoTIA51EuGnbpF *Jkhj;WFGHElU1w;YKUKB%DaH^e;SZMNPBvW5wNd-}i> z?b?2Y{qAYPqoU&?X(ZCntj9VFYQiZZR4}d68FBab(3G)ck-3=eH`bmkJVvY^<*sFJ z$K5a27CjP)13K|K;BP6F+m*cUDTi+4z2(_D{qtzpAe0PI=Kcs2i-1cP_QgtJM#sFN z{cl)ME=&n($gmc!wq_yslY0Mpz5;HnQh%~w?#$;H`<95tf1zW%#4~62_D%BiO2QN$ z`8gGs!wTL*JEP5@r9pl)lccAZsmo-yOH`G$ix+hQhCd}tEV<5sy+Y-65A}!Ak9w5y zi!Q3!5*CD?zD_`oBCCP~xC&HflTDAgloSn~B{+TbtgQU3SA y<_D%1y(Kc2jqwE2(li_74l0am|}mE`EjzKv=BBh;+W`lDK@@H4{)9@7Ta zh-Oz#(G)ZL%QkaSJ{w)VR=;GbD?S1~LN)bw#xKV3D>>ph%}x*iobz&2Y~ZGeanELT z+jgrCJiPTTGi~tez-+%I-Rv58337k_Y^tOsZ!I_R>5pv>;D2{fhsBVm_`~+|HW+gv z+v{v{CZMSWB&br&Z#nHQa_}1E1OY}l0@M9WftDxBSia7}9uixFwR4O80~>3cb%p~h zr`}fY!wJzw;6LKZ?#JK1GmtgM(SN~QzdMxM)SE%?^s|`kaJYi=g}IaZpJL;V zx !R+BvZ+mIw1_jZ#u2177s`lq47&kYjipfhV(Ep_tZ zK{t8al0hwH+@e7@WqcdpTk?ZJEqQ#q!Fk8+m?b_=%Rizt<79 V1?*CtGL(LThE)=VnKQ0Qg7lr?ZJ(`*cQ+ zVY;p?3ItwRUxa`tmeM}pDJ*qI#QIhm&BhrCH$&?2# >X@!OG zbqZIIK`~jrpm2^2(22;fH?w Y#V}4?TmROnw}OxT+f$ zPiDKeuOZBmC0-7;sA 6;R_le`Z)+QC?b!CytRBv#dTh(IXZOwm?HE z34Uu#HD#G%t-frX$Qs^6>vxc}*%aM&(EoFMqg&2pzW?lhG4Ym%4&NzkB`PeN m z$4|J-HQ7q~x2`SKIHrf&!jrj#Bu%G60&|)0YN1TeQ`P8Tb>+KO$V+BurRt=f`Of~N zTgMuff?Qpzt_4tkvz?HbOPMiW@bpA^GH7~x4-De8#}BIm?{m#ECbe5fxRJ>w{&AK9 zZUE|{Yqp~RV1GZQin?2*sf#fz$LzzYx9vIwL-Fk?Rdw_ads%6-FSmh-n~&$=mW`;{ zMxMx$aCP3ssV8}*2c`06GE*(F1R4vMZiD$(p@VHd;i6M#{_#+pUAfgq51un_dm`Cj zV?CK$*Xl;p%4k=ql)GP-Ek>Kxn}A2xct0J?f-T80xd`>-c-c6?ul#Z?v^gE(40%yc zvM*7^H;l2DQPS~xv2u21T>aNTQ{pe C8A1u{B{z0_>{M(SGqRDMRchZka~pje=$259brG6T6C7 zL4+eVdK?yX1Hj;&9mUM%?>k!bzZ`oRW<02o#bCk&b@hb_v*f1XU!W)%P8b>O{Wp>n ztaV5DvIDD7hB`(i< vK$0|cnwUItuZNCLi4}tsOfP4drZe2Ff25>2dS46dc8e?Y4`~-fxZB# z7WO&`g-9?NCff#ja^53!3T6JjXhf7{P^Rpt$N4oy&1 F&+@IcxH$tj_2eOwYI{eC z|7PeBJj7x;!Zjh!1UMf~3?~3~P201(UnmB(spFx`U>5z{^1{C-yLvoF%T&t&rxhdk z^ZO|*;w^}#tihxxJK3s4p41`O$-PSa-VkcH? vuyPdU%K-+nzfierk@;rEjaEkOULItnM4mJ3X^GngDEi8RQ z9_AUo@iI>Jen&RX=^q6${78#o3ZK`X+p2jcI+;LXv|+xf<8{aUO3M1>9u#(QY}n~@ zEih^` l8Z+9Kt z#%A{TVd py)GjoC*y8-MUZS98_^#C zKhjs8a37}kw$4Z(m_M0^mb48RoI8=TxP7X2!ZliEjhkrFpq20!yVYqwWxCZ#_sF^R z*TfoP-7U(({XEq&e{4Y{htF)|+%TOyr^_s)A}DUa5cE^X|14xreX8s2P)gS#P0|ea zXG>cf`P(q`3Mvl$06yvQi&O9wHDW^4w1Qr6LXQ~YMj*okM|L$jGtS~!r%*mf)q6Lm zy5g*!dh45W$bf{4*Jp;!&drMXnxD+@-m*$g@9rNg@_`%z$t*lgm}V-^+HUh!IG+cy zDK8?ms(XYV4Mw@WAoBZ;Jm>qNZ0$(toD|TOIO{YhqQ Xbu#B7ub0U@%p?Z^ z*|1819uynTu2tCS-tN1MFbo#G5&O|eY#DISU||wYBXTzK`#HW3ZyL}!sKc;-o>(ZI zA1(0fbNztd>v=hbHZ?`kO|NL%4pPm|O+zZCOb*J(#14cP$9`hLQ!?IOq8TeA_UO@H zEew8H9oJ2R-KPi6yY(x6RmsW{I+{1rO$4b9c=PAYMk{TLERHAE&Q=uqjo5;p@AiGI zJyOl?ti8+C2?^IFwVJ#)(Q@GWiiZvNuvX{v;pXquX{T4*hgJf0K~q6d R(c0s2g 21~Fe>3Sf48p>Klu8GsIBRi3MImv2g&YlsuOPkO^1571l| ?Ptk}9mCtxSZ1Eiy6(@#1{-UG%;KQGjzMqPipwRoNDx =rWs8?;Q@|5P;#n!bMXvGna`DPA`05*^5$% z0~$r2mEz=#!%%P#lyDY3B<#*x&P{y{{U2^8GT`B;BYBat!SkCKNXWcmYh8<`Y0ziR zL~RC|Ya#f&nV9U%gk#1>Rp#%>)$Ape9L0QMMknSRl6lzkK?*OERG79CFku~Z6(InM z%%=ZLCNh-(Tdl`N$hyKuWp2Pi=x$#!?N0UYCFb^R@b;nKTII}QSUWJ+b{}>y5&wIQ zf}aBw9==Eo&HgkN3F&p+fuaOtrs>t+=0Y+|F-29{$9!GtvRa-XJOYIvdostz!DeJd zSs8ptTs&6}>yCwP;YjoC@!VUD^%7Y^(66eOgdawj+s%fYcK;i@?j+`ikE$2`_hwrw z5fnYTsbeMduatyy&qw3`+^$ryNMSuPD5TZNC8X&t({UVL$~5G$c%`uMF3AfhG=vlw z)aOET!(BN%B;9H5iUvzZ+#a)~5N1P3VZ)VwWeaofCSPEEzO%meXM?em+hx=2pxR0q zjwRuRL6m;j=sT6r|7K*WC{*_;rgG#0vX@oanK1sj(?mh3YocMlK4SH# qf8Y#Pw`H3X+Si5(%_Rl*-dv zKJl4Cg#O|4)tL3IJN6D&Mm_ ZkzD^hHvh8y){ox!XO%3B z`&uQ#Rhu|GVthS5+R|8>oofY2M!|dY@SdWpTg$8CEwXRMa*LkF?fYJM%x{MwOLn`u zOwh3MVc|57MI??8GtX^9vp@MaoUy`XpXQ!`{|j~+iRJuhCiDi5R@bD_+Fd(G{nU)! zV$}<$`0?&F|8SLj MO9v8V(@3-0r=ftfuSd} 8|_{HBFL?#59S@mLdA!TX7giDtfOvH4l zmKEfiII>K3mJ2QyB+_Hy1=u-fRPHMs^)R)Npwo+Jb|PBch*r; =a21Db<7rXhydzD?lhl!-e z7Qc4~)6~)I#x&Y7jZQ?f6K>*|PTxp2A)z=K0_46wekZPY_up=y)uohEt3%GL4LG$r zWW`IG2Lli}CY5Ms4&`b}nvXO6vK-poh|PUdKf1eHq0x@V!hkF@V=bcWH7SJv_J||( z4M!%+wOmVCS+dsY)g>F;QAyOQCn|+_@BMlPsurqf=Bo+*4k&vrlb)Y?8g=4%7sG6- zRM>(D=ln3+TfqKNU#ozbG5{qc827(+@Sn^=S1TEnB=@`VqnVL?KRf*}6FR+!{g(0X z8@>Uj)s5)*4!zJJ7GlWK+ZHJ2D3Um5sg==a$8>tO8=hVpu(o1hLgcjE8a=ZJv46px z@C&;?a5Os+JB@_(-74$5RW|l2bb6ND5Si}Xl$(+iOWY-qQccVNEY(tzfcJ^umBoyu z1#2~qJuUe`JOdbKetsOxBhaEOSoM5>?BM@RFjCMeGq&bt>R={NIA>#jRfrr#OnAT9 z|NFwn?DUOxOtWK;cF&q_g8QFlw(Er*p?u_%?_X}M3-$kQKO#+qMmu41zrvZ5ea@Zk z^TL@P)x ^h(^bZL8l*iH(w?+@$CIRb{I*x0ZWTH&4fW3 z(dr59zN0sAs0xc! 4U-SD>2Y?6)IUoAGqdpkiX9p@}IfH(xzuh!~{Z!u{CpYIwWyG3&(7 znZYa@0ARG6mepsRCt)m9vZ>nlAN!vEkKm%GnWNKpG}|N9o&8pFV5c`(E@wA*5gR^S zH`-xZ{36OQb?h}0;z(JnjojEu?5V9seNiS5>i*@DUYZGwPQ*tWHEwR!eBXSCk3ac$ zC`y4Pk1Nf@i*-)-3_{!T39n(WP|dBZ2oIDmm_!hyU8rP4QRzmVwF@-`vuptF>-5RJ zUY` TxalFLANAIIagBDE+!J;z9WxyF!}4RK$~OcC{&|?=n_xMPMZC^IdHQc} z7_rw(xV4oRq^D|
pK=|IdR0;1(Ip*qp0!HGjr|BVjA_9?fC7Um*EZ)Te)~@ z=O`U VQjfI8p=$g^;;)M hBAlLg})H<(}nI@IJC^>@X%VLs!i(s|Fya zi10=Tp>vuG?Osf?8{=GtRBYnSsDp1*jw*NY4N@s;(0g7*r_nN5r&iY|rb0}Ae>=Tm zi@fcBcCi|7*T2@p3_u;b(Ho#$|BffHDaQ?Ls_awPPG{d$taR4u#%$M>J3CdD{2YOW zYJO0L`zSA#+OZB&q1$)twG!^^RN2_8+Ss#$t3L;Nzy|Ox@DZ>n!hW991!57_VC-=c zGn5Hd8ea5|CCrl=^AKdxGf1US?s1-JxLC`mw_?_olOilwTTWT5=7kDU5Fd%$`15dm zvOMq_V%q(fG X9A8QeNoGncVhNhiMeZPO0)`e2bMtV z4IKSJL~rPy4;`&;M5CP)as8kqrkUk3Vwg?c>8DzO9&i)nI&dAh4Q#2hEuwq=JA@Em z=%1&hbN^c+`hlwa0q}1y%BX!>(DM_eJ8<0Dsj^thcxJ87+HyKG&SoBnKRI;!j_rEF z-JJ@Xdll;K_^^z459AK;Ch&hn^f#D+?BaD&7`grl#-m>bRzObzXGG)$MqH6IAgh>? z*wpJ*%DWcTicUWwO&$B~m}IBQVs+HwTdRx|kZP5jnlC-psu@+Ub(m&Cvm3M1NZ4y9 zbb1k)Z|0g<=NZrjX_v15Okh?GKnGh;A7Nvbmcu^?R`=g&R1l!qiCOjxIt6+Iqv7@k zj@}?D7JqNx==9A}_Xn %i?im#sXP-FAC*e|2^D zp4Q$uHdX0}Xr?O5z`w+Hy97oGH^WreZ6<8)RoH1%II(1&z)=rC4Xi(l{Vgopu2+h3 zUw_~V9l!8jum!LV{3Gx)5&kYo+ qzu6)P#04Z!A}k(vfW z(_);0CPo0dgKZi!gPAe_C9=yN@TLe)dCR^GqYKy@I5u`G>@{PO$TyAn;gcigoqw)@ zjb|4;#G^1#4LB46X2JKd3wRymLlLe6H&nR|>;N5*9!Ou+4W4>xL(??5=Q}%>xANRw z$#coo^gB8t@-^U@azZea)b^U@S})Zs+nmHlyO}8F0tbbk{?H7-cD+J>=$PW|4zY0P z3h4h4(Z3gwyVYvaKXD>E^mEcw`0|&t^x8FTIY%F~4%`BLOEq7zT#EZ5@CDHGB86vg z;?S$=4NW1-E?V$0217?HC<{$CBZb$|LhGPEuqsj>$`a$JsE>s@zp?L4=SVNw1ZK(r zSZD}78FUHUX%T)0>k2H^X_gDEZiIH@GCv5)zvN4FlZ(5E4dqbRKEp0ri0OOS0>1@( z t>-ycMMy-5F&(*O zEUtC_e2}W6)r;8Jt+MK6saF<`mJ}39e}mK#V2yUnZqsrq!S$awzAiR3_n$!Ds@1N) zSFis;E^?bB$q6Zt?| =zja#KP*1y!w(&COlIDa_8{L+l4UBDlho_)UyI{~TcFoL zTJkMC6OWv!E+jo?sDcGAo+P#*9F?_<>_k{+{7JnYh=AyXSDFp+0aI^JZ^ip1@3D zrVK!q*^ZW`gLV|f*W$SPJjgom1xn>IgOtQ_#~1q4HF4kqP5muZr7glHa09z&w^g|= z!uyyd?|^iGwsWp`_wKFi#EFw-CF2Kx`tL2xDAG$J)I|6ku 0{vWVeum5fy$J;z;`OMC> zkmo~&!v<+O=tj}PM W&fRb{`xkS2lyhU4^T7)m6JUW zxd{gMti>p%uLB#Z+!5i12siVb+j-7SRc^&`h~Ml&W?9OqQ>Tm2<@?|N&-eAg7cYJn z7|lRT63u~zH!^PmPh+`&B^ZS&X(rU$F+25y-DbktvJK%#9`hhn3$;d_mc4;vt6pJi zze2lby%3>&*`JzF68!*pQ;f(=sn(->a0uxPVhgE+b;9m2& z4tX269F7g(wb#CL|L^iCW2Owi#>O=Oo_p>~eDJ|90qUSvL0-hlK&6ZHiEsKounD{m zd?=zHVY~hfRoTYe)#5Q2(2qa;vsK3y$SL5TV~R)xvXBdCjdB6cM?I2-?4dsFVPRSH zQta=Of7^`;gP|MkrK9>^6L?QVeg(XpW%^N?(yvxO9lG4g%CEHFf41Y?;4U_s?;5t) zPpIlMBAf-zi^xluK{%(XXDF3nKOs_J3%j@85|Jw)%~{&{17^wqy!hhp0+3|`(sY1` z)Pc86B24 |$lR_kj;VZ#b9VaxS|&999Np zmtF*FHQV(-dE<>oW5Hj4-QMSwS3;~??2?x;V|12M=u_kZx)JNU6;>B*6xZ@X_E<}T zWx20z-%$^-|KVl7wurn7{91%taV*_9hCH{3?$uZS>jQoMkAM7Q|I moFOh9wlW?g=*y|N53HH-T-&LICZ4{_|G{SFZevBl+H6|N2{lzxkWr z+i@ _s<&+oBbjfphv|W++x;ES+_U}ifGT7Me-cr?fL9Y7e zk2QH|p@{JO^S?u{*X%gw?t;`Ac?K&WCxNFy&j6 XZs+?eyq|LDf-^M(} zu<$PdZ(*CumWcG7b9tUWPBVRfm?;DBXMgrR0A6|J2Z%(7FaWmx=#T1KKl#b(^?u*o z$aA(pu8S0k!ND7dDH#CF^=p9opZ1!FG=Z%slDla-KB-03arNq#an4-o$(Z!h#!r9x z6`a!)3r&9GXUw0$8-S^~fJTM2rS!4n0zNkO_u7A@#hqgd;}&pDRd1-$4Y`3w DlZLsy(@dzLcY!6AwcXOz5`_}1n4oMfX`ID|1iv+Pg264{E5}ejpr|< zsc$%ekLALTh%^(FP&pW*zWVC7kNT?u@X9Oy-9K|R(5E5$x1j$C_}5JE0u O7pMLkK z58*Mxx38uf3JgFufXk|!72#=2U3O|NV5d=Gb;%TlD{=m4k4nqKQv&BdDb@X5A)W0v z$k6R~8@LKw_g# i|M-)?$uY;=1DHV=g;o%erii@jOK7dh-^)rp0=KtK zY_r>o#?+A?1wz>`==}GGQi}bfQr*A!FQJ+1GVmVgI;1nz1T%+WZUANouf6t7UVH7E zMV`Vr*Aa0aVm +RSSa6CC`0xe^3>Q&HIF}i7vnZr!y06y#J^|~q|eO2yayXiSb$~a@W zfJWPdDRvq$t4k3lmP`xplMrt5G1uQb05brIulu{n$-1Gx;ttmG`vGWs#DPEhX}EKY zW9|XWFh;6CAs4_E4$B1$9Q&<=JG(VD_Nugdksr !=)Y~TXIi=sfgVA5F0CynjL2d5)&oJf&;26NU zs3Rgbuw>x7a7Zq|XXiKfDl|J0y`jmUrw?cZvRoJrO++>I O^I0h)SCO3i0s(Kdq zXPB@>fiNhw(J`UQ#aiYiuu~NE(}+#au51KCwm+yNmuvnaHf+PlMmE}uVp@}iV+;KG zE0_mxGtcv0^ssZ==6GzF8-N+c#f#RXaN)v_!b>5>J_~#mQ^Ktg6cGL7qfXDpa4*&} zRu(cAs@5cwJBV^AH1C5EC=02U8GpI=2AW+f|J7Rw!&HjFB_)L8x(wWQ&UKx0Guiz% z$2jH&;20r_qE4RYH&ivWo1VdpfrSEIZf=kY+x3K{TE=sy`bE5+27-}TgB1kr1&Xm= zArt@@W+wExU9Yg$OlWqk-(QLkE6@Zki^yf5IbZn42Xg~(j8Mu2gjjnl7XY>{)6CK8 z#_ai#XRC`Di?xinq!-|1G!0XAyr4Hek055dp3v&W3^R-U!!Q;s_Aloq-p8cPf!XeY zo5L`#0vsdw{(!&>C`2bFe@}fbpyh{FY}XU(*Dp2f EE_M% zO QAR1QEw+~*Aw Ls9ILK;VXcIJ2x%niUXM3!Y`t-W7k$-qJ{07hf0+uewrX2Ql^m4#}~GbaZm zRU4x=IqEv}{Wm%>x3_ED+OAS>Ck)a9T7N<3|2puFu@tp%{V!ge$Nt9!^AO+|B2aKe zv>~FGfVVNx(=mE(Q1I>aB5rTjxV=-OJBW I|6K~!Exg!$wovY4c|6_=`0XW83S;+>@=?>^M zRsBaS8P}L}?Nh(AZ`Ui_+^Vs@TctmAMhzAv%c0$KZ0;qze`kRk8#Ow8H!(o9nBSLS z^AvuqDwkAUBP1Q?IDVMt0FE*C_hUpDs l-|&>+laZlQ{~Qfjoqd({@lTxe}Er(rOMSjcQ;jC*ZEI+ {_Sb-R&x?ODU_1DZ@TSW?%~cqtj&47q)s1L(ZJgI$D`9i5O2e1?%A%s)0A$#7rFTJp3j7>+KaSIO zr?W;V|NZip|NE#<%^VMixd-qB;JN4iV}9q(pZB7u@)77?VXk@&8(~$UH0?T+|I*CS z>6_R`U=EIA{=;^Deg^W_pqD`FHpyrn{2yn`4ZyL6Ez-@+|3wtla_90LRW5<6s7e@j zeI7Fe_CHGNI?YTlB)o1M|FH!fX5U={{tozC;2n@1+x3ln`1 ^(0@ %sqf72p2B= zH~&oWDZgdlMd0(Q`bDf^=p5EJ5N6!RSgha07XLc7_}77VfS-%78RWrWzVkmxn0o+E zB#Ojd*H07L!J2lKK$bBBa1QhtV8wC;+yuD;x{a0mdO%Z^{dtGqlZ*MKeF9O^5G+CI z^-`{0-Q}xaJ-ad(WM@_LXFOr33+|?>+f-d?i0n^Q^?LpF`Og2OVeSEZh7iY&^XJz{ zlBhixWH*6LtW@aRdtF~-Tj#gMX9sf+;4^^leeZt)aQgHjjYgmC?JilC` DcGh#=ia^G8y;1Xgl^C8S$Amyqrd1eKPKB}75GVToN(=@g_xS|pcV zYT@y|zH{E0Gjl)8mzg E0vwe;xGTK9)Pb`Ew71o)8mn z03f3HU&jG*@@N6zk*2evqK=M}hmVK1lZPjZnxZ0$r G^oYPn^M z{S!ll*~7X_SR}y4UJ2?aHTg{X39ybPB?tGsd;iFgl8P)3V$l6|>JbF~eyxxj;rR07 zd($`rbIAkd#nPtGAoTwJ^~`n0R^HalXyDkB2r_c6l)s-{04d#fFQjLgle8h-1IP$m zD#!{x3+dmXAC3e)0C0#G7!c-DD}RGi;{o6To>KxG ZMTC>A z3-k-<_frD>v_P$1gWV$_4FF()Aqs3jIWe$zswPJO%$B7t(g3rc8OuOG0uGSPt;&H5 zZU?LkB6az2yM6$Lm0&gj{H|)82$N=ERon<90pOQtocsiA1w>>k@C^ejlDL54Q;HEh z7ARif^NG%tve%yP5D*-oYbbprQ)5De5|RFk-v9V;WsP<12dqxPn&ug)1K|c+US=*k z1!M~kI{Fv@=r6~=-%83SZ~fg^{p+v=L!b71zI8qHV3T7#TE6Xw$HfOowZ_o%uQxZR z@jUx*YJEFh%glgzL%?bI(n4f`u+a3;ub|7gK*<~M)BGZx{ufM)kBEr&Ic j2R4kJkKK8V$4;1OQ5fkvz38A3pw0 zS=mLB_noPuiw4*FffD#JN7oBdg$ElEjE{ }_(gsxj19@f+tJdn0)p$cQj1TIk1rY^mS08##l> zFS`S5r0bH6RVuj-Sf8@yb6WmKLh(8k!a*|dX+!G~D`&E>8j+eSWC6neMemE;1gUc# zlxsKHZQ#!as6L{SB{QWZ`AM?&r|W^A8!eR5J@40`gr7Ndzoe0?i`mO>;(sj=R>&?a ze>GB;KM5*-FI`}&=2qyZBd8Z!Mj`5(!#R>mtvK|Bzj*3bj Zx+( zugnS8e-F2}wxdq{9}~wANA*E$xanN!g6T?WTj&I{p(O;rGqd~kpU((0WIJX($?`BT z<~ipHp-LGfPnS+NOb<)nD%UsgHjtkREGN>hFnCg7X&73fV$h(oUPd@cT`^V0WYAtF zUOlSoubZSZ_Ud&p>NWQ5l`V07%sZ9B7)Y_cZA&j*0xNZ|u>Fy-!nBtm-Y%bOmZpta z{pB9ikKmfYPcRs&r|4boQ0b830RQ`D1c#)zZskyFE>C@wb(DBCm>-W{p1*F|rOKfy ztV&`&XdX3hv+uP}y}vt;_Vt8=;e7BjX*X$%FJYT_+pD&BZ416*J958mcLTQx&j!y( zwwK0L&)iOn&uDhg)97(#iRYpq@nkxfkfiP5aI)<`*DPnm_+j+wH?kq8wv=wC;&HX& z{}5aUv5xCv0W@+Bl^%>Xm7;&_7hPXi+c*m^eChtuvw?axlIEJ@&^F%q+h=&VpKq~p zwsK%EQEDpBHQyRF*RgPu@b0T}UXOa5cwAq`d`8F+L55}qrZUS=&M?sM%y6bsZQ6X7 zZ`W 0bWI(Mk~TUBmVw_mQ?GUXa&(zA(YXL|1QLVGuRkM?r*9_&k zwk(Tc51S6l4tsc$e=T!0giX5WTn#*?KGGtv!ugJ~iGz%!k8Hqm#bd_L#{c?Ij39xa z{ej?PIVy$6gv2JyUa1~kG{+2=wjzs;d^zJ(gCIDSDZ|zCVJ_&?X|lwaG0-w;m`BMa zbbGiN^nOJZ_8!6POqWe_8A|z#N4Q*I=T)Pg&l?{M-*n}M$+aUg@hGV*zEx(yrP<5R zvC;*m3$xwJMMNOV5s?A07s^MO ;hx@Ws(KdgJ>ZozUy@-}kxGkk2THy1y* z()`^X9m@BAVIpRd93uHHi#)Slelv _l&=Ly*a}I*8haSww)z(F$9qayvD9oF0w8fRKf5n_YnO;Y8?=(@=c| zR%gvv*WlPCaPc@%H)`VRS4G~pMxyCuX#+#<)u*Pdwp7;Xb_Qsd%qcU&a2}fU*Oi`? z->NTaRS @)g`5St&CmZ)ZyDU*h3tOWb+5#jbk?XNU0zQ8ia8{%VmM0JWO(hS z{>P^%$mJ|?q;X_$1W(LbY~O6SxpLvSNWAzw2p(=RWQeV*XhF?!%};kO`3IknL@`mx z{6VMfbu{q?7`Y;qL(kkN4&E*$(c3Vzb^Z-oLa6#{_v9x9e+_ )R)mWRzbB=axOX+<2S1UTRmG57&~H zoy=Yg#6WMdT`gW&ARQIQ^5toK4xlZsF#{)mwvsFkJ3LR>Fg6REEgDs_)v~H#p4e4L zjhV-;J!WX%=tZ^9sphWCIQn<^l}p!@_sqqNfJH$d65YGU(BjUu#E9T*JG<~Z->30^ zbO2qn2ucd5xk1ficOG6n*$HpFt+VfPTe-06vKsqo@&rvn7@L2acK17WbwYJmb&6eu zJs}Cs%*;Sck36;;O @tch>1SA=A0-H zxmTMkwh&!S00`m)fQTpnxV*c^Z2<6n4gfn=03e+O05l$-UiYZnt5K+$(o6k-`Muo0 zcym>FU%0_pH42@7ux-1Sz5P>)l9j9n94!%D$j3VkQNvGRvkoMVn+0?ce(da&q$%L8 zpoTp4=XU9KU+tUf5sKZM9OT9dxZlrxw3GT|WkWHiVoTU7q|w9h_ }k2>RB2dWOBh;=T%k+Loz^cP7s&cQHe04Sf3?2Uc{|uFi_q7&Y2h>5E;_jAH4oWN z*|)r?3&mKN5Ygr~KU_?_J@Y>L8p~TX>*3W?*;s7Ol0Gab+Fn#lovzHGgPdF6lSi)G zL^yLVH+_Q=>wUEj-%sE@TUwrf1xP~1p7_iN_cAh+sDxHG1s_+;wKCzch DeCAOo-@o}`asDR~{uPgu1&}n#Oa=LFsLvp3f`C>Vt~|jK zy_%nl{Zg&~$MZF%AA1=UPk~<8^!g4H@3cdr`6qHkzF~rSpo=V%Q{$Dr?VYlliu04v z%=&RRf@F2de7c>);typLsxv{6>P2a7CpLZDX$>arZUIc2 _Ku zUlbW`031ZK?1SN6t ^_0fyGvg`-+!y|wIj(a0BaG-bmnF! z-?&Ny8zS6sLm&VVOE>O+ox*~U^9i^5Cev4Mr=}OVv(#jGI%h6)ozpvIw=QeWg5yL% zxc;dSYTByPsn;~w8I3%nVM7fPj~q;T4;*eQE H((##3K+F+ELsa= X*VuO?{$UoJERCFv1zCRtLIenGy2;i*IhzdLb#!lN%sklL-`-+F z?JxllW2nPY *Y~!;oIPgyr6C68E{%9$}}MS`_bfXO`Ru~*8xi-vjX-H zvjoT^#5dq8?}IJ&Wlp}ze&Elo>fpvkve9{Y{0o(4l0UkcbJe=OGP1WBh}U=wuzoO( zCb3vXz{I}y= 8r136RhGZj7?Wab`-)4x%6(E35ET$*S>Gr{7Hy?1 zPvuKMN4}VU7FTXrm>eeq5bN>rBwlp`PgxV`{`=85$()C5uFqLw0HxJzMi4{*__${J zMO_0Q;^bTGu%N6*_-eEle8n4*dr{LGd=cI^nYaDe)$!S|w^k}Q2j^)sa|wa)rOWr7 z=U@&U{>sTuswbr)?Sjc 9{E5BTD&WCFGRb!kCS_jD{BTS9)Yijf$eoGejH$BRliS>kQVwr#VP zPs^4Xc>MxrsW#M9V*lD85LOCp=F8J-00UjX^#H61y@ElSuoh4Tf)joqVWmY3|`1 zzHE?to7@Gpk`sq@4s#@)7@1z!JPU>^GKJpn>%Q;Y^>4==VlYTCO|4^&7;9(e5 &vsb23+jj1) z4F{o&?1`kXX!p1QbG-x^0H9^JkC(#5i6HC4TWS(z9%5Q}!C`+c IJOr-(fMiVq%-|BreT|=+0PWgXb&y5S$ zG_jI1l%yt}bT4l#k^g0eq2yHHjK&w{?`d3k@CQ ?v1K)MT #dYWTTR+A7RoqtH(&|aO_;V>9LbLXPn3YBbp>+MnYOoTceweya=B)lEz5H zLp=NDAK0Im^8*inYho^qYR#Qdzn_6Db?UQTs4j<|%h}JQ5# ? z5{Fs+B?@B0C()s2L3QFMo?LZZrBRzLX=X>-xfw1_^{nkMY^?6lVgoW|%aOd~y;V$f zSC2PJkfFe5A(&8sdo{0Co%f9>o#kz*CRzHQ8F$tEB>cewUnj)^>+%O%(dyCa!bQiP zd$9D}qa>x9CI;OPHw~G}AbY<}mG;j)*X33HunLBdiRVoznp0xEgd+S?KC>~mPK80W zQ^fo F{<7rqIFN9hCB? zZ{1Q3@oG>#AA8vR@Mza{MS#=Uc_yV~`N UvJ{jza zT|v*pR%1$2TRUMF0e`DV+%8O#ii1 Jz8+U5lkts*sd)3SKz%c (j|OkN$*b3z1o8lke_ zZzLZqleC$I#|o*|>1;QvIPMtF8WlW@z%EFY@*W$g1UVFe01tVC?CaWvKX+N~&SMFh w3o}1aSIuJtnzw?rKNs-3{y)=#g);%#4FR;juZ0`#H8`NAtff?~VD { + if (typeof window !== 'undefined') { + window._properties = privateConfig; + } +})(); + +export const _properties = {...privateConfig}; diff --git a/server/index.js b/server/index.js new file mode 100644 index 0000000..95109b2 --- /dev/null +++ b/server/index.js @@ -0,0 +1,21 @@ +const WebSocket = require('ws'); + +// 创建WebSocket服务器实例 +const wss = new WebSocket.Server({ port: 8080 }); + +wss.on('connection', function connection(ws) { + // 当客户端连接时触发 + + ws.on('message', function incoming(message) { + // 当服务器接收到客户端发来的消息时触发 + console.log('received: %s', message); + }); + + // 发送消息到客户端 + ws.send(JSON.stringify({ + type: '2', + message: 'message', + })); +}); + +console.log('WebSocket server is running on ws://localhost:8080'); \ No newline at end of file diff --git a/src-electron/main.js b/src-electron/main.js new file mode 100644 index 0000000..2aae86a --- /dev/null +++ b/src-electron/main.js @@ -0,0 +1,57 @@ +const { app, BrowserWindow , screen } = require('electron') +const { join } = require('path') + +// 屏蔽安全警告 +// ectron Security Warning (Insecure Content-Security-Policy) +process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true' + +// 创建浏览器窗口时,调用这个函数。 +const createWindow = () => { + const win = new BrowserWindow({ + width: 800, + height: 600, + title:'沈阳华翔',//标题 + icon: join(__dirname, '../public/app.ico'),//图标 + // frame:false,//Frame是否可见 + autoHideMenuBar:true,//隐藏菜单栏 + }) + // 获取主屏幕的分辨率 + const screenRect = screen.getPrimaryDisplay().bounds; + // 设置窗口大小和位置 + + win.setBounds({ + x: 0, + y: 0, + width: screenRect.width, + height: screenRect.height, + }); + console.log(process.env.npm_lifecycle_event); + // if (process.env.npm_lifecycle_event === "start") { + // win.loadURL("http://127.0.0.1:3212"); + // win.webContents.openDevTools(); + // //快捷命令shift+ctrl+i + // } else { + // win.loadFile("dist/index.html"); + // } + // development模式 + if(process.env.VITE_DEV_SERVER_URL) { + win.loadURL(process.env.VITE_DEV_SERVER_URL) + // 开启调试台 + win.webContents.openDevTools() + }else { + win.loadFile(join(__dirname, '../dist/index.html')) + } +} + + +// Electron 会在初始化后并准备 +app.whenReady().then(() => { + createWindow() + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) createWindow() + }) +}) + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') app.quit() +}) diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..31839f2 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/src/api/login.js b/src/api/login.js new file mode 100644 index 0000000..7b7388f --- /dev/null +++ b/src/api/login.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 登录方法 +export function login(username, password, code, uuid) { + const data = { + username, + password, + code, + uuid + } + return request({ + url: '/login', + headers: { + isToken: false, + repeatSubmit: false + }, + method: 'post', + data: data + }) +} + +// 注册方法 +export function register(data) { + return request({ + url: '/register', + headers: { + isToken: false + }, + method: 'post', + data: data + }) +} + +// 获取用户详细信息 +export function getInfo() { + return request({ + url: '/getInfo', + method: 'get' + }) +} + +// 退出方法 +export function logout() { + return request({ + url: '/logout', + method: 'post' + }) +} + +// 获取验证码 +export function getCodeImg() { + return request({ + url: '/captchaImage', + headers: { + isToken: false + }, + method: 'get', + timeout: 20000 + }) +} \ No newline at end of file diff --git a/src/api/menu.js b/src/api/menu.js new file mode 100644 index 0000000..faef101 --- /dev/null +++ b/src/api/menu.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 获取路由 +export const getRouters = () => { + return request({ + url: '/getRouters', + method: 'get' + }) +} \ No newline at end of file diff --git a/src/api/monitor/cache.js b/src/api/monitor/cache.js new file mode 100644 index 0000000..72c5f6a --- /dev/null +++ b/src/api/monitor/cache.js @@ -0,0 +1,57 @@ +import request from '@/utils/request' + +// 查询缓存详细 +export function getCache() { + return request({ + url: '/monitor/cache', + method: 'get' + }) +} + +// 查询缓存名称列表 +export function listCacheName() { + return request({ + url: '/monitor/cache/getNames', + method: 'get' + }) +} + +// 查询缓存键名列表 +export function listCacheKey(cacheName) { + return request({ + url: '/monitor/cache/getKeys/' + cacheName, + method: 'get' + }) +} + +// 查询缓存内容 +export function getCacheValue(cacheName, cacheKey) { + return request({ + url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, + method: 'get' + }) +} + +// 清理指定名称缓存 +export function clearCacheName(cacheName) { + return request({ + url: '/monitor/cache/clearCacheName/' + cacheName, + method: 'delete' + }) +} + +// 清理指定键名缓存 +export function clearCacheKey(cacheKey) { + return request({ + url: '/monitor/cache/clearCacheKey/' + cacheKey, + method: 'delete' + }) +} + +// 清理全部缓存 +export function clearCacheAll() { + return request({ + url: '/monitor/cache/clearCacheAll', + method: 'delete' + }) +} diff --git a/src/api/monitor/job.js b/src/api/monitor/job.js new file mode 100644 index 0000000..3815569 --- /dev/null +++ b/src/api/monitor/job.js @@ -0,0 +1,71 @@ +import request from '@/utils/request' + +// 查询定时任务调度列表 +export function listJob(query) { + return request({ + url: '/monitor/job/list', + method: 'get', + params: query + }) +} + +// 查询定时任务调度详细 +export function getJob(jobId) { + return request({ + url: '/monitor/job/' + jobId, + method: 'get' + }) +} + +// 新增定时任务调度 +export function addJob(data) { + return request({ + url: '/monitor/job', + method: 'post', + data: data + }) +} + +// 修改定时任务调度 +export function updateJob(data) { + return request({ + url: '/monitor/job', + method: 'put', + data: data + }) +} + +// 删除定时任务调度 +export function delJob(jobId) { + return request({ + url: '/monitor/job/' + jobId, + method: 'delete' + }) +} + +// 任务状态修改 +export function changeJobStatus(jobId, status) { + const data = { + jobId, + status + } + return request({ + url: '/monitor/job/changeStatus', + method: 'put', + data: data + }) +} + + +// 定时任务立即执行一次 +export function runJob(jobId, jobGroup) { + const data = { + jobId, + jobGroup + } + return request({ + url: '/monitor/job/run', + method: 'put', + data: data + }) +} \ No newline at end of file diff --git a/src/api/monitor/jobLog.js b/src/api/monitor/jobLog.js new file mode 100644 index 0000000..6e0be61 --- /dev/null +++ b/src/api/monitor/jobLog.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 查询调度日志列表 +export function listJobLog(query) { + return request({ + url: '/monitor/jobLog/list', + method: 'get', + params: query + }) +} + +// 删除调度日志 +export function delJobLog(jobLogId) { + return request({ + url: '/monitor/jobLog/' + jobLogId, + method: 'delete' + }) +} + +// 清空调度日志 +export function cleanJobLog() { + return request({ + url: '/monitor/jobLog/clean', + method: 'delete' + }) +} diff --git a/src/api/monitor/logininfor.js b/src/api/monitor/logininfor.js new file mode 100644 index 0000000..4d112b7 --- /dev/null +++ b/src/api/monitor/logininfor.js @@ -0,0 +1,34 @@ +import request from '@/utils/request' + +// 查询登录日志列表 +export function list(query) { + return request({ + url: '/monitor/logininfor/list', + method: 'get', + params: query + }) +} + +// 删除登录日志 +export function delLogininfor(infoId) { + return request({ + url: '/monitor/logininfor/' + infoId, + method: 'delete' + }) +} + +// 解锁用户登录状态 +export function unlockLogininfor(userName) { + return request({ + url: '/monitor/logininfor/unlock/' + userName, + method: 'get' + }) +} + +// 清空登录日志 +export function cleanLogininfor() { + return request({ + url: '/monitor/logininfor/clean', + method: 'delete' + }) +} diff --git a/src/api/monitor/online.js b/src/api/monitor/online.js new file mode 100644 index 0000000..bd22137 --- /dev/null +++ b/src/api/monitor/online.js @@ -0,0 +1,18 @@ +import request from '@/utils/request' + +// 查询在线用户列表 +export function list(query) { + return request({ + url: '/monitor/online/list', + method: 'get', + params: query + }) +} + +// 强退用户 +export function forceLogout(tokenId) { + return request({ + url: '/monitor/online/' + tokenId, + method: 'delete' + }) +} diff --git a/src/api/monitor/operlog.js b/src/api/monitor/operlog.js new file mode 100644 index 0000000..a04bca8 --- /dev/null +++ b/src/api/monitor/operlog.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 查询操作日志列表 +export function list(query) { + return request({ + url: '/monitor/operlog/list', + method: 'get', + params: query + }) +} + +// 删除操作日志 +export function delOperlog(operId) { + return request({ + url: '/monitor/operlog/' + operId, + method: 'delete' + }) +} + +// 清空操作日志 +export function cleanOperlog() { + return request({ + url: '/monitor/operlog/clean', + method: 'delete' + }) +} diff --git a/src/api/monitor/server.js b/src/api/monitor/server.js new file mode 100644 index 0000000..e1f9ca2 --- /dev/null +++ b/src/api/monitor/server.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 获取服务信息 +export function getServer() { + return request({ + url: '/monitor/server', + method: 'get' + }) +} \ No newline at end of file diff --git a/src/api/system/config.js b/src/api/system/config.js new file mode 100644 index 0000000..a404d82 --- /dev/null +++ b/src/api/system/config.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 查询参数列表 +export function listConfig(query) { + return request({ + url: '/system/config/list', + method: 'get', + params: query + }) +} + +// 查询参数详细 +export function getConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'get' + }) +} + +// 根据参数键名查询参数值 +export function getConfigKey(configKey) { + return request({ + url: '/system/config/configKey/' + configKey, + method: 'get' + }) +} + +// 新增参数配置 +export function addConfig(data) { + return request({ + url: '/system/config', + method: 'post', + data: data + }) +} + +// 修改参数配置 +export function updateConfig(data) { + return request({ + url: '/system/config', + method: 'put', + data: data + }) +} + +// 删除参数配置 +export function delConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'delete' + }) +} + +// 刷新参数缓存 +export function refreshCache() { + return request({ + url: '/system/config/refreshCache', + method: 'delete' + }) +} diff --git a/src/api/system/dept.js b/src/api/system/dept.js new file mode 100644 index 0000000..fc943cd --- /dev/null +++ b/src/api/system/dept.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 查询部门列表 +export function listDept(query) { + return request({ + url: '/system/dept/list', + method: 'get', + params: query + }) +} + +// 查询部门列表(排除节点) +export function listDeptExcludeChild(deptId) { + return request({ + url: '/system/dept/list/exclude/' + deptId, + method: 'get' + }) +} + +// 查询部门详细 +export function getDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'get' + }) +} + +// 新增部门 +export function addDept(data) { + return request({ + url: '/system/dept', + method: 'post', + data: data + }) +} + +// 修改部门 +export function updateDept(data) { + return request({ + url: '/system/dept', + method: 'put', + data: data + }) +} + +// 删除部门 +export function delDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/src/api/system/dict/data.js b/src/api/system/dict/data.js new file mode 100644 index 0000000..6c9eb79 --- /dev/null +++ b/src/api/system/dict/data.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 查询字典数据列表 +export function listData(query) { + return request({ + url: '/system/dict/data/list', + method: 'get', + params: query + }) +} + +// 查询字典数据详细 +export function getData(dictCode) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'get' + }) +} + +// 根据字典类型查询字典数据信息 +export function getDicts(dictType) { + return request({ + url: '/system/dict/data/type/' + dictType, + method: 'get' + }) +} + +// 新增字典数据 +export function addData(data) { + return request({ + url: '/system/dict/data', + method: 'post', + data: data + }) +} + +// 修改字典数据 +export function updateData(data) { + return request({ + url: '/system/dict/data', + method: 'put', + data: data + }) +} + +// 删除字典数据 +export function delData(dictCode) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'delete' + }) +} diff --git a/src/api/system/dict/type.js b/src/api/system/dict/type.js new file mode 100644 index 0000000..a0254ba --- /dev/null +++ b/src/api/system/dict/type.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 查询字典类型列表 +export function listType(query) { + return request({ + url: '/system/dict/type/list', + method: 'get', + params: query + }) +} + +// 查询字典类型详细 +export function getType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'get' + }) +} + +// 新增字典类型 +export function addType(data) { + return request({ + url: '/system/dict/type', + method: 'post', + data: data + }) +} + +// 修改字典类型 +export function updateType(data) { + return request({ + url: '/system/dict/type', + method: 'put', + data: data + }) +} + +// 删除字典类型 +export function delType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'delete' + }) +} + +// 刷新字典缓存 +export function refreshCache() { + return request({ + url: '/system/dict/type/refreshCache', + method: 'delete' + }) +} + +// 获取字典选择框列表 +export function optionselect() { + return request({ + url: '/system/dict/type/optionselect', + method: 'get' + }) +} diff --git a/src/api/system/menu.js b/src/api/system/menu.js new file mode 100644 index 0000000..f6415c6 --- /dev/null +++ b/src/api/system/menu.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 查询菜单列表 +export function listMenu(query) { + return request({ + url: '/system/menu/list', + method: 'get', + params: query + }) +} + +// 查询菜单详细 +export function getMenu(menuId) { + return request({ + url: '/system/menu/' + menuId, + method: 'get' + }) +} + +// 查询菜单下拉树结构 +export function treeselect() { + return request({ + url: '/system/menu/treeselect', + method: 'get' + }) +} + +// 根据角色ID查询菜单下拉树结构 +export function roleMenuTreeselect(roleId) { + return request({ + url: '/system/menu/roleMenuTreeselect/' + roleId, + method: 'get' + }) +} + +// 新增菜单 +export function addMenu(data) { + return request({ + url: '/system/menu', + method: 'post', + data: data + }) +} + +// 修改菜单 +export function updateMenu(data) { + return request({ + url: '/system/menu', + method: 'put', + data: data + }) +} + +// 删除菜单 +export function delMenu(menuId) { + return request({ + url: '/system/menu/' + menuId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/src/api/system/notice.js b/src/api/system/notice.js new file mode 100644 index 0000000..c274ea5 --- /dev/null +++ b/src/api/system/notice.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询公告列表 +export function listNotice(query) { + return request({ + url: '/system/notice/list', + method: 'get', + params: query + }) +} + +// 查询公告详细 +export function getNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'get' + }) +} + +// 新增公告 +export function addNotice(data) { + return request({ + url: '/system/notice', + method: 'post', + data: data + }) +} + +// 修改公告 +export function updateNotice(data) { + return request({ + url: '/system/notice', + method: 'put', + data: data + }) +} + +// 删除公告 +export function delNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/src/api/system/post.js b/src/api/system/post.js new file mode 100644 index 0000000..1a8e9ca --- /dev/null +++ b/src/api/system/post.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询岗位列表 +export function listPost(query) { + return request({ + url: '/system/post/list', + method: 'get', + params: query + }) +} + +// 查询岗位详细 +export function getPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'get' + }) +} + +// 新增岗位 +export function addPost(data) { + return request({ + url: '/system/post', + method: 'post', + data: data + }) +} + +// 修改岗位 +export function updatePost(data) { + return request({ + url: '/system/post', + method: 'put', + data: data + }) +} + +// 删除岗位 +export function delPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'delete' + }) +} diff --git a/src/api/system/role.js b/src/api/system/role.js new file mode 100644 index 0000000..f13e6f4 --- /dev/null +++ b/src/api/system/role.js @@ -0,0 +1,119 @@ +import request from '@/utils/request' + +// 查询角色列表 +export function listRole(query) { + return request({ + url: '/system/role/list', + method: 'get', + params: query + }) +} + +// 查询角色详细 +export function getRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'get' + }) +} + +// 新增角色 +export function addRole(data) { + return request({ + url: '/system/role', + method: 'post', + data: data + }) +} + +// 修改角色 +export function updateRole(data) { + return request({ + url: '/system/role', + method: 'put', + data: data + }) +} + +// 角色数据权限 +export function dataScope(data) { + return request({ + url: '/system/role/dataScope', + method: 'put', + data: data + }) +} + +// 角色状态修改 +export function changeRoleStatus(roleId, status) { + const data = { + roleId, + status + } + return request({ + url: '/system/role/changeStatus', + method: 'put', + data: data + }) +} + +// 删除角色 +export function delRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'delete' + }) +} + +// 查询角色已授权用户列表 +export function allocatedUserList(query) { + return request({ + url: '/system/role/authUser/allocatedList', + method: 'get', + params: query + }) +} + +// 查询角色未授权用户列表 +export function unallocatedUserList(query) { + return request({ + url: '/system/role/authUser/unallocatedList', + method: 'get', + params: query + }) +} + +// 取消用户授权角色 +export function authUserCancel(data) { + return request({ + url: '/system/role/authUser/cancel', + method: 'put', + data: data + }) +} + +// 批量取消用户授权角色 +export function authUserCancelAll(data) { + return request({ + url: '/system/role/authUser/cancelAll', + method: 'put', + params: data + }) +} + +// 授权用户选择 +export function authUserSelectAll(data) { + return request({ + url: '/system/role/authUser/selectAll', + method: 'put', + params: data + }) +} + +// 根据角色ID查询部门树结构 +export function deptTreeSelect(roleId) { + return request({ + url: '/system/role/deptTree/' + roleId, + method: 'get' + }) +} diff --git a/src/api/system/user.js b/src/api/system/user.js new file mode 100644 index 0000000..9b0211a --- /dev/null +++ b/src/api/system/user.js @@ -0,0 +1,136 @@ +import request from '@/utils/request' +import { parseStrEmpty } from "@/utils/ruoyi"; + +// 查询用户列表 +export function listUser(query) { + return request({ + url: '/system/user/list', + method: 'get', + params: query + }) +} + +// 查询用户详细 +export function getUser(userId) { + return request({ + url: '/system/user/' + parseStrEmpty(userId), + method: 'get' + }) +} + +// 新增用户 +export function addUser(data) { + return request({ + url: '/system/user', + method: 'post', + data: data + }) +} + +// 修改用户 +export function updateUser(data) { + return request({ + url: '/system/user', + method: 'put', + data: data + }) +} + +// 删除用户 +export function delUser(userId) { + return request({ + url: '/system/user/' + userId, + method: 'delete' + }) +} + +// 用户密码重置 +export function resetUserPwd(userId, password) { + const data = { + userId, + password + } + return request({ + url: '/system/user/resetPwd', + method: 'put', + data: data + }) +} + +// 用户状态修改 +export function changeUserStatus(userId, status) { + const data = { + userId, + status + } + return request({ + url: '/system/user/changeStatus', + method: 'put', + data: data + }) +} + +// 查询用户个人信息 +export function getUserProfile() { + return request({ + url: '/system/user/profile', + method: 'get' + }) +} + +// 修改用户个人信息 +export function updateUserProfile(data) { + return request({ + url: '/system/user/profile', + method: 'put', + data: data + }) +} + +// 用户密码重置 +export function updateUserPwd(oldPassword, newPassword) { + const data = { + oldPassword, + newPassword + } + return request({ + url: '/system/user/profile/updatePwd', + method: 'put', + params: data + }) +} + +// 用户头像上传 +export function uploadAvatar(data) { + return request({ + url: '/system/user/profile/avatar', + method: 'post', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + data: data + }) +} + +// 查询授权角色 +export function getAuthRole(userId) { + return request({ + url: '/system/user/authRole/' + userId, + method: 'get' + }) +} + +// 保存授权角色 +export function updateAuthRole(data) { + return request({ + url: '/system/user/authRole', + method: 'put', + params: data + }) +} + +// 查询部门下拉树结构 +export function deptTreeSelect() { + return request({ + url: '/system/user/deptTree', + method: 'get' + }) +} diff --git a/src/api/tool/gen.js b/src/api/tool/gen.js new file mode 100644 index 0000000..2075677 --- /dev/null +++ b/src/api/tool/gen.js @@ -0,0 +1,85 @@ +import request from '@/utils/request' + +// 查询生成表数据 +export function listTable(query) { + return request({ + url: '/tool/gen/list', + method: 'get', + params: query + }) +} +// 查询db数据库列表 +export function listDbTable(query) { + return request({ + url: '/tool/gen/db/list', + method: 'get', + params: query + }) +} + +// 查询表详细信息 +export function getGenTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'get' + }) +} + +// 修改代码生成信息 +export function updateGenTable(data) { + return request({ + url: '/tool/gen', + method: 'put', + data: data + }) +} + +// 导入表 +export function importTable(data) { + return request({ + url: '/tool/gen/importTable', + method: 'post', + params: data + }) +} + +// 创建表 +export function createTable(data) { + return request({ + url: '/tool/gen/createTable', + method: 'post', + params: data + }) +} + +// 预览生成代码 +export function previewTable(tableId) { + return request({ + url: '/tool/gen/preview/' + tableId, + method: 'get' + }) +} + +// 删除表数据 +export function delTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'delete' + }) +} + +// 生成代码(自定义路径) +export function genCode(tableName) { + return request({ + url: '/tool/gen/genCode/' + tableName, + method: 'get' + }) +} + +// 同步数据库 +export function synchDb(tableName) { + return request({ + url: '/tool/gen/synchDb/' + tableName, + method: 'get' + }) +} diff --git a/src/assets/401_images/401.gif b/src/assets/401_images/401.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd6e0d9433421b3f29d0ec0c40f755e354728000 GIT binary patch literal 164227 zcmeFZWmH>j*Dkt}AW4u?O0nV^C JJ??B{WLN%@& ckY+J4b9iZvx<3D_n2&|&Z&h4vq*>(t`hn@MF%=w~&6z}y zqP(U8LV`?U5=a3N2|;mT9wtG40Z~4FVLkx~UI8K0^+%YW=^qEn^=Qs!7AS2+rGJcd zeI?Ce>FVl;;^T97cSpJlAsw7wUAL8x;NutM6BOjVuEFc#Y42*{!E5ir`p+H|&0S2L ztsGsg9PF9?>e1w-!)sS*mg|}ReF=7s|LWG>1^Kt-AWa?Y_&iJ;`2>*se=X^s6*V;e z->cf${j0W%tG4-n&G&!o*yV|*qdA|pxr@VVXH)a*>a2ea<%m*nHaBr~aDL+8VEfOz zsAcKk>fmDO;K-z)@Yh`vL5eUTG)zpb?Efm}`dd2<4U~$#i>ryfskw@xG|P2QNGmHd zl!SnSh`fT5khrj-kbuB_QF#SHMF}|}5d{S$1u-QFrGK_nbTEBwXKwHM&$ed&)mHdF zw*3ndc8=F0E1El7xtW_OIXl=f{cY(etN%O~f&bXwKiZo8=eb jScm6 zwKdgMmG3Ib%Sua%iwX^&K2DM^%sxR|Jju#lhtKOd5p=PoxFf|G-tjg^I&iIIVx?hY*t zH5KJ;id*D2$!?I65EH>+P(lKHJO~&B0L+(o_z-{*-~q0Wzw8o#kIUhVHnYmIEUUEL z>2%~7cePvas66mKz+rP7m3cl>P=r9bpJ-F`m$<6F(|e{Ih=<+t0+IKfs3OzHH{*M1 zNSYT8#i>kGz8+lsvLgxoiE{v;T3$iHA@1Jj2sA+YIy5#eUJg!49+`?JH%-XO&OzFw zq!l`o2IiKPXNMP6`MFlq)dy8pH~V86+B