From 8f3d679a57056e2b351323f0e75dd6f057293f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E5=B8=85?= <133814250@qq.com> Date: Fri, 25 Feb 2022 17:11:17 +0800 Subject: [PATCH] tt --- LICENSE | 201 +++ hotgo-server/.gitattributes | 1 + hotgo-server/.gitignore | 20 + hotgo-server/LICENSE | 21 + hotgo-server/README.MD | 1 + hotgo-server/app/com/cache_com.go | 31 + hotgo-server/app/com/captcha_com.go | 62 + hotgo-server/app/com/context_com.go | 107 ++ hotgo-server/app/com/ip_com.go | 254 +++ hotgo-server/app/com/jwt_com.go | 161 ++ hotgo-server/app/com/redis_com.go | 83 + hotgo-server/app/com/response_com.go | 121 ++ hotgo-server/app/consts/app_consts.go | 14 + hotgo-server/app/consts/code_consts.go | 31 + hotgo-server/app/consts/context_consts.go | 12 + hotgo-server/app/consts/debris_consts.go | 8 + hotgo-server/app/consts/error_consts.go | 14 + hotgo-server/app/consts/openapi_consts.go | 15 + hotgo-server/app/consts/queue_consts.go | 14 + hotgo-server/app/consts/redis_consts.go | 13 + hotgo-server/app/consts/status_consts.go | 14 + hotgo-server/app/consts/version_consts.go | 12 + .../adminController/config_controller.go | 172 +++ .../adminController/dept_controller.go | 176 +++ .../adminController/dict_controller.go | 252 +++ .../adminController/log_controller.go | 95 ++ .../adminController/login_controller.go | 104 ++ .../adminController/member_controller.go | 371 +++++ .../adminController/menu_controller.go | 188 +++ .../adminController/notice_controller.go | 151 ++ .../adminController/post_controller.go | 170 +++ .../adminController/role_controller.go | 95 ++ .../apiController/base_controller.go | 95 ++ .../apiController/dict_controller.go | 29 + .../apiController/log_controller.go | 95 ++ .../apiController/login_controller.go | 98 ++ .../apiController/member_controller.go | 71 + hotgo-server/app/factory/queue/kafkamq.go | 246 +++ hotgo-server/app/factory/queue/list.go | 63 + hotgo-server/app/factory/queue/logger.go | 39 + hotgo-server/app/factory/queue/main.go | 248 +++ hotgo-server/app/factory/queue/queue_test.go | 133 ++ hotgo-server/app/factory/queue/redismq.go | 284 ++++ hotgo-server/app/factory/queue/rocketmq.go | 165 ++ .../factory/queue/rocketmq_rewrite_logger.go | 83 + .../app/form/adminForm/config_form.go | 73 + hotgo-server/app/form/adminForm/dept_form.go | 65 + hotgo-server/app/form/adminForm/dict_form.go | 136 ++ hotgo-server/app/form/adminForm/log_form.go | 47 + hotgo-server/app/form/adminForm/login_form.go | 41 + .../app/form/adminForm/member_form.go | 212 +++ hotgo-server/app/form/adminForm/menu_form.go | 92 ++ .../app/form/adminForm/notice_form.go | 64 + hotgo-server/app/form/adminForm/post_form.go | 75 + hotgo-server/app/form/adminForm/role_form.go | 89 ++ hotgo-server/app/form/apiForm/base_form.go | 34 + hotgo-server/app/form/apiForm/dict_form.go | 13 + hotgo-server/app/form/apiForm/log_form.go | 47 + hotgo-server/app/form/apiForm/login_form.go | 37 + hotgo-server/app/form/apiForm/member_form.go | 20 + hotgo-server/app/form/common.go | 28 + .../app/form/input/admin_dept_input.go | 75 + .../app/form/input/admin_member_input.go | 171 +++ .../app/form/input/admin_notice_input.go | 64 + .../app/form/input/admin_post_input.go | 68 + .../app/form/input/admin_role_input.go | 44 + .../app/form/input/sys_config_input.go | 72 + hotgo-server/app/form/input/sys_log_input.go | 26 + hotgo-server/app/hook/hook.go | 45 + .../interfaces/queue_producer_interface.go | 20 + hotgo-server/app/middleware/admin_auth.go | 127 ++ hotgo-server/app/middleware/api_auth.go | 127 ++ .../app/middleware/handler_response.go | 74 + hotgo-server/app/middleware/middleware.go | 64 + hotgo-server/app/model/context.go | 40 + hotgo-server/app/model/entity/admin_dept.go | 26 + hotgo-server/app/model/entity/admin_member.go | 42 + .../app/model/entity/admin_member_post.go | 11 + .../app/model/entity/admin_member_role.go | 11 + hotgo-server/app/model/entity/admin_menu.go | 33 + .../app/model/entity/admin_menu_old.go | 32 + hotgo-server/app/model/entity/admin_notice.go | 21 + hotgo-server/app/model/entity/admin_post.go | 21 + hotgo-server/app/model/entity/admin_role.go | 24 + .../app/model/entity/admin_role_dept.go | 11 + .../app/model/entity/admin_role_menu.go | 11 + hotgo-server/app/model/entity/sys_config.go | 22 + .../app/model/entity/sys_dict_data.go | 24 + .../app/model/entity/sys_dict_type.go | 21 + hotgo-server/app/model/entity/sys_log.go | 36 + .../app/model/entity/sys_provinces.go | 21 + hotgo-server/app/model/response.go | 17 + hotgo-server/app/model/tree.go | 23 + .../app/service/adminService/dept_service.go | 358 +++++ .../adminService/member_post_service.go | 67 + .../service/adminService/member_service.go | 657 ++++++++ .../app/service/adminService/menu_service.go | 533 +++++++ .../service/adminService/notice_service.go | 263 ++++ .../app/service/adminService/post_service.go | 274 ++++ .../app/service/adminService/role_service.go | 130 ++ .../app/service/apiService/member_service.go | 23 + .../app/service/internal/dao/admin_dept.go | 81 + .../app/service/internal/dao/admin_member.go | 118 ++ .../service/internal/dao/admin_member_post.go | 24 + .../service/internal/dao/admin_member_role.go | 24 + .../app/service/internal/dao/admin_menu.go | 180 +++ .../service/internal/dao/admin_menu_old.go | 24 + .../app/service/internal/dao/admin_notice.go | 58 + .../app/service/internal/dao/admin_post.go | 88 ++ .../app/service/internal/dao/admin_role.go | 24 + .../service/internal/dao/admin_role_dept.go | 29 + .../service/internal/dao/admin_role_menu.go | 24 + .../internal/dao/internal/admin_dept.go | 96 ++ .../internal/dao/internal/admin_member.go | 128 ++ .../dao/internal/admin_member_post.go | 74 + .../dao/internal/admin_member_role.go | 74 + .../internal/dao/internal/admin_menu.go | 110 ++ .../internal/dao/internal/admin_menu_old.go | 108 ++ .../internal/dao/internal/admin_notice.go | 86 ++ .../internal/dao/internal/admin_post.go | 86 ++ .../internal/dao/internal/admin_role.go | 92 ++ .../internal/dao/internal/admin_role_dept.go | 74 + .../internal/dao/internal/admin_role_menu.go | 74 + .../internal/dao/internal/sys_config.go | 88 ++ .../internal/dao/internal/sys_dict_data.go | 92 ++ .../internal/dao/internal/sys_dict_type.go | 86 ++ .../service/internal/dao/internal/sys_log.go | 116 ++ .../internal/dao/internal/sys_provinces.go | 94 ++ .../app/service/internal/dao/sys_config.go | 58 + .../app/service/internal/dao/sys_dict_data.go | 62 + .../app/service/internal/dao/sys_dict_type.go | 62 + .../app/service/internal/dao/sys_log.go | 24 + .../app/service/internal/dao/sys_provinces.go | 73 + .../app/service/internal/dto/admin_dept.go | 28 + .../app/service/internal/dto/admin_member.go | 44 + .../service/internal/dto/admin_member_post.go | 16 + .../service/internal/dto/admin_member_role.go | 16 + .../app/service/internal/dto/admin_menu.go | 35 + .../service/internal/dto/admin_menu_old.go | 34 + .../app/service/internal/dto/admin_notice.go | 23 + .../app/service/internal/dto/admin_post.go | 23 + .../app/service/internal/dto/admin_role.go | 26 + .../service/internal/dto/admin_role_dept.go | 16 + .../service/internal/dto/admin_role_menu.go | 16 + .../app/service/internal/dto/sys_config.go | 24 + .../app/service/internal/dto/sys_dict_data.go | 26 + .../app/service/internal/dto/sys_dict_type.go | 23 + .../app/service/internal/dto/sys_log.go | 38 + .../app/service/internal/dto/sys_provinces.go | 26 + .../app/service/sysService/config_service.go | 233 +++ .../app/service/sysService/dict_service.go | 505 ++++++ .../app/service/sysService/log_service.go | 400 +++++ .../service/sysService/provinces_service.go | 29 + hotgo-server/app/utils/auth_util.go | 65 + hotgo-server/app/utils/charset_util.go | 121 ++ hotgo-server/app/utils/excel_util.go | 87 ++ hotgo-server/app/utils/filter_util.go | 17 + hotgo-server/app/utils/signal_util.go | 76 + hotgo-server/app/utils/validate_util.go | 30 + hotgo-server/boot/queue.go | 42 + hotgo-server/boot/run.go | 96 ++ hotgo-server/config/config.example.yaml | 132 ++ hotgo-server/config/config.yaml | 132 ++ hotgo-server/go.mod | 26 + hotgo-server/go.sum | 312 ++++ hotgo-server/main.go | 18 + hotgo-server/pull.bat | 15 + hotgo-server/push.bat | 11 + hotgo-server/resource/public/html/.gitkeep | 0 hotgo-server/resource/public/plugin/.gitkeep | 0 .../public/plugin/layer-3.1.1/layer.js | 2 + .../public/plugin/layer-3.1.1/mobile/layer.js | 2 + .../plugin/layer-3.1.1/mobile/need/layer.css | 1 + .../layer-3.1.1/theme/default/icon-ext.png | Bin 0 -> 5911 bytes .../plugin/layer-3.1.1/theme/default/icon.png | Bin 0 -> 11493 bytes .../layer-3.1.1/theme/default/layer.css | 1 + .../layer-3.1.1/theme/default/loading-0.gif | Bin 0 -> 5793 bytes .../layer-3.1.1/theme/default/loading-1.gif | Bin 0 -> 701 bytes .../layer-3.1.1/theme/default/loading-2.gif | Bin 0 -> 1787 bytes .../resource/public/resource/css/.gitkeep | 0 .../resource/public/resource/image/.gitkeep | 0 .../resource/public/resource/image/cover.png | Bin 0 -> 24590 bytes .../public/resource/image/favicon.ico | Bin 0 -> 4286 bytes .../resource/public/resource/image/gf.ico | Bin 0 -> 4286 bytes .../resource/public/resource/js/.gitkeep | 0 hotgo-server/resource/template/.gitkeep | 0 hotgo-server/router/admin.go | 43 + hotgo-server/router/api.go | 38 + hotgo-server/runtime/log/exception/.gitignore | 1 + hotgo-server/runtime/log/logger/.gitignore | 1 + hotgo-server/runtime/log/queue/.gitignore | 1 + hotgo-server/runtime/log/server/.gitignore | 1 + .../runtime/log/server/access/.gitignore | 1 + .../runtime/log/server/error/.gitignore | 1 + hotgo-server/storage/ip/qqwry-utf8.dat | Bin 0 -> 12935023 bytes hotgo-uniapp/.gitignore | 7 + hotgo-uniapp/.vscode/settings.json | 5 + hotgo-uniapp/App.vue | 26 + hotgo-uniapp/LICENSE | 223 +++ hotgo-uniapp/README.md | 151 ++ hotgo-uniapp/common/base64.js | 74 + hotgo-uniapp/common/config.js | 35 + hotgo-uniapp/common/http.api.js | 72 + hotgo-uniapp/common/http.interceptor.js | 139 ++ hotgo-uniapp/common/locales/en.js | 33 + hotgo-uniapp/common/locales/zh_CN.js | 33 + hotgo-uniapp/common/spark-md5.js | 751 +++++++++ hotgo-uniapp/common/vue-i18n.min.js | 6 + .../components/js-checkbox/js-checkbox.vue | 102 ++ hotgo-uniapp/components/js-lang/js-lang.vue | 69 + hotgo-uniapp/components/js-radio/js-radio.vue | 93 ++ .../components/js-select/js-select.vue | 215 +++ .../js-uploadfile/js-uploadfile.vue | 278 ++++ hotgo-uniapp/h5.html | 50 + hotgo-uniapp/main.js | 60 + hotgo-uniapp/manifest.json | 158 ++ hotgo-uniapp/package-lock.json | 13 + hotgo-uniapp/package.json | 26 + hotgo-uniapp/pages.json | 160 ++ hotgo-uniapp/pages/common/jeesite.scss | 121 ++ hotgo-uniapp/pages/common/webview.vue | 33 + hotgo-uniapp/pages/sys/home/index.scss | 22 + hotgo-uniapp/pages/sys/home/index.vue | 225 +++ hotgo-uniapp/pages/sys/login/forget.vue | 144 ++ hotgo-uniapp/pages/sys/login/index.scss | 81 + hotgo-uniapp/pages/sys/login/index.vue | 192 +++ hotgo-uniapp/pages/sys/login/reg.vue | 187 +++ hotgo-uniapp/pages/sys/msg/form.vue | 77 + hotgo-uniapp/pages/sys/msg/index.vue | 163 ++ hotgo-uniapp/pages/sys/user/about.vue | 78 + hotgo-uniapp/pages/sys/user/comment.vue | 98 ++ hotgo-uniapp/pages/sys/user/help.vue | 106 ++ hotgo-uniapp/pages/sys/user/index.scss | 98 ++ hotgo-uniapp/pages/sys/user/index.vue | 128 ++ hotgo-uniapp/pages/sys/user/info.vue | 224 +++ hotgo-uniapp/pages/sys/user/pwd.vue | 106 ++ hotgo-uniapp/pages/sys/user/setting.vue | 87 ++ hotgo-uniapp/pages/testData/form.vue | 129 ++ hotgo-uniapp/pages/testData/index.vue | 123 ++ hotgo-uniapp/static/common/img/iPhoneX.png | Bin 0 -> 41116 bytes .../static/common/js/touch-emulator.js | 363 +++++ hotgo-uniapp/static/index.html | 52 + hotgo-uniapp/static/jeesite/banner/1.svg | 843 ++++++++++ hotgo-uniapp/static/jeesite/banner/2.svg | 966 ++++++++++++ hotgo-uniapp/static/jeesite/banner/3.svg | 479 ++++++ hotgo-uniapp/static/jeesite/favicon.png | Bin 0 -> 4794 bytes .../static/jeesite/login/eye_close.png | Bin 0 -> 2914 bytes .../static/jeesite/login/eye_open.png | Bin 0 -> 4708 bytes hotgo-uniapp/static/jeesite/logo200.png | Bin 0 -> 6936 bytes hotgo-uniapp/static/jeesite/tabbar/home_1.png | Bin 0 -> 760 bytes hotgo-uniapp/static/jeesite/tabbar/home_2.png | Bin 0 -> 1020 bytes hotgo-uniapp/static/jeesite/tabbar/msg_1.png | Bin 0 -> 835 bytes hotgo-uniapp/static/jeesite/tabbar/msg_2.png | Bin 0 -> 1060 bytes hotgo-uniapp/static/jeesite/tabbar/my_1.png | Bin 0 -> 1297 bytes hotgo-uniapp/static/jeesite/tabbar/my_2.png | Bin 0 -> 1161 bytes hotgo-uniapp/static/uview/common/favicon.ico | Bin 0 -> 4286 bytes hotgo-uniapp/static/uview/common/logo.png | Bin 0 -> 15558 bytes .../static/uview/example/component.png | Bin 0 -> 3074 bytes .../static/uview/example/component_select.png | Bin 0 -> 1521 bytes hotgo-uniapp/static/uview/example/js.png | Bin 0 -> 4236 bytes hotgo-uniapp/static/uview/example/js_bak.png | Bin 0 -> 3212 bytes .../static/uview/example/js_select.png | Bin 0 -> 4278 bytes .../static/uview/example/js_select_bak.png | Bin 0 -> 2248 bytes .../static/uview/example/min_button.png | Bin 0 -> 2962 bytes .../uview/example/min_button_select.png | Bin 0 -> 2936 bytes .../static/uview/example/template.png | Bin 0 -> 4097 bytes .../static/uview/example/template_select.png | Bin 0 -> 4641 bytes hotgo-uniapp/store/$u.mixin.js | 27 + hotgo-uniapp/store/index.js | 93 ++ hotgo-uniapp/uni.scss | 41 + .../unpackage/res/icons/1024x1024.png | Bin 0 -> 16475 bytes hotgo-uniapp/unpackage/res/icons/120x120.png | Bin 0 -> 3740 bytes hotgo-uniapp/unpackage/res/icons/144x144.png | Bin 0 -> 4639 bytes hotgo-uniapp/unpackage/res/icons/152x152.png | Bin 0 -> 4959 bytes hotgo-uniapp/unpackage/res/icons/167x167.png | Bin 0 -> 5320 bytes hotgo-uniapp/unpackage/res/icons/180x180.png | Bin 0 -> 5893 bytes hotgo-uniapp/unpackage/res/icons/192x192.png | Bin 0 -> 6257 bytes hotgo-uniapp/unpackage/res/icons/20x20.png | Bin 0 -> 433 bytes hotgo-uniapp/unpackage/res/icons/29x29.png | Bin 0 -> 690 bytes hotgo-uniapp/unpackage/res/icons/40x40.png | Bin 0 -> 1019 bytes hotgo-uniapp/unpackage/res/icons/58x58.png | Bin 0 -> 1672 bytes hotgo-uniapp/unpackage/res/icons/60x60.png | Bin 0 -> 1741 bytes hotgo-uniapp/unpackage/res/icons/72x72.png | Bin 0 -> 2145 bytes hotgo-uniapp/unpackage/res/icons/76x76.png | Bin 0 -> 2246 bytes hotgo-uniapp/unpackage/res/icons/80x80.png | Bin 0 -> 2364 bytes hotgo-uniapp/unpackage/res/icons/87x87.png | Bin 0 -> 2685 bytes hotgo-uniapp/unpackage/res/icons/96x96.png | Bin 0 -> 2986 bytes hotgo-uniapp/uview-ui/LICENSE | 21 + hotgo-uniapp/uview-ui/README.md | 106 ++ .../u-action-sheet/u-action-sheet.vue | 190 +++ .../components/u-alert-tips/u-alert-tips.vue | 256 ++++ .../u-avatar-cropper/u-avatar-cropper.vue | 290 ++++ .../components/u-avatar-cropper/weCropper.js | 1265 +++++++++++++++ .../uview-ui/components/u-avatar/u-avatar.vue | 244 +++ .../components/u-back-top/u-back-top.vue | 153 ++ .../uview-ui/components/u-badge/u-badge.vue | 216 +++ .../uview-ui/components/u-button/u-button.vue | 596 ++++++++ .../components/u-calendar/u-calendar.vue | 639 ++++++++ .../u-car-keyboard/u-car-keyboard.vue | 257 ++++ .../uview-ui/components/u-card/u-card.vue | 299 ++++ .../components/u-cell-group/u-cell-group.vue | 70 + .../components/u-cell-item/u-cell-item.vue | 316 ++++ .../u-checkbox-group/u-checkbox-group.vue | 123 ++ .../components/u-checkbox/u-checkbox.vue | 284 ++++ .../u-circle-progress/u-circle-progress.vue | 220 +++ .../u-line-progress/u-line-progress.vue | 147 ++ .../uview-ui/components/u-col/u-col.vue | 156 ++ .../u-collapse-item/u-collapse-item.vue | 204 +++ .../components/u-collapse/u-collapse.vue | 99 ++ .../u-column-notice/u-column-notice.vue | 237 +++ .../components/u-count-down/u-count-down.vue | 318 ++++ .../components/u-count-to/u-count-to.vue | 241 +++ .../components/u-divider/u-divider.vue | 153 ++ .../u-dropdown-item/u-dropdown-item.vue | 132 ++ .../components/u-dropdown/u-dropdown.vue | 298 ++++ .../uview-ui/components/u-empty/u-empty.vue | 193 +++ .../uview-ui/components/u-field/u-field.vue | 384 +++++ .../components/u-form-item/u-form-item.vue | 431 ++++++ .../uview-ui/components/u-form/u-form.vue | 134 ++ .../u-full-screen/u-full-screen.vue | 52 + .../uview-ui/components/u-gap/u-gap.vue | 54 + .../components/u-grid-item/u-grid-item.vue | 126 ++ .../uview-ui/components/u-grid/u-grid.vue | 108 ++ .../uview-ui/components/u-icon/u-icon.vue | 336 ++++ .../uview-ui/components/u-image/u-image.vue | 267 ++++ .../u-index-anchor/u-index-anchor.vue | 89 ++ .../components/u-index-list/u-index-list.vue | 315 ++++ .../uview-ui/components/u-input/u-input.vue | 387 +++++ .../components/u-keyboard/u-keyboard.vue | 217 +++ .../components/u-lazy-load/u-lazy-load.vue | 244 +++ .../u-line-progress/u-line-progress.vue | 147 ++ .../uview-ui/components/u-line/u-line.vue | 84 + .../uview-ui/components/u-link/u-link.vue | 89 ++ .../u-loading-page/u-loading-page.vue | 25 + .../components/u-loading/u-loading.vue | 103 ++ .../components/u-loadmore/u-loadmore.vue | 203 +++ .../uview-ui/components/u-mask/u-mask.vue | 123 ++ .../u-message-input/u-message-input.vue | 311 ++++ .../uview-ui/components/u-modal/u-modal.vue | 283 ++++ .../uview-ui/components/u-navbar/u-navbar.vue | 315 ++++ .../components/u-no-network/u-no-network.vue | 233 +++ .../components/u-notice-bar/u-notice-bar.vue | 272 ++++ .../components/u-number-box/u-number-box.vue | 363 +++++ .../u-number-keyboard/u-number-keyboard.vue | 158 ++ .../components/u-parse/libs/CssHandler.js | 100 ++ .../components/u-parse/libs/MpHtmlParser.js | 580 +++++++ .../components/u-parse/libs/config.js | 80 + .../components/u-parse/libs/handler.wxs | 22 + .../components/u-parse/libs/trees.vue | 505 ++++++ .../uview-ui/components/u-parse/u-parse.vue | 645 ++++++++ .../uview-ui/components/u-picker/u-picker.vue | 676 ++++++++ .../uview-ui/components/u-popup/u-popup.vue | 456 ++++++ .../u-radio-group/u-radio-group.vue | 128 ++ .../uview-ui/components/u-radio/u-radio.vue | 271 ++++ .../uview-ui/components/u-rate/u-rate.vue | 275 ++++ .../components/u-read-more/u-read-more.vue | 179 +++ .../components/u-row-notice/u-row-notice.vue | 269 ++++ .../uview-ui/components/u-row/u-row.vue | 84 + .../uview-ui/components/u-search/u-search.vue | 342 +++++ .../components/u-section/u-section.vue | 154 ++ .../uview-ui/components/u-select/u-select.vue | 424 ++++++ .../components/u-skeleton/u-skeleton.vue | 199 +++ .../uview-ui/components/u-slider/u-slider.vue | 257 ++++ .../uview-ui/components/u-steps/u-steps.vue | 200 +++ .../uview-ui/components/u-sticky/u-sticky.vue | 157 ++ .../components/u-subsection/u-subsection.vue | 355 +++++ .../u-swipe-action/u-swipe-action.vue | 255 ++++ .../uview-ui/components/u-swiper/u-swiper.vue | 340 +++++ .../uview-ui/components/u-switch/u-switch.vue | 163 ++ .../uview-ui/components/u-tabbar/u-tabbar.vue | 330 ++++ .../uview-ui/components/u-table/u-table.vue | 84 + .../u-tabs-swiper/u-tabs-swiper.vue | 488 ++++++ .../uview-ui/components/u-tabs/u-tabs.vue | 369 +++++ .../uview-ui/components/u-tag/u-tag.vue | 294 ++++ .../uview-ui/components/u-td/u-td.vue | 66 + .../uview-ui/components/u-th/u-th.vue | 62 + .../u-time-line-item/u-time-line-item.vue | 83 + .../components/u-time-line/u-time-line.vue | 43 + .../uview-ui/components/u-toast/u-toast.vue | 220 +++ .../components/u-top-tips/u-top-tips.vue | 121 ++ .../uview-ui/components/u-tr/u-tr.vue | 25 + .../uview-ui/components/u-upload/u-upload.vue | 660 ++++++++ .../u-verification-code.vue | 164 ++ .../components/u-waterfall/u-waterfall.vue | 176 +++ hotgo-uniapp/uview-ui/iconfont.css | 910 +++++++++++ hotgo-uniapp/uview-ui/index.js | 140 ++ hotgo-uniapp/uview-ui/index.scss | 23 + hotgo-uniapp/uview-ui/libs/config/config.js | 15 + hotgo-uniapp/uview-ui/libs/config/zIndex.js | 20 + hotgo-uniapp/uview-ui/libs/css/color.scss | 155 ++ hotgo-uniapp/uview-ui/libs/css/common.scss | 176 +++ .../uview-ui/libs/css/style.components.scss | 7 + hotgo-uniapp/uview-ui/libs/css/style.h5.scss | 8 + hotgo-uniapp/uview-ui/libs/css/style.mp.scss | 72 + .../uview-ui/libs/css/style.nvue.scss | 3 + hotgo-uniapp/uview-ui/libs/css/style.vue.scss | 175 +++ .../uview-ui/libs/function/$parent.js | 18 + .../uview-ui/libs/function/addUnit.js | 8 + hotgo-uniapp/uview-ui/libs/function/bem.js | 5 + hotgo-uniapp/uview-ui/libs/function/color.js | 37 + .../uview-ui/libs/function/colorGradient.js | 134 ++ hotgo-uniapp/uview-ui/libs/function/date.js | 173 +++ .../uview-ui/libs/function/debounce.js | 29 + .../uview-ui/libs/function/deepClone.js | 23 + .../uview-ui/libs/function/deepMerge.js | 30 + .../uview-ui/libs/function/getParent.js | 47 + hotgo-uniapp/uview-ui/libs/function/guid.js | 41 + hotgo-uniapp/uview-ui/libs/function/md5.js | 385 +++++ .../uview-ui/libs/function/queryParams.js | 58 + hotgo-uniapp/uview-ui/libs/function/random.js | 10 + .../uview-ui/libs/function/randomArray.js | 7 + hotgo-uniapp/uview-ui/libs/function/route.js | 122 ++ hotgo-uniapp/uview-ui/libs/function/sys.js | 9 + hotgo-uniapp/uview-ui/libs/function/test.js | 232 +++ .../uview-ui/libs/function/throttle.js | 32 + .../uview-ui/libs/function/timeFormat.js | 51 + .../uview-ui/libs/function/timeFrom.js | 47 + hotgo-uniapp/uview-ui/libs/function/toast.js | 9 + hotgo-uniapp/uview-ui/libs/function/trim.js | 15 + .../uview-ui/libs/function/type2icon.js | 35 + hotgo-uniapp/uview-ui/libs/mixin/mixin.js | 64 + hotgo-uniapp/uview-ui/libs/mixin/mpShare.js | 18 + hotgo-uniapp/uview-ui/libs/request/index.js | 182 +++ hotgo-uniapp/uview-ui/libs/store/index.js | 19 + hotgo-uniapp/uview-ui/libs/util/area.js | 1 + .../uview-ui/libs/util/async-validator.js | 1356 +++++++++++++++++ hotgo-uniapp/uview-ui/libs/util/city.js | 1 + hotgo-uniapp/uview-ui/libs/util/emitter.js | 51 + hotgo-uniapp/uview-ui/libs/util/province.js | 1 + hotgo-uniapp/uview-ui/package.json | 39 + hotgo-uniapp/uview-ui/theme.scss | 38 + hotgo-uniapp/vue.config.js | 20 + hotgo-web/.browserslistrc | 3 + hotgo-web/.editorconfig | 39 + hotgo-web/.env | 3 + hotgo-web/.env.development | 3 + hotgo-web/.env.preview | 3 + hotgo-web/.eslintrc.js | 78 + hotgo-web/.eslintrc.json | 5 + hotgo-web/.gitattributes | 1 + hotgo-web/.gitignore | 23 + hotgo-web/.prettierrc | 6 + hotgo-web/.travis.yml | 7 + hotgo-web/LICENSE | 21 + hotgo-web/README.md | 4 + hotgo-web/babel.config.js | 28 + hotgo-web/bin/build.bat | 12 + hotgo-web/bin/package.bat | 12 + hotgo-web/bin/run-web.bat | 12 + hotgo-web/config/plugin.config.js | 49 + hotgo-web/config/themePluginConfig.js | 115 ++ hotgo-web/jest.config.js | 23 + hotgo-web/jsconfig.json | 11 + hotgo-web/package.json | 71 + hotgo-web/postcss.config.js | 5 + hotgo-web/public/index.html | 33 + hotgo-web/public/logo.png | Bin 0 -> 7628 bytes hotgo-web/pull.bat | 15 + hotgo-web/push.bat | 11 + hotgo-web/src/App.vue | 28 + hotgo-web/src/api/login.js | 85 ++ hotgo-web/src/api/manage.js | 70 + hotgo-web/src/api/menu.js | 9 + hotgo-web/src/api/monitor/cache.js | 49 + hotgo-web/src/api/monitor/job.js | 79 + hotgo-web/src/api/monitor/jobLog.js | 35 + hotgo-web/src/api/monitor/loginLog.js | 35 + hotgo-web/src/api/monitor/online.js | 18 + hotgo-web/src/api/monitor/operlog.js | 35 + hotgo-web/src/api/monitor/server.js | 9 + .../api/monitor/sysDataPermissionsDefRule.js | 69 + .../api/monitor/sysDataPermissionsMethod.js | 78 + .../src/api/monitor/sysDataPermissionsRule.js | 61 + hotgo-web/src/api/system/config.js | 70 + hotgo-web/src/api/system/dept.js | 173 +++ hotgo-web/src/api/system/dict/data.js | 83 + hotgo-web/src/api/system/dict/type.js | 71 + hotgo-web/src/api/system/menu.js | 121 ++ hotgo-web/src/api/system/notice.js | 62 + hotgo-web/src/api/system/post.js | 72 + hotgo-web/src/api/system/role.js | 127 ++ hotgo-web/src/api/system/sysNoticeUserRead.js | 53 + hotgo-web/src/api/system/sysPortalConfig.js | 93 ++ hotgo-web/src/api/system/sysPortlet.js | 79 + hotgo-web/src/api/system/sysTableConfig.js | 27 + hotgo-web/src/api/system/sysThemeConfig.js | 60 + hotgo-web/src/api/system/upload.js | 17 + hotgo-web/src/api/system/user.js | 181 +++ hotgo-web/src/api/tool/gen.js | 101 ++ hotgo-web/src/api/tool/genConfigTemplate.js | 98 ++ hotgo-web/src/assets/background.svg | 69 + hotgo-web/src/assets/icons/Alipay.svg | 1 + hotgo-web/src/assets/icons/DragColumn.svg | 1 + hotgo-web/src/assets/icons/QRcode.svg | 1 + hotgo-web/src/assets/icons/Sina.svg | 1 + hotgo-web/src/assets/icons/WeChat.svg | 1 + hotgo-web/src/assets/icons/bug.svg | 1 + hotgo-web/src/assets/icons/build.svg | 1 + hotgo-web/src/assets/icons/button.svg | 1 + hotgo-web/src/assets/icons/bxAnalyse.svg | 1 + hotgo-web/src/assets/icons/cascader.svg | 1 + hotgo-web/src/assets/icons/chart.svg | 1 + hotgo-web/src/assets/icons/checkbox.svg | 1 + hotgo-web/src/assets/icons/clipboard.svg | 1 + hotgo-web/src/assets/icons/codeNew.svg | 1 + hotgo-web/src/assets/icons/color.svg | 1 + hotgo-web/src/assets/icons/company.svg | 1 + hotgo-web/src/assets/icons/companyFill.svg | 1 + hotgo-web/src/assets/icons/component.svg | 1 + hotgo-web/src/assets/icons/compress.svg | 1 + hotgo-web/src/assets/icons/connections.svg | 1 + hotgo-web/src/assets/icons/dashboardNew.svg | 1 + hotgo-web/src/assets/icons/date.svg | 1 + hotgo-web/src/assets/icons/dateRange.svg | 1 + hotgo-web/src/assets/icons/dict.svg | 1 + hotgo-web/src/assets/icons/dingtalk.svg | 1 + hotgo-web/src/assets/icons/documentation.svg | 1 + hotgo-web/src/assets/icons/download.svg | 1 + hotgo-web/src/assets/icons/dragImg.svg | 1 + hotgo-web/src/assets/icons/dragtable.svg | 1 + hotgo-web/src/assets/icons/druid.svg | 1 + hotgo-web/src/assets/icons/edit.svg | 1 + hotgo-web/src/assets/icons/expend.svg | 1 + hotgo-web/src/assets/icons/eyeOpen.svg | 1 + hotgo-web/src/assets/icons/github.svg | 1 + hotgo-web/src/assets/icons/guide.svg | 1 + hotgo-web/src/assets/icons/input.svg | 1 + hotgo-web/src/assets/icons/job.svg | 1 + hotgo-web/src/assets/icons/log.svg | 1 + hotgo-web/src/assets/icons/loginLog.svg | 1 + hotgo-web/src/assets/icons/message.svg | 1 + hotgo-web/src/assets/icons/monitor.svg | 2 + hotgo-web/src/assets/icons/number.svg | 1 + hotgo-web/src/assets/icons/online.svg | 1 + hotgo-web/src/assets/icons/password.svg | 1 + hotgo-web/src/assets/icons/pdf.svg | 1 + hotgo-web/src/assets/icons/peoples.svg | 1 + hotgo-web/src/assets/icons/phone.svg | 1 + hotgo-web/src/assets/icons/post.svg | 1 + hotgo-web/src/assets/icons/question.svg | 1 + hotgo-web/src/assets/icons/radio.svg | 1 + hotgo-web/src/assets/icons/rate.svg | 1 + hotgo-web/src/assets/icons/redis.svg | 1 + hotgo-web/src/assets/icons/row.svg | 1 + hotgo-web/src/assets/icons/select.svg | 1 + hotgo-web/src/assets/icons/server.svg | 1 + hotgo-web/src/assets/icons/swagger.svg | 1 + hotgo-web/src/assets/icons/switch.svg | 1 + hotgo-web/src/assets/icons/system.svg | 2 + hotgo-web/src/assets/icons/textarea.svg | 1 + hotgo-web/src/assets/icons/time.svg | 1 + hotgo-web/src/assets/icons/timeRange.svg | 1 + hotgo-web/src/assets/icons/tool.svg | 1 + hotgo-web/src/assets/icons/tree.svg | 1 + hotgo-web/src/assets/icons/treeTable.svg | 1 + hotgo-web/src/assets/icons/upload.svg | 1 + hotgo-web/src/assets/icons/users.svg | 1 + hotgo-web/src/assets/icons/validCode.svg | 1 + hotgo-web/src/assets/images/dark.svg | 39 + hotgo-web/src/assets/images/light.svg | 39 + .../src/assets/images/login-background.jpg | Bin 0 -> 521275 bytes hotgo-web/src/assets/images/profile.jpg | Bin 0 -> 81131 bytes hotgo-web/src/assets/images/upload/excel.svg | 52 + hotgo-web/src/assets/images/upload/gif.svg | 23 + hotgo-web/src/assets/images/upload/jpg.svg | 25 + hotgo-web/src/assets/images/upload/other.svg | 44 + hotgo-web/src/assets/images/upload/pdf.svg | 23 + hotgo-web/src/assets/images/upload/png.svg | 26 + hotgo-web/src/assets/images/upload/ppt.svg | 52 + hotgo-web/src/assets/images/upload/text.svg | 60 + hotgo-web/src/assets/images/upload/word.svg | 55 + hotgo-web/src/assets/images/upload/zip.svg | 44 + hotgo-web/src/assets/login-bg.png | Bin 0 -> 64891 bytes hotgo-web/src/assets/logo.png | Bin 0 -> 15033 bytes hotgo-web/src/assets/logo.svg | 319 ++++ hotgo-web/src/assets/projects/antdv.png | Bin 0 -> 24773 bytes hotgo-web/src/assets/projects/ruoyi.png | Bin 0 -> 2658 bytes hotgo-web/src/assets/styles/antv-theme.less | 705 +++++++++ hotgo-web/src/assets/styles/default.less | 700 +++++++++ hotgo-web/src/assets/wrapper.jpg | Bin 0 -> 37004 bytes .../ArticleListContent/ArticleListContent.vue | 89 ++ .../components/ArticleListContent/index.js | 3 + hotgo-web/src/components/AvatarList/Item.jsx | 24 + hotgo-web/src/components/AvatarList/List.jsx | 72 + hotgo-web/src/components/AvatarList/index.js | 9 + .../src/components/AvatarList/index.less | 60 + hotgo-web/src/components/AvatarList/index.md | 64 + hotgo-web/src/components/Dialog.js | 113 ++ .../src/components/Ellipsis/Ellipsis.vue | 64 + hotgo-web/src/components/Ellipsis/index.js | 3 + hotgo-web/src/components/Ellipsis/index.md | 38 + .../FooterToolbar/FooterToolBar.vue | 47 + .../src/components/FooterToolbar/index.js | 4 + .../src/components/FooterToolbar/index.less | 23 + .../src/components/FooterToolbar/index.md | 48 + .../src/components/GlobalFooter/index.vue | 21 + .../GlobalHeader/AvatarDropdown.vue | 83 + .../GlobalHeader/PlatformVersion.vue | 115 ++ .../components/GlobalHeader/RightContent.vue | 251 +++ hotgo-web/src/components/GridContent/index.js | 44 + .../src/components/GridContent/index.less | 14 + .../components/IconSelector/IconDetail.vue | 187 +++ .../components/IconSelector/IconSelector.vue | 109 ++ .../src/components/IconSelector/README.md | 48 + .../src/components/IconSelector/icons.js | 36 + .../src/components/IconSelector/index.js | 2 + .../src/components/MultiTab/MultiTab.vue | 175 +++ hotgo-web/src/components/MultiTab/events.js | 2 + hotgo-web/src/components/MultiTab/index.js | 40 + hotgo-web/src/components/MultiTab/index.less | 31 + .../src/components/NProgress/nprogress.less | 76 + .../src/components/NoticeIcon/NoticeIcon.vue | 90 ++ hotgo-web/src/components/NoticeIcon/index.js | 2 + .../src/components/NumberInfo/NumberInfo.vue | 54 + hotgo-web/src/components/NumberInfo/index.js | 3 + .../src/components/NumberInfo/index.less | 55 + hotgo-web/src/components/NumberInfo/index.md | 43 + hotgo-web/src/components/Other/CarbonAds.vue | 114 ++ .../src/components/PageLoading/index.jsx | 106 ++ .../src/components/ProLayout/BasicLayout.jsx | 187 +++ .../src/components/ProLayout/BasicLayout.less | 101 ++ .../src/components/ProLayout/BlockLayout.jsx | 9 + hotgo-web/src/components/ProLayout/Header.jsx | 109 ++ .../src/components/ProLayout/Header.less | 91 ++ .../src/components/ProLayout/PageView.jsx | 14 + .../src/components/ProLayout/WrapContent.jsx | 44 + .../components/ConfigProvider/index.js | 27 + .../DocumentTitle/SideEffect/index.js | 17 + .../components/DocumentTitle/index.js | 89 ++ .../components/DocumentTitle/util.js | 17 + .../ProLayout/components/Fragment.jsx | 7 + .../components/GlobalFooter/index.jsx | 43 + .../components/GlobalFooter/index.less | 31 + .../components/GlobalHeader/index.jsx | 81 + .../components/GlobalHeader/index.less | 109 ++ .../components/GridContent/index.jsx | 27 + .../components/GridContent/index.less | 13 + .../components/PageHeaderWrapper/index.jsx | 232 +++ .../components/PageHeaderWrapper/index.less | 93 ++ .../components/RouteMenu/BaseMenu.jsx | 181 +++ .../ProLayout/components/RouteMenu/index.js | 2 + .../SettingDrawer/BlockCheckbox.jsx | 69 + .../components/SettingDrawer/LayoutChange.jsx | 95 ++ .../components/SettingDrawer/ThemeColor.jsx | 75 + .../components/SettingDrawer/ThemeColor.less | 26 + .../components/SettingDrawer/index.jsx | 267 ++++ .../components/SettingDrawer/index.less | 90 ++ .../SettingDrawer/index原始文件勿删.jsx | 344 +++++ .../components/SiderMenu/SiderMenu.jsx | 137 ++ .../ProLayout/components/SiderMenu/index.jsx | 54 + .../ProLayout/components/SiderMenu/index.less | 130 ++ .../components/ProLayout/components/index.js | 15 + hotgo-web/src/components/ProLayout/index.js | 9 + .../ProLayout/utils/dynamicTheme.js | 38 + .../src/components/ProLayout/utils/request.js | 62 + .../src/components/ProLayout/utils/util.js | 64 + .../src/components/Search/GlobalSearch.jsx | 63 + hotgo-web/src/components/Search/index.less | 25 + hotgo-web/src/components/SelectLang/index.jsx | 54 + .../src/components/SelectLang/index.less | 31 + .../SettingDrawer/SettingDrawer.vue | 343 +++++ .../components/SettingDrawer/SettingItem.vue | 38 + .../src/components/SettingDrawer/index.js | 2 + .../components/SettingDrawer/settingConfig.js | 48 + .../components/SettingDrawer/themeColor.js | 24 + .../StandardFormRow/StandardFormRow.vue | 122 ++ .../src/components/StandardFormRow/index.js | 3 + .../components/TagSelect/TagSelectOption.jsx | 45 + hotgo-web/src/components/TagSelect/index.jsx | 113 ++ hotgo-web/src/components/TextArea/index.jsx | 69 + hotgo-web/src/components/TextArea/style.less | 12 + hotgo-web/src/components/Tree/Tree.jsx | 124 ++ hotgo-web/src/components/Trend/Trend.vue | 41 + hotgo-web/src/components/Trend/index.js | 3 + hotgo-web/src/components/Trend/index.less | 42 + hotgo-web/src/components/Trend/index.md | 45 + hotgo-web/src/components/_util/util.js | 46 + hotgo-web/src/components/index.js | 37 + hotgo-web/src/components/index.less | 6 + .../components/pt/asyncComponent/Error.vue | 3 + .../components/pt/asyncComponent/Loading.vue | 34 + .../components/pt/asyncComponent/index.vue | 117 ++ .../src/components/pt/dialog/AntModal.vue | 294 ++++ .../src/components/pt/import/ImportExcel.vue | 112 ++ .../components/pt/passwordStrength/index.vue | 126 ++ .../src/components/pt/ptButtons/Delete.vue | 88 ++ .../src/components/pt/ptButtons/index.js | 2 + .../components/pt/selectDept/SelectDept.vue | 719 +++++++++ .../components/pt/selectUser/SelectUser.vue | 787 ++++++++++ hotgo-web/src/components/pt/split/Index.vue | 100 ++ hotgo-web/src/components/pt/switch/Index.vue | 63 + .../src/components/pt/table/ActionColumns.vue | 265 ++++ .../src/components/pt/table/ActionSize.vue | 49 + .../src/components/pt/table/AdvanceTable.vue | 333 ++++ .../src/components/pt/table/SearchArea.vue | 352 +++++ hotgo-web/src/components/pt/table/index.js | 2 + .../src/components/table/ActionColumns.vue | 147 ++ hotgo-web/src/components/table/ActionSize.vue | 44 + .../src/components/table/AdvanceTable.vue | 251 +++ hotgo-web/src/components/table/SearchArea.vue | 352 +++++ hotgo-web/src/components/table/index.js | 2 + hotgo-web/src/config/defaultSettings.js | 30 + hotgo-web/src/config/router.config.js | 125 ++ hotgo-web/src/core/bootstrap.js | 30 + hotgo-web/src/core/directives/action.js | 34 + hotgo-web/src/core/icons.js | 147 ++ hotgo-web/src/core/lazy_use.js | 125 ++ hotgo-web/src/core/permission/permission.js | 55 + hotgo-web/src/core/use.js | 25 + .../src/directive/permission/hasPermi.js | 27 + hotgo-web/src/directive/permission/hasRole.js | 27 + hotgo-web/src/directive/permission/index.js | 15 + hotgo-web/src/global.less | 183 +++ hotgo-web/src/layouts/BasicLayout.less | 66 + hotgo-web/src/layouts/BasicLayout.vue | 217 +++ hotgo-web/src/layouts/BlankLayout.vue | 16 + hotgo-web/src/layouts/PageView.vue | 12 + hotgo-web/src/layouts/RouteView.vue | 32 + hotgo-web/src/layouts/UserLayout.vue | 160 ++ hotgo-web/src/layouts/index.js | 7 + hotgo-web/src/layouts/modules/tabs-view.vue | 199 +++ hotgo-web/src/locales/index.js | 59 + hotgo-web/src/locales/lang/en-US.js | 16 + hotgo-web/src/locales/lang/en-US/setting.js | 29 + hotgo-web/src/locales/lang/zh-CN.js | 16 + hotgo-web/src/locales/lang/zh-CN/setting.js | 29 + hotgo-web/src/main.js | 68 + hotgo-web/src/mock/index.js | 18 + hotgo-web/src/mock/services/user.js | 26 + hotgo-web/src/mock/util.js | 38 + hotgo-web/src/permission.js | 84 + hotgo-web/src/router/README.md | 134 ++ hotgo-web/src/router/generator-routers.js | 444 ++++++ hotgo-web/src/router/index.js | 17 + hotgo-web/src/store/app-mixin.js | 32 + hotgo-web/src/store/device-mixin.js | 11 + hotgo-web/src/store/getters.js | 23 + hotgo-web/src/store/i18n-mixin.js | 16 + hotgo-web/src/store/index.js | 32 + hotgo-web/src/store/modules/app.js | 99 ++ hotgo-web/src/store/modules/async-router.js | 31 + hotgo-web/src/store/modules/permission.js | 104 ++ hotgo-web/src/store/modules/user.js | 320 ++++ hotgo-web/src/store/mutation-types.js | 24 + hotgo-web/src/utils/aidex.js | 269 ++++ hotgo-web/src/utils/axios.js | 35 + hotgo-web/src/utils/domUtil.js | 21 + hotgo-web/src/utils/drag.js | 95 ++ hotgo-web/src/utils/errorCode.js | 7 + hotgo-web/src/utils/filter.js | 20 + hotgo-web/src/utils/highlight.js | 29 + .../src/utils/pt/layout/baseMouldStyles.js | 385 +++++ hotgo-web/src/utils/request.js | 136 ++ hotgo-web/src/utils/requireIcons.js | 9 + hotgo-web/src/utils/routeConvert.js | 30 + hotgo-web/src/utils/screenLog.js | 5 + hotgo-web/src/utils/util.js | 128 ++ hotgo-web/src/utils/utils.less | 50 + hotgo-web/src/utils/validate.js | 83 + hotgo-web/src/utils/zipdownload.js | 42 + hotgo-web/src/views/404.vue | 15 + hotgo-web/src/views/account/center/index.vue | 277 ++++ .../src/views/account/center/page/App.vue | 113 ++ .../src/views/account/center/page/Article.vue | 75 + .../src/views/account/center/page/Project.vue | 115 ++ .../src/views/account/center/page/index.js | 5 + .../views/account/settings/AvatarModal.vue | 201 +++ .../views/account/settings/BaseSetting.vue | 222 +++ .../src/views/account/settings/Security.vue | 48 + .../src/views/account/settings/UpdataPass.vue | 126 ++ .../views/account/settings/UpdatePassword.vue | 121 ++ .../src/views/account/settings/index.vue | 312 ++++ .../src/views/applyLicense/ApplyLicense.vue | 0 .../src/views/dashboard/images/QQCode.png | Bin 0 -> 120384 bytes .../src/views/dashboard/images/banner1.png | Bin 0 -> 28779 bytes .../src/views/dashboard/images/banner2.png | Bin 0 -> 28779 bytes .../src/views/dashboard/images/img02.png | Bin 0 -> 13077 bytes .../src/views/dashboard/images/img03.png | Bin 0 -> 10566 bytes .../src/views/dashboard/images/wxCode.png | Bin 0 -> 154797 bytes hotgo-web/src/views/dashboard/index.vue | 32 + .../src/views/dashboard/portal/About.vue | 70 + .../src/views/dashboard/portal/CommonUse.vue | 165 ++ hotgo-web/src/views/dashboard/portal/ToDo.vue | 837 ++++++++++ .../src/views/dashboard/typical-home.less | 523 +++++++ hotgo-web/src/views/demo/chart/area-chart.vue | 129 ++ .../src/views/demo/chart/chart-radar.vue | 108 ++ .../src/views/demo/chart/dashboard-chart.vue | 122 ++ .../src/views/demo/chart/echartDashBoard.vue | 280 ++++ .../src/views/demo/chart/histogram-chart.vue | 115 ++ hotgo-web/src/views/demo/chart/line-chart.vue | 225 +++ hotgo-web/src/views/demo/chart/pie-chart.vue | 105 ++ .../src/views/demo/chart/scatter-chart.vue | 165 ++ .../src/views/demo/chart/sm-pieChart.vue | 82 + .../demo/portLetCards/AmountStatistics.vue | 32 + .../demo/portLetCards/DashboardChart.vue | 47 + .../portLetCards/TaskCompletionStatistics.vue | 34 + .../demo/portLetCards/TaskTotalStatistics.vue | 32 + .../demo/portLetCards/TrafficStatistics.vue | 38 + .../demo/portLetCards/icon/MtimeIcon.vue | 18 + .../views/demo/portLetCards/images-m/bg01.png | Bin 0 -> 1827 bytes .../demo/portLetCards/images-m/chart_sm.png | Bin 0 -> 4238 bytes .../demo/portLetCards/images-m/img01.png | Bin 0 -> 5625 bytes .../demo/portLetCards/images-m/img02.png | Bin 0 -> 5062 bytes .../demo/portLetCards/images-m/img03.png | Bin 0 -> 18956 bytes .../demo/portLetCards/images-m/img401.png | Bin 0 -> 413155 bytes .../demo/portLetCards/images-m/title_left.png | Bin 0 -> 187 bytes .../views/demo/portLetCards/style/base.less | 619 ++++++++ hotgo-web/src/views/exception/403.vue | 20 + hotgo-web/src/views/exception/404.vue | 20 + hotgo-web/src/views/exception/500.vue | 20 + hotgo-web/src/views/index.less | 107 ++ hotgo-web/src/views/index.vue | 772 ++++++++++ hotgo-web/src/views/monitor/cache/index.vue | 299 ++++ .../views/monitor/cache/indexCacheList.vue | 360 +++++ .../src/views/monitor/cache/indexOld.vue | 229 +++ hotgo-web/src/views/monitor/druid/index.vue | 42 + hotgo-web/src/views/monitor/job/index.vue | 377 +++++ hotgo-web/src/views/monitor/job/log.vue | 325 ++++ .../views/monitor/job/modules/CreateForm.vue | 196 +++ .../views/monitor/job/modules/LogViewForm.vue | 81 + .../views/monitor/job/modules/ViewForm.vue | 96 ++ .../views/monitor/loginlog/LoginLogIndex.vue | 304 ++++ hotgo-web/src/views/monitor/online/index.vue | 213 +++ .../views/monitor/operlog/OperlogIndex.vue | 447 ++++++ .../monitor/operlog/modules/ViewForm.vue | 99 ++ hotgo-web/src/views/monitor/server/index.vue | 499 ++++++ .../src/views/system/config/ConfigIndex.vue | 342 +++++ .../system/config/modules/ConfigAddForm.vue | 59 + .../system/config/modules/ConfigEditForm.vue | 48 + .../views/system/config/modules/ConfigForm.js | 117 ++ .../src/views/system/dept/SysDeptIndex.vue | 429 ++++++ .../system/dept/modules/SysDeptAddForm.vue | 83 + .../system/dept/modules/SysDeptEditForm.vue | 97 ++ .../views/system/dept/modules/SysDeptForm.js | 273 ++++ .../src/views/system/dict/DictDataIndex.vue | 279 ++++ hotgo-web/src/views/system/dict/DictIndex.vue | 360 +++++ .../system/dict/modules/DictDataAddForm.vue | 63 + .../system/dict/modules/DictDataEditForm.vue | 49 + .../views/system/dict/modules/DictDataForm.js | 129 ++ .../system/dict/modules/DictTypeAddForm.vue | 51 + .../system/dict/modules/DictTypeEditForm.vue | 43 + .../views/system/dict/modules/DictTypeForm.js | 114 ++ .../views/system/iconSelect/IconSelect.vue | 22 + hotgo-web/src/views/system/menu/MenuIndex.vue | 449 ++++++ .../views/system/menu/modules/MenuAddForm.vue | 140 ++ .../system/menu/modules/MenuEditForm.vue | 109 ++ .../src/views/system/menu/modules/MenuForm.js | 272 ++++ .../src/views/system/notice/NoticeIndex.vue | 295 ++++ .../views/system/notice/NoticeReadIndex.vue | 290 ++++ .../system/notice/modules/NoticeAddForm.vue | 57 + .../system/notice/modules/NoticeEditForm.vue | 57 + .../views/system/notice/modules/NoticeForm.js | 229 +++ .../system/notice/modules/NoticeViewForm.vue | 65 + hotgo-web/src/views/system/post/PostIndex.vue | 332 ++++ .../views/system/post/modules/PostAddForm.vue | 56 + .../system/post/modules/PostEditForm.vue | 46 + .../src/views/system/post/modules/PostForm.js | 140 ++ hotgo-web/src/views/system/role/QueryList.vue | 691 +++++++++ .../src/views/system/role/SysRoleAuth.vue | 453 ++++++ .../src/views/system/role/SysRoleIndex.vue | 360 +++++ .../role/modules/CreateDataScopeForm.vue | 293 ++++ .../views/system/role/modules/DataScope.vue | 324 ++++ .../system/role/modules/PortletScope.vue | 256 ++++ .../system/role/modules/SysRoleAddForm.vue | 84 + .../system/role/modules/SysRoleEditForm.vue | 72 + .../views/system/role/modules/SysRoleForm.js | 285 ++++ .../modules/SysPortalConfigAddForm.vue | 80 + .../modules/SysPortalConfigEditForm.vue | 84 + .../modules/SysPortalConfigForm.js | 159 ++ .../src/views/system/sysportlet/index.vue | 356 +++++ .../sysportlet/modules/SysPortletAddForm.vue | 120 ++ .../sysportlet/modules/SysPortletEditForm.vue | 124 ++ .../sysportlet/modules/SysPortletForm.js | 135 ++ .../src/views/system/user/SysUserIndex.vue | 497 ++++++ .../views/system/user/modules/DeptTree.vue | 180 +++ .../views/system/user/modules/ImportExcel.vue | 114 ++ .../system/user/modules/ResetPassword.vue | 111 ++ .../system/user/modules/SysUserAddForm.vue | 119 ++ .../system/user/modules/SysUserEditForm.vue | 127 ++ .../views/system/user/modules/SysUserForm.js | 243 +++ hotgo-web/src/views/test/temp/home.vue | 5 + hotgo-web/src/views/tool/build/index.vue | 40 + .../tool/gen/genconfigtemplate/index.vue | 359 +++++ .../module/GenConfigTemplateAddForm.vue | 91 ++ .../module/GenConfigTemplateEditForm.vue | 94 ++ .../module/GenConfigTemplateForm.js | 169 ++ hotgo-web/src/views/tool/gen/index.vue | 384 +++++ .../views/tool/gen/modules/BasicInfoForm.vue | 77 + .../src/views/tool/gen/modules/GenEdit.vue | 772 ++++++++++ .../views/tool/gen/modules/GenInfoForm.vue | 491 ++++++ .../views/tool/gen/modules/ImportTable.vue | 198 +++ .../views/tool/gen/modules/PreviewCode.vue | 71 + hotgo-web/src/views/tool/swagger/index.vue | 42 + hotgo-web/src/views/user/Login.vue | 226 +++ hotgo-web/tests/unit/.eslintrc.js | 5 + hotgo-web/vue.config.js | 145 ++ hotgo-web/webstorm.config.js | 3 + 897 files changed, 95731 insertions(+) create mode 100644 LICENSE create mode 100644 hotgo-server/.gitattributes create mode 100644 hotgo-server/.gitignore create mode 100644 hotgo-server/LICENSE create mode 100644 hotgo-server/README.MD create mode 100644 hotgo-server/app/com/cache_com.go create mode 100644 hotgo-server/app/com/captcha_com.go create mode 100644 hotgo-server/app/com/context_com.go create mode 100644 hotgo-server/app/com/ip_com.go create mode 100644 hotgo-server/app/com/jwt_com.go create mode 100644 hotgo-server/app/com/redis_com.go create mode 100644 hotgo-server/app/com/response_com.go create mode 100644 hotgo-server/app/consts/app_consts.go create mode 100644 hotgo-server/app/consts/code_consts.go create mode 100644 hotgo-server/app/consts/context_consts.go create mode 100644 hotgo-server/app/consts/debris_consts.go create mode 100644 hotgo-server/app/consts/error_consts.go create mode 100644 hotgo-server/app/consts/openapi_consts.go create mode 100644 hotgo-server/app/consts/queue_consts.go create mode 100644 hotgo-server/app/consts/redis_consts.go create mode 100644 hotgo-server/app/consts/status_consts.go create mode 100644 hotgo-server/app/consts/version_consts.go create mode 100644 hotgo-server/app/controller/adminController/config_controller.go create mode 100644 hotgo-server/app/controller/adminController/dept_controller.go create mode 100644 hotgo-server/app/controller/adminController/dict_controller.go create mode 100644 hotgo-server/app/controller/adminController/log_controller.go create mode 100644 hotgo-server/app/controller/adminController/login_controller.go create mode 100644 hotgo-server/app/controller/adminController/member_controller.go create mode 100644 hotgo-server/app/controller/adminController/menu_controller.go create mode 100644 hotgo-server/app/controller/adminController/notice_controller.go create mode 100644 hotgo-server/app/controller/adminController/post_controller.go create mode 100644 hotgo-server/app/controller/adminController/role_controller.go create mode 100644 hotgo-server/app/controller/apiController/base_controller.go create mode 100644 hotgo-server/app/controller/apiController/dict_controller.go create mode 100644 hotgo-server/app/controller/apiController/log_controller.go create mode 100644 hotgo-server/app/controller/apiController/login_controller.go create mode 100644 hotgo-server/app/controller/apiController/member_controller.go create mode 100644 hotgo-server/app/factory/queue/kafkamq.go create mode 100644 hotgo-server/app/factory/queue/list.go create mode 100644 hotgo-server/app/factory/queue/logger.go create mode 100644 hotgo-server/app/factory/queue/main.go create mode 100644 hotgo-server/app/factory/queue/queue_test.go create mode 100644 hotgo-server/app/factory/queue/redismq.go create mode 100644 hotgo-server/app/factory/queue/rocketmq.go create mode 100644 hotgo-server/app/factory/queue/rocketmq_rewrite_logger.go create mode 100644 hotgo-server/app/form/adminForm/config_form.go create mode 100644 hotgo-server/app/form/adminForm/dept_form.go create mode 100644 hotgo-server/app/form/adminForm/dict_form.go create mode 100644 hotgo-server/app/form/adminForm/log_form.go create mode 100644 hotgo-server/app/form/adminForm/login_form.go create mode 100644 hotgo-server/app/form/adminForm/member_form.go create mode 100644 hotgo-server/app/form/adminForm/menu_form.go create mode 100644 hotgo-server/app/form/adminForm/notice_form.go create mode 100644 hotgo-server/app/form/adminForm/post_form.go create mode 100644 hotgo-server/app/form/adminForm/role_form.go create mode 100644 hotgo-server/app/form/apiForm/base_form.go create mode 100644 hotgo-server/app/form/apiForm/dict_form.go create mode 100644 hotgo-server/app/form/apiForm/log_form.go create mode 100644 hotgo-server/app/form/apiForm/login_form.go create mode 100644 hotgo-server/app/form/apiForm/member_form.go create mode 100644 hotgo-server/app/form/common.go create mode 100644 hotgo-server/app/form/input/admin_dept_input.go create mode 100644 hotgo-server/app/form/input/admin_member_input.go create mode 100644 hotgo-server/app/form/input/admin_notice_input.go create mode 100644 hotgo-server/app/form/input/admin_post_input.go create mode 100644 hotgo-server/app/form/input/admin_role_input.go create mode 100644 hotgo-server/app/form/input/sys_config_input.go create mode 100644 hotgo-server/app/form/input/sys_log_input.go create mode 100644 hotgo-server/app/hook/hook.go create mode 100644 hotgo-server/app/interfaces/queue_producer_interface.go create mode 100644 hotgo-server/app/middleware/admin_auth.go create mode 100644 hotgo-server/app/middleware/api_auth.go create mode 100644 hotgo-server/app/middleware/handler_response.go create mode 100644 hotgo-server/app/middleware/middleware.go create mode 100644 hotgo-server/app/model/context.go create mode 100644 hotgo-server/app/model/entity/admin_dept.go create mode 100644 hotgo-server/app/model/entity/admin_member.go create mode 100644 hotgo-server/app/model/entity/admin_member_post.go create mode 100644 hotgo-server/app/model/entity/admin_member_role.go create mode 100644 hotgo-server/app/model/entity/admin_menu.go create mode 100644 hotgo-server/app/model/entity/admin_menu_old.go create mode 100644 hotgo-server/app/model/entity/admin_notice.go create mode 100644 hotgo-server/app/model/entity/admin_post.go create mode 100644 hotgo-server/app/model/entity/admin_role.go create mode 100644 hotgo-server/app/model/entity/admin_role_dept.go create mode 100644 hotgo-server/app/model/entity/admin_role_menu.go create mode 100644 hotgo-server/app/model/entity/sys_config.go create mode 100644 hotgo-server/app/model/entity/sys_dict_data.go create mode 100644 hotgo-server/app/model/entity/sys_dict_type.go create mode 100644 hotgo-server/app/model/entity/sys_log.go create mode 100644 hotgo-server/app/model/entity/sys_provinces.go create mode 100644 hotgo-server/app/model/response.go create mode 100644 hotgo-server/app/model/tree.go create mode 100644 hotgo-server/app/service/adminService/dept_service.go create mode 100644 hotgo-server/app/service/adminService/member_post_service.go create mode 100644 hotgo-server/app/service/adminService/member_service.go create mode 100644 hotgo-server/app/service/adminService/menu_service.go create mode 100644 hotgo-server/app/service/adminService/notice_service.go create mode 100644 hotgo-server/app/service/adminService/post_service.go create mode 100644 hotgo-server/app/service/adminService/role_service.go create mode 100644 hotgo-server/app/service/apiService/member_service.go create mode 100644 hotgo-server/app/service/internal/dao/admin_dept.go create mode 100644 hotgo-server/app/service/internal/dao/admin_member.go create mode 100644 hotgo-server/app/service/internal/dao/admin_member_post.go create mode 100644 hotgo-server/app/service/internal/dao/admin_member_role.go create mode 100644 hotgo-server/app/service/internal/dao/admin_menu.go create mode 100644 hotgo-server/app/service/internal/dao/admin_menu_old.go create mode 100644 hotgo-server/app/service/internal/dao/admin_notice.go create mode 100644 hotgo-server/app/service/internal/dao/admin_post.go create mode 100644 hotgo-server/app/service/internal/dao/admin_role.go create mode 100644 hotgo-server/app/service/internal/dao/admin_role_dept.go create mode 100644 hotgo-server/app/service/internal/dao/admin_role_menu.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_dept.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_member.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_member_post.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_member_role.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_menu.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_menu_old.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_notice.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_post.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_role.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_role_dept.go create mode 100644 hotgo-server/app/service/internal/dao/internal/admin_role_menu.go create mode 100644 hotgo-server/app/service/internal/dao/internal/sys_config.go create mode 100644 hotgo-server/app/service/internal/dao/internal/sys_dict_data.go create mode 100644 hotgo-server/app/service/internal/dao/internal/sys_dict_type.go create mode 100644 hotgo-server/app/service/internal/dao/internal/sys_log.go create mode 100644 hotgo-server/app/service/internal/dao/internal/sys_provinces.go create mode 100644 hotgo-server/app/service/internal/dao/sys_config.go create mode 100644 hotgo-server/app/service/internal/dao/sys_dict_data.go create mode 100644 hotgo-server/app/service/internal/dao/sys_dict_type.go create mode 100644 hotgo-server/app/service/internal/dao/sys_log.go create mode 100644 hotgo-server/app/service/internal/dao/sys_provinces.go create mode 100644 hotgo-server/app/service/internal/dto/admin_dept.go create mode 100644 hotgo-server/app/service/internal/dto/admin_member.go create mode 100644 hotgo-server/app/service/internal/dto/admin_member_post.go create mode 100644 hotgo-server/app/service/internal/dto/admin_member_role.go create mode 100644 hotgo-server/app/service/internal/dto/admin_menu.go create mode 100644 hotgo-server/app/service/internal/dto/admin_menu_old.go create mode 100644 hotgo-server/app/service/internal/dto/admin_notice.go create mode 100644 hotgo-server/app/service/internal/dto/admin_post.go create mode 100644 hotgo-server/app/service/internal/dto/admin_role.go create mode 100644 hotgo-server/app/service/internal/dto/admin_role_dept.go create mode 100644 hotgo-server/app/service/internal/dto/admin_role_menu.go create mode 100644 hotgo-server/app/service/internal/dto/sys_config.go create mode 100644 hotgo-server/app/service/internal/dto/sys_dict_data.go create mode 100644 hotgo-server/app/service/internal/dto/sys_dict_type.go create mode 100644 hotgo-server/app/service/internal/dto/sys_log.go create mode 100644 hotgo-server/app/service/internal/dto/sys_provinces.go create mode 100644 hotgo-server/app/service/sysService/config_service.go create mode 100644 hotgo-server/app/service/sysService/dict_service.go create mode 100644 hotgo-server/app/service/sysService/log_service.go create mode 100644 hotgo-server/app/service/sysService/provinces_service.go create mode 100644 hotgo-server/app/utils/auth_util.go create mode 100644 hotgo-server/app/utils/charset_util.go create mode 100644 hotgo-server/app/utils/excel_util.go create mode 100644 hotgo-server/app/utils/filter_util.go create mode 100644 hotgo-server/app/utils/signal_util.go create mode 100644 hotgo-server/app/utils/validate_util.go create mode 100644 hotgo-server/boot/queue.go create mode 100644 hotgo-server/boot/run.go create mode 100644 hotgo-server/config/config.example.yaml create mode 100644 hotgo-server/config/config.yaml create mode 100644 hotgo-server/go.mod create mode 100644 hotgo-server/go.sum create mode 100644 hotgo-server/main.go create mode 100644 hotgo-server/pull.bat create mode 100644 hotgo-server/push.bat create mode 100644 hotgo-server/resource/public/html/.gitkeep create mode 100644 hotgo-server/resource/public/plugin/.gitkeep create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/layer.js create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/mobile/layer.js create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/mobile/need/layer.css create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/theme/default/icon-ext.png create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/theme/default/icon.png create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/theme/default/layer.css create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/theme/default/loading-0.gif create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/theme/default/loading-1.gif create mode 100644 hotgo-server/resource/public/plugin/layer-3.1.1/theme/default/loading-2.gif create mode 100644 hotgo-server/resource/public/resource/css/.gitkeep create mode 100644 hotgo-server/resource/public/resource/image/.gitkeep create mode 100644 hotgo-server/resource/public/resource/image/cover.png create mode 100644 hotgo-server/resource/public/resource/image/favicon.ico create mode 100644 hotgo-server/resource/public/resource/image/gf.ico create mode 100644 hotgo-server/resource/public/resource/js/.gitkeep create mode 100644 hotgo-server/resource/template/.gitkeep create mode 100644 hotgo-server/router/admin.go create mode 100644 hotgo-server/router/api.go create mode 100644 hotgo-server/runtime/log/exception/.gitignore create mode 100644 hotgo-server/runtime/log/logger/.gitignore create mode 100644 hotgo-server/runtime/log/queue/.gitignore create mode 100644 hotgo-server/runtime/log/server/.gitignore create mode 100644 hotgo-server/runtime/log/server/access/.gitignore create mode 100644 hotgo-server/runtime/log/server/error/.gitignore create mode 100644 hotgo-server/storage/ip/qqwry-utf8.dat create mode 100644 hotgo-uniapp/.gitignore create mode 100644 hotgo-uniapp/.vscode/settings.json create mode 100644 hotgo-uniapp/App.vue create mode 100644 hotgo-uniapp/LICENSE create mode 100644 hotgo-uniapp/README.md create mode 100644 hotgo-uniapp/common/base64.js create mode 100644 hotgo-uniapp/common/config.js create mode 100644 hotgo-uniapp/common/http.api.js create mode 100644 hotgo-uniapp/common/http.interceptor.js create mode 100644 hotgo-uniapp/common/locales/en.js create mode 100644 hotgo-uniapp/common/locales/zh_CN.js create mode 100644 hotgo-uniapp/common/spark-md5.js create mode 100644 hotgo-uniapp/common/vue-i18n.min.js create mode 100644 hotgo-uniapp/components/js-checkbox/js-checkbox.vue create mode 100644 hotgo-uniapp/components/js-lang/js-lang.vue create mode 100644 hotgo-uniapp/components/js-radio/js-radio.vue create mode 100644 hotgo-uniapp/components/js-select/js-select.vue create mode 100644 hotgo-uniapp/components/js-uploadfile/js-uploadfile.vue create mode 100644 hotgo-uniapp/h5.html create mode 100644 hotgo-uniapp/main.js create mode 100644 hotgo-uniapp/manifest.json create mode 100644 hotgo-uniapp/package-lock.json create mode 100644 hotgo-uniapp/package.json create mode 100644 hotgo-uniapp/pages.json create mode 100644 hotgo-uniapp/pages/common/jeesite.scss create mode 100644 hotgo-uniapp/pages/common/webview.vue create mode 100644 hotgo-uniapp/pages/sys/home/index.scss create mode 100644 hotgo-uniapp/pages/sys/home/index.vue create mode 100644 hotgo-uniapp/pages/sys/login/forget.vue create mode 100644 hotgo-uniapp/pages/sys/login/index.scss create mode 100644 hotgo-uniapp/pages/sys/login/index.vue create mode 100644 hotgo-uniapp/pages/sys/login/reg.vue create mode 100644 hotgo-uniapp/pages/sys/msg/form.vue create mode 100644 hotgo-uniapp/pages/sys/msg/index.vue create mode 100644 hotgo-uniapp/pages/sys/user/about.vue create mode 100644 hotgo-uniapp/pages/sys/user/comment.vue create mode 100644 hotgo-uniapp/pages/sys/user/help.vue create mode 100644 hotgo-uniapp/pages/sys/user/index.scss create mode 100644 hotgo-uniapp/pages/sys/user/index.vue create mode 100644 hotgo-uniapp/pages/sys/user/info.vue create mode 100644 hotgo-uniapp/pages/sys/user/pwd.vue create mode 100644 hotgo-uniapp/pages/sys/user/setting.vue create mode 100644 hotgo-uniapp/pages/testData/form.vue create mode 100644 hotgo-uniapp/pages/testData/index.vue create mode 100644 hotgo-uniapp/static/common/img/iPhoneX.png create mode 100644 hotgo-uniapp/static/common/js/touch-emulator.js create mode 100644 hotgo-uniapp/static/index.html create mode 100644 hotgo-uniapp/static/jeesite/banner/1.svg create mode 100644 hotgo-uniapp/static/jeesite/banner/2.svg create mode 100644 hotgo-uniapp/static/jeesite/banner/3.svg create mode 100644 hotgo-uniapp/static/jeesite/favicon.png create mode 100644 hotgo-uniapp/static/jeesite/login/eye_close.png create mode 100644 hotgo-uniapp/static/jeesite/login/eye_open.png create mode 100644 hotgo-uniapp/static/jeesite/logo200.png create mode 100644 hotgo-uniapp/static/jeesite/tabbar/home_1.png create mode 100644 hotgo-uniapp/static/jeesite/tabbar/home_2.png create mode 100644 hotgo-uniapp/static/jeesite/tabbar/msg_1.png create mode 100644 hotgo-uniapp/static/jeesite/tabbar/msg_2.png create mode 100644 hotgo-uniapp/static/jeesite/tabbar/my_1.png create mode 100644 hotgo-uniapp/static/jeesite/tabbar/my_2.png create mode 100644 hotgo-uniapp/static/uview/common/favicon.ico create mode 100644 hotgo-uniapp/static/uview/common/logo.png create mode 100644 hotgo-uniapp/static/uview/example/component.png create mode 100644 hotgo-uniapp/static/uview/example/component_select.png create mode 100644 hotgo-uniapp/static/uview/example/js.png create mode 100644 hotgo-uniapp/static/uview/example/js_bak.png create mode 100644 hotgo-uniapp/static/uview/example/js_select.png create mode 100644 hotgo-uniapp/static/uview/example/js_select_bak.png create mode 100644 hotgo-uniapp/static/uview/example/min_button.png create mode 100644 hotgo-uniapp/static/uview/example/min_button_select.png create mode 100644 hotgo-uniapp/static/uview/example/template.png create mode 100644 hotgo-uniapp/static/uview/example/template_select.png create mode 100644 hotgo-uniapp/store/$u.mixin.js create mode 100644 hotgo-uniapp/store/index.js create mode 100644 hotgo-uniapp/uni.scss create mode 100644 hotgo-uniapp/unpackage/res/icons/1024x1024.png create mode 100644 hotgo-uniapp/unpackage/res/icons/120x120.png create mode 100644 hotgo-uniapp/unpackage/res/icons/144x144.png create mode 100644 hotgo-uniapp/unpackage/res/icons/152x152.png create mode 100644 hotgo-uniapp/unpackage/res/icons/167x167.png create mode 100644 hotgo-uniapp/unpackage/res/icons/180x180.png create mode 100644 hotgo-uniapp/unpackage/res/icons/192x192.png create mode 100644 hotgo-uniapp/unpackage/res/icons/20x20.png create mode 100644 hotgo-uniapp/unpackage/res/icons/29x29.png create mode 100644 hotgo-uniapp/unpackage/res/icons/40x40.png create mode 100644 hotgo-uniapp/unpackage/res/icons/58x58.png create mode 100644 hotgo-uniapp/unpackage/res/icons/60x60.png create mode 100644 hotgo-uniapp/unpackage/res/icons/72x72.png create mode 100644 hotgo-uniapp/unpackage/res/icons/76x76.png create mode 100644 hotgo-uniapp/unpackage/res/icons/80x80.png create mode 100644 hotgo-uniapp/unpackage/res/icons/87x87.png create mode 100644 hotgo-uniapp/unpackage/res/icons/96x96.png create mode 100644 hotgo-uniapp/uview-ui/LICENSE create mode 100644 hotgo-uniapp/uview-ui/README.md create mode 100644 hotgo-uniapp/uview-ui/components/u-action-sheet/u-action-sheet.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-alert-tips/u-alert-tips.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-avatar-cropper/weCropper.js create mode 100644 hotgo-uniapp/uview-ui/components/u-avatar/u-avatar.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-back-top/u-back-top.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-badge/u-badge.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-button/u-button.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-calendar/u-calendar.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-car-keyboard/u-car-keyboard.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-card/u-card.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-cell-group/u-cell-group.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-cell-item/u-cell-item.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-checkbox-group/u-checkbox-group.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-checkbox/u-checkbox.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-circle-progress/u-circle-progress.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-circle-progress/u-line-progress/u-line-progress.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-col/u-col.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-collapse-item/u-collapse-item.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-collapse/u-collapse.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-column-notice/u-column-notice.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-count-down/u-count-down.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-count-to/u-count-to.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-divider/u-divider.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-dropdown-item/u-dropdown-item.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-dropdown/u-dropdown.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-empty/u-empty.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-field/u-field.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-form-item/u-form-item.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-form/u-form.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-full-screen/u-full-screen.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-gap/u-gap.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-grid-item/u-grid-item.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-grid/u-grid.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-icon/u-icon.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-image/u-image.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-index-anchor/u-index-anchor.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-index-list/u-index-list.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-input/u-input.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-keyboard/u-keyboard.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-lazy-load/u-lazy-load.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-line-progress/u-line-progress.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-line/u-line.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-link/u-link.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-loading-page/u-loading-page.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-loading/u-loading.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-loadmore/u-loadmore.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-mask/u-mask.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-message-input/u-message-input.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-modal/u-modal.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-navbar/u-navbar.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-no-network/u-no-network.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-notice-bar/u-notice-bar.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-number-box/u-number-box.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-number-keyboard/u-number-keyboard.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-parse/libs/CssHandler.js create mode 100644 hotgo-uniapp/uview-ui/components/u-parse/libs/MpHtmlParser.js create mode 100644 hotgo-uniapp/uview-ui/components/u-parse/libs/config.js create mode 100644 hotgo-uniapp/uview-ui/components/u-parse/libs/handler.wxs create mode 100644 hotgo-uniapp/uview-ui/components/u-parse/libs/trees.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-parse/u-parse.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-picker/u-picker.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-popup/u-popup.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-radio-group/u-radio-group.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-radio/u-radio.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-rate/u-rate.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-read-more/u-read-more.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-row-notice/u-row-notice.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-row/u-row.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-search/u-search.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-section/u-section.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-select/u-select.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-skeleton/u-skeleton.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-slider/u-slider.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-steps/u-steps.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-sticky/u-sticky.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-subsection/u-subsection.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-swipe-action/u-swipe-action.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-swiper/u-swiper.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-switch/u-switch.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-tabbar/u-tabbar.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-table/u-table.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-tabs-swiper/u-tabs-swiper.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-tabs/u-tabs.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-tag/u-tag.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-td/u-td.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-th/u-th.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-time-line-item/u-time-line-item.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-time-line/u-time-line.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-toast/u-toast.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-top-tips/u-top-tips.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-tr/u-tr.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-upload/u-upload.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-verification-code/u-verification-code.vue create mode 100644 hotgo-uniapp/uview-ui/components/u-waterfall/u-waterfall.vue create mode 100644 hotgo-uniapp/uview-ui/iconfont.css create mode 100644 hotgo-uniapp/uview-ui/index.js create mode 100644 hotgo-uniapp/uview-ui/index.scss create mode 100644 hotgo-uniapp/uview-ui/libs/config/config.js create mode 100644 hotgo-uniapp/uview-ui/libs/config/zIndex.js create mode 100644 hotgo-uniapp/uview-ui/libs/css/color.scss create mode 100644 hotgo-uniapp/uview-ui/libs/css/common.scss create mode 100644 hotgo-uniapp/uview-ui/libs/css/style.components.scss create mode 100644 hotgo-uniapp/uview-ui/libs/css/style.h5.scss create mode 100644 hotgo-uniapp/uview-ui/libs/css/style.mp.scss create mode 100644 hotgo-uniapp/uview-ui/libs/css/style.nvue.scss create mode 100644 hotgo-uniapp/uview-ui/libs/css/style.vue.scss create mode 100644 hotgo-uniapp/uview-ui/libs/function/$parent.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/addUnit.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/bem.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/color.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/colorGradient.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/date.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/debounce.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/deepClone.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/deepMerge.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/getParent.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/guid.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/md5.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/queryParams.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/random.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/randomArray.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/route.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/sys.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/test.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/throttle.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/timeFormat.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/timeFrom.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/toast.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/trim.js create mode 100644 hotgo-uniapp/uview-ui/libs/function/type2icon.js create mode 100644 hotgo-uniapp/uview-ui/libs/mixin/mixin.js create mode 100644 hotgo-uniapp/uview-ui/libs/mixin/mpShare.js create mode 100644 hotgo-uniapp/uview-ui/libs/request/index.js create mode 100644 hotgo-uniapp/uview-ui/libs/store/index.js create mode 100644 hotgo-uniapp/uview-ui/libs/util/area.js create mode 100644 hotgo-uniapp/uview-ui/libs/util/async-validator.js create mode 100644 hotgo-uniapp/uview-ui/libs/util/city.js create mode 100644 hotgo-uniapp/uview-ui/libs/util/emitter.js create mode 100644 hotgo-uniapp/uview-ui/libs/util/province.js create mode 100644 hotgo-uniapp/uview-ui/package.json create mode 100644 hotgo-uniapp/uview-ui/theme.scss create mode 100644 hotgo-uniapp/vue.config.js create mode 100644 hotgo-web/.browserslistrc create mode 100644 hotgo-web/.editorconfig create mode 100644 hotgo-web/.env create mode 100644 hotgo-web/.env.development create mode 100644 hotgo-web/.env.preview create mode 100644 hotgo-web/.eslintrc.js create mode 100644 hotgo-web/.eslintrc.json create mode 100644 hotgo-web/.gitattributes create mode 100644 hotgo-web/.gitignore create mode 100644 hotgo-web/.prettierrc create mode 100644 hotgo-web/.travis.yml create mode 100644 hotgo-web/LICENSE create mode 100644 hotgo-web/README.md create mode 100644 hotgo-web/babel.config.js create mode 100644 hotgo-web/bin/build.bat create mode 100644 hotgo-web/bin/package.bat create mode 100644 hotgo-web/bin/run-web.bat create mode 100644 hotgo-web/config/plugin.config.js create mode 100644 hotgo-web/config/themePluginConfig.js create mode 100644 hotgo-web/jest.config.js create mode 100644 hotgo-web/jsconfig.json create mode 100644 hotgo-web/package.json create mode 100644 hotgo-web/postcss.config.js create mode 100644 hotgo-web/public/index.html create mode 100644 hotgo-web/public/logo.png create mode 100644 hotgo-web/pull.bat create mode 100644 hotgo-web/push.bat create mode 100644 hotgo-web/src/App.vue create mode 100644 hotgo-web/src/api/login.js create mode 100644 hotgo-web/src/api/manage.js create mode 100644 hotgo-web/src/api/menu.js create mode 100644 hotgo-web/src/api/monitor/cache.js create mode 100644 hotgo-web/src/api/monitor/job.js create mode 100644 hotgo-web/src/api/monitor/jobLog.js create mode 100644 hotgo-web/src/api/monitor/loginLog.js create mode 100644 hotgo-web/src/api/monitor/online.js create mode 100644 hotgo-web/src/api/monitor/operlog.js create mode 100644 hotgo-web/src/api/monitor/server.js create mode 100644 hotgo-web/src/api/monitor/sysDataPermissionsDefRule.js create mode 100644 hotgo-web/src/api/monitor/sysDataPermissionsMethod.js create mode 100644 hotgo-web/src/api/monitor/sysDataPermissionsRule.js create mode 100644 hotgo-web/src/api/system/config.js create mode 100644 hotgo-web/src/api/system/dept.js create mode 100644 hotgo-web/src/api/system/dict/data.js create mode 100644 hotgo-web/src/api/system/dict/type.js create mode 100644 hotgo-web/src/api/system/menu.js create mode 100644 hotgo-web/src/api/system/notice.js create mode 100644 hotgo-web/src/api/system/post.js create mode 100644 hotgo-web/src/api/system/role.js create mode 100644 hotgo-web/src/api/system/sysNoticeUserRead.js create mode 100644 hotgo-web/src/api/system/sysPortalConfig.js create mode 100644 hotgo-web/src/api/system/sysPortlet.js create mode 100644 hotgo-web/src/api/system/sysTableConfig.js create mode 100644 hotgo-web/src/api/system/sysThemeConfig.js create mode 100644 hotgo-web/src/api/system/upload.js create mode 100644 hotgo-web/src/api/system/user.js create mode 100644 hotgo-web/src/api/tool/gen.js create mode 100644 hotgo-web/src/api/tool/genConfigTemplate.js create mode 100644 hotgo-web/src/assets/background.svg create mode 100644 hotgo-web/src/assets/icons/Alipay.svg create mode 100644 hotgo-web/src/assets/icons/DragColumn.svg create mode 100644 hotgo-web/src/assets/icons/QRcode.svg create mode 100644 hotgo-web/src/assets/icons/Sina.svg create mode 100644 hotgo-web/src/assets/icons/WeChat.svg create mode 100644 hotgo-web/src/assets/icons/bug.svg create mode 100644 hotgo-web/src/assets/icons/build.svg create mode 100644 hotgo-web/src/assets/icons/button.svg create mode 100644 hotgo-web/src/assets/icons/bxAnalyse.svg create mode 100644 hotgo-web/src/assets/icons/cascader.svg create mode 100644 hotgo-web/src/assets/icons/chart.svg create mode 100644 hotgo-web/src/assets/icons/checkbox.svg create mode 100644 hotgo-web/src/assets/icons/clipboard.svg create mode 100644 hotgo-web/src/assets/icons/codeNew.svg create mode 100644 hotgo-web/src/assets/icons/color.svg create mode 100644 hotgo-web/src/assets/icons/company.svg create mode 100644 hotgo-web/src/assets/icons/companyFill.svg create mode 100644 hotgo-web/src/assets/icons/component.svg create mode 100644 hotgo-web/src/assets/icons/compress.svg create mode 100644 hotgo-web/src/assets/icons/connections.svg create mode 100644 hotgo-web/src/assets/icons/dashboardNew.svg create mode 100644 hotgo-web/src/assets/icons/date.svg create mode 100644 hotgo-web/src/assets/icons/dateRange.svg create mode 100644 hotgo-web/src/assets/icons/dict.svg create mode 100644 hotgo-web/src/assets/icons/dingtalk.svg create mode 100644 hotgo-web/src/assets/icons/documentation.svg create mode 100644 hotgo-web/src/assets/icons/download.svg create mode 100644 hotgo-web/src/assets/icons/dragImg.svg create mode 100644 hotgo-web/src/assets/icons/dragtable.svg create mode 100644 hotgo-web/src/assets/icons/druid.svg create mode 100644 hotgo-web/src/assets/icons/edit.svg create mode 100644 hotgo-web/src/assets/icons/expend.svg create mode 100644 hotgo-web/src/assets/icons/eyeOpen.svg create mode 100644 hotgo-web/src/assets/icons/github.svg create mode 100644 hotgo-web/src/assets/icons/guide.svg create mode 100644 hotgo-web/src/assets/icons/input.svg create mode 100644 hotgo-web/src/assets/icons/job.svg create mode 100644 hotgo-web/src/assets/icons/log.svg create mode 100644 hotgo-web/src/assets/icons/loginLog.svg create mode 100644 hotgo-web/src/assets/icons/message.svg create mode 100644 hotgo-web/src/assets/icons/monitor.svg create mode 100644 hotgo-web/src/assets/icons/number.svg create mode 100644 hotgo-web/src/assets/icons/online.svg create mode 100644 hotgo-web/src/assets/icons/password.svg create mode 100644 hotgo-web/src/assets/icons/pdf.svg create mode 100644 hotgo-web/src/assets/icons/peoples.svg create mode 100644 hotgo-web/src/assets/icons/phone.svg create mode 100644 hotgo-web/src/assets/icons/post.svg create mode 100644 hotgo-web/src/assets/icons/question.svg create mode 100644 hotgo-web/src/assets/icons/radio.svg create mode 100644 hotgo-web/src/assets/icons/rate.svg create mode 100644 hotgo-web/src/assets/icons/redis.svg create mode 100644 hotgo-web/src/assets/icons/row.svg create mode 100644 hotgo-web/src/assets/icons/select.svg create mode 100644 hotgo-web/src/assets/icons/server.svg create mode 100644 hotgo-web/src/assets/icons/swagger.svg create mode 100644 hotgo-web/src/assets/icons/switch.svg create mode 100644 hotgo-web/src/assets/icons/system.svg create mode 100644 hotgo-web/src/assets/icons/textarea.svg create mode 100644 hotgo-web/src/assets/icons/time.svg create mode 100644 hotgo-web/src/assets/icons/timeRange.svg create mode 100644 hotgo-web/src/assets/icons/tool.svg create mode 100644 hotgo-web/src/assets/icons/tree.svg create mode 100644 hotgo-web/src/assets/icons/treeTable.svg create mode 100644 hotgo-web/src/assets/icons/upload.svg create mode 100644 hotgo-web/src/assets/icons/users.svg create mode 100644 hotgo-web/src/assets/icons/validCode.svg create mode 100644 hotgo-web/src/assets/images/dark.svg create mode 100644 hotgo-web/src/assets/images/light.svg create mode 100644 hotgo-web/src/assets/images/login-background.jpg create mode 100644 hotgo-web/src/assets/images/profile.jpg create mode 100644 hotgo-web/src/assets/images/upload/excel.svg create mode 100644 hotgo-web/src/assets/images/upload/gif.svg create mode 100644 hotgo-web/src/assets/images/upload/jpg.svg create mode 100644 hotgo-web/src/assets/images/upload/other.svg create mode 100644 hotgo-web/src/assets/images/upload/pdf.svg create mode 100644 hotgo-web/src/assets/images/upload/png.svg create mode 100644 hotgo-web/src/assets/images/upload/ppt.svg create mode 100644 hotgo-web/src/assets/images/upload/text.svg create mode 100644 hotgo-web/src/assets/images/upload/word.svg create mode 100644 hotgo-web/src/assets/images/upload/zip.svg create mode 100644 hotgo-web/src/assets/login-bg.png create mode 100644 hotgo-web/src/assets/logo.png create mode 100644 hotgo-web/src/assets/logo.svg create mode 100644 hotgo-web/src/assets/projects/antdv.png create mode 100644 hotgo-web/src/assets/projects/ruoyi.png create mode 100644 hotgo-web/src/assets/styles/antv-theme.less create mode 100644 hotgo-web/src/assets/styles/default.less create mode 100644 hotgo-web/src/assets/wrapper.jpg create mode 100644 hotgo-web/src/components/ArticleListContent/ArticleListContent.vue create mode 100644 hotgo-web/src/components/ArticleListContent/index.js create mode 100644 hotgo-web/src/components/AvatarList/Item.jsx create mode 100644 hotgo-web/src/components/AvatarList/List.jsx create mode 100644 hotgo-web/src/components/AvatarList/index.js create mode 100644 hotgo-web/src/components/AvatarList/index.less create mode 100644 hotgo-web/src/components/AvatarList/index.md create mode 100644 hotgo-web/src/components/Dialog.js create mode 100644 hotgo-web/src/components/Ellipsis/Ellipsis.vue create mode 100644 hotgo-web/src/components/Ellipsis/index.js create mode 100644 hotgo-web/src/components/Ellipsis/index.md create mode 100644 hotgo-web/src/components/FooterToolbar/FooterToolBar.vue create mode 100644 hotgo-web/src/components/FooterToolbar/index.js create mode 100644 hotgo-web/src/components/FooterToolbar/index.less create mode 100644 hotgo-web/src/components/FooterToolbar/index.md create mode 100644 hotgo-web/src/components/GlobalFooter/index.vue create mode 100644 hotgo-web/src/components/GlobalHeader/AvatarDropdown.vue create mode 100644 hotgo-web/src/components/GlobalHeader/PlatformVersion.vue create mode 100644 hotgo-web/src/components/GlobalHeader/RightContent.vue create mode 100644 hotgo-web/src/components/GridContent/index.js create mode 100644 hotgo-web/src/components/GridContent/index.less create mode 100644 hotgo-web/src/components/IconSelector/IconDetail.vue create mode 100644 hotgo-web/src/components/IconSelector/IconSelector.vue create mode 100644 hotgo-web/src/components/IconSelector/README.md create mode 100644 hotgo-web/src/components/IconSelector/icons.js create mode 100644 hotgo-web/src/components/IconSelector/index.js create mode 100644 hotgo-web/src/components/MultiTab/MultiTab.vue create mode 100644 hotgo-web/src/components/MultiTab/events.js create mode 100644 hotgo-web/src/components/MultiTab/index.js create mode 100644 hotgo-web/src/components/MultiTab/index.less create mode 100644 hotgo-web/src/components/NProgress/nprogress.less create mode 100644 hotgo-web/src/components/NoticeIcon/NoticeIcon.vue create mode 100644 hotgo-web/src/components/NoticeIcon/index.js create mode 100644 hotgo-web/src/components/NumberInfo/NumberInfo.vue create mode 100644 hotgo-web/src/components/NumberInfo/index.js create mode 100644 hotgo-web/src/components/NumberInfo/index.less create mode 100644 hotgo-web/src/components/NumberInfo/index.md create mode 100644 hotgo-web/src/components/Other/CarbonAds.vue create mode 100644 hotgo-web/src/components/PageLoading/index.jsx create mode 100644 hotgo-web/src/components/ProLayout/BasicLayout.jsx create mode 100644 hotgo-web/src/components/ProLayout/BasicLayout.less create mode 100644 hotgo-web/src/components/ProLayout/BlockLayout.jsx create mode 100644 hotgo-web/src/components/ProLayout/Header.jsx create mode 100644 hotgo-web/src/components/ProLayout/Header.less create mode 100644 hotgo-web/src/components/ProLayout/PageView.jsx create mode 100644 hotgo-web/src/components/ProLayout/WrapContent.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/ConfigProvider/index.js create mode 100644 hotgo-web/src/components/ProLayout/components/DocumentTitle/SideEffect/index.js create mode 100644 hotgo-web/src/components/ProLayout/components/DocumentTitle/index.js create mode 100644 hotgo-web/src/components/ProLayout/components/DocumentTitle/util.js create mode 100644 hotgo-web/src/components/ProLayout/components/Fragment.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/GlobalFooter/index.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/GlobalFooter/index.less create mode 100644 hotgo-web/src/components/ProLayout/components/GlobalHeader/index.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/GlobalHeader/index.less create mode 100644 hotgo-web/src/components/ProLayout/components/GridContent/index.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/GridContent/index.less create mode 100644 hotgo-web/src/components/ProLayout/components/PageHeaderWrapper/index.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/PageHeaderWrapper/index.less create mode 100644 hotgo-web/src/components/ProLayout/components/RouteMenu/BaseMenu.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/RouteMenu/index.js create mode 100644 hotgo-web/src/components/ProLayout/components/SettingDrawer/BlockCheckbox.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/SettingDrawer/LayoutChange.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/SettingDrawer/ThemeColor.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/SettingDrawer/ThemeColor.less create mode 100644 hotgo-web/src/components/ProLayout/components/SettingDrawer/index.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/SettingDrawer/index.less create mode 100644 hotgo-web/src/components/ProLayout/components/SettingDrawer/index原始文件勿删.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/SiderMenu/SiderMenu.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/SiderMenu/index.jsx create mode 100644 hotgo-web/src/components/ProLayout/components/SiderMenu/index.less create mode 100644 hotgo-web/src/components/ProLayout/components/index.js create mode 100644 hotgo-web/src/components/ProLayout/index.js create mode 100644 hotgo-web/src/components/ProLayout/utils/dynamicTheme.js create mode 100644 hotgo-web/src/components/ProLayout/utils/request.js create mode 100644 hotgo-web/src/components/ProLayout/utils/util.js create mode 100644 hotgo-web/src/components/Search/GlobalSearch.jsx create mode 100644 hotgo-web/src/components/Search/index.less create mode 100644 hotgo-web/src/components/SelectLang/index.jsx create mode 100644 hotgo-web/src/components/SelectLang/index.less create mode 100644 hotgo-web/src/components/SettingDrawer/SettingDrawer.vue create mode 100644 hotgo-web/src/components/SettingDrawer/SettingItem.vue create mode 100644 hotgo-web/src/components/SettingDrawer/index.js create mode 100644 hotgo-web/src/components/SettingDrawer/settingConfig.js create mode 100644 hotgo-web/src/components/SettingDrawer/themeColor.js create mode 100644 hotgo-web/src/components/StandardFormRow/StandardFormRow.vue create mode 100644 hotgo-web/src/components/StandardFormRow/index.js create mode 100644 hotgo-web/src/components/TagSelect/TagSelectOption.jsx create mode 100644 hotgo-web/src/components/TagSelect/index.jsx create mode 100644 hotgo-web/src/components/TextArea/index.jsx create mode 100644 hotgo-web/src/components/TextArea/style.less create mode 100644 hotgo-web/src/components/Tree/Tree.jsx create mode 100644 hotgo-web/src/components/Trend/Trend.vue create mode 100644 hotgo-web/src/components/Trend/index.js create mode 100644 hotgo-web/src/components/Trend/index.less create mode 100644 hotgo-web/src/components/Trend/index.md create mode 100644 hotgo-web/src/components/_util/util.js create mode 100644 hotgo-web/src/components/index.js create mode 100644 hotgo-web/src/components/index.less create mode 100644 hotgo-web/src/components/pt/asyncComponent/Error.vue create mode 100644 hotgo-web/src/components/pt/asyncComponent/Loading.vue create mode 100644 hotgo-web/src/components/pt/asyncComponent/index.vue create mode 100644 hotgo-web/src/components/pt/dialog/AntModal.vue create mode 100644 hotgo-web/src/components/pt/import/ImportExcel.vue create mode 100644 hotgo-web/src/components/pt/passwordStrength/index.vue create mode 100644 hotgo-web/src/components/pt/ptButtons/Delete.vue create mode 100644 hotgo-web/src/components/pt/ptButtons/index.js create mode 100644 hotgo-web/src/components/pt/selectDept/SelectDept.vue create mode 100644 hotgo-web/src/components/pt/selectUser/SelectUser.vue create mode 100644 hotgo-web/src/components/pt/split/Index.vue create mode 100644 hotgo-web/src/components/pt/switch/Index.vue create mode 100644 hotgo-web/src/components/pt/table/ActionColumns.vue create mode 100644 hotgo-web/src/components/pt/table/ActionSize.vue create mode 100644 hotgo-web/src/components/pt/table/AdvanceTable.vue create mode 100644 hotgo-web/src/components/pt/table/SearchArea.vue create mode 100644 hotgo-web/src/components/pt/table/index.js create mode 100644 hotgo-web/src/components/table/ActionColumns.vue create mode 100644 hotgo-web/src/components/table/ActionSize.vue create mode 100644 hotgo-web/src/components/table/AdvanceTable.vue create mode 100644 hotgo-web/src/components/table/SearchArea.vue create mode 100644 hotgo-web/src/components/table/index.js create mode 100644 hotgo-web/src/config/defaultSettings.js create mode 100644 hotgo-web/src/config/router.config.js create mode 100644 hotgo-web/src/core/bootstrap.js create mode 100644 hotgo-web/src/core/directives/action.js create mode 100644 hotgo-web/src/core/icons.js create mode 100644 hotgo-web/src/core/lazy_use.js create mode 100644 hotgo-web/src/core/permission/permission.js create mode 100644 hotgo-web/src/core/use.js create mode 100644 hotgo-web/src/directive/permission/hasPermi.js create mode 100644 hotgo-web/src/directive/permission/hasRole.js create mode 100644 hotgo-web/src/directive/permission/index.js create mode 100644 hotgo-web/src/global.less create mode 100644 hotgo-web/src/layouts/BasicLayout.less create mode 100644 hotgo-web/src/layouts/BasicLayout.vue create mode 100644 hotgo-web/src/layouts/BlankLayout.vue create mode 100644 hotgo-web/src/layouts/PageView.vue create mode 100644 hotgo-web/src/layouts/RouteView.vue create mode 100644 hotgo-web/src/layouts/UserLayout.vue create mode 100644 hotgo-web/src/layouts/index.js create mode 100644 hotgo-web/src/layouts/modules/tabs-view.vue create mode 100644 hotgo-web/src/locales/index.js create mode 100644 hotgo-web/src/locales/lang/en-US.js create mode 100644 hotgo-web/src/locales/lang/en-US/setting.js create mode 100644 hotgo-web/src/locales/lang/zh-CN.js create mode 100644 hotgo-web/src/locales/lang/zh-CN/setting.js create mode 100644 hotgo-web/src/main.js create mode 100644 hotgo-web/src/mock/index.js create mode 100644 hotgo-web/src/mock/services/user.js create mode 100644 hotgo-web/src/mock/util.js create mode 100644 hotgo-web/src/permission.js create mode 100644 hotgo-web/src/router/README.md create mode 100644 hotgo-web/src/router/generator-routers.js create mode 100644 hotgo-web/src/router/index.js create mode 100644 hotgo-web/src/store/app-mixin.js create mode 100644 hotgo-web/src/store/device-mixin.js create mode 100644 hotgo-web/src/store/getters.js create mode 100644 hotgo-web/src/store/i18n-mixin.js create mode 100644 hotgo-web/src/store/index.js create mode 100644 hotgo-web/src/store/modules/app.js create mode 100644 hotgo-web/src/store/modules/async-router.js create mode 100644 hotgo-web/src/store/modules/permission.js create mode 100644 hotgo-web/src/store/modules/user.js create mode 100644 hotgo-web/src/store/mutation-types.js create mode 100644 hotgo-web/src/utils/aidex.js create mode 100644 hotgo-web/src/utils/axios.js create mode 100644 hotgo-web/src/utils/domUtil.js create mode 100644 hotgo-web/src/utils/drag.js create mode 100644 hotgo-web/src/utils/errorCode.js create mode 100644 hotgo-web/src/utils/filter.js create mode 100644 hotgo-web/src/utils/highlight.js create mode 100644 hotgo-web/src/utils/pt/layout/baseMouldStyles.js create mode 100644 hotgo-web/src/utils/request.js create mode 100644 hotgo-web/src/utils/requireIcons.js create mode 100644 hotgo-web/src/utils/routeConvert.js create mode 100644 hotgo-web/src/utils/screenLog.js create mode 100644 hotgo-web/src/utils/util.js create mode 100644 hotgo-web/src/utils/utils.less create mode 100644 hotgo-web/src/utils/validate.js create mode 100644 hotgo-web/src/utils/zipdownload.js create mode 100644 hotgo-web/src/views/404.vue create mode 100644 hotgo-web/src/views/account/center/index.vue create mode 100644 hotgo-web/src/views/account/center/page/App.vue create mode 100644 hotgo-web/src/views/account/center/page/Article.vue create mode 100644 hotgo-web/src/views/account/center/page/Project.vue create mode 100644 hotgo-web/src/views/account/center/page/index.js create mode 100644 hotgo-web/src/views/account/settings/AvatarModal.vue create mode 100644 hotgo-web/src/views/account/settings/BaseSetting.vue create mode 100644 hotgo-web/src/views/account/settings/Security.vue create mode 100644 hotgo-web/src/views/account/settings/UpdataPass.vue create mode 100644 hotgo-web/src/views/account/settings/UpdatePassword.vue create mode 100644 hotgo-web/src/views/account/settings/index.vue create mode 100644 hotgo-web/src/views/applyLicense/ApplyLicense.vue create mode 100644 hotgo-web/src/views/dashboard/images/QQCode.png create mode 100644 hotgo-web/src/views/dashboard/images/banner1.png create mode 100644 hotgo-web/src/views/dashboard/images/banner2.png create mode 100644 hotgo-web/src/views/dashboard/images/img02.png create mode 100644 hotgo-web/src/views/dashboard/images/img03.png create mode 100644 hotgo-web/src/views/dashboard/images/wxCode.png create mode 100644 hotgo-web/src/views/dashboard/index.vue create mode 100644 hotgo-web/src/views/dashboard/portal/About.vue create mode 100644 hotgo-web/src/views/dashboard/portal/CommonUse.vue create mode 100644 hotgo-web/src/views/dashboard/portal/ToDo.vue create mode 100644 hotgo-web/src/views/dashboard/typical-home.less create mode 100644 hotgo-web/src/views/demo/chart/area-chart.vue create mode 100644 hotgo-web/src/views/demo/chart/chart-radar.vue create mode 100644 hotgo-web/src/views/demo/chart/dashboard-chart.vue create mode 100644 hotgo-web/src/views/demo/chart/echartDashBoard.vue create mode 100644 hotgo-web/src/views/demo/chart/histogram-chart.vue create mode 100644 hotgo-web/src/views/demo/chart/line-chart.vue create mode 100644 hotgo-web/src/views/demo/chart/pie-chart.vue create mode 100644 hotgo-web/src/views/demo/chart/scatter-chart.vue create mode 100644 hotgo-web/src/views/demo/chart/sm-pieChart.vue create mode 100644 hotgo-web/src/views/demo/portLetCards/AmountStatistics.vue create mode 100644 hotgo-web/src/views/demo/portLetCards/DashboardChart.vue create mode 100644 hotgo-web/src/views/demo/portLetCards/TaskCompletionStatistics.vue create mode 100644 hotgo-web/src/views/demo/portLetCards/TaskTotalStatistics.vue create mode 100644 hotgo-web/src/views/demo/portLetCards/TrafficStatistics.vue create mode 100644 hotgo-web/src/views/demo/portLetCards/icon/MtimeIcon.vue create mode 100644 hotgo-web/src/views/demo/portLetCards/images-m/bg01.png create mode 100644 hotgo-web/src/views/demo/portLetCards/images-m/chart_sm.png create mode 100644 hotgo-web/src/views/demo/portLetCards/images-m/img01.png create mode 100644 hotgo-web/src/views/demo/portLetCards/images-m/img02.png create mode 100644 hotgo-web/src/views/demo/portLetCards/images-m/img03.png create mode 100644 hotgo-web/src/views/demo/portLetCards/images-m/img401.png create mode 100644 hotgo-web/src/views/demo/portLetCards/images-m/title_left.png create mode 100644 hotgo-web/src/views/demo/portLetCards/style/base.less create mode 100644 hotgo-web/src/views/exception/403.vue create mode 100644 hotgo-web/src/views/exception/404.vue create mode 100644 hotgo-web/src/views/exception/500.vue create mode 100644 hotgo-web/src/views/index.less create mode 100644 hotgo-web/src/views/index.vue create mode 100644 hotgo-web/src/views/monitor/cache/index.vue create mode 100644 hotgo-web/src/views/monitor/cache/indexCacheList.vue create mode 100644 hotgo-web/src/views/monitor/cache/indexOld.vue create mode 100644 hotgo-web/src/views/monitor/druid/index.vue create mode 100644 hotgo-web/src/views/monitor/job/index.vue create mode 100644 hotgo-web/src/views/monitor/job/log.vue create mode 100644 hotgo-web/src/views/monitor/job/modules/CreateForm.vue create mode 100644 hotgo-web/src/views/monitor/job/modules/LogViewForm.vue create mode 100644 hotgo-web/src/views/monitor/job/modules/ViewForm.vue create mode 100644 hotgo-web/src/views/monitor/loginlog/LoginLogIndex.vue create mode 100644 hotgo-web/src/views/monitor/online/index.vue create mode 100644 hotgo-web/src/views/monitor/operlog/OperlogIndex.vue create mode 100644 hotgo-web/src/views/monitor/operlog/modules/ViewForm.vue create mode 100644 hotgo-web/src/views/monitor/server/index.vue create mode 100644 hotgo-web/src/views/system/config/ConfigIndex.vue create mode 100644 hotgo-web/src/views/system/config/modules/ConfigAddForm.vue create mode 100644 hotgo-web/src/views/system/config/modules/ConfigEditForm.vue create mode 100644 hotgo-web/src/views/system/config/modules/ConfigForm.js create mode 100644 hotgo-web/src/views/system/dept/SysDeptIndex.vue create mode 100644 hotgo-web/src/views/system/dept/modules/SysDeptAddForm.vue create mode 100644 hotgo-web/src/views/system/dept/modules/SysDeptEditForm.vue create mode 100644 hotgo-web/src/views/system/dept/modules/SysDeptForm.js create mode 100644 hotgo-web/src/views/system/dict/DictDataIndex.vue create mode 100644 hotgo-web/src/views/system/dict/DictIndex.vue create mode 100644 hotgo-web/src/views/system/dict/modules/DictDataAddForm.vue create mode 100644 hotgo-web/src/views/system/dict/modules/DictDataEditForm.vue create mode 100644 hotgo-web/src/views/system/dict/modules/DictDataForm.js create mode 100644 hotgo-web/src/views/system/dict/modules/DictTypeAddForm.vue create mode 100644 hotgo-web/src/views/system/dict/modules/DictTypeEditForm.vue create mode 100644 hotgo-web/src/views/system/dict/modules/DictTypeForm.js create mode 100644 hotgo-web/src/views/system/iconSelect/IconSelect.vue create mode 100644 hotgo-web/src/views/system/menu/MenuIndex.vue create mode 100644 hotgo-web/src/views/system/menu/modules/MenuAddForm.vue create mode 100644 hotgo-web/src/views/system/menu/modules/MenuEditForm.vue create mode 100644 hotgo-web/src/views/system/menu/modules/MenuForm.js create mode 100644 hotgo-web/src/views/system/notice/NoticeIndex.vue create mode 100644 hotgo-web/src/views/system/notice/NoticeReadIndex.vue create mode 100644 hotgo-web/src/views/system/notice/modules/NoticeAddForm.vue create mode 100644 hotgo-web/src/views/system/notice/modules/NoticeEditForm.vue create mode 100644 hotgo-web/src/views/system/notice/modules/NoticeForm.js create mode 100644 hotgo-web/src/views/system/notice/modules/NoticeViewForm.vue create mode 100644 hotgo-web/src/views/system/post/PostIndex.vue create mode 100644 hotgo-web/src/views/system/post/modules/PostAddForm.vue create mode 100644 hotgo-web/src/views/system/post/modules/PostEditForm.vue create mode 100644 hotgo-web/src/views/system/post/modules/PostForm.js create mode 100644 hotgo-web/src/views/system/role/QueryList.vue create mode 100644 hotgo-web/src/views/system/role/SysRoleAuth.vue create mode 100644 hotgo-web/src/views/system/role/SysRoleIndex.vue create mode 100644 hotgo-web/src/views/system/role/modules/CreateDataScopeForm.vue create mode 100644 hotgo-web/src/views/system/role/modules/DataScope.vue create mode 100644 hotgo-web/src/views/system/role/modules/PortletScope.vue create mode 100644 hotgo-web/src/views/system/role/modules/SysRoleAddForm.vue create mode 100644 hotgo-web/src/views/system/role/modules/SysRoleEditForm.vue create mode 100644 hotgo-web/src/views/system/role/modules/SysRoleForm.js create mode 100644 hotgo-web/src/views/system/sysportalconfig/modules/SysPortalConfigAddForm.vue create mode 100644 hotgo-web/src/views/system/sysportalconfig/modules/SysPortalConfigEditForm.vue create mode 100644 hotgo-web/src/views/system/sysportalconfig/modules/SysPortalConfigForm.js create mode 100644 hotgo-web/src/views/system/sysportlet/index.vue create mode 100644 hotgo-web/src/views/system/sysportlet/modules/SysPortletAddForm.vue create mode 100644 hotgo-web/src/views/system/sysportlet/modules/SysPortletEditForm.vue create mode 100644 hotgo-web/src/views/system/sysportlet/modules/SysPortletForm.js create mode 100644 hotgo-web/src/views/system/user/SysUserIndex.vue create mode 100644 hotgo-web/src/views/system/user/modules/DeptTree.vue create mode 100644 hotgo-web/src/views/system/user/modules/ImportExcel.vue create mode 100644 hotgo-web/src/views/system/user/modules/ResetPassword.vue create mode 100644 hotgo-web/src/views/system/user/modules/SysUserAddForm.vue create mode 100644 hotgo-web/src/views/system/user/modules/SysUserEditForm.vue create mode 100644 hotgo-web/src/views/system/user/modules/SysUserForm.js create mode 100644 hotgo-web/src/views/test/temp/home.vue create mode 100644 hotgo-web/src/views/tool/build/index.vue create mode 100644 hotgo-web/src/views/tool/gen/genconfigtemplate/index.vue create mode 100644 hotgo-web/src/views/tool/gen/genconfigtemplate/module/GenConfigTemplateAddForm.vue create mode 100644 hotgo-web/src/views/tool/gen/genconfigtemplate/module/GenConfigTemplateEditForm.vue create mode 100644 hotgo-web/src/views/tool/gen/genconfigtemplate/module/GenConfigTemplateForm.js create mode 100644 hotgo-web/src/views/tool/gen/index.vue create mode 100644 hotgo-web/src/views/tool/gen/modules/BasicInfoForm.vue create mode 100644 hotgo-web/src/views/tool/gen/modules/GenEdit.vue create mode 100644 hotgo-web/src/views/tool/gen/modules/GenInfoForm.vue create mode 100644 hotgo-web/src/views/tool/gen/modules/ImportTable.vue create mode 100644 hotgo-web/src/views/tool/gen/modules/PreviewCode.vue create mode 100644 hotgo-web/src/views/tool/swagger/index.vue create mode 100644 hotgo-web/src/views/user/Login.vue create mode 100644 hotgo-web/tests/unit/.eslintrc.js create mode 100644 hotgo-web/vue.config.js create mode 100644 hotgo-web/webstorm.config.js diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hotgo-server/.gitattributes b/hotgo-server/.gitattributes new file mode 100644 index 0000000..1fbf887 --- /dev/null +++ b/hotgo-server/.gitattributes @@ -0,0 +1 @@ +* linguist-language=GO \ No newline at end of file diff --git a/hotgo-server/.gitignore b/hotgo-server/.gitignore new file mode 100644 index 0000000..8aa20ab --- /dev/null +++ b/hotgo-server/.gitignore @@ -0,0 +1,20 @@ +.DS_Store +.buildpath +.hgignore.swp +.project +.orig +.swp +.idea/ +.settings/ +runtime/log/logger/*.log +runtime/log/logger/exception/*.log +runtime/log/logger/queue/*.log +runtime/log/server/*.log +runtime/log/server/access/*.log +runtime/log/server/error/*.log +bin/ +*/.DS_Store +.vscode +main.exe +main.exe~ +hotgo.exe \ No newline at end of file diff --git a/hotgo-server/LICENSE b/hotgo-server/LICENSE new file mode 100644 index 0000000..d410ffc --- /dev/null +++ b/hotgo-server/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 john@goframe.org https://goframe.org + +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/hotgo-server/README.MD b/hotgo-server/README.MD new file mode 100644 index 0000000..61de0ed --- /dev/null +++ b/hotgo-server/README.MD @@ -0,0 +1 @@ +测试 \ No newline at end of file diff --git a/hotgo-server/app/com/cache_com.go b/hotgo-server/app/com/cache_com.go new file mode 100644 index 0000000..972bdaa --- /dev/null +++ b/hotgo-server/app/com/cache_com.go @@ -0,0 +1,31 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package com + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gcache" +) + +type cache struct { +} + +var ( + Cache = new(cache) +) + +func (component *cache) New() *gcache.Cache { + c := gcache.New() + + //redis + adapter := gcache.NewAdapterRedis(g.Redis()) + + //内存 + //adapter := gcache.NewAdapterMemory() + c.SetAdapter(adapter) + return c +} diff --git a/hotgo-server/app/com/captcha_com.go b/hotgo-server/app/com/captcha_com.go new file mode 100644 index 0000000..965189f --- /dev/null +++ b/hotgo-server/app/com/captcha_com.go @@ -0,0 +1,62 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package com + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/text/gstr" + "github.com/mojocn/base64Captcha" +) + +var Captcha = new(captcha) + +type captcha struct{} + +// +// @Title 获取字母数字混合验证码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Return idKeyC +// @Return base64stringC +// +func (component *captcha) GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string) { + driver := &base64Captcha.DriverString{ + Height: 80, + Width: 240, + //NoiseCount: 50, + //ShowLineOptions: 20, + Length: 4, + Source: "abcdefghjkmnpqrstuvwxyz23456789", + Fonts: []string{"chromohv.ttf"}, + } + driver = driver.ConvertFonts() + store := base64Captcha.DefaultMemStore + c := base64Captcha.NewCaptcha(driver, store) + idKeyC, base64stringC, err := c.Generate() + if err != nil { + g.Log().Error(ctx,err) + } + return +} + +// +// @Title 验证输入的验证码是否正确 +// @Description +// @Author Ms <133814250@qq.com> +// @Param id +// @Param answer +// @Return bool +// +func (component *captcha) VerifyString(id, answer string) bool { + driver := new(base64Captcha.DriverString) + store := base64Captcha.DefaultMemStore + c := base64Captcha.NewCaptcha(driver, store) + answer = gstr.ToLower(answer) + return c.Verify(id, answer, true) +} \ No newline at end of file diff --git a/hotgo-server/app/com/context_com.go b/hotgo-server/app/com/context_com.go new file mode 100644 index 0000000..622e512 --- /dev/null +++ b/hotgo-server/app/com/context_com.go @@ -0,0 +1,107 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package com + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model" + "github.com/gogf/gf/v2/net/ghttp" +) + +type comContext struct{} + +var Context = new(comContext) + +// +// @Title 初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// @Param customCtx +// +func (component *comContext) Init(r *ghttp.Request, customCtx *model.Context) { + r.SetCtxVar(consts.ContextKey, customCtx) +} + +// +// @Title 获得上下文变量,如果没有设置,那么返回nil +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Return *model.Context +// +func (component *comContext) Get(ctx context.Context) *model.Context { + value := ctx.Value(consts.ContextKey) + if value == nil { + return nil + } + if localCtx, ok := value.(*model.Context); ok { + return localCtx + } + return nil +} + +// +// @Title 将上下文信息设置到上下文请求中,注意是完整覆盖 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param user +// +func (component *comContext) SetUser(ctx context.Context, user *model.Identity) { + component.Get(ctx).User = user +} + +// +// @Title 设置组件响应 用于全局日志使用 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param response +// +func (component *comContext) SetResponse(ctx context.Context, response *model.Response) { + component.Get(ctx).ComResponse = response +} + +// +// @Title 设置应用模块 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param module +// +func (component *comContext) SetModule(ctx context.Context, module string) { + component.Get(ctx).Module = module +} + +// +// @Title 设置请求耗时 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param module +// +func (component *comContext) SetTakeUpTime(ctx context.Context, takeUpTime int64) { + component.Get(ctx).TakeUpTime = takeUpTime +} + +// +// @Title 获取用户ID +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Return int +// +func (component *comContext) GetUserId(ctx context.Context) int64 { + user := component.Get(ctx).User + if user == nil { + return 0 + } + + return user.Id +} diff --git a/hotgo-server/app/com/ip_com.go b/hotgo-server/app/com/ip_com.go new file mode 100644 index 0000000..1506bbc --- /dev/null +++ b/hotgo-server/app/com/ip_com.go @@ -0,0 +1,254 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package com + +import ( + "context" + "github.com/axgle/mahonia" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "github.com/kayon/iploc" + "time" +) + +var Ip = new(ip) + +type ip struct{} + +type IpLocationData struct { + Ip string `json:"ip"` + Country string `json:"country"` + Region string `json:"region"` + Province string `json:"province"` + ProvinceCode int `json:"province_code"` + City string `json:"city"` + CityCode int `json:"city_code"` + Area string `json:"area"` + AreaCode int `json:"area_code"` +} + +// +// @Title 通过Whois接口查询IP归属地 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param ip +// @Return IpLocationData +// +func (component *ip) WhoisLocation(ctx context.Context, ip string) IpLocationData { + + type whoisRegionData struct { + Ip string `json:"ip"` + Pro string `json:"pro" ` + ProCode string `json:"proCode" ` + City string `json:"city" ` + CityCode string `json:"cityCode"` + Region string `json:"region"` + RegionCode string `json:"regionCode"` + Addr string `json:"addr"` + Err string `json:"err"` + } + + if !utils.Validate.IsIp(ip) { + return IpLocationData{} + } + + response, err := g.Client().Timeout(10*time.Second).Get(ctx, "http://whois.pconline.com.cn/ipJson.jsp?ip="+ip+"&json=true") + if err != nil { + err = gerror.New(err.Error()) + return IpLocationData{ + Ip: ip, + } + } + + defer response.Close() + + var enc mahonia.Decoder + enc = mahonia.NewDecoder("gbk") + + data := enc.ConvertString(response.ReadAllString()) + + g.Log().Print(ctx, "data:", data) + whoisData := whoisRegionData{} + if err := gconv.Struct(data, &whoisData); err != nil { + err = gerror.New(err.Error()) + + g.Log().Print(ctx, "err:", err) + return IpLocationData{ + Ip: ip, + } + } + + g.Log().Print(ctx, "whoisData:", whoisData) + + return IpLocationData{ + Ip: whoisData.Ip, + //Country string `json:"country"` + Region: whoisData.Addr, + Province: whoisData.Pro, + ProvinceCode: gconv.Int(whoisData.ProCode), + City: whoisData.City, + CityCode: gconv.Int(whoisData.CityCode), + Area: whoisData.Region, + AreaCode: gconv.Int(whoisData.RegionCode), + } +} + +// +// @Title 通过Cz88的IP库查询IP归属地 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param ip +// @Return IpLocationData +// +func (component *ip) Cz88Find(ctx context.Context, ip string) IpLocationData { + if !utils.Validate.IsIp(ip) { + g.Log().Print(ctx, "ip格式错误:", ip) + return IpLocationData{} + } + + loc, err := iploc.OpenWithoutIndexes("./storage/ip/qqwry-utf8.dat") + if err != nil { + err = gerror.New(err.Error()) + return IpLocationData{ + Ip: ip, + } + } + + detail := loc.Find(ip) + if detail == nil { + return IpLocationData{ + Ip: ip, + } + } + + locationData := IpLocationData{ + Ip: ip, + Country: detail.Country, + Region: detail.Region, + Province: detail.Province, + City: detail.City, + Area: detail.County, + } + + if gstr.LenRune(locationData.Province) == 0 { + return locationData + } + + var ( + provinceModel *entity.SysProvinces + cityModel *entity.SysProvinces + areaModel *entity.SysProvinces + ) + + err = g.DB().Model("hg_common_provinces"). + Where("level", 1). + WhereLike("title", "%"+locationData.Province+"%"). + Scan(&provinceModel) + + if err != nil { + err = gerror.New(err.Error()) + return locationData + } + + if provinceModel != nil { + locationData.ProvinceCode = provinceModel.Id + locationData.Province = provinceModel.Title + } + + if gstr.LenRune(locationData.City) == 0 { + return locationData + + // 是否为直辖市 + } else if component.IsJurisdictionByIpTitle(locationData.City) { + locationData.CityCode = provinceModel.Id + 100 + locationData.City = "直辖市" + } else { + + //替换掉 + locationData.City = gstr.Replace(locationData.City, "地区", "") + + err = g.DB().Model("hg_common_provinces"). + Where("level", 2). + Where("pid", locationData.ProvinceCode). + WhereLike("title", "%"+locationData.City+"%"). + Scan(&cityModel) + + if err != nil { + err = gerror.New(err.Error()) + return locationData + } + + if cityModel != nil { + locationData.CityCode = cityModel.Id + locationData.City = cityModel.Title + } + } + + if gstr.LenRune(locationData.Area) == 0 { + return locationData + } + + err = g.DB().Model("hg_common_provinces"). + Where("level", 3). + Where("pid", locationData.CityCode). + WhereLike("title", "%"+locationData.Area+"%"). + Scan(&areaModel) + + if err != nil { + err = gerror.New(err.Error()) + return locationData + } + + if areaModel != nil { + locationData.AreaCode = areaModel.Id + locationData.Area = areaModel.Title + } + + return locationData +} + +// +// @Title 判断地区名称是否为直辖市 +// @Description +// @Author Ms <133814250@qq.com> +// @Param title +// @Return bool +// +func (component *ip) IsJurisdictionByIpTitle(title string) bool { + + lists := []string{"北京市", "天津市", "重庆市", "上海市"} + + for i := 0; i < len(lists); i++ { + if gstr.Contains(lists[i], title) { + return true + } + } + return false +} + +// +// @Title 获取IP归属地信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param ip +// @Return IpLocationData +// +func (component *ip) GetLocation(ctx context.Context, ip string) IpLocationData { + method, _ := g.Cfg().Get(ctx, "hotgo.ipMethod", "cz88") + + if method.String() == "whois" { + return component.WhoisLocation(ctx, ip) + } + return component.Cz88Find(ctx, ip) +} diff --git a/hotgo-server/app/com/jwt_com.go b/hotgo-server/app/com/jwt_com.go new file mode 100644 index 0000000..9bd1275 --- /dev/null +++ b/hotgo-server/app/com/jwt_com.go @@ -0,0 +1,161 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package com + +import ( + "context" + "fmt" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model" + "github.com/dgrijalva/jwt-go" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "time" +) + +type JWT struct{} + +var Jwt = new(JWT) + +// +// @Title 为指定用户生成token +// @Description 主要用于登录成功的jwt鉴权绑定 +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param user 用户信息 +// @Param isRefresh 是否是刷新token +// @Return interface{} +// @Return error +// +func (component *JWT) GenerateLoginToken(ctx context.Context, user *model.Identity, isRefresh bool) (interface{}, error) { + + jwtVersion, _ := g.Cfg().Get(ctx, "jwt.version", "1.0") + jwtSign, _ := g.Cfg().Get(ctx, "jwt.sign", "hotGo") + + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ + "id": user.Id, + "username": user.Username, + "realname": user.Realname, + "avatar": user.Avatar, + "email": user.Email, + "mobile": user.Mobile, + "last_time": user.LastTime, + "last_ip": user.LastIp, + "exp": user.Exp, + "expires": user.Expires, + "app": user.App, + "role": user.Role, + "visit_count": user.VisitCount, + "is_refresh": isRefresh, + "jwt_version": jwtVersion.String(), + }) + + tokenString, err := token.SignedString(jwtSign.Bytes()) + if err != nil { + err := gerror.New(err.Error()) + return nil, err + } + + tokenStringMd5 := gmd5.MustEncryptString(tokenString) + + // TODO 绑定登录token + cache := Cache.New() + key := consts.RedisJwtToken + tokenStringMd5 + + // TODO 将有效期转为持续时间,单位:秒 + expires, _ := time.ParseDuration(fmt.Sprintf("+%vs", user.Expires)) + + err = cache.Set(ctx, key, tokenString, expires) + if err != nil { + err := gerror.New(err.Error()) + return nil, err + } + _ = cache.Set(ctx, consts.RedisJwtUserBind+user.App+":"+gconv.String(user.Id), key, expires) + + return tokenString, err +} + +// +// @Title 解析token +// @Description +// @Author Ms <133814250@qq.com> +// @Param tokenString +// @Param secret +// @Return jwt.MapClaims +// @Return error +// +func (component *JWT) ParseToken(tokenString string, secret []byte) (jwt.MapClaims, error) { + if tokenString == "" { + err := gerror.New("token 为空") + return nil, err + } + token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { + + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + } + return secret, nil + }) + + if token == nil { + err := gerror.New("token不存在") + return nil, err + } + + if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + return claims, nil + } else { + return nil, err + } +} + +/** +token有效正确返回用户id +*/ +//func(component *JWT) VerifyLoginToken(tokenString string) (uint, err error) { +// //if tokenString == "" { +// // err = gerror.New("token不能为空") +// // return 0, err +// //} +// +//} + +// +// @Title 获取 authorization +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// @Return string +// +func (component *JWT) GetAuthorization(r *ghttp.Request) string { + + // TODO 默认从请求头获取 + var authorization = r.Header.Get("Authorization") + + // TODO 如果请求头不存在则从get参数获取 + if authorization == "" { + return r.Get("authorization").String() + } + + return gstr.Replace(authorization, "Bearer ", "") +} + +/** +清掉所以的相关的redis +*/ +func (component *JWT) Layout(adminUserId int, tokenString string) { + if tokenString == "" { + return + } + //g.Redis().Do("HDEL", "VerifyLoginToken", gmd5.MustEncryptString(tokenString)) + //// 删除 + //g.Redis().Do("HDEL", "VerifyLoginTokenAdminUserId", adminUserId) +} diff --git a/hotgo-server/app/com/redis_com.go b/hotgo-server/app/com/redis_com.go new file mode 100644 index 0000000..26dab5a --- /dev/null +++ b/hotgo-server/app/com/redis_com.go @@ -0,0 +1,83 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package com + +import ( + "context" + "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/database/gredis" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" +) + +var Redis = new(redis) + +type redis struct{} + +// +// @Title 实例化redis +// @Description +// @Author Ms <133814250@qq.com> +// @Param name +// @Return *gredis.Redis +// +func (component *redis) Instance(name ...string) *gredis.Redis { + return g.Redis(name...) +} + +// +// @Title 获取 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param key +// @Return *gvar.Var +// @Return error +// +func (component *redis) Get(ctx context.Context, key string) (*gvar.Var, error) { + data, err := Redis.Instance().Do(ctx, "GET", key) + if err != nil { + err := gerror.New(err.Error()) + return nil, err + } + + return data, nil +} + +// +// @Title 设置 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param key +// @Param value +// @Param expire +// @Return *gvar.Var +// @Return error +// +func (component *redis) Set(ctx context.Context, key string, value string, expire interface{}) (*gvar.Var, error) { + + redisInstance := Redis.Instance() + response, err := redisInstance.Do(ctx, "SET", key, value) + if err != nil { + err := gerror.New(err.Error()) + return nil, err + } + + exp := gconv.Int(expire) + // TODO 设置有效期 + if exp > 0 { + _, err = redisInstance.Do(ctx, "EXPIRE", key, exp) + if err != nil { + err := gerror.New(err.Error()) + return nil, err + } + } + + return response, nil +} diff --git a/hotgo-server/app/com/response_com.go b/hotgo-server/app/com/response_com.go new file mode 100644 index 0000000..f21fc2c --- /dev/null +++ b/hotgo-server/app/com/response_com.go @@ -0,0 +1,121 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package com + +import ( + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "time" +) + +var Response = new(response) + +type response struct{} + +// +// @Title 返回JSON数据并退出当前HTTP执行函数 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// @Param code +// @Param message +// @Param data +// +func (component *response) JsonExit(r *ghttp.Request, code int, message string, data ...interface{}) { + component.RJson(r, code, message, data...) + r.Exit() +} + +// +// @Title 标准返回结果数据结构封装 +// @Description 返回固定数据结构的JSON +// @Author Ms <133814250@qq.com> +// @Param r +// @Param code 状态码(200:成功,302跳转,和http请求状态码一至) +// @Param message 请求结果信息 +// @Param data 请求结果,根据不同接口返回结果的数据结构不同 +// +func (component *response) RJson(r *ghttp.Request, code int, message string, data ...interface{}) { + responseData := interface{}(nil) + if len(data) > 0 { + responseData = data[0] + } + Res := &model.Response{ + Code: code, + Message: message, + Timestamp: time.Now().Unix(), + ReqId: Context.Get(r.Context()).ReqId, + } + + // TODO 如果不是正常的返回,则将data转为error + if consts.CodeOK == code { + Res.Data = responseData + } else { + Res.Error = responseData + } + + // TODO 清空响应 + r.Response.ClearBuffer() + + // TODO 写入响应 + if err := r.Response.WriteJson(Res); err != nil { + g.Log().Error(r.Context(), "响应异常:", err) + } + + // TODO 加入到上下文 + Context.SetResponse(r.Context(), Res) +} + +// +// @Title 返回成功JSON +// @Description +// @Author Ms <133814250@qq.com> +// @Param isExit +// @Param r +// @Param message +// @Param data +// +func (component *response) SusJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) { + if isExit { + component.JsonExit(r, consts.CodeOK, message, data...) + } + component.RJson(r, consts.CodeOK, message, data...) +} + +// +// @Title 返回失败JSON +// @Description +// @Author Ms <133814250@qq.com> +// @Param isExit +// @Param r +// @Param message +// @Param data +// +func (component *response) FailJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) { + if isExit { + component.JsonExit(r, consts.CodeNil, message, data...) + } + component.RJson(r, consts.CodeNil, message, data...) +} + +// +// @Title 重定向 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// @Param location +// @Param code +// +func (component *response) Redirect(r *ghttp.Request, location string, code ...int) { + r.Response.RedirectTo(location, code...) +} + +func (component *response) Download(r *ghttp.Request, location string, code ...int) { + r.Response.ServeFileDownload("test.txt") +} diff --git a/hotgo-server/app/consts/app_consts.go b/hotgo-server/app/consts/app_consts.go new file mode 100644 index 0000000..b097cf6 --- /dev/null +++ b/hotgo-server/app/consts/app_consts.go @@ -0,0 +1,14 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// 应用类型 +const ( + AppAdmin = "admin" + AppApi = "api" + AppDefault = "default" +) diff --git a/hotgo-server/app/consts/code_consts.go b/hotgo-server/app/consts/code_consts.go new file mode 100644 index 0000000..c86d07d --- /dev/null +++ b/hotgo-server/app/consts/code_consts.go @@ -0,0 +1,31 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// 全局状态码 +const ( + CodeNil = -1 // No error code specified. + CodeOK = 0 // It is OK. + CodeInternalError = 50 // An error occurred internally. + CodeValidationFailed = 51 // Data validation failed. + CodeDbOperationError = 52 // Database operation error. + CodeInvalidParameter = 53 // The given parameter for current operation is invalid. + CodeMissingParameter = 54 // Parameter for current operation is missing. + CodeInvalidOperation = 55 // The function cannot be used like this. + CodeInvalidConfiguration = 56 // The configuration is invalid for current operation. + CodeMissingConfiguration = 57 // The configuration is missing for current operation. + CodeNotImplemented = 58 // The operation is not implemented yet. + CodeNotSupported = 59 // The operation is not supported yet. + CodeOperationFailed = 60 // I tried, but I cannot give you what you want. + CodeNotAuthorized = 61 // Not Authorized. + CodeSecurityReason = 62 // Security Reason. + CodeServerBusy = 63 // Server is busy, please try again later. + CodeUnknown = 64 // Unknown error. + CodeNotFound = 65 // Resource does not exist. + CodeInvalidRequest = 66 // Invalid request. + CodeBusinessValidationFailed = 300 // Business validation failed. +) diff --git a/hotgo-server/app/consts/context_consts.go b/hotgo-server/app/consts/context_consts.go new file mode 100644 index 0000000..cd62528 --- /dev/null +++ b/hotgo-server/app/consts/context_consts.go @@ -0,0 +1,12 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// 上下文 +const ( + ContextKey = "HotGoContext" +) diff --git a/hotgo-server/app/consts/debris_consts.go b/hotgo-server/app/consts/debris_consts.go new file mode 100644 index 0000000..44e5dc4 --- /dev/null +++ b/hotgo-server/app/consts/debris_consts.go @@ -0,0 +1,8 @@ +package consts + +// 碎片 +const ( + + // 默认分页 + DebrisPageSize = 10 +) diff --git a/hotgo-server/app/consts/error_consts.go b/hotgo-server/app/consts/error_consts.go new file mode 100644 index 0000000..a8ff338 --- /dev/null +++ b/hotgo-server/app/consts/error_consts.go @@ -0,0 +1,14 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// 错误解释 +const ( + ErrorORM = "sql执行异常" + ErrorNotData = "数据不存在" + ErrorRotaPointer = "指针转换异常" +) diff --git a/hotgo-server/app/consts/openapi_consts.go b/hotgo-server/app/consts/openapi_consts.go new file mode 100644 index 0000000..886dc49 --- /dev/null +++ b/hotgo-server/app/consts/openapi_consts.go @@ -0,0 +1,15 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// 开放API +const ( + OpenAPITitle = `HotGo` + OpenAPIDescription = `这是一个使用HotGo的简单演示HTTP服务器项目。 ` + OpenAPIName = `HotGo` + OpenAPIURL = `http://hotgo.bufanyun.cn` +) diff --git a/hotgo-server/app/consts/queue_consts.go b/hotgo-server/app/consts/queue_consts.go new file mode 100644 index 0000000..9a265b5 --- /dev/null +++ b/hotgo-server/app/consts/queue_consts.go @@ -0,0 +1,14 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// 消息队列 +const ( + QueueName = `queue:` + QueueLogPath = "queue" // 需要在config中配置queue的log + QueueLogTopic = `request-log` +) diff --git a/hotgo-server/app/consts/redis_consts.go b/hotgo-server/app/consts/redis_consts.go new file mode 100644 index 0000000..6586a68 --- /dev/null +++ b/hotgo-server/app/consts/redis_consts.go @@ -0,0 +1,13 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// redis +const ( + RedisJwtToken = "jwtToken:" // JWT-token + RedisJwtUserBind = "jwtUserBind:" // JWT-用户身份绑定 +) diff --git a/hotgo-server/app/consts/status_consts.go b/hotgo-server/app/consts/status_consts.go new file mode 100644 index 0000000..cdcaf22 --- /dev/null +++ b/hotgo-server/app/consts/status_consts.go @@ -0,0 +1,14 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// +const ( + StatusEnabled = "1" // 启用 + StatusDisable = "2" // 禁用 + StatusDelete = "3" //已删除 +) diff --git a/hotgo-server/app/consts/version_consts.go b/hotgo-server/app/consts/version_consts.go new file mode 100644 index 0000000..77eaf01 --- /dev/null +++ b/hotgo-server/app/consts/version_consts.go @@ -0,0 +1,12 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package consts + +// 应用版本 +const ( + VersionApp = "1.0.0" +) diff --git a/hotgo-server/app/controller/adminController/config_controller.go b/hotgo-server/app/controller/adminController/config_controller.go new file mode 100644 index 0000000..cb100ea --- /dev/null +++ b/hotgo-server/app/controller/adminController/config_controller.go @@ -0,0 +1,172 @@ +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/sysService" + "github.com/gogf/gf/v2/util/gconv" +) + +var Config = config{} + +type config struct{} + +// +// @Title 名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *config) GetValue(ctx context.Context, req *adminForm.ConfigGetValueReq) (*adminForm.ConfigGetValueRes, error) { + + data, err := sysService.Config.GetValue(ctx, input.SysConfigGetValueInp{Key: req.Key}) + if err != nil { + return nil, err + } + + var res adminForm.ConfigGetValueRes + res.Value = data.Value + return &res, nil +} + +// +// @Title 名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *config) NameUnique(ctx context.Context, req *adminForm.ConfigNameUniqueReq) (*adminForm.ConfigNameUniqueRes, error) { + + data, err := sysService.Config.NameUnique(ctx, input.SysConfigNameUniqueInp{Id: req.Id, Name: req.Name}) + if err != nil { + return nil, err + } + + var res adminForm.ConfigNameUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *config) Delete(ctx context.Context, req *adminForm.ConfigDeleteReq) (res *adminForm.ConfigDeleteRes, err error) { + var in input.SysConfigDeleteInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = sysService.Config.Delete(ctx, in); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *config) Edit(ctx context.Context, req *adminForm.ConfigEditReq) (res *adminForm.ConfigEditRes, err error) { + + var in input.SysConfigEditInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = sysService.Config.Edit(ctx, in); err != nil { + return nil, err + } + + return res, nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *config) MaxSort(ctx context.Context, req *adminForm.ConfigMaxSortReq) (*adminForm.ConfigMaxSortRes, error) { + + data, err := sysService.Config.MaxSort(ctx, input.SysConfigMaxSortInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.ConfigMaxSortRes + res.Sort = data.Sort + return &res, nil +} + +// +// @Title 获取指定信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *config) View(ctx context.Context, req *adminForm.ConfigViewReq) (*adminForm.ConfigViewRes, error) { + + data, err := sysService.Config.View(ctx, input.SysConfigViewInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.ConfigViewRes + res.SysConfigViewModel = data + return &res, nil +} + +// +// @Title 查看列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *config) List(ctx context.Context, req *adminForm.ConfigListReq) (*adminForm.ConfigListRes, error) { + + var ( + in input.SysConfigListInp + res adminForm.ConfigListRes + ) + + if err := gconv.Scan(req, &in); err != nil { + return nil, err + } + + list, totalCount, err := sysService.Config.List(ctx, in) + if err != nil { + return nil, err + } + + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} diff --git a/hotgo-server/app/controller/adminController/dept_controller.go b/hotgo-server/app/controller/adminController/dept_controller.go new file mode 100644 index 0000000..7f615be --- /dev/null +++ b/hotgo-server/app/controller/adminController/dept_controller.go @@ -0,0 +1,176 @@ +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/util/gconv" +) + +var Dept = dept{} + +type dept struct{} + +// +// @Title 名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dept) NameUnique(ctx context.Context, req *adminForm.DeptNameUniqueReq) (*adminForm.DeptNameUniqueRes, error) { + + data, err := adminService.Dept.NameUnique(ctx, input.AdminDeptNameUniqueInp{Id: req.Id, Name: req.Name}) + if err != nil { + return nil, err + } + + var res adminForm.DeptNameUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dept) Delete(ctx context.Context, req *adminForm.DeptDeleteReq) (res *adminForm.DeptDeleteRes, err error) { + var in input.AdminDeptDeleteInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Dept.Delete(ctx, in); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dept) Edit(ctx context.Context, req *adminForm.DeptEditReq) (res *adminForm.DeptEditRes, err error) { + + var in input.AdminDeptEditInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Dept.Edit(ctx, in); err != nil { + return nil, err + } + + return res, nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dept) MaxSort(ctx context.Context, req *adminForm.DeptMaxSortReq) (*adminForm.DeptMaxSortRes, error) { + + data, err := adminService.Dept.MaxSort(ctx, input.AdminDeptMaxSortInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.DeptMaxSortRes + res.Sort = data.Sort + return &res, nil +} + +// +// @Title 获取指定信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dept) View(ctx context.Context, req *adminForm.DeptViewReq) (*adminForm.DeptViewRes, error) { + + data, err := adminService.Dept.View(ctx, input.AdminDeptViewInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.DeptViewRes + res.AdminDeptViewModel = data + return &res, nil +} + +// +// @Title 查看列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dept) List(ctx context.Context, req *adminForm.DeptListReq) (*adminForm.DeptListRes, error) { + + var ( + in input.AdminDeptListInp + res adminForm.DeptListRes + ) + + if err := gconv.Scan(req, &in); err != nil { + return nil, err + } + data, err := adminService.Dept.List(ctx, in) + if err != nil { + return nil, err + } + + _ = gconv.Structs(data, &res) + + return &res, nil +} + +// +// @Title 查看列表树 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dept) ListTree(ctx context.Context, req *adminForm.DeptListTreeReq) (*adminForm.DeptListTreeRes, error) { + + var ( + in input.AdminDeptListTreeInp + res adminForm.DeptListTreeRes + ) + + if err := gconv.Scan(req, &in); err != nil { + return nil, err + } + data, err := adminService.Dept.ListTree(ctx, in) + if err != nil { + return nil, err + } + + _ = gconv.Structs(data, &res) + + return &res, nil +} diff --git a/hotgo-server/app/controller/adminController/dict_controller.go b/hotgo-server/app/controller/adminController/dict_controller.go new file mode 100644 index 0000000..cecf3f6 --- /dev/null +++ b/hotgo-server/app/controller/adminController/dict_controller.go @@ -0,0 +1,252 @@ +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/service/sysService" +) + +var Dict = dict{} + +type dict struct{} + +// +// @Title 数据键值是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) DataUnique(ctx context.Context, req *adminForm.DictDataUniqueReq) (res *adminForm.DictDataUniqueRes, err error) { + + res, err = sysService.Dict.DataUnique(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 查询字典数据最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) DataMaxSort(ctx context.Context, req *adminForm.DictDataMaxSortReq) (res *adminForm.DictDataMaxSortRes, err error) { + + res, err = sysService.Dict.DataMaxSort(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 删除字典数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) DataDelete(ctx context.Context, req *adminForm.DictDataDeleteReq) (res *adminForm.DictDataDeleteRes, err error) { + + if err = sysService.Dict.DataDelete(ctx, req); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增字典数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) DataEdit(ctx context.Context, req *adminForm.DictDataEditReq) (res *adminForm.DictDataEditRes, err error) { + + if err = sysService.Dict.DataEdit(ctx, req); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) DataView(ctx context.Context, req *adminForm.DictDataViewReq) (res *adminForm.DictDataViewRes, err error) { + + res, err = sysService.Dict.DataView(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 获取字典数据列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) DataList(ctx context.Context, req *adminForm.DictDataListReq) (res *adminForm.DictDataListRes, err error) { + + res, err = sysService.Dict.DataList(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 获取指定字典类型的属性数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) Attribute(ctx context.Context, req *adminForm.DictAttributeReq) (res *adminForm.DictAttributeRes, err error) { + + res, err = sysService.Dict.Attribute(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 导出字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) TypeExport(ctx context.Context, req *adminForm.DictTypeExportReq) (res *adminForm.DictTypeExportRes, err error) { + if err = sysService.Dict.TypeExport(ctx, req); err != nil { + return nil, err + } + return +} + +// +// @Title 刷新字典缓存 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) TypeRefreshCache(ctx context.Context, req *adminForm.DictTypeRefreshCacheReq) (res *adminForm.DictTypeRefreshCacheRes, err error) { + return nil, nil +} + +// +// @Title 删除字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) TypeDelete(ctx context.Context, req *adminForm.DictTypeDeleteReq) (res *adminForm.DictTypeDeleteRes, err error) { + + if err = sysService.Dict.TypeDelete(ctx, req); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) TypeEdit(ctx context.Context, req *adminForm.DictTypeEditReq) (res *adminForm.DictTypeEditRes, err error) { + + if err = sysService.Dict.TypeEdit(ctx, req); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 类型是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) TypeUnique(ctx context.Context, req *adminForm.DictTypeUniqueReq) (res *adminForm.DictTypeUniqueRes, err error) { + + res, err = sysService.Dict.TypeUnique(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) TypeView(ctx context.Context, req *adminForm.DictTypeViewReq) (res *adminForm.DictTypeViewRes, err error) { + + res, err = sysService.Dict.TypeView(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 获取字典类型列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) TypeList(ctx context.Context, req *adminForm.DictTypeListReq) (res *adminForm.DictTypeListRes, err error) { + + res, err = sysService.Dict.TypeList(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/hotgo-server/app/controller/adminController/log_controller.go b/hotgo-server/app/controller/adminController/log_controller.go new file mode 100644 index 0000000..b934841 --- /dev/null +++ b/hotgo-server/app/controller/adminController/log_controller.go @@ -0,0 +1,95 @@ +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/sysService" + "github.com/gogf/gf/v2/errors/gerror" +) + +var Log = log{} + +type log struct{} + +// +// @Title 清空日志 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *log) Clear(ctx context.Context, req *adminForm.LogClearReq) (res *adminForm.LogClearRes, err error) { + err = gerror.New("考虑安全,请到数据库清空") + return +} + +// +// @Title 导出 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *log) Export(ctx context.Context, req *adminForm.LogExportReq) (res *adminForm.LogExportRes, err error) { + + err = sysService.Log.Export(ctx, input.LogListInp{ + Page: req.Page, + Limit: req.Limit, + Module: req.Module, + Method: req.Method, + Url: req.Url, + Ip: req.Ip, + ErrorCode: req.ErrorCode, + StartTime: req.StartTime, + EndTime: req.EndTime, + MemberId: req.MemberId, + TakeUpTime: req.TakeUpTime, + }) + if err != nil { + return nil, err + } + + return +} + +// +// @Title 获取全局日志列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *log) List(ctx context.Context, req *adminForm.LogListReq) (*adminForm.LogListRes, error) { + + list, totalCount, err := sysService.Log.List(ctx, input.LogListInp{ + Page: req.Page, + Limit: req.Limit, + Module: req.Module, + Method: req.Method, + Url: req.Url, + Ip: req.Ip, + ErrorCode: req.ErrorCode, + StartTime: req.StartTime, + EndTime: req.EndTime, + MemberId: req.MemberId, + TakeUpTime: req.TakeUpTime, + }) + if err != nil { + return nil, err + } + + var res adminForm.LogListRes + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} diff --git a/hotgo-server/app/controller/adminController/login_controller.go b/hotgo-server/app/controller/adminController/login_controller.go new file mode 100644 index 0000000..b41a507 --- /dev/null +++ b/hotgo-server/app/controller/adminController/login_controller.go @@ -0,0 +1,104 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/util/gconv" +) + +var Login = login{} + +type login struct{} + +// +// @Title 登录验证码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *login) Captcha(ctx context.Context, req *adminForm.LoginCaptchaReq) (res *adminForm.LoginCaptchaRes, err error) { + + // TODO 获取生成的验证码图片 + Cid, Base64 := com.Captcha.GetVerifyImgString(ctx) + res = &adminForm.LoginCaptchaRes{Cid: Cid, Base64: Base64} + + return +} + +// +// @Title 提交登录 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *login) Sign(ctx context.Context, req *adminForm.LoginReq) (res *adminForm.LoginRes, err error) { + + //// 校验 验证码 + //if !com.Captcha.VerifyString(req.Cid, req.Code) { + // err = gerror.New("验证码错误") + // return + //} + + var in input.AdminMemberLoginSignInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + + model, err := adminService.Member.Login(ctx, in) + if err != nil { + return nil, err + } + + if err = gconv.Scan(model, &res); err != nil { + return nil, err + } + return +} + +// +// @Title 注销登录 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *login) Logout(ctx context.Context, req *adminForm.LoginLogoutReq) (res *adminForm.LoginLogoutRes, err error) { + + var authorization = com.Jwt.GetAuthorization(com.Context.Get(ctx).Request) + + // TODO 获取jwtToken + jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization) + if len(jwtToken) == 0 { + err = gerror.New("当前用户未登录!") + return res, err + } + + // TODO 删除登录token + cache := com.Cache.New() + _, err = cache.Remove(ctx, jwtToken) + if err != nil { + return res, err + } + + return +} diff --git a/hotgo-server/app/controller/adminController/member_controller.go b/hotgo-server/app/controller/adminController/member_controller.go new file mode 100644 index 0000000..b15b415 --- /dev/null +++ b/hotgo-server/app/controller/adminController/member_controller.go @@ -0,0 +1,371 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/util/gconv" +) + +var Member = member{} + +type member struct{} + +// +// @Title 修改登录密码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) UpdateProfile(ctx context.Context, req *adminForm.MemberUpdateProfileReq) (res *adminForm.MemberUpdateProfileRes, err error) { + + var in input.AdminMemberUpdateProfileInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + + if err = adminService.Member.UpdateProfile(ctx, in); err != nil { + return nil, err + } + + return +} + +// +// @Title 修改登录密码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) UpdatePwd(ctx context.Context, req *adminForm.MemberUpdatePwdReq) (res *adminForm.MemberUpdatePwdRes, err error) { + + memberId := com.Context.Get(ctx).User.Id + if memberId <= 0 { + err := gerror.New("获取用户信息失败!") + return nil, err + } + + if err = adminService.Member. + UpdatePwd(ctx, input.AdminMemberUpdatePwdInp{Id: memberId, OldPassword: req.OldPassword, NewPassword: req.NewPassword}); err != nil { + return nil, err + } + + return +} + +// +// @Title 获取登录用户的基本信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) Profile(ctx context.Context, req *adminForm.MemberProfileReq) (*adminForm.MemberProfileRes, error) { + + var res adminForm.MemberProfileRes + + memberId := com.Context.Get(ctx).User.Id + if memberId <= 0 { + err := gerror.New("获取用户信息失败!") + return nil, err + } + + // TODO 用户基本信息 + memberInfo, err := adminService.Member.View(ctx, input.AdminMemberViewInp{Id: memberId}) + if err != nil { + return nil, err + } + res.User = memberInfo + + // TODO 所在部门 + sysDept, err := adminService.Dept.View(ctx, input.AdminDeptViewInp{Id: memberInfo.DeptId}) + if err != nil { + return nil, err + } + res.SysDept = sysDept + + // TODO 角色列表 + sysRoles, err := adminService.Role.GetMemberList(ctx, memberInfo.Role) + if err != nil { + return nil, err + } + res.SysRoles = sysRoles + + // TODO 获取角色名称 + roleGroup, err := adminService.Role.GetName(ctx, memberInfo.Role) + if err != nil { + return nil, err + } + res.RoleGroup = roleGroup + + // TODO 获取第一岗位名称 + postGroup, err := adminService.Post.GetMemberByStartName(ctx, memberInfo.Id) + if err != nil { + return nil, err + } + res.PostGroup = postGroup + + return &res, nil +} + +// +// @Title 重置密码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) ResetPwd(ctx context.Context, req *adminForm.MemberResetPwdReq) (res *adminForm.MemberResetPwdRes, err error) { + + if err = adminService.Member. + ResetPwd(ctx, input.AdminMemberResetPwdInp{Id: req.Id, Password: req.Password}); err != nil { + return nil, err + } + + return +} + +// +// @Title 邮箱是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) EmailUnique(ctx context.Context, req *adminForm.MemberEmailUniqueReq) (*adminForm.MemberEmailUniqueRes, error) { + + data, err := adminService.Member.EmailUnique(ctx, input.AdminMemberEmailUniqueInp{Id: req.Id, Email: req.Email}) + if err != nil { + return nil, err + } + + var res adminForm.MemberEmailUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 手机号是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) MobileUnique(ctx context.Context, req *adminForm.MemberMobileUniqueReq) (*adminForm.MemberMobileUniqueRes, error) { + + data, err := adminService.Member.MobileUnique(ctx, input.AdminMemberMobileUniqueInp{Id: req.Id, Mobile: req.Mobile}) + if err != nil { + return nil, err + } + + var res adminForm.MemberMobileUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) NameUnique(ctx context.Context, req *adminForm.MemberNameUniqueReq) (*adminForm.MemberNameUniqueRes, error) { + + data, err := adminService.Member.NameUnique(ctx, input.AdminMemberNameUniqueInp{Id: req.Id, Username: req.Username}) + if err != nil { + return nil, err + } + + var res adminForm.MemberNameUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) Delete(ctx context.Context, req *adminForm.MemberDeleteReq) (res *adminForm.MemberDeleteRes, err error) { + + err = gerror.New("考虑安全暂时不允许删除用户,请选择禁用!") + return nil, err + + var in input.AdminMemberDeleteInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Member.Delete(ctx, in); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) Edit(ctx context.Context, req *adminForm.MemberEditReq) (res *adminForm.MemberEditRes, err error) { + + var in input.AdminMemberEditInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Member.Edit(ctx, in); err != nil { + return nil, err + } + + return res, nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) MaxSort(ctx context.Context, req *adminForm.MemberMaxSortReq) (*adminForm.MemberMaxSortRes, error) { + + data, err := adminService.Member.MaxSort(ctx, input.AdminMemberMaxSortInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.MemberMaxSortRes + res.Sort = data.Sort + return &res, nil +} + +// +// @Title 获取指定信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) View(ctx context.Context, req *adminForm.MemberViewReq) (*adminForm.MemberViewRes, error) { + + postsList, _, err := adminService.Post.List(ctx, input.AdminPostListInp{}) + if err != nil { + return nil, err + } + + roleList, _, err := adminService.Role.List(ctx, input.AdminRoleListInp{}) + if err != nil { + return nil, err + } + + var res adminForm.MemberViewRes + res.Posts = postsList + res.Roles = roleList + + if req.Id <= 0 { + return &res, err + } + + memberInfo, err := adminService.Member.View(ctx, input.AdminMemberViewInp{Id: req.Id}) + if err != nil { + return nil, err + } + + res.AdminMemberViewModel = memberInfo + + res.PostIds, err = adminService.MemberPost.GetMemberByIds(ctx, memberInfo.Id) + if err != nil { + return nil, err + } + + res.RoleIds = []int64{memberInfo.Role} + res.DeptName, err = adminService.Dept.GetName(ctx, memberInfo.DeptId) + if err != nil { + return nil, err + } + return &res, nil +} + +// +// @Title 查看列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) List(ctx context.Context, req *adminForm.MemberListReq) (*adminForm.MemberListRes, error) { + + var ( + in input.AdminMemberListInp + res adminForm.MemberListRes + ) + + if err := gconv.Scan(req, &in); err != nil { + return nil, err + } + + list, totalCount, err := adminService.Member.List(ctx, in) + if err != nil { + return nil, err + } + + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} + +// +// @Title 登录用户信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) Info(ctx context.Context, req *adminForm.MemberInfoReq) (res *adminForm.MemberInfoRes, err error) { + + return adminService.Member.LoginMemberInfo(ctx, req) +} diff --git a/hotgo-server/app/controller/adminController/menu_controller.go b/hotgo-server/app/controller/adminController/menu_controller.go new file mode 100644 index 0000000..84357bd --- /dev/null +++ b/hotgo-server/app/controller/adminController/menu_controller.go @@ -0,0 +1,188 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/util/gconv" +) + +var Menu = menu{} + +type menu struct{} + +// +// @Title 查询角色菜单列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) RoleList(ctx context.Context, req *adminForm.MenuRoleListReq) (*adminForm.MenuRoleListRes, error) { + + var in input.MenuRoleListInp + if err := gconv.Scan(req, &in); err != nil { + return nil, err + } + + data, err := adminService.Menu.RoleList(ctx, in) + if err != nil { + return nil, err + } + + var res adminForm.MenuRoleListRes + res.CheckedKeys = data.CheckedKeys + res.Menus = data.Menus + return &res, nil +} + +// +// @Title 查询菜单列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) SearchList(ctx context.Context, req *adminForm.MenuSearchListReq) (res *adminForm.MenuSearchListRes, err error) { + + res, err = adminService.Menu.SearchList(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) MaxSort(ctx context.Context, req *adminForm.MenuMaxSortReq) (res *adminForm.MenuMaxSortRes, err error) { + + res, err = adminService.Menu.MaxSort(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) NameUnique(ctx context.Context, req *adminForm.MenuNameUniqueReq) (res *adminForm.MenuNameUniqueRes, err error) { + + res, err = adminService.Menu.NameUnique(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 菜单编码是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) CodeUnique(ctx context.Context, req *adminForm.MenuCodeUniqueReq) (res *adminForm.MenuCodeUniqueRes, err error) { + + res, err = adminService.Menu.CodeUnique(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) Delete(ctx context.Context, req *adminForm.MenuDeleteReq) (res *adminForm.MenuDeleteRes, err error) { + + if err = adminService.Menu.Delete(ctx, req); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) Edit(ctx context.Context, req *adminForm.MenuEditReq) (res *adminForm.MenuEditRes, err error) { + + if err = adminService.Menu.Edit(ctx, req); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 获取信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) View(ctx context.Context, req *adminForm.MenuViewReq) (res *adminForm.MenuViewRes, err error) { + + res, err = adminService.Menu.View(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *menu) List(ctx context.Context, req *adminForm.MenuListReq) (res *adminForm.MenuListRes, err error) { + + res, err = adminService.Menu.List(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/hotgo-server/app/controller/adminController/notice_controller.go b/hotgo-server/app/controller/adminController/notice_controller.go new file mode 100644 index 0000000..36ab285 --- /dev/null +++ b/hotgo-server/app/controller/adminController/notice_controller.go @@ -0,0 +1,151 @@ +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/util/gconv" +) + +var Notice = notice{} + +type notice struct{} + +// +// @Title 名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *notice) NameUnique(ctx context.Context, req *adminForm.NoticeNameUniqueReq) (*adminForm.NoticeNameUniqueRes, error) { + + data, err := adminService.Notice.NameUnique(ctx, input.AdminNoticeNameUniqueInp{Id: req.Id, Title: req.Title}) + if err != nil { + return nil, err + } + + var res adminForm.NoticeNameUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *notice) Delete(ctx context.Context, req *adminForm.NoticeDeleteReq) (res *adminForm.NoticeDeleteRes, err error) { + var in input.AdminNoticeDeleteInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Notice.Delete(ctx, in); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *notice) Edit(ctx context.Context, req *adminForm.NoticeEditReq) (res *adminForm.NoticeEditRes, err error) { + + var in input.AdminNoticeEditInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Notice.Edit(ctx, in); err != nil { + return nil, err + } + + return res, nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *notice) MaxSort(ctx context.Context, req *adminForm.NoticeMaxSortReq) (*adminForm.NoticeMaxSortRes, error) { + + data, err := adminService.Notice.MaxSort(ctx, input.AdminNoticeMaxSortInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.NoticeMaxSortRes + res.Sort = data.Sort + return &res, nil +} + +// +// @Title 获取指定信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *notice) View(ctx context.Context, req *adminForm.NoticeViewReq) (*adminForm.NoticeViewRes, error) { + + data, err := adminService.Notice.View(ctx, input.AdminNoticeViewInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.NoticeViewRes + res.AdminNoticeViewModel = data + return &res, nil +} + +// +// @Title 查看列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *notice) List(ctx context.Context, req *adminForm.NoticeListReq) (*adminForm.NoticeListRes, error) { + + var ( + in input.AdminNoticeListInp + res adminForm.NoticeListRes + ) + + if err := gconv.Scan(req, &in); err != nil { + return nil, err + } + + list, totalCount, err := adminService.Notice.List(ctx, in) + if err != nil { + return nil, err + } + + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} diff --git a/hotgo-server/app/controller/adminController/post_controller.go b/hotgo-server/app/controller/adminController/post_controller.go new file mode 100644 index 0000000..c955910 --- /dev/null +++ b/hotgo-server/app/controller/adminController/post_controller.go @@ -0,0 +1,170 @@ +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/util/gconv" +) + +var Post = post{} + +type post struct{} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *post) Delete(ctx context.Context, req *adminForm.PostDeleteReq) (res *adminForm.PostDeleteRes, err error) { + var in input.AdminPostDeleteInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Post.Delete(ctx, in); err != nil { + return nil, err + } + return res, nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *post) Edit(ctx context.Context, req *adminForm.PostEditReq) (res *adminForm.PostEditRes, err error) { + + var in input.AdminPostEditInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + if err = adminService.Post.Edit(ctx, in); err != nil { + return nil, err + } + + return res, nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *post) MaxSort(ctx context.Context, req *adminForm.PostMaxSortReq) (*adminForm.PostMaxSortRes, error) { + + data, err := adminService.Post.MaxSort(ctx, input.AdminPostMaxSortInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.PostMaxSortRes + res.Sort = data.Sort + return &res, nil +} + +// +// @Title 名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *post) NameUnique(ctx context.Context, req *adminForm.PostNameUniqueReq) (*adminForm.PostNameUniqueRes, error) { + + data, err := adminService.Post.NameUnique(ctx, input.AdminPostNameUniqueInp{Id: req.Id, Name: req.Name}) + if err != nil { + return nil, err + } + + var res adminForm.PostNameUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 编码是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *post) CodeUnique(ctx context.Context, req *adminForm.PostCodeUniqueReq) (*adminForm.PostCodeUniqueRes, error) { + + data, err := adminService.Post.CodeUnique(ctx, input.AdminPostCodeUniqueInp{Id: req.Id, Code: req.Code}) + if err != nil { + return nil, err + } + + var res adminForm.PostCodeUniqueRes + res.IsUnique = data.IsUnique + return &res, nil +} + +// +// @Title 获取指定信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *post) View(ctx context.Context, req *adminForm.PostViewReq) (*adminForm.PostViewRes, error) { + + data, err := adminService.Post.View(ctx, input.AdminPostViewInp{Id: req.Id}) + if err != nil { + return nil, err + } + + var res adminForm.PostViewRes + res.AdminPostViewModel = data + return &res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *post) List(ctx context.Context, req *adminForm.PostListReq) (*adminForm.PostListRes, error) { + + list, totalCount, err := adminService.Post.List(ctx, input.AdminPostListInp{ + Page: req.Page, + Limit: req.Limit, + Name: req.Name, + Code: req.Code, + Status: req.Status, + }) + if err != nil { + return nil, err + } + + var res adminForm.PostListRes + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} diff --git a/hotgo-server/app/controller/adminController/role_controller.go b/hotgo-server/app/controller/adminController/role_controller.go new file mode 100644 index 0000000..16d59c5 --- /dev/null +++ b/hotgo-server/app/controller/adminController/role_controller.go @@ -0,0 +1,95 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminController + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/util/gconv" +) + +var Role = role{} + +type role struct{} + +// +// @Title 获取角色下的会员列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *role) RoleMemberList(ctx context.Context, req *adminForm.RoleMemberListReq) (*adminForm.RoleMemberListRes, error) { + + var in input.AdminRoleMemberListInp + if err := gconv.Scan(req, &in); err != nil { + return nil, err + } + list, totalCount, err := adminService.Member.RoleMemberList(ctx, in) + if err != nil { + return nil, err + } + + var res adminForm.RoleMemberListRes + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *role) List(ctx context.Context, req *adminForm.RoleListReq) (*adminForm.RoleListRes, error) { + + list, totalCount, err := adminService.Role.List(ctx, input.AdminRoleListInp{ + Page: req.Page, + Limit: req.Limit, + }) + if err != nil { + return nil, err + } + + var res adminForm.RoleListRes + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} + +// +// @Title 动态路由 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *role) Dynamic(ctx context.Context, req *adminForm.RoleDynamicReq) (res *adminForm.RoleDynamicRes, err error) { + + res, err = adminService.Menu.GetMenuList(ctx, com.Context.GetUserId(ctx)) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/hotgo-server/app/controller/apiController/base_controller.go b/hotgo-server/app/controller/apiController/base_controller.go new file mode 100644 index 0000000..77c7ad5 --- /dev/null +++ b/hotgo-server/app/controller/apiController/base_controller.go @@ -0,0 +1,95 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package apiController + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/apiForm" + "github.com/bufanyun/hotgo/app/model" + "github.com/gogf/gf/v2/frame/g" + "github.com/xuri/excelize/v2" + "time" +) + +var Base = base{} + +type base struct{} + +// +// @Title 获取lang信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *base) Lang(ctx context.Context, req *apiForm.BaseLangReq) (res *apiForm.BaseLangRes, err error) { + + return +} + +// +// @Title 获取IP归属地信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *base) IpLocation(ctx context.Context, req *apiForm.IpLocationReq) (res *apiForm.IpLocationRes, err error) { + + panic("测试panic...") + data := com.Ip.GetLocation(ctx, req.Ip) + res = &apiForm.IpLocationRes{data} + + return +} + +func (controller *base) Excel(ctx context.Context, req *apiForm.ExportReq) (res *apiForm.ExportRes, err error) { + w := com.Context.Get(ctx).Request.Response + + // 文件名 + fileName := "demo.xlsx" + // 创建excel文件 (第三方excel包) + file := excelize.NewFile() + // 填充数据 + index := file.NewSheet("Sheet1") + err = file.SetCellValue("Sheet1", "A1", "Hello world.") + if err != nil { + g.Log().Print(ctx, "SetCellValue:", err) + return nil, err + } + err = file.SetCellValue("Sheet1", "B1", 100) + if err != nil { + g.Log().Print(ctx, "SetCellValue2:", err) + return nil, err + } + file.SetActiveSheet(index) + // 设置header头 + w.Header().Add("Content-Disposition", "attachment; filename="+fileName) + w.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + // 写入字节数据 + err = file.Write(w.Writer) + if err != nil { + g.Log().Print(ctx, "Write:", err) + return nil, err + } + + // TODO 加入到上下文 + com.Context.SetResponse(ctx, &model.Response{ + Code: consts.CodeOK, + Message: "", + Timestamp: time.Now().Unix(), + ReqId: com.Context.Get(ctx).ReqId, + }) + //com.Context.Get(ctx).Request.Exit() + return +} diff --git a/hotgo-server/app/controller/apiController/dict_controller.go b/hotgo-server/app/controller/apiController/dict_controller.go new file mode 100644 index 0000000..7d22a59 --- /dev/null +++ b/hotgo-server/app/controller/apiController/dict_controller.go @@ -0,0 +1,29 @@ +package apiController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/service/sysService" +) + +var Dict = dict{} + +type dict struct{} + +// +// @Title 获取指定字典类型的属性数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *dict) Attribute(ctx context.Context, req *adminForm.DictAttributeReq) (res *adminForm.DictAttributeRes, err error) { + + res, err = sysService.Dict.Attribute(ctx, req) + if err != nil { + return nil, err + } + return res, nil +} diff --git a/hotgo-server/app/controller/apiController/log_controller.go b/hotgo-server/app/controller/apiController/log_controller.go new file mode 100644 index 0000000..685599e --- /dev/null +++ b/hotgo-server/app/controller/apiController/log_controller.go @@ -0,0 +1,95 @@ +package apiController + +import ( + "context" + "github.com/bufanyun/hotgo/app/form/apiForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/sysService" + "github.com/gogf/gf/v2/errors/gerror" +) + +var Log = log{} + +type log struct{} + +// +// @Title 清空日志 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *log) Clear(ctx context.Context, req *apiForm.LogClearReq) (res *apiForm.LogClearRes, err error) { + err = gerror.New("考虑安全,请到数据库清空") + return +} + +// +// @Title 导出 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *log) Export(ctx context.Context, req *apiForm.LogExportReq) (res *apiForm.LogExportRes, err error) { + + err = sysService.Log.Export(ctx, input.LogListInp{ + Page: req.Page, + Limit: req.Limit, + Module: req.Module, + Method: req.Method, + Url: req.Url, + Ip: req.Ip, + ErrorCode: req.ErrorCode, + StartTime: req.StartTime, + EndTime: req.EndTime, + MemberId: req.MemberId, + TakeUpTime: req.TakeUpTime, + }) + if err != nil { + return nil, err + } + + return +} + +// +// @Title 获取全局日志列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *log) List(ctx context.Context, req *apiForm.LogListReq) (*apiForm.LogListRes, error) { + + list, totalCount, err := sysService.Log.List(ctx, input.LogListInp{ + Page: req.Page, + Limit: req.Limit, + Module: req.Module, + Method: req.Method, + Url: req.Url, + Ip: req.Ip, + ErrorCode: req.ErrorCode, + StartTime: req.StartTime, + EndTime: req.EndTime, + MemberId: req.MemberId, + TakeUpTime: req.TakeUpTime, + }) + if err != nil { + return nil, err + } + + var res apiForm.LogListRes + res.List = list + res.TotalCount = totalCount + res.Limit = req.Page + res.Limit = req.Limit + + return &res, nil +} diff --git a/hotgo-server/app/controller/apiController/login_controller.go b/hotgo-server/app/controller/apiController/login_controller.go new file mode 100644 index 0000000..fc14477 --- /dev/null +++ b/hotgo-server/app/controller/apiController/login_controller.go @@ -0,0 +1,98 @@ +package apiController + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/apiForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/util/gconv" +) + +var Login = login{} + +type login struct{} + +// +// @Title 检查登录 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *login) Check(ctx context.Context, req *apiForm.LoginCheckReq) (*apiForm.LoginCheckRes, error) { + + var res apiForm.LoginCheckRes + res.IsValidCodeLogin = false + res.Result = "login" + + return &res, nil +} + +// +// @Title 提交登录 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *login) Sign(ctx context.Context, req *apiForm.LoginReq) (res *apiForm.LoginRes, err error) { + + //// 校验 验证码 + //if !com.Captcha.VerifyString(req.Cid, req.Code) { + // err = gerror.New("验证码错误") + // return + //} + + var in input.AdminMemberLoginSignInp + if err = gconv.Scan(req, &in); err != nil { + return nil, err + } + + model, err := adminService.Member.Login(ctx, in) + if err != nil { + return nil, err + } + + if err = gconv.Scan(model, &res); err != nil { + return nil, err + } + return +} + +// +// @Title 注销登录 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *login) Logout(ctx context.Context, req *apiForm.LoginLogoutReq) (res *apiForm.LoginLogoutRes, err error) { + + var authorization = com.Jwt.GetAuthorization(com.Context.Get(ctx).Request) + + // TODO 获取jwtToken + jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization) + if len(jwtToken) == 0 { + err = gerror.New("当前用户未登录!") + return res, err + } + + // TODO 删除登录token + cache := com.Cache.New() + _, err = cache.Remove(ctx, jwtToken) + if err != nil { + return res, err + } + + return +} diff --git a/hotgo-server/app/controller/apiController/member_controller.go b/hotgo-server/app/controller/apiController/member_controller.go new file mode 100644 index 0000000..e10ed47 --- /dev/null +++ b/hotgo-server/app/controller/apiController/member_controller.go @@ -0,0 +1,71 @@ +package apiController + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/form/apiForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/adminService" + "github.com/gogf/gf/v2/errors/gerror" +) + +var Member = member{} + +type member struct{} + +// +// @Title 获取登录用户的基本信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (controller *member) Profile(ctx context.Context, req *apiForm.MemberProfileReq) (*apiForm.MemberProfileRes, error) { + + var res apiForm.MemberProfileRes + + memberId := com.Context.Get(ctx).User.Id + if memberId <= 0 { + err := gerror.New("获取用户信息失败!") + return nil, err + } + + // TODO 用户基本信息 + memberInfo, err := adminService.Member.View(ctx, input.AdminMemberViewInp{Id: memberId}) + if err != nil { + return nil, err + } + res.User = memberInfo + + // TODO 所在部门 + sysDept, err := adminService.Dept.View(ctx, input.AdminDeptViewInp{Id: memberInfo.DeptId}) + if err != nil { + return nil, err + } + res.SysDept = sysDept + + // TODO 角色列表 + sysRoles, err := adminService.Role.GetMemberList(ctx, memberInfo.Role) + if err != nil { + return nil, err + } + res.SysRoles = sysRoles + + // TODO 获取角色名称 + roleGroup, err := adminService.Role.GetName(ctx, memberInfo.Role) + if err != nil { + return nil, err + } + res.RoleGroup = roleGroup + + // TODO 获取第一岗位名称 + postGroup, err := adminService.Post.GetMemberByStartName(ctx, memberInfo.Id) + if err != nil { + return nil, err + } + res.PostGroup = postGroup + + return &res, nil +} diff --git a/hotgo-server/app/factory/queue/kafkamq.go b/hotgo-server/app/factory/queue/kafkamq.go new file mode 100644 index 0000000..193af40 --- /dev/null +++ b/hotgo-server/app/factory/queue/kafkamq.go @@ -0,0 +1,246 @@ +package queue + +import ( + "context" + "fmt" + "github.com/Shopify/sarama" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/errors/gerror" + "sync" + "time" +) + +type KafkaMq struct { + endPoints []string + Partitions int32 + producerIns sarama.AsyncProducer + consumerIns sarama.ConsumerGroup +} + +type KafkaConfig struct { + ClientId string + Brokers []string + GroupID string + Partitions int32 + Replication int16 + Version string + UserName string + Password string +} + +var wg sync.WaitGroup + +// SendMsg 按字符串类型生产数据 +func (r *KafkaMq) SendMsg(topic string, body string) (mqMsg MqMsg, err error) { + return r.SendByteMsg(topic, []byte(body)) +} + +// SendByteMsg 生产数据 +func (r *KafkaMq) SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error) { + msg := &sarama.ProducerMessage{ + Topic: topic, + Value: sarama.ByteEncoder(body), + Timestamp: time.Now(), + } + + if r.producerIns == nil { + return mqMsg, gerror.New("queue kafka producerIns is nil") + } + + r.producerIns.Input() <- msg + ctx, cancle := context.WithTimeout(context.Background(), 5*time.Second) + defer cancle() + + select { + case info := <-r.producerIns.Successes(): + return MqMsg{ + RunType: SendMsg, + Topic: info.Topic, + Offset: info.Offset, + Partition: info.Partition, + Timestamp: info.Timestamp, + }, nil + case fail := <-r.producerIns.Errors(): + if nil != fail { + return mqMsg, fail.Err + } + case <-ctx.Done(): + return mqMsg, gerror.New("send mqMst timeout") + } + + return mqMsg, nil +} + +// ListenReceiveMsgDo 消费数据 +func (r *KafkaMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error) { + if r.consumerIns == nil { + return gerror.New("queue kafka consumer not register") + } + + consumer := Consumer{ + ready: make(chan bool), + receiveDoFun: receiveDo, + } + + ctx, cancel := context.WithCancel(context.Background()) + + go func() { + + for { + if err := r.consumerIns.Consume(ctx, []string{topic}, &consumer); err != nil { + FatalLog(ctx, "kafka Error from consumer", err) + } + + if ctx.Err() != nil { + Log(ctx, fmt.Sprint("kafka consoumer stop : %v", ctx.Err())) + return + } + consumer.ready = make(chan bool) + } + }() + + <-consumer.ready // Await till the consumer has been set up + Log(ctx, "kafka consumer up and running!...") + + utils.Signal.AppDefer(func() { + Log(ctx, "kafka consumer close...") + cancel() + if err = r.consumerIns.Close(); err != nil { + FatalLog(ctx, "kafka Error closing client", err) + } + }) + + return +} + +// RegisterRedisMqConsumerMust 注册消费者 +func RegisterKafkaMqConsumerMust(connOpt KafkaConfig) (client MqConsumer) { + mqIns := &KafkaMq{} + + kfkVersion, _ := sarama.ParseKafkaVersion(connOpt.Version) + if validateVersion(kfkVersion) == false { + kfkVersion = sarama.V2_4_0_0 + } + + brokers := connOpt.Brokers + config := sarama.NewConfig() + config.Consumer.Return.Errors = true + config.Version = kfkVersion + if connOpt.UserName != "" { + config.Net.SASL.Enable = true + config.Net.SASL.User = connOpt.UserName + config.Net.SASL.Password = connOpt.Password + } + + // 默认按随机方式消费 + config.Consumer.Group.Rebalance.Strategy = sarama.BalanceStrategyRange + config.Consumer.Offsets.Initial = sarama.OffsetNewest + config.Consumer.Offsets.AutoCommit.Interval = 10 * time.Millisecond + config.ClientID = connOpt.ClientId + + consumerClient, err := sarama.NewConsumerGroup(brokers, connOpt.GroupID, config) + if err != nil { + panic(err) + } + mqIns.consumerIns = consumerClient + return mqIns +} + +// RegisterKafkaProducerMust 注册并启动生产者接口实现 +func RegisterKafkaProducerMust(connOpt KafkaConfig) (client MqProducer) { + mqIns := &KafkaMq{} + + connOpt.ClientId = "HOTGO-Producer" + RegisterKafkaProducer(connOpt, mqIns) //这里如果使用go程需要处理chan同步问题 + + return mqIns +} + +// RegisterKafkaProducerAsync 注册同步类型实例 +func RegisterKafkaProducer(connOpt KafkaConfig, mqIns *KafkaMq) { + kfkVersion, _ := sarama.ParseKafkaVersion(connOpt.Version) + if validateVersion(kfkVersion) == false { + kfkVersion = sarama.V2_4_0_0 + } + + brokers := connOpt.Brokers + config := sarama.NewConfig() + // 等待服务器所有副本都保存成功后的响应 + config.Producer.RequiredAcks = sarama.WaitForAll + // 随机向partition发送消息 + config.Producer.Partitioner = sarama.NewRandomPartitioner + // 是否等待成功和失败后的响应,只有上面的RequireAcks设置不是NoReponse这里才有用. + config.Producer.Return.Successes = true + + config.Producer.Return.Errors = true + config.Producer.Compression = sarama.CompressionNone + config.ClientID = connOpt.ClientId + + config.Version = kfkVersion + if connOpt.UserName != "" { + config.Net.SASL.Enable = true + config.Net.SASL.User = connOpt.UserName + config.Net.SASL.Password = connOpt.Password + } + + var err error + mqIns.producerIns, err = sarama.NewAsyncProducer(brokers, config) + if err != nil { + panic(err) + } + + utils.Signal.AppDefer(func() { + Log(ctx, "kafka producer AsyncClose...") + mqIns.producerIns.AsyncClose() + }) +} + +// validateVersion 验证版本是否有效 +func validateVersion(version sarama.KafkaVersion) bool { + for _, item := range sarama.SupportedVersions { + if version.String() == item.String() { + return true + } + } + return false +} + +type Consumer struct { + ready chan bool + receiveDoFun func(mqMsg MqMsg) +} + +// Setup is run at the beginning of a new session, before ConsumeClaim +func (consumer *Consumer) Setup(sarama.ConsumerGroupSession) error { + // Mark the consumer as ready + close(consumer.ready) + return nil +} + +// Cleanup is run at the end of a session, once all ConsumeClaim goroutines have exited +func (consumer *Consumer) Cleanup(sarama.ConsumerGroupSession) error { + return nil +} + +// ConsumeClaim must start a consumer loop of ConsumerGroupClaim's Messages(). +func (consumer *Consumer) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { + + // NOTE: + // Do not move the code below to a goroutine. + // The `ConsumeClaim` itself is called within a goroutine, see: + // https://github.com/Shopify/sarama/blob/master/consumer_group.go#L27-L29 + // `ConsumeClaim` 方法已经是 goroutine 调用 不要在该方法内进行 goroutine + for message := range claim.Messages() { + consumer.receiveDoFun(MqMsg{ + RunType: ReceiveMsg, + Topic: message.Topic, + Body: message.Value, + Offset: message.Offset, + Timestamp: message.Timestamp, + Partition: message.Partition, + }) + session.MarkMessage(message, "") + } + + return nil +} diff --git a/hotgo-server/app/factory/queue/list.go b/hotgo-server/app/factory/queue/list.go new file mode 100644 index 0000000..898a25e --- /dev/null +++ b/hotgo-server/app/factory/queue/list.go @@ -0,0 +1,63 @@ +package queue + +import ( + "container/list" + "sync" +) + +type Queue struct { + l *list.List + m sync.Mutex +} + +func NewQueue() *Queue { + return &Queue{l: list.New()} +} + +func (q *Queue) LPush(v interface{}) { + if v == nil { + return + } + q.m.Lock() + defer q.m.Unlock() + q.l.PushFront(v) +} + +func (q *Queue) RPush(v interface{}) { + if v == nil { + return + } + q.m.Lock() + defer q.m.Unlock() + q.l.PushBack(v) +} + +func (q *Queue) LPop() interface{} { + q.m.Lock() + defer q.m.Unlock() + + element := q.l.Front() + if element == nil { + return nil + } + + q.l.Remove(element) + return element.Value +} + +func (q *Queue) RPop() interface{} { + q.m.Lock() + defer q.m.Unlock() + + element := q.l.Back() + if element == nil { + return nil + } + + q.l.Remove(element) + return element.Value +} + +func (q *Queue) Len() int { + return q.l.Len() +} diff --git a/hotgo-server/app/factory/queue/logger.go b/hotgo-server/app/factory/queue/logger.go new file mode 100644 index 0000000..1f61a76 --- /dev/null +++ b/hotgo-server/app/factory/queue/logger.go @@ -0,0 +1,39 @@ +package queue + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" +) + + +// 消费日志 +func ConsumerLog(ctx context.Context, topic string, mqMsg MqMsg, err error) { + + if err != nil { + g.Log(consts.QueueLogPath).Error(ctx, "消费 ["+topic+"] 失败", mqMsg, err) + } else { + g.Log(consts.QueueLogPath).Print(ctx, "消费 ["+topic+"] 成功", mqMsg.MsgId) + } +} + +// 生产日志 +func ProducerLog(ctx context.Context, topic string, data interface{}, err error) { + + if err != nil { + g.Log(consts.QueueLogPath).Error(ctx, "生产 ["+topic+"] 失败", gconv.String(data)) + } else { + g.Log(consts.QueueLogPath).Print(ctx, "生产 ["+topic+"] 成功", gconv.String(data)) + } +} + +// 致命日志 +func FatalLog(ctx context.Context, text string, err error) { + g.Log(consts.QueueLogPath).Fatal(ctx, text+":", err) +} + +// 通用 +func Log(ctx context.Context, text string) { + g.Log(consts.QueueLogPath).Print(ctx, text) +} diff --git a/hotgo-server/app/factory/queue/main.go b/hotgo-server/app/factory/queue/main.go new file mode 100644 index 0000000..db241c2 --- /dev/null +++ b/hotgo-server/app/factory/queue/main.go @@ -0,0 +1,248 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package queue + +import ( + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + "sync" + "time" +) + +// +// MqProducer +// @Description +// +type MqProducer interface { + SendMsg(topic string, body string) (mqMsg MqMsg, err error) + SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error) +} + +// +// MqConsumer +// @Description +// +type MqConsumer interface { + ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error) +} + +const ( + _ = iota + SendMsg + ReceiveMsg +) + +type MqMsg struct { + RunType int `json:"run_type"` + Topic string `json:"topic"` + MsgId string `json:"msg_id"` + Offset int64 `json:"offset"` + Partition int32 `json:"partition"` + Timestamp time.Time `json:"timestamp"` + + Body []byte `json:"body"` +} + +var ( + ctx = gctx.New() + mqProducerInstanceMap map[string]MqProducer + mqConsumerInstanceMap map[string]MqConsumer + mutex sync.Mutex +) + +func init() { + mqProducerInstanceMap = make(map[string]MqProducer) + mqConsumerInstanceMap = make(map[string]MqConsumer) +} + +// +// @Title 实例化消费者 +// @Description +// @Author Ms <133814250@qq.com> +// @Return mqClient +// @Return err +// +func InstanceConsumer() (mqClient MqConsumer, err error) { + groupName, _ := g.Cfg().Get(ctx, "queue.groupName", "hotgo") + return NewConsumer(groupName.String()) +} + +// +// @Title 实例化生产者 +// @Description +// @Author Ms <133814250@qq.com> +// @Return mqClient +// @Return err +// +func InstanceProducer() (mqClient MqProducer, err error) { + groupName, _ := g.Cfg().Get(ctx, "queue.groupName", "hotgo") + return NewProducer(groupName.String()) +} + +// +// @Title 新建一个生产者实例 +// @Description +// @Author Ms <133814250@qq.com> +// @Param groupName +// @Return mqClient +// @Return err +// +func NewProducer(groupName string) (mqClient MqProducer, err error) { + if item, ok := mqProducerInstanceMap[groupName]; ok { + return item, nil + } + + if groupName == "" { + return mqClient, gerror.New("mq groupName is empty.") + } + + // 驱动 + driver, _ := g.Cfg().Get(ctx, "queue.driver", "") + + // 重试次数 + retryCount, _ := g.Cfg().Get(ctx, "queue.retry", 2) + retry := retryCount.Int() + + switch driver.String() { + case "rocketmq": + address, _ := g.Cfg().Get(ctx, "queue.rocketmq.address", nil) + if len(address.Strings()) == 0 { + panic("queue rocketmq address is not support") + } + mqClient = RegisterRocketProducerMust(address.Strings(), groupName, retry) + case "kafka": + address, _ := g.Cfg().Get(ctx, "queue.kafka.address", nil) + if len(address.Strings()) == 0 { + panic("queue kafka address is not support") + } + version, _ := g.Cfg().Get(ctx, "queue.kafka.version", "2.0.0") + mqClient = RegisterKafkaProducerMust(KafkaConfig{ + Brokers: address.Strings(), + GroupID: groupName, + Version: version.String(), + }) + case "redis": + address, _ := g.Cfg().Get(ctx, "queue.redis.address", nil) + if len(address.String()) == 0 { + panic("queue redis address is not support") + } + db, _ := g.Cfg().Get(ctx, "queue.redis.db", 0) + pass, _ := g.Cfg().Get(ctx, "queue.redis.pass", "") + timeout, _ := g.Cfg().Get(ctx, "queue.redis.timeout", 0) + + mqClient = RegisterRedisMqProducerMust(RedisOption{ + Addr: address.String(), + Passwd: pass.String(), + DBnum: db.Int(), + Timeout: timeout.Int(), + }, PoolOption{ + 5, 50, 5, + }, groupName, retry) + + default: + panic("queue driver is not support") + } + + mutex.Lock() + defer mutex.Unlock() + mqProducerInstanceMap[groupName] = mqClient + + return mqClient, nil +} + +// +// @Title 新建一个消费者实例 +// @Description +// @Author Ms <133814250@qq.com> +// @Param groupName +// @Return mqClient +// @Return err +// +func NewConsumer(groupName string) (mqClient MqConsumer, err error) { + // 是否支持创建多个消费者 + multiComsumer, _ := g.Cfg().Get(ctx, "queue.multiComsumer", true) + randTag := string(utils.Charset.RandomCreateBytes(6)) + if multiComsumer.Bool() == false { + randTag = "001" + } + + if item, ok := mqConsumerInstanceMap[groupName+"-"+randTag]; ok { + return item, nil + } + + driver, _ := g.Cfg().Get(ctx, "queue.driver", "") + + if groupName == "" { + return mqClient, gerror.New("mq groupName is empty.") + } + + switch driver.String() { + case "rocketmq": + address, _ := g.Cfg().Get(ctx, "queue.rocketmq.address", nil) + if address == nil { + return nil, gerror.New("queue.rocketmq.address is empty.") + } + + mqClient = RegisterRocketConsumerMust(address.Strings(), groupName) + case "kafka": + address, _ := g.Cfg().Get(ctx, "queue.kafka.address", nil) + if len(address.Strings()) == 0 { + panic("queue kafka address is not support") + } + version, _ := g.Cfg().Get(ctx, "queue.kafka.version", "2.0.0") + + clientId := "HOTGO-Consumer-" + groupName + randClient, _ := g.Cfg().Get(ctx, "queue.kafka.randClient", true) + if randClient.Bool() { + clientId += "-" + randTag + } + + mqClient = RegisterKafkaMqConsumerMust(KafkaConfig{ + Brokers: address.Strings(), + GroupID: groupName, + Version: version.String(), + ClientId: clientId, + }) + case "redis": + address, _ := g.Cfg().Get(ctx, "queue.redis.address", nil) + if len(address.String()) == 0 { + panic("queue redis address is not support") + } + db, _ := g.Cfg().Get(ctx, "queue.redis.db", 0) + pass, _ := g.Cfg().Get(ctx, "queue.redis.pass", "") + timeout, _ := g.Cfg().Get(ctx, "queue.redis.pass", 0) + + mqClient = RegisterRedisMqConsumerMust(RedisOption{ + Addr: address.String(), + Passwd: pass.String(), + DBnum: db.Int(), + Timeout: timeout.Int(), + }, PoolOption{ + 5, 50, 5, + }, groupName) + default: + panic("queue driver is not support") + } + + mutex.Lock() + defer mutex.Unlock() + mqConsumerInstanceMap[groupName] = mqClient + + return mqClient, nil +} + +// +// @Title 返回消息体 +// @Description +// @Author Ms <133814250@qq.com> +// @Return string +// +func (m *MqMsg) BodyString() string { + return string(m.Body) +} diff --git a/hotgo-server/app/factory/queue/queue_test.go b/hotgo-server/app/factory/queue/queue_test.go new file mode 100644 index 0000000..432eebf --- /dev/null +++ b/hotgo-server/app/factory/queue/queue_test.go @@ -0,0 +1,133 @@ +package queue + +import ( + "fmt" + "testing" + "time" +) + +func TestRPushQueue(t *testing.T) { + + ll := NewQueue() + + ll.RPush("1") + ll.RPush("2") + ll.RPush("3") + + go func() { + ll.RPush("4") + }() + go func() { + ll.RPush("5") + }() + + go func() { + ll.RPush("6") + }() + + time.Sleep(1 * time.Second) + + if ll.Len() != 6 { + t.Error("list Len() do error #1") + } + + listVal := fmt.Sprintf("num=>%v,%v,%v", ll.LPop(), ll.LPop(), ll.LPop()) + if listVal != "num=>1,2,3" { + t.Error("list do error #2") + } + + if ll.Len() != 3 { + t.Error("list Len() do error #3") + } + + ll.LPop() + ll.LPop() + ll.LPop() + c := ll.LPop() + + if c != nil { + t.Error("list LPop() do error #4") + } + + time.Sleep(1 * time.Second) +} + +func TestLPushQueue(t *testing.T) { + + ll := NewQueue() + + ll.LPush("1") + ll.LPush("2") + ll.LPush("3") + + go func() { + ll.LPush("4") + }() + go func() { + ll.LPush("5") + }() + + go func() { + ll.LPush("6") + }() + + time.Sleep(1 * time.Second) + + if ll.Len() != 6 { + t.Error("list Len() do error #1") + } + + listVal := fmt.Sprintf("num=>%v,%v,%v", ll.RPop(), ll.RPop(), ll.RPop()) + if listVal != "num=>1,2,3" { + t.Error("list do error #2") + } + + if ll.Len() != 3 { + t.Error("list Len() do error #3") + } + + ll.RPop() + ll.RPop() + ll.RPop() + c := ll.RPop() + + if c != nil { + t.Error("list RPop() do error #4") + } + + time.Sleep(1 * time.Second) +} + +func TestRegisterRocketMqProducer(t *testing.T) { + ins, err := RegisterRocketMqProducer([]string{}, "tests", 2) + if err == nil { + t.Error("RegisterRocketMqProducer err #1") + } + + ins, err = RegisterRocketMqProducer([]string{"192.168.1.1:9876"}, "tests", 2) + if err != nil { + t.Error("RegisterRocketMqProducer err #2") + } + + if ins.endPoints[0] != "192.168.1.1:9876" { + t.Error("RegisterRocketMqProducer err #3") + } + +} + +func TestRegisterRocketMqConsumer(t *testing.T) { + ins, err := RegisterRocketMqConsumer([]string{}, "tests") + if err == nil { + t.Error("RegisterRocketMqConsumer err #1") + } + + ins, err = RegisterRocketMqProducer([]string{"192.168.1.1:9876"}, "tests", 2) + if err != nil { + t.Error("RegisterRocketMqConsumer err #2") + } + + if ins.endPoints[0] != "192.168.1.1:9876" { + t.Error("RegisterRocketMqConsumer err #3") + } + +} diff --git a/hotgo-server/app/factory/queue/redismq.go b/hotgo-server/app/factory/queue/redismq.go new file mode 100644 index 0000000..132d75e --- /dev/null +++ b/hotgo-server/app/factory/queue/redismq.go @@ -0,0 +1,284 @@ +package queue + +import ( + "encoding/json" + "fmt" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/utils" + "github.com/bufanyun/pool" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gomodule/redigo/redis" + "math/rand" + "time" +) + +type RedisMq struct { + poolName string + groupName string + retry int + timeout int +} + +type PoolOption struct { + InitCap int + MaxCap int + IdleTimeout int +} + +type RedisOption struct { + Addr string + Passwd string + DBnum int + Timeout int +} + +var redisPoolMap map[string]pool.Pool + +func init() { + redisPoolMap = make(map[string]pool.Pool) + +} + +// SendMsg 按字符串类型生产数据 +func (r *RedisMq) SendMsg(topic string, body string) (mqMsg MqMsg, err error) { + return r.SendByteMsg(topic, []byte(body)) +} + +// SendByteMsg 生产数据 +func (r *RedisMq) SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error) { + if r.poolName == "" { + return mqMsg, gerror.New("RedisMq producer not register") + } + if topic == "" { + return mqMsg, gerror.New("RedisMq topic is empty") + } + + msgId := getRandMsgId() + rdx, put, err := getRedis(r.poolName, r.retry) + defer put() + + if err != nil { + return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者获取redis实例失败:", err)) + } + + mqMsg = MqMsg{ + RunType: SendMsg, + Topic: topic, + MsgId: msgId, + Body: body, + } + mqMsgJson, err := json.Marshal(mqMsg) + if err != nil { + return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者解析json消息失败:", err)) + } + + queueName := r.genQueueName(r.groupName, topic) + + _, err = redis.Int64(rdx.Do("LPUSH", queueName, mqMsgJson)) + if err != nil { + return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者添加消息失败:", err)) + } + + if r.timeout > 0 { + _, err = rdx.Do("EXPIRE", queueName, r.timeout) + if err != nil { + return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者设置过期时间失败:", err)) + } + } + return +} + +// ListenReceiveMsgDo 消费数据 +func (r *RedisMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error) { + if r.poolName == "" { + return gerror.New("RedisMq producer not register") + } + if topic == "" { + return gerror.New("RedisMq topic is empty") + } + + queueName := r.genQueueName(r.groupName, topic) + + go func() { + for range time.Tick(1000 * time.Millisecond) { + mqMsgList := r.loopReadQueue(queueName) + for _, mqMsg := range mqMsgList { + receiveDo(mqMsg) + } + } + }() + + return +} + +// 生成队列名称 +func (r *RedisMq) genQueueName(groupName string, topic string) string { + return fmt.Sprintf(consts.QueueName+"%s-%s", groupName, topic) +} + +func (r *RedisMq) loopReadQueue(queueName string) (mqMsgList []MqMsg) { + rdx, put, err := getRedis(r.poolName, r.retry) + defer put() + if err != nil { + return + } + + for { + infoByte, err := redis.Bytes(rdx.Do("RPOP", queueName)) + if err != nil || len(infoByte) == 0 { + break + } + var mqMsg MqMsg + json.Unmarshal(infoByte, &mqMsg) + if mqMsg.MsgId != "" { + mqMsgList = append(mqMsgList, mqMsg) + } + + } + return mqMsgList +} + +func RegisterRedisMqProducerMust(connOpt RedisOption, poolOpt PoolOption, groupName string, retry int) (client MqProducer) { + var err error + client, err = RegisterRedisMq(connOpt, poolOpt, groupName, retry) + if err != nil { + panic(err) + } + return client +} + +// RegisterRedisMqConsumerMust 注册消费者 +func RegisterRedisMqConsumerMust(connOpt RedisOption, poolOpt PoolOption, groupName string) (client MqConsumer) { + var err error + client, err = RegisterRedisMq(connOpt, poolOpt, groupName, 0) + if err != nil { + panic(err) + } + return client +} + +// RegisterRedisMq 注册redismq实例 +func RegisterRedisMq(connOpt RedisOption, poolOpt PoolOption, groupName string, retry int) (mqIns *RedisMq, err error) { + poolName, err := registerRedis(connOpt.Addr, connOpt.Passwd, connOpt.DBnum, poolOpt) + if err != nil { + return + } + + if retry <= 0 { + retry = 0 + } + + mqIns = &RedisMq{ + poolName: poolName, + groupName: groupName, + retry: retry, + timeout: connOpt.Timeout, + } + + return mqIns, nil +} + +// RegisterRedis 注册一个redis配置 +func registerRedis(host, pass string, dbnum int, opt PoolOption) (poolName string, err error) { + poolName = utils.Charset.Md5ToString(fmt.Sprintf("%s-%s-%d", host, pass, dbnum)) + if _, ok := redisPoolMap[poolName]; ok { + return poolName, nil + } + + connRedis := func() (interface{}, error) { + conn, err := redis.Dial("tcp", host) + if err != nil { + return nil, err + } + if pass != "" { + _, err := conn.Do("AUTH", pass) + if err != nil { + return nil, err + } + } + if dbnum > 0 { + _, err := conn.Do("SELECT", dbnum) + if err != nil { + return nil, err + } + } + return conn, err + } + + // closeRedis 关闭连接 + closeRedis := func(v interface{}) error { + return v.(redis.Conn).Close() + } + + // pingRedis 检测连接连通性 + pingRedis := func(v interface{}) error { + conn := v.(redis.Conn) + + val, err := redis.String(conn.Do("PING")) + + if err != nil { + return err + } + if val != "PONG" { + return gerror.New("queue redis ping is error ping => " + val) + } + + return nil + } + + p, err := pool.NewChannelPool(&pool.Config{ + InitialCap: opt.InitCap, + MaxCap: opt.MaxCap, + Factory: connRedis, + Close: closeRedis, + Ping: pingRedis, + IdleTimeout: time.Duration(opt.IdleTimeout) * time.Second, + }) + + if err != nil { + return poolName, err + } + + mutex.Lock() + defer mutex.Unlock() + redisPoolMap[poolName] = p + + return poolName, nil +} + +// getRedis 获取一个redis db连接 +func getRedis(poolName string, retry int) (db redis.Conn, put func(), err error) { + put = func() {} + if _, ok := redisPoolMap[poolName]; ok == false { + return nil, put, gerror.New("db connect is nil") + } + redisPool := redisPoolMap[poolName] + + conn, err := redisPool.Get() + for i := 0; i < retry; i++ { + if err == nil { + break + } + conn, err = redisPool.Get() + time.Sleep(time.Second) + } + + if err != nil { + return nil, put, err + } + put = func() { + redisPool.Put(conn) + } + + db = conn.(redis.Conn) + return db, put, nil +} + +func getRandMsgId() (msgId string) { + rand.Seed(time.Now().UnixNano()) + radium := rand.Intn(999) + 1 + timeCode := time.Now().UnixNano() + + msgId = fmt.Sprintf("%d%.4d", timeCode, radium) + return msgId +} diff --git a/hotgo-server/app/factory/queue/rocketmq.go b/hotgo-server/app/factory/queue/rocketmq.go new file mode 100644 index 0000000..e278823 --- /dev/null +++ b/hotgo-server/app/factory/queue/rocketmq.go @@ -0,0 +1,165 @@ +package queue + +import ( + "context" + "errors" + "fmt" + "github.com/apache/rocketmq-client-go/v2" + "github.com/apache/rocketmq-client-go/v2/consumer" + "github.com/apache/rocketmq-client-go/v2/primitive" + "github.com/apache/rocketmq-client-go/v2/producer" + "github.com/apache/rocketmq-client-go/v2/rlog" + "github.com/gogf/gf/v2/frame/g" +) + +type RocketMq struct { + endPoints []string + producerIns rocketmq.Producer + consumerIns rocketmq.PushConsumer +} + +// 重写日志 +func rewriteLog() { + level, _ := g.Cfg().Get(ctx, "queue.rocketmq.logLevel", "debug") + rlog.SetLogger(&RocketMqLogger{Flag: "[rocket_mq]", LevelLog: level.String()}) +} + +// RegisterRocketProducerMust 注册并启动生产者接口实现 +func RegisterRocketProducerMust(endPoints []string, groupName string, retry int) (client MqProducer) { + rewriteLog() + var err error + client, err = RegisterRocketMqProducer(endPoints, groupName, retry) + if err != nil { + panic(err) + } + return client +} + +// RegisterRocketConsumerMust 注册消费者 +func RegisterRocketConsumerMust(endPoints []string, groupName string) (client MqConsumer) { + rewriteLog() + var err error + client, err = RegisterRocketMqConsumer(endPoints, groupName) + if err != nil { + panic(err) + } + return client +} + +// SendMsg 按字符串类型生产数据 +func (r *RocketMq) SendMsg(topic string, body string) (mqMsg MqMsg, err error) { + return r.SendByteMsg(topic, []byte(body)) +} + +// SendByteMsg 生产数据 +func (r *RocketMq) SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error) { + if r.producerIns == nil { + return mqMsg, errors.New("RocketMq producer not register") + } + + result, err := r.producerIns.SendSync(context.Background(), &primitive.Message{ + Topic: topic, + Body: body, + }) + + if err != nil { + return + } + if result.Status != primitive.SendOK { + return mqMsg, errors.New(fmt.Sprintf("RocketMq producer send msg error status:%v", result.Status)) + } + + mqMsg = MqMsg{ + RunType: SendMsg, + Topic: topic, + MsgId: result.MsgID, + Body: body, + } + return mqMsg, nil +} + +// ListenReceiveMsgDo 消费数据 +func (r *RocketMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error) { + if r.consumerIns == nil { + return errors.New("RocketMq consumer not register") + } + + err = r.consumerIns.Subscribe(topic, consumer.MessageSelector{}, func(ctx context.Context, + msgs ...*primitive.MessageExt) (consumer.ConsumeResult, error) { + for _, item := range msgs { + go receiveDo(MqMsg{ + RunType: ReceiveMsg, + Topic: item.Topic, + MsgId: item.MsgId, + Body: item.Body, + }) + } + return consumer.ConsumeSuccess, nil + }) + + if err != nil { + return err + } + + err = r.consumerIns.Start() + if err != nil { + r.consumerIns.Unsubscribe(topic) + return err + } + + return +} + +// RegisterRocketMqProducer 注册rocketmq生产者 +func RegisterRocketMqProducer(endPoints []string, groupName string, retry int) (mqIns *RocketMq, err error) { + addr, err := primitive.NewNamesrvAddr(endPoints...) + if err != nil { + return nil, err + } + mqIns = &RocketMq{ + endPoints: endPoints, + } + + if retry <= 0 { + retry = 0 + } + + mqIns.producerIns, err = rocketmq.NewProducer( + producer.WithNameServer(addr), + producer.WithRetry(retry), + producer.WithGroupName(groupName), + ) + + if err != nil { + return nil, err + } + + err = mqIns.producerIns.Start() + if err != nil { + return nil, err + } + + return mqIns, nil +} + +// RegisterRocketMqConsumer 注册rocketmq消费者 +func RegisterRocketMqConsumer(endPoints []string, groupName string) (mqIns *RocketMq, err error) { + addr, err := primitive.NewNamesrvAddr(endPoints...) + if err != nil { + return nil, err + } + mqIns = &RocketMq{ + endPoints: endPoints, + } + mqIns.consumerIns, err = rocketmq.NewPushConsumer( + consumer.WithNameServer(addr), + consumer.WithConsumerModel(consumer.Clustering), + consumer.WithGroupName(groupName), + ) + + if err != nil { + return nil, err + } + + return mqIns, nil +} diff --git a/hotgo-server/app/factory/queue/rocketmq_rewrite_logger.go b/hotgo-server/app/factory/queue/rocketmq_rewrite_logger.go new file mode 100644 index 0000000..262c609 --- /dev/null +++ b/hotgo-server/app/factory/queue/rocketmq_rewrite_logger.go @@ -0,0 +1,83 @@ +package queue + +import ( + "fmt" +) + +type RocketMqLogger struct { + Flag string + LevelLog string +} + +func (l *RocketMqLogger) Debug(msg string, fields map[string]interface{}) { + if l.LevelLog == "close" { + return + } + if msg == "" && len(fields) == 0 { + return + } + + if l.LevelLog == "debug" || l.LevelLog == "all" { + Log(ctx, fmt.Sprint(l.Flag, " [debug] ", msg)) + } +} + +func (l *RocketMqLogger) Level(level string) { + Log(ctx, fmt.Sprint(l.Flag, " [level] ", level)) +} + +func (l *RocketMqLogger) OutputPath(path string) (err error) { + Log(ctx, fmt.Sprint(l.Flag, " [path] ", path)) + return nil +} + +func (l *RocketMqLogger) Info(msg string, fields map[string]interface{}) { + if l.LevelLog == "close" { + return + } + if msg == "" && len(fields) == 0 { + return + } + + if l.LevelLog == "info" || l.LevelLog == "all" { + Log(ctx, fmt.Sprint(l.Flag, " [info] ", msg)) + } +} + +func (l *RocketMqLogger) Warning(msg string, fields map[string]interface{}) { + if l.LevelLog == "close" { + return + } + if msg == "" && len(fields) == 0 { + return + } + + if l.LevelLog == "warn" || l.LevelLog == "all" { + Log(ctx, fmt.Sprint(l.Flag, " [warn] ", msg)) + } +} + +func (l *RocketMqLogger) Error(msg string, fields map[string]interface{}) { + if l.LevelLog == "close" { + return + } + if msg == "" && len(fields) == 0 { + return + } + if l.LevelLog == "error" || l.LevelLog == "all" { + Log(ctx, fmt.Sprint(l.Flag, " [error] ", msg)) + } +} + +func (l *RocketMqLogger) Fatal(msg string, fields map[string]interface{}) { + if l.LevelLog == "close" { + return + } + if msg == "" && len(fields) == 0 { + return + } + + if l.LevelLog == "fatal" || l.LevelLog == "all" { + Log(ctx, fmt.Sprint(l.Flag, " [fatal] ", msg)) + } +} diff --git a/hotgo-server/app/form/adminForm/config_form.go b/hotgo-server/app/form/adminForm/config_form.go new file mode 100644 index 0000000..5fbe83c --- /dev/null +++ b/hotgo-server/app/form/adminForm/config_form.go @@ -0,0 +1,73 @@ +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" +) + +// 获取指定配置键的值 +type ConfigGetValueReq struct { + Key string `json:"key" v:"required#配置键不能为空" description:"配置键"` + g.Meta `path:"/config/get_value" method:"get" tags:"配置" summary:"获取指定配置键的值"` +} +type ConfigGetValueRes struct { + Value string `json:"value" description:"配置值"` +} + +// 名称是否唯一 +type ConfigNameUniqueReq struct { + Name string `json:"name" v:"required#配置名称不能为空" description:"配置名称"` + Id int64 `json:"id" description:"配置ID"` + g.Meta `path:"/config/name_unique" method:"get" tags:"配置" summary:"配置名称是否唯一"` +} +type ConfigNameUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 查询列表 +type ConfigListReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + Name string `json:"name" description:"配置名称"` + g.Meta `path:"/config/list" method:"get" tags:"配置" summary:"获取配置列表"` +} + +type ConfigListRes struct { + List []*input.SysConfigListModel `json:"list" description:"数据列表"` + form.PageRes +} + +// 获取指定信息 +type ConfigViewReq struct { + Id string `json:"id" v:"required#配置ID不能为空" description:"配置ID"` + g.Meta `path:"/config/view" method:"get" tags:"配置" summary:"获取指定信息"` +} +type ConfigViewRes struct { + *input.SysConfigViewModel +} + +// 修改/新增 +type ConfigEditReq struct { + entity.SysConfig + g.Meta `path:"/config/edit" method:"post" tags:"配置" summary:"修改/新增配置"` +} +type ConfigEditRes struct{} + +// 删除 +type ConfigDeleteReq struct { + Id interface{} `json:"id" v:"required#配置ID不能为空" description:"配置ID"` + g.Meta `path:"/config/delete" method:"post" tags:"配置" summary:"删除配置"` +} +type ConfigDeleteRes struct{} + +// 最大排序 +type ConfigMaxSortReq struct { + Id int64 `json:"id" description:"配置ID"` + g.Meta `path:"/config/max_sort" method:"get" tags:"配置" summary:"配置最大排序"` +} +type ConfigMaxSortRes struct { + Sort int `json:"sort" description:"排序"` +} diff --git a/hotgo-server/app/form/adminForm/dept_form.go b/hotgo-server/app/form/adminForm/dept_form.go new file mode 100644 index 0000000..bda2890 --- /dev/null +++ b/hotgo-server/app/form/adminForm/dept_form.go @@ -0,0 +1,65 @@ +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" +) + +// 名称是否唯一 +type DeptNameUniqueReq struct { + Name string `json:"name" v:"required#部门名称不能为空" description:"部门名称"` + Id int64 `json:"id" description:"部门ID"` + g.Meta `path:"/dept/name_unique" method:"get" tags:"部门" summary:"部门名称是否唯一"` +} +type DeptNameUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 查询列表树 +type DeptListTreeReq struct { + Id int64 `json:"id" description:"部门ID"` + g.Meta `path:"/dept/list_tree" method:"get" tags:"部门" summary:"获取部门列表树"` +} + +type DeptListTreeRes []*input.AdminDeptListTreeModel + +// 查询列表 +type DeptListReq struct { + Name string `json:"name" description:"部门名称"` + g.Meta `path:"/dept/list" method:"get" tags:"部门" summary:"获取部门列表"` +} + +type DeptListRes []*input.AdminDeptListModel + +// 获取指定信息 +type DeptViewReq struct { + Id int64 `json:"id" v:"required#部门ID不能为空" description:"部门ID"` + g.Meta `path:"/dept/view" method:"get" tags:"部门" summary:"获取指定信息"` +} +type DeptViewRes struct { + *input.AdminDeptViewModel +} + +// 修改/新增字典数据 +type DeptEditReq struct { + entity.AdminDept + g.Meta `path:"/dept/edit" method:"post" tags:"部门" summary:"修改/新增部门"` +} +type DeptEditRes struct{} + +// 删除字典类型 +type DeptDeleteReq struct { + Id interface{} `json:"id" v:"required#部门ID不能为空" description:"部门ID"` + g.Meta `path:"/dept/delete" method:"post" tags:"部门" summary:"删除部门"` +} +type DeptDeleteRes struct{} + +// 最大排序 +type DeptMaxSortReq struct { + Id int64 `json:"id" description:"部门ID"` + g.Meta `path:"/dept/max_sort" method:"get" tags:"部门" summary:"部门最大排序"` +} +type DeptMaxSortRes struct { + Sort int `json:"sort" description:"排序"` +} diff --git a/hotgo-server/app/form/adminForm/dict_form.go b/hotgo-server/app/form/adminForm/dict_form.go new file mode 100644 index 0000000..b2df2a8 --- /dev/null +++ b/hotgo-server/app/form/adminForm/dict_form.go @@ -0,0 +1,136 @@ +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" +) + +/************************ 字典数据 *****************/ + +// 数据键值是否唯一 +type DictDataUniqueReq struct { + Value string `json:"value" v:"required#数据键值不能为空" description:"数据键值"` + Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"` + Id int64 `json:"id" description:"字典数据ID"` + g.Meta `path:"/dict_data/unique" method:"get" tags:"字典" summary:"数据键值是否唯一"` +} +type DictDataUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 查询字典数据最大排序 +type DictDataMaxSortReq struct { + Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"` + g.Meta `path:"/dict_data/max_sort" method:"get" tags:"字典" summary:"查询字典数据最大排序"` +} +type DictDataMaxSortRes struct { + Sort int `json:"sort" description:"排序"` +} + +// 修改/新增字典数据 +type DictDataEditReq struct { + entity.SysDictData + g.Meta `path:"/dict_data/edit" method:"post" tags:"字典" summary:"修改/新增字典数据"` +} +type DictDataEditRes struct{} + +// 删除字典类型 +type DictDataDeleteReq struct { + Id interface{} `json:"id" v:"required#字典数据ID不能为空" description:"字典数据ID"` + g.Meta `path:"/dict_data/delete" method:"post" tags:"字典" summary:"删除字典数据"` +} +type DictDataDeleteRes struct{} + +// 获取指定字典数据信息 +type DictDataViewReq struct { + Id string `json:"id" v:"required#字典数据ID不能为空" description:"字典数据ID"` + g.Meta `path:"/dict_data/view" method:"get" tags:"字典" summary:"获取指定字典数据信息"` +} +type DictDataViewRes struct { + *entity.SysDictData +} + +// 获取字典数据列表 +type DictDataListReq struct { + form.PageReq + Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"` + g.Meta `path:"/dict_data/list" method:"get" tags:"字典" summary:"获取字典数据列表"` +} +type DictDataListRes struct { + List []*entity.SysDictData `json:"list" description:"数据列表"` + form.PageRes +} + +// 获取指定字典类型的属性数据 +type DictAttributeReq struct { + Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"` + g.Meta `path:"/dict/attribute" method:"get" tags:"字典" summary:"获取指定字典类型的属性数据"` +} +type DictAttributeRes []*entity.SysDictData + +/************************ 字典类型 *****************/ + +// 修改/新增字典类型 +type DictTypeExportReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + Name string `json:"name" description:"字典名称"` + Type string `json:"type" description:"字典类型"` + g.Meta `path:"/dict_type/export" method:"get" tags:"字典" summary:"导出字典类型"` +} +type DictTypeExportRes struct{} + +// 刷新字典缓存 +type DictTypeRefreshCacheReq struct { + g.Meta `path:"/dict_type/refresh_cache" method:"get" tags:"字典" summary:"刷新字典缓存"` +} +type DictTypeRefreshCacheRes struct{} + +// 获取字典类型列表 +type DictTypeListReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + Name string `json:"name" description:"字典名称"` + Type string `json:"type" description:"字典类型"` + g.Meta `path:"/dict_type/list" method:"get" tags:"字典" summary:"获取字典类型列表"` +} +type DictTypeListRes struct { + List []*entity.SysDictType `json:"list" description:"数据列表"` + form.PageRes +} + +// 修改/新增字典类型 +type DictTypeEditReq struct { + entity.SysDictType + g.Meta `path:"/dict_type/edit" method:"post" tags:"字典" summary:"修改/新增字典类型"` +} +type DictTypeEditRes struct{} + +// 删除字典类型 +type DictTypeDeleteReq struct { + Id interface{} `json:"id" v:"required#字典类型ID不能为空" description:"字典类型ID"` + g.Meta `path:"/dict_type/delete" method:"post" tags:"字典" summary:"删除字典类型"` +} +type DictTypeDeleteRes struct{} + +// 获取指定字典类型信息 +type DictTypeViewReq struct { + Id string `json:"id" v:"required#字典类型ID不能为空" description:"字典类型ID"` + g.Meta `path:"/dict_type/view" method:"get" tags:"字典" summary:"获取指定字典类型信息"` +} +type DictTypeViewRes struct { + *entity.SysDictType +} + +// 类型是否唯一 +type DictTypeUniqueReq struct { + Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"` + Id int64 `json:"id" description:"字典类型ID"` + g.Meta `path:"/dict_type/unique" method:"get" tags:"字典" summary:"类型是否唯一"` +} +type DictTypeUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} diff --git a/hotgo-server/app/form/adminForm/log_form.go b/hotgo-server/app/form/adminForm/log_form.go new file mode 100644 index 0000000..dcba676 --- /dev/null +++ b/hotgo-server/app/form/adminForm/log_form.go @@ -0,0 +1,47 @@ +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/gogf/gf/v2/frame/g" +) + +// 清空日志 +type LogClearReq struct { + g.Meta `path:"/log/clear" method:"post" tags:"日志" summary:"清空日志"` +} +type LogClearRes struct{} + +// 导出 +type LogExportReq struct { + form.PageReq + form.RangeDateReq + Module string `json:"module" description:"应用端口"` + MemberId int `json:"member_id" description:"用户ID"` + TakeUpTime int `json:"take_up_time" description:"请求耗时"` + Method string `json:"method" description:"请求方式"` + Url string `json:"url" description:"请求路径"` + Ip string `json:"ip" description:"访问IP"` + ErrorCode string `json:"error_code" description:"状态码"` + g.Meta `path:"/log/export" method:"get" tags:"日志" summary:"导出日志"` +} +type LogExportRes struct{} + +// 获取菜单列表 +type LogListReq struct { + form.PageReq + form.RangeDateReq + Module string `json:"module" description:"应用端口"` + MemberId int `json:"member_id" description:"用户ID"` + TakeUpTime int `json:"take_up_time" description:"请求耗时"` + Method string `json:"method" description:"请求方式"` + Url string `json:"url" description:"请求路径"` + Ip string `json:"ip" description:"访问IP"` + ErrorCode string `json:"error_code" description:"状态码"` + g.Meta `path:"/log/list" method:"get" tags:"日志" summary:"获取日志列表"` +} + +type LogListRes struct { + List []*input.LogListModel `json:"list" description:"数据列表"` + form.PageRes +} diff --git a/hotgo-server/app/form/adminForm/login_form.go b/hotgo-server/app/form/adminForm/login_form.go new file mode 100644 index 0000000..5904a93 --- /dev/null +++ b/hotgo-server/app/form/adminForm/login_form.go @@ -0,0 +1,41 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/model" + "github.com/gogf/gf/v2/frame/g" +) + +// 注销登录 +type LoginLogoutReq struct { + g.Meta `path:"/login/logout" method:"post" tags:"登录" summary:"注销登录"` +} +type LoginLogoutRes struct{} + +// 获取登录验证码 +type LoginCaptchaReq struct { + g.Meta `path:"/login/captcha" method:"get" tags:"登录" summary:"获取登录验证码"` +} +type LoginCaptchaRes struct { + Cid string `json:"cid" v:"" description:"验证码ID"` + Base64 string `json:"base64" v:"" description:"验证码"` +} + +// 提交登录 +type LoginReq struct { + g.Meta `path:"/login/sign" method:"post" tags:"登录" summary:"提交登录"` + Username string `json:"username" v:"required#用户名不能为空" description:"用户名"` + Password string `json:"password" v:"required#密码不能为空" description:"密码"` + Cid string `json:"cid" v:"required#验证码ID不能为空" description:"验证码ID"` + Code string `json:"code" v:"required#验证码不能为空" description:"验证码"` + Device string `json:"device" description:"登录设备"` +} +type LoginRes struct { + model.Identity + Token string `json:"token" v:"" description:"登录token"` +} diff --git a/hotgo-server/app/form/adminForm/member_form.go b/hotgo-server/app/form/adminForm/member_form.go new file mode 100644 index 0000000..3fb8e53 --- /dev/null +++ b/hotgo-server/app/form/adminForm/member_form.go @@ -0,0 +1,212 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// 更新会员资料 +type MemberUpdateProfileReq struct { + Mobile int `json:"mobile" description:"手机号"` + Email string `json:"email" description:"邮箱"` + Realname string `json:"realname" description:"真实姓名"` + g.Meta `path:"/member/update_profile" method:"post" tags:"会员" summary:"更新会员资料"` +} +type MemberUpdateProfileRes struct{} + +// 修改登录密码 +type MemberUpdatePwdReq struct { + OldPassword string `json:"oldPassword" v:"required#原密码不能为空" description:"原密码"` + NewPassword string `json:"newPassword" v:"required|length:6,16#新密码不能为空#新密码需在6~16之间" description:"新密码"` + g.Meta `path:"/member/update_pwd" method:"post" tags:"会员" summary:"重置密码"` +} +type MemberUpdatePwdRes struct{} + +// 获取登录用户的基本信息 +type MemberProfileReq struct { + g.Meta `path:"/member/profile" method:"get" tags:"会员" summary:"获取登录用户的基本信息"` +} +type MemberProfileRes struct { + PostGroup string `json:"postGroup" description:"岗位名称"` + RoleGroup string `json:"roleGroup" description:"角色名称"` + User *input.AdminMemberViewModel `json:"user" description:"用户基本信息"` + SysDept *input.AdminDeptViewModel `json:"sysDept" description:"部门信息"` + SysRoles []*input.AdminRoleListModel `json:"sysRoles" description:"角色列表"` + PostIds int64 `json:"postIds" description:"当前岗位"` + RoleIds int64 `json:"roleIds" description:"当前角色"` +} + +// 重置密码 +type MemberResetPwdReq struct { + Password string `json:"password" v:"required#密码不能为空" description:"密码"` + Id int64 `json:"id" description:"会员ID"` + g.Meta `path:"/member/reset_pwd" method:"post" tags:"会员" summary:"重置密码"` +} +type MemberResetPwdRes struct{} + +// 邮箱是否唯一 +type MemberEmailUniqueReq struct { + Email string `json:"email" v:"required#邮箱不能为空" description:"邮箱"` + Id int64 `json:"id" description:"会员ID"` + g.Meta `path:"/member/email_unique" method:"get" tags:"会员" summary:"邮箱是否唯一"` +} +type MemberEmailUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 手机号是否唯一 +type MemberMobileUniqueReq struct { + Mobile string `json:"mobile" v:"required#手机号不能为空" description:"手机号"` + Id int64 `json:"id" description:"会员ID"` + g.Meta `path:"/member/mobile_unique" method:"get" tags:"会员" summary:"手机号是否唯一"` +} +type MemberMobileUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 名称是否唯一 +type MemberNameUniqueReq struct { + Username string `json:"username" v:"required#会员名称不能为空" description:"会员名称"` + Id int64 `json:"id" description:"会员ID"` + g.Meta `path:"/member/name_unique" method:"get" tags:"会员" summary:"会员名称是否唯一"` +} +type MemberNameUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 查询列表 +type MemberListReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + DeptId int `json:"dept_id" description:"部门ID"` + Mobile int `json:"mobile" description:"手机号"` + Username string `json:"username" description:"用户名"` + Realname string `json:"realname" description:"真实姓名"` + StartTime string `json:"start_time" description:"开始时间"` + EndTime string `json:"end_time" description:"结束时间"` + Name string `json:"name" description:"岗位名称"` + Code string `json:"code" description:"岗位编码"` + g.Meta `path:"/member/list" method:"get" tags:"会员" summary:"获取会员列表"` +} + +type MemberListRes struct { + List []*input.AdminMemberListModel `json:"list" description:"数据列表"` + form.PageRes +} + +// 获取指定信息 +type MemberViewReq struct { + Id int64 `json:"id" description:"会员ID"` // v:"required#会员ID不能为空" + g.Meta `path:"/member/view" method:"get" tags:"会员" summary:"获取指定信息"` +} +type MemberViewRes struct { + *input.AdminMemberViewModel + Posts []*input.AdminPostListModel `json:"posts" description:"可选岗位"` + PostIds []int64 `json:"postIds" description:"当前岗位"` + Roles []*input.AdminRoleListModel `json:"roles" description:"可选角色"` + RoleIds []int64 `json:"roleIds" description:"当前角色"` + DeptName string `json:"dept_name" description:"部门名称"` +} + +// 修改/新增 +type MemberEditReq struct { + input.AdminMemberEditInp + g.Meta `path:"/member/edit" method:"post" tags:"会员" summary:"修改/新增会员"` +} +type MemberEditRes struct{} + +// 删除 +type MemberDeleteReq struct { + Id interface{} `json:"id" v:"required#会员ID不能为空" description:"会员ID"` + g.Meta `path:"/member/delete" method:"post" tags:"会员" summary:"删除会员"` +} +type MemberDeleteRes struct{} + +// 最大排序 +type MemberMaxSortReq struct { + Id int64 `json:"id" description:"会员ID"` + g.Meta `path:"/member/max_sort" method:"get" tags:"会员" summary:"会员最大排序"` +} +type MemberMaxSortRes struct { + Sort int `json:"sort" description:"排序"` +} + +// 获取登录用户信息 +type MemberInfoReq struct { + g.Meta `path:"/member/info" method:"get" tags:"会员" summary:"获取登录用户信息" description:"获取管理后台的登录用户信息"` +} + +type PortalConfigContentOptions struct { + TitleRequired bool `json:"titleRequired" titleRequired:""` + MoreUrl string `json:"moreUrl" description:"模块地址"` + Refresh int `json:"refresh" description:"刷新"` +} + +type PortalConfigContent struct { + Id int `json:"id" description:"内容ID"` + X int `json:"x" description:""` + Y int `json:"y" description:""` + W int `json:"w" description:"宽"` + H int `json:"h" description:"高"` + I int `json:"i" description:""` + Key string `json:"key" description:""` + IsShowTitle string `json:"isShowTitle" description:""` + IsAllowDrag bool `json:"isAllowDrag" description:""` + Name string `json:"name" description:""` + Type string `json:"type" description:""` + Url string `json:"url" description:""` + Options []*PortalConfigContentOptions `json:"options" description:""` + Moved bool `json:"moved" description:""` +} + +type PortalConfig struct { + CreateByName string `json:"createByName" description:"创建者名称"` + CreateDeptName string `json:"createDeptName" description:"创建部门名称"` + ImportErrInfo string `json:"importErrInfo" description:"导出错误信息"` + Id string `json:"id" description:"用户ID"` + SearchValue string `json:"searchValue" description:"搜索内容"` + CreateBy string `json:"createBy" description:"创建者名称"` + CreateDept string `json:"createDept" description:"创建部门名称"` + CreateTime *gtime.Time `json:"createTime" description:"创建时间"` + UpdateBy string `json:"updateBy" description:"更新者名称"` + UpdateTime *gtime.Time `json:"updateTime" description:"更新时间"` + UpdateIp string `json:"updateIp" description:"更新iP"` + Remark string `json:"remark" description:"备注"` + Version string `json:"version" description:"版本号"` + DelFlag string `json:"delFlag" description:"删除标签"` + HandleType string `json:"handleType" description:""` + Params string `json:"params" description:""` + Name string `json:"name" description:"配置名称"` + Code string `json:"code" description:"配置代码"` + ApplicationRange string `json:"applicationRange" description:""` + IsDefault string `json:"isDefault" description:"是否默认"` + ResourceId string `json:"resourceId" description:""` + ResourceName string `json:"resourceName" description:""` + SystemDefinedId string `json:"systemDefinedId" description:""` + Sort string `json:"sort" description:"排序"` + SaveType string `json:"saveType" description:""` + Status string `json:"status" description:"状态"` + RecordLog string `json:"recordLog" description:""` + PortalConfigContent string `json:"content" description:"配置内容"` +} + +type MemberInfoRes struct { + DefaultPortalConfig []*PortalConfig `json:"defaultPortalConfig" description:"默认用户配置"` + LincenseInfo string `json:"lincenseInfo" description:"应用版本号"` + Permissions []string `json:"permissions"description:"权限"` + Roles []string `json:"roles" description:"角色"` + SysNoticeList []*entity.AdminNotice `json:"sysNoticeList" description:"系统公告"` + UserPortalConfig []*PortalConfig `json:"userPortalConfig" description:"用户配置"` + User model.Identity `json:"user" description:"用户信息"` +} diff --git a/hotgo-server/app/form/adminForm/menu_form.go b/hotgo-server/app/form/adminForm/menu_form.go new file mode 100644 index 0000000..131f8c6 --- /dev/null +++ b/hotgo-server/app/form/adminForm/menu_form.go @@ -0,0 +1,92 @@ +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" +) + +// 菜单最大排序 +type MenuMaxSortReq struct { + Id int64 `json:"id" description:"菜单ID"` + g.Meta `path:"/menu/max_sort" method:"get" tags:"菜单" summary:"菜单最大排序"` +} +type MenuMaxSortRes struct { + Sort int `json:"sort" description:"排序"` +} + +// 菜单编码是否唯一 +type MenuCodeUniqueReq struct { + Code string `json:"code" v:"required#菜单编码不能为空" description:"菜单编码"` + Id int64 `json:"id" description:"菜单ID"` + g.Meta `path:"/menu/code_unique" method:"get" tags:"菜单" summary:"菜单编码是否唯一"` +} +type MenuCodeUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 菜单名称是否唯一 +type MenuNameUniqueReq struct { + Name string `json:"name" v:"required#菜单名称不能为空" description:"菜单名称"` + Id int64 `json:"id" description:"菜单ID"` + g.Meta `path:"/menu/name_unique" method:"get" tags:"菜单" summary:"菜单名称是否唯一"` +} +type MenuNameUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 修改/新增字典数据 +type MenuEditReq struct { + entity.AdminMenu + g.Meta `path:"/menu/edit" method:"post" tags:"菜单" summary:"修改/新增菜单"` +} +type MenuEditRes struct{} + +// 删除字典类型 +type MenuDeleteReq struct { + Id interface{} `json:"id" v:"required#菜单ID不能为空" description:"菜单ID"` + g.Meta `path:"/menu/delete" method:"post" tags:"菜单" summary:"删除菜单"` +} +type MenuDeleteRes struct{} + +// 获取指定字典数据信息 +type MenuViewReq struct { + Id string `json:"id" v:"required#菜单ID不能为空" description:"菜单ID"` + g.Meta `path:"/menu/view" method:"get" tags:"菜单" summary:"获取指定菜单信息"` +} +type MenuViewRes struct { + *entity.AdminMenu +} + +// 获取菜单列表 +type MenuListReq struct { + form.PageReq + Pid int64 `json:"pid" description:"父ID"` + g.Meta `path:"/menu/list" method:"get" tags:"菜单" summary:"获取菜单列表"` +} + +type MenuListRes struct { + List []*entity.AdminMenu `json:"list" description:"数据列表"` + form.PageRes +} + +// 查询菜单列表 +type MenuSearchListReq struct { + Name string `json:"name" description:"菜单名称"` + form.StatusReq + g.Meta `path:"/menu/search_list" method:"get" tags:"菜单" summary:"获取菜单列表"` +} + +type MenuSearchListRes []*model.TreeMenu + +// 查询角色菜单列表 +type MenuRoleListReq struct { + RoleId string `json:"role_id" description:"角色ID"` + g.Meta `path:"/menu/role_list" method:"get" tags:"菜单" summary:"查询角色菜单列表"` +} + +type MenuRoleListRes struct { + Menus []*model.LabelTreeMenu `json:"menus" description:"菜单列表"` + CheckedKeys []int64 `json:"checkedKeys" description:"选择的菜单ID"` +} diff --git a/hotgo-server/app/form/adminForm/notice_form.go b/hotgo-server/app/form/adminForm/notice_form.go new file mode 100644 index 0000000..8aed408 --- /dev/null +++ b/hotgo-server/app/form/adminForm/notice_form.go @@ -0,0 +1,64 @@ +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" +) + +// 名称是否唯一 +type NoticeNameUniqueReq struct { + Title string `json:"name" v:"required#公告名称不能为空" description:"公告名称"` + Id int64 `json:"id" description:"公告ID"` + g.Meta `path:"/notice/name_unique" method:"get" tags:"公告" summary:"公告名称是否唯一"` +} +type NoticeNameUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 查询列表 +type NoticeListReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + Name string `json:"name" description:"公告名称"` + g.Meta `path:"/notice/list" method:"get" tags:"公告" summary:"获取公告列表"` +} + +type NoticeListRes struct { + List []*input.AdminNoticeListModel `json:"list" description:"数据列表"` + form.PageRes +} + +// 获取指定信息 +type NoticeViewReq struct { + Id string `json:"id" v:"required#公告ID不能为空" description:"公告ID"` + g.Meta `path:"/notice/view" method:"get" tags:"公告" summary:"获取指定信息"` +} +type NoticeViewRes struct { + *input.AdminNoticeViewModel +} + +// 修改/新增 +type NoticeEditReq struct { + entity.AdminNotice + g.Meta `path:"/notice/edit" method:"post" tags:"公告" summary:"修改/新增公告"` +} +type NoticeEditRes struct{} + +// 删除 +type NoticeDeleteReq struct { + Id interface{} `json:"id" v:"required#公告ID不能为空" description:"公告ID"` + g.Meta `path:"/notice/delete" method:"post" tags:"公告" summary:"删除公告"` +} +type NoticeDeleteRes struct{} + +// 最大排序 +type NoticeMaxSortReq struct { + Id int64 `json:"id" description:"公告ID"` + g.Meta `path:"/notice/max_sort" method:"get" tags:"公告" summary:"公告最大排序"` +} +type NoticeMaxSortRes struct { + Sort int `json:"sort" description:"排序"` +} diff --git a/hotgo-server/app/form/adminForm/post_form.go b/hotgo-server/app/form/adminForm/post_form.go new file mode 100644 index 0000000..27f830e --- /dev/null +++ b/hotgo-server/app/form/adminForm/post_form.go @@ -0,0 +1,75 @@ +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" +) + +// 修改/新增字典数据 +type PostEditReq struct { + entity.AdminPost + g.Meta `path:"/post/edit" method:"post" tags:"岗位" summary:"修改/新增岗位"` +} +type PostEditRes struct{} + +// 删除字典类型 +type PostDeleteReq struct { + Id interface{} `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"` + g.Meta `path:"/post/delete" method:"post" tags:"岗位" summary:"删除岗位"` +} +type PostDeleteRes struct{} + +// 最大排序 +type PostMaxSortReq struct { + Id int64 `json:"id" description:"岗位ID"` + g.Meta `path:"/post/max_sort" method:"get" tags:"岗位" summary:"岗位最大排序"` +} +type PostMaxSortRes struct { + Sort int `json:"sort" description:"排序"` +} + +// 获取列表 +type PostListReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + Name string `json:"name" description:"岗位名称"` + Code string `json:"code" description:"岗位编码"` + g.Meta `path:"/post/list" method:"get" tags:"岗位" summary:"获取岗位列表"` +} + +type PostListRes struct { + List []*input.AdminPostListModel `json:"list" description:"数据列表"` + form.PageRes +} + +// 获取指定信息 +type PostViewReq struct { + Id string `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"` + g.Meta `path:"/post/view" method:"get" tags:"岗位" summary:"获取指定信息"` +} +type PostViewRes struct { + *input.AdminPostViewModel +} + +// 编码是否唯一 +type PostCodeUniqueReq struct { + Code string `json:"code" v:"required#岗位编码不能为空" description:"岗位编码"` + Id int64 `json:"id" description:"岗位ID"` + g.Meta `path:"/post/code_unique" method:"get" tags:"岗位" summary:"岗位编码是否唯一"` +} +type PostCodeUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} + +// 名称是否唯一 +type PostNameUniqueReq struct { + Name string `json:"name" v:"required#岗位名称不能为空" description:"岗位名称"` + Id int64 `json:"id" description:"岗位ID"` + g.Meta `path:"/post/name_unique" method:"get" tags:"岗位" summary:"岗位名称是否唯一"` +} +type PostNameUniqueRes struct { + IsUnique bool `json:"is_unique" description:"是否唯一"` +} diff --git a/hotgo-server/app/form/adminForm/role_form.go b/hotgo-server/app/form/adminForm/role_form.go new file mode 100644 index 0000000..20a06aa --- /dev/null +++ b/hotgo-server/app/form/adminForm/role_form.go @@ -0,0 +1,89 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/gogf/gf/v2/frame/g" +) + +// 查询列表 +type RoleMemberListReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + Role int `json:"role" description:"角色ID"` + DeptId int `json:"dept_id" description:"部门ID"` + Mobile int `json:"mobile" description:"手机号"` + Username string `json:"username" description:"用户名"` + Realname string `json:"realname" description:"真实姓名"` + StartTime string `json:"start_time" description:"开始时间"` + EndTime string `json:"end_time" description:"结束时间"` + Name string `json:"name" description:"岗位名称"` + Code string `json:"code" description:"岗位编码"` + g.Meta `path:"/role/member_list" method:"get" tags:"角色" summary:"获取角色下的会员列表"` +} + +type RoleMemberListRes struct { + List []*input.AdminMemberListModel `json:"list" description:"数据列表"` + form.PageRes +} + +// 查询列表 +type RoleListReq struct { + form.PageReq + form.RangeDateReq + form.StatusReq + DeptId int `json:"dept_id" description:"部门ID"` + Mobile int `json:"mobile" description:"手机号"` + Username string `json:"username" description:"用户名"` + Realname string `json:"realname" description:"真实姓名"` + StartTime string `json:"start_time" description:"开始时间"` + EndTime string `json:"end_time" description:"结束时间"` + Name string `json:"name" description:"岗位名称"` + Code string `json:"code" description:"岗位编码"` + g.Meta `path:"/role/list" method:"get" tags:"角色" summary:"获取角色列表"` +} + +type RoleListRes struct { + List []*input.AdminRoleListModel `json:"list" description:"数据列表"` + form.PageRes +} + +// 动态路由 +type RoleDynamicReq struct { + g.Meta `path:"/role/dynamic" method:"get" tags:"路由" summary:"获取动态路由" description:"获取登录用户动态路由"` +} + +type RoleDynamicMeta struct { + Title string `json:"title" description:"菜单标题"` + Icon string `json:"icon" description:"菜单图标"` + NoCache bool `json:"noCache" description:"是否缓存"` + Remark string `json:"remark" description:"备注"` +} + +type RoleDynamicBase struct { + Id int64 `json:"id" description:"菜单ID"` + Pid int64 `json:"pid" description:"父ID"` + Name string `json:"name" description:"菜单名称"` + Code string `json:"code" description:"菜单编码"` + Path string `json:"path" description:"路由地址"` + Hidden bool `json:"hidden" description:"是否隐藏"` + Redirect string `json:"redirect" description:"重定向"` + Component string `json:"component" description:"组件路径"` + AlwaysShow bool `json:"alwaysShow" description:"暂时不知道干啥"` + IsFrame string `json:"isFrame" description:"是否为外链(0是 1否)"` + Meta *RoleDynamicMeta `json:"meta" description:"配置数据集"` +} + +type RoleDynamicMenu struct { + RoleDynamicBase + Children []*RoleDynamicBase `json:"children" description:"子菜单"` +} + +type RoleDynamicRes []*RoleDynamicMenu diff --git a/hotgo-server/app/form/apiForm/base_form.go b/hotgo-server/app/form/apiForm/base_form.go new file mode 100644 index 0000000..332ca3c --- /dev/null +++ b/hotgo-server/app/form/apiForm/base_form.go @@ -0,0 +1,34 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package apiForm + +import ( + "github.com/bufanyun/hotgo/app/com" + "github.com/gogf/gf/v2/frame/g" +) + +// 获取lang信息 +type BaseLangReq struct { + g.Meta `path:"/base/lang" method:"get" tags:"基础" summary:"获取lang信息"` + L string `json:"l" v:"required#语言不能为空" description:"语言"` +} +type BaseLangRes struct { +} + +// 获取登录验证码 +type IpLocationReq struct { + g.Meta `path:"/base/ip_location" method:"get" tags:"基础" summary:"获取IP归属地信息"` + Ip string `json:"ip" v:"required#ip不能为空" description:"ipv4地址"` +} +type IpLocationRes struct { + com.IpLocationData +} + +type ExportReq struct { + g.Meta `path:"/base/export" method:"get" tags:"字典" summary:"导出字典类型"` +} +type ExportRes struct{} diff --git a/hotgo-server/app/form/apiForm/dict_form.go b/hotgo-server/app/form/apiForm/dict_form.go new file mode 100644 index 0000000..dd8df5a --- /dev/null +++ b/hotgo-server/app/form/apiForm/dict_form.go @@ -0,0 +1,13 @@ +package apiForm + +import ( + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/frame/g" +) + +// 获取指定字典类型的属性数据 +type DictAttributeReq struct { + Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"` + g.Meta `path:"/dict/attribute" method:"get" tags:"字典" summary:"获取指定字典类型的属性数据"` +} +type DictAttributeRes []*entity.SysDictData diff --git a/hotgo-server/app/form/apiForm/log_form.go b/hotgo-server/app/form/apiForm/log_form.go new file mode 100644 index 0000000..0a48f87 --- /dev/null +++ b/hotgo-server/app/form/apiForm/log_form.go @@ -0,0 +1,47 @@ +package apiForm + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/gogf/gf/v2/frame/g" +) + +// 清空日志 +type LogClearReq struct { + g.Meta `path:"/log/clear" method:"post" tags:"日志" summary:"清空日志"` +} +type LogClearRes struct{} + +// 导出 +type LogExportReq struct { + form.PageReq + form.RangeDateReq + Module string `json:"module" description:"应用端口"` + MemberId int `json:"member_id" description:"用户ID"` + TakeUpTime int `json:"take_up_time" description:"请求耗时"` + Method string `json:"method" description:"请求方式"` + Url string `json:"url" description:"请求路径"` + Ip string `json:"ip" description:"访问IP"` + ErrorCode string `json:"error_code" description:"状态码"` + g.Meta `path:"/log/export" method:"get" tags:"日志" summary:"导出日志"` +} +type LogExportRes struct{} + +// 获取菜单列表 +type LogListReq struct { + form.PageReq + form.RangeDateReq + Module string `json:"module" description:"应用端口"` + MemberId int `json:"member_id" description:"用户ID"` + TakeUpTime int `json:"take_up_time" description:"请求耗时"` + Method string `json:"method" description:"请求方式"` + Url string `json:"url" description:"请求路径"` + Ip string `json:"ip" description:"访问IP"` + ErrorCode string `json:"error_code" description:"状态码"` + g.Meta `path:"/log/list" method:"get" tags:"日志" summary:"获取日志列表"` +} + +type LogListRes struct { + List []*input.LogListModel `json:"list" description:"数据列表"` + form.PageRes +} diff --git a/hotgo-server/app/form/apiForm/login_form.go b/hotgo-server/app/form/apiForm/login_form.go new file mode 100644 index 0000000..1a14f68 --- /dev/null +++ b/hotgo-server/app/form/apiForm/login_form.go @@ -0,0 +1,37 @@ +package apiForm + +import ( + "github.com/bufanyun/hotgo/app/model" + "github.com/gogf/gf/v2/frame/g" +) + +// 注销登录 +type LoginLogoutReq struct { + g.Meta `path:"/login/logout" method:"get" tags:"登录" summary:"注销登录"` +} +type LoginLogoutRes struct{} + +// 登录效验 +type LoginCheckReq struct { + g.Meta `path:"/login/check" method:"get" tags:"登录" summary:"登录效验"` +} +type LoginCheckRes struct { + IsValidCodeLogin bool `json:"isValidCodeLogin" description:"是否验证码"` + Message string `json:"message" description:"消息"` + Result string `json:"result" description:"响应"` + // Sessionid string `json:"sessionid" description:"sessionid"` +} + +// 提交登录 +type LoginReq struct { + g.Meta `path:"/login/sign" method:"post" tags:"登录" summary:"提交登录"` + Username string `json:"username" v:"required#用户名不能为空" description:"用户名"` + Password string `json:"password" v:"required#密码不能为空" description:"密码"` + Cid string `json:"cid" v:"required#验证码ID不能为空" description:"验证码ID"` + Code string `json:"code" v:"required#验证码不能为空" description:"验证码"` + Device string `json:"device" description:"登录设备"` +} +type LoginRes struct { + model.Identity + Token string `json:"token" v:"" description:"登录token"` +} diff --git a/hotgo-server/app/form/apiForm/member_form.go b/hotgo-server/app/form/apiForm/member_form.go new file mode 100644 index 0000000..b150ac6 --- /dev/null +++ b/hotgo-server/app/form/apiForm/member_form.go @@ -0,0 +1,20 @@ +package apiForm + +import ( + "github.com/bufanyun/hotgo/app/form/input" + "github.com/gogf/gf/v2/frame/g" +) + +// 获取登录用户的基本信息 +type MemberProfileReq struct { + g.Meta `path:"/member/profile" method:"get" tags:"会员" summary:"获取登录用户的基本信息"` +} +type MemberProfileRes struct { + PostGroup string `json:"postGroup" description:"岗位名称"` + RoleGroup string `json:"roleGroup" description:"角色名称"` + User *input.AdminMemberViewModel `json:"user" description:"用户基本信息"` + SysDept *input.AdminDeptViewModel `json:"sysDept" description:"部门信息"` + SysRoles []*input.AdminRoleListModel `json:"sysRoles" description:"角色列表"` + PostIds int64 `json:"postIds" description:"当前岗位"` + RoleIds int64 `json:"roleIds" description:"当前角色"` +} diff --git a/hotgo-server/app/form/common.go b/hotgo-server/app/form/common.go new file mode 100644 index 0000000..6e51118 --- /dev/null +++ b/hotgo-server/app/form/common.go @@ -0,0 +1,28 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package form + +// 分页 +type PageReq struct { + Page int `json:"page" example:"10" d:"1" v:"min:1#页码最小值不能低于1" description:"当前页码"` + Limit int `json:"limit" example:"1" d:"10" v:"min:1|max:100#|每页数量最小值不能低于1|最大值不能大于100" description:"每页数量"` +} +type PageRes struct { + PageReq + TotalCount int `json:"total_count" example:"0" description:"全部数据量"` +} + +// 时间查询 +type RangeDateReq struct { + StartTime string `json:"start_time" v:"date#开始日期格式不正确" description:"开始日期"` + EndTime string `json:"end_time" v:"date#结束日期格式不正确" description:"结束日期"` +} + +// 状态查询 +type StatusReq struct { + Status int `json:"status" v:"in:0,1,2,3#状态可选范围:0~3" description:"状态"` +} diff --git a/hotgo-server/app/form/input/admin_dept_input.go b/hotgo-server/app/form/input/admin_dept_input.go new file mode 100644 index 0000000..4c7df38 --- /dev/null +++ b/hotgo-server/app/form/input/admin_dept_input.go @@ -0,0 +1,75 @@ +package input + +import "github.com/bufanyun/hotgo/app/model/entity" + +// 名称是否唯一 +type AdminDeptNameUniqueInp struct { + Name string + Id int64 +} + +type AdminDeptNameUniqueModel struct { + IsUnique bool +} + +// 最大排序 +type AdminDeptMaxSortInp struct { + Id int64 +} + +type AdminDeptMaxSortModel struct { + Sort int +} + +// 修改/新增字典数据 +type AdminDeptEditInp struct { + entity.AdminDept +} +type AdminDeptEditModel struct{} + +// 删除字典类型 +type AdminDeptDeleteInp struct { + Id interface{} +} +type AdminDeptDeleteModel struct{} + +// 获取信息 +type AdminDeptViewInp struct { + Id int64 +} + +type AdminDeptViewModel struct { + entity.AdminDept +} + +// 获取列表 +type AdminDeptListInp struct { + Name string +} + +// 树 +type AdminDeptTreeDept struct { + entity.AdminDept + Children []*AdminDeptTreeDept `json:"children"` +} + +type AdminDeptListModel AdminDeptTreeDept + +// 获取列表树 +type AdminDeptListTreeInp struct { + Name string +} + +// 树 +type AdminDeptListTreeDept struct { + Id int64 `json:"id" ` + Key int64 `json:"key" ` + Pid int64 `json:"pid" ` + Label string `json:"label"` + Title string `json:"title"` + Name string `json:"name"` + Type string `json:"type"` + Children []*AdminDeptListTreeDept `json:"children"` +} + +type AdminDeptListTreeModel AdminDeptListTreeDept diff --git a/hotgo-server/app/form/input/admin_member_input.go b/hotgo-server/app/form/input/admin_member_input.go new file mode 100644 index 0000000..b5ff5d2 --- /dev/null +++ b/hotgo-server/app/form/input/admin_member_input.go @@ -0,0 +1,171 @@ +package input + +import ( + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/gogf/gf/v2/os/gtime" +) + +// 更新会员资料 +type AdminMemberUpdateProfileInp struct { + Mobile int + Email string + Realname string +} + +// 获取指定会员资料 +type AdminMemberProfileInp struct { + Id int64 +} +type AdminMemberProfileModel struct { + PostGroup string `json:"postGroup" description:"岗位名称"` + RoleGroup string `json:"roleGroup" description:"角色名称"` + User *AdminMemberViewModel `json:"user" description:"用户基本信息"` + SysDept *AdminDeptViewModel `json:"sysDept" description:"部门信息"` + SysRoles []*AdminRoleListModel `json:"sysRoles" description:"角色列表"` + PostIds int64 `json:"postIds" description:"当前岗位"` + RoleIds int64 `json:"roleIds" description:"当前角色"` +} + +// 更新会员资料 +type MemberUpdateProfileInp struct { + Mobile int + Email string + Realname string +} + +// 修改登录密码 +type AdminMemberUpdatePwdInp struct { + Id int64 + OldPassword string + NewPassword string +} + +// 重置密码 +type AdminMemberResetPwdInp struct { + Password string + Id int64 +} + +// 邮箱是否唯一 +type AdminMemberEmailUniqueInp struct { + Email string + Id int64 +} + +type AdminMemberEmailUniqueModel struct { + IsUnique bool +} + +// 手机号是否唯一 +type AdminMemberMobileUniqueInp struct { + Mobile string + Id int64 +} + +type AdminMemberMobileUniqueModel struct { + IsUnique bool +} + +// 名称是否唯一 +type AdminMemberNameUniqueInp struct { + Username string + Id int64 +} + +type AdminMemberNameUniqueModel struct { + IsUnique bool +} + +// 最大排序 +type AdminMemberMaxSortInp struct { + Id int64 +} + +type AdminMemberMaxSortModel struct { + Sort int +} + +// 修改/新增字典数据 +type AdminMemberEditInp struct { + Id int64 `json:"id" description:""` + PostIds []int64 `json:"postIds" v:"required#岗位不能为空" description:"岗位ID"` + DeptId int64 `json:"dept_id" v:"required#部门不能为空" description:"部门ID"` + Username string `json:"username" v:"required#账号不能为空" description:"帐号"` + Password string `json:"password" description:"密码"` + Realname string `json:"realname" description:"真实姓名"` + Avatar string `json:"avatar" description:"头像"` + Sex string `json:"sex" description:"性别[0:未知;1:男;2:女]"` + Qq string `json:"qq" description:"qq"` + Email string `json:"email" description:"邮箱"` + Birthday *gtime.Time `json:"birthday" description:"生日"` + ProvinceId int `json:"province_id" description:"省"` + CityId int `json:"city_id" description:"城市"` + AreaId int `json:"area_id" description:"地区"` + Address string `json:"address" description:"默认地址"` + Mobile string `json:"mobile" description:"手机号码"` + HomePhone string `json:"home_phone" description:"家庭号码"` + DingtalkRobotToken string `json:"dingtalk_robot_token" description:"钉钉机器人token"` + Role int `json:"role" v:"required#角色不能为空" description:"权限"` + Remark string `json:"remark" description:"备注"` + Status string `json:"status" description:"状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"修改时间"` +} + +type AdminMemberAddInp struct { + AdminMemberEditInp + PasswordHash string `json:"password_hash" description:"密码hash"` + Salt string `json:"salt" description:"密码盐"` +} + +type AdminMemberEditModel struct{} + +// 删除字典类型 +type AdminMemberDeleteInp struct { + Id interface{} +} +type AdminMemberDeleteModel struct{} + +// 获取信息 +type AdminMemberViewInp struct { + Id int64 +} + +type AdminMemberViewModel struct { + entity.AdminMember +} + +// 获取列表 +type AdminMemberListInp struct { + Page int + Limit int + Name string + Code string + DeptId int + Mobile int + Username string + Realname string + StartTime string + EndTime string + Status int +} + +type AdminMemberListModel struct { + entity.AdminMember + DeptName string `json:"dept_name"` + RoleName string `json:"role_name"` +} + +// 登录 +type AdminMemberLoginSignInp struct { + Username string + Password string + Device string + Cid string + Code string +} +type AdminMemberLoginSignModel struct { + model.Identity + Token string `json:"token" v:"" description:"登录token"` +} diff --git a/hotgo-server/app/form/input/admin_notice_input.go b/hotgo-server/app/form/input/admin_notice_input.go new file mode 100644 index 0000000..00877f1 --- /dev/null +++ b/hotgo-server/app/form/input/admin_notice_input.go @@ -0,0 +1,64 @@ +package input + +import "github.com/bufanyun/hotgo/app/model/entity" + +// 名称是否唯一 +type AdminNoticeNameUniqueInp struct { + Title string + Id int64 +} + +type AdminNoticeNameUniqueModel struct { + IsUnique bool +} + +// 最大排序 +type AdminNoticeMaxSortInp struct { + Id int64 +} + +type AdminNoticeMaxSortModel struct { + Sort int +} + +// 修改/新增字典数据 +type AdminNoticeEditInp struct { + entity.AdminNotice +} +type AdminNoticeEditModel struct{} + +// 删除字典类型 +type AdminNoticeDeleteInp struct { + Id interface{} +} +type AdminNoticeDeleteModel struct{} + +// 获取信息 +type AdminNoticeViewInp struct { + Id string +} + +type AdminNoticeViewModel struct { + entity.AdminNotice +} + +// 获取列表 +type AdminNoticeListInp struct { + Page int + Limit int + Name string + Code string + DeptId int + Mobile int + Username string + Realname string + StartTime string + EndTime string + Status int +} + +type AdminNoticeListModel struct { + entity.AdminNotice + DeptName string `json:"dept_name"` + RoleName string `json:"role_name"` +} diff --git a/hotgo-server/app/form/input/admin_post_input.go b/hotgo-server/app/form/input/admin_post_input.go new file mode 100644 index 0000000..09a23da --- /dev/null +++ b/hotgo-server/app/form/input/admin_post_input.go @@ -0,0 +1,68 @@ +package input + +import ( + "github.com/bufanyun/hotgo/app/model/entity" +) + +// 获取列表 +type AdminPostListInp struct { + Page int + Limit int + Name string + Code string + Status int +} + +type AdminPostListModel struct { + entity.AdminPost +} + +// 获取信息 +type AdminPostViewInp struct { + Id string +} + +type AdminPostViewModel struct { + entity.AdminPost +} + +// 编码是否唯一 +type AdminPostCodeUniqueInp struct { + Code string + Id int64 +} + +type AdminPostCodeUniqueModel struct { + IsUnique bool +} + +// 名称是否唯一 +type AdminPostNameUniqueInp struct { + Name string + Id int64 +} + +type AdminPostNameUniqueModel struct { + IsUnique bool +} + +// 最大排序 +type AdminPostMaxSortInp struct { + Id int64 +} + +type AdminPostMaxSortModel struct { + Sort int +} + +// 修改/新增字典数据 +type AdminPostEditInp struct { + entity.AdminPost +} +type AdminPostEditModel struct{} + +// 删除字典类型 +type AdminPostDeleteInp struct { + Id interface{} +} +type AdminPostDeleteModel struct{} diff --git a/hotgo-server/app/form/input/admin_role_input.go b/hotgo-server/app/form/input/admin_role_input.go new file mode 100644 index 0000000..02b1f04 --- /dev/null +++ b/hotgo-server/app/form/input/admin_role_input.go @@ -0,0 +1,44 @@ +package input + +import ( + "github.com/bufanyun/hotgo/app/form" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" +) + +// 获取列表 +type AdminRoleListInp struct { + Page int + Limit int +} + +type AdminRoleListModel struct { + entity.AdminRole +} + +// 查询列表 +type AdminRoleMemberListInp struct { + form.PageReq + form.RangeDateReq + form.StatusReq + Role int `json:"role" description:"角色ID"` + DeptId int `json:"dept_id" description:"部门ID"` + Mobile int `json:"mobile" description:"手机号"` + Username string `json:"username" description:"用户名"` + Realname string `json:"realname" description:"真实姓名"` + StartTime string `json:"start_time" description:"开始时间"` + EndTime string `json:"end_time" description:"结束时间"` + Name string `json:"name" description:"岗位名称"` + Code string `json:"code" description:"岗位编码"` +} + +type AdminRoleMemberListModel []*AdminMemberListModel + +// 查询角色菜单列表 +type MenuRoleListInp struct { + RoleId int64 +} +type MenuRoleListModel struct { + Menus []*model.LabelTreeMenu `json:"menus" description:"菜单列表"` + CheckedKeys []int64 `json:"checkedKeys" description:"选择的菜单ID"` +} diff --git a/hotgo-server/app/form/input/sys_config_input.go b/hotgo-server/app/form/input/sys_config_input.go new file mode 100644 index 0000000..87ec6b6 --- /dev/null +++ b/hotgo-server/app/form/input/sys_config_input.go @@ -0,0 +1,72 @@ +package input + +import "github.com/bufanyun/hotgo/app/model/entity" + +// 获取指定配置键的值 +type SysConfigGetValueInp struct { + Key string +} +type SysConfigGetValueModel struct { + Value string +} + +// 名称是否唯一 +type SysConfigNameUniqueInp struct { + Name string + Id int64 +} + +type SysConfigNameUniqueModel struct { + IsUnique bool +} + +// 最大排序 +type SysConfigMaxSortInp struct { + Id int64 +} + +type SysConfigMaxSortModel struct { + Sort int +} + +// 修改/新增字典数据 +type SysConfigEditInp struct { + entity.SysConfig +} +type SysConfigEditModel struct{} + +// 删除字典类型 +type SysConfigDeleteInp struct { + Id interface{} +} +type SysConfigDeleteModel struct{} + +// 获取信息 +type SysConfigViewInp struct { + Id string +} + +type SysConfigViewModel struct { + entity.SysConfig +} + +// 获取列表 +type SysConfigListInp struct { + Page int + Limit int + Name string + Code string + DeptId int + Mobile int + Username string + Realname string + StartTime string + EndTime string + Status int +} + +type SysConfigListModel struct { + entity.SysConfig + DeptName string `json:"dept_name"` + RoleName string `json:"role_name"` +} diff --git a/hotgo-server/app/form/input/sys_log_input.go b/hotgo-server/app/form/input/sys_log_input.go new file mode 100644 index 0000000..c9aa62c --- /dev/null +++ b/hotgo-server/app/form/input/sys_log_input.go @@ -0,0 +1,26 @@ +package input + +import ( + "github.com/bufanyun/hotgo/app/model/entity" +) + +// 获取菜单列表 +type LogListInp struct { + Page int + Limit int + Module string + MemberId int + TakeUpTime int + Method string + Url string + Ip string + ErrorCode string + StartTime string + EndTime string +} + +type LogListModel struct { + entity.SysLog + MemberName string `json:"member_name"` + Region string `json:"region"` +} diff --git a/hotgo-server/app/hook/hook.go b/hotgo-server/app/hook/hook.go new file mode 100644 index 0000000..b705720 --- /dev/null +++ b/hotgo-server/app/hook/hook.go @@ -0,0 +1,45 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package hook + +import ( + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/service/sysService" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gtime" +) + +type ( + // sHook is service struct of module Hook. + sHook struct{} +) + +var ( + // insHook is the instance of service Hook. + insHook = sHook{} +) + +// Hook returns the interface of Hook service. +func Instance() *sHook { + return &insHook +} + +// +// @Title 全局日志 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// +func (s *sHook) GlobalLog(r *ghttp.Request) { + var ( + ctx = r.Context() + ) + + com.Context.SetTakeUpTime(ctx, gtime.TimestampMilli()-r.EnterTime) + + go sysService.Log.AutoLog(ctx) +} diff --git a/hotgo-server/app/interfaces/queue_producer_interface.go b/hotgo-server/app/interfaces/queue_producer_interface.go new file mode 100644 index 0000000..253154e --- /dev/null +++ b/hotgo-server/app/interfaces/queue_producer_interface.go @@ -0,0 +1,20 @@ +// +// @Package interfaces +// @Description +// @Author Ms <133814250@qq.com> +// +package interfaces + +// +// QueueProducer +// @Description +// +type QueueProducer interface { + // + // @Title + // @Description + // @Author Ms <133814250@qq.com> + // @Return string + // + Push() string +} \ No newline at end of file diff --git a/hotgo-server/app/middleware/admin_auth.go b/hotgo-server/app/middleware/admin_auth.go new file mode 100644 index 0000000..df8301f --- /dev/null +++ b/hotgo-server/app/middleware/admin_auth.go @@ -0,0 +1,127 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package middleware + +import ( + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" +) + +// +// @Title 后台中间件 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// +func (s *sMiddleware) AdminAuth(r *ghttp.Request) { + + var ( + ctx = r.Context() + user = new(model.Identity) + authorization = com.Jwt.GetAuthorization(r) + ) + + // TODO 替换掉模块前缀 + routerPrefix, _ := g.Cfg().Get(ctx, "router.admin.prefix", "/admin") + path := gstr.Replace(r.URL.Path, routerPrefix.String(), "", 1) + + /// TODO 不需要验证登录的路由地址 + if utils.Auth.IsExceptLogin(ctx, path) { + r.Middleware.Next() + return + } + + if authorization == "" { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "请先登录!") + return + } + + // TODO 获取jwtToken + jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization) + jwtSign, _ := g.Cfg().Get(ctx, "jwt.sign", "hotgo") + + data, ParseErr := com.Jwt.ParseToken(authorization, jwtSign.Bytes()) + if ParseErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token不正确或已过期!", ParseErr.Error()) + } + + parseErr := gconv.Struct(data, &user) + if parseErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "登录信息解析异常,请重新登录!", parseErr.Error()) + } + + // TODO 判断token跟redis的缓存的token是否一样 + cache := com.Cache.New() + isContains, containsErr := cache.Contains(ctx, jwtToken) + if containsErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token无效!", containsErr.Error()) + return + } + if !isContains { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期!") + return + } + + // TODO 是否开启多端登录 + if multiPort, _ := g.Cfg().Get(ctx, "jwt.multiPort", true); !multiPort.Bool() { + key := consts.RedisJwtUserBind + consts.AppAdmin + ":" + gconv.String(user.Id) + originJwtToken, originErr := cache.Get(ctx, key) + if originErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "信息异常,请重新登录!", originErr.Error()) + return + } + + if originJwtToken == nil || originJwtToken.IsEmpty() { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期!") + return + } + + if jwtToken != originJwtToken.String() { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "账号已在其他地方登录!") + return + } + } + + // TODO 保存到上下文 + customCtx := &model.Context{} + if user != nil { + customCtx.User = &model.Identity{ + Id: user.Id, + Username: user.Username, + Realname: user.Realname, + Avatar: user.Avatar, + Email: user.Email, + Mobile: user.Mobile, + VisitCount: user.VisitCount, + LastTime: user.LastTime, + LastIp: user.LastIp, + Role: user.Role, + Exp: user.Exp, + Expires: user.Expires, + App: user.App, + } + } + com.Context.SetUser(ctx, customCtx.User) + com.Context.SetModule(ctx, consts.AppAdmin) + + //// TODO 验证路由访问权限 + //verify := adminService.Role.Verify(ctx, customCtx.User.Id, path) + //if !verify { + // com.Response.JsonExit(r, gcode.CodeSecurityReason.Code(), "你没有访问权限!") + // return + //} + + r.Middleware.Next() +} diff --git a/hotgo-server/app/middleware/api_auth.go b/hotgo-server/app/middleware/api_auth.go new file mode 100644 index 0000000..b1ae655 --- /dev/null +++ b/hotgo-server/app/middleware/api_auth.go @@ -0,0 +1,127 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package middleware + +import ( + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" +) + +// +// @Title 接口中间件 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// +func (s *sMiddleware) ApiAuth(r *ghttp.Request) { + + var ( + ctx = r.Context() + user = new(model.Identity) + authorization = com.Jwt.GetAuthorization(r) + ) + + // TODO 替换掉模块前缀 + routerPrefix, _ := g.Cfg().Get(ctx, "router.api.prefix", "/api") + path := gstr.Replace(r.URL.Path, routerPrefix.String(), "", 1) + + /// TODO 不需要验证登录的路由地址 + if utils.Auth.IsExceptLogin(ctx, path) { + r.Middleware.Next() + return + } + + if authorization == "" { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "请先登录!") + return + } + + // TODO 获取jwtToken + jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization) + jwtSign, _ := g.Cfg().Get(ctx, "jwt.sign", "hotgo") + + data, ParseErr := com.Jwt.ParseToken(authorization, jwtSign.Bytes()) + if ParseErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token不正确或已过期!", ParseErr.Error()) + } + + parseErr := gconv.Struct(data, &user) + if parseErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "登录信息解析异常,请重新登录!", parseErr.Error()) + } + + // TODO 判断token跟redis的缓存的token是否一样 + cache := com.Cache.New() + isContains, containsErr := cache.Contains(ctx, jwtToken) + if containsErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token无效!", containsErr.Error()) + return + } + if !isContains { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期!") + return + } + + // TODO 是否开启多端登录 + if multiPort, _ := g.Cfg().Get(ctx, "jwt.multiPort", true); !multiPort.Bool() { + key := consts.RedisJwtUserBind + consts.AppApi + ":" + gconv.String(user.Id) + originJwtToken, originErr := cache.Get(ctx, key) + if originErr != nil { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "信息异常,请重新登录!", originErr.Error()) + return + } + + if originJwtToken == nil || originJwtToken.IsEmpty() { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期!") + return + } + + if jwtToken != originJwtToken.String() { + com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "账号已在其他地方登录!") + return + } + } + + // TODO 保存到上下文 + customCtx := &model.Context{} + if user != nil { + customCtx.User = &model.Identity{ + Id: user.Id, + Username: user.Username, + Realname: user.Realname, + Avatar: user.Avatar, + Email: user.Email, + Mobile: user.Mobile, + VisitCount: user.VisitCount, + LastTime: user.LastTime, + LastIp: user.LastIp, + Role: user.Role, + Exp: user.Exp, + Expires: user.Expires, + App: user.App, + } + } + com.Context.SetUser(ctx, customCtx.User) + com.Context.SetModule(ctx, consts.AppApi) + + //// TODO 验证路由访问权限 + //verify := adminService.Role.Verify(ctx, customCtx.User.Id, path) + //if !verify { + // com.Response.JsonExit(r, gcode.CodeSecurityReason.Code(), "你没有访问权限!") + // return + //} + + r.Middleware.Next() +} diff --git a/hotgo-server/app/middleware/handler_response.go b/hotgo-server/app/middleware/handler_response.go new file mode 100644 index 0000000..4c8a4ab --- /dev/null +++ b/hotgo-server/app/middleware/handler_response.go @@ -0,0 +1,74 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package middleware + +import ( + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" +) + +// +// @Title 全局响应中间件 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// +func (s *sMiddleware) HandlerResponse(r *ghttp.Request) { + r.Middleware.Next() + + var ( + ctx = r.Context() + comResponse = com.Context.Get(ctx).ComResponse + code = gcode.CodeOK.Code() + message = "操作成功" + data interface{} + err error + ) + + if err := r.GetError(); err != nil { + g.Log().Print(ctx, err) + // 记录到自定义错误日志文件 + //g.Log("exception").Error(err) + ////返回固定的友好信息 + //r.Response.ClearBuffer() + //r.Response.Writeln("服务器居然开小差了,请稍后再试吧!") + } + + // TODO 已存在响应内容,且是comResponse返回的时,中断运行 + if r.Response.BufferLength() > 0 && comResponse != nil { + return + } + + if err = r.GetError(); err != nil { + // TODO 记录到自定义错误日志文件 + g.Log("exception").Print(r.Context(), "exception:", err) + + code = consts.CodeInternalError + message = "服务器居然开小差了,请稍后再试吧!" + + // TODO 是否输出错误到页面 + if debug, _ := g.Cfg().Get(ctx, "hotgo.debug", true); debug.Bool() { + data = utils.Charset.GetStack(err) + } + + } else if data, err = r.GetHandlerResponse(); err != nil { + errCode := gerror.Code(err) + if errCode == gcode.CodeNil { + errCode = gcode.CodeInternalError + } + code = errCode.Code() + message = err.Error() + } + + // TODO 返回固定的友好信息 + com.Response.RJson(r, code, message, data) +} diff --git a/hotgo-server/app/middleware/middleware.go b/hotgo-server/app/middleware/middleware.go new file mode 100644 index 0000000..5723732 --- /dev/null +++ b/hotgo-server/app/middleware/middleware.go @@ -0,0 +1,64 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package middleware + +import ( + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/model" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/util/grand" + "github.com/gogf/gf/v2/util/guid" + "go.opentelemetry.io/otel/trace" +) + +type ( + // sMiddleware is service struct of module Middleware. + sMiddleware struct{} +) + +var ( + // insMiddleware is the instance of service Middleware. + insMiddleware = sMiddleware{} +) + +// Middleware returns the interface of Middleware service. +func Instance() *sMiddleware { + return &insMiddleware +} + +// +// @Title 初始化请求上下文 +// @Description +// @Author Ms <133814250@qq.com> +// @Param r +// +func (s *sMiddleware) Ctx(r *ghttp.Request) { + + spanCtx := trace.SpanContextFromContext(r.Context()) + + reqId := guid.S(grand.B(64)) + if traceId := spanCtx.TraceID(); traceId.IsValid() { + reqId = traceId.String() + } + + customCtx := &model.Context{ + Data: make(g.Map), + Request: r, + ReqId: reqId, + } + + com.Context.Init(r, customCtx) + + r.Middleware.Next() +} + +// CORS allows Cross-origin resource sharing. +func (s *sMiddleware) CORS(r *ghttp.Request) { + r.Response.CORSDefault() + r.Middleware.Next() +} diff --git a/hotgo-server/app/model/context.go b/hotgo-server/app/model/context.go new file mode 100644 index 0000000..d6b5785 --- /dev/null +++ b/hotgo-server/app/model/context.go @@ -0,0 +1,40 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package model + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" +) + +// Context 请求上下文结构 +type Context struct { + ReqId string // 上下文ID + Module string // 应用模块 + TakeUpTime int64 // 请求耗时 ms + Request *ghttp.Request // 当前Request管理对象 + User *Identity // 上下文用户信息 + ComResponse *Response // 组件响应 + Data g.Map // 自定KV变量,业务模块根据需要设置,不固定 +} + +// 通用身份模型 +type Identity struct { + Id int64 `json:"id" description:"会员ID"` + Username string `json:"username" description:"用户名"` + Realname string `json:"realname" description:"昵称"` + Avatar string `json:"avatar" description:"头像"` + Email string `json:"email" description:"邮箱"` + Mobile string `json:"mobile" description:"手机号码"` + VisitCount uint `json:"visit_count" description:"访问次数"` + LastTime int `json:"last_time" description:"最后一次登录时间"` + LastIp string `json:"last_ip" description:"最后一次登录ip"` + Role int64 `json:"role" description:"权限"` + Exp int64 `json:"exp" description:"登录有效期截止时间戳"` + Expires int64 `json:"expires" description:"登录有效期"` + App string `json:"app" description:"登录应用"` +} diff --git a/hotgo-server/app/model/entity/admin_dept.go b/hotgo-server/app/model/entity/admin_dept.go new file mode 100644 index 0000000..035b774 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_dept.go @@ -0,0 +1,26 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminDept is the golang structure for table admin_dept. +type AdminDept struct { + Id int64 `json:"id" description:"部门id"` + Pid int64 `json:"pid" description:"父部门id"` + Ancestors string `json:"ancestors" description:"祖级列表"` + Name string `json:"name" description:"部门名称"` + Code string `json:"code" description:"部门编码"` + Type string `json:"type" description:"部门类型"` + Leader string `json:"leader" description:"负责人"` + Phone string `json:"phone" description:"联系电话"` + Email string `json:"email" description:"邮箱"` + Sort int `json:"sort" description:"排序"` + Status string `json:"status" description:"部门状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/admin_member.go b/hotgo-server/app/model/entity/admin_member.go new file mode 100644 index 0000000..9db55bc --- /dev/null +++ b/hotgo-server/app/model/entity/admin_member.go @@ -0,0 +1,42 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminMember is the golang structure for table admin_member. +type AdminMember struct { + Id int64 `json:"id" description:""` + DeptId int64 `json:"dept_id" description:"部门ID"` + Username string `json:"username" description:"帐号"` + PasswordHash string `json:"password_hash" description:"密码"` + Salt string `json:"salt" description:"密码盐"` + AuthKey string `json:"auth_key" description:"授权令牌"` + PasswordResetToken string `json:"password_reset_token" description:"密码重置令牌"` + Type string `json:"type" description:"1:普通管理员;10超级管理员"` + Realname string `json:"realname" description:"真实姓名"` + Avatar string `json:"avatar" description:"头像"` + Sex string `json:"sex" description:"性别[0:未知;1:男;2:女]"` + Qq string `json:"qq" description:"qq"` + Email string `json:"email" description:"邮箱"` + Birthday *gtime.Time `json:"birthday" description:"生日"` + ProvinceId int `json:"province_id" description:"省"` + CityId int `json:"city_id" description:"城市"` + AreaId int `json:"area_id" description:"地区"` + Address string `json:"address" description:"默认地址"` + Mobile string `json:"mobile" description:"手机号码"` + HomePhone string `json:"home_phone" description:"家庭号码"` + DingtalkRobotToken string `json:"dingtalk_robot_token" description:"钉钉机器人token"` + VisitCount uint `json:"visit_count" description:"访问次数"` + LastTime int `json:"last_time" description:"最后一次登录时间"` + LastIp string `json:"last_ip" description:"最后一次登录ip"` + Role int64 `json:"role" description:"权限"` + Remark string `json:"remark" description:"备注"` + Status string `json:"status" description:"状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"修改时间"` +} diff --git a/hotgo-server/app/model/entity/admin_member_post.go b/hotgo-server/app/model/entity/admin_member_post.go new file mode 100644 index 0000000..88aaba2 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_member_post.go @@ -0,0 +1,11 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// AdminMemberPost is the golang structure for table admin_member_post. +type AdminMemberPost struct { + MemberId int64 `json:"member_id" description:"用户ID"` + PostId int64 `json:"post_id" description:"岗位ID"` +} diff --git a/hotgo-server/app/model/entity/admin_member_role.go b/hotgo-server/app/model/entity/admin_member_role.go new file mode 100644 index 0000000..13a81b0 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_member_role.go @@ -0,0 +1,11 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// AdminMemberRole is the golang structure for table admin_member_role. +type AdminMemberRole struct { + MemberId int64 `json:"member_id" description:"用户ID"` + RoleId int64 `json:"role_id" description:"角色ID"` +} diff --git a/hotgo-server/app/model/entity/admin_menu.go b/hotgo-server/app/model/entity/admin_menu.go new file mode 100644 index 0000000..cc16576 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_menu.go @@ -0,0 +1,33 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminMenu is the golang structure for table admin_menu. +type AdminMenu struct { + Id int64 `json:"id" description:"菜单ID"` + Pid int64 `json:"pid" description:"父菜单ID"` + Name string `json:"name" description:"菜单名称"` + Code string `json:"code" description:"菜单编码"` + Icon string `json:"icon" description:"菜单图标"` + Type string `json:"type" description:"菜单类型(M目录 C菜单 F按钮)"` + Perms string `json:"perms" description:"权限标识"` + Path string `json:"path" description:"路由地址"` + Component string `json:"component" description:"组件路径"` + Query string `json:"query" description:"路由参数"` + IsFrame string `json:"is_frame" description:"是否内嵌"` + IsCache string `json:"is_cache" description:"是否不缓存"` + IsVisible string `json:"is_visible" description:"是否隐藏"` + Remark string `json:"remark" description:"备注"` + Level int `json:"level" description:"级别"` + Tree string `json:"tree" description:"树"` + Sort int `json:"sort" description:"排序"` + Status string `json:"status" description:"菜单状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/admin_menu_old.go b/hotgo-server/app/model/entity/admin_menu_old.go new file mode 100644 index 0000000..ea8d422 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_menu_old.go @@ -0,0 +1,32 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminMenuOld is the golang structure for table admin_menu_old. +type AdminMenuOld struct { + Id int64 `json:"id" description:"菜单ID"` + Pid int64 `json:"pid" description:"父菜单ID"` + Name string `json:"name" description:"菜单名称"` + Icon string `json:"icon" description:"菜单图标"` + Type string `json:"type" description:"菜单类型(M目录 C菜单 F按钮)"` + Perms string `json:"perms" description:"权限标识"` + Path string `json:"path" description:"路由地址"` + Component string `json:"component" description:"组件路径"` + Query string `json:"query" description:"路由参数"` + IsFrame int `json:"is_frame" description:"是否为外链(0是 1否)"` + IsCache int `json:"is_cache" description:"是否缓存(0缓存 1不缓存)"` + IsVisible int `json:"is_visible" description:"菜单状态(0显示 1隐藏)"` + Remark string `json:"remark" description:"备注"` + Level int `json:"level" description:"级别"` + Tree string `json:"tree" description:"树"` + Sort int `json:"sort" description:"排序"` + Status int `json:"status" description:"菜单状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/admin_notice.go b/hotgo-server/app/model/entity/admin_notice.go new file mode 100644 index 0000000..355c0d1 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_notice.go @@ -0,0 +1,21 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminNotice is the golang structure for table admin_notice. +type AdminNotice struct { + Id int64 `json:"id" description:"公告ID"` + Title string `json:"title" description:"公告标题"` + Type string `json:"type" description:"公告类型(1通知 2公告)"` + Content string `json:"content" description:"公告内容"` + Remark string `json:"remark" description:"备注"` + Status string `json:"status" description:"公告状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/admin_post.go b/hotgo-server/app/model/entity/admin_post.go new file mode 100644 index 0000000..935a099 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_post.go @@ -0,0 +1,21 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminPost is the golang structure for table admin_post. +type AdminPost struct { + Id int64 `json:"id" description:"岗位ID"` + Code string `json:"code" description:"岗位编码"` + Name string `json:"name" description:"岗位名称"` + Remark string `json:"remark" description:"备注"` + Sort int `json:"sort" description:"显示顺序"` + Status string `json:"status" description:"状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/admin_role.go b/hotgo-server/app/model/entity/admin_role.go new file mode 100644 index 0000000..2f0f92c --- /dev/null +++ b/hotgo-server/app/model/entity/admin_role.go @@ -0,0 +1,24 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminRole is the golang structure for table admin_role. +type AdminRole struct { + Id int64 `json:"id" description:"角色ID"` + Name string `json:"name" description:"角色名称"` + Key string `json:"key" description:"角色权限字符串"` + DataScope int `json:"data_scope" description:"数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)"` + MenuCheckStrictly int `json:"menu_check_strictly" description:"菜单树选择项是否关联显示"` + DeptCheckStrictly int `json:"dept_check_strictly" description:"部门树选择项是否关联显示"` + Remark string `json:"remark" description:"备注"` + Sort int `json:"sort" description:"排序"` + Status string `json:"status" description:"角色状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/admin_role_dept.go b/hotgo-server/app/model/entity/admin_role_dept.go new file mode 100644 index 0000000..7a65652 --- /dev/null +++ b/hotgo-server/app/model/entity/admin_role_dept.go @@ -0,0 +1,11 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// AdminRoleDept is the golang structure for table admin_role_dept. +type AdminRoleDept struct { + RoleId int64 `json:"role_id" description:"角色ID"` + DeptId int64 `json:"dept_id" description:"部门ID"` +} diff --git a/hotgo-server/app/model/entity/admin_role_menu.go b/hotgo-server/app/model/entity/admin_role_menu.go new file mode 100644 index 0000000..47d3e9b --- /dev/null +++ b/hotgo-server/app/model/entity/admin_role_menu.go @@ -0,0 +1,11 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// AdminRoleMenu is the golang structure for table admin_role_menu. +type AdminRoleMenu struct { + RoleId int64 `json:"role_id" description:"角色ID"` + MenuId int64 `json:"menu_id" description:"菜单ID"` +} diff --git a/hotgo-server/app/model/entity/sys_config.go b/hotgo-server/app/model/entity/sys_config.go new file mode 100644 index 0000000..2fc7844 --- /dev/null +++ b/hotgo-server/app/model/entity/sys_config.go @@ -0,0 +1,22 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysConfig is the golang structure for table sys_config. +type SysConfig struct { + Id int64 `json:"id" description:"配置ID"` + Name string `json:"name" description:"参数名称"` + Key string `json:"key" description:"参数键名"` + Value string `json:"value" description:"参数键值"` + IsDefault string `json:"is_default" description:"是否默认"` + Status string `json:"status" description:"状态"` + Remark string `json:"remark" description:"备注"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/sys_dict_data.go b/hotgo-server/app/model/entity/sys_dict_data.go new file mode 100644 index 0000000..3a66971 --- /dev/null +++ b/hotgo-server/app/model/entity/sys_dict_data.go @@ -0,0 +1,24 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictData is the golang structure for table sys_dict_data. +type SysDictData struct { + Id int64 `json:"id" description:"字典编码"` + Label string `json:"label" description:"字典标签"` + Value string `json:"value" description:"字典键值"` + Type string `json:"type" description:"字典类型"` + ListClass string `json:"list_class" description:"表格回显样式"` + IsDefault string `json:"is_default" description:"是否默认"` + Sort int `json:"sort" description:"字典排序"` + Remark string `json:"remark" description:"备注"` + Status string `json:"status" description:"状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/sys_dict_type.go b/hotgo-server/app/model/entity/sys_dict_type.go new file mode 100644 index 0000000..51a247e --- /dev/null +++ b/hotgo-server/app/model/entity/sys_dict_type.go @@ -0,0 +1,21 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictType is the golang structure for table sys_dict_type. +type SysDictType struct { + Id int64 `json:"id" description:"字典主键"` + Name string `json:"name" description:"字典名称"` + Type string `json:"type" description:"字典类型"` + Sort int `json:"sort" description:"排序"` + Remark string `json:"remark" description:"备注"` + Status string `json:"status" description:"状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"` +} diff --git a/hotgo-server/app/model/entity/sys_log.go b/hotgo-server/app/model/entity/sys_log.go new file mode 100644 index 0000000..7205ee3 --- /dev/null +++ b/hotgo-server/app/model/entity/sys_log.go @@ -0,0 +1,36 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysLog is the golang structure for table sys_log. +type SysLog struct { + Id int64 `json:"id" description:""` + AppId string `json:"app_id" description:"应用id"` + MerchantId uint `json:"merchant_id" description:"商户id"` + MemberId int `json:"member_id" description:"用户id"` + Method string `json:"method" description:"提交类型"` + Module string `json:"module" description:"模块"` + Url string `json:"url" description:"提交url"` + GetData string `json:"get_data" description:"get数据"` + PostData string `json:"post_data" description:"post数据"` + HeaderData string `json:"header_data" description:"header数据"` + Ip string `json:"ip" description:"ip地址"` + ProvinceId int `json:"province_id" description:"省编码"` + CityId int `json:"city_id" description:"市编码"` + ErrorCode int `json:"error_code" description:"报错code"` + ErrorMsg string `json:"error_msg" description:"报错信息"` + ErrorData string `json:"error_data" description:"报错日志"` + ReqId string `json:"req_id" description:"对外id"` + Timestamp int `json:"timestamp" description:"响应时间"` + UserAgent string `json:"user_agent" description:"UA信息"` + TakeUpTime int64 `json:"take_up_time" description:"请求耗时"` + Status string `json:"status" description:"状态"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updated_at" description:"修改时间"` +} diff --git a/hotgo-server/app/model/entity/sys_provinces.go b/hotgo-server/app/model/entity/sys_provinces.go new file mode 100644 index 0000000..1c56a52 --- /dev/null +++ b/hotgo-server/app/model/entity/sys_provinces.go @@ -0,0 +1,21 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// SysProvinces is the golang structure for table sys_provinces. +type SysProvinces struct { + Id int `json:"id" description:"ID"` + Title string `json:"title" description:"栏目名"` + Pid int `json:"pid" description:"父栏目"` + ShortTitle string `json:"short_title" description:"缩写"` + Areacode int `json:"areacode" description:"区域编码"` + Zipcode int `json:"zipcode" description:"邮政编码"` + Pinyin string `json:"pinyin" description:"拼音"` + Lng string `json:"lng" description:"经度"` + Lat string `json:"lat" description:"纬度"` + Level int `json:"level" description:"级别"` + Tree string `json:"tree" description:""` + Sort uint `json:"sort" description:"排序"` +} diff --git a/hotgo-server/app/model/response.go b/hotgo-server/app/model/response.go new file mode 100644 index 0000000..7363b09 --- /dev/null +++ b/hotgo-server/app/model/response.go @@ -0,0 +1,17 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package model + +// HTTP响应 +type Response struct { + Code int `json:"code" example:"0" description:"状态码"` + Message string `json:"message" example:"操作成功" description:"提示消息"` + Data interface{} `json:"data" description:"数据集"` + Error interface{} `json:"error" description:"错误信息"` + Timestamp int64 `json:"timestamp" example:"1640966400" description:"服务器时间戳"` + ReqId string `json:"req_id" v:"0" example:"d0bb93048bc5c9164cdee845dcb7f820" description:"唯一请求ID"` +} diff --git a/hotgo-server/app/model/tree.go b/hotgo-server/app/model/tree.go new file mode 100644 index 0000000..cf722ec --- /dev/null +++ b/hotgo-server/app/model/tree.go @@ -0,0 +1,23 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package model + +import "github.com/bufanyun/hotgo/app/model/entity" + +// 菜单树 +type TreeMenu struct { + entity.AdminMenu + Children []*TreeMenu `json:"children"` +} + +// 菜单kl树 +type LabelTreeMenu struct { + entity.AdminMenu + Key int64 `json:"key" description:"键名"` + Label string `json:"label" description:"键标签"` + Children []*LabelTreeMenu `json:"children"` +} diff --git a/hotgo-server/app/service/adminService/dept_service.go b/hotgo-server/app/service/adminService/dept_service.go new file mode 100644 index 0000000..7fb351f --- /dev/null +++ b/hotgo-server/app/service/adminService/dept_service.go @@ -0,0 +1,358 @@ +package adminService + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/util/gconv" +) + +var Dept = dept{} + +type dept struct{} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *dept) NameUnique(ctx context.Context, in input.AdminDeptNameUniqueInp) (*input.AdminDeptNameUniqueModel, error) { + + var res input.AdminDeptNameUniqueModel + isUnique, err := dao.AdminDept.IsUniqueName(ctx, in.Id, in.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *dept) Delete(ctx context.Context, in input.AdminDeptDeleteInp) error { + + exist, err := dao.AdminRoleDept.Ctx(ctx).Where("dept_id", in.Id).One() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !exist.IsEmpty() { + return gerror.New("请先解除该部门下所有已关联用户关联关系!") + } + _, err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *dept) Edit(ctx context.Context, in input.AdminDeptEditInp) (err error) { + + if in.Name == "" { + err = gerror.New("名称不能为空") + return err + } + + uniqueName, err := dao.AdminDept.IsUniqueName(ctx, in.Id, in.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueName { + err = gerror.New("名称已存在") + return err + } + + // 修改 + in.UpdatedAt = gtime.Now() + if in.Id > 0 { + _, err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Data(in).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil + } + + // 新增 + in.CreatedAt = gtime.Now() + _, err = dao.AdminDept.Ctx(ctx).Data(in).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + return nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *dept) MaxSort(ctx context.Context, in input.AdminDeptMaxSortInp) (*input.AdminDeptMaxSortModel, error) { + var res input.AdminDeptMaxSortModel + + if in.Id > 0 { + if err := dao.AdminDept.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + } + + res.Sort = res.Sort + 10 + + return &res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *dept) View(ctx context.Context, in input.AdminDeptViewInp) (res *input.AdminDeptViewModel, err error) { + + if err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *dept) List(ctx context.Context, in input.AdminDeptListInp) (list []*input.AdminDeptListModel, err error) { + + mod := dao.AdminDept.Ctx(ctx) + + var ( + dataList []*entity.AdminDept + models []*DeptTree + //searchResult []*entity.AdminDept + //id int64 + //ids []int64 + ) + + // 部门名称 + if in.Name != "" { + //err = dao.AdminDept.Ctx(ctx).WhereLike("name", "%"+in.Name+"%").Scan(&searchResult) + //if err != nil { + // err = gerror.Wrap(err, consts.ErrorORM) + // return nil, err + //} + //for i := 0; i < len(searchResult); i++ { + // id, err = dao.AdminDept.TopPid(ctx, searchResult[i]) + // ids = append(ids, id) + //} + // + //if len(ids) == 0 { + // return nil, nil + //} + //mod = mod.Where("id", ids) + } + + err = mod.Order("id desc").Scan(&dataList) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, err + } + + _ = gconv.Structs(dataList, &models) + + childIds := service.getDeptChildIds(ctx, models, 0) + + _ = gconv.Structs(childIds, &list) + + return list, nil +} + +type DeptTree struct { + entity.AdminDept + Children []*DeptTree `json:"children"` +} + +// +// @Title 将列表转为父子关系列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param lists +// @Param pid +// @Return []*RelationTree +// +func (service *dept) getDeptChildIds(ctx context.Context, lists []*DeptTree, pid int64) []*DeptTree { + + var ( + count = len(lists) + newLists []*DeptTree + ) + + if count == 0 { + return nil + } + + for i := 0; i < len(lists); i++ { + if lists[i].Id > 0 && lists[i].Pid == pid { + var row *DeptTree + if err := gconv.Structs(lists[i], &row); err != nil { + panic(err) + } + row.Children = service.getDeptChildIds(ctx, lists, row.Id) + newLists = append(newLists, row) + } + } + + return newLists +} + +type DeptListTree struct { + Id int64 `json:"id" ` + Key int64 `json:"key" ` + Pid int64 `json:"pid" ` + Label string `json:"label"` + Title string `json:"title"` + Name string `json:"name"` + Type string `json:"type"` + Children []*DeptListTree `json:"children"` +} + +// +// @Title 获取列表树 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *dept) ListTree(ctx context.Context, in input.AdminDeptListTreeInp) (list []*input.AdminDeptListTreeModel, err error) { + + mod := dao.AdminDept.Ctx(ctx) + + var ( + dataList []*entity.AdminDept + models []*DeptListTree + ) + + err = mod.Order("id desc").Scan(&dataList) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, err + } + + _ = gconv.Structs(dataList, &models) + + // TODO 重写树入参 + for i := 0; i < len(models); i++ { + models[i].Key = models[i].Id + models[i].Title = models[i].Name + models[i].Label = models[i].Name + } + + childIds := service.getDeptTreeChildIds(ctx, models, 0) + + _ = gconv.Structs(childIds, &list) + + return list, nil +} + +// +// @Title 将列表转为父子关系列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param lists +// @Param pid +// @Return []*RelationTree +// +func (service *dept) getDeptTreeChildIds(ctx context.Context, lists []*DeptListTree, pid int64) []*DeptListTree { + + var ( + count = len(lists) + newLists []*DeptListTree + ) + + if count == 0 { + return nil + } + + for i := 0; i < len(lists); i++ { + if lists[i].Id > 0 && lists[i].Pid == pid { + var row *DeptListTree + if err := gconv.Structs(lists[i], &row); err != nil { + panic(err) + } + row.Children = service.getDeptTreeChildIds(ctx, lists, row.Id) + newLists = append(newLists, row) + } + } + + return newLists +} + +// +// @Title 获取部门名称 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Return name +// @Return err +// +func (service *dept) GetName(ctx context.Context, id int64) (name string, err error) { + + var data entity.AdminDept + + err = dao.AdminDept.Ctx(ctx). + Where("id", id). + Fields("name"). + Scan(&data) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return name, err + } + + return data.Name, nil +} diff --git a/hotgo-server/app/service/adminService/member_post_service.go b/hotgo-server/app/service/adminService/member_post_service.go new file mode 100644 index 0000000..41304ba --- /dev/null +++ b/hotgo-server/app/service/adminService/member_post_service.go @@ -0,0 +1,67 @@ +package adminService + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" +) + +var MemberPost = new(memberPost) + +type memberPost struct{} + +func (service *memberPost) UpdatePostIds(ctx context.Context, member_id int64, post_ids []int64) (err error) { + _, err = dao.AdminMemberPost.Ctx(ctx). + Where("member_id", member_id). + Delete() + if err != nil { + err = gerror.Wrap(err, "删除失败") + return err + } + + for i := 0; i < len(post_ids); i++ { + _, err = dao.AdminMemberPost.Ctx(ctx). + Insert(entity.AdminMemberPost{ + MemberId: member_id, + PostId: post_ids[i], + }) + if err != nil { + err = gerror.Wrap(err, "插入会员岗位失败") + return err + } + } + + return nil +} + +// +// @Title 获取指定会员的岗位ids +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param member_id +// @Return post_ids +// @Return err +// +func (service *memberPost) GetMemberByIds(ctx context.Context, member_id int64) (post_ids []int64, err error) { + + var list []*entity.AdminMemberPost + err = dao.AdminMemberPost.Ctx(ctx). + Fields("post_id"). + Where("member_id", member_id). + Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return post_ids, err + } + + for i := 0; i < len(list); i++ { + post_ids = append(post_ids, list[i].PostId) + } + + g.Log().Print(ctx, "post_ids:", post_ids) + return post_ids, nil +} diff --git a/hotgo-server/app/service/adminService/member_service.go b/hotgo-server/app/service/adminService/member_service.go new file mode 100644 index 0000000..2f1b7ef --- /dev/null +++ b/hotgo-server/app/service/adminService/member_service.go @@ -0,0 +1,657 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminService + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/bufanyun/hotgo/app/service/internal/dto" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/util/gconv" + "github.com/gogf/gf/v2/util/grand" +) + +var Member = new(member) + +type member struct{} + +// +// @Title 修改登录密码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *member) UpdateProfile(ctx context.Context, in input.AdminMemberUpdateProfileInp) (err error) { + + memberId := com.Context.Get(ctx).User.Id + if memberId <= 0 { + err := gerror.New("获取用户信息失败!") + return err + } + + var memberInfo entity.AdminMember + if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + _, err = dao.AdminMember.Ctx(ctx). + Where("id", memberId). + Data(g.Map{ + "mobile": in.Mobile, + "email": in.Email, + "realname": in.Realname, + }). + Update() + + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return +} + +// +// @Title 修改登录密码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *member) UpdatePwd(ctx context.Context, in input.AdminMemberUpdatePwdInp) (err error) { + + var memberInfo entity.AdminMember + if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&memberInfo); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + if gmd5.MustEncryptString(in.OldPassword+memberInfo.Salt) != memberInfo.PasswordHash { + err = gerror.New("原密码不正确") + return err + } + + _, err = dao.AdminMember.Ctx(ctx). + Where("id", in.Id). + Data(g.Map{ + "password_hash": gmd5.MustEncryptString(in.NewPassword + memberInfo.Salt), + "updated_at": gtime.Now(), + }). + Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return +} + +// +// @Title 重置密码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *member) ResetPwd(ctx context.Context, in input.AdminMemberResetPwdInp) (err error) { + + var memberInfo entity.AdminMember + if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&memberInfo); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + _, err = dao.AdminMember.Ctx(ctx). + Where("id", in.Id). + Data(g.Map{ + "password_hash": gmd5.MustEncryptString(in.Password + memberInfo.Salt), + "updated_at": gtime.Now(), + }). + Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return +} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *member) EmailUnique(ctx context.Context, in input.AdminMemberEmailUniqueInp) (*input.AdminMemberEmailUniqueModel, error) { + + var res input.AdminMemberEmailUniqueModel + isUnique, err := dao.AdminMember.IsUniqueEmail(ctx, in.Id, in.Email) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + return &res, nil +} + +// +// @Title 手机号是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *member) MobileUnique(ctx context.Context, in input.AdminMemberMobileUniqueInp) (*input.AdminMemberMobileUniqueModel, error) { + + var res input.AdminMemberMobileUniqueModel + isUnique, err := dao.AdminMember.IsUniqueMobile(ctx, in.Id, in.Mobile) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + return &res, nil +} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *member) NameUnique(ctx context.Context, in input.AdminMemberNameUniqueInp) (*input.AdminMemberNameUniqueModel, error) { + + var res input.AdminMemberNameUniqueModel + isUnique, err := dao.AdminMember.IsUniqueName(ctx, in.Id, in.Username) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *member) Delete(ctx context.Context, in input.AdminMemberDeleteInp) error { + + exist, err := dao.AdminMember.Ctx(ctx).Where("member_id", in.Id).One() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !exist.IsEmpty() { + return gerror.New("请先解除该部门下所有已关联用户关联关系!") + } + _, err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *member) Edit(ctx context.Context, in input.AdminMemberEditInp) (err error) { + + if in.Username == "" { + err = gerror.New("帐号不能为空") + return err + } + + uniqueName, err := dao.AdminMember.IsUniqueName(ctx, in.Id, in.Username) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueName { + err = gerror.New("帐号已存在") + return err + } + + if in.Mobile != "" { + uniqueMobile, err := dao.AdminMember.IsUniqueMobile(ctx, in.Id, in.Mobile) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueMobile { + err = gerror.New("手机号已存在") + return err + } + } + + if in.Email != "" { + uniqueEmail, err := dao.AdminMember.IsUniqueMobile(ctx, in.Id, in.Email) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueEmail { + err = gerror.New("邮箱已存在") + return err + } + } + + // 修改 + in.UpdatedAt = gtime.Now() + if in.Id > 0 { + _, err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Data(in).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + // 更新岗位 + err = MemberPost.UpdatePostIds(ctx, in.Id, in.PostIds) + if err != nil { + return err + } + return nil + } + + // 新增 + in.CreatedAt = gtime.Now() + + // 新增用户时的额外属性 + var data input.AdminMemberAddInp + data.AdminMemberEditInp = in + data.Salt = grand.S(6) + data.PasswordHash = gmd5.MustEncryptString(data.Password + data.Salt) + + g.Log().Print(ctx, "data.Salt:", data) + insert, err := dao.AdminMember.Ctx(ctx).Data(data).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + // 更新岗位 + id, err := insert.LastInsertId() + if err != nil { + return err + } + err = MemberPost.UpdatePostIds(ctx, id, in.PostIds) + if err != nil { + return err + } + return nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *member) MaxSort(ctx context.Context, in input.AdminMemberMaxSortInp) (*input.AdminMemberMaxSortModel, error) { + var res input.AdminMemberMaxSortModel + + if in.Id > 0 { + if err := dao.AdminMember.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + } + + res.Sort = res.Sort + 10 + + return &res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *member) View(ctx context.Context, in input.AdminMemberViewInp) (res *input.AdminMemberViewModel, err error) { + + if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *member) List(ctx context.Context, in input.AdminMemberListInp) (list []*input.AdminMemberListModel, totalCount int, err error) { + + var authorization = com.Jwt.GetAuthorization(com.Context.Get(ctx).Request) + // TODO 获取jwtToken + jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization) + g.Log().Print(ctx, "jwtToken:", jwtToken) + + mod := dao.AdminMember.Ctx(ctx) + + if in.Realname != "" { + mod = mod.WhereLike("realname", "%"+in.Realname+"%") + } + if in.Username != "" { + mod = mod.WhereLike("username", "%"+in.Username+"%") + } + if in.Mobile > 0 { + mod = mod.Where("mobile", in.Mobile) + } + if in.Status > 0 { + mod = mod.Where("status", in.Status) + } + if in.DeptId > 0 { + mod = mod.Where("dept_id", in.DeptId) + } + + // 日期范围 + if in.StartTime != "" { + mod = mod.WhereGTE("created_at", in.StartTime) + } + if in.EndTime != "" { + mod = mod.WhereLTE("created_at", in.EndTime) + } + + totalCount, err = mod.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + // TODO 重写树入参 + for i := 0; i < len(list); i++ { + // TODO 部门 + deptName, err := dao.AdminDept.Ctx(ctx). + Fields("name"). + Where("id", list[i].DeptId). + Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + list[i].DeptName = deptName.String() + + // TODO 角色 + roleName, err := dao.AdminRole.Ctx(ctx). + Fields("name"). + Where("id", list[i].Role). + Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + list[i].RoleName = roleName.String() + } + + return list, totalCount, err +} + +// // +// @Title 获取登录用户信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *member) LoginMemberInfo(ctx context.Context, req *adminForm.MemberInfoReq) (res *adminForm.MemberInfoRes, err error) { + + var ( + defaultPortalConfig adminForm.PortalConfig + defaultPortalConfigs []*adminForm.PortalConfig + configContent adminForm.PortalConfigContent + configContents []*adminForm.PortalConfigContent + configContentOptions []*adminForm.PortalConfigContentOptions + Options adminForm.PortalConfigContentOptions + ) + + g.Log().Print(ctx, "测试") + + // TODO 配置内容选项 + Options.TitleRequired = true + Options.Refresh = 1 + configContentOptions = append(configContentOptions, &Options) + + // TODO 配置内容 + configContent.Options = configContentOptions + configContent.Id = 1 + configContent.X = 0 + configContent.Y = 0 + configContent.W = 3 + configContent.H = 262 + configContent.I = 1 + configContent.Key = "kuaijierukou" + configContent.IsShowTitle = "N" + configContent.IsAllowDrag = false + configContent.Name = "快捷入口" + configContent.Type = "smallPage" + configContent.Url = "dashboard/portal/CommonUse" + configContent.Moved = true + + configContents = append(configContents, &configContent) + + // TODO 默认配置 + defaultPortalConfig.Id = "4ae60dd1debe462096698e1da993317a" + defaultPortalConfig.Name = "首页" + defaultPortalConfig.Code = "6c297eb4651940edbb45c87c75be00d7" + defaultPortalConfig.ApplicationRange = "U" + defaultPortalConfig.IsDefault = "Y" + defaultPortalConfig.ResourceId = "1" + defaultPortalConfig.SystemDefinedId = "app1" + defaultPortalConfig.PortalConfigContent = gconv.String(configContents) + + defaultPortalConfigs = append(defaultPortalConfigs, &defaultPortalConfig) + + member := com.Context.Get(ctx).User + + noticeList, err := Notice.WhereAll(ctx, dto.AdminNotice{ + Status: consts.StatusEnabled, + }) + if err != nil { + noticeList = nil + } + + res = &adminForm.MemberInfoRes{ + LincenseInfo: consts.VersionApp, + Permissions: []string{"*:*:*"}, + Roles: []string{"admin"}, + User: *member, + DefaultPortalConfig: defaultPortalConfigs, + UserPortalConfig: defaultPortalConfigs, + SysNoticeList: noticeList, + } + + return +} + +// +// @Title 提交登录 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *member) Login(ctx context.Context, in input.AdminMemberLoginSignInp) (res *input.AdminMemberLoginSignModel, err error) { + + var member *entity.AdminMember + err = dao.AdminMember.Ctx(ctx).Where("username", in.Username).Scan(&member) + + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return + } + if member == nil { + err = gerror.New(consts.ErrorNotData) + return + } + + if member.Salt == "" { + err = gerror.New("用户信息错误") + return + } + + if member.PasswordHash != gmd5.MustEncryptString(in.Password+member.Salt) { + err = gerror.New("用户密码不正确") + return + } + + // 默认设备 + if in.Device != consts.AppAdmin && in.Device != consts.AppApi { + in.Device = consts.AppAdmin + } + + // TODO 生成token + jwtExpires, err := g.Cfg().Get(ctx, "jwt.expires", 1) + if err != nil { + err := gerror.New(err.Error()) + return nil, err + } + // TODO 有效期 + expires := jwtExpires.Int64() + + // TODO 过期时间戳 + exp := gconv.Int64(gtime.Timestamp()) + expires + + var identity *model.Identity + identity = &model.Identity{ + Id: member.Id, + Username: member.Username, + Realname: member.Realname, + Avatar: member.Avatar, + Email: member.Email, + Mobile: member.Mobile, + VisitCount: member.VisitCount, + LastTime: member.LastTime, + LastIp: member.LastIp, + Role: member.Role, + Exp: exp, + Expires: expires, + App: consts.AppAdmin, + } + token, err := com.Jwt.GenerateLoginToken(ctx, identity, false) + if err != nil { + err = gerror.New(err.Error()) + return + } + + // TODO 更新登录信息 + authKey := gmd5.MustEncryptString(gconv.String(token)) + + _, err = dao.AdminMember.Ctx(ctx).Data(dto.AdminMember{ + AuthKey: gmd5.MustEncryptString(authKey), + VisitCount: member.VisitCount + 1, + LastTime: gtime.Timestamp(), + LastIp: com.Context.Get(ctx).Request.GetClientIp(), + }).Where(dto.AdminMember{ + Id: member.Id, + }).Update() + + if err != nil { + err = gerror.New(err.Error()) + return + } + + res = &input.AdminMemberLoginSignModel{ + Identity: *identity, + Token: gconv.String(token), + } + + return res, nil +} + +// +// @Title 获取角色下的会员列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *member) RoleMemberList(ctx context.Context, in input.AdminRoleMemberListInp) (list []*input.AdminMemberListModel, totalCount int, err error) { + + mod := dao.AdminMember.Ctx(ctx) + if in.Role > 0 { + mod = mod.Where("role", in.Role) + } + + totalCount, err = mod.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + return list, totalCount, err +} diff --git a/hotgo-server/app/service/adminService/menu_service.go b/hotgo-server/app/service/adminService/menu_service.go new file mode 100644 index 0000000..35f9efd --- /dev/null +++ b/hotgo-server/app/service/adminService/menu_service.go @@ -0,0 +1,533 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminService + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/bufanyun/hotgo/app/service/internal/dto" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/util/gconv" +) + +var Menu = new(menu) + +type menu struct{} + +// +// @Title 查询角色菜单列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.MenuSearchListRes +// @Return error +// +func (service *menu) RoleList(ctx context.Context, in input.MenuRoleListInp) (*input.MenuRoleListModel, error) { + + var ( + mod = dao.AdminRoleMenu.Ctx(ctx) + roleMenu []*entity.AdminRoleMenu + lst []*model.LabelTreeMenu + res input.MenuRoleListModel + err error + checkedKeys []int64 + ) + + // TODO 获取选中菜单ID + if in.RoleId > 0 { + mod = mod.Where("role_id", in.RoleId) + } + err = mod.Fields().Scan(&roleMenu) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + for i := 0; i < len(roleMenu); i++ { + checkedKeys = append(checkedKeys, roleMenu[i].MenuId) + } + res.CheckedKeys = checkedKeys + + // TODO 获取菜单树 + lst, err = dao.AdminMenu.GenLabelTreeList(ctx, 0) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + _ = gconv.Structs(lst, &res.Menus) + + return &res, nil +} + +// +// @Title 查询菜单列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.MenuSearchListRes +// @Return error +// +func (service *menu) SearchList(ctx context.Context, req *adminForm.MenuSearchListReq) (*adminForm.MenuSearchListRes, error) { + + var ( + mod = dao.AdminMenu.Ctx(ctx) + lst []*model.TreeMenu + res adminForm.MenuSearchListRes + searchResult []*entity.AdminMenu + id int64 + ids []int64 + err error + ) + + if req.Name != "" { + mod = mod.WhereLike("name", "%"+req.Name+"%") + } + + if req.Status > 0 { + mod = mod.Where("status", req.Status) + } + + if req.Name != "" || req.Status > 0 { + err = mod.Scan(&searchResult) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + for i := 0; i < len(searchResult); i++ { + id, err = dao.AdminMenu.TopPid(ctx, searchResult[i]) + ids = append(ids, id) + } + } + + lst, err = dao.AdminMenu.GenTreeList(ctx, 0, ids) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + _ = gconv.Structs(lst, &res) + + return &res, nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *menu) MaxSort(ctx context.Context, req *adminForm.MenuMaxSortReq) (*adminForm.MenuMaxSortRes, error) { + var ( + res adminForm.MenuMaxSortRes + err error + ) + + if req.Id > 0 { + if err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Order("sort desc").Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + } + + res.Sort = res.Sort + 10 + + return &res, nil +} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *menu) NameUnique(ctx context.Context, req *adminForm.MenuNameUniqueReq) (*adminForm.MenuNameUniqueRes, error) { + var ( + res adminForm.MenuNameUniqueRes + err error + ) + + res.IsUnique, err = dao.AdminMenu.IsUniqueName(ctx, req.Id, req.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 菜单编码是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *menu) CodeUnique(ctx context.Context, req *adminForm.MenuCodeUniqueReq) (*adminForm.MenuCodeUniqueRes, error) { + var ( + res adminForm.MenuCodeUniqueRes + err error + ) + + res.IsUnique, err = dao.AdminMenu.IsUniqueCode(ctx, req.Id, req.Code) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *menu) Delete(ctx context.Context, req *adminForm.MenuDeleteReq) error { + + exist, err := dao.AdminMenu.Ctx(ctx).Where("pid", req.Id).One() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !exist.IsEmpty() { + return gerror.New("请先删除该菜单下的所有菜单!") + } + _, err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *menu) Edit(ctx context.Context, req *adminForm.MenuEditReq) (err error) { + var ( + pidData *dto.AdminMenu + uniqueName bool + uniqueCode bool + ) + + if req.Name == "" { + err = gerror.New("菜单名称不能为空") + return err + } + if req.Path == "" { + err = gerror.New("菜单路径不能为空") + return err + } + if req.Code == "" { + err = gerror.New("菜单编码不能为空") + return err + } + + uniqueName, err = dao.AdminMenu.IsUniqueName(ctx, req.Id, req.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueName { + err = gerror.New("菜单名称已存在") + return err + } + + uniqueCode, err = dao.AdminMenu.IsUniqueCode(ctx, req.Id, req.Code) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueCode { + err = gerror.New("菜单编码已存在") + return err + } + + // TODO 维护菜单等级 + if req.Pid == 0 { + req.Level = 1 + } else { + if err = dao.AdminMenu.Ctx(ctx).Where("id", req.Pid).Scan(&pidData); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if pidData == nil { + return gerror.New("上级菜单信息错误") + } + req.Level = gconv.Int(pidData.Level) + 1 + } + + // 修改 + req.UpdatedAt = gtime.Now() + if req.Id > 0 { + if req.Pid == req.Id { + return gerror.New("上级菜单不能是当前菜单") + } + _, err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Data(req).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil + } + + // 新增 + req.CreatedAt = gtime.Now() + _, err = dao.AdminMenu.Ctx(ctx).Data(req).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + return nil +} + +// +// @Title 获取信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *menu) View(ctx context.Context, req *adminForm.MenuViewReq) (res *adminForm.MenuViewRes, err error) { + //var ( + // res adminForm.MenuViewRes + //) + + if err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return res, nil +} + +// +// @Title 获取菜单列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *menu) List(ctx context.Context, req *adminForm.MenuListReq) (*adminForm.MenuListRes, error) { + var ( + m = dao.AdminMenu.Ctx(ctx) + list []*entity.AdminMenu + res adminForm.MenuListRes + totalCount int + err error + ) + + if req.Pid == 0 { + m = m.Where("level", 1) + } else { + m = m.Where("pid", req.Pid) + } + + totalCount, err = m.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + err = m.Page(req.Page, req.Limit).Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.List = list + res.Page = req.Page + res.Limit = req.Limit + res.TotalCount = totalCount + + return &res, nil +} + +type RelationTree struct { + adminForm.RoleDynamicBase + Children []*RelationTree `json:"children"` +} + +// +// @Title 获取菜单列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param member_id +// +func (service *menu) GetMenuList(ctx context.Context, member_id int64) (lists *adminForm.RoleDynamicRes, err error) { + + var ( + results []*entity.AdminMenu + models []*RelationTree + recursion []*adminForm.RoleDynamicBase + finalResponse adminForm.RoleDynamicRes + ) + + err = dao.AdminMenu.Ctx(ctx).Order("sort asc,id desc").Scan(&results) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + for i := 0; i < len(results); i++ { + + // 元数据 + var ( + meta adminForm.RoleDynamicMeta + rec adminForm.RoleDynamicBase + ) + + meta.Title = results[i].Name + meta.Icon = results[i].Icon + meta.NoCache = gconv.Bool(results[i].IsCache) + meta.Remark = results[i].Remark + + rec.Id = results[i].Id + rec.Pid = results[i].Pid + rec.IsFrame = results[i].IsFrame + rec.Name = results[i].Name + rec.Code = results[i].Code + rec.Path = results[i].Path + rec.Hidden = results[i].IsVisible == "1" + rec.Redirect = service.getRedirect(results[i]) + rec.Component = service.getComponent(results[i]) + rec.AlwaysShow = true + rec.Meta = &meta + + recursion = append(recursion, &rec) + } + + _ = gconv.Structs(recursion, &models) + + childIds := service.getChildIds(ctx, models, 0) + + _ = gconv.Structs(childIds, &finalResponse) + + return &finalResponse, nil +} + +// +// @Title 获取菜单的组件配置 +// @Description +// @Author Ms <133814250@qq.com> +// @Param model +// @Return string +// +func (service *menu) getComponent(mod *entity.AdminMenu) string { + + if mod.Type == "M" { + return "Layout" + } + + if mod.Type == "C" { + return mod.Component + } + + return mod.Component +} + +// +// @Title 获取菜单是否重定向 +// @Description +// @Author Ms <133814250@qq.com> +// @Param model +// @Return string +// +func (service *menu) getRedirect(model *entity.AdminMenu) string { + if model.Type == "M" { + return "noRedirect" + } + + return "" +} + +// +// @Title 将菜单转为父子关系菜单 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param lists +// @Param pid +// @Return []*RelationTree +// +func (service *menu) getChildIds(ctx context.Context, lists []*RelationTree, pid int64) []*RelationTree { + + var ( + count = len(lists) + newLists []*RelationTree + ) + + if count == 0 { + return nil + } + + for i := 0; i < len(lists); i++ { + if lists[i].Id > 0 && lists[i].Pid == pid { + var row *RelationTree + if err := gconv.Structs(lists[i], &row); err != nil { + panic(err) + } + row.Children = service.getChildIds(ctx, lists, row.Id) + newLists = append(newLists, row) + } + } + + return newLists +} + +// +// @Title 根据条件查询一行的数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param where +// @Return *entity.AdminMenu +// +func (service *menu) WhereScan(ctx context.Context, where dto.AdminMenu) *entity.AdminMenu { + var ( + mod *entity.AdminMenu + err error + ) + + if err = dao.AdminMenu.Ctx(ctx).Where(where).Scan(&mod); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil + } + + return mod +} diff --git a/hotgo-server/app/service/adminService/notice_service.go b/hotgo-server/app/service/adminService/notice_service.go new file mode 100644 index 0000000..fbefaed --- /dev/null +++ b/hotgo-server/app/service/adminService/notice_service.go @@ -0,0 +1,263 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminService + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/bufanyun/hotgo/app/service/internal/dto" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/util/gconv" +) + +var Notice = new(notice) + +type notice struct{} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *notice) NameUnique(ctx context.Context, in input.AdminNoticeNameUniqueInp) (*input.AdminNoticeNameUniqueModel, error) { + + var res input.AdminNoticeNameUniqueModel + isUnique, err := dao.AdminNotice.IsUniqueTitle(ctx, in.Id, in.Title) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *notice) Delete(ctx context.Context, in input.AdminNoticeDeleteInp) error { + + _, err := dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *notice) Edit(ctx context.Context, in input.AdminNoticeEditInp) (err error) { + + if in.Title == "" { + err = gerror.New("名称不能为空") + return err + } + + uniqueName, err := dao.AdminNotice.IsUniqueTitle(ctx, in.Id, in.Title) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueName { + err = gerror.New("名称已存在") + return err + } + + // 修改 + in.UpdatedAt = gtime.Now() + if in.Id > 0 { + _, err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Data(in).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil + } + + // 新增 + in.CreatedAt = gtime.Now() + _, err = dao.AdminNotice.Ctx(ctx).Data(in).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + return nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *notice) MaxSort(ctx context.Context, in input.AdminNoticeMaxSortInp) (*input.AdminNoticeMaxSortModel, error) { + var res input.AdminNoticeMaxSortModel + + if in.Id > 0 { + if err := dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + } + + res.Sort = res.Sort + 10 + + return &res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *notice) View(ctx context.Context, in input.AdminNoticeViewInp) (res *input.AdminNoticeViewModel, err error) { + + if err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *notice) List(ctx context.Context, in input.AdminNoticeListInp) (list []*input.AdminNoticeListModel, totalCount int, err error) { + + mod := dao.AdminNotice.Ctx(ctx) + + if in.Realname != "" { + mod = mod.WhereLike("realname", "%"+in.Realname+"%") + } + if in.Username != "" { + mod = mod.WhereLike("username", "%"+in.Username+"%") + } + if in.Mobile > 0 { + mod = mod.Where("mobile", in.Mobile) + } + if in.Status > 0 { + mod = mod.Where("status", in.Status) + } + if in.DeptId > 0 { + mod = mod.Where("dept_id", in.DeptId) + } + + // 日期范围 + if in.StartTime != "" { + mod = mod.WhereGTE("created_at", in.StartTime) + } + if in.EndTime != "" { + mod = mod.WhereLTE("created_at", in.EndTime) + } + + totalCount, err = mod.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + //// TODO 重写树入参 + //for i := 0; i < len(list); i++ { + //} + + return list, totalCount, err +} + +// +// @Title 根据条件查询所有数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param where +// @Return []*entity.AdminNotice +// @Return error +// +func (service *notice) WhereAll(ctx context.Context, where dto.AdminNotice) ([]*entity.AdminNotice, error) { + var ( + model []*entity.AdminNotice + err error + result gdb.Result + ) + result, err = dao.AdminNotice.Ctx(ctx).Where(where).All() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + err = gconv.Scan(result, &model) + if err != nil { + err = gerror.Wrap(err, consts.ErrorRotaPointer) + return nil, err + } + + return model, nil +} + +// +// @Title 根据条件查询一行的数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param where +// @Return *entity.AdminMenu +// +func (service *notice) WhereScan(ctx context.Context, where dto.AdminNotice) *entity.AdminNotice { + var ( + model *entity.AdminNotice + err error + ) + + if err = dao.AdminMenu.Ctx(ctx).Where(where).Scan(&model); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil + } + + return model +} diff --git a/hotgo-server/app/service/adminService/post_service.go b/hotgo-server/app/service/adminService/post_service.go new file mode 100644 index 0000000..2f9414f --- /dev/null +++ b/hotgo-server/app/service/adminService/post_service.go @@ -0,0 +1,274 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminService + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +var Post = new(post) + +type post struct{} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *post) Delete(ctx context.Context, in input.AdminPostDeleteInp) error { + + exist, err := dao.AdminMemberPost.Ctx(ctx).Where("post_id", in.Id).One() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !exist.IsEmpty() { + return gerror.New("请先解除该岗位下所有已关联用户关联关系!") + } + _, err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *post) Edit(ctx context.Context, in input.AdminPostEditInp) (err error) { + + if in.Name == "" { + err = gerror.New("名称不能为空") + return err + } + if in.Code == "" { + err = gerror.New("编码不能为空") + return err + } + + uniqueName, err := dao.AdminPost.IsUniqueName(ctx, in.Id, in.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueName { + err = gerror.New("名称已存在") + return err + } + + uniqueCode, err := dao.AdminPost.IsUniqueCode(ctx, in.Id, in.Code) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueCode { + err = gerror.New("编码已存在") + return err + } + + // 修改 + in.UpdatedAt = gtime.Now() + if in.Id > 0 { + _, err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Data(in).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil + } + + // 新增 + in.CreatedAt = gtime.Now() + _, err = dao.AdminPost.Ctx(ctx).Data(in).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + return nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *post) MaxSort(ctx context.Context, in input.AdminPostMaxSortInp) (*input.AdminPostMaxSortModel, error) { + var res input.AdminPostMaxSortModel + + if in.Id > 0 { + if err := dao.AdminMenu.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + } + + res.Sort = res.Sort + 10 + + return &res, nil +} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *post) NameUnique(ctx context.Context, in input.AdminPostNameUniqueInp) (*input.AdminPostNameUniqueModel, error) { + + var res input.AdminPostNameUniqueModel + isUnique, err := dao.AdminPost.IsUniqueName(ctx, in.Id, in.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + return &res, nil +} + +// +// @Title 编码是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *post) CodeUnique(ctx context.Context, in input.AdminPostCodeUniqueInp) (*input.AdminPostCodeUniqueModel, error) { + + var res input.AdminPostCodeUniqueModel + isUnique, err := dao.AdminPost.IsUniqueCode(ctx, in.Id, in.Code) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + + return &res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *post) View(ctx context.Context, in input.AdminPostViewInp) (res *input.AdminPostViewModel, err error) { + + if err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *post) List(ctx context.Context, in input.AdminPostListInp) (list []*input.AdminPostListModel, totalCount int, err error) { + + mod := dao.AdminPost.Ctx(ctx) + + // 访问路径 + if in.Name != "" { + mod = mod.WhereLike("name", "%"+in.Name+"%") + } + + // 模块 + if in.Code != "" { + mod = mod.Where("code", in.Code) + } + + // 请求方式 + if in.Status > 0 { + mod = mod.Where("status", in.Status) + } + + totalCount, err = mod.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + return list, totalCount, err +} + +// +// @Title 获取指定用户的第一岗位 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param RoleId +// @Return name +// @Return err +// +func (service *post) GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error) { + + // TODO 默认取第一岗位 + postId, err := dao.AdminMemberPost.Ctx(ctx). + Fields("post_id"). + Where("member_id", memberId). + Limit(1). + Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return name, err + } + + val, err := dao.AdminPost.Ctx(ctx). + Fields("name"). + Where("id", postId.Int()). + Order("id desc"). + Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return name, err + } + + return val.String(), nil +} diff --git a/hotgo-server/app/service/adminService/role_service.go b/hotgo-server/app/service/adminService/role_service.go new file mode 100644 index 0000000..48a63f4 --- /dev/null +++ b/hotgo-server/app/service/adminService/role_service.go @@ -0,0 +1,130 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package adminService + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/bufanyun/hotgo/app/service/internal/dto" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" +) + +var Role = new(role) + +type role struct{} + +// +// @Title 验证权限 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param member_id +// @Param path +// @Return bool +// +func (service *role) Verify(ctx context.Context, member_id int, path string) bool { + var ( + err error + ) + + if utils.Auth.IsExceptAuth(ctx, path) { + return true + } + + menu := Menu.WhereScan(ctx, dto.AdminMenu{ + Path: path, + Status: consts.StatusEnabled, + }) + + if menu == nil { + err = gerror.New(consts.ErrorNotData) + return false + } + + g.Log().Print(ctx, "menu:", menu) + g.Log().Print(ctx, "err:", err) + + return true +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *role) List(ctx context.Context, in input.AdminRoleListInp) (list []*input.AdminRoleListModel, totalCount int, err error) { + + mod := dao.AdminRole.Ctx(ctx) + + totalCount, err = mod.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + err = mod.Page(in.Page, in.Limit).Order("id asc").Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + return list, totalCount, err +} + +// +// @Title 获取指定角色的名称 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param RoleId +// @Return name +// @Return err +// +func (service *role) GetName(ctx context.Context, RoleId int64) (name string, err error) { + roleName, err := dao.AdminRole.Ctx(ctx). + Fields("name"). + Where("id", RoleId). + Order("id desc"). + Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return name, err + } + + return roleName.String(), nil +} + +// +// @Title 获取指定会员的岗位列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *role) GetMemberList(ctx context.Context, RoleId int64) (list []*input.AdminRoleListModel, err error) { + + err = dao.AdminRole.Ctx(ctx). + Where("id", RoleId). + Order("id desc"). + Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, err + } + + return list, err +} diff --git a/hotgo-server/app/service/apiService/member_service.go b/hotgo-server/app/service/apiService/member_service.go new file mode 100644 index 0000000..0ea9a02 --- /dev/null +++ b/hotgo-server/app/service/apiService/member_service.go @@ -0,0 +1,23 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package apiService + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" +) + +var Member = new(member) + +type member struct {} + +func (service *member) Test() (ctx context.Context) { + g.Log().Print(ctx, "apiService--WithMember--test...") + + //g.Log().Print(ctx, "api调用:" , service.App.Admin.Member.Test()) + return +} \ No newline at end of file diff --git a/hotgo-server/app/service/internal/dao/admin_dept.go b/hotgo-server/app/service/internal/dao/admin_dept.go new file mode 100644 index 0000000..c3e7a83 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_dept.go @@ -0,0 +1,81 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// adminDeptDao is the data access object for table hg_admin_dept. +// You can define custom methods on it to extend its functionality as you wish. +type adminDeptDao struct { + *internal.AdminDeptDao +} + +var ( + // AdminDept is globally public accessible object for table hg_admin_dept operations. + AdminDept = adminDeptDao{ + internal.NewAdminDeptDao(), + } +) + +// +// @Title 判断名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *adminDeptDao) IsUniqueName(ctx context.Context, id int64, name string) (bool, error) { + var data *entity.AdminDept + m := dao.Ctx(ctx).Where("name", name) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// +// @Title 获取最上级pid +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param data +// @Return int64 +// @Return error +// +func (dao *adminDeptDao) TopPid(ctx context.Context, data *entity.AdminDept) (int64, error) { + var pidData *entity.AdminDept + if data.Pid == 0 { + return data.Id, nil + } + err := dao.Ctx(ctx).Where("id", data.Pid).Scan(&pidData) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return 0, err + } + + return dao.TopPid(ctx, pidData) +} + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_member.go b/hotgo-server/app/service/internal/dao/admin_member.go new file mode 100644 index 0000000..f8b3d61 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_member.go @@ -0,0 +1,118 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// adminMemberDao is the data access object for table hg_admin_member. +// You can define custom methods on it to extend its functionality as you wish. +type adminMemberDao struct { + *internal.AdminMemberDao +} + +var ( + // AdminMember is globally public accessible object for table hg_admin_member operations. + AdminMember = adminMemberDao{ + internal.NewAdminMemberDao(), + } +) + +// +// @Title 判断用户名是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *adminMemberDao) IsUniqueName(ctx context.Context, id int64, name string) (bool, error) { + var data *entity.AdminDept + m := dao.Ctx(ctx).Where("username", name) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// +// @Title 判断邮箱是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *adminMemberDao) IsUniqueEmail(ctx context.Context, id int64, email string) (bool, error) { + var data *entity.AdminMember + m := dao.Ctx(ctx).Where("email", email) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// +// @Title 判断手机号是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *adminMemberDao) IsUniqueMobile(ctx context.Context, id int64, mobile string) (bool, error) { + var data *entity.AdminMember + m := dao.Ctx(ctx).Where("mobile", mobile) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_member_post.go b/hotgo-server/app/service/internal/dao/admin_member_post.go new file mode 100644 index 0000000..8f85887 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_member_post.go @@ -0,0 +1,24 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" +) + +// adminMemberPostDao is the data access object for table hg_admin_member_post. +// You can define custom methods on it to extend its functionality as you wish. +type adminMemberPostDao struct { + *internal.AdminMemberPostDao +} + +var ( + // AdminMemberPost is globally public accessible object for table hg_admin_member_post operations. + AdminMemberPost = adminMemberPostDao{ + internal.NewAdminMemberPostDao(), + } +) + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_member_role.go b/hotgo-server/app/service/internal/dao/admin_member_role.go new file mode 100644 index 0000000..d81409d --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_member_role.go @@ -0,0 +1,24 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" +) + +// adminMemberRoleDao is the data access object for table hg_admin_member_role. +// You can define custom methods on it to extend its functionality as you wish. +type adminMemberRoleDao struct { + *internal.AdminMemberRoleDao +} + +var ( + // AdminMemberRole is globally public accessible object for table hg_admin_member_role operations. + AdminMemberRole = adminMemberRoleDao{ + internal.NewAdminMemberRoleDao(), + } +) + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_menu.go b/hotgo-server/app/service/internal/dao/admin_menu.go new file mode 100644 index 0000000..ac104ce --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_menu.go @@ -0,0 +1,180 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// @Description +type adminMenuDao struct { + *internal.AdminMenuDao // } +} + +var ( + // AdminMenu is globally public accessible object for table hg_admin_menu operations. + AdminMenu = adminMenuDao{ + internal.NewAdminMenuDao(), + } +) + +// +// @Title 判断名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *adminMenuDao) IsUniqueName(ctx context.Context, id int64, name string) (bool, error) { + var data *entity.AdminMenu + m := dao.Ctx(ctx).Where("name", name) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// +// @Title 判断编码是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param code +// @Return bool +// @Return error +// +func (dao *adminMenuDao) IsUniqueCode(ctx context.Context, id int64, code string) (bool, error) { + var data *entity.AdminMenu + m := dao.Ctx(ctx).Where("code", code) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// +// @Title 生成kl树列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param pid +// @Param lists +// @Return []*model.TreeMenu +// @Return error +// +func (dao *adminMenuDao) GenLabelTreeList(ctx context.Context, pid int64) ([]*model.LabelTreeMenu, error) { + + var ( + newLst []*model.LabelTreeMenu + ) + if err := dao.Ctx(ctx).Where("pid", pid).Order("sort asc,id desc").Scan(&newLst); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + for i := 0; i < len(newLst); i++ { + newLst[i].Key = newLst[i].Id + newLst[i].Label = newLst[i].Name + err := dao.Ctx(ctx).Where("pid", newLst[i].Id).Order("sort asc,id desc").Scan(&newLst[i].Children) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + for i2 := 0; i2 < len(newLst[i].Children); i2++ { + newLst[i].Children[i2].Key = newLst[i].Children[i2].Id + newLst[i].Children[i2].Label = newLst[i].Children[i2].Name + } + } + + return newLst, nil +} + +// +// @Title 生成树列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param pid +// @Param lists +// @Return []*model.TreeMenu +// @Return error +// +func (dao *adminMenuDao) GenTreeList(ctx context.Context, pid int64, ids []int64) ([]*model.TreeMenu, error) { + + var ( + newLst []*model.TreeMenu + ) + if err := dao.Ctx(ctx).Where("id", ids).Where("pid", pid).Order("sort asc,id desc").Scan(&newLst); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + for i := 0; i < len(newLst); i++ { + err := dao.Ctx(ctx).Where("pid", newLst[i].Id).Order("sort asc,id desc").Scan(&newLst[i].Children) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + } + + return newLst, nil +} + +// +// @Title 获取最上级pid +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param data +// @Return int64 +// @Return error +// +func (dao *adminMenuDao) TopPid(ctx context.Context, data *entity.AdminMenu) (int64, error) { + var pidData *entity.AdminMenu + if data.Pid == 0 { + return data.Id, nil + } + err := dao.Ctx(ctx).Where("id", data.Pid).Scan(&pidData) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return 0, err + } + + return dao.TopPid(ctx, pidData) +} + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_menu_old.go b/hotgo-server/app/service/internal/dao/admin_menu_old.go new file mode 100644 index 0000000..265e376 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_menu_old.go @@ -0,0 +1,24 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" +) + +// adminMenuOldDao is the data access object for table hg_admin_menu_old. +// You can define custom methods on it to extend its functionality as you wish. +type adminMenuOldDao struct { + *internal.AdminMenuOldDao +} + +var ( + // AdminMenuOld is globally public accessible object for table hg_admin_menu_old operations. + AdminMenuOld = adminMenuOldDao{ + internal.NewAdminMenuOldDao(), + } +) + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_notice.go b/hotgo-server/app/service/internal/dao/admin_notice.go new file mode 100644 index 0000000..b64b4fa --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_notice.go @@ -0,0 +1,58 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// adminNoticeDao is the data access object for table hg_admin_notice. +// You can define custom methods on it to extend its functionality as you wish. +type adminNoticeDao struct { + *internal.AdminNoticeDao +} + +var ( + // AdminNotice is globally public accessible object for table hg_admin_notice operations. + AdminNotice = adminNoticeDao{ + internal.NewAdminNoticeDao(), + } +) + +// Fill with you ideas below. + +// +// @Title 判断名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *adminNoticeDao) IsUniqueTitle(ctx context.Context, id int64, title string) (bool, error) { + var data *entity.AdminNotice + m := dao.Ctx(ctx).Where("title", title) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} diff --git a/hotgo-server/app/service/internal/dao/admin_post.go b/hotgo-server/app/service/internal/dao/admin_post.go new file mode 100644 index 0000000..4184e80 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_post.go @@ -0,0 +1,88 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// adminPostDao is the data access object for table hg_admin_post. +// You can define custom methods on it to extend its functionality as you wish. +type adminPostDao struct { + *internal.AdminPostDao +} + +var ( + // AdminPost is globally public accessible object for table hg_admin_post operations. + AdminPost = adminPostDao{ + internal.NewAdminPostDao(), + } +) + +// Fill with you ideas below. + +// +// @Title 判断名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *adminPostDao) IsUniqueName(ctx context.Context, id int64, name string) (bool, error) { + var data *entity.AdminPost + m := dao.Ctx(ctx).Where("name", name) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// +// @Title 判断编码是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param code +// @Return bool +// @Return error +// +func (dao *adminPostDao) IsUniqueCode(ctx context.Context, id int64, code string) (bool, error) { + var data *entity.AdminPost + m := dao.Ctx(ctx).Where("code", code) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} diff --git a/hotgo-server/app/service/internal/dao/admin_role.go b/hotgo-server/app/service/internal/dao/admin_role.go new file mode 100644 index 0000000..3ef3b48 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_role.go @@ -0,0 +1,24 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" +) + +// adminRoleDao is the data access object for table hg_admin_role. +// You can define custom methods on it to extend its functionality as you wish. +type adminRoleDao struct { + *internal.AdminRoleDao +} + +var ( + // AdminRole is globally public accessible object for table hg_admin_role operations. + AdminRole = adminRoleDao{ + internal.NewAdminRoleDao(), + } +) + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_role_dept.go b/hotgo-server/app/service/internal/dao/admin_role_dept.go new file mode 100644 index 0000000..2626c8b --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_role_dept.go @@ -0,0 +1,29 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +// +// @Package dao +// @Description +// @Author Ms <133814250@qq.com> +// +package dao + +import ( + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" +) + +// adminRoleDeptDao is the data access object for table hg_admin_role_dept. +// You can define custom methods on it to extend its functionality as you wish. +type adminRoleDeptDao struct { + *internal.AdminRoleDeptDao +} + +var ( + // AdminRoleDept is globally public accessible object for table hg_admin_role_dept operations. + AdminRoleDept = adminRoleDeptDao{ + internal.NewAdminRoleDeptDao(), + } +) + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/admin_role_menu.go b/hotgo-server/app/service/internal/dao/admin_role_menu.go new file mode 100644 index 0000000..2bffe60 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/admin_role_menu.go @@ -0,0 +1,24 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" +) + +// adminRoleMenuDao is the data access object for table hg_admin_role_menu. +// You can define custom methods on it to extend its functionality as you wish. +type adminRoleMenuDao struct { + *internal.AdminRoleMenuDao +} + +var ( + // AdminRoleMenu is globally public accessible object for table hg_admin_role_menu operations. + AdminRoleMenu = adminRoleMenuDao{ + internal.NewAdminRoleMenuDao(), + } +) + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/internal/admin_dept.go b/hotgo-server/app/service/internal/dao/internal/admin_dept.go new file mode 100644 index 0000000..ab0226a --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_dept.go @@ -0,0 +1,96 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminDeptDao is the data access object for table hg_admin_dept. +type AdminDeptDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminDeptColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminDeptColumns defines and stores column names for table hg_admin_dept. +type AdminDeptColumns struct { + Id string // 部门id + Pid string // 父部门id + Ancestors string // 祖级列表 + Name string // 部门名称 + Code string // 部门编码 + Type string // 部门类型 + Leader string // 负责人 + Phone string // 联系电话 + Email string // 邮箱 + Sort string // 排序 + Status string // 部门状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// adminDeptColumns holds the columns for table hg_admin_dept. +var adminDeptColumns = AdminDeptColumns{ + Id: "id", + Pid: "pid", + Ancestors: "ancestors", + Name: "name", + Code: "code", + Type: "type", + Leader: "leader", + Phone: "phone", + Email: "email", + Sort: "sort", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewAdminDeptDao creates and returns a new DAO object for table data access. +func NewAdminDeptDao() *AdminDeptDao { + return &AdminDeptDao{ + group: "default", + table: "hg_admin_dept", + columns: adminDeptColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminDeptDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminDeptDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminDeptDao) Columns() AdminDeptColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminDeptDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminDeptDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_member.go b/hotgo-server/app/service/internal/dao/internal/admin_member.go new file mode 100644 index 0000000..f0c629e --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_member.go @@ -0,0 +1,128 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminMemberDao is the data access object for table hg_admin_member. +type AdminMemberDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminMemberColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminMemberColumns defines and stores column names for table hg_admin_member. +type AdminMemberColumns struct { + Id string // + DeptId string // 部门ID + Username string // 帐号 + PasswordHash string // 密码 + Salt string // 密码盐 + AuthKey string // 授权令牌 + PasswordResetToken string // 密码重置令牌 + Type string // 1:普通管理员;10超级管理员 + Realname string // 真实姓名 + Avatar string // 头像 + Sex string // 性别[0:未知;1:男;2:女] + Qq string // qq + Email string // 邮箱 + Birthday string // 生日 + ProvinceId string // 省 + CityId string // 城市 + AreaId string // 地区 + Address string // 默认地址 + Mobile string // 手机号码 + HomePhone string // 家庭号码 + DingtalkRobotToken string // 钉钉机器人token + VisitCount string // 访问次数 + LastTime string // 最后一次登录时间 + LastIp string // 最后一次登录ip + Role string // 权限 + Remark string // 备注 + Status string // 状态 + CreatedAt string // 创建时间 + UpdatedAt string // 修改时间 +} + +// adminMemberColumns holds the columns for table hg_admin_member. +var adminMemberColumns = AdminMemberColumns{ + Id: "id", + DeptId: "dept_id", + Username: "username", + PasswordHash: "password_hash", + Salt: "salt", + AuthKey: "auth_key", + PasswordResetToken: "password_reset_token", + Type: "type", + Realname: "realname", + Avatar: "avatar", + Sex: "sex", + Qq: "qq", + Email: "email", + Birthday: "birthday", + ProvinceId: "province_id", + CityId: "city_id", + AreaId: "area_id", + Address: "address", + Mobile: "mobile", + HomePhone: "home_phone", + DingtalkRobotToken: "dingtalk_robot_token", + VisitCount: "visit_count", + LastTime: "last_time", + LastIp: "last_ip", + Role: "role", + Remark: "remark", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewAdminMemberDao creates and returns a new DAO object for table data access. +func NewAdminMemberDao() *AdminMemberDao { + return &AdminMemberDao{ + group: "default", + table: "hg_admin_member", + columns: adminMemberColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminMemberDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminMemberDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminMemberDao) Columns() AdminMemberColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminMemberDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminMemberDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminMemberDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_member_post.go b/hotgo-server/app/service/internal/dao/internal/admin_member_post.go new file mode 100644 index 0000000..d9492aa --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_member_post.go @@ -0,0 +1,74 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminMemberPostDao is the data access object for table hg_admin_member_post. +type AdminMemberPostDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminMemberPostColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminMemberPostColumns defines and stores column names for table hg_admin_member_post. +type AdminMemberPostColumns struct { + MemberId string // 用户ID + PostId string // 岗位ID +} + +// adminMemberPostColumns holds the columns for table hg_admin_member_post. +var adminMemberPostColumns = AdminMemberPostColumns{ + MemberId: "member_id", + PostId: "post_id", +} + +// NewAdminMemberPostDao creates and returns a new DAO object for table data access. +func NewAdminMemberPostDao() *AdminMemberPostDao { + return &AdminMemberPostDao{ + group: "default", + table: "hg_admin_member_post", + columns: adminMemberPostColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminMemberPostDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminMemberPostDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminMemberPostDao) Columns() AdminMemberPostColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminMemberPostDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminMemberPostDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminMemberPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_member_role.go b/hotgo-server/app/service/internal/dao/internal/admin_member_role.go new file mode 100644 index 0000000..b1b1f7e --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_member_role.go @@ -0,0 +1,74 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminMemberRoleDao is the data access object for table hg_admin_member_role. +type AdminMemberRoleDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminMemberRoleColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminMemberRoleColumns defines and stores column names for table hg_admin_member_role. +type AdminMemberRoleColumns struct { + MemberId string // 用户ID + RoleId string // 角色ID +} + +// adminMemberRoleColumns holds the columns for table hg_admin_member_role. +var adminMemberRoleColumns = AdminMemberRoleColumns{ + MemberId: "member_id", + RoleId: "role_id", +} + +// NewAdminMemberRoleDao creates and returns a new DAO object for table data access. +func NewAdminMemberRoleDao() *AdminMemberRoleDao { + return &AdminMemberRoleDao{ + group: "default", + table: "hg_admin_member_role", + columns: adminMemberRoleColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminMemberRoleDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminMemberRoleDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminMemberRoleDao) Columns() AdminMemberRoleColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminMemberRoleDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminMemberRoleDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminMemberRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_menu.go b/hotgo-server/app/service/internal/dao/internal/admin_menu.go new file mode 100644 index 0000000..54de553 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_menu.go @@ -0,0 +1,110 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminMenuDao is the data access object for table hg_admin_menu. +type AdminMenuDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminMenuColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminMenuColumns defines and stores column names for table hg_admin_menu. +type AdminMenuColumns struct { + Id string // 菜单ID + Pid string // 父菜单ID + Name string // 菜单名称 + Code string // 菜单编码 + Icon string // 菜单图标 + Type string // 菜单类型(M目录 C菜单 F按钮) + Perms string // 权限标识 + Path string // 路由地址 + Component string // 组件路径 + Query string // 路由参数 + IsFrame string // 是否内嵌 + IsCache string // 是否不缓存 + IsVisible string // 是否隐藏 + Remark string // 备注 + Level string // 级别 + Tree string // 树 + Sort string // 排序 + Status string // 菜单状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// adminMenuColumns holds the columns for table hg_admin_menu. +var adminMenuColumns = AdminMenuColumns{ + Id: "id", + Pid: "pid", + Name: "name", + Code: "code", + Icon: "icon", + Type: "type", + Perms: "perms", + Path: "path", + Component: "component", + Query: "query", + IsFrame: "is_frame", + IsCache: "is_cache", + IsVisible: "is_visible", + Remark: "remark", + Level: "level", + Tree: "tree", + Sort: "sort", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewAdminMenuDao creates and returns a new DAO object for table data access. +func NewAdminMenuDao() *AdminMenuDao { + return &AdminMenuDao{ + group: "default", + table: "hg_admin_menu", + columns: adminMenuColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminMenuDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminMenuDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminMenuDao) Columns() AdminMenuColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminMenuDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminMenuDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminMenuDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_menu_old.go b/hotgo-server/app/service/internal/dao/internal/admin_menu_old.go new file mode 100644 index 0000000..a2c50e8 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_menu_old.go @@ -0,0 +1,108 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminMenuOldDao is the data access object for table hg_admin_menu_old. +type AdminMenuOldDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminMenuOldColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminMenuOldColumns defines and stores column names for table hg_admin_menu_old. +type AdminMenuOldColumns struct { + Id string // 菜单ID + Pid string // 父菜单ID + Name string // 菜单名称 + Icon string // 菜单图标 + Type string // 菜单类型(M目录 C菜单 F按钮) + Perms string // 权限标识 + Path string // 路由地址 + Component string // 组件路径 + Query string // 路由参数 + IsFrame string // 是否为外链(0是 1否) + IsCache string // 是否缓存(0缓存 1不缓存) + IsVisible string // 菜单状态(0显示 1隐藏) + Remark string // 备注 + Level string // 级别 + Tree string // 树 + Sort string // 排序 + Status string // 菜单状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// adminMenuOldColumns holds the columns for table hg_admin_menu_old. +var adminMenuOldColumns = AdminMenuOldColumns{ + Id: "id", + Pid: "pid", + Name: "name", + Icon: "icon", + Type: "type", + Perms: "perms", + Path: "path", + Component: "component", + Query: "query", + IsFrame: "is_frame", + IsCache: "is_cache", + IsVisible: "is_visible", + Remark: "remark", + Level: "level", + Tree: "tree", + Sort: "sort", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewAdminMenuOldDao creates and returns a new DAO object for table data access. +func NewAdminMenuOldDao() *AdminMenuOldDao { + return &AdminMenuOldDao{ + group: "default", + table: "hg_admin_menu_old", + columns: adminMenuOldColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminMenuOldDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminMenuOldDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminMenuOldDao) Columns() AdminMenuOldColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminMenuOldDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminMenuOldDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminMenuOldDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_notice.go b/hotgo-server/app/service/internal/dao/internal/admin_notice.go new file mode 100644 index 0000000..384de50 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_notice.go @@ -0,0 +1,86 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminNoticeDao is the data access object for table hg_admin_notice. +type AdminNoticeDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminNoticeColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminNoticeColumns defines and stores column names for table hg_admin_notice. +type AdminNoticeColumns struct { + Id string // 公告ID + Title string // 公告标题 + Type string // 公告类型(1通知 2公告) + Content string // 公告内容 + Remark string // 备注 + Status string // 公告状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// adminNoticeColumns holds the columns for table hg_admin_notice. +var adminNoticeColumns = AdminNoticeColumns{ + Id: "id", + Title: "title", + Type: "type", + Content: "content", + Remark: "remark", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewAdminNoticeDao creates and returns a new DAO object for table data access. +func NewAdminNoticeDao() *AdminNoticeDao { + return &AdminNoticeDao{ + group: "default", + table: "hg_admin_notice", + columns: adminNoticeColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminNoticeDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminNoticeDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminNoticeDao) Columns() AdminNoticeColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminNoticeDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminNoticeDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminNoticeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_post.go b/hotgo-server/app/service/internal/dao/internal/admin_post.go new file mode 100644 index 0000000..a0e3ef3 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_post.go @@ -0,0 +1,86 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminPostDao is the data access object for table hg_admin_post. +type AdminPostDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminPostColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminPostColumns defines and stores column names for table hg_admin_post. +type AdminPostColumns struct { + Id string // 岗位ID + Code string // 岗位编码 + Name string // 岗位名称 + Remark string // 备注 + Sort string // 显示顺序 + Status string // 状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// adminPostColumns holds the columns for table hg_admin_post. +var adminPostColumns = AdminPostColumns{ + Id: "id", + Code: "code", + Name: "name", + Remark: "remark", + Sort: "sort", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewAdminPostDao creates and returns a new DAO object for table data access. +func NewAdminPostDao() *AdminPostDao { + return &AdminPostDao{ + group: "default", + table: "hg_admin_post", + columns: adminPostColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminPostDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminPostDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminPostDao) Columns() AdminPostColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminPostDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminPostDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_role.go b/hotgo-server/app/service/internal/dao/internal/admin_role.go new file mode 100644 index 0000000..3af5500 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_role.go @@ -0,0 +1,92 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminRoleDao is the data access object for table hg_admin_role. +type AdminRoleDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminRoleColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminRoleColumns defines and stores column names for table hg_admin_role. +type AdminRoleColumns struct { + Id string // 角色ID + Name string // 角色名称 + Key string // 角色权限字符串 + DataScope string // 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限) + MenuCheckStrictly string // 菜单树选择项是否关联显示 + DeptCheckStrictly string // 部门树选择项是否关联显示 + Remark string // 备注 + Sort string // 排序 + Status string // 角色状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// adminRoleColumns holds the columns for table hg_admin_role. +var adminRoleColumns = AdminRoleColumns{ + Id: "id", + Name: "name", + Key: "key", + DataScope: "data_scope", + MenuCheckStrictly: "menu_check_strictly", + DeptCheckStrictly: "dept_check_strictly", + Remark: "remark", + Sort: "sort", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewAdminRoleDao creates and returns a new DAO object for table data access. +func NewAdminRoleDao() *AdminRoleDao { + return &AdminRoleDao{ + group: "default", + table: "hg_admin_role", + columns: adminRoleColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminRoleDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminRoleDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminRoleDao) Columns() AdminRoleColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminRoleDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminRoleDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_role_dept.go b/hotgo-server/app/service/internal/dao/internal/admin_role_dept.go new file mode 100644 index 0000000..6cb3f02 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_role_dept.go @@ -0,0 +1,74 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminRoleDeptDao is the data access object for table hg_admin_role_dept. +type AdminRoleDeptDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminRoleDeptColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminRoleDeptColumns defines and stores column names for table hg_admin_role_dept. +type AdminRoleDeptColumns struct { + RoleId string // 角色ID + DeptId string // 部门ID +} + +// adminRoleDeptColumns holds the columns for table hg_admin_role_dept. +var adminRoleDeptColumns = AdminRoleDeptColumns{ + RoleId: "role_id", + DeptId: "dept_id", +} + +// NewAdminRoleDeptDao creates and returns a new DAO object for table data access. +func NewAdminRoleDeptDao() *AdminRoleDeptDao { + return &AdminRoleDeptDao{ + group: "default", + table: "hg_admin_role_dept", + columns: adminRoleDeptColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminRoleDeptDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminRoleDeptDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminRoleDeptDao) Columns() AdminRoleDeptColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminRoleDeptDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminRoleDeptDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminRoleDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/admin_role_menu.go b/hotgo-server/app/service/internal/dao/internal/admin_role_menu.go new file mode 100644 index 0000000..c543072 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/admin_role_menu.go @@ -0,0 +1,74 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// AdminRoleMenuDao is the data access object for table hg_admin_role_menu. +type AdminRoleMenuDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns AdminRoleMenuColumns // columns contains all the column names of Table for convenient usage. +} + +// AdminRoleMenuColumns defines and stores column names for table hg_admin_role_menu. +type AdminRoleMenuColumns struct { + RoleId string // 角色ID + MenuId string // 菜单ID +} + +// adminRoleMenuColumns holds the columns for table hg_admin_role_menu. +var adminRoleMenuColumns = AdminRoleMenuColumns{ + RoleId: "role_id", + MenuId: "menu_id", +} + +// NewAdminRoleMenuDao creates and returns a new DAO object for table data access. +func NewAdminRoleMenuDao() *AdminRoleMenuDao { + return &AdminRoleMenuDao{ + group: "default", + table: "hg_admin_role_menu", + columns: adminRoleMenuColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *AdminRoleMenuDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *AdminRoleMenuDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *AdminRoleMenuDao) Columns() AdminRoleMenuColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *AdminRoleMenuDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *AdminRoleMenuDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *AdminRoleMenuDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/sys_config.go b/hotgo-server/app/service/internal/dao/internal/sys_config.go new file mode 100644 index 0000000..98fd841 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/sys_config.go @@ -0,0 +1,88 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysConfigDao is the data access object for table hg_sys_config. +type SysConfigDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysConfigColumns // columns contains all the column names of Table for convenient usage. +} + +// SysConfigColumns defines and stores column names for table hg_sys_config. +type SysConfigColumns struct { + Id string // 配置ID + Name string // 参数名称 + Key string // 参数键名 + Value string // 参数键值 + IsDefault string // 是否默认 + Status string // 状态 + Remark string // 备注 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// sysConfigColumns holds the columns for table hg_sys_config. +var sysConfigColumns = SysConfigColumns{ + Id: "id", + Name: "name", + Key: "key", + Value: "value", + IsDefault: "is_default", + Status: "status", + Remark: "remark", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysConfigDao creates and returns a new DAO object for table data access. +func NewSysConfigDao() *SysConfigDao { + return &SysConfigDao{ + group: "default", + table: "hg_sys_config", + columns: sysConfigColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysConfigDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysConfigDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysConfigDao) Columns() SysConfigColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysConfigDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysConfigDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysConfigDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/sys_dict_data.go b/hotgo-server/app/service/internal/dao/internal/sys_dict_data.go new file mode 100644 index 0000000..79cd3c7 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/sys_dict_data.go @@ -0,0 +1,92 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysDictDataDao is the data access object for table hg_sys_dict_data. +type SysDictDataDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysDictDataColumns // columns contains all the column names of Table for convenient usage. +} + +// SysDictDataColumns defines and stores column names for table hg_sys_dict_data. +type SysDictDataColumns struct { + Id string // 字典编码 + Label string // 字典标签 + Value string // 字典键值 + Type string // 字典类型 + ListClass string // 表格回显样式 + IsDefault string // 是否默认 + Sort string // 字典排序 + Remark string // 备注 + Status string // 状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// sysDictDataColumns holds the columns for table hg_sys_dict_data. +var sysDictDataColumns = SysDictDataColumns{ + Id: "id", + Label: "label", + Value: "value", + Type: "type", + ListClass: "list_class", + IsDefault: "is_default", + Sort: "sort", + Remark: "remark", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysDictDataDao creates and returns a new DAO object for table data access. +func NewSysDictDataDao() *SysDictDataDao { + return &SysDictDataDao{ + group: "default", + table: "hg_sys_dict_data", + columns: sysDictDataColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysDictDataDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysDictDataDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysDictDataDao) Columns() SysDictDataColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysDictDataDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysDictDataDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysDictDataDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/sys_dict_type.go b/hotgo-server/app/service/internal/dao/internal/sys_dict_type.go new file mode 100644 index 0000000..affc22d --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/sys_dict_type.go @@ -0,0 +1,86 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysDictTypeDao is the data access object for table hg_sys_dict_type. +type SysDictTypeDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysDictTypeColumns // columns contains all the column names of Table for convenient usage. +} + +// SysDictTypeColumns defines and stores column names for table hg_sys_dict_type. +type SysDictTypeColumns struct { + Id string // 字典主键 + Name string // 字典名称 + Type string // 字典类型 + Sort string // 排序 + Remark string // 备注 + Status string // 状态 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// sysDictTypeColumns holds the columns for table hg_sys_dict_type. +var sysDictTypeColumns = SysDictTypeColumns{ + Id: "id", + Name: "name", + Type: "type", + Sort: "sort", + Remark: "remark", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysDictTypeDao creates and returns a new DAO object for table data access. +func NewSysDictTypeDao() *SysDictTypeDao { + return &SysDictTypeDao{ + group: "default", + table: "hg_sys_dict_type", + columns: sysDictTypeColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysDictTypeDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysDictTypeDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysDictTypeDao) Columns() SysDictTypeColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysDictTypeDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysDictTypeDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysDictTypeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/sys_log.go b/hotgo-server/app/service/internal/dao/internal/sys_log.go new file mode 100644 index 0000000..e52dfed --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/sys_log.go @@ -0,0 +1,116 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysLogDao is the data access object for table hg_sys_log. +type SysLogDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysLogColumns // columns contains all the column names of Table for convenient usage. +} + +// SysLogColumns defines and stores column names for table hg_sys_log. +type SysLogColumns struct { + Id string // + AppId string // 应用id + MerchantId string // 商户id + MemberId string // 用户id + Method string // 提交类型 + Module string // 模块 + Url string // 提交url + GetData string // get数据 + PostData string // post数据 + HeaderData string // header数据 + Ip string // ip地址 + ProvinceId string // 省编码 + CityId string // 市编码 + ErrorCode string // 报错code + ErrorMsg string // 报错信息 + ErrorData string // 报错日志 + ReqId string // 对外id + Timestamp string // 响应时间 + UserAgent string // UA信息 + TakeUpTime string // 请求耗时 + Status string // 状态 + CreatedAt string // 创建时间 + UpdatedAt string // 修改时间 +} + +// sysLogColumns holds the columns for table hg_sys_log. +var sysLogColumns = SysLogColumns{ + Id: "id", + AppId: "app_id", + MerchantId: "merchant_id", + MemberId: "member_id", + Method: "method", + Module: "module", + Url: "url", + GetData: "get_data", + PostData: "post_data", + HeaderData: "header_data", + Ip: "ip", + ProvinceId: "province_id", + CityId: "city_id", + ErrorCode: "error_code", + ErrorMsg: "error_msg", + ErrorData: "error_data", + ReqId: "req_id", + Timestamp: "timestamp", + UserAgent: "user_agent", + TakeUpTime: "take_up_time", + Status: "status", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysLogDao creates and returns a new DAO object for table data access. +func NewSysLogDao() *SysLogDao { + return &SysLogDao{ + group: "default", + table: "hg_sys_log", + columns: sysLogColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysLogDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysLogDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysLogDao) Columns() SysLogColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysLogDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysLogDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/internal/sys_provinces.go b/hotgo-server/app/service/internal/dao/internal/sys_provinces.go new file mode 100644 index 0000000..714b542 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/internal/sys_provinces.go @@ -0,0 +1,94 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysProvincesDao is the data access object for table hg_sys_provinces. +type SysProvincesDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysProvincesColumns // columns contains all the column names of Table for convenient usage. +} + +// SysProvincesColumns defines and stores column names for table hg_sys_provinces. +type SysProvincesColumns struct { + Id string // ID + Title string // 栏目名 + Pid string // 父栏目 + ShortTitle string // 缩写 + Areacode string // 区域编码 + Zipcode string // 邮政编码 + Pinyin string // 拼音 + Lng string // 经度 + Lat string // 纬度 + Level string // 级别 + Tree string // + Sort string // 排序 +} + +// sysProvincesColumns holds the columns for table hg_sys_provinces. +var sysProvincesColumns = SysProvincesColumns{ + Id: "id", + Title: "title", + Pid: "pid", + ShortTitle: "short_title", + Areacode: "areacode", + Zipcode: "zipcode", + Pinyin: "pinyin", + Lng: "lng", + Lat: "lat", + Level: "level", + Tree: "tree", + Sort: "sort", +} + +// NewSysProvincesDao creates and returns a new DAO object for table data access. +func NewSysProvincesDao() *SysProvincesDao { + return &SysProvincesDao{ + group: "default", + table: "hg_sys_provinces", + columns: sysProvincesColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysProvincesDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysProvincesDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysProvincesDao) Columns() SysProvincesColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysProvincesDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysProvincesDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysProvincesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/hotgo-server/app/service/internal/dao/sys_config.go b/hotgo-server/app/service/internal/dao/sys_config.go new file mode 100644 index 0000000..9915d79 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/sys_config.go @@ -0,0 +1,58 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// sysConfigDao is the data access object for table hg_sys_config. +// You can define custom methods on it to extend its functionality as you wish. +type sysConfigDao struct { + *internal.SysConfigDao +} + +var ( + // SysConfig is globally public accessible object for table hg_sys_config operations. + SysConfig = sysConfigDao{ + internal.NewSysConfigDao(), + } +) + +// +// @Title 判断名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param name +// @Return bool +// @Return error +// +func (dao *sysConfigDao) IsUniqueName(ctx context.Context, id int64, name string) (bool, error) { + var data *entity.SysConfig + m := dao.Ctx(ctx).Where("name", name) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err := m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil +} + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/sys_dict_data.go b/hotgo-server/app/service/internal/dao/sys_dict_data.go new file mode 100644 index 0000000..c0b6b11 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/sys_dict_data.go @@ -0,0 +1,62 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// sysDictDataDao is the data access object for table hg_sys_dict_data. +// You can define custom methods on it to extend its functionality as you wish. +type sysDictDataDao struct { + *internal.SysDictDataDao +} + +var ( + // SysDictData is globally public accessible object for table hg_sys_dict_data operations. + SysDictData = sysDictDataDao{ + internal.NewSysDictDataDao(), + } +) + +// +// @Title 判断字典类型是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param dictType +// @Return bool +// @Return error +// +func (dao *sysDictDataDao) IsUnique(ctx context.Context, id int64, dictType string, dictValue string) (bool, error) { + var ( + data *entity.SysDictData + err error + ) + m := dao.Ctx(ctx).Where("type", dictType).Where("value", dictValue) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err = m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil + +} + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/sys_dict_type.go b/hotgo-server/app/service/internal/dao/sys_dict_type.go new file mode 100644 index 0000000..0f6c73a --- /dev/null +++ b/hotgo-server/app/service/internal/dao/sys_dict_type.go @@ -0,0 +1,62 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/errors/gerror" +) + +// sysDictTypeDao is the data access object for table hg_sys_dict_type. +// You can define custom methods on it to extend its functionality as you wish. +type sysDictTypeDao struct { + *internal.SysDictTypeDao +} + +var ( + // SysDictType is globally public accessible object for table hg_sys_dict_type operations. + SysDictType = sysDictTypeDao{ + internal.NewSysDictTypeDao(), + } +) + +// +// @Title 判断字典类型是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param id +// @Param dictType +// @Return bool +// @Return error +// +func (dao *sysDictTypeDao) IsUnique(ctx context.Context, id int64, dictType string) (bool, error) { + var ( + data *entity.SysDictType + err error + ) + m := dao.Ctx(ctx).Where("type", dictType) + + if id > 0 { + m = m.WhereNot("id", id) + } + + if err = m.Scan(&data); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return false, err + } + + if data == nil { + return true, nil + } + + return false, nil + +} + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/sys_log.go b/hotgo-server/app/service/internal/dao/sys_log.go new file mode 100644 index 0000000..b4a39fa --- /dev/null +++ b/hotgo-server/app/service/internal/dao/sys_log.go @@ -0,0 +1,24 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" +) + +// sysLogDao is the data access object for table hg_sys_log. +// You can define custom methods on it to extend its functionality as you wish. +type sysLogDao struct { + *internal.SysLogDao +} + +var ( + // SysLog is globally public accessible object for table hg_sys_log operations. + SysLog = sysLogDao{ + internal.NewSysLogDao(), + } +) + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dao/sys_provinces.go b/hotgo-server/app/service/internal/dao/sys_provinces.go new file mode 100644 index 0000000..9ab5ae2 --- /dev/null +++ b/hotgo-server/app/service/internal/dao/sys_provinces.go @@ -0,0 +1,73 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/service/internal/dao/internal" + "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/errors/gerror" +) + +// sysProvincesDao is the data access object for table hg_sys_provinces. +// You can define custom methods on it to extend its functionality as you wish. +type sysProvincesDao struct { + *internal.SysProvincesDao +} + +var ( + // SysProvinces is globally public accessible object for table hg_sys_provinces operations. + SysProvinces = sysProvincesDao{ + internal.NewSysProvincesDao(), + } +) + +// +// @Title 获取省市编码对应的地区名称 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param province +// @Param city +// @Param spilt +// @Return string +// @Return error +// +func (dao *sysProvincesDao) GetRegion(ctx context.Context, province int, city int, spilt ...string) (string, error) { + + var ( + provinceName *gvar.Var + cityName *gvar.Var + err error + ) + // TODO 默认分隔符 + spiltSymbol := "-" + if len(spilt) > 0 { + spiltSymbol = spilt[0] + } + + if province > 0 { + provinceName, err = dao.Ctx(ctx).Where("id", province).Fields("title").Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return "", err + } + + if city > 0 { + cityName, err = dao.Ctx(ctx).Where("id", city).Fields("title").Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return "", err + } + } + } else { + return "内网IP", nil + } + + return provinceName.String() + spiltSymbol + cityName.String(), nil +} + +// Fill with you ideas below. diff --git a/hotgo-server/app/service/internal/dto/admin_dept.go b/hotgo-server/app/service/internal/dto/admin_dept.go new file mode 100644 index 0000000..0f3d80a --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_dept.go @@ -0,0 +1,28 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminDept is the golang structure of table hg_admin_dept for DAO operations like Where/Data. +type AdminDept struct { + g.Meta `orm:"table:hg_admin_dept, dto:true"` + Id interface{} // 部门id + Pid interface{} // 父部门id + Ancestors interface{} // 祖级列表 + Name interface{} // 部门名称 + Code interface{} // 部门编码 + Type interface{} // 部门类型 + Leader interface{} // 负责人 + Phone interface{} // 联系电话 + Email interface{} // 邮箱 + Sort interface{} // 排序 + Status interface{} // 部门状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/admin_member.go b/hotgo-server/app/service/internal/dto/admin_member.go new file mode 100644 index 0000000..7515fca --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_member.go @@ -0,0 +1,44 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminMember is the golang structure of table hg_admin_member for DAO operations like Where/Data. +type AdminMember struct { + g.Meta `orm:"table:hg_admin_member, dto:true"` + Id interface{} // + DeptId interface{} // 部门ID + Username interface{} // 帐号 + PasswordHash interface{} // 密码 + Salt interface{} // 密码盐 + AuthKey interface{} // 授权令牌 + PasswordResetToken interface{} // 密码重置令牌 + Type interface{} // 1:普通管理员;10超级管理员 + Realname interface{} // 真实姓名 + Avatar interface{} // 头像 + Sex interface{} // 性别[0:未知;1:男;2:女] + Qq interface{} // qq + Email interface{} // 邮箱 + Birthday *gtime.Time // 生日 + ProvinceId interface{} // 省 + CityId interface{} // 城市 + AreaId interface{} // 地区 + Address interface{} // 默认地址 + Mobile interface{} // 手机号码 + HomePhone interface{} // 家庭号码 + DingtalkRobotToken interface{} // 钉钉机器人token + VisitCount interface{} // 访问次数 + LastTime interface{} // 最后一次登录时间 + LastIp interface{} // 最后一次登录ip + Role interface{} // 权限 + Remark interface{} // 备注 + Status interface{} // 状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 修改时间 +} diff --git a/hotgo-server/app/service/internal/dto/admin_member_post.go b/hotgo-server/app/service/internal/dto/admin_member_post.go new file mode 100644 index 0000000..0347b2d --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_member_post.go @@ -0,0 +1,16 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// AdminMemberPost is the golang structure of table hg_admin_member_post for DAO operations like Where/Data. +type AdminMemberPost struct { + g.Meta `orm:"table:hg_admin_member_post, dto:true"` + MemberId interface{} // 用户ID + PostId interface{} // 岗位ID +} diff --git a/hotgo-server/app/service/internal/dto/admin_member_role.go b/hotgo-server/app/service/internal/dto/admin_member_role.go new file mode 100644 index 0000000..8ac83f2 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_member_role.go @@ -0,0 +1,16 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// AdminMemberRole is the golang structure of table hg_admin_member_role for DAO operations like Where/Data. +type AdminMemberRole struct { + g.Meta `orm:"table:hg_admin_member_role, dto:true"` + MemberId interface{} // 用户ID + RoleId interface{} // 角色ID +} diff --git a/hotgo-server/app/service/internal/dto/admin_menu.go b/hotgo-server/app/service/internal/dto/admin_menu.go new file mode 100644 index 0000000..c15f45b --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_menu.go @@ -0,0 +1,35 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminMenu is the golang structure of table hg_admin_menu for DAO operations like Where/Data. +type AdminMenu struct { + g.Meta `orm:"table:hg_admin_menu, dto:true"` + Id interface{} // 菜单ID + Pid interface{} // 父菜单ID + Name interface{} // 菜单名称 + Code interface{} // 菜单编码 + Icon interface{} // 菜单图标 + Type interface{} // 菜单类型(M目录 C菜单 F按钮) + Perms interface{} // 权限标识 + Path interface{} // 路由地址 + Component interface{} // 组件路径 + Query interface{} // 路由参数 + IsFrame interface{} // 是否内嵌 + IsCache interface{} // 是否不缓存 + IsVisible interface{} // 是否隐藏 + Remark interface{} // 备注 + Level interface{} // 级别 + Tree interface{} // 树 + Sort interface{} // 排序 + Status interface{} // 菜单状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/admin_menu_old.go b/hotgo-server/app/service/internal/dto/admin_menu_old.go new file mode 100644 index 0000000..bd0f3b4 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_menu_old.go @@ -0,0 +1,34 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminMenuOld is the golang structure of table hg_admin_menu_old for DAO operations like Where/Data. +type AdminMenuOld struct { + g.Meta `orm:"table:hg_admin_menu_old, dto:true"` + Id interface{} // 菜单ID + Pid interface{} // 父菜单ID + Name interface{} // 菜单名称 + Icon interface{} // 菜单图标 + Type interface{} // 菜单类型(M目录 C菜单 F按钮) + Perms interface{} // 权限标识 + Path interface{} // 路由地址 + Component interface{} // 组件路径 + Query interface{} // 路由参数 + IsFrame interface{} // 是否为外链(0是 1否) + IsCache interface{} // 是否缓存(0缓存 1不缓存) + IsVisible interface{} // 菜单状态(0显示 1隐藏) + Remark interface{} // 备注 + Level interface{} // 级别 + Tree interface{} // 树 + Sort interface{} // 排序 + Status interface{} // 菜单状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/admin_notice.go b/hotgo-server/app/service/internal/dto/admin_notice.go new file mode 100644 index 0000000..796a76f --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_notice.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminNotice is the golang structure of table hg_admin_notice for DAO operations like Where/Data. +type AdminNotice struct { + g.Meta `orm:"table:hg_admin_notice, dto:true"` + Id interface{} // 公告ID + Title interface{} // 公告标题 + Type interface{} // 公告类型(1通知 2公告) + Content interface{} // 公告内容 + Remark interface{} // 备注 + Status interface{} // 公告状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/admin_post.go b/hotgo-server/app/service/internal/dto/admin_post.go new file mode 100644 index 0000000..3116209 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_post.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminPost is the golang structure of table hg_admin_post for DAO operations like Where/Data. +type AdminPost struct { + g.Meta `orm:"table:hg_admin_post, dto:true"` + Id interface{} // 岗位ID + Code interface{} // 岗位编码 + Name interface{} // 岗位名称 + Remark interface{} // 备注 + Sort interface{} // 显示顺序 + Status interface{} // 状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/admin_role.go b/hotgo-server/app/service/internal/dto/admin_role.go new file mode 100644 index 0000000..89c96bb --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_role.go @@ -0,0 +1,26 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// AdminRole is the golang structure of table hg_admin_role for DAO operations like Where/Data. +type AdminRole struct { + g.Meta `orm:"table:hg_admin_role, dto:true"` + Id interface{} // 角色ID + Name interface{} // 角色名称 + Key interface{} // 角色权限字符串 + DataScope interface{} // 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限) + MenuCheckStrictly interface{} // 菜单树选择项是否关联显示 + DeptCheckStrictly interface{} // 部门树选择项是否关联显示 + Remark interface{} // 备注 + Sort interface{} // 排序 + Status interface{} // 角色状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/admin_role_dept.go b/hotgo-server/app/service/internal/dto/admin_role_dept.go new file mode 100644 index 0000000..da2b391 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_role_dept.go @@ -0,0 +1,16 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// AdminRoleDept is the golang structure of table hg_admin_role_dept for DAO operations like Where/Data. +type AdminRoleDept struct { + g.Meta `orm:"table:hg_admin_role_dept, dto:true"` + RoleId interface{} // 角色ID + DeptId interface{} // 部门ID +} diff --git a/hotgo-server/app/service/internal/dto/admin_role_menu.go b/hotgo-server/app/service/internal/dto/admin_role_menu.go new file mode 100644 index 0000000..983aae5 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/admin_role_menu.go @@ -0,0 +1,16 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// AdminRoleMenu is the golang structure of table hg_admin_role_menu for DAO operations like Where/Data. +type AdminRoleMenu struct { + g.Meta `orm:"table:hg_admin_role_menu, dto:true"` + RoleId interface{} // 角色ID + MenuId interface{} // 菜单ID +} diff --git a/hotgo-server/app/service/internal/dto/sys_config.go b/hotgo-server/app/service/internal/dto/sys_config.go new file mode 100644 index 0000000..930ed94 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/sys_config.go @@ -0,0 +1,24 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysConfig is the golang structure of table hg_sys_config for DAO operations like Where/Data. +type SysConfig struct { + g.Meta `orm:"table:hg_sys_config, dto:true"` + Id interface{} // 配置ID + Name interface{} // 参数名称 + Key interface{} // 参数键名 + Value interface{} // 参数键值 + IsDefault interface{} // 是否默认 + Status interface{} // 状态 + Remark interface{} // 备注 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/sys_dict_data.go b/hotgo-server/app/service/internal/dto/sys_dict_data.go new file mode 100644 index 0000000..654b4a7 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/sys_dict_data.go @@ -0,0 +1,26 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictData is the golang structure of table hg_sys_dict_data for DAO operations like Where/Data. +type SysDictData struct { + g.Meta `orm:"table:hg_sys_dict_data, dto:true"` + Id interface{} // 字典编码 + Label interface{} // 字典标签 + Value interface{} // 字典键值 + Type interface{} // 字典类型 + ListClass interface{} // 表格回显样式 + IsDefault interface{} // 是否默认 + Sort interface{} // 字典排序 + Remark interface{} // 备注 + Status interface{} // 状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/sys_dict_type.go b/hotgo-server/app/service/internal/dto/sys_dict_type.go new file mode 100644 index 0000000..a03db93 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/sys_dict_type.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictType is the golang structure of table hg_sys_dict_type for DAO operations like Where/Data. +type SysDictType struct { + g.Meta `orm:"table:hg_sys_dict_type, dto:true"` + Id interface{} // 字典主键 + Name interface{} // 字典名称 + Type interface{} // 字典类型 + Sort interface{} // 排序 + Remark interface{} // 备注 + Status interface{} // 状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/hotgo-server/app/service/internal/dto/sys_log.go b/hotgo-server/app/service/internal/dto/sys_log.go new file mode 100644 index 0000000..b8cb299 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/sys_log.go @@ -0,0 +1,38 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysLog is the golang structure of table hg_sys_log for DAO operations like Where/Data. +type SysLog struct { + g.Meta `orm:"table:hg_sys_log, dto:true"` + Id interface{} // + AppId interface{} // 应用id + MerchantId interface{} // 商户id + MemberId interface{} // 用户id + Method interface{} // 提交类型 + Module interface{} // 模块 + Url interface{} // 提交url + GetData interface{} // get数据 + PostData interface{} // post数据 + HeaderData interface{} // header数据 + Ip interface{} // ip地址 + ProvinceId interface{} // 省编码 + CityId interface{} // 市编码 + ErrorCode interface{} // 报错code + ErrorMsg interface{} // 报错信息 + ErrorData interface{} // 报错日志 + ReqId interface{} // 对外id + Timestamp interface{} // 响应时间 + UserAgent interface{} // UA信息 + TakeUpTime interface{} // 请求耗时 + Status interface{} // 状态 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 修改时间 +} diff --git a/hotgo-server/app/service/internal/dto/sys_provinces.go b/hotgo-server/app/service/internal/dto/sys_provinces.go new file mode 100644 index 0000000..1e39430 --- /dev/null +++ b/hotgo-server/app/service/internal/dto/sys_provinces.go @@ -0,0 +1,26 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package dto + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// SysProvinces is the golang structure of table hg_sys_provinces for DAO operations like Where/Data. +type SysProvinces struct { + g.Meta `orm:"table:hg_sys_provinces, dto:true"` + Id interface{} // ID + Title interface{} // 栏目名 + Pid interface{} // 父栏目 + ShortTitle interface{} // 缩写 + Areacode interface{} // 区域编码 + Zipcode interface{} // 邮政编码 + Pinyin interface{} // 拼音 + Lng interface{} // 经度 + Lat interface{} // 纬度 + Level interface{} // 级别 + Tree interface{} // + Sort interface{} // 排序 +} diff --git a/hotgo-server/app/service/sysService/config_service.go b/hotgo-server/app/service/sysService/config_service.go new file mode 100644 index 0000000..ee8dfa0 --- /dev/null +++ b/hotgo-server/app/service/sysService/config_service.go @@ -0,0 +1,233 @@ +package sysService + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/os/gtime" +) + +var Config = new(config) + +type config struct{} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *config) GetValue(ctx context.Context, in input.SysConfigGetValueInp) (*input.SysConfigGetValueModel, error) { + var res input.SysConfigGetValueModel + + if err := dao.SysConfig.Ctx(ctx). + Fields("value"). + Where("key", in.Key). + Order("id desc"). + Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 菜单名称是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *config) NameUnique(ctx context.Context, in input.SysConfigNameUniqueInp) (*input.SysConfigNameUniqueModel, error) { + + var res input.SysConfigNameUniqueModel + isUnique, err := dao.SysConfig.IsUniqueName(ctx, in.Id, in.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.IsUnique = isUnique + return &res, nil +} + +// +// @Title 删除 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *config) Delete(ctx context.Context, in input.SysConfigDeleteInp) error { + + exist, err := dao.SysConfig.Ctx(ctx).Where("Member_id", in.Id).One() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !exist.IsEmpty() { + return gerror.New("请先解除该部门下所有已关联用户关联关系!") + } + _, err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *config) Edit(ctx context.Context, in input.SysConfigEditInp) (err error) { + + if in.Name == "" { + err = gerror.New("名称不能为空") + return err + } + + uniqueName, err := dao.SysConfig.IsUniqueName(ctx, in.Id, in.Name) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + if !uniqueName { + err = gerror.New("名称已存在") + return err + } + + // 修改 + in.UpdatedAt = gtime.Now() + if in.Id > 0 { + _, err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Data(in).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil + } + + // 新增 + in.CreatedAt = gtime.Now() + _, err = dao.SysConfig.Ctx(ctx).Data(in).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + return nil +} + +// +// @Title 最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *config) MaxSort(ctx context.Context, in input.SysConfigMaxSortInp) (*input.SysConfigMaxSortModel, error) { + var res input.SysConfigMaxSortModel + + if in.Id > 0 { + if err := dao.SysConfig.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + } + + res.Sort = res.Sort + 10 + + return &res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *config) View(ctx context.Context, in input.SysConfigViewInp) (res *input.SysConfigViewModel, err error) { + + if err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return res, nil +} + +// +// @Title 获取列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *config) List(ctx context.Context, in input.SysConfigListInp) (list []*input.SysConfigListModel, totalCount int, err error) { + + mod := dao.SysConfig.Ctx(ctx) + + if in.Realname != "" { + mod = mod.WhereLike("realname", "%"+in.Realname+"%") + } + if in.Username != "" { + mod = mod.WhereLike("username", "%"+in.Username+"%") + } + if in.Mobile > 0 { + mod = mod.Where("mobile", in.Mobile) + } + if in.Status > 0 { + mod = mod.Where("status", in.Status) + } + if in.DeptId > 0 { + mod = mod.Where("dept_id", in.DeptId) + } + + // 日期范围 + if in.StartTime != "" { + mod = mod.WhereGTE("created_at", in.StartTime) + } + if in.EndTime != "" { + mod = mod.WhereLTE("created_at", in.EndTime) + } + + totalCount, err = mod.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + //// TODO 重写树入参 + //for i := 0; i < len(list); i++ { + //} + + return list, totalCount, err +} diff --git a/hotgo-server/app/service/sysService/dict_service.go b/hotgo-server/app/service/sysService/dict_service.go new file mode 100644 index 0000000..2bfa589 --- /dev/null +++ b/hotgo-server/app/service/sysService/dict_service.go @@ -0,0 +1,505 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package sysService + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/form/adminForm" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/util/gconv" + "time" +) + +var Dict = new(dict) + +type dict struct{} + +// +// @Title 数据键值是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *dict) DataUnique(ctx context.Context, req *adminForm.DictDataUniqueReq) (*adminForm.DictDataUniqueRes, error) { + var ( + res adminForm.DictDataUniqueRes + err error + ) + + res.IsUnique, err = dao.SysDictData.IsUnique(ctx, req.Id, req.Type, req.Value) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 查询字典数据最大排序 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataMaxSortRes +// @Return error +// +func (service *dict) DataMaxSort(ctx context.Context, req *adminForm.DictDataMaxSortReq) (*adminForm.DictDataMaxSortRes, error) { + var ( + m = dao.SysDictData.Ctx(ctx).Where("type", req.Type).Order("sort desc") + res adminForm.DictDataMaxSortRes + err error + ) + + if err = m.Scan(&res); err != nil && err.Error() != "sql: no rows in result set" { + + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.Sort = res.Sort + 10 + + return &res, nil +} + +// +// @Title 删除字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *dict) DataDelete(ctx context.Context, req *adminForm.DictDataDeleteReq) error { + var ( + m = dao.SysDictData.Ctx(ctx).Where("id", req.Id) + err error + ) + + _, err = m.Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *dict) DataEdit(ctx context.Context, req *adminForm.DictDataEditReq) error { + var ( + m = dao.SysDictData.Ctx(ctx) + isUnique bool + err error + ) + + if req.Label == "" { + err = gerror.New("字典标签不能为空") + return err + } + if req.Type == "" { + err = gerror.New("字典类型不能为空") + return err + } + if req.Value == "" { + err = gerror.New("字典键值不能为空") + return err + } + + isUnique, err = dao.SysDictData.IsUnique(ctx, req.Id, req.Type, req.Value) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + if !isUnique { + err = gerror.New("字典键值已存在") + return err + } + + req.UpdatedAt = gtime.Now() + + // 修改 + if req.Id > 0 { + _, err = m.Where("id", req.Id).Data(req).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil + } + + req.CreatedAt = gtime.Now() + + // 新增 + _, err = m.Data(req).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + return nil +} + +// +// @Title 获取指定字典数据信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *dict) DataView(ctx context.Context, req *adminForm.DictDataViewReq) (*adminForm.DictDataViewRes, error) { + var ( + m = dao.SysDictData.Ctx(ctx).Where("id", req.Id) + res adminForm.DictDataViewRes + err error + ) + + if err = m.Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 获取指定字典类型的属性数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictAttributeRes +// @Return error +// +func (service *dict) Attribute(ctx context.Context, req *adminForm.DictAttributeReq) (*adminForm.DictAttributeRes, error) { + var ( + m = dao.SysDictData.Ctx(ctx).Where("type", req.Type).Order("sort asc,id desc") + res adminForm.DictAttributeRes + err error + ) + + if err = m.Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 获取字典数据列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *dict) DataList(ctx context.Context, req *adminForm.DictDataListReq) (*adminForm.DictDataListRes, error) { + var ( + m = dao.SysDictData.Ctx(ctx).Where("type", req.Type) + list []*entity.SysDictData + res adminForm.DictDataListRes + totalCount int + err error + ) + + totalCount, err = m.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + if err = m.Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.List = list + res.Page = req.Page + res.Limit = req.Limit + res.TotalCount = totalCount + + return &res, nil +} + +// +// @Title 导出字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictDataListRes +// @Return error +// +func (service *dict) TypeExport(ctx context.Context, req *adminForm.DictTypeExportReq) error { + + // 导出格式 + type exportImage struct { + Id int64 `json:"id" ` + Name string `json:"name" ` + Type string `json:"type" ` + Remark string `json:"remark" ` + Status string `json:"status" ` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + } + + var ( + list []exportImage + titleList = []string{"ID", "字典名称", "字典类型", "备注", "状态", "创建时间", "更新时间"} + fileName = "字典类型导出-" + com.Context.Get(ctx).ReqId + ".xlsx" + sheetName = "HotGo" + err error + ) + + if err = dao.SysDictType.Ctx(ctx).Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + // TODO 格式化格式 + for i := 0; i < len(list); i++ { + if list[i].Status == consts.StatusEnabled { + list[i].Status = "启用" + } else if list[i].Status == consts.StatusDisable { + list[i].Status = "禁用" + } else if list[i].Status == consts.StatusDelete { + list[i].Status = "已删除" + } + } + + // TODO 强转类型 + writer := com.Context.Get(ctx).Request.Response.Writer + w, _ := interface{}(writer).(*ghttp.ResponseWriter) + + g.Log().Print(ctx, "gconv.Interfaces(list):", gconv.Interfaces(list)) + if err = utils.Excel.ExportByStruct(w, titleList, gconv.Interfaces(list), fileName, sheetName); err != nil { + err = gerror.Wrap(err, "ExportByStruct:") + return err + } + + // TODO 加入到上下文 + com.Context.SetResponse(ctx, &model.Response{ + Code: consts.CodeOK, + Message: "导出成功", + Timestamp: time.Now().Unix(), + ReqId: com.Context.Get(ctx).ReqId, + }) + + return nil +} + +// +// @Title 删除字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *dict) TypeDelete(ctx context.Context, req *adminForm.DictTypeDeleteReq) error { + var ( + m = dao.SysDictType.Ctx(ctx).Where("id", req.Id) + err error + ) + + _, err = m.Delete() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil +} + +// +// @Title 修改/新增字典类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return error +// +func (service *dict) TypeEdit(ctx context.Context, req *adminForm.DictTypeEditReq) error { + var ( + m = dao.SysDictType.Ctx(ctx) + isUnique bool + err error + ) + + if req.Name == "" { + err = gerror.New("字典名称不能为空") + return err + } + if req.Type == "" { + err = gerror.New("字典类型不能为空") + return err + } + + isUnique, err = dao.SysDictType.IsUnique(ctx, req.Id, req.Type) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + if !isUnique { + err = gerror.New("字典类型已存在") + return err + } + + req.UpdatedAt = gtime.Now() + + // 修改 + if req.Id > 0 { + _, err = m.Where("id", req.Id).Data(req).Update() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + + return nil + } + + req.CreatedAt = gtime.Now() + + // 新增 + _, err = m.Where("id", req.Id).Data(req).Insert() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return err + } + return nil +} + +// +// @Title 类型是否唯一 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeUniqueRes +// @Return error +// +func (service *dict) TypeUnique(ctx context.Context, req *adminForm.DictTypeUniqueReq) (*adminForm.DictTypeUniqueRes, error) { + var ( + res adminForm.DictTypeUniqueRes + err error + ) + + res.IsUnique, err = dao.SysDictType.IsUnique(ctx, req.Id, req.Type) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 获取指定字典类型信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return *adminForm.DictTypeViewRes +// @Return error +// +func (service *dict) TypeView(ctx context.Context, req *adminForm.DictTypeViewReq) (*adminForm.DictTypeViewRes, error) { + var ( + m = dao.SysDictType.Ctx(ctx).Where("id", req.Id) + res adminForm.DictTypeViewRes + err error + ) + + if err = m.Scan(&res); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + return &res, nil +} + +// +// @Title 获取字典类型列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *dict) TypeList(ctx context.Context, req *adminForm.DictTypeListReq) (*adminForm.DictTypeListRes, error) { + var ( + m = dao.SysDictType.Ctx(ctx) + list []*entity.SysDictType + res adminForm.DictTypeListRes + totalCount int + err error + ) + + if req.Name != "" { + m = m.WhereLike("name", "%"+req.Name+"%") + } + + if req.Type != "" { + m = m.Where("type", req.Type) + } + + // 日期范围 + if req.StartTime != "" { + m = m.WhereGTE("created_at", req.StartTime) + } + if req.EndTime != "" { + m = m.WhereLTE("created_at", req.EndTime) + } + + // 状态 + if req.Status > 0 { + m = m.Where("status", req.Status) + } + + totalCount, err = m.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + if err = m.Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return nil, err + } + + res.List = list + res.Page = req.Page + res.Limit = req.Limit + res.TotalCount = totalCount + + return &res, nil +} diff --git a/hotgo-server/app/service/sysService/log_service.go b/hotgo-server/app/service/sysService/log_service.go new file mode 100644 index 0000000..7f38aef --- /dev/null +++ b/hotgo-server/app/service/sysService/log_service.go @@ -0,0 +1,400 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package sysService + +import ( + "context" + "encoding/json" + "github.com/bufanyun/hotgo/app/com" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/factory/queue" + "github.com/bufanyun/hotgo/app/form/input" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/app/model/entity" + "github.com/bufanyun/hotgo/app/service/internal/dao" + "github.com/bufanyun/hotgo/app/utils" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "time" +) + +var Log = new(log) + +type log struct{} + +// +// @Title 导出 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param in +// @Return err +// +func (service *log) Export(ctx context.Context, in input.LogListInp) (err error) { + + // 导出格式 + type exportImage struct { + Id int64 `json:"id" description:""` + AppId string `json:"app_id" description:"应用id"` + Method string `json:"method" description:"提交类型"` + Module string `json:"module" description:"模块"` + Url string `json:"url" description:"提交url"` + Ip string `json:"ip" description:"ip地址"` + ErrorCode int `json:"error_code" description:"报错code"` + ErrorMsg string `json:"error_msg" description:"报错信息"` + ReqId string `json:"req_id" description:"对外id"` + TakeUpTime int64 `json:"take_up_time" description:"请求耗时"` + CreatedAt *gtime.Time `json:"created_at" description:"创建时间"` + MemberName string `json:"member_name"` + Region string `json:"region"` + } + + var ( + titleList = []string{"ID", "应用", "提交类型", "模块", "提交url", "ip地址", "报错code", "报错信息", "对外id", "请求耗时", "创建时间", "用户", "访问地"} + fileName = "全局日志导出-" + com.Context.Get(ctx).ReqId + ".xlsx" + sheetName = "HotGo" + exportList []exportImage + row exportImage + ) + + list, _, err := service.List(ctx, in) + if err != nil { + return err + } + + // TODO 格式化格式 + for i := 0; i < len(list); i++ { + row.Id = list[i].Id + row.AppId = list[i].AppId + row.Module = list[i].Module + row.Method = list[i].Method + row.Url = list[i].Url + row.Ip = list[i].Ip + row.ReqId = list[i].ReqId + row.ErrorCode = list[i].ErrorCode + row.ErrorMsg = list[i].ErrorMsg + row.TakeUpTime = list[i].TakeUpTime + row.CreatedAt = list[i].CreatedAt + row.MemberName = list[i].MemberName + row.Region = list[i].Region + exportList = append(exportList, row) + } + + // TODO 强转类型 + writer := com.Context.Get(ctx).Request.Response.Writer + w, _ := interface{}(writer).(*ghttp.ResponseWriter) + + if err = utils.Excel.ExportByStruct(w, titleList, gconv.Interfaces(exportList), fileName, sheetName); err != nil { + err = gerror.Wrap(err, "ExportByStruct:") + return err + } + + // TODO 加入到上下文 + com.Context.SetResponse(ctx, &model.Response{ + Code: consts.CodeOK, + Message: "导出成功", + Timestamp: time.Now().Unix(), + ReqId: com.Context.Get(ctx).ReqId, + }) + + return +} + +// +// @Title 获取菜单列表 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param req +// @Return res +// @Return err +// +func (service *log) List(ctx context.Context, in input.LogListInp) (list []*input.LogListModel, totalCount int, err error) { + + mod := dao.SysLog.Ctx(ctx) + + // 访问路径 + if in.Url != "" { + mod = mod.WhereLike("url", "%"+in.Url+"%") + } + + // 模块 + if in.Module != "" { + mod = mod.Where("module", in.Module) + } + + // 请求方式 + if in.Method != "" { + mod = mod.Where("method", in.Method) + } + + // 用户 + if in.MemberId > 0 { + mod = mod.Where("member_id", in.MemberId) + } + + // 访问IP + if in.Ip != "" { + mod = mod.Where("ip", in.Ip) + } + + // 日期范围 + if in.StartTime != "" { + mod = mod.WhereGTE("created_at", in.StartTime) + } + if in.EndTime != "" { + mod = mod.WhereLTE("created_at", in.EndTime) + } + + // 状态码 + if in.ErrorCode != "" { + mod = mod.Where("error_code", in.ErrorCode) + } + + // 请求耗时 + if in.TakeUpTime > 0 { + mod = mod.WhereGTE("take_up_time", in.TakeUpTime) + } + + totalCount, err = mod.Count() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list) + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + + for i := 0; i < len(list); i++ { + // TODO 管理员 + if list[i].AppId == consts.AppAdmin { + memberName, err := dao.AdminMember.Ctx(ctx).Fields("realname").Where("id", list[i].MemberId).Value() + if err != nil { + err = gerror.Wrap(err, consts.ErrorORM) + return list, totalCount, err + } + list[i].MemberName = memberName.String() + } + // TODO 接口 + if list[i].AppId == consts.AppApi { + //memberName, err = dao.Member.Ctx(ctx).Fields("realname").Where("id", res.List[i].MemberId).Value() + //if err != nil { + // err = gerror.Wrap(err, consts.ErrorORM) + // return nil, err + //} + } + + if list[i].MemberName == "" { + list[i].MemberName = "游客" + } + + // TODO 获取省市编码对应的地区名称 + region, err := dao.SysProvinces.GetRegion(ctx, list[i].ProvinceId, list[i].CityId) + if err != nil { + return list, totalCount, err + } + list[i].Region = region + + // TODO 截取请求url路径 + if gstr.Contains(list[i].Url, "?") { + list[i].Url = gstr.StrTillEx(list[i].Url, "?") + } + } + + return list, totalCount, err +} + +// +// @Title 真实写入 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param commonLog +// @Return err +// +func (service *log) RealWrite(ctx context.Context, commonLog entity.SysLog) error { + + result, err := dao.SysLog.Ctx(ctx).Data(commonLog).Insert() + if err != nil { + return err + } + + if _, err := result.LastInsertId(); err != nil { + return err + } + + return nil +} + +// +// @Title 根据配置自动记录请求日志 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Return err +// +func (service *log) AutoLog(ctx context.Context) (err error) { + // TODO 日志开关 + logSwitch, _ := g.Cfg().Get(ctx, "hotgo.log.switch", true) + if !logSwitch.Bool() { + return nil + } + + data := service.AnalysisLog(ctx) + + // TODO 判断模块是否需要记录 + module, _ := g.Cfg().Get(ctx, "hotgo.log.module", nil) + if module == nil { + return nil + } + if exist := utils.Charset.IsExists(module.Strings(), data.Module); !exist { + return nil + } + + // TODO 判断状态码是否需要记录 + code, _ := g.Cfg().Get(ctx, "hotgo.log.skipCode", nil) + if code != nil { + if exist := utils.Charset.IsExists(code.Strings(), gconv.String(data.ErrorCode)); exist { + return nil + } + } + + // TODO 是否开启队列 + queueSwitch, _ := g.Cfg().Get(ctx, "hotgo.log.queue", true) + if queueSwitch.Bool() { + // TODO 获取生产者实例 + queueInstance, err := queue.InstanceProducer() + if err != nil { + queue.FatalLog(ctx, "InstanceProducer异常", err) + return err + } + + // TODO 生产消息 + mqMsg, err := queueInstance.SendMsg(consts.QueueLogTopic, gconv.String(data)) + + // TODO 记录生产日志 + queue.ProducerLog(ctx, consts.QueueLogTopic, mqMsg.MsgId, err) + + return err + } + + return service.RealWrite(ctx, data) +} + +// +// @Title 队列消费 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param mqMsg +// @Return err +// +func (service *log) QueueJob(ctx context.Context, mqMsg queue.MqMsg) (err error) { + + var data entity.SysLog + if err = json.Unmarshal(mqMsg.Body, &data); err != nil { + return err + } + + return service.RealWrite(ctx, data) +} + +// +// @Title 解析日志数据 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Return entity.SysLog +// +func (service *log) AnalysisLog(ctx context.Context) entity.SysLog { + + var ( + modelContext = com.Context.Get(ctx) + response = modelContext.ComResponse + user = modelContext.User + request = modelContext.Request + module = modelContext.Module + ip = request.GetClientIp() + locationData = com.Ip.GetLocation(ctx, ip) + postData = "null" + getData = "null" + headerData = "null" + data = entity.SysLog{} + memberId = 0 + errorCode = 0 + errorMsg = "" + errorData = "null" + reqId = "" + timestamp = 0 + appId = "" + ) + + // TODO 响应数据 + if response != nil { + errorCode = response.Code + errorMsg = response.Message + reqId = response.ReqId + timestamp = gconv.Int(response.Timestamp) + + if len(gconv.String(response.Error)) > 0 { + errorData = gconv.String(response.Error) + } + } + + // TODO 请求头 + if reqHeadersBytes, _ := json.Marshal(request.Header); len(gconv.String(reqHeadersBytes)) > 0 { + headerData = gconv.String(reqHeadersBytes) + } + + // TODO post参数 + if gconv.String(request.PostForm) != "" { + postData = gconv.String(request.PostForm) + } + + // TODO get参数 + if len(request.URL.Query()) > 0 { + getData = gconv.String(request.URL.Query()) + } + + // TODO 当前登录用户 + if user != nil { + memberId = int(user.Id) + appId = user.App + } + + data = entity.SysLog{ + AppId: appId, + MerchantId: 0, + MemberId: memberId, + Method: request.Method, + Module: module, + Url: request.RequestURI, + GetData: getData, + PostData: postData, + HeaderData: headerData, + Ip: ip, + ProvinceId: locationData.ProvinceCode, + CityId: locationData.CityCode, + ErrorCode: errorCode, + ErrorMsg: errorMsg, + ErrorData: errorData, + ReqId: reqId, + Timestamp: timestamp, + UserAgent: request.Header.Get("User-Agent"), + Status: consts.StatusEnabled, + TakeUpTime: modelContext.TakeUpTime, + } + + return data +} diff --git a/hotgo-server/app/service/sysService/provinces_service.go b/hotgo-server/app/service/sysService/provinces_service.go new file mode 100644 index 0000000..b652873 --- /dev/null +++ b/hotgo-server/app/service/sysService/provinces_service.go @@ -0,0 +1,29 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package sysService + +import ( + "context" + "github.com/bufanyun/hotgo/app/com" +) + +var Provinces = new(provinces) + +type provinces struct{} + +// +// @Title 获取地区中的省市编码 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param location +// +func (service *provinces) GetLocationCode(ctx context.Context, location com.IpLocationData) { + + return +} + diff --git a/hotgo-server/app/utils/auth_util.go b/hotgo-server/app/utils/auth_util.go new file mode 100644 index 0000000..1964418 --- /dev/null +++ b/hotgo-server/app/utils/auth_util.go @@ -0,0 +1,65 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package utils + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" +) + +// 权限认证类 +var Auth = new(auth) + +type auth struct{} + +// +// @Title 是否是不需要验证权限的路由地址 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param path +// @Return bool +// +func (util *auth) IsExceptAuth(ctx context.Context, path string) bool { + + var pathList []string + + except, _ := g.Cfg().Get(ctx, "router.admin.exceptAuth") + pathList = except.Strings() + + for i := 0; i < len(pathList); i++ { + if Charset.IsExists(pathList[i], path) { + return true + } + } + + return false +} + +// +// @Title 是否是不需要登录的路由地址 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// @Param path +// @Return bool +// +func (util *auth) IsExceptLogin(ctx context.Context, path string) bool { + + var pathList []string + + except, _ := g.Cfg().Get(ctx, "router.admin.exceptLogin") + pathList = except.Strings() + + for i := 0; i < len(pathList); i++ { + if Charset.IsExists(pathList[i], path) { + return true + } + } + + return false +} diff --git a/hotgo-server/app/utils/charset_util.go b/hotgo-server/app/utils/charset_util.go new file mode 100644 index 0000000..9f1e49e --- /dev/null +++ b/hotgo-server/app/utils/charset_util.go @@ -0,0 +1,121 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package utils + +import ( + "crypto/md5" + "crypto/rand" + "fmt" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + r "math/rand" + "time" +) + +// 字符类 +var Charset = new(charset) + +type charset struct{} + +// +// @Title 获取map的所有key,字串符类型 +// @Description +// @Author Ms <133814250@qq.com> +// @Param m +// @Return []string +// +func (util *charset) GetMapKeysByString(m map[string]string) []string { + // 数组默认长度为map长度,后面append时,不需要重新申请内存和拷贝,效率很高 + j := 0 + keys := make([]string, len(m)) + for k := range m { + keys[j] = k + j++ + } + return keys +} + +// +// @Title 生成md5 +// @Description +// @Author Ms <133814250@qq.com> +// @Param str +// @Return string +// +func (util *charset) Md5ToString(str string) string { + md5str := fmt.Sprintf("%x", md5.Sum([]byte(str))) + return md5str +} + +// +// @Title 生成随机字串符 +// @Description +// @Author Ms <133814250@qq.com> +// @Param n +// @Param alphabets +// @Return []byte +// +func (util *charset) RandomCreateBytes(n int, alphabets ...byte) []byte { + if len(alphabets) == 0 { + alphabets = []byte(`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`) + } + var bytes = make([]byte, n) + var randBy bool + r.Seed(time.Now().UnixNano()) + if num, err := rand.Read(bytes); num != n || err != nil { + randBy = true + } + for i, b := range bytes { + if randBy { + bytes[i] = alphabets[r.Intn(len(alphabets))] + } else { + bytes[i] = alphabets[b%byte(len(alphabets))] + } + } + return bytes +} + +// +// @Title 格式化错误的堆栈信息 +// @Description +// @Author Ms <133814250@qq.com> +// @Param err +// @Return []string +// +func (util *charset) GetStack(err error) []string { + stackList := gstr.Split(gerror.Stack(err), "\n") + for i := 0; i < len(stackList); i++ { + stackList[i] = gstr.Replace(stackList[i], "\t", "--> ") + } + + return stackList +} + +// +// @Title 判断字符或切片字符是否存在指定字符 +// @Description +// @Author Ms <133814250@qq.com> +// @Param elems +// @Param search +// @Return bool +// +func (util *charset) IsExists(elems interface{}, search string) bool { + switch elems.(type) { + case []string: + elem := gconv.Strings(elems) + for i := 0; i < len(elem); i++ { + if gconv.String(elem[i]) == search { + return true + } + } + default: + return gconv.String(elems) == search + } + + return false +} diff --git a/hotgo-server/app/utils/excel_util.go b/hotgo-server/app/utils/excel_util.go new file mode 100644 index 0000000..e248597 --- /dev/null +++ b/hotgo-server/app/utils/excel_util.go @@ -0,0 +1,87 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package utils + +import ( + "fmt" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/util/gconv" + "github.com/xuri/excelize/v2" + "net/url" + "reflect" +) + +// 字符类 +var Excel = new(excel) + +type excel struct{} + +func (util *excel) ExportByStruct(w *ghttp.ResponseWriter, titleList []string, data []interface{}, fileName string, sheetName string) error { + + f := excelize.NewFile() + f.SetSheetName("Sheet1", sheetName) + header := make([]string, 0) + for _, v := range titleList { + header = append(header, v) + } + + rowStyleID, _ := f.NewStyle(`{"font":{"color":"#666666","size":13,"family":"arial"},"alignment":{"vertical":"center","horizontal":"center"}}`) + _ = f.SetSheetRow(sheetName, "A1", &header) + _ = f.SetRowHeight("Sheet1", 1, 30) + length := len(titleList) + headStyle := util.letter(length) + var lastRow string + var widthRow string + for k, v := range headStyle { + if k == length-1 { + lastRow = fmt.Sprintf("%s1", v) + widthRow = v + } + } + if err := f.SetColWidth(sheetName, "A", widthRow, 30); err != nil { + return err + } + + rowNum := 1 + for _, v := range data { + t := reflect.TypeOf(v) + value := reflect.ValueOf(v) + row := make([]interface{}, 0) + for l := 0; l < t.NumField(); l++ { + val := value.Field(l).Interface() + row = append(row, val) + } + rowNum++ + err := f.SetSheetRow(sheetName, "A"+gconv.String(rowNum), &row) + _ = f.SetCellStyle(sheetName, fmt.Sprintf("A%d", rowNum), fmt.Sprintf("%s", lastRow), rowStyleID) + if err != nil { + return err + } + } + disposition := fmt.Sprintf("attachment; filename=%s.xlsx", url.QueryEscape(fileName)) + + w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", disposition) + w.Header().Set("Content-Transfer-Encoding", "binary") + w.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") + + err := f.Write(w) + if err != nil { + return err + } + + return nil +} + +// Letter 遍历a-z +func (util *excel) letter(length int) []string { + var str []string + for i := 0; i < length; i++ { + str = append(str, string(rune('A'+i))) + } + return str +} diff --git a/hotgo-server/app/utils/filter_util.go b/hotgo-server/app/utils/filter_util.go new file mode 100644 index 0000000..da4db92 --- /dev/null +++ b/hotgo-server/app/utils/filter_util.go @@ -0,0 +1,17 @@ +package utils + +// 过滤类 +var Filter = new(filter) + +type filter struct{} + +//func (util *filter) RangeDate(startTime string, endTime string) map[string]interface{} { +// g.Map{ +// "uid <=" : 1000, +// "age >=" : 18, +// } +// return g.Map{ +// "uid <=" : 1000, +// "age >=" : 18, +// } +//} diff --git a/hotgo-server/app/utils/signal_util.go b/hotgo-server/app/utils/signal_util.go new file mode 100644 index 0000000..be6096a --- /dev/null +++ b/hotgo-server/app/utils/signal_util.go @@ -0,0 +1,76 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package utils + +import ( + "sync" +) + +// 信号类 +var Signal = new(signal) + +type signal struct{} + +type StopSignal int32 + +type exitWait struct { + mutex sync.Mutex + wg *sync.WaitGroup + deferFuns []func() + stopSignList []chan StopSignal +} + +var exitWaitHandler *exitWait + +func init() { + exitWaitHandler = &exitWait{ + wg: &sync.WaitGroup{}, + } +} + +// +// @Title 退出后等待处理完成 +// @Description +// @Author Ms <133814250@qq.com> +// @Param doFun +// +func (util *signal) ExitWaitFunDo(doFun func()) { + exitWaitHandler.wg.Add(1) + defer exitWaitHandler.wg.Done() + if doFun != nil { + doFun() + } +} + +// +// @Title 应用退出后置操作 +// @Description +// @Author Ms <133814250@qq.com> +// @Param deferFun +// +func (util *signal) AppDefer(deferFun ...func()) { + exitWaitHandler.mutex.Lock() + defer exitWaitHandler.mutex.Unlock() + for _, funcItem := range deferFun { + if funcItem != nil { + exitWaitHandler.deferFuns = append(exitWaitHandler.deferFuns, funcItem) + } + } +} + +// +// @Title 订阅app退出信号 +// @Description +// @Author Ms <133814250@qq.com> +// @Param stopSig +// +func (util *signal) ListenStop(stopSig chan StopSignal) { + exitWaitHandler.mutex.Lock() + defer exitWaitHandler.mutex.Unlock() + + exitWaitHandler.stopSignList = append(exitWaitHandler.stopSignList, stopSig) +} diff --git a/hotgo-server/app/utils/validate_util.go b/hotgo-server/app/utils/validate_util.go new file mode 100644 index 0000000..fd4adb0 --- /dev/null +++ b/hotgo-server/app/utils/validate_util.go @@ -0,0 +1,30 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package utils + +import ( + "net" +) + +// 验证类 +var Validate = new(validate) + +type validate struct{} + +// +// @Title 是否为ipv4 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ip +// @Return bool +// +func (util *validate) IsIp(ip string) bool { + if net.ParseIP(ip) != nil { + return true + } + return false +} diff --git a/hotgo-server/boot/queue.go b/hotgo-server/boot/queue.go new file mode 100644 index 0000000..1260e47 --- /dev/null +++ b/hotgo-server/boot/queue.go @@ -0,0 +1,42 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package boot + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/factory/queue" + "github.com/bufanyun/hotgo/app/service/sysService" +) + +// +// @Title 消息队列监听 +// @Description +// @Author Ms <133814250@qq.com> +// @Param ctx +// +func QueueListen(ctx context.Context) { + + consumer, err := queue.InstanceConsumer() + if err != nil { + queue.FatalLog(ctx, "InstanceConsumer异常", err) + return + } + + // 全局日志 + if listenErr := consumer.ListenReceiveMsgDo(consts.QueueLogTopic, func(mqMsg queue.MqMsg) { + + // 自定义消费回调 + err := sysService.Log.QueueJob(ctx, mqMsg) + + // 记录消费日志 + queue.ConsumerLog(ctx, consts.QueueLogTopic, mqMsg, err) + }); listenErr != nil { + queue.FatalLog(ctx, "主题:"+consts.QueueLogTopic+" 监听失败", listenErr) + } + +} diff --git a/hotgo-server/boot/run.go b/hotgo-server/boot/run.go new file mode 100644 index 0000000..486f909 --- /dev/null +++ b/hotgo-server/boot/run.go @@ -0,0 +1,96 @@ +// +// @Link https://github.com/bufanyun/hotgo +// @Copyright Copyright (c) 2022 HotGo CLI +// @Author Ms <133814250@qq.com> +// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE +// +package boot + +import ( + "context" + "github.com/bufanyun/hotgo/app/consts" + "github.com/bufanyun/hotgo/app/hook" + "github.com/bufanyun/hotgo/app/middleware" + "github.com/bufanyun/hotgo/app/model" + "github.com/bufanyun/hotgo/router" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gcmd" + "github.com/gogf/gf/v2/protocol/goai" +) + +var ( + Main = gcmd.Command{ + Name: "main", + Usage: "main", + Brief: "start http server of HotGo!", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + s := g.Server() + + // 错误状态码接管 + s.BindStatusHandler(404, func(r *ghttp.Request) { + r.Response.Writeln("404 - 你似乎来到了没有知识存在的荒原…") + }) + s.BindStatusHandler(403, func(r *ghttp.Request) { + r.Response.Writeln("403 - 网站拒绝显示此网页") + }) + + // 请求结束事件回调 + s.BindHookHandler("/*any", ghttp.HookAfterOutput, hook.Instance().GlobalLog) + + s.Group("/", func(group *ghttp.RouterGroup) { + + // 注册全局中间件 + group.Middleware( + middleware.Instance().Ctx, //必须第一个加载 + middleware.Instance().CORS, + middleware.Instance().HandlerResponse, + ) + + // 注册默认首页路由 + group.ALL("/", func(r *ghttp.Request) { + r.Response.Write("hello hotGo!!") + }) + + // 注册后台路由 + router.Admin(ctx, group) + + // 注册API路由 + router.Api(ctx, group) + + }) + + // Custom enhance API document. + enhanceOpenAPIDoc(s) + + // 消息队列 + QueueListen(ctx) + + // Just run the server. + s.Run() + return nil + }, + } +) + +// +// @Title API document +// @Description +// @Author Ms <133814250@qq.com> +// @Param s +// +func enhanceOpenAPIDoc(s *ghttp.Server) { + openapi := s.GetOpenApi() + openapi.Config.CommonResponse = model.Response{} + openapi.Config.CommonResponseDataField = `Data` + + // API description. + openapi.Info = goai.Info{ + Title: consts.OpenAPITitle, + Description: consts.OpenAPIDescription, + Contact: &goai.Contact{ + Name: consts.OpenAPIName, + URL: consts.OpenAPIURL, + }, + } +} diff --git a/hotgo-server/config/config.example.yaml b/hotgo-server/config/config.example.yaml new file mode 100644 index 0000000..fbd876b --- /dev/null +++ b/hotgo-server/config/config.example.yaml @@ -0,0 +1,132 @@ +# hotgo配置 +hotgo: + debug: true # debug开关,开启后:接口出现错误时会输出堆栈信息,默认为true + ipMethod: "cz88" # IP归属地解析方法,可选:cz88|whois,默认为cz88 + log: # 全局请求日志 + switch: true # 日志开关,默认为true + queue: true # 是否启用队列,启用时需要配置队列信息,默认为true + module: ["admin", "api"] # 需要记录的模块 + skipCode: [] # 不记录的状态码,如: ["0", "-1"] + +# 路由配置 +router: + # 后台 + admin: + # 前缀 + prefix: "/admin" + # 不需要验证登录的路由地址 + exceptLogin: [ + "/login/captcha", # 登录验证码 + "/login/sign", # 登录 + ] + # 不需要验证权限的路由地址 + exceptAuth: [ + "/member/info", # 登录用户信息 + "/role/dynamic", # 获取动态路由 + ] + # 接口 + api: + # 前缀 + prefix: "/api" + # 不需要验证登录的路由地址 + exceptPath: [] + + +# HTTP Server. +server: + address: ":8299" + serverRoot: "resource/public" + openapiPath: "/openApi.json" + swaggerPath: "/doc" + DumpRouterMap: false + logPath: "./runtime/log/server" + ErrorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true + ErrorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true + errorLogPattern: "error/{Y-m-d}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log" + accessLogEnabled: true # 是否记录访问日志。默认为false + accessLogPattern: "access/{Y-m-d}.log" # 访问日志文件格式。默认为"access-{Ymd}.log" + serverAgent: "HG HTTP Server" + + +# Global logging. +logger: + level: "all" + stdout: true + headerPrint: false + ctxKeys: [] + path: "./runtime/log/logger" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + file: "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log" + exception: # 系统异常日志 + path: "./runtime/log/exception" + level: "all" + file: "{Y-m-d}.log" + queue: # 消息队列日志 + path: "./runtime/log/queue" + level: "all" + file: "{Y-m-d}.log" + +#JWT +jwt: + version: "1.0" # 版本号 + expires: "864000" # 有效期,单位:秒 + sign: "hotgo" # 秘钥,考虑安全问题请修改默认值 + multiPort: true # 是否允许多端登录,默认为true + +#消息队列 +queue: + switch: true # 队列开关,默认为true + driver: "redis" # 队列驱动,可选:redis|rocketmq|kafka + retry: 2 # 重试次数 + multiComsumer: true # 是否支持创建多个消费者 + groupName: "hotgo" # mq群组名称 + redis: + address: "127.0.0.1:6379" # redis服务地址,默认为127.0.0.1:6379 + db: 5 # 指定redis库 + pass: "meng133814250" # redis密码 + timeout: 0 # 队列超时时间(s) ,0为永不超时,当队列一直没有被消费到达超时时间则队列会被销毁 + rocketmq: + address: "127.0.0.1:9876" # brocker地址+端口 + logLevel: "all" # 系统日志级别,可选:all|close|debug|info|warn|error|fatal + kafka: + address: "127.0.0.1:9092" # kafka地址+端口 + version: "2.0.0.0" # kafka专属配置,默认2.0.0.0 + randClient: true # 开启随机生成clientID,可以实现启动多实例同时一起消费相同topic,加速消费能力的特性,默认为true + +# Redis数据库配置 +redis: + default: + address: "127.0.0.1:6379" + db: "5" + pass: "meng133814250" + idleTimeout: "20" +# cache: +# address: "127.0.0.1:6379" +# db: "5" +# pass: "meng133814250" +# idleTimeout: "20" + +# Database. +database: + logger: + level: "all" + stdout: true + + default: + link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo" + debug: true + Prefix: "hg_" + +# CLI. +gfcli: + build: + name: "hg" + gen: + dao: + - link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo" + path: "./app" + # tables: "" #指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。 + # tablesEx: "" #指定当前数据库中需要排除代码生成的数据表。 + removePrefix: "hg_" + descriptionTag: true + noModelComment: true + jsonCase: "Snake" \ No newline at end of file diff --git a/hotgo-server/config/config.yaml b/hotgo-server/config/config.yaml new file mode 100644 index 0000000..99c574c --- /dev/null +++ b/hotgo-server/config/config.yaml @@ -0,0 +1,132 @@ +# hotgo配置 +hotgo: + debug: true # debug开关,开启后:接口出现错误时会输出堆栈信息,默认为true + ipMethod: "cz88" # IP归属地解析方法,可选:cz88|whois,默认为cz88 + log: # 全局请求日志 + switch: true # 日志开关,默认为true + queue: true # 是否启用队列,启用时需要配置队列信息,默认为true + module: ["admin", "api"] # 需要记录的模块 + skipCode: [] # 不记录的状态码,如: ["0", "-1"] + +# 路由配置 +router: + # 后台 + admin: + # 前缀 + prefix: "/admin" + # 不需要验证登录的路由地址 + exceptLogin: [ + "/login/captcha", # 登录验证码 + "/login/sign", # 登录 + ] + # 不需要验证权限的路由地址 + exceptAuth: [ + "/member/info", # 登录用户信息 + "/role/dynamic", # 获取动态路由 + ] + # 接口 + api: + # 前缀 + prefix: "/api" + # 不需要验证登录的路由地址 + exceptPath: [] + + +# HTTP Server. +server: + address: ":8299" + serverRoot: "resource/public" + openapiPath: "/openApi.json" + swaggerPath: "/doc" + DumpRouterMap: false + logPath: "./runtime/log/server" + ErrorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true + ErrorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true + errorLogPattern: "error/{Y-m-d}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log" + accessLogEnabled: true # 是否记录访问日志。默认为false + accessLogPattern: "access/{Y-m-d}.log" # 访问日志文件格式。默认为"access-{Ymd}.log" + serverAgent: "HG HTTP Server" + + +# Global logging. +logger: + level: "all" + stdout: true + headerPrint: false + ctxKeys: [] + path: "./runtime/log/logger" # 日志文件路径。默认为空,表示关闭,仅输出到终端 + file: "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log" + exception: # 系统异常日志 + path: "./runtime/log/exception" + level: "all" + file: "{Y-m-d}.log" + queue: # 消息队列日志 + path: "./runtime/log/queue" + level: "all" + file: "{Y-m-d}.log" + +#JWT +jwt: + version: "1.0" # 版本号 + expires: "864000" # 有效期,单位:秒 + sign: "hotgo" # 秘钥,考虑安全问题请修改默认值 + multiPort: true # 是否允许多端登录,默认为true + +#消息队列 +queue: + switch: true # 队列开关,默认为true + driver: "redis" # 队列驱动,可选:redis|rocketmq|kafka + retry: 2 # 重试次数 + multiComsumer: true # 是否支持创建多个消费者 + groupName: "hotgo" # mq群组名称 + redis: + address: "42.194.151.158:6379" # redis服务地址,默认为127.0.0.1:6379 + db: 5 # 指定redis库 + pass: "meng133814250" # redis密码 + timeout: 0 # 队列超时时间(s) ,0为永不超时,当队列一直没有被消费到达超时时间则队列会被销毁 + rocketmq: + address: "42.194.151.158:9876" # brocker地址+端口 + logLevel: "all" # 系统日志级别,可选:all|close|debug|info|warn|error|fatal + kafka: + address: "42.194.151.158:9092" # kafka地址+端口 + version: "2.0.0.0" # kafka专属配置,默认2.0.0.0 + randClient: true # 开启随机生成clientID,可以实现启动多实例同时一起消费相同topic,加速消费能力的特性,默认为true + +# Redis数据库配置 +redis: + default: + address: "42.194.151.158:6379" + db: "5" + pass: "meng133814250" + idleTimeout: "20" +# cache: +# address: "42.194.151.158:6379" +# db: "5" +# pass: "meng133814250" +# idleTimeout: "20" + +# Database. +database: + logger: + level: "all" + stdout: true + + default: + link: "mysql:hotgo:7P7KKABcknecLJFF@tcp(42.194.151.158:3306)/hotgo" + debug: true + Prefix: "hg_" + +# CLI. +gfcli: + build: + name: "hg" + gen: + dao: + - link: "mysql:hotgo:7P7KKABcknecLJFF@tcp(42.194.151.158:3306)/hotgo" + path: "./app" + # tables: "" #指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。 + # tablesEx: "" #指定当前数据库中需要排除代码生成的数据表。 + removePrefix: "hg_" + descriptionTag: true + noModelComment: true + jsonCase: "Snake" \ No newline at end of file diff --git a/hotgo-server/go.mod b/hotgo-server/go.mod new file mode 100644 index 0000000..255b5b9 --- /dev/null +++ b/hotgo-server/go.mod @@ -0,0 +1,26 @@ +module github.com/bufanyun/hotgo + +go 1.15 + +require ( + github.com/Shopify/sarama v1.30.1 + github.com/apache/rocketmq-client-go/v2 v2.1.0 + github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 + github.com/bufanyun/pool v0.2.1 + github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/gogf/gf/v2 v2.0.0-rc2 + github.com/gomodule/redigo v2.0.0+incompatible + github.com/google/btree v1.0.1 // indirect + github.com/ip2location/ip2location-go v8.3.0+incompatible + github.com/json-iterator/go v1.1.10 // indirect + github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794 + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/mojocn/base64Captcha v1.3.5 + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/pflag v1.0.5 + github.com/xuri/excelize/v2 v2.5.0 + go.opentelemetry.io/otel/trace v1.0.0 + go.uber.org/atomic v1.6.0 // indirect + golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 +) diff --git a/hotgo-server/go.sum b/hotgo-server/go.sum new file mode 100644 index 0000000..3f5a422 --- /dev/null +++ b/hotgo-server/go.sum @@ -0,0 +1,312 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Shopify/sarama v1.30.1 h1:z47lP/5PBw2UVKf1lvfS5uWXaJws6ggk9PLnKEHtZiQ= +github.com/Shopify/sarama v1.30.1/go.mod h1:hGgx05L/DiW8XYBXeJdKIN6V2QUy2H6JqME5VT1NLRw= +github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae h1:ePgznFqEG1v3AjMklnK8H7BSc++FDSo7xfK9K7Af+0Y= +github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= +github.com/apache/rocketmq-client-go/v2 v2.1.0 h1:3eABKfxc1WmS2lLTTbKMe1gZfZV6u1Sx9orFnOfABV0= +github.com/apache/rocketmq-client-go/v2 v2.1.0/go.mod h1:oEZKFDvS7sz/RWU0839+dQBupazyBV7WX5cP6nrio0Q= +github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= +github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= +github.com/bufanyun/pool v0.2.1 h1:rW6TVJt+vS71d1uBI9sCMUjS39AWZFsUww+2XOh+338= +github.com/bufanyun/pool v0.2.1/go.mod h1:uZsjaA/H4agFQ1E0KWj4bnzRUVGmieM54pJiIKPTrAI= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E= +github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= +github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogf/gf/v2 v2.0.0-rc2 h1:WznHd6sGOQ0ef1r4UdejUnXHT4058b1R/cumQL5tooE= +github.com/gogf/gf/v2 v2.0.0-rc2/go.mod h1:apktt6TleWtCIwpz63vBqUnw8MX8gWKoZyxgDpXFtgM= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0= +github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ip2location/ip2location-go v8.3.0+incompatible h1:QwUE+FlSbo6bjOWZpv2Grb57vJhWYFNPyBj2KCvfWaM= +github.com/ip2location/ip2location-go v8.3.0+incompatible/go.mod h1:3JUY1TBjTx1GdA7oRT7Zeqfc0bg3lMMuU5lXmzdpuME= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794 h1:dWJxw+KQOMeVcoyxqG9I5fppPld1hh1FG8ngv0fKNsQ= +github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794/go.mod h1:IwrOeG3O3K9vVXmcVvc9T0XLabw67QePi5pKQt5U+Kw= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= +github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= +github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= +github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 h1:N8Bg45zpk/UcpNGnfJt2y/3lRWASHNTUET8owPYCgYI= +github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tidwall/gjson v1.2.1 h1:j0efZLrZUvNerEf6xqoi0NjWMK5YlLrR7Guo/dxY174= +github.com/tidwall/gjson v1.2.1/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA= +github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65 h1:rQ229MBgvW68s1/g6f1/63TgYwYxfF4E+bi/KC19P8g= +github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o= +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.5.0 h1:nDDVfX0qaDuGjAvb+5zTd0Bxxoqa1Ffv9B4kiE23PTM= +github.com/xuri/excelize/v2 v2.5.0/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI= +go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg= +go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y= +go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM= +go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4= +go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 h1:kETrAMYZq6WVGPa8IIixL0CaEcIUNi+1WX7grUoi3y8= +golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 h1:GLw7MR8AfAG2GmGcmVgObFOHXYypgGjnGno25RDwn3Y= +golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +stathat.com/c/consistent v1.0.0 h1:ezyc51EGcRPJUxfHGSgJjWzJdj3NiMU9pNfLNGiXV0c= +stathat.com/c/consistent v1.0.0/go.mod h1:QkzMWzcbB+yQBL2AttO6sgsQS/JSTapcDISJalmCDS0= diff --git a/hotgo-server/main.go b/hotgo-server/main.go new file mode 100644 index 0000000..20efd7f --- /dev/null +++ b/hotgo-server/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "github.com/bufanyun/hotgo/boot" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" +) + +func main() { + + var ( + ctx = gctx.New() + ) + + if err := boot.Main.RunWithError(ctx); err != nil { + g.Log().Fatal(ctx, err) + } +} diff --git a/hotgo-server/pull.bat b/hotgo-server/pull.bat new file mode 100644 index 0000000..cfa6d5f --- /dev/null +++ b/hotgo-server/pull.bat @@ -0,0 +1,15 @@ +::强制和远程同步,不保留本地修改 +::git fetch --all +::git reset --hard origin/master +::git pull + + +::保存本地修改,拉取远程后恢复本地修改 +::git stash +::git pull origin master +::git stash pop +::git stash list +::git stash clear + +::拉取远程 +git pull origin master \ No newline at end of file diff --git a/hotgo-server/push.bat b/hotgo-server/push.bat new file mode 100644 index 0000000..fb2eecc --- /dev/null +++ b/hotgo-server/push.bat @@ -0,0 +1,11 @@ +echo -e "\n \n" >> ./README.md + +::git rm -r --cached -f . +git init && git add -A + +for /f "tokens=2 delims==" %%a in ('wmic path win32_operatingsystem get LocalDateTime /value') do (set t=%%a) +set Today=%t:~0,4%-%t:~4,2%-%t:~6,2% %t:~8,2%:%t:~10,2% + +git commit -m "%Today%" + +git push git@gitee.com:bufanyun/hotgo.git master \ No newline at end of file diff --git a/hotgo-server/resource/public/html/.gitkeep b/hotgo-server/resource/public/html/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/hotgo-server/resource/public/plugin/.gitkeep b/hotgo-server/resource/public/plugin/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/hotgo-server/resource/public/plugin/layer-3.1.1/layer.js b/hotgo-server/resource/public/plugin/layer-3.1.1/layer.js new file mode 100644 index 0000000..12cb6b5 --- /dev/null +++ b/hotgo-server/resource/public/plugin/layer-3.1.1/layer.js @@ -0,0 +1,2 @@ +/*! layer-v3.1.1 Web弹层组件 MIT License http://layer.layui.com/ By 贤心 */ + ;!function(e,t){"use strict";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,i=t.length-1,n=i;n>0;n--)if("interactive"===t[n].readyState){e=t[n].src;break}return e||t[i].src}();return e.substring(0,e.lastIndexOf("/")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:["确定","取消"],type:["dialog","page","iframe","loading","tips"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName("head")[0],s=document.createElement("link");"string"==typeof i&&(n=i);var l=(n||t).replace(/\.|\//g,""),f="layuicss-"+l,c=0;s.rel="stylesheet",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),"function"==typeof i&&!function u(){return++c>80?e.console&&console.error("layer.css: Invalid"):void(1989===parseInt(o.getStyle(document.getElementById(f),"width"))?i():setTimeout(u,100))}()}}},r={v:"3.1.1",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||"ActiveXObject"in e)&&((t.match(/msie\s(\d+)/)||[])[1]||"11")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,"string"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss("modules/layer/"+e.extend):o.link("theme/"+e.extend),this):this},ready:function(e){var t="layer",i="",n=(a?"modules/layer/":"theme/")+"default/layer.css?v="+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a="function"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s="function"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s="function"==typeof n,f=o.config.skin,c=(f?f+" "+f+"-msg":"")||"layui-layer-msg",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+" layui-layer-hui",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+" "+(n.skin||"layui-layer-hui")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},s=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},30)};s.pt=s.prototype;var l=["layui-layer",".layui-layer-title",".layui-layer-main",".layui-layer-dialog","layui-layer-iframe","layui-layer-content","layui-layer-btn","layui-layer-close"];l.anim=["layer-anim-00","layer-anim-01","layer-anim-02","layer-anim-03","layer-anim-04","layer-anim-05","layer-anim-06"],s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:"信息",offset:"auto",area:"auto",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f="object"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'
'+(n.content||"")+"
"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"':"")+'=`ua
zfic<-4J8bxat(%{#u1VF`w7bYxVKhb6q?tch9)4|d-w!er=Z!MnN!4!@I sAcE&D*As&d
zm?SnubQ1AxK;W-}f!42;rcT_YlTMb1h={+u*AifV)YWp|a_$j}gv@tX-Sn_x|1Vu?
z`Am17rltTs18JUj-JPex^-Vf)x8iutFV8?xqN1v5ch~AKHJG6j0!zAGgucEcY7^xf
z73iv`+LxeEGKd;~{6PxYL@;(_dA;*0-vwePCL-d!HzVI|=5zDSvtY_rV7FUjvYg73
z72LQ_!)EEV9_c9{|D*;cwy)Pfjt(X%_ntM%t4yD^TE`+xPEN)X3uGX(vpUPf?9fEI~1ugxg92Smq=TX}NN*{{O
z_%@&Hcw?%)J<^S#TkyIpGAoTQw8efW!yc^QS4qczDIsS*$
zFnYQG-N~KoU9g1?3>4(|{w-k(G#DruR(~p4+^-TOQW5%Vy|;IY291sEbHg8rebxd5
zD^PFVV6{8~FH37nTF4(U>))Rz{yl@=;Pm&27e-{UL5r6GY-BhvevYz{-zn`uWdJ}<
zXD5G74v~vNk|>2JC!<`TAsH+zY