├── .gitattributes ├── .gitignore ├── .idea ├── .gitignore ├── .name ├── dataSources.xml ├── ev2.iml ├── inspectionProfiles │ └── Project_Default.xml ├── modules.xml └── vcs.xml ├── Dockerfile ├── LICENSE ├── README-cn.md ├── README.md ├── cmd ├── ev │ ├── ev_windows.syso │ └── main.go ├── ev_builder │ └── main.go ├── ev_plugin_builder │ └── main.go └── ev_plugin_zip │ └── main.go ├── config ├── config.yml ├── config.yml.tpl └── i18n │ ├── en.json │ └── zh-cn.json ├── config_dev └── config.yml ├── debug.go ├── generate.go ├── go.mod ├── go.sum ├── go.work ├── go.work.sum ├── gowatch.yml ├── pkg ├── api │ ├── ai_controller.go │ ├── base_controller.go │ ├── es_controller.go │ ├── es_link_controller.go │ ├── gm_operater_log.go │ ├── index_controller.go │ ├── live_controller.go │ ├── manager_role_controller.go │ ├── manager_user_controller.go │ ├── notice_controller.go │ ├── plugin_config_controller.go │ ├── plugin_controller.go │ └── plugin_util_controller.go ├── consts │ └── notice.go ├── infrastructure │ ├── access_control │ │ └── rbac.go │ ├── config │ │ ├── config.go │ │ ├── save_config.go │ │ └── version.go │ ├── dao │ │ ├── es_connect_dao.go │ │ ├── es_link_v2_dao.go │ │ ├── eslink_cfg_v2_dao.go │ │ ├── eslink_role_cfg_reletion_dao.go │ │ ├── ev_back_dao.go │ │ ├── gm_operater_log_dao.go │ │ ├── gm_role_dao.go │ │ ├── gm_role_eslink_cfg_v2.go │ │ ├── gm_user.go │ │ ├── notice_dao.go │ │ └── plugin_config_dao.go │ ├── dto │ │ ├── ai.go │ │ ├── common │ │ │ └── common.go │ │ ├── datax.go │ │ ├── es_alias.go │ │ ├── es_cat.go │ │ ├── es_connect.go │ │ ├── es_crud.go │ │ ├── es_doc.go │ │ ├── es_index.go │ │ ├── es_link.go │ │ ├── es_map.go │ │ ├── es_optimize.go │ │ ├── es_reindex.go │ │ ├── es_rest.go │ │ ├── es_task.go │ │ ├── gm_role.go │ │ ├── guid.go │ │ ├── live.go │ │ ├── notice.go │ │ ├── oauth.go │ │ ├── operater_log_list.go │ │ ├── plugin.go │ │ ├── plugin_config.go │ │ ├── plugin_util.go │ │ ├── route.go │ │ ├── snapshot.go │ │ ├── sql2dsl.go │ │ ├── url_config.go │ │ ├── user.go │ │ └── ws.go │ ├── es_sdk │ │ └── pkg │ │ │ ├── base │ │ │ └── base_datasource.go │ │ │ ├── cache │ │ │ └── data_source.go │ │ │ ├── clickhouse │ │ │ └── clickhouse.go │ │ │ ├── dameng │ │ │ └── dameng.go │ │ │ ├── es_log │ │ │ └── logger.go │ │ │ ├── factory │ │ │ └── factory.go │ │ │ ├── hive │ │ │ ├── hive.go │ │ │ └── hive_dirver │ │ │ │ ├── dsn.go │ │ │ │ ├── hive.go │ │ │ │ ├── migrator.go │ │ │ │ └── serializer.go │ │ │ ├── mariadb │ │ │ └── mariadb.go │ │ │ ├── mongo │ │ │ └── mongo.go │ │ │ ├── mysql │ │ │ └── mysql.go │ │ │ ├── oracle │ │ │ └── oracle.go │ │ │ ├── postgresql │ │ │ └── postgresql.go │ │ │ ├── proto │ │ │ └── config.go │ │ │ ├── redis │ │ │ └── redis.go │ │ │ ├── sqlserver │ │ │ └── sqlserver.go │ │ │ ├── utils │ │ │ └── sql.go │ │ │ ├── v6 │ │ │ └── es.go │ │ │ ├── v7 │ │ │ └── es.go │ │ │ └── v8 │ │ │ └── es.go │ ├── eve_api │ │ ├── api │ │ │ └── api.go │ │ ├── doc.go │ │ ├── dto │ │ │ ├── comment.go │ │ │ ├── ev_key.go │ │ │ └── plugin.go │ │ ├── ev_api.go │ │ └── vo │ │ │ ├── comment.go │ │ │ ├── common.go │ │ │ ├── plugin.go │ │ │ └── wx_article.go │ ├── jwt_svr │ │ ├── errors.go │ │ ├── exception_msg.go │ │ └── jwt.go │ ├── localcache │ │ └── cache.go │ ├── logger │ │ └── log.go │ ├── middleware │ │ ├── Exception.go │ │ └── middleware_svr.go │ ├── migrator_cfg │ │ └── migrators.go │ ├── model │ │ ├── datax_link_info_model.go │ │ ├── datax_list_model.go │ │ ├── es_connect.go │ │ ├── es_link_cfg_v3.go │ │ ├── es_link_model.go │ │ ├── es_link_role_v3.go │ │ ├── es_link_v3.go │ │ ├── eslink_cfg.go │ │ ├── eslink_role_cfg_reletion.go │ │ ├── gm_operater_log.go │ │ ├── gm_role.go │ │ ├── gm_role_eslink_cfg.go │ │ ├── gm_user.go │ │ ├── guid_model.go │ │ ├── jwt_key.go │ │ ├── notice.go │ │ ├── notice_read_log.go │ │ ├── notice_target.go │ │ ├── plugin_config.go │ │ └── user_role_relation.go │ ├── my_error │ │ ├── es_index.go │ │ └── my_error.go │ ├── orm │ │ ├── gorm_log.go │ │ ├── migrator │ │ │ └── migrator.go │ │ ├── orm.go │ │ ├── sqlite │ │ │ ├── ddlmod.go │ │ │ ├── errors.go │ │ │ ├── migrator.go │ │ │ └── sqlite.go │ │ ├── squirrel.go │ │ └── svr_log │ │ │ └── svr_log.go │ ├── plugin_rpc │ │ ├── plugin_rpc_server.go │ │ └── plugin_util.go │ ├── plugins │ │ ├── backendplugin │ │ │ ├── grpc_plugin │ │ │ │ ├── client.go │ │ │ │ ├── client_v2.go │ │ │ │ ├── grpc_plugin.go │ │ │ │ └── log_wrapper.go │ │ │ ├── plugin.go │ │ │ └── provider │ │ │ │ └── provider.go │ │ ├── datasource.go │ │ ├── manager │ │ │ ├── interfaces.go │ │ │ ├── plugin_manager.go │ │ │ └── process │ │ │ │ ├── ifaces.go │ │ │ │ └── process.go │ │ └── plugin │ │ │ └── plugin.go │ ├── pluginstore │ │ └── plugin_store_service.go │ ├── process │ │ ├── process.go │ │ ├── root_check.go │ │ └── root_check_windows.go │ ├── request │ │ └── Request.go │ ├── response │ │ └── response.go │ ├── sqlstore │ │ ├── gorm_log.go │ │ ├── migrator │ │ │ └── migrator.go │ │ ├── orm.go │ │ ├── sqlite │ │ │ ├── ddlmod.go │ │ │ ├── errors.go │ │ │ ├── migrator.go │ │ │ └── sqlite.go │ │ ├── squirrel.go │ │ └── svr_log │ │ │ └── svr_log.go │ ├── vo │ │ ├── alias_info.go │ │ ├── cat_index.go │ │ ├── es_back.go │ │ ├── es_link.go │ │ ├── index_html.go │ │ ├── live.go │ │ ├── oauth.go │ │ ├── operater.go │ │ ├── ping_result.go │ │ ├── plugin_util.go │ │ ├── snapshot.go │ │ ├── sql2dsl.go │ │ ├── task_info.go │ │ ├── url_config.go │ │ ├── user.go │ │ ├── user_info.go │ │ └── ws.go │ └── web_engine │ │ ├── mock_map.go │ │ └── web_engine.go ├── registry │ └── registry.go ├── server │ ├── backgroundsvcs │ │ └── background_services.go │ ├── generate.go │ ├── server.go │ ├── systray_darwin.go │ ├── systray_linux.go │ ├── systray_windows.go │ ├── wire.go │ └── wire_gen.go ├── services │ ├── big_mode_service │ │ └── big_mode.go │ ├── cache_service │ │ └── es_link_cache.go │ ├── es │ │ └── es.go │ ├── es_link_service │ │ └── es_link_service.go │ ├── es_service │ │ └── es_service.go │ ├── eve_service │ │ └── eve_service.go │ ├── gm_operater_log │ │ ├── gm_operater_log_service.go │ │ └── report_accpet_status.go │ ├── gm_role │ │ └── gm_role_service.go │ ├── gm_user │ │ ├── exception.go │ │ └── gm_user_service.go │ ├── live_svr │ │ ├── consts.go │ │ └── live.go │ ├── notice_service │ │ └── notice_service.go │ ├── oauth │ │ ├── dingtalk.go │ │ ├── feishu.go │ │ ├── idp.go │ │ ├── interfaces.go │ │ ├── utils │ │ │ └── util.go │ │ └── work_wechat.go │ ├── plugin_config_service │ │ └── plugin_config_service.go │ ├── plugin_install_service │ │ └── plugin_install_service.go │ ├── plugin_service │ │ └── plugin_service.go │ ├── print_logo │ │ └── print.go │ ├── updatechecker │ │ ├── ev_update.go │ │ └── plugins.go │ ├── web │ │ ├── ai.go │ │ ├── es.go │ │ ├── es_link.go │ │ ├── manager_user.go │ │ ├── notice.go │ │ ├── operater_log.go │ │ ├── plugins.go │ │ ├── pprof.go │ │ ├── web_server.go │ │ └── ws.go │ └── webview │ │ ├── webview.go │ │ ├── webview_darwin.go │ │ ├── webview_linux.go │ │ └── webview_windows.go └── util │ ├── _excel.go │ ├── aes.go │ ├── array.go │ ├── cast.go │ ├── charset.go │ ├── config.go │ ├── dir.go │ ├── download.go │ ├── ecb.go │ ├── encoding.go │ ├── encryption.go │ ├── errors.go │ ├── exec.go │ ├── exnet.go │ ├── filepath.go │ ├── gzip.go │ ├── hash.go │ ├── http.go │ ├── interface.go │ ├── ip.go │ ├── ip_address.go │ ├── json.go │ ├── map.go │ ├── math.go │ ├── md5.go │ ├── process.go │ ├── proxyutil │ ├── proxyutil.go │ └── reverse_proxy.go │ ├── response │ └── res.go │ ├── retry.go │ ├── split_email.go │ ├── strings.go │ ├── sys.go │ ├── time.go │ ├── token.go │ ├── url.go │ ├── validation.go │ └── zip.go ├── resources ├── docs │ ├── docs.go │ ├── swagger.json │ └── swagger.yaml ├── views │ ├── dist │ │ ├── css │ │ │ ├── 401.groh0FKW.css │ │ │ ├── 404.DdLmOjPs.css │ │ │ ├── EsHeader.BKG5A0gH.css │ │ │ ├── SocialSignin.B51_dUaK.css │ │ │ ├── auth.DWNkgu85.css │ │ │ ├── el-card.BJ3sbP9B.css │ │ │ ├── el-checkbox.BFZaSjz7.css │ │ │ ├── el-col.BP4dtlli.css │ │ │ ├── el-descriptions-item.D_IHWRLM.css │ │ │ ├── el-dialog.BCeqVwJ2.css │ │ │ ├── el-divider.Ca8J-BER.css │ │ │ ├── el-dropdown-item.OF0DpcuD.css │ │ │ ├── el-empty.BgB1A-Jc.css │ │ │ ├── el-form.Bw6vhIyH.css │ │ │ ├── el-loading.BzeNAeTO.css │ │ │ ├── el-main.Dk0d5xqJ.css │ │ │ ├── el-pagination.EEgK1E05.css │ │ │ ├── el-popover.BXo9j6C6.css │ │ │ ├── el-popper.8rcjPMiY.css │ │ │ ├── el-scrollbar.DgVM_IK3.css │ │ │ ├── el-select.DiVaJgmx.css │ │ │ ├── el-switch.BhrVVMax.css │ │ │ ├── el-tab-pane.99T6i4TO.css │ │ │ ├── el-table-column.Ds_oPOdx.css │ │ │ ├── el-tag.5TqU4q48.css │ │ │ ├── el-text.CjuDOozN.css │ │ │ ├── el-tree.LD6oLcSu.css │ │ │ ├── index.BDPie1vG.css │ │ │ ├── index.CFpa0Vkg.css │ │ │ ├── index.COMmMkyX.css │ │ │ ├── index.CiheunKZ.css │ │ │ ├── index.DCEm4HY0.css │ │ │ ├── index.gIaAfrbD.css │ │ │ ├── index.yYoVy1fL.css │ │ │ ├── link.022h2UdK.css │ │ │ ├── manager.D-PSOYEY.css │ │ │ ├── market.BGeD_Tr7.css │ │ │ ├── operater_log.Bsg7BLuc.css │ │ │ ├── role.Dzp6fMUx.css │ │ │ └── user.DcIEw2vN.css │ │ ├── favicon.ico │ │ ├── img │ │ │ ├── 401.DaBJYOxp.gif │ │ │ ├── 404.D6_y3Jr2.png │ │ │ ├── login-background-dark.BfPFE40x.jpg │ │ │ ├── login-background-light.CKlK6emc.jpg │ │ │ ├── login_bg.BzmVCLXR.png │ │ │ ├── login_dark_bg2.CmiPvwd_.png │ │ │ ├── logo.Cq2B5Nmk.png │ │ │ ├── social_dingtalk.CFQi2ZM6.png │ │ │ └── work_wechat.BCef331m.png │ │ ├── index.html │ │ └── js │ │ │ ├── 401.CMUobuGv.js │ │ │ ├── 401.CMUobuGv.js.map │ │ │ ├── 404.ZvXmlrTg.js │ │ │ ├── 404.ZvXmlrTg.js.map │ │ │ ├── EsDashbord.DQ8PFQ7Z.js │ │ │ ├── EsDashbord.DQ8PFQ7Z.js.map │ │ │ ├── EsDashbord.vue_vue_type_script_setup_true_lang.CAKr5SDJ.js │ │ │ ├── EsDashbord.vue_vue_type_script_setup_true_lang.CAKr5SDJ.js.map │ │ │ ├── EsHeader.DzWjgZKX.js │ │ │ ├── EsHeader.DzWjgZKX.js.map │ │ │ ├── SocialSignin.Cx4e1zW9.js │ │ │ ├── SocialSignin.Cx4e1zW9.js.map │ │ │ ├── _Uint8Array.BXE-IZF6.js │ │ │ ├── _Uint8Array.BXE-IZF6.js.map │ │ │ ├── _plugin-vue_export-helper.BCo6x5W8.js │ │ │ ├── _plugin-vue_export-helper.BCo6x5W8.js.map │ │ │ ├── api-rbac.CA2SkCO7.js │ │ │ ├── api-rbac.CA2SkCO7.js.map │ │ │ ├── auth.h-wbLJy6.js │ │ │ ├── auth.h-wbLJy6.js.map │ │ │ ├── config.BqZ2rU3T.js │ │ │ ├── config.BqZ2rU3T.js.map │ │ │ ├── dropdown.4KO_-19L.js │ │ │ ├── dropdown.4KO_-19L.js.map │ │ │ ├── el-card.R72UYFc_.js │ │ │ ├── el-card.R72UYFc_.js.map │ │ │ ├── el-checkbox.rYFi_c9y.js │ │ │ ├── el-checkbox.rYFi_c9y.js.map │ │ │ ├── el-col.BsOiadIF.js │ │ │ ├── el-col.BsOiadIF.js.map │ │ │ ├── el-descriptions-item.ByqtsUbZ.js │ │ │ ├── el-descriptions-item.ByqtsUbZ.js.map │ │ │ ├── el-dialog.Bqm6netJ.js │ │ │ ├── el-dialog.Bqm6netJ.js.map │ │ │ ├── el-divider.DpgZ14tg.js │ │ │ ├── el-divider.DpgZ14tg.js.map │ │ │ ├── el-dropdown-item.DJlbMif0.js │ │ │ ├── el-dropdown-item.DJlbMif0.js.map │ │ │ ├── el-empty.180sZlog.js │ │ │ ├── el-empty.180sZlog.js.map │ │ │ ├── el-form-item.l0sNRNKZ.js │ │ │ ├── el-form-item.l0sNRNKZ.js.map │ │ │ ├── el-form.YCpBerBb.js │ │ │ ├── el-form.YCpBerBb.js.map │ │ │ ├── el-loading.BfmLw6GA.js │ │ │ ├── el-loading.BfmLw6GA.js.map │ │ │ ├── el-main.BRYAhTR8.js │ │ │ ├── el-main.BRYAhTR8.js.map │ │ │ ├── el-pagination.FyRe8rDt.js │ │ │ ├── el-pagination.FyRe8rDt.js.map │ │ │ ├── el-popover._y-NWNOE.js │ │ │ ├── el-popover._y-NWNOE.js.map │ │ │ ├── el-popper.BzcpLqPh.js │ │ │ ├── el-popper.BzcpLqPh.js.map │ │ │ ├── el-scrollbar.BjxYtaG6.js │ │ │ ├── el-scrollbar.BjxYtaG6.js.map │ │ │ ├── el-select.CkmlXTKn.js │ │ │ ├── el-select.CkmlXTKn.js.map │ │ │ ├── el-switch.F8zLIDGp.js │ │ │ ├── el-switch.F8zLIDGp.js.map │ │ │ ├── el-tab-pane.ClbpsFZs.js │ │ │ ├── el-tab-pane.ClbpsFZs.js.map │ │ │ ├── el-table-column.WTvCZQDW.js │ │ │ ├── el-table-column.WTvCZQDW.js.map │ │ │ ├── el-text.Bypy8Vf2.js │ │ │ ├── el-text.Bypy8Vf2.js.map │ │ │ ├── el-tree.BQKfct64.js │ │ │ ├── el-tree.BQKfct64.js.map │ │ │ ├── es.B8paRaNL.js │ │ │ ├── es.B8paRaNL.js.map │ │ │ ├── index.3FmgA6sU.js │ │ │ ├── index.3FmgA6sU.js.map │ │ │ ├── index.B-gegPCF.js │ │ │ ├── index.B-gegPCF.js.map │ │ │ ├── index.B6fdKp2E.js │ │ │ ├── index.B6fdKp2E.js.map │ │ │ ├── index.BHh4Vwwu.js │ │ │ ├── index.BHh4Vwwu.js.map │ │ │ ├── index.BmjA1d9j.js │ │ │ ├── index.BmjA1d9j.js.map │ │ │ ├── index.Bwnvd-8P.js │ │ │ ├── index.Bwnvd-8P.js.map │ │ │ ├── index.CMEj-nma.js │ │ │ ├── index.CMEj-nma.js.map │ │ │ ├── index.Cz0VP9-_.js │ │ │ ├── index.Cz0VP9-_.js.map │ │ │ ├── index.DMDxf-Di.js │ │ │ ├── index.DMDxf-Di.js.map │ │ │ ├── index.FgtPyCZj.js │ │ │ ├── index.FgtPyCZj.js.map │ │ │ ├── index.JXlPAEz_.js │ │ │ ├── index.JXlPAEz_.js.map │ │ │ ├── index.Yqe6XU6l.js │ │ │ ├── index.Yqe6XU6l.js.map │ │ │ ├── isUndefined.DgmxjSXK.js │ │ │ ├── isUndefined.DgmxjSXK.js.map │ │ │ ├── link.DMLGjcYp.js │ │ │ ├── link.DMLGjcYp.js.map │ │ │ ├── manager.RUppTU7u.js │ │ │ ├── manager.RUppTU7u.js.map │ │ │ ├── market.Ck3HgwJl.js │ │ │ ├── market.Ck3HgwJl.js.map │ │ │ ├── oauth.CVPlsWaw.js │ │ │ ├── oauth.CVPlsWaw.js.map │ │ │ ├── oauth.vue_vue_type_script_setup_true_lang.BHISIm4Y.js │ │ │ ├── oauth.vue_vue_type_script_setup_true_lang.BHISIm4Y.js.map │ │ │ ├── operater_log.Bmp3Yp6G.js │ │ │ ├── operater_log.Bmp3Yp6G.js.map │ │ │ ├── plugins.B0Y3JA-_.js │ │ │ ├── plugins.B0Y3JA-_.js.map │ │ │ ├── refs.CMTy-Ge4.js │ │ │ ├── refs.CMTy-Ge4.js.map │ │ │ ├── role.BbB4bKuW.js │ │ │ ├── role.BbB4bKuW.js.map │ │ │ ├── strings.zoB2amMQ.js │ │ │ ├── strings.zoB2amMQ.js.map │ │ │ ├── use-dialog.DSeAULj5.js │ │ │ ├── use-dialog.DSeAULj5.js.map │ │ │ ├── user.DOzKosF8.js │ │ │ └── user.DOzKosF8.js.map │ └── fs.go └── vue │ ├── .editorconfig │ ├── .env.development │ ├── .env.production │ ├── .eslintignore │ ├── .eslintrc-auto-import.json │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .husky │ ├── commit-msg │ └── pre-commit │ ├── .prettierignore │ ├── .prettierrc.cjs │ ├── .stylelintignore │ ├── .stylelintrc.cjs │ ├── .vscode │ ├── extensions.json │ ├── settings.json │ ├── vue3.0.code-snippets │ ├── vue3.2.code-snippets │ └── vue3.3.code-snippets │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.en-US.md │ ├── README.md │ ├── commitlint.config.cjs │ ├── index.html │ ├── licenses │ ├── vue-element-admin │ │ └── LICENSE │ └── vue3-element-admin │ │ └── LICENSE │ ├── mock │ ├── auth.mock.ts │ ├── base.ts │ ├── dept.mock.ts │ ├── dict.mock.ts │ ├── log.mock.ts │ ├── menu.mock.ts │ ├── role.mock.ts │ └── user.mock.ts │ ├── npminstall-debug.log │ ├── package.json │ ├── public │ └── favicon.ico │ ├── src │ ├── App.vue │ ├── api │ │ ├── ai.ts │ │ ├── api-rbac.ts │ │ ├── auth.ts │ │ ├── es-link.ts │ │ ├── es.ts │ │ ├── i18n.ts │ │ ├── menu.ts │ │ ├── notice.ts │ │ ├── operate.ts │ │ ├── plugin.js │ │ ├── plugins.ts │ │ ├── role.ts │ │ └── user.ts │ ├── assets │ │ ├── icons │ │ │ ├── api.svg │ │ │ ├── backtop.svg │ │ │ ├── captcha.svg │ │ │ ├── cascader.svg │ │ │ ├── client.svg │ │ │ ├── close.svg │ │ │ ├── close_all.svg │ │ │ ├── close_left.svg │ │ │ ├── close_other.svg │ │ │ ├── close_right.svg │ │ │ ├── collapse.svg │ │ │ ├── dict.svg │ │ │ ├── document.svg │ │ │ ├── download.svg │ │ │ ├── fullscreen-exit.svg │ │ │ ├── fullscreen.svg │ │ │ ├── github.svg │ │ │ ├── homepage.svg │ │ │ ├── ip.svg │ │ │ ├── language.svg │ │ │ ├── menu.svg │ │ │ ├── message.svg │ │ │ ├── monitor.svg │ │ │ ├── project.svg │ │ │ ├── pv.svg │ │ │ ├── refresh.svg │ │ │ ├── role.svg │ │ │ ├── setting.svg │ │ │ ├── size.svg │ │ │ ├── system.svg │ │ │ ├── table.svg │ │ │ ├── todo.svg │ │ │ ├── tree.svg │ │ │ ├── user.svg │ │ │ └── uv.svg │ │ ├── images │ │ │ ├── 401.gif │ │ │ ├── 404.png │ │ │ ├── 404_cloud.png │ │ │ ├── login-background-dark.jpg │ │ │ ├── login-background-light.jpg │ │ │ ├── login_bg.png │ │ │ ├── login_bg2.png │ │ │ ├── login_dark_bg2.png │ │ │ ├── social_dingtalk.png │ │ │ ├── social_lark.png │ │ │ └── work_wechat.png │ │ ├── logo.jpg │ │ ├── logo.png │ │ └── zsxq.jpg │ ├── components │ │ ├── AppLink │ │ │ └── index.vue │ │ ├── Breadcrumb │ │ │ └── index.vue │ │ ├── CommentItem.vue │ │ ├── CopyButton │ │ │ └── index.vue │ │ ├── Date │ │ │ └── index.vue │ │ ├── FloatBtn.vue │ │ ├── GithubCorner │ │ │ └── index.vue │ │ ├── Hamburger │ │ │ └── index.vue │ │ ├── IconSelect │ │ │ └── index.vue │ │ ├── ImportEvKey │ │ │ └── index.vue │ │ ├── LangSelect │ │ │ └── index.vue │ │ ├── MarkDownView │ │ │ └── index.vue │ │ ├── MenuSelect │ │ │ └── index.vue │ │ ├── NoticeDropdown │ │ │ └── index.vue │ │ ├── SelectLink │ │ │ └── index.vue │ │ ├── SizeSelect │ │ │ └── index.vue │ │ └── SvgIcon │ │ │ └── index.vue │ ├── directive │ │ ├── index.ts │ │ └── permission │ │ │ └── index.ts │ ├── enums │ │ ├── CacheEnum.ts │ │ ├── DeviceEnum.ts │ │ ├── LanguageEnum.ts │ │ ├── LayoutEnum.ts │ │ ├── MenuTypeEnum.ts │ │ ├── MessageTypeEnum.ts │ │ ├── NoticeTypeEnum.ts │ │ ├── ResultEnum.ts │ │ ├── SidebarStatusEnum.ts │ │ ├── SizeEnum.ts │ │ └── ThemeEnum.ts │ ├── icons │ │ └── svg │ │ │ ├── dingtalk.svg │ │ │ └── feishu.svg │ ├── layout │ │ ├── components │ │ │ ├── AppMain │ │ │ │ └── index.vue │ │ │ ├── NavBar │ │ │ │ ├── components │ │ │ │ │ └── NavbarAction.vue │ │ │ │ └── index.vue │ │ │ ├── Settings │ │ │ │ ├── components │ │ │ │ │ ├── LayoutSelect.vue │ │ │ │ │ └── ThemeColorPicker.vue │ │ │ │ └── index.vue │ │ │ ├── Sidebar │ │ │ │ ├── components │ │ │ │ │ ├── SidebarLogo.vue │ │ │ │ │ ├── SidebarMenu.vue │ │ │ │ │ ├── SidebarMenuItem.vue │ │ │ │ │ ├── SidebarMenuItemTitle.vue │ │ │ │ │ └── SidebarMixTopMenu.vue │ │ │ │ └── index.vue │ │ │ └── TagsView │ │ │ │ └── index.vue │ │ └── index.vue │ ├── main.ts │ ├── plugins │ │ ├── icons.ts │ │ ├── index.ts │ │ └── permission.ts │ ├── router │ │ └── index.ts │ ├── settings.ts │ ├── store │ │ ├── index.ts │ │ └── modules │ │ │ ├── app.ts │ │ │ ├── notice.ts │ │ │ ├── permission.ts │ │ │ ├── settings.ts │ │ │ ├── tagsView.ts │ │ │ └── user.ts │ ├── styles │ │ ├── index.scss │ │ ├── login.scss │ │ ├── reset.scss │ │ ├── variables.module.scss │ │ └── variables.scss │ ├── types │ │ ├── auto-imports.d.ts │ │ ├── components.d.ts │ │ ├── env.d.ts │ │ ├── global.d.ts │ │ ├── router.d.ts │ │ └── socket.d.ts │ ├── utils │ │ ├── asyncRoutes.ts │ │ ├── auth.ts │ │ ├── centrifuge.js │ │ ├── clipboard.ts │ │ ├── es_link.ts │ │ ├── i18n.ts │ │ ├── index.ts │ │ ├── monaco.ts │ │ ├── nprogress.ts │ │ ├── plugin.ts │ │ ├── request.ts │ │ ├── theme.ts │ │ └── ui.ts │ └── views │ │ ├── ai │ │ └── config.vue │ │ ├── connect-tree │ │ ├── EsHeader.vue │ │ ├── auth.vue │ │ └── link.vue │ │ ├── dashboard │ │ ├── components │ │ │ └── EsDashbord.vue │ │ └── index.vue │ │ ├── error-page │ │ ├── 401.vue │ │ └── 404.vue │ │ ├── login │ │ ├── components │ │ │ └── SocialSignin.vue │ │ └── index.vue │ │ ├── notice │ │ └── index.vue │ │ ├── permission │ │ ├── oauth.vue │ │ ├── operater_log.vue │ │ ├── role.vue │ │ └── user.vue │ │ ├── plugins │ │ ├── manager.vue │ │ └── market.vue │ │ └── redirect │ │ └── index.vue │ ├── tsconfig.json │ ├── uno.config.ts │ └── vite.config.ts └── testing ├── dao_test.go └── logs └── ev ├── info.log.20240914 └── info.log.20241022 /.gitattributes: -------------------------------------------------------------------------------- 1 | *.vue linguist-language=Go 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | resources/vue/node_moudules 2 | /logs/ 3 | /resources/dist 4 | /ev.exe 5 | /cmd/test/main.go 6 | /ev_store/ 7 | /cmd/test/ 8 | /ev 9 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | server.go -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sqlite.xerial 6 | true 7 | org.sqlite.JDBC 8 | jdbc:sqlite:D:\eve\ev2\ev_store\data\es_view.db 9 | $ProjectFileDir$ 10 | 11 | 12 | file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar 13 | 14 | 15 | file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/ev2.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 使用基础镜像,比如 alpine 或者 debian,alpine 体积较小 2 | FROM alpine:latest 3 | 4 | VOLUME /app/config 5 | VOLUME /app/ev_store 6 | 7 | # 设置工作目录 8 | WORKDIR /app 9 | 10 | RUN mkdir -p /app/ev_store 11 | 12 | # 将本地的二进制文件和配置文件复制到容器中 13 | COPY ev_linux_amd64 /app/ 14 | COPY config /app/config/ 15 | 16 | # 确保二进制文件有可执行权限 17 | RUN chmod +x /app/ev_linux_amd64 18 | 19 | EXPOSE 8090 20 | 21 | # 定义容器启动时执行的命令 22 | CMD ["./ev_linux_amd64", "-configFile=config/config.yml"] 23 | -------------------------------------------------------------------------------- /cmd/ev/ev_windows.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/cmd/ev/ev_windows.syso -------------------------------------------------------------------------------- /cmd/ev_plugin_builder/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "github.com/1340691923/eve-plugin-sdk-go/build" 8 | "github.com/pkg/errors" 9 | "os" 10 | "os/exec" 11 | "path/filepath" 12 | ) 13 | 14 | var pluginJsonFile string 15 | var execUpx bool 16 | 17 | func init() { 18 | flag.StringVar(&pluginJsonFile, "pj", "plugin.json", "插件配置文件") 19 | flag.BoolVar(&execUpx, "upx", false, "是否使用upx") 20 | flag.Parse() 21 | } 22 | 23 | func main() { 24 | 25 | BuildVue() 26 | 27 | err := build.BuildPluginSvr(pluginJsonFile, execUpx) 28 | 29 | if err != nil { 30 | fmt.Println("BuildPluginSvr err", err) 31 | } else { 32 | fmt.Println("BuildPluginSvr success") 33 | } 34 | 35 | } 36 | 37 | func BuildVue() (err error) { 38 | cmd := exec.Command("npm", "run", "build") 39 | 40 | sourceDir, _ := os.Getwd() 41 | 42 | cmd.Dir = filepath.Join(sourceDir, "frontend") 43 | 44 | stdout, err := cmd.StdoutPipe() 45 | if err != nil { 46 | return errors.WithStack(err) 47 | } 48 | if err = cmd.Start(); err != nil { 49 | return errors.WithStack(err) 50 | } 51 | scanner := bufio.NewScanner(stdout) 52 | fmt.Println("=================build vue================") 53 | 54 | for scanner.Scan() { 55 | fmt.Println(scanner.Text()) 56 | } 57 | if err = cmd.Wait(); err != nil { 58 | return errors.WithStack(err) 59 | } 60 | 61 | return 62 | } 63 | -------------------------------------------------------------------------------- /cmd/ev_plugin_zip/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "github.com/1340691923/eve-plugin-sdk-go/build" 7 | "os" 8 | "runtime" 9 | ) 10 | 11 | func main() { 12 | // 解析命令行参数 13 | 14 | destZip := flag.String("o", "dist/source_code.zip", "输出的zip文件路径") 15 | excludeDir := flag.String("e", "node_modules,dist,.idea,.vscode,.git", "要排除的文件夹路径") 16 | flag.Parse() 17 | 18 | sourceDir, _ := os.Getwd() 19 | execFileName := "plugin" 20 | if runtime.GOOS == "windows" { 21 | execFileName = execFileName + ".exe" 22 | } 23 | 24 | os.MkdirAll("dist", os.ModePerm) 25 | 26 | err := build.CompressPathToZip(sourceDir, *excludeDir, execFileName, *destZip) 27 | 28 | if err != nil { 29 | fmt.Println("压缩过程中出错:", err) 30 | os.Exit(1) 31 | } 32 | 33 | fmt.Println("压缩完成,输出文件:", *destZip) 34 | } 35 | -------------------------------------------------------------------------------- /config/config.yml: -------------------------------------------------------------------------------- 1 | ai: 2 | bigmodekey: "" 3 | checkforevupdates: true 4 | checkforpluginupdates: true 5 | dbtype: sqlite3 6 | espwdsecret: concat_mail!!->1340691923@qq.com 7 | log: 8 | logdir: logs 9 | storagedays: 4 10 | mysql: 11 | dbname: test 12 | ip: localhost 13 | port: "3306" 14 | pwd: "" 15 | username: root 16 | oauth: 17 | workwechat: 18 | agentid: "" 19 | corpid: "" 20 | enable: false 21 | secert: "" 22 | dingtalk: 23 | clientid: "" 24 | appsecret: "" 25 | enable: false 26 | feishu: 27 | appid: "" 28 | appsecret: "" 29 | enable: false 30 | plugin: 31 | loadpath: plugins 32 | storepath: plugins_store 33 | pluginrpcport: 8091 34 | port: 8090 35 | rooturl: "" 36 | openSwagger: false 37 | sqlite: 38 | dbname: es_view.db 39 | storefiledir: store_file_dir 40 | translation: 41 | cfgdir: config/i18n 42 | lang: zh-cn 43 | version: 0.0.21 44 | watermarkcontent: ElasticView 45 | -------------------------------------------------------------------------------- /config/config.yml.tpl: -------------------------------------------------------------------------------- 1 | log: 2 | storageDays: 4 # 日志保留天数 3 | logDir: "logs" # 日志保留文件夹 4 | port: 8090 # 启动端口 5 | pluginRpcPort: 8091 #插件内网访问端口 6 | dbType: "sqlite3" # 数据保留类型 分为 sqlite3 和 mysql 7 | enableLogEs: false #是否记录es请求记录 8 | enableLogEsRes: false #是否记录es请求记录中返回的响应体 9 | sqlite: # dbType为sqlite3时填 dbPath为数据保存文件地址 10 | dbName: "es_view.db" 11 | mysql: # dbType为mysql时填 12 | username: "root" 13 | pwd: "" 14 | ip: "localhost" 15 | port: "3306" 16 | dbName: "test" 17 | maxOpenConns: 10 18 | maxIdleConns: 10 19 | appSecret: "1340691923@qq.com" # jwt 加密密钥 20 | esPwdSecret: "concat_mail!!->1340691923@qq.com" # es密码加密密钥 加密方式为 AES 21 | version: "0.0.3" # EV 版本号 22 | deBug: false # 是否为测试模式 如果为 false则打开默认浏览器直接访问地址 23 | checkForevUpdates: true #是否自动检测ev更新 24 | checkForPluginUpdates: true #是否自动检测ev插件更新 25 | evKey: #evKey 需要到插件者后台注册获取 26 | storeFileDir: #临时文件存放目录 例如下载的excel 27 | plugin: 28 | loadPath: plugins #插件存放目录 29 | storePath: plugins_store #插件临时文件存放目录 30 | watermarkContent: ElasticView #水印 31 | translation: 32 | lang: zh-cn # zh-cn or en 33 | cfgDir: config/i18n #i18n文件存放目录 34 | Ai: 35 | bigModeKey: "" #阿里百炼大模型appkey 36 | -------------------------------------------------------------------------------- /config/i18n/zh-cn.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | 5 | -------------------------------------------------------------------------------- /config_dev/config.yml: -------------------------------------------------------------------------------- 1 | ai: 2 | bigmodekey: "" 3 | checkforevupdates: true 4 | checkforpluginupdates: true 5 | dbtype: sqlite3 6 | debug: true 7 | espwdsecret: concat_mail!!->1340691923@qq.com 8 | evkey: admin-xwl 9 | log: 10 | logdir: logs 11 | storagedays: 4 12 | mysql: 13 | dbname: test 14 | ip: 127.0.0.1 15 | port: "3306" 16 | pwd: 123456 17 | username: root 18 | oauth: 19 | dingtalk: 20 | appid: "111" 21 | appsecret: "123" 22 | clientid: dingycls0zzps44fa8yi 23 | enable: false 24 | feishu: 25 | appid: "" 26 | appsecret: "" 27 | enable: true 28 | workwechat: 29 | agentid: "" 30 | corpid: "" 31 | enable: false 32 | secert: "" 33 | plugin: 34 | loadpath: plugins 35 | storepath: plugins_store 36 | pluginrpcport: 8091 37 | port: 8090 38 | rooturl: 39 | sqlite: 40 | dbname: D:\eve\ev2\ev_store\data\es_view.db 41 | storefiledir: store_file_dir 42 | translation: 43 | cfgdir: D:\eve\ev2\config\i18n 44 | lang: zh-cn 45 | version: 0.0.21 46 | watermarkcontent: ElasticView 47 | -------------------------------------------------------------------------------- /debug.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //go:generate go build -o build.exe cmd/build_ev/main.go 4 | //go:generate build.exe 5 | //go:generate swag init -g cmd/ev/main.go -o docs -exclude resources,logs,config 6 | //go:generate gowatch 7 | -------------------------------------------------------------------------------- /generate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //go:generate go install github.com/1340691923/ElasticView/cmd/ev_builder/ 4 | 5 | //go:generate ev_builder.exe 6 | 7 | //go:generate swag init -g cmd/ev/main.go -o resources/docs -exclude resources,logs,config 8 | 9 | //go:generate gowatch 10 | -------------------------------------------------------------------------------- /go.work: -------------------------------------------------------------------------------- 1 | go 1.23.0 2 | 3 | toolchain go1.23.1 4 | 5 | use ( 6 | . 7 | ../eve-plugin-sdk-go 8 | ) 9 | -------------------------------------------------------------------------------- /gowatch.yml: -------------------------------------------------------------------------------- 1 | # gowatch.yml 配置示例 2 | 3 | # 当前目录执行下生成的可执行文件的名字,默认是当前目录名 4 | appname: "ev" 5 | # 是否对当前目录下相关依赖执行 ‘go install’命令,将会执行安装依赖 6 | go_install: true 7 | # 需要监听的文件名后缀,默认只有'.go'文件 8 | watch_exts: 9 | - .go 10 | - .yml 11 | # 在执行命令时,需要增加的其他参数 12 | cmd_args: 13 | - -configFile=config_dev/config.yml 14 | # 需要增加环境变量,默认已加载当前环境变量 15 | #envs: 16 | # - a=b 17 | # 是否监听 ‘vendor’ 文件夹下的文件改变 18 | vendor_watch: false 19 | # 不需要监听的目录名字 20 | excluded_paths: 21 | - resources 22 | - config 23 | - config_dev 24 | # build tags 25 | build_tags: "" 26 | # main 包路径,也可以是单个文件,多个文件使用逗号分隔 27 | build_pkg: "cmd/ev/main.go" 28 | -------------------------------------------------------------------------------- /pkg/api/ai_controller.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/1340691923/ElasticView/pkg/infrastructure/dto" 5 | "github.com/1340691923/ElasticView/pkg/infrastructure/logger" 6 | "github.com/1340691923/ElasticView/pkg/infrastructure/response" 7 | "github.com/1340691923/ElasticView/pkg/services/big_mode_service" 8 | "github.com/gin-gonic/gin" 9 | "github.com/pkg/errors" 10 | ) 11 | 12 | type AiController struct { 13 | *BaseController 14 | log *logger.AppLogger 15 | bigMode *big_mode_service.BigMode 16 | } 17 | 18 | func NewAiController(baseController *BaseController, log *logger.AppLogger, bigMode *big_mode_service.BigMode) *AiController { 19 | return &AiController{BaseController: baseController, log: log, bigMode: bigMode} 20 | } 21 | 22 | func (this *AiController) SearchBigMode(ctx *gin.Context) { 23 | var req dto.SearchBigModeReq 24 | err := ctx.BindJSON(&req) 25 | if err != nil { 26 | this.Error(ctx, errors.WithStack(err)) 27 | return 28 | } 29 | 30 | typ := big_mode_service.CommonSysMd 31 | switch req.SysType { 32 | case 1: 33 | typ = big_mode_service.DefaultSysContent 34 | case 2: 35 | typ = big_mode_service.DefaultSysMd 36 | } 37 | 38 | res, err := this.bigMode.BigModelSearch(typ, req.Content) 39 | if err != nil { 40 | this.Error(ctx, errors.WithStack(err)) 41 | return 42 | } 43 | this.Success(ctx, response.SearchSuccess, res) 44 | } 45 | -------------------------------------------------------------------------------- /pkg/api/base_controller.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "bytes" 5 | "github.com/1340691923/ElasticView/pkg/infrastructure/request" 6 | "github.com/1340691923/ElasticView/pkg/infrastructure/response" 7 | "github.com/gin-gonic/gin" 8 | "io/ioutil" 9 | ) 10 | 11 | // 父控制器结构体 12 | type BaseController struct { 13 | *request.Request 14 | *response.Response 15 | } 16 | 17 | func NewBaseController(request *request.Request, response *response.Response) *BaseController { 18 | return &BaseController{Request: request, Response: response} 19 | } 20 | 21 | func (this *BaseController) getPostBody(ctx *gin.Context) []byte { 22 | body, _ := ctx.GetRawData() 23 | ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body)) 24 | return body 25 | } 26 | 27 | func (this *BaseController) GetRoleCache(ctx *gin.Context) []int { 28 | roles, _ := ctx.Get("ev_roles") 29 | return roles.([]int) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/api/live_controller.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/1340691923/ElasticView/pkg/infrastructure/logger" 5 | "github.com/1340691923/ElasticView/pkg/services/live_svr" 6 | "github.com/1340691923/ElasticView/pkg/util" 7 | "net/http" 8 | ) 9 | 10 | type LiveController struct { 11 | live *live_svr.Live 12 | log *logger.AppLogger 13 | } 14 | 15 | func NewLiveController(live *live_svr.Live, log *logger.AppLogger) *LiveController { 16 | return &LiveController{live: live, log: log} 17 | } 18 | 19 | func (this *LiveController) HttpHandle() http.Handler { 20 | return util.Cors(this.live.Handler) 21 | } 22 | -------------------------------------------------------------------------------- /pkg/consts/notice.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | ChannelSplit = "$v$" 5 | //总频道 6 | EvAllMsgChannel = "EvAllMsgChannel" 7 | //角色频道 8 | EvRoleMsgChannel = "EvRoleMsgChannel" 9 | //用户频道 10 | EvUserMsgChannel = "EvUserMsgChannel" 11 | ) 12 | -------------------------------------------------------------------------------- /pkg/infrastructure/config/save_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "io/ioutil" 5 | 6 | "gopkg.in/yaml.v2" 7 | ) 8 | 9 | func SaveConfig(cfg *Config) error { 10 | cfg.lock.Lock() 11 | defer cfg.lock.Unlock() 12 | 13 | configPath := "config_dev/config.yml" 14 | data, err := yaml.Marshal(cfg) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | return ioutil.WriteFile(configPath, data, 0644) 20 | } 21 | -------------------------------------------------------------------------------- /pkg/infrastructure/config/version.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | const Version = "v0.0.21" 4 | 5 | -------------------------------------------------------------------------------- /pkg/infrastructure/dao/es_connect_dao.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import "github.com/1340691923/ElasticView/pkg/infrastructure/orm" 4 | 5 | type EsConnectDao struct { 6 | orm *orm.Gorm 7 | } 8 | -------------------------------------------------------------------------------- /pkg/infrastructure/dao/gm_operater_log_dao.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "github.com/1340691923/ElasticView/pkg/infrastructure/sqlstore" 5 | ) 6 | 7 | type GmOperaterLogDao struct { 8 | orm *sqlstore.SqlStore 9 | } 10 | 11 | func NewGmOperaterLogDao(orm *sqlstore.SqlStore) *GmOperaterLogDao { 12 | return &GmOperaterLogDao{orm: orm} 13 | } 14 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/ai.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type SearchBigModeReq struct { 4 | SysType int `json:"sys_type"` 5 | Content string `json:"content"` 6 | } 7 | 8 | type AIConfigReq struct { 9 | QwenEnabled bool `json:"qwen_enabled"` 10 | BigModeKey string `json:"big_mode_key"` 11 | OpenAIEnabled bool `json:"openai_enabled"` 12 | OpenAIKey string `json:"open_ai_key"` 13 | DeepSeekEnabled bool `json:"deepseek_enabled"` 14 | DeepSeekKey string `json:"deep_seek_key"` 15 | } 16 | 17 | type AIConfigRes struct { 18 | QwenEnabled bool `json:"qwen_enabled"` 19 | BigModeKey string `json:"big_mode_key"` 20 | OpenAIEnabled bool `json:"openai_enabled"` 21 | OpenAIKey string `json:"open_ai_key"` 22 | DeepSeekEnabled bool `json:"deepseek_enabled"` 23 | DeepSeekKey string `json:"deep_seek_key"` 24 | } 25 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/common/common.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | //一些需要用到的结构 4 | 5 | type Json map[string]interface{} 6 | 7 | type Sort struct { 8 | Field string 9 | Ascending bool 10 | } 11 | 12 | type Page struct { 13 | PageNum int 14 | PageSize int 15 | } 16 | 17 | type EsConnectID struct { 18 | EsConnectID int `json:"es_connect"` 19 | } 20 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_alias.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import "github.com/1340691923/ElasticView/pkg/infrastructure/dto/common" 4 | 5 | type EsAliasInfo struct { 6 | EsConnect int `json:"es_connect"` 7 | Settings common.Json `json:"settings"` 8 | IndexName string `json:"index_name"` 9 | AliasName string `json:"alias_name"` 10 | NewAliasNameList []string `json:"new_alias_name_list"` 11 | NewIndexList []string `json:"new_index_list"` 12 | Types int `json:"types"` 13 | } 14 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_cat.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type EsCat struct { 4 | EsConnect int `json:"es_connect"` 5 | Cat string `json:"cat"` 6 | IndexBytesFormat string `json:"index_bytes_format"` 7 | } 8 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_crud.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type CrudFilter struct { 4 | Relation AnalysisFilter `json:"relation"` 5 | SortList []SortStruct `json:"sort_list"` 6 | EsConnect int `json:"es_connect"` 7 | IndexName string `json:"index_name"` 8 | Page int `json:"page"` 9 | Limit int `json:"limit"` 10 | } 11 | 12 | type AnalysisFilter struct { 13 | FilterType string `json:"filterType"` 14 | Filts []struct { 15 | FilterType string `json:"filterType"` 16 | Filts []struct { 17 | ColumnName string `json:"columnName"` 18 | Comparator string `json:"comparator"` 19 | FilterType string `json:"filterType"` 20 | Ftv interface{} `json:"ftv"` 21 | } `json:"filts,omitempty"` 22 | Relation string `json:"relation,omitempty"` 23 | ColumnName string `json:"columnName,omitempty"` 24 | Comparator string `json:"comparator,omitempty"` 25 | Ftv interface{} `json:"ftv,omitempty"` 26 | } `json:"filts"` 27 | Relation string `json:"relation"` 28 | } 29 | 30 | type SortStruct struct { 31 | Col string `json:"col"` 32 | SortRule string `json:"sortRule"` 33 | } 34 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_doc.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import "github.com/1340691923/ElasticView/pkg/infrastructure/dto/common" 4 | 5 | type EsDocUpdateByID struct { 6 | EsConnect int `json:"es_connect"` 7 | ID string `json:"id"` 8 | JSON common.Json `json:"json"` 9 | Type string `json:"type_name"` 10 | Index string `json:"index"` 11 | } 12 | 13 | type EsDocDeleteRowByID struct { 14 | EsConnect int `json:"es_connect"` 15 | ID string `json:"id"` 16 | IndexName string `json:"index_name"` 17 | Type string `json:"type"` 18 | } 19 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_index.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import "github.com/1340691923/ElasticView/pkg/infrastructure/dto/common" 4 | 5 | type EsIndexInfo struct { 6 | EsConnect int `json:"es_connect"` 7 | Settings common.Json `json:"settings"` 8 | IndexName string `json:"index_name"` 9 | Types string `json:"types"` 10 | } 11 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_map.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import "github.com/1340691923/ElasticView/pkg/infrastructure/dto/common" 4 | 5 | type EsMapGetProperties struct { 6 | EsConnectID int `json:"es_connect"` 7 | IndexName string `json:"index_name"` 8 | } 9 | 10 | type UpdateMapping struct { 11 | EsConnect int `json:"es_connect"` 12 | IndexName string `json:"index_name"` 13 | TypeName string `json:"type_name"` 14 | Properties common.Json `json:"properties"` 15 | } 16 | 17 | type EsMappingInfo struct { 18 | IndexNameList []string `json:"index_name_list"` 19 | EsConnect int `json:"es_connect"` 20 | Mappings common.Json `json:"mappings"` 21 | IndexName string `json:"index_name"` 22 | } 23 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_optimize.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type EsOptimize struct { 4 | EsConnect int `json:"es_connect"` 5 | IndexName string `json:"index_name"` 6 | } 7 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_reindex.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import "github.com/1340691923/ElasticView/pkg/util" 4 | 5 | type EsReIndexInfo struct { 6 | EsConnect int `json:"es_connect"` 7 | UrlValues struct { 8 | Timeout int `json:"timeout"` 9 | RequestsPerSecond int `json:"requests_per_second"` 10 | Slices int `json:"slices"` 11 | Scroll string `json:"scroll"` 12 | WaitForActiveShards string `json:"wait_for_active_shards"` 13 | Refresh *bool `json:"refresh"` 14 | WaitForCompletion *bool `json:"wait_for_completion"` 15 | } `json:"url_values"` 16 | Body util.Map `json:"body"` 17 | } 18 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_rest.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type EsRest struct { 4 | EsConnect int `json:"es_connect"` 5 | Body string `json:"body"` 6 | Path string `json:"path"` 7 | } 8 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/es_task.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type TaskList struct { 4 | EsConnect int `json:"es_connect"` 5 | } 6 | 7 | type CancelTask struct { 8 | EsConnect int `json:"es_connect"` 9 | TaskID string `json:"task_id"` 10 | } 11 | 12 | type EsTaskInfo struct { 13 | EsConnect int `json:"es_connect"` 14 | TaskId []string `json:"task_id"` 15 | Actions []string `json:"actions"` 16 | NodeId []string `json:"node_id"` 17 | ParentTaskId string `json:"parent_task_id"` 18 | } 19 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/guid.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type GuidFinish struct { 4 | GuidName string `json:"guid_name"` 5 | } 6 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/live.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type LiveBroadcast struct { 4 | Channel string `json:"channel"` 5 | Data interface{} `json:"data"` 6 | } 7 | 8 | type BatchLiveBroadcast struct { 9 | Channel string `json:"channel"` 10 | List []interface{} `json:"list"` 11 | } 12 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/notice.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type NoticeReq struct { 4 | ReadType int `json:"read_type"` 5 | Title string `json:"title"` 6 | Page int `json:"page"` 7 | PageSize int `json:"page_size"` 8 | } 9 | 10 | type MarkReadNoticeReq struct { 11 | Ids []int `json:"ids"` 12 | } 13 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/oauth.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type GetOAuthConfigReq struct { 4 | CallBack string `json:"call_back"` 5 | } 6 | 7 | type SaveOAuthConfigReq struct { 8 | ApplicationName string `json:"application_name"` 9 | Config map[string]interface{} `json:"config"` 10 | } 11 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/operater_log_list.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type GmOperaterLogList struct { 4 | Page int `json:"page"` 5 | Limit int `json:"limit"` 6 | UserId int `json:"operater_id"` 7 | OperaterAction string `json:"operater_action"` 8 | Date []string `json:"date"` 9 | } 10 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/plugin.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type PluginMarketReq struct { 4 | SearchTxt string `json:"search_txt"` 5 | OrderCol string `json:"order_col"` 6 | OrderByDesc bool `json:"order_by_desc"` 7 | IsInstall *bool `json:"is_install"` 8 | Page int `json:"page"` 9 | Limit int `json:"limit"` 10 | } 11 | 12 | type InstallPlugin struct { 13 | PluginID string `json:"plugin_id"` 14 | Version string `json:"version"` 15 | } 16 | 17 | type ImportEvKey struct { 18 | EvKey string `json:"ev_key"` 19 | } 20 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/plugin_config.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type UpdatePluginConfigReq struct { 4 | PluginID string `json:"plugin_id" binding:"required"` 5 | AutoUpdate bool `json:"auto_update"` 6 | } 7 | 8 | type GetPluginConfigReq struct { 9 | PluginID string `json:"plugin_id" binding:"required"` 10 | } 11 | 12 | type PluginConfigRes struct { 13 | PluginID string `json:"plugin_id"` 14 | AutoUpdate bool `json:"auto_update"` 15 | } 16 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/route.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import "github.com/1340691923/ElasticView/pkg/services/gm_user" 4 | 5 | type GetMetaByPathReq struct { 6 | FullPath string `json:"full_path"` 7 | Routers []*gm_user.Route `json:"routers"` 8 | } 9 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/sql2dsl.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type SqlToDsl struct { 4 | Sql string `json:"sql"` 5 | } 6 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/url_config.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type UrlConfigReq struct { 4 | NeedAuth bool `json:"need_auth"` 5 | } 6 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/user.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type User struct { 4 | OAuthCode string `json:"oauth_code"` 5 | State string `json:"state"` 6 | 7 | Username string `json:"username"` 8 | Password string `json:"password"` 9 | } 10 | 11 | -------------------------------------------------------------------------------- /pkg/infrastructure/dto/ws.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type C2S_PING struct{} 4 | -------------------------------------------------------------------------------- /pkg/infrastructure/es_sdk/pkg/hive/hive_dirver/dsn.go: -------------------------------------------------------------------------------- 1 | package hive_dirver 2 | 3 | import ( 4 | gohive "github.com/philhuan/gohive-driver" 5 | "os/user" 6 | "strings" 7 | ) 8 | 9 | type DSNConfig gohive.Config 10 | 11 | func (c *DSNConfig) Complete() *DSNConfig { 12 | c.ColumnsWithoutTableName = true 13 | if c.User == "" { 14 | _user, _ := user.Current() 15 | if _user != nil { 16 | c.User = strings.Replace(_user.Name, " ", "", -1) 17 | } 18 | if c.User == "" { 19 | c.User = "default_user" 20 | } 21 | } 22 | // password may not matter but can't be empty 23 | if c.Passwd == "" { 24 | c.Passwd = "x" 25 | } 26 | if c.Auth == "" { 27 | c.Auth = "PLAIN" 28 | } 29 | return c 30 | } 31 | 32 | func ParseDSN(dsn string) (*DSNConfig, error) { 33 | config, err := gohive.ParseDSN(dsn) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return (*DSNConfig)(config), nil 38 | } 39 | 40 | func (c *DSNConfig) FormatDSN() string { 41 | return (*gohive.Config)(c).FormatDSN() 42 | } 43 | -------------------------------------------------------------------------------- /pkg/infrastructure/es_sdk/pkg/hive/hive_dirver/migrator.go: -------------------------------------------------------------------------------- 1 | package hive_dirver 2 | 3 | import ( 4 | "database/sql" 5 | "gorm.io/gorm" 6 | "gorm.io/gorm/migrator" 7 | ) 8 | 9 | type Migrator struct { 10 | migrator.Migrator 11 | *Dialector 12 | } 13 | 14 | func (m Migrator) CurrentDatabase() (name string) { 15 | m.handleError(m.DB.Raw("SELECT current_database()").Row().Scan(&name)) 16 | return 17 | } 18 | 19 | func (m Migrator) HasTable(value interface{}) bool { 20 | var name string 21 | m.handleError(m.RunWithValue(value, func(stmt *gorm.Statement) error { 22 | //currentDatabase := m.DB.Migrator().CurrentDatabase() 23 | return m.DB.Raw( 24 | "SHOW TABLES LIKE ?", stmt.Table, 25 | ).Row().Scan(&name) 26 | }), sql.ErrNoRows) 27 | return name != "" 28 | } 29 | -------------------------------------------------------------------------------- /pkg/infrastructure/es_sdk/pkg/hive/hive_dirver/serializer.go: -------------------------------------------------------------------------------- 1 | package hive_dirver 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "reflect" 8 | 9 | "gorm.io/gorm/schema" 10 | ) 11 | 12 | func init() { 13 | schema.RegisterSerializer("map", MapSerializer{}) 14 | } 15 | 16 | // MapSerializer map serializer 17 | type MapSerializer struct{} 18 | 19 | // Scan implements serializer interface 20 | func (MapSerializer) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error) { 21 | fieldValue := reflect.New(field.FieldType) 22 | 23 | if dbValue != nil { 24 | var bytes []byte 25 | switch v := dbValue.(type) { 26 | case []byte: 27 | bytes = v 28 | case string: 29 | bytes = []byte(v) 30 | default: 31 | return fmt.Errorf("failed to unmarshal JSONB value: %#v", dbValue) 32 | } 33 | 34 | if len(bytes) > 0 { 35 | err = json.Unmarshal(bytes, fieldValue.Interface()) 36 | } 37 | } 38 | 39 | field.ReflectValueOf(ctx, dst).Set(fieldValue.Elem()) 40 | return 41 | } 42 | 43 | // Value implements serializer interface 44 | func (MapSerializer) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) { 45 | // TODO: not implemented 46 | // MAP('math',120,'english', 123) 47 | 48 | result, err := json.Marshal(fieldValue) 49 | if string(result) == "null" { 50 | if field.TagSettings["NOT NULL"] != "" { 51 | return "", nil 52 | } 53 | return nil, err 54 | } 55 | return string(result), err 56 | } 57 | -------------------------------------------------------------------------------- /pkg/infrastructure/es_sdk/pkg/utils/sql.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "gorm.io/gorm" 6 | ) 7 | 8 | // QuerySQL 通用的 SQL 查询函数 9 | func QuerySQL(db *gorm.DB, sql string, args ...interface{}) (columns []string, results []map[string]interface{}, err error) { 10 | // 执行 SQL 查询 11 | rows, err := db.Raw(sql, args...).Rows() 12 | if err != nil { 13 | err = fmt.Errorf("failed to execute SQL: %v", err) 14 | return 15 | } 16 | defer rows.Close() 17 | 18 | // 获取字段名 19 | columns, err = rows.Columns() 20 | if err != nil { 21 | err = fmt.Errorf("failed to get columns: %v", err) 22 | return 23 | } 24 | 25 | // 准备结果容器 26 | results = []map[string]interface{}{} 27 | 28 | // 遍历每一行数据 29 | for rows.Next() { 30 | // 创建值的容器 31 | values := make([]interface{}, len(columns)) 32 | valuePtrs := make([]interface{}, len(columns)) 33 | for i := range values { 34 | valuePtrs[i] = &values[i] 35 | } 36 | 37 | // 扫描数据到容器 38 | if err = rows.Scan(valuePtrs...); err != nil { 39 | err = fmt.Errorf("failed to scan row: %v", err) 40 | return 41 | } 42 | 43 | // 将每一行数据转换为 map 44 | rowData := make(map[string]interface{}) 45 | for i, col := range columns { 46 | rowData[col] = values[i] 47 | } 48 | 49 | // 添加到结果集 50 | results = append(results, rowData) 51 | } 52 | 53 | // 检查遍历过程中是否有错误 54 | if err = rows.Err(); err != nil { 55 | err = fmt.Errorf("row iteration error: %v", err) 56 | return 57 | } 58 | 59 | // 返回结果 60 | return 61 | } 62 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/api/api.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | type API = string 4 | 5 | const ( 6 | GetEvAccessToken API = "GetEvAccessToken" 7 | GetPluginList API = "GetPluginList" 8 | GetPluginInfo API = "GetPluginInfo" 9 | GetPluginDownloadUrl API = "GetPluginDownloadUrl" 10 | GetEvPluginMaxVersion API = "GetEvPluginMaxVersion" 11 | GetEvMaxVersion API = "GetEvMaxVersion" 12 | GetEvPluginsMaxVersion API = "GetEvPluginsMaxVersion" 13 | StarPlugin API = "StarPlugin" 14 | GetWxArticleList API = "GetWxArticleList" 15 | // 16 | AddComment API = "AddComment" 17 | LikeComment API = "LikeComment" 18 | ListComments API = "ListComments" 19 | ) 20 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/doc.go: -------------------------------------------------------------------------------- 1 | package eve_api 2 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/dto/comment.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type AddCommentRequest struct { 4 | PluginID int `json:"plugin_id"` 5 | Content string `json:"content"` 6 | ParentID int `json:"parent_id"` 7 | } 8 | 9 | type DeleteCommentRequest struct { 10 | CommentID int `json:"comment_id"` 11 | } 12 | 13 | type BlockUserRequest struct { 14 | UserID int `json:"user_id"` 15 | Reason string `json:"reason"` 16 | } 17 | 18 | type UnblockUserRequest struct { 19 | UserID int `json:"user_id"` 20 | } 21 | 22 | type ListCommentsRequest struct { 23 | PluginID int `json:"plugin_id"` 24 | } 25 | 26 | type LikeCommentRequest struct { 27 | CommentID int `json:"comment_id"` 28 | State int `json:"state"` 29 | } 30 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/dto/ev_key.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type EvKeyReq struct { 4 | EvKey string `json:"ev_key"` 5 | } 6 | 7 | type Empty struct { 8 | } 9 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/dto/plugin.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type FromEvPluginReq struct { 4 | SearchTxt string `json:"search_txt"` 5 | OrderByCol string `json:"order_by_col"` 6 | OrderByDesc bool `json:"order_by_desc"` 7 | Page int `json:"page"` 8 | Limit int `json:"limit"` 9 | HasDownloadPlugins []string `json:"has_download_plugins"` 10 | HasDownloadType *bool `json:"has_download_type"` 11 | } 12 | 13 | type StarPlugin struct { 14 | PluginId int64 `json:"plugin_id"` 15 | } 16 | 17 | type FormEvPluginInfoReq struct { 18 | PluginId int64 `json:"plugin_id"` 19 | Page int `json:"page"` 20 | Limit int `json:"limit"` 21 | } 22 | 23 | type GetPluginDownloadUrlReq struct { 24 | PluginAlias string `json:"plugin_alias"` 25 | Version string `json:"version"` 26 | Os string `json:"os"` 27 | Arch string `json:"arch"` 28 | } 29 | 30 | type GetEvPluginMaxVersion struct { 31 | PluginAlias string `json:"plugin_alias"` 32 | } 33 | 34 | type GetEvPluginsMaxVersion struct { 35 | PluginIds []string `json:"plugin_ids"` 36 | } 37 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/vo/comment.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type Comment struct { 4 | ID int64 `db:"id" json:"id"` 5 | PluginID int64 `db:"plugin_id" json:"plugin_id"` 6 | UserID int64 `db:"user_id" json:"user_id"` 7 | Content string `db:"content" json:"content"` 8 | ParentID int64 `db:"parent_id" json:"parent_id"` 9 | LikeCount int `db:"like_count" json:"like_count"` 10 | CreatedAt string `db:"created_at" json:"created_at"` 11 | Nickname string `db:"realname" json:"realname"` 12 | HasLike bool `json:"has_like" db:"-"` 13 | Children []*Comment `json:"children,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/vo/common.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | type ApiCommonRes struct { 8 | Code int `json:"code"` 9 | Msg string `json:"msg"` 10 | Data interface{} `json:"data"` 11 | } 12 | 13 | func (this *ApiCommonRes) Error() error { 14 | if this.Code != 0 { 15 | return errors.New(this.Msg) 16 | } 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /pkg/infrastructure/eve_api/vo/wx_article.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type WxArticleModel struct { 4 | ID int `json:"id" db:"id"` 5 | Title string `json:"title" db:"title"` 6 | Link string `json:"link" db:"link"` 7 | CreateTime string `json:"create_time" db:"create_time"` 8 | Typ string `json:"typ" db:"typ"` // info/warning/success/danger/primary 9 | TagName string `json:"tag_name" db:"tag_name"` 10 | } 11 | 12 | type WxArticleList struct { 13 | Data []WxArticleModel 14 | } 15 | -------------------------------------------------------------------------------- /pkg/infrastructure/jwt_svr/errors.go: -------------------------------------------------------------------------------- 1 | package jwt_svr 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | var TokenExpiredErr = errors.New("token has invalid claims: token is expired") 8 | -------------------------------------------------------------------------------- /pkg/infrastructure/jwt_svr/exception_msg.go: -------------------------------------------------------------------------------- 1 | package jwt_svr 2 | 3 | // 内置异常 4 | const ( 5 | ERROR_AUTH_TOKEN = 40006 6 | ) 7 | 8 | var TOKEN_ERROR = map[int]string{ 9 | ERROR_AUTH_TOKEN: "Token生成失败", 10 | } 11 | -------------------------------------------------------------------------------- /pkg/infrastructure/localcache/cache.go: -------------------------------------------------------------------------------- 1 | package localcache 2 | 3 | import ( 4 | "time" 5 | 6 | gocache "github.com/patrickmn/go-cache" 7 | ) 8 | 9 | // CacheService cache any object in memory on the local instance. 10 | type CacheService struct { 11 | *gocache.Cache 12 | } 13 | 14 | func ProvideService() *CacheService { 15 | return New(5*time.Minute, 10*time.Minute) 16 | } 17 | 18 | // New returns a new CacheService 19 | func New(defaultExpiration, cleanupInterval time.Duration) *CacheService { 20 | return &CacheService{ 21 | Cache: gocache.New(defaultExpiration, cleanupInterval), 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pkg/infrastructure/middleware/Exception.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | // 内置异常 4 | const ( 5 | INVALID_PARAMS int = 40001 6 | ERROR_AUTH_CHECK_TOKEN_FAIL int = 40002 7 | ERROR_AUTH_CHECK_TOKEN_TIMEOUT int = 40003 8 | ERROR_RBAC_LOAD int = 40004 9 | ERROR_RBAC_AUTH int = 40005 10 | ERROR_Will_TIMEOUT int = 40006 11 | ERROR_CEHCK_VERSION_FAIL int = 40007 12 | ERROR_CEHCK_USER_EXITS int = 40008 13 | ) 14 | 15 | // 内置异常表 TOKEN_ERROR 16 | var TOKEN_ERROR = map[int]string{ 17 | INVALID_PARAMS: "Token不能为空", 18 | ERROR_AUTH_CHECK_TOKEN_FAIL: "Token鉴权失败", 19 | ERROR_AUTH_CHECK_TOKEN_TIMEOUT: "Token已超时", 20 | ERROR_RBAC_LOAD: "读取rdbc权限列表失败", 21 | ERROR_RBAC_AUTH: "您没有该资源的访问权限", 22 | ERROR_Will_TIMEOUT: "Token即将超时,已续约", 23 | ERROR_CEHCK_VERSION_FAIL: "客户端版本落后服务器版本", 24 | ERROR_CEHCK_USER_EXITS: "该用户已被删除或封禁", 25 | } 26 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/datax_link_info_model.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type DataxLinkInfo struct { 6 | Id int `gorm:"column:id;primaryKey;autoIncrement;NOT NULL" json:"id"` 7 | Ip string `gorm:"column:ip;default:'';NOT NULL" json:"ip"` 8 | Port int `gorm:"column:port;default:0;NOT NULL" json:"port"` 9 | DbName string `gorm:"column:db_name;default:'';NOT NULL" json:"db_name"` 10 | Username string `gorm:"column:username;default:'';NOT NULL" json:"username"` 11 | Pwd string `gorm:"column:pwd;default:'';NOT NULL" json:"pwd"` 12 | Remark string `gorm:"column:remark;default:;NOT NULL;index:link_remark_uniq,unique" json:"remark"` 13 | Typ string `gorm:"column:typ;default:;NOT NULL;index:link_remark_uniq,unique" json:"typ"` 14 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 15 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 16 | } 17 | 18 | func (d *DataxLinkInfo) TableName() string { 19 | return "datax_link_info" 20 | } 21 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/datax_list_model.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type DataxTransferList struct { 6 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 7 | FormData string `gorm:"column:form_data;default:NULL" json:"form_data"` 8 | Remark string `gorm:"column:remark;default:;NOT NULL;index:datax_transfer_list_remark,unique" json:"remark"` 9 | TableName2 string `gorm:"column:table_name;default:'';NOT NULL" json:"table_name"` 10 | IndexName string `gorm:"column:index_name;default:'';NOT NULL" json:"index_name"` 11 | ErrorMsg string `gorm:"column:error_msg;default:'';NOT NULL" json:"error_msg"` 12 | CrontabSpec string `gorm:"column:crontab_spec;default:'';NOT NULL" json:"crontab_spec"` 13 | Dbcount int `gorm:"column:dbcount;default:0;NOT NULL" json:"dbcount"` 14 | Escount int `gorm:"column:escount;default:0;NOT NULL" json:"escount"` 15 | EsConnect int `gorm:"column:es_connect;default:0;NOT NULL;index:datax_transfer_list_remark,unique" json:"es_connect"` 16 | Status string `gorm:"column:status;default:'任务运行中...';NOT NULL" json:"status"` 17 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 18 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 19 | } 20 | 21 | func (d *DataxTransferList) TableName() string { 22 | return "datax_transfer_list" 23 | } 24 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/es_link_role_v3.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | // EsLinkRoleV3 es连接与角色的关联表 (v3版本) 6 | type EsLinkRoleV3 struct { 7 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 8 | EsLinkId int `gorm:"column:es_link_id;default:0;NOT NULL" json:"es_link_id"` 9 | RoleId int `gorm:"column:role_id;default:0;NOT NULL" json:"role_id"` 10 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 11 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 12 | } 13 | 14 | func (e *EsLinkRoleV3) TableName() string { 15 | return "es_link_role_v3" 16 | } 17 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/es_link_v3.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | // EsLinkV3 es连接信息表 (v3版本) 6 | type EsLinkV3 struct { 7 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 8 | Ip string `gorm:"column:ip;default:'';NOT NULL" json:"ip"` 9 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 10 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 11 | Remark string `gorm:"column:remark;default:默认连接;index:es_link_v3_remark,unique" json:"remark"` 12 | Version string `gorm:"column:version;default:'elasticsearch6.x';NOT NULL" json:"version"` 13 | CreateBy int `gorm:"column:create_by;default:0;NOT NULL;index:es_link_v3_remark,unique" json:"create_by"` 14 | } 15 | 16 | func (e *EsLinkV3) TableName() string { 17 | return "es_link_v3" 18 | } 19 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/eslink_role_cfg_reletion.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type EslinkRoleCfgReletion struct { 6 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 7 | EsLinkId int `gorm:"column:es_link_id;default:0;NOT NULL" json:"es_link_id"` 8 | RoleCfgId int `gorm:"column:role_cfg_id;default:0;NOT NULL" json:"role_cfg_id"` 9 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 10 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 11 | } 12 | 13 | func (e *EslinkRoleCfgReletion) TableName() string { 14 | return "eslink_role_cfg_reletion" 15 | } 16 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/gm_operater_log.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type GmOperaterLog struct { 6 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 7 | OperaterId int `gorm:"column:operater_id;default:0;NOT NULL" json:"operater_id"` 8 | OperaterName string `gorm:"column:operater_name;default:'';NOT NULL" json:"operater_name"` 9 | OperaterAction string `gorm:"column:operater_action;default:'';NOT NULL" json:"operater_action"` 10 | Method string `gorm:"column:method;default:'';NOT NULL" json:"method"` 11 | Body []byte `gorm:"column:body;NOT NULL" json:"body"` 12 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 13 | CostTime string `gorm:"column:cost_time;default:'';NOT NULL" json:"cost_time"` 14 | Status string `gorm:"column:status;default:'';NOT NULL" json:"status"` 15 | } 16 | 17 | func (g *GmOperaterLog) TableName() string { 18 | return "gm_operater_log" 19 | } 20 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/gm_role.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type GmRole struct { 4 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 5 | RoleName string `gorm:"column:role_name;default:NULL" json:"name"` 6 | Description string `gorm:"column:description;default:NULL" json:"description"` 7 | RoleList *string `gorm:"column:role_list" json:"role_list"` 8 | } 9 | 10 | func (g *GmRole) TableName() string { 11 | return "gm_role" 12 | } 13 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/gm_role_eslink_cfg.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type GmRoleEslinkCfgV2 struct { 6 | Id int32 `gorm:"column:id;primary_key;NOT NULL" json:"id"` 7 | RoleId int32 `gorm:"column:role_id;default:0;NOT NULL" json:"role_id"` 8 | EsLinkCfgId int32 `gorm:"column:es_link_cfg_id;default:0;NOT NULL" json:"es_link_cfg_id"` 9 | EsLinkId int32 `gorm:"column:es_link_id;default:0;NOT NULL" json:"es_link_id"` 10 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 11 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 12 | } 13 | 14 | func (g *GmRoleEslinkCfgV2) TableName() string { 15 | return "gm_role_eslink_cfg_v2" 16 | } 17 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/gm_user.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/1340691923/ElasticView/pkg/util" 5 | "time" 6 | ) 7 | 8 | // GmUserModel BI用户 9 | type GmUserModel struct { 10 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 11 | Username string `gorm:"column:username;default:NULL;index:gm_user_username,unique" json:"username"` 12 | Password string `gorm:"column:password;default:NULL" json:"password"` 13 | 14 | Avatar string `gorm:"column:avatar;default:NULL" json:"avatar"` 15 | 16 | Realname string `gorm:"column:realname;default:" json:"realname"` 17 | Email string `gorm:"column:email;default:" json:"email"` 18 | WorkWechatUid string `gorm:"column:work_wechat_uid;default:" json:"work_wechat_uid"` 19 | DingtalkId string `gorm:"column:dingtalk_id;default:" json:"dingtalk_id"` 20 | FeishuOpenId string `gorm:"column:feishu_open_id;default:" json:"feishu_open_id"` 21 | 22 | UpdateTime time.Time `gorm:"column:update_time;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"update_time"` 23 | CreateTime time.Time `gorm:"column:create_time;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"create_time"` 24 | LastLoginTime time.Time `gorm:"column:last_login_time;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"last_login_time"` 25 | 26 | IsBan int32 `gorm:"column:is_ban;default:0;NOT NULL" json:"is_ban"` 27 | } 28 | 29 | func (g *GmUserModel) TableName() string { 30 | return "gm_user" 31 | } 32 | 33 | // 密码进行md5混淆 34 | func (this *GmUserModel) GetPassword() string { 35 | return util.MD5HexHash(util.Str2bytes(this.Password)) 36 | } 37 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/guid_model.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type GmGuid struct { 6 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 7 | Uid int `gorm:"column:uid;NOT NULL;index:guid_name,unique" json:"uid"` 8 | GuidName string `gorm:"column:guid_name;NOT NULL;index:guid_name,unique" json:"guid_name"` 9 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 10 | } 11 | 12 | func (g *GmGuid) TableName() string { 13 | return "gm_guid" 14 | } 15 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/jwt_key.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type JwtKeyModel struct { 4 | JwtKey string 5 | } 6 | 7 | func (g *JwtKeyModel) TableName() string { 8 | return "jwt_key" 9 | } 10 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/notice_read_log.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type NoticeReadLog struct { 6 | ID int `gorm:"column:id;primaryKey;autoIncrement" json:"id"` 7 | UserID int `gorm:"column:user_id;not null;uniqueIndex:uniq_user_notice" json:"user_id"` 8 | NoticeID int `gorm:"column:notice_id;not null;uniqueIndex:uniq_user_notice" json:"notice_id"` 9 | ReadAt time.Time `gorm:"column:read_at;autoCreateTime" json:"read_at"` 10 | } 11 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/notice_target.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type NoticeTarget struct { 6 | ID int `gorm:"column:id;primaryKey;autoIncrement" json:"id"` 7 | NoticeID int `gorm:"column:notice_id;not null;uniqueIndex:idx_noticeid_target" json:"notice_id"` // 通知 ID 8 | TargetID int `gorm:"column:target_id;uniqueIndex:idx_noticeid_target" json:"target_id"` // 目标 ID,可为空 9 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 10 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 11 | } 12 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/plugin_config.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type PluginConfig struct { 6 | ID int `gorm:"column:id;primaryKey;autoIncrement" json:"id"` 7 | PluginID string `gorm:"column:plugin_id;uniqueIndex;not null" json:"plugin_id"` // 插件ID 8 | AutoUpdate bool `gorm:"column:auto_update;default:false" json:"auto_update"` // 自动更新开关,默认关闭 9 | Created time.Time `gorm:"column:created;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"created"` 10 | Updated time.Time `gorm:"column:updated;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"updated"` 11 | } 12 | 13 | func (PluginConfig) TableName() string { 14 | return "plugin_config" 15 | } 16 | -------------------------------------------------------------------------------- /pkg/infrastructure/model/user_role_relation.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type UserRoleRelationModel struct { 6 | Id int `gorm:"column:id;primary_key;NOT NULL" json:"id"` 7 | UserId int `gorm:"column:user_id;default:0;index:user_role_id,unique" json:"user_id"` 8 | RoleId int `gorm:"column:role_id;default:0;index:user_role_id,unique" json:"role_id"` 9 | 10 | UpdateTime time.Time `gorm:"column:update_time;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"update_time"` 11 | CreateTime time.Time `gorm:"column:create_time;type:timestamp;default:CURRENT_TIMESTAMP;NOT NULL" json:"create_time"` 12 | } 13 | 14 | func (g *UserRoleRelationModel) TableName() string { 15 | return "user_role_relation" 16 | } 17 | -------------------------------------------------------------------------------- /pkg/infrastructure/my_error/es_index.go: -------------------------------------------------------------------------------- 1 | package my_error 2 | 3 | const ( 4 | IndexNameNullError = 200001 5 | AliasNameNullError = 200002 6 | ) 7 | 8 | var ParmasNullError = map[int]string{ 9 | IndexNameNullError: "索引名不能为空", 10 | AliasNameNullError: "别名不能为空", 11 | } 12 | -------------------------------------------------------------------------------- /pkg/infrastructure/my_error/my_error.go: -------------------------------------------------------------------------------- 1 | //自定义异常层 2 | package my_error 3 | 4 | //自定义异常结构体 实现Error方法 5 | type MyError struct { 6 | code int 7 | msg string 8 | } 9 | 10 | // 自定义业务异常 11 | func NewBusiness(ErrEnum map[int]string, code int) error { 12 | text := ErrEnum[code] 13 | return &MyError{code, text} 14 | } 15 | 16 | func NewError(text string, code int) error { 17 | return &MyError{code, text} 18 | } 19 | 20 | func (this *MyError) Error() string { 21 | return this.msg 22 | } 23 | 24 | func (this *MyError) Code() int { 25 | return this.code 26 | } 27 | -------------------------------------------------------------------------------- /pkg/infrastructure/orm/sqlite/errors.go: -------------------------------------------------------------------------------- 1 | package sqlite 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrConstraintsNotImplemented = errors.New("constraints not implemented on sqlite, consider using DisableForeignKeyConstraintWhenMigrating, more details https://github.com/go-gorm/gorm/wiki/GORM-V2-Release-Note-Draft#all-new-migrator") 7 | ) 8 | -------------------------------------------------------------------------------- /pkg/infrastructure/orm/squirrel.go: -------------------------------------------------------------------------------- 1 | package orm 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // 创建分页查询 8 | func CreatePage(page, limit int) int { 9 | tmp := (page - 1) * limit 10 | return int(tmp) 11 | } 12 | 13 | // 创建模糊查询 14 | func CreateLike(column string) string { 15 | return fmt.Sprint("%", column, "%") 16 | } 17 | -------------------------------------------------------------------------------- /pkg/infrastructure/plugins/backendplugin/plugin.go: -------------------------------------------------------------------------------- 1 | package backendplugin 2 | 3 | import ( 4 | "context" 5 | "github.com/1340691923/eve-plugin-sdk-go/backend" 6 | "github.com/hashicorp/go-hclog" 7 | process2 "github.com/shirou/gopsutil/v3/process" 8 | ) 9 | 10 | type Plugin interface { 11 | PluginID() string 12 | Logger() hclog.Logger 13 | Start(ctx context.Context) error 14 | Stop(ctx context.Context) error 15 | Exited() bool 16 | Decommission() error 17 | DisDecommission() error 18 | IsDecommissioned() bool 19 | backend.CheckHealthHandler 20 | backend.CallResourceHandler 21 | backend.LiveHandler 22 | GetPid() int 23 | GetProcessUtil() (*process2.Process, error) 24 | } 25 | -------------------------------------------------------------------------------- /pkg/infrastructure/plugins/backendplugin/provider/provider.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "context" 5 | "github.com/1340691923/ElasticView/pkg/infrastructure/config" 6 | "github.com/1340691923/ElasticView/pkg/infrastructure/orm" 7 | grpcplugin "github.com/1340691923/ElasticView/pkg/infrastructure/plugins/backendplugin/grpc_plugin" 8 | "github.com/1340691923/ElasticView/pkg/infrastructure/plugins/plugin" 9 | "github.com/hashicorp/go-hclog" 10 | "path" 11 | ) 12 | 13 | type Config struct { 14 | ID string 15 | PluginDir string 16 | PluginFileName string 17 | ExecArgs []string 18 | IsDebug bool 19 | TestAddr string 20 | TestPid int 21 | } 22 | 23 | func (p *Config) ExecutablePath() string { 24 | return path.Join(p.PluginDir, p.PluginFileName) 25 | } 26 | 27 | func DefaultProvider(_ context.Context, log hclog.Logger, 28 | logPath string, closeLogWriteCallback func() error, 29 | provideCfg *Config, cfg *config.Config, evOrm *orm.Gorm) *plugin.Plugin { 30 | p := new(plugin.Plugin) 31 | p.PluginDir = provideCfg.PluginDir 32 | p.PluginFileName = provideCfg.PluginFileName 33 | p.ID = provideCfg.ID 34 | p.Cfg = cfg 35 | p.EvOrm = evOrm 36 | p.LogFilePath = logPath 37 | p.RegisterClient(grpcplugin.NewBackendPlugin( 38 | log, closeLogWriteCallback, provideCfg.ID, provideCfg.ExecutablePath(), provideCfg.IsDebug, 39 | provideCfg.TestAddr, provideCfg.TestPid, provideCfg.ExecArgs)) 40 | 41 | p.SetLogger(log) 42 | return p 43 | } 44 | -------------------------------------------------------------------------------- /pkg/infrastructure/plugins/manager/interfaces.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import ( 4 | "context" 5 | "github.com/1340691923/ElasticView/pkg/infrastructure/plugins/plugin" 6 | ) 7 | 8 | type Service interface { 9 | //插件通过ID查找插件。 10 | Plugin(ctx context.Context, id string) (*plugin.Plugin, bool) 11 | //Plugins返回所有插件。 12 | Plugins(ctx context.Context) []*plugin.Plugin 13 | //Add将提供的插件添加到注册表中。 14 | AddPlugin(ctx context.Context, plugin *plugin.Plugin) error 15 | 16 | Reload(ctx context.Context, plugin *plugin.Plugin) error 17 | 18 | //Remove从注册表中删除请求的插件。 19 | Remove(ctx context.Context, id string) error 20 | } 21 | -------------------------------------------------------------------------------- /pkg/infrastructure/plugins/manager/process/ifaces.go: -------------------------------------------------------------------------------- 1 | package process 2 | 3 | import ( 4 | "context" 5 | "github.com/1340691923/ElasticView/pkg/infrastructure/plugins/plugin" 6 | ) 7 | 8 | type Manager interface { 9 | Start(ctx context.Context, p *plugin.Plugin) error 10 | Stop(ctx context.Context, p *plugin.Plugin) error 11 | } 12 | -------------------------------------------------------------------------------- /pkg/infrastructure/process/process.go: -------------------------------------------------------------------------------- 1 | package process 2 | 3 | func IsRunningWithElevatedPrivileges() (bool, error) { 4 | return elevatedPrivilegesCheck() 5 | } 6 | -------------------------------------------------------------------------------- /pkg/infrastructure/process/root_check.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package process 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/user" 10 | ) 11 | 12 | func elevatedPrivilegesCheck() (bool, error) { 13 | u, err := user.Current() 14 | if err != nil { 15 | return false, fmt.Errorf("could not get current OS user to detect process privileges") 16 | } 17 | 18 | return (u != nil && u.Username == "root") || 19 | os.Geteuid() != os.Getuid() || 20 | os.Geteuid() == 0, nil 21 | } 22 | -------------------------------------------------------------------------------- /pkg/infrastructure/process/root_check_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package process 5 | 6 | func elevatedPrivilegesCheck() (bool, error) { 7 | // TODO implement Windows process root check 8 | return false, nil 9 | } 10 | -------------------------------------------------------------------------------- /pkg/infrastructure/request/Request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | // 自定义请求 辅助方法 8 | type Request struct { 9 | } 10 | 11 | func NewRequest() *Request { 12 | return &Request{} 13 | } 14 | 15 | // 获取用户token信息 16 | func (this Request) GetToken(ctx *gin.Context) (token string) { 17 | return ctx.GetHeader("X-Token") 18 | } 19 | -------------------------------------------------------------------------------- /pkg/infrastructure/sqlstore/sqlite/errors.go: -------------------------------------------------------------------------------- 1 | package sqlite 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrConstraintsNotImplemented = errors.New("constraints not implemented on sqlite, consider using DisableForeignKeyConstraintWhenMigrating, more details https://github.com/go-gorm/gorm/wiki/GORM-V2-Release-Note-Draft#all-new-migrator") 7 | ) 8 | -------------------------------------------------------------------------------- /pkg/infrastructure/sqlstore/squirrel.go: -------------------------------------------------------------------------------- 1 | package sqlstore 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // 创建分页查询 8 | func CreatePage(page, limit int) int { 9 | tmp := (page - 1) * limit 10 | return int(tmp) 11 | } 12 | 13 | // 创建模糊查询 14 | func CreateLike(column string) string { 15 | return fmt.Sprint("%", column, "%") 16 | } 17 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/alias_info.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type AliasInfo struct { 4 | AliasName string `json:"AliasName"` 5 | } 6 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/cat_index.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type Status struct { 4 | Status string `json:"status"` 5 | } 6 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/es_back.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type SnapshotRepositoryList struct { 4 | List []Snashot `json:"list"` 5 | Res map[string]SnapshotRepository `json:"res"` 6 | PathRepo []interface{} `json:"pathRepo"` 7 | } 8 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/index_html.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type FrontEndCfg struct { 4 | AppUrl string 5 | AppSubUrl string 6 | Version string 7 | Lang string 8 | WatermarkContent string 9 | } 10 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/live.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type LivePrivateData struct { 4 | Channel string `json:"channel"` 5 | Data interface{} `json:"data"` 6 | } 7 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/oauth.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type OAuthConfig struct { 4 | OauthUrl string `json:"oauthUrl"` 5 | Name string `json:"name"` 6 | Enable bool `json:"enable"` 7 | Img string `json:"img"` 8 | } 9 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/operater.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type GmOperaterLog struct { 4 | Id int `json:"id"` 5 | OperaterId int `json:"operater_id"` 6 | OperaterName string `json:"operater_name"` 7 | OperaterAction string `json:"operater_action"` 8 | Method string `json:"method"` 9 | Body string `json:"body_str"` 10 | OperaterRoleId int `json:"operater_role_id"` 11 | Created string `json:"created"` 12 | CostTime string `json:"cost_time"` 13 | Status string `json:"status"` 14 | } 15 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/ping_result.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type PingResult struct { 4 | Name string `json:"name"` 5 | ClusterName string `json:"cluster_name"` 6 | Version struct { 7 | Number string `json:"number"` 8 | BuildFlavor string `json:"build_flavor"` // e.g. "oss" or "default" 9 | BuildType string `json:"build_type"` // e.g. "docker" 10 | BuildHash string `json:"build_hash"` // e.g. "b7e28a7" 11 | BuildDate string `json:"build_date"` // e.g. "2019-04-05T22:55:32.697037Z" 12 | BuildSnapshot bool `json:"build_snapshot"` // e.g. false 13 | LuceneVersion string `json:"lucene_version"` // e.g. "8.0.0" 14 | MinimumWireCompatibilityVersion string `json:"minimum_wire_compatibility_version"` // e.g. "6.7.0" 15 | MinimumIndexCompatibilityVersion string `json:"minimum_index_compatibility_version"` // e.g. "6.0.0-beta1" 16 | } `json:"version"` 17 | TagLine string `json:"tagline"` 18 | } 19 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/plugin_util.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type ExecSqlRes struct { 4 | RowsAffected int64 `json:"rows_affected"` 5 | } 6 | 7 | type SelectSqlRes struct { 8 | Result []map[string]interface{} `json:"result"` 9 | } 10 | 11 | type FirstSqlRes struct { 12 | Result map[string]interface{} `json:"result"` 13 | } 14 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/sql2dsl.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type SqlToDsl struct { 4 | Dsl string `json:"dsl"` 5 | TableName string `json:"tableName"` 6 | } 7 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/url_config.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type RouterConfig struct { 4 | Url string `json:"url"` 5 | Remark string `json:"remark"` 6 | } 7 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/user.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type User struct { 4 | Token string `json:"token"` 5 | UnixTime int64 `json:"unix_time"` 6 | } 7 | 8 | type GmUsers struct { 9 | Id int `json:"id"` 10 | Username string `json:"username"` 11 | Password string `json:"password"` 12 | 13 | Avatar string `json:"avatar"` 14 | IsBan int32 `json:"is_ban"` 15 | Realname string `json:"realname"` 16 | Email string `json:"email"` 17 | WorkWechatUid string `json:"work_wechat_uid"` 18 | RoleIds []int `json:"role_ids"` 19 | UpdateTime string `json:"update_time"` 20 | CreateTime string `json:"create_time"` 21 | LastLoginTime string `json:"last_login_time"` 22 | } 23 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/user_info.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type UserInfoV2 struct { 4 | UserId int `json:"userId"` 5 | Username string `json:"username"` 6 | Nickname string `json:"nickname"` 7 | Avatar string `json:"avatar"` 8 | Roles []int `json:"roles"` 9 | Perms []string `json:"perms"` 10 | } 11 | -------------------------------------------------------------------------------- /pkg/infrastructure/vo/ws.go: -------------------------------------------------------------------------------- 1 | package vo 2 | 3 | type S2C_PONG struct{} 4 | -------------------------------------------------------------------------------- /pkg/registry/registry.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type BackgroundServiceRegistry interface { 8 | GetServices() []BackgroundService 9 | } 10 | 11 | type CanBeDisabled interface { 12 | IsDisabled() bool 13 | } 14 | 15 | type BackgroundService interface { 16 | Run(ctx context.Context) error 17 | } 18 | 19 | type UsageStatsProvidersRegistry interface { 20 | GetServices() []ProvidesUsageStats 21 | } 22 | 23 | type ProvidesUsageStats interface { 24 | GetUsageStats(ctx context.Context) map[string]interface{} 25 | } 26 | 27 | func IsDisabled(srv BackgroundService) bool { 28 | canBeDisabled, ok := srv.(CanBeDisabled) 29 | return ok && canBeDisabled.IsDisabled() 30 | } 31 | -------------------------------------------------------------------------------- /pkg/server/generate.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | //go:generate wire 4 | -------------------------------------------------------------------------------- /pkg/server/systray_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build darwin 2 | // +build darwin 3 | 4 | package server 5 | 6 | func (this *Server) runSystray() { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /pkg/server/systray_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | // +build linux 3 | 4 | package server 5 | 6 | func (this *Server) runSystray() { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /pkg/services/gm_user/exception.go: -------------------------------------------------------------------------------- 1 | package gm_user 2 | 3 | // 自定义业务异常 4 | const ( 5 | ERROR_AUTH_TOKEN = 40006 6 | ERROR_AUTH = 40007 7 | ) 8 | 9 | var AUTH_ERROR = map[int]string{ 10 | ERROR_AUTH_TOKEN: "Token生成失败", 11 | ERROR_AUTH: "用户验证失败", 12 | } 13 | -------------------------------------------------------------------------------- /pkg/services/live_svr/consts.go: -------------------------------------------------------------------------------- 1 | package live_svr 2 | -------------------------------------------------------------------------------- /pkg/services/oauth/idp.go: -------------------------------------------------------------------------------- 1 | package oauth 2 | 3 | type UserInfo struct { 4 | Id string 5 | Username string 6 | DisplayName string 7 | UnionId string 8 | Email string 9 | Phone string 10 | CountryCode string 11 | AvatarUrl string 12 | Extra map[string]string 13 | } 14 | -------------------------------------------------------------------------------- /pkg/services/oauth/interfaces.go: -------------------------------------------------------------------------------- 1 | package oauth 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | "golang.org/x/oauth2" 6 | ) 7 | 8 | type OAuthInterface interface { 9 | GetOAuthUrl(callback string, state map[string]interface{}) string 10 | GetAppliactionName() string 11 | GetToken(code string) (*oauth2.Token, error) 12 | GetUserInfo(token *oauth2.Token) (*UserInfo, error) 13 | Enable() bool 14 | GetImg() string 15 | GetUserField() string 16 | GetConfig() map[string]interface{} 17 | SetConfig(data map[string]interface{}) 18 | } 19 | 20 | func ProvideOAuthServiceRegistry( 21 | workWechat *WorkWechat, 22 | dingtalk *Dingtalk, 23 | feishu *Feishu, 24 | ) *OAuthServiceRegistry { 25 | return NewOAuthServiceRegistry( 26 | workWechat, 27 | dingtalk, 28 | feishu, 29 | ) 30 | } 31 | 32 | type OAuthServiceRegistry struct { 33 | oAuthInterfaces []OAuthInterface 34 | } 35 | 36 | func NewOAuthServiceRegistry(services ...OAuthInterface) *OAuthServiceRegistry { 37 | return &OAuthServiceRegistry{services} 38 | } 39 | 40 | func (this *OAuthServiceRegistry) GetServices() []OAuthInterface { 41 | return this.oAuthInterfaces 42 | } 43 | 44 | func (this *OAuthServiceRegistry) FindServiceByName(name string) (OAuthInterface, error) { 45 | for _, v := range this.GetServices() { 46 | if v.GetAppliactionName() == name { 47 | return v, nil 48 | } 49 | } 50 | return nil, errors.New("没有找到对应第三方登录信息") 51 | } 52 | -------------------------------------------------------------------------------- /pkg/services/oauth/utils/util.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "fmt" 4 | 5 | func GetCallbackUrl(domain string) string { 6 | return fmt.Sprintf("%s%s", domain, "api/callback") 7 | } 8 | -------------------------------------------------------------------------------- /pkg/services/plugin_config_service/plugin_config_service.go: -------------------------------------------------------------------------------- 1 | package plugin_config_service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/1340691923/ElasticView/pkg/infrastructure/dao" 7 | "github.com/1340691923/ElasticView/pkg/infrastructure/logger" 8 | "github.com/1340691923/ElasticView/pkg/infrastructure/model" 9 | "go.uber.org/zap" 10 | ) 11 | 12 | type PluginConfigServie struct { 13 | log *logger.AppLogger 14 | pluginConfigDao *dao.PluginConfigDao 15 | } 16 | 17 | func NewPluginConfigServie(log *logger.AppLogger, pluginConfigDao *dao.PluginConfigDao) *PluginConfigServie { 18 | return &PluginConfigServie{log: log, pluginConfigDao: pluginConfigDao} 19 | } 20 | 21 | func (this *PluginConfigServie) GetPluginConfig(ctx context.Context, pluginID string) (*model.PluginConfig, error) { 22 | return this.pluginConfigDao.GetPluginConfig(ctx, pluginID) 23 | } 24 | 25 | // UpdatePluginConfig 更新插件配置 26 | func (this *PluginConfigServie) UpdatePluginConfig(ctx context.Context, pluginID string, autoUpdate bool) error { 27 | return this.pluginConfigDao.UpdatePluginConfig(ctx, pluginID, autoUpdate) 28 | } 29 | 30 | // IsAutoUpdateEnabled 检查插件是否启用自动更新 31 | func (this *PluginConfigServie) IsAutoUpdateEnabled(ctx context.Context, pluginID string) bool { 32 | config, err := this.pluginConfigDao.GetPluginConfig(ctx, pluginID) 33 | if err != nil { 34 | this.log.Error("获取插件配置失败", zap.Error(err), zap.String("pluginID", pluginID)) 35 | return false 36 | } 37 | return config.AutoUpdate 38 | } 39 | -------------------------------------------------------------------------------- /pkg/services/web/ai.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | func (this *WebServer) runAI() { 4 | group := this.engine.Group("AI模块", "/api/ai") 5 | { 6 | group.Use(this.middleWareService.OperaterLog) 7 | group.POST(false, "查询百炼大模型", "/SearchBigMode", this.aiController.SearchBigMode) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /pkg/services/web/es.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | // ES基础操作 路由 4 | func (this *WebServer) runEs() { 5 | 6 | const AbsolutePath = "/api/es" 7 | group := this.engine.Group("ES基础操作", AbsolutePath) 8 | { 9 | group.POST(false, "Ping连接", "/PingAction", this.esController.PingAction) 10 | group.POST(false, "获取ES索引数", "/IndexsCountAction", this.esController.IndexsCountAction) 11 | group.POST(false, "进行ES的Cat操作", "/CatAction", this.esController.CatAction) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /pkg/services/web/es_link.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | // ES连接 路由 4 | func (this *WebServer) runEsLink() { 5 | 6 | const AbsolutePath = "/api/es_link" 7 | group := this.engine.Group("数据源", AbsolutePath) 8 | { 9 | group.POST(false, "查看连接配置下拉选", "/OptAction", this.esLinkController.OptAction) 10 | group.POST(false, "查看数据源列表", "/ListAction", this.esLinkController.ListAction) 11 | group.POST(false, "查看鉴权列表", "/GetEsCfgList", this.esLinkController.GetEsCfgList) 12 | group.POST(false, "查看鉴权配置下拉选", "/GetEsCfgOpt", this.esLinkController.GetEsCfgOpt) 13 | 14 | group.Use(this.middleWareService.OperaterLog) 15 | 16 | group.POST(false, "按id删除连接鉴权配置", "/DeleteEsCfgRelation", this.esLinkController.DeleteEsCfgRelation) 17 | 18 | group.POST(true, "新增数据源信息", "/InsertAction", this.esLinkController.InsertAction) 19 | group.POST(true, "删除数据源信息", "/DeleteAction", this.esLinkController.DeleteAction) 20 | group.POST(true, "修改数据源信息", "/UpdateAction", this.esLinkController.UpdateAction) 21 | 22 | group.POST(true, "新增鉴权配置信息", "/InsertEsCfgAction", this.esLinkController.InsertEsCfgAction) 23 | group.POST(true, "修改鉴权配置信息", "/UpdateEsCfgAction", this.esLinkController.UpdateEsCfgAction) 24 | group.POST(true, "删除鉴权配置信息", "/DeleteEsCfgAction", this.esLinkController.DeleteEsCfgAction) 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pkg/services/web/notice.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | func (this *WebServer) runNotice() { 4 | const AbsolutePath = "/api/notice" 5 | group := this.engine.Group("通知模块", AbsolutePath) 6 | { 7 | group.Use(this.middleWareService.OperaterLog) 8 | group.POST(false, "查询通知列表", "/GetList", this.noticeController.GetList) 9 | group.POST(false, "标记通知为已读", "/MarkReadNotice", this.noticeController.MarkReadNotice) 10 | group.POST(true, "清空通知数据", "/Truncate", this.noticeController.Truncate) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /pkg/services/web/operater_log.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | func (this *WebServer) runOperaterLog() { 4 | group := this.engine.Group("操作记录模块", "/api/operater_log") 5 | { 6 | group.POST(false, "查看用户操作记录", "/ListAction", this.gmOperaterController.ListAction) 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /pkg/services/web/pprof.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | "net/http/pprof" 7 | ) 8 | 9 | func (this *WebServer) runpprof() { 10 | pprofGroup := this.engine.GetGinEngine().Group("/debug/pprof") 11 | { 12 | pprofGroup.GET("/", gin.WrapF(pprof.Index)) 13 | pprofGroup.GET("/cmdline", gin.WrapF(pprof.Cmdline)) 14 | pprofGroup.GET("/profile", gin.WrapF(pprof.Profile)) 15 | pprofGroup.POST("/symbol", gin.WrapF(pprof.Symbol)) 16 | pprofGroup.GET("/symbol", gin.WrapF(pprof.Symbol)) 17 | pprofGroup.GET("/trace", gin.WrapF(pprof.Trace)) 18 | pprofGroup.GET("/allocs", gin.WrapH(http.HandlerFunc(pprof.Handler("allocs").ServeHTTP))) 19 | pprofGroup.GET("/block", gin.WrapH(http.HandlerFunc(pprof.Handler("block").ServeHTTP))) 20 | pprofGroup.GET("/goroutine", gin.WrapH(http.HandlerFunc(pprof.Handler("goroutine").ServeHTTP))) 21 | pprofGroup.GET("/heap", gin.WrapH(http.HandlerFunc(pprof.Handler("heap").ServeHTTP))) 22 | pprofGroup.GET("/mutex", gin.WrapH(http.HandlerFunc(pprof.Handler("mutex").ServeHTTP))) 23 | pprofGroup.GET("/threadcreate", gin.WrapH(http.HandlerFunc(pprof.Handler("threadcreate").ServeHTTP))) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /pkg/services/web/ws.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import "github.com/gin-gonic/gin" 4 | 5 | // ES 任务 路由 6 | func (this *WebServer) runWs() { 7 | this.engine.GetGinEngine().GET("/ws", gin.WrapH(this.liveController.HttpHandle())) 8 | } 9 | -------------------------------------------------------------------------------- /pkg/services/webview/webview.go: -------------------------------------------------------------------------------- 1 | package webview 2 | 3 | import ( 4 | "github.com/1340691923/ElasticView/pkg/infrastructure/config" 5 | "github.com/1340691923/ElasticView/pkg/infrastructure/logger" 6 | 7 | "go.uber.org/zap" 8 | ) 9 | 10 | type WebView struct { 11 | log *zap.Logger 12 | cfg *config.Config 13 | } 14 | 15 | func ProvideWebView(log *logger.AppLogger, cfg *config.Config) (*WebView, error) { 16 | log = log.Named("webview") 17 | return &WebView{ 18 | log: logger.ZapLog2AppLog(log), 19 | cfg: cfg, 20 | }, nil 21 | } 22 | -------------------------------------------------------------------------------- /pkg/services/webview/webview_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build darwin 2 | // +build darwin 3 | 4 | package webview 5 | 6 | import ( 7 | "context" 8 | ) 9 | 10 | func (this *WebView) Run(ctx context.Context) (err error) { 11 | <-ctx.Done() 12 | return nil 13 | } 14 | -------------------------------------------------------------------------------- /pkg/services/webview/webview_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | // +build linux 3 | 4 | package webview 5 | 6 | import ( 7 | "context" 8 | ) 9 | 10 | func (this *WebView) Run(ctx context.Context) (err error) { 11 | <-ctx.Done() 12 | return nil 13 | } 14 | -------------------------------------------------------------------------------- /pkg/services/webview/webview_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package webview 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "github.com/inkeliz/gowebview" 10 | "github.com/pkg/errors" 11 | "runtime" 12 | ) 13 | 14 | func (this *WebView) Run(ctx context.Context) (err error) { 15 | var w gowebview.WebView 16 | if !this.cfg.DeBug && runtime.GOOS == "windows" { 17 | openAddr := fmt.Sprintf("http://localhost:%d/#/", this.cfg.Port) 18 | w, err = gowebview.New(&gowebview.Config{ 19 | Debug: this.cfg.DeBug, 20 | URL: openAddr, 21 | WindowConfig: &gowebview.WindowConfig{ 22 | Title: "ElasticView", 23 | Size: &gowebview.Point{X: 1280, Y: 720}, 24 | }}) 25 | if err != nil { 26 | return errors.WithStack(err) 27 | } 28 | defer w.Destroy() 29 | 30 | go func() { 31 | w.Run() 32 | }() 33 | } 34 | <-ctx.Done() 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /pkg/util/config.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "github.com/goccy/go-json" 5 | "io/ioutil" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | // LoadJSONConfig 读取配置文件 json格式 11 | func LoadJSONConfig(filename string, v interface{}) error { 12 | b, err := ioutil.ReadFile(filename) 13 | if err != nil { 14 | return err 15 | } 16 | err = json.Unmarshal(b, v) 17 | if err != nil { 18 | return err 19 | } 20 | return nil 21 | } 22 | 23 | func JoinInt(s []int, sp string) string { 24 | var tmp = make([]string, 0, len(s)) 25 | for i, _ := range s { 26 | tmp = append(tmp, strconv.Itoa(s[i])) 27 | } 28 | return strings.Join(tmp, sp) 29 | } 30 | -------------------------------------------------------------------------------- /pkg/util/errors.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "database/sql" 5 | "github.com/pkg/errors" 6 | "strings" 7 | ) 8 | 9 | func FilterMysqlNilErr(err error) bool { 10 | if err != nil && !errors.Is(err, sql.ErrNoRows) { 11 | return true 12 | } 13 | return false 14 | } 15 | 16 | func IsMysqlRepeatError(err error) bool { 17 | if err != nil && strings.Contains(err.Error(), "Error 1062") { 18 | return true 19 | } 20 | return false 21 | } 22 | -------------------------------------------------------------------------------- /pkg/util/exec.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "log" 5 | "os/exec" 6 | "runtime" 7 | "syscall" 8 | ) 9 | 10 | func OpenWinBrowser(uri string) error { 11 | switch runtime.GOOS { 12 | case "windows": 13 | cmd := exec.Command(`cmd`, `/c`, `start`, uri) 14 | cmd.SysProcAttr = &syscall.SysProcAttr{} 15 | err := cmd.Start() 16 | if err != nil { 17 | log.Println(err) 18 | return err 19 | } 20 | } 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /pkg/util/gzip.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "io/ioutil" 7 | ) 8 | 9 | func GzipCompressByte(data []byte) ([]byte, error) { 10 | buf := bytes.NewBuffer(nil) 11 | gzW := gzip.NewWriter(buf) 12 | _, err := gzW.Write(data) 13 | if err != nil { 14 | return nil, err 15 | } 16 | gzW.Close() 17 | return buf.Bytes(), err 18 | } 19 | 20 | func GzipCompress(data string) ([]byte, error) { 21 | buf := bytes.NewBuffer(nil) 22 | gzW := gzip.NewWriter(buf) 23 | _, err := gzW.Write(Str2bytes(data)) 24 | if err != nil { 25 | return nil, err 26 | } 27 | gzW.Close() 28 | return buf.Bytes(), err 29 | } 30 | 31 | func GzipUnCompress(data []byte) (string, error) { 32 | gzR, err := gzip.NewReader(bytes.NewReader(data)) 33 | if err != nil { 34 | return "", err 35 | } 36 | b, err := ioutil.ReadAll(gzR) 37 | return Bytes2str(b), err 38 | } 39 | 40 | func GzipUnCompressByte(data []byte) ([]byte, error) { 41 | gzR, err := gzip.NewReader(bytes.NewReader(data)) 42 | if err != nil { 43 | return nil, err 44 | } 45 | b, err := ioutil.ReadAll(gzR) 46 | return b, err 47 | } 48 | -------------------------------------------------------------------------------- /pkg/util/interface.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "reflect" 4 | 5 | // interface{}转为 []interface{} 6 | func CreateAnyTypeSlice(slice interface{}) ([]interface{}, bool) { 7 | val, ok := isSlice(slice) 8 | 9 | if !ok { 10 | return nil, false 11 | } 12 | 13 | sliceLen := val.Len() 14 | 15 | out := make([]interface{}, sliceLen) 16 | 17 | for i := 0; i < sliceLen; i++ { 18 | out[i] = val.Index(i).Interface() 19 | } 20 | 21 | return out, true 22 | } 23 | 24 | // 判断是否为slcie数据 25 | func isSlice(arg interface{}) (val reflect.Value, ok bool) { 26 | val = reflect.ValueOf(arg) 27 | 28 | if val.Kind() == reflect.Slice { 29 | ok = true 30 | } 31 | 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /pkg/util/ip.go: -------------------------------------------------------------------------------- 1 | package util 2 | -------------------------------------------------------------------------------- /pkg/util/ip_address.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "strings" 7 | ) 8 | 9 | type NetworkAddress struct { 10 | Host string 11 | Port string 12 | } 13 | 14 | // SplitHostPortDefault splits ip address/hostname string by host and port. Defaults used if no match found 15 | func SplitHostPortDefault(input, defaultHost, defaultPort string) (NetworkAddress, error) { 16 | addr := NetworkAddress{ 17 | Host: defaultHost, 18 | Port: defaultPort, 19 | } 20 | if len(input) == 0 { 21 | return addr, nil 22 | } 23 | 24 | start := 0 25 | // Determine if IPv6 address, in which case IP address will be enclosed in square brackets 26 | if strings.Index(input, "[") == 0 { 27 | addrEnd := strings.LastIndex(input, "]") 28 | if addrEnd < 0 { 29 | // Malformed address 30 | return addr, fmt.Errorf("malformed IPv6 address: '%s'", input) 31 | } 32 | 33 | start = addrEnd 34 | } 35 | if strings.LastIndex(input[start:], ":") < 0 { 36 | // There's no port section of the input 37 | // It's still useful to call net.SplitHostPort though, since it removes IPv6 38 | // square brackets from the address 39 | input = fmt.Sprintf("%s:%s", input, defaultPort) 40 | } 41 | 42 | host, port, err := net.SplitHostPort(input) 43 | if err != nil { 44 | return addr, fmt.Errorf("net.SplitHostPort failed for '%s': %w", input, err) 45 | } 46 | 47 | if len(host) > 0 { 48 | addr.Host = host 49 | } 50 | if len(port) > 0 { 51 | addr.Port = port 52 | } 53 | 54 | return addr, nil 55 | } 56 | -------------------------------------------------------------------------------- /pkg/util/json.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | // DynMap defines a dynamic map interface. 4 | type DynMap map[string]interface{} 5 | -------------------------------------------------------------------------------- /pkg/util/map.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | type Map map[string]interface{} 4 | -------------------------------------------------------------------------------- /pkg/util/math.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "strconv" 7 | ) 8 | 9 | // MinInt returns the smaller of x or y. 10 | func MinInt(x, y int) int { 11 | if x > y { 12 | return y 13 | } 14 | return x 15 | } 16 | 17 | func Decimal(value float64) float64 { 18 | value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64) 19 | if math.IsNaN(value) || math.IsInf(value, 0) { 20 | return 0 21 | } 22 | 23 | return value 24 | } 25 | -------------------------------------------------------------------------------- /pkg/util/md5.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | "io" 7 | "strings" 8 | ) 9 | 10 | // Md5Sum calculates the md5sum of a stream 11 | func Md5Sum(reader io.Reader) (string, error) { 12 | var returnMD5String string 13 | hash := md5.New() 14 | if _, err := io.Copy(hash, reader); err != nil { 15 | return returnMD5String, err 16 | } 17 | hashInBytes := hash.Sum(nil)[:16] 18 | returnMD5String = hex.EncodeToString(hashInBytes) 19 | return returnMD5String, nil 20 | } 21 | 22 | // Md5SumString calculates the md5sum of a string 23 | func Md5SumString(input string) (string, error) { 24 | buffer := strings.NewReader(input) 25 | return Md5Sum(buffer) 26 | } 27 | -------------------------------------------------------------------------------- /pkg/util/process.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/shirou/gopsutil/v3/process" 8 | ) 9 | 10 | func GetProcCPUPercent(pid int32) { 11 | proc, err := process.NewProcess(pid) 12 | if err != nil { 13 | log.Fatalf("Failed to create process object: %v", err) 14 | } 15 | 16 | // 获取 CPU 使用率 17 | cpuPercent, err := proc.CPUPercent() 18 | if err != nil { 19 | log.Printf("Failed to get CPU usage: %v", err) 20 | } else { 21 | fmt.Printf("CPU Usage: %.2f%%\n", cpuPercent) 22 | } 23 | 24 | } 25 | 26 | func GetProcMemoryInfo(pid int32) { 27 | proc, err := process.NewProcess(pid) 28 | if err != nil { 29 | log.Fatalf("Failed to create process object: %v", err) 30 | } 31 | // 获取内存信息 32 | memInfo, err := proc.MemoryInfo() 33 | if err != nil { 34 | log.Printf("Failed to get memory usage: %v", err) 35 | } else { 36 | fmt.Printf("Memory Usage: %v mb\n", memInfo.RSS/1024/1024) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pkg/util/proxyutil/proxyutil.go: -------------------------------------------------------------------------------- 1 | package proxyutil 2 | 3 | import ( 4 | "net" 5 | "net/http" 6 | ) 7 | 8 | func PrepareProxyRequest(req *http.Request) { 9 | req.Header.Del("X-Forwarded-Host") 10 | req.Header.Del("X-Forwarded-Port") 11 | req.Header.Del("X-Forwarded-Proto") 12 | 13 | if req.RemoteAddr != "" { 14 | remoteAddr, _, err := net.SplitHostPort(req.RemoteAddr) 15 | if err != nil { 16 | remoteAddr = req.RemoteAddr 17 | } 18 | if req.Header.Get("X-Forwarded-For") != "" { 19 | req.Header.Set("X-Forwarded-For", req.Header.Get("X-Forwarded-For")+", "+remoteAddr) 20 | } else { 21 | req.Header.Set("X-Forwarded-For", remoteAddr) 22 | } 23 | } 24 | } 25 | 26 | func ClearCookieHeader(req *http.Request, keepCookiesNames []string) { 27 | var keepCookies []*http.Cookie 28 | for _, c := range req.Cookies() { 29 | for _, v := range keepCookiesNames { 30 | if c.Name == v { 31 | keepCookies = append(keepCookies, c) 32 | } 33 | } 34 | } 35 | 36 | req.Header.Del("Cookie") 37 | for _, c := range keepCookies { 38 | req.AddCookie(c) 39 | } 40 | } 41 | 42 | func SetProxyResponseHeaders(header http.Header) { 43 | header.Set("Content-Security-Policy", "sandbox") 44 | } 45 | -------------------------------------------------------------------------------- /pkg/util/response/res.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | func JsonApiErr(c *gin.Context, code int, msg string, err error) { 9 | c.JSON(code, map[string]interface{}{"code": code, "msg": fmt.Sprintf(msg, err)}) 10 | } 11 | -------------------------------------------------------------------------------- /pkg/util/retry.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | "time" 6 | ) 7 | 8 | func Retry(attempts int, sleep time.Duration, fn func() error) error { 9 | if err := fn(); err != nil { 10 | if s, ok := err.(stop); ok { 11 | return s.error 12 | } 13 | 14 | if attempts--; attempts > 0 { 15 | time.Sleep(sleep) 16 | return Retry(attempts, 2*sleep, fn) 17 | } 18 | return errors.WithStack(err) 19 | } 20 | return nil 21 | } 22 | 23 | type stop struct { 24 | error 25 | } 26 | 27 | func NoRetryError(err error) stop { 28 | return stop{err} 29 | } 30 | -------------------------------------------------------------------------------- /pkg/util/split_email.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "strings" 4 | 5 | // SplitEmails splits addresses with a few different ways 6 | func SplitEmails(emails string) []string { 7 | return strings.FieldsFunc(emails, func(r rune) bool { 8 | switch r { 9 | case ',', ';', '\n': 10 | return true 11 | } 12 | return false 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /pkg/util/sys.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "os" 5 | "os/signal" 6 | "syscall" 7 | ) 8 | 9 | func WaitQuit(fns ...func()) { 10 | c := make(chan os.Signal, 1) 11 | signal.Notify(c, os.Interrupt, syscall.SIGTERM) 12 | <-c 13 | for _, fn := range fns { 14 | fn() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /pkg/util/token.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "github.com/google/uuid" 5 | "sync" 6 | ) 7 | 8 | var TokenBucket sync.Map 9 | 10 | func GetUUid() string { 11 | return uuid.New().String() 12 | } 13 | -------------------------------------------------------------------------------- /pkg/util/url.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "net/url" 5 | "strings" 6 | ) 7 | 8 | // URLQueryReader is a ApiURL query type. 9 | type URLQueryReader struct { 10 | values url.Values 11 | } 12 | 13 | // NewURLQueryReader parses a raw query and returns it as a URLQueryReader type. 14 | func NewURLQueryReader(urlInfo *url.URL) (*URLQueryReader, error) { 15 | u, err := url.ParseQuery(urlInfo.RawQuery) 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | return &URLQueryReader{ 21 | values: u, 22 | }, nil 23 | } 24 | 25 | // Get parse parameters from an ApiURL. If the parameter does not exist, it returns 26 | // the default value. 27 | func (r *URLQueryReader) Get(name string, def string) string { 28 | val := r.values[name] 29 | if len(val) == 0 { 30 | return def 31 | } 32 | 33 | return val[0] 34 | } 35 | 36 | // JoinURLFragments joins two ApiURL fragments into only one ApiURL string. 37 | func JoinURLFragments(a, b string) string { 38 | aslash := strings.HasSuffix(a, "/") 39 | bslash := strings.HasPrefix(b, "/") 40 | 41 | if len(b) == 0 { 42 | return a 43 | } 44 | 45 | switch { 46 | case aslash && bslash: 47 | return a + b[1:] 48 | case !aslash && !bslash: 49 | return a + "/" + b 50 | } 51 | return a + b 52 | } 53 | -------------------------------------------------------------------------------- /pkg/util/validation.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "regexp" 5 | "strings" 6 | ) 7 | 8 | const ( 9 | emailRegexPattern string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" 10 | ) 11 | 12 | var ( 13 | regexEmail = regexp.MustCompile(emailRegexPattern) 14 | ) 15 | 16 | // IsEmail checks if a string is a valid email address. 17 | func IsEmail(str string) bool { 18 | return regexEmail.MatchString(strings.ToLower(str)) 19 | } 20 | -------------------------------------------------------------------------------- /pkg/util/zip.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "archive/zip" 5 | "io" 6 | "os" 7 | ) 8 | 9 | // CompressPathToZip 压缩文件夹 10 | func CompressPathToZip(path, targetFile string) error { 11 | d, err := os.Create(targetFile) 12 | if err != nil { 13 | return err 14 | } 15 | defer d.Close() 16 | w := zip.NewWriter(d) 17 | defer w.Close() 18 | 19 | f, err := os.Open(path) 20 | if err != nil { 21 | return err 22 | } 23 | 24 | defer f.Close() 25 | 26 | err = compress(f, "", w) 27 | 28 | return err 29 | } 30 | 31 | func compress(file *os.File, prefix string, zw *zip.Writer) error { 32 | info, err := file.Stat() 33 | if err != nil { 34 | return err 35 | } 36 | if info.IsDir() { 37 | prefix = prefix + "/" + info.Name() 38 | fileInfos, err := file.Readdir(-1) 39 | if err != nil { 40 | return err 41 | } 42 | for _, fi := range fileInfos { 43 | f, err := os.Open(file.Name() + "/" + fi.Name()) 44 | if err != nil { 45 | return err 46 | } 47 | defer f.Close() 48 | err = compress(f, prefix, zw) 49 | if err != nil { 50 | return err 51 | } 52 | } 53 | } else { 54 | header, err := zip.FileInfoHeader(info) 55 | header.Name = prefix + "/" + header.Name 56 | if err != nil { 57 | return err 58 | } 59 | writer, err := zw.CreateHeader(header) 60 | if err != nil { 61 | return err 62 | } 63 | _, err = io.Copy(writer, file) 64 | file.Close() 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | return nil 70 | } 71 | -------------------------------------------------------------------------------- /resources/views/dist/css/401.groh0FKW.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";[data-v-849ad0a6]:root{--menu-background: #fff;--menu-text: #212121;--menu-active-text: var( --el-menu-active-color );--menu-hover: #e6f4ff;--sidebar-logo-background: #f5f5f5;--sidebar-logo-text-color: #333}:root .el-table[data-v-849ad0a6]{--el-table-current-row-bg-color: rgb(235 243 250)}html.dark[data-v-849ad0a6]{--menu-background: var(--el-bg-color-overlay);--menu-text: #fff;--menu-active-text: var(--el-menu-active-color);--menu-hover: rgb(0 0 0 / 20%);--sidebar-logo-background: rgb(0 0 0 / 20%);--sidebar-logo-text-color: #fff}.page-container[data-v-849ad0a6]{width:100%;padding:100px}.page-container .pan-back-btn[data-v-849ad0a6]{color:#fff;background:#008489;border:none!important}.page-container .pan-gif[data-v-849ad0a6]{display:block;margin:0 auto}.page-container .pan-img[data-v-849ad0a6]{display:block;width:100%;margin:0 auto}.page-container .text-jumbo[data-v-849ad0a6]{font-size:60px;font-weight:700;color:#484848}.page-container .list-unstyled[data-v-849ad0a6]{font-size:14px}.page-container .list-unstyled li[data-v-849ad0a6]{padding-bottom:5px}.page-container .list-unstyled a[data-v-849ad0a6]{color:#008489;text-decoration:none}.page-container .list-unstyled a[data-v-849ad0a6]:hover{text-decoration:underline} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/EsHeader.BKG5A0gH.css: -------------------------------------------------------------------------------- 1 | .el-input[data-v-2429757a]{width:100%} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/SocialSignin.B51_dUaK.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";[data-v-af045c6a]:root{--menu-background: #fff;--menu-text: #212121;--menu-active-text: var( --el-menu-active-color );--menu-hover: #e6f4ff;--sidebar-logo-background: #f5f5f5;--sidebar-logo-text-color: #333}:root .el-table[data-v-af045c6a]{--el-table-current-row-bg-color: rgb(235 243 250)}html.dark[data-v-af045c6a]{--menu-background: var(--el-bg-color-overlay);--menu-text: #fff;--menu-active-text: var(--el-menu-active-color);--menu-hover: rgb(0 0 0 / 20%);--sidebar-logo-background: rgb(0 0 0 / 20%);--sidebar-logo-text-color: #fff}.social-container[data-v-af045c6a]{margin:20px 0}.social-container .social-title[data-v-af045c6a]{font-size:14px;color:#606266;margin-bottom:10px;text-align:center}.social-container .social-icons[data-v-af045c6a]{display:flex;justify-content:center}.social-container .social-icons a[data-v-af045c6a]{margin:0 10px;color:#606266;font-size:24px;cursor:pointer}.social-container .social-icons a[data-v-af045c6a]:hover{color:#409eff}.social-container .social-icons a .svg-icon[data-v-af045c6a]{width:30px;height:30px} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/el-card.BJ3sbP9B.css: -------------------------------------------------------------------------------- 1 | .el-card{--el-card-border-color:var(--el-border-color-light);--el-card-border-radius:4px;--el-card-padding:20px;--el-card-bg-color:var(--el-fill-color-blank);background-color:var(--el-card-bg-color);border:1px solid var(--el-card-border-color);border-radius:var(--el-card-border-radius);color:var(--el-text-color-primary);overflow:hidden;transition:var(--el-transition-duration)}.el-card.is-always-shadow,.el-card.is-hover-shadow:focus,.el-card.is-hover-shadow:hover{box-shadow:var(--el-box-shadow-light)}.el-card__header{border-bottom:1px solid var(--el-card-border-color);box-sizing:border-box;padding:calc(var(--el-card-padding) - 2px) var(--el-card-padding)}.el-card__body{padding:var(--el-card-padding)}.el-card__footer{border-top:1px solid var(--el-card-border-color);box-sizing:border-box;padding:calc(var(--el-card-padding) - 2px) var(--el-card-padding)} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/el-divider.Ca8J-BER.css: -------------------------------------------------------------------------------- 1 | .el-divider{position:relative}.el-divider--horizontal{border-top:1px var(--el-border-color) var(--el-border-style);display:block;height:1px;margin:24px 0;width:100%}.el-divider--vertical{border-left:1px var(--el-border-color) var(--el-border-style);display:inline-block;height:1em;margin:0 8px;position:relative;vertical-align:middle;width:1px}.el-divider__text{background-color:var(--el-bg-color);color:var(--el-text-color-primary);font-size:14px;font-weight:500;padding:0 20px;position:absolute}.el-divider__text.is-left{left:20px;transform:translateY(-50%)}.el-divider__text.is-center{left:50%;transform:translate(-50%) translateY(-50%)}.el-divider__text.is-right{right:20px;transform:translateY(-50%)} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/el-empty.BgB1A-Jc.css: -------------------------------------------------------------------------------- 1 | .el-empty{--el-empty-padding:40px 0;--el-empty-image-width:160px;--el-empty-description-margin-top:20px;--el-empty-bottom-margin-top:20px;--el-empty-fill-color-0:var(--el-color-white);--el-empty-fill-color-1:#fcfcfd;--el-empty-fill-color-2:#f8f9fb;--el-empty-fill-color-3:#f7f8fc;--el-empty-fill-color-4:#eeeff3;--el-empty-fill-color-5:#edeef2;--el-empty-fill-color-6:#e9ebef;--el-empty-fill-color-7:#e5e7e9;--el-empty-fill-color-8:#e0e3e9;--el-empty-fill-color-9:#d5d7de;align-items:center;box-sizing:border-box;display:flex;flex-direction:column;justify-content:center;padding:var(--el-empty-padding);text-align:center}.el-empty__image{width:var(--el-empty-image-width)}.el-empty__image img{height:100%;-o-object-fit:contain;object-fit:contain;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:top;width:100%}.el-empty__image svg{color:var(--el-svg-monochrome-grey);fill:currentColor;height:100%;vertical-align:top;width:100%}.el-empty__description{margin-top:var(--el-empty-description-margin-top)}.el-empty__description p{color:var(--el-text-color-secondary);font-size:var(--el-font-size-base);margin:0}.el-empty__bottom{margin-top:var(--el-empty-bottom-margin-top)} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/el-main.Dk0d5xqJ.css: -------------------------------------------------------------------------------- 1 | .el-container{box-sizing:border-box;display:flex;flex:1;flex-basis:auto;flex-direction:row;min-width:0}.el-container.is-vertical{flex-direction:column}.el-aside{box-sizing:border-box;flex-shrink:0;overflow:auto;width:var(--el-aside-width,300px)}.el-footer{--el-footer-padding:0 20px;--el-footer-height:60px;box-sizing:border-box;flex-shrink:0;height:var(--el-footer-height);padding:var(--el-footer-padding)}.el-header{--el-header-padding:0 20px;--el-header-height:60px;box-sizing:border-box;flex-shrink:0;height:var(--el-header-height);padding:var(--el-header-padding)}.el-main{--el-main-padding:20px;box-sizing:border-box;display:block;flex:1;flex-basis:auto;overflow:auto;padding:var(--el-main-padding)} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/el-popover.BXo9j6C6.css: -------------------------------------------------------------------------------- 1 | .el-popover{--el-popover-bg-color:var(--el-bg-color-overlay);--el-popover-font-size:var(--el-font-size-base);--el-popover-border-color:var(--el-border-color-lighter);--el-popover-padding:12px;--el-popover-padding-large:18px 20px;--el-popover-title-font-size:16px;--el-popover-title-text-color:var(--el-text-color-primary);--el-popover-border-radius:4px}.el-popover.el-popper{background:var(--el-popover-bg-color);border:1px solid var(--el-popover-border-color);border-radius:var(--el-popover-border-radius);box-shadow:var(--el-box-shadow-light);box-sizing:border-box;color:var(--el-text-color-regular);font-size:var(--el-popover-font-size);line-height:1.4;min-width:150px;overflow-wrap:break-word;padding:var(--el-popover-padding);z-index:var(--el-index-popper)}.el-popover.el-popper--plain{padding:var(--el-popover-padding-large)}.el-popover__title{color:var(--el-popover-title-text-color);font-size:var(--el-popover-title-font-size);line-height:1;margin-bottom:12px}.el-popover__reference:focus:hover,.el-popover__reference:focus:not(.focusing){outline-width:0}.el-popover.el-popper.is-dark{--el-popover-bg-color:var(--el-text-color-primary);--el-popover-border-color:var(--el-text-color-primary);--el-popover-title-text-color:var(--el-bg-color);color:var(--el-bg-color)}.el-popover.el-popper:focus,.el-popover.el-popper:focus:active{outline-width:0} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/el-scrollbar.DgVM_IK3.css: -------------------------------------------------------------------------------- 1 | .el-scrollbar{--el-scrollbar-opacity:.3;--el-scrollbar-bg-color:var(--el-text-color-secondary);--el-scrollbar-hover-opacity:.5;--el-scrollbar-hover-bg-color:var(--el-text-color-secondary);height:100%;overflow:hidden;position:relative}.el-scrollbar__wrap{height:100%;overflow:auto}.el-scrollbar__wrap--hidden-default{scrollbar-width:none}.el-scrollbar__wrap--hidden-default::-webkit-scrollbar{display:none}.el-scrollbar__thumb{background-color:var(--el-scrollbar-bg-color,var(--el-text-color-secondary));border-radius:inherit;cursor:pointer;display:block;height:0;opacity:var(--el-scrollbar-opacity,.3);position:relative;transition:var(--el-transition-duration) background-color;width:0}.el-scrollbar__thumb:hover{background-color:var(--el-scrollbar-hover-bg-color,var(--el-text-color-secondary));opacity:var(--el-scrollbar-hover-opacity,.5)}.el-scrollbar__bar{border-radius:4px;bottom:2px;position:absolute;right:2px;z-index:1}.el-scrollbar__bar.is-vertical{top:2px;width:6px}.el-scrollbar__bar.is-vertical>div{width:100%}.el-scrollbar__bar.is-horizontal{height:6px;left:2px}.el-scrollbar__bar.is-horizontal>div{height:100%}.el-scrollbar-fade-enter-active{transition:opacity .34s ease-out}.el-scrollbar-fade-leave-active{transition:opacity .12s ease-out}.el-scrollbar-fade-enter-from,.el-scrollbar-fade-leave-active{opacity:0} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/el-text.CjuDOozN.css: -------------------------------------------------------------------------------- 1 | .el-text{--el-text-font-size:var(--el-font-size-base);--el-text-color:var(--el-text-color-regular);align-self:center;color:var(--el-text-color);font-size:var(--el-text-font-size);margin:0;overflow-wrap:break-word;padding:0}.el-text.is-truncated{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.el-text.is-line-clamp{display:-webkit-inline-box;-webkit-box-orient:vertical;overflow:hidden}.el-text--large{--el-text-font-size:var(--el-font-size-medium)}.el-text--default{--el-text-font-size:var(--el-font-size-base)}.el-text--small{--el-text-font-size:var(--el-font-size-extra-small)}.el-text.el-text--primary{--el-text-color:var(--el-color-primary)}.el-text.el-text--success{--el-text-color:var(--el-color-success)}.el-text.el-text--warning{--el-text-color:var(--el-color-warning)}.el-text.el-text--danger{--el-text-color:var(--el-color-danger)}.el-text.el-text--error{--el-text-color:var(--el-color-error)}.el-text.el-text--info{--el-text-color:var(--el-color-info)}.el-text>.el-icon{vertical-align:-2px} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/index.CiheunKZ.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";.github-corner:hover .octo-arm[data-v-c5522eca]{animation:octocat-wave-c5522eca .56s ease-in-out}@keyframes octocat-wave-c5522eca{0%,to{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (width <= 500px){.github-corner .octo-arm[data-v-c5522eca]{animation:octocat-wave-c5522eca .56s ease-in-out}.github-corner:hover .octo-arm[data-v-c5522eca]{animation:none}}[data-v-2a9bf884]:root{--menu-background: #fff;--menu-text: #212121;--menu-active-text: var( --el-menu-active-color );--menu-hover: #e6f4ff;--sidebar-logo-background: #f5f5f5;--sidebar-logo-text-color: #333}:root .el-table[data-v-2a9bf884]{--el-table-current-row-bg-color: rgb(235 243 250)}html.dark[data-v-2a9bf884]{--menu-background: var(--el-bg-color-overlay);--menu-text: #fff;--menu-active-text: var(--el-menu-active-color);--menu-hover: rgb(0 0 0 / 20%);--sidebar-logo-background: rgb(0 0 0 / 20%);--sidebar-logo-text-color: #fff}.dashboard-container[data-v-2a9bf884]{position:relative;padding:24px}.dashboard-container .github-corner[data-v-2a9bf884]{position:absolute;top:0;right:0;z-index:1;border:0} 2 | -------------------------------------------------------------------------------- /resources/views/dist/css/index.gIaAfrbD.css: -------------------------------------------------------------------------------- 1 | .svg-icon[data-v-73782c74]{display:inline-block;width:1em;height:1em;overflow:hidden;vertical-align:-.15em;outline:none;fill:currentcolor} 2 | -------------------------------------------------------------------------------- /resources/views/dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/favicon.ico -------------------------------------------------------------------------------- /resources/views/dist/img/401.DaBJYOxp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/401.DaBJYOxp.gif -------------------------------------------------------------------------------- /resources/views/dist/img/404.D6_y3Jr2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/404.D6_y3Jr2.png -------------------------------------------------------------------------------- /resources/views/dist/img/login-background-dark.BfPFE40x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/login-background-dark.BfPFE40x.jpg -------------------------------------------------------------------------------- /resources/views/dist/img/login-background-light.CKlK6emc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/login-background-light.CKlK6emc.jpg -------------------------------------------------------------------------------- /resources/views/dist/img/login_bg.BzmVCLXR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/login_bg.BzmVCLXR.png -------------------------------------------------------------------------------- /resources/views/dist/img/login_dark_bg2.CmiPvwd_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/login_dark_bg2.CmiPvwd_.png -------------------------------------------------------------------------------- /resources/views/dist/img/logo.Cq2B5Nmk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/logo.Cq2B5Nmk.png -------------------------------------------------------------------------------- /resources/views/dist/img/social_dingtalk.CFQi2ZM6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/social_dingtalk.CFQi2ZM6.png -------------------------------------------------------------------------------- /resources/views/dist/img/work_wechat.BCef331m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/views/dist/img/work_wechat.BCef331m.png -------------------------------------------------------------------------------- /resources/views/dist/js/EsDashbord.DQ8PFQ7Z.js: -------------------------------------------------------------------------------- 1 | import{_ as s}from"./EsDashbord.vue_vue_type_script_setup_true_lang.CAKr5SDJ.js";import"./index.3FmgA6sU.js";import"./el-col.BsOiadIF.js";import"./el-card.R72UYFc_.js";/* empty css */import"./es.B8paRaNL.js";import"./index.Cz0VP9-_.js";export{s as default}; 2 | //# sourceMappingURL=EsDashbord.DQ8PFQ7Z.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/EsDashbord.DQ8PFQ7Z.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"EsDashbord.DQ8PFQ7Z.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} -------------------------------------------------------------------------------- /resources/views/dist/js/SocialSignin.Cx4e1zW9.js: -------------------------------------------------------------------------------- 1 | import{_ as o}from"./index.DMDxf-Di.js";import{c8 as e,e as a,h as i,p as t,C as s,S as r,V as n,l as c}from"./index.3FmgA6sU.js";import{_ as d}from"./_plugin-vue_export-helper.BCo6x5W8.js";const l={class:"social-container"},h={key:0,class:"social-title"},u={class:"social-icons"},p=["onClick"];const m=d({name:"SocialSignin",data:()=>({oauthProviders:[]}),created(){this.getOAuthProviders()},methods:{async getOAuthProviders(){try{const{data:o}=await e();o&&0===o.code&&(this.oauthProviders=o.data.filter((o=>o.enable)))}catch(o){console.error("Failed to load OAuth providers:",o)}},handleLogin(o){const e=encodeURIComponent(`${window.location.origin}/#/auth-redirect`),a=encodeURIComponent(JSON.stringify({redirect:this.$route.query.redirect||"/"}));window.location.href=`/api/oauth/${o.name}/login?redirect_uri=${e}&state=${a}`}}},[["render",function(e,d,m,v,g,f){const _=o;return a(),i("div",l,[g.oauthProviders.length>0?(a(),i("div",h,"第三方登录")):t("",!0),s("div",u,[(a(!0),i(r,null,n(g.oauthProviders,(o=>(a(),i("a",{key:o.name,onClick:e=>f.handleLogin(o)},[c(_,{"icon-class":o.img},null,8,["icon-class"])],8,p)))),128))])])}],["__scopeId","data-v-af045c6a"]]);export{m as default}; 2 | //# sourceMappingURL=SocialSignin.Cx4e1zW9.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/_plugin-vue_export-helper.BCo6x5W8.js: -------------------------------------------------------------------------------- 1 | const o=(o,t)=>{const c=o.__vccOpts||o;for(const[s,n]of t)c[s]=n;return c};export{o as _}; 2 | //# sourceMappingURL=_plugin-vue_export-helper.BCo6x5W8.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/_plugin-vue_export-helper.BCo6x5W8.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"_plugin-vue_export-helper.BCo6x5W8.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} -------------------------------------------------------------------------------- /resources/views/dist/js/api-rbac.CA2SkCO7.js: -------------------------------------------------------------------------------- 1 | import{bf as r}from"./index.3FmgA6sU.js";function o(o){return r({url:"/api/gm_user/UrlConfig",method:"post",data:o})}export{o as U}; 2 | //# sourceMappingURL=api-rbac.CA2SkCO7.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/api-rbac.CA2SkCO7.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"api-rbac.CA2SkCO7.js","sources":["../../../vue/src/api/api-rbac.ts"],"sourcesContent":["import request from '@/utils/request'\n\nvar api = '/api/gm_user/'\n\nexport function UrlConfig(data) {\n return request({\n url: api + 'UrlConfig',\n method: 'post',\n data\n })\n}\n\nexport function SaveRbac(data) {\n return request({\n url: api + 'SaveRbac',\n method: 'post',\n data\n })\n}\n\nexport function RbacList() {\n return request({\n url: api + 'RbacList',\n method: 'post'\n })\n}\n"],"names":["UrlConfig","data","request","url","api","method"],"mappings":"yCAIO,SAASA,EAAUC,GACxB,OAAOC,EAAQ,CACbC,IAAKC,yBACLC,OAAQ,OACPJ,QAEL"} -------------------------------------------------------------------------------- /resources/views/dist/js/config.BqZ2rU3T.js: -------------------------------------------------------------------------------- 1 | import{_ as e}from"./_plugin-vue_export-helper.BCo6x5W8.js";const r=e({},[["render",function(e,r){return null}]]);export{r as default}; 2 | //# sourceMappingURL=config.BqZ2rU3T.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/config.BqZ2rU3T.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"config.BqZ2rU3T.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} -------------------------------------------------------------------------------- /resources/views/dist/js/el-card.R72UYFc_.js: -------------------------------------------------------------------------------- 1 | import{v as s,A as a,d as e,b as t,e as o,h as r,i as d,g as l,k as y,a7 as i,F as f,p as n,C as h,n as v,_ as c,q as p}from"./index.3FmgA6sU.js";const u=s({header:{type:String,default:""},footer:{type:String,default:""},bodyStyle:{type:a([String,Object,Array]),default:""},bodyClass:String,shadow:{type:String,values:["always","hover","never"],default:"always"}}),b=e({name:"ElCard"});const S=p(c(e({...b,props:u,setup(s){const a=t("card");return(s,e)=>(o(),r("div",{class:d([l(a).b(),l(a).is(`${s.shadow}-shadow`)])},[s.$slots.header||s.header?(o(),r("div",{key:0,class:d(l(a).e("header"))},[y(s.$slots,"header",{},(()=>[i(f(s.header),1)]))],2)):n("v-if",!0),h("div",{class:d([l(a).e("body"),s.bodyClass]),style:v(s.bodyStyle)},[y(s.$slots,"default")],6),s.$slots.footer||s.footer?(o(),r("div",{key:1,class:d(l(a).e("footer"))},[y(s.$slots,"footer",{},(()=>[i(f(s.footer),1)]))],2)):n("v-if",!0)],2))}}),[["__file","card.vue"]]));export{S as E}; 2 | //# sourceMappingURL=el-card.R72UYFc_.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/el-divider.DpgZ14tg.js: -------------------------------------------------------------------------------- 1 | import{I as t,v as e,A as i,d as n,b as s,c as o,e as r,h as l,i as a,g as c,k as d,p as u,n as h,_ as g,q as p}from"./index.3FmgA6sU.js";const f=(e,i)=>{if(!t||!e||!i)return!1;const n=e.getBoundingClientRect();let s;return s=i instanceof Element?i.getBoundingClientRect():{top:0,right:window.innerWidth,bottom:window.innerHeight,left:0},n.tops.top&&n.right>s.left&&n.left{let e,i;return"touchend"===t.type?(i=t.changedTouches[0].clientY,e=t.changedTouches[0].clientX):t.type.startsWith("touch")?(i=t.touches[0].clientY,e=t.touches[0].clientX):(i=t.clientY,e=t.clientX),{clientX:e,clientY:i}},y=e({direction:{type:String,values:["horizontal","vertical"],default:"horizontal"},contentPosition:{type:String,values:["left","center","right"],default:"center"},borderStyle:{type:i(String),default:"solid"}}),b=n({name:"ElDivider"});const m=p(g(n({...b,props:y,setup(t){const e=t,i=s("divider"),n=o((()=>i.cssVar({"border-style":e.borderStyle})));return(t,e)=>(r(),l("div",{class:a([c(i).b(),c(i).m(t.direction)]),style:h(c(n)),role:"separator"},[t.$slots.default&&"vertical"!==t.direction?(r(),l("div",{key:0,class:a([c(i).e("text"),c(i).is(t.contentPosition)])},[d(t.$slots,"default")],2)):u("v-if",!0)],6))}}),[["__file","divider.vue"]]));export{m as E,v as g,f as i}; 2 | //# sourceMappingURL=el-divider.DpgZ14tg.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/el-form-item.l0sNRNKZ.js: -------------------------------------------------------------------------------- 1 | 2 | //# sourceMappingURL=el-form-item.l0sNRNKZ.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/el-form-item.l0sNRNKZ.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"el-form-item.l0sNRNKZ.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} -------------------------------------------------------------------------------- /resources/views/dist/js/el-text.Bypy8Vf2.js: -------------------------------------------------------------------------------- 1 | import{v as a,ax as e,d as s,X as t,b as l,c as n,bK as i,e as p,f as r,w as u,k as c,i as m,g as d,n as o,D as f,_ as g,q as y}from"./index.3FmgA6sU.js";const x=a({type:{type:String,values:["primary","success","info","warning","danger",""],default:""},size:{type:String,values:e,default:""},truncated:Boolean,lineClamp:{type:[String,Number]},tag:{type:String,default:"span"}}),b=s({name:"ElText"});const v=y(g(s({...b,props:x,setup(a){const e=a,s=t(),g=l("text"),y=n((()=>[g.b(),g.m(e.type),g.m(s.value),g.is("truncated",e.truncated),g.is("line-clamp",!i(e.lineClamp))]));return(a,e)=>(p(),r(f(a.tag),{class:m(d(y)),style:o({"-webkit-line-clamp":a.lineClamp})},{default:u((()=>[c(a.$slots,"default")])),_:3},8,["class","style"]))}}),[["__file","text.vue"]]));export{v as E}; 2 | //# sourceMappingURL=el-text.Bypy8Vf2.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/es.B8paRaNL.js: -------------------------------------------------------------------------------- 1 | import{bf as t}from"./index.3FmgA6sU.js";const n="/api/es/";function o(o){return t({url:n+"PingAction",method:"post",data:o})}function a(o){return t({url:n+"IndexsCountAction",method:"post",data:o})}function r(o){return t({url:n+"CatAction",method:"post",data:o})}export{r as C,a as I,o as P}; 2 | //# sourceMappingURL=es.B8paRaNL.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/es.B8paRaNL.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"es.B8paRaNL.js","sources":["../../../vue/src/api/es.ts"],"sourcesContent":["import request from '@/utils/request'\n\nconst api = '/api/es/'\n\nexport function PingAction(data) {\n return request({\n url: api + `PingAction`,\n method: 'post',\n data\n })\n}\n\nexport function IndexsCountAction(data) {\n return request({\n url: api + `IndexsCountAction`,\n method: 'post',\n data\n })\n}\n\nexport function CatAction(data) {\n return request({\n url: api + `CatAction`,\n method: 'post',\n data\n })\n}\n"],"names":["api","PingAction","data","request","url","method","IndexsCountAction","CatAction"],"mappings":"yCAEA,MAAMA,EAAM,WAEL,SAASC,EAAWC,GACzB,OAAOC,EAAQ,CACbC,IAAKJ,EAAM,aACXK,OAAQ,OACRH,QAEJ,CAEO,SAASI,EAAkBJ,GAChC,OAAOC,EAAQ,CACbC,IAAKJ,EAAM,oBACXK,OAAQ,OACRH,QAEJ,CAEO,SAASK,EAAUL,GACxB,OAAOC,EAAQ,CACbC,IAAKJ,EAAM,YACXK,OAAQ,OACRH,QAEJ"} -------------------------------------------------------------------------------- /resources/views/dist/js/index.B6fdKp2E.js: -------------------------------------------------------------------------------- 1 | function t(t){return/^(https?:|http?:|mailto:|tel:)/.test(t)}function r(t){if(!t&&"object"!=typeof t)throw new Error("error arguments","deepClone");const e=t.constructor===Array?[]:{};return Object.keys(t).forEach((o=>{t[o]&&"object"==typeof t[o]?e[o]=r(t[o]):e[o]=t[o]})),e}export{r as d,t as i}; 2 | //# sourceMappingURL=index.B6fdKp2E.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/index.BHh4Vwwu.js: -------------------------------------------------------------------------------- 1 | import{_ as r}from"./operater_log.Bmp3Yp6G.js";import"./index.3FmgA6sU.js";import"./el-loading.BfmLw6GA.js";import"./use-dialog.DSeAULj5.js";import"./isUndefined.DgmxjSXK.js";import"./el-pagination.FyRe8rDt.js";import"./el-select.CkmlXTKn.js";import"./el-popper.BzcpLqPh.js";import"./_Uint8Array.BXE-IZF6.js";import"./el-scrollbar.BjxYtaG6.js";import"./index.Cz0VP9-_.js";import"./strings.zoB2amMQ.js";import"./index.Yqe6XU6l.js";/* empty css */import"./el-table-column.WTvCZQDW.js";import"./el-checkbox.rYFi_c9y.js";import"./el-form.YCpBerBb.js";import"./el-card.R72UYFc_.js";import"./el-form-item.l0sNRNKZ.js";import"./api-rbac.CA2SkCO7.js";import"./_plugin-vue_export-helper.BCo6x5W8.js";export{r as default}; 2 | //# sourceMappingURL=index.BHh4Vwwu.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/index.BHh4Vwwu.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.BHh4Vwwu.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} -------------------------------------------------------------------------------- /resources/views/dist/js/index.DMDxf-Di.js: -------------------------------------------------------------------------------- 1 | import{d as e,c as s,e as i,h as t,C as r,g as a,n as l}from"./index.3FmgA6sU.js";import{_ as n}from"./_plugin-vue_export-helper.BCo6x5W8.js";const o=["xlink:href","fill"],p=n(e({__name:"index",props:{prefix:{type:String,default:"icon"},iconClass:{type:String,required:!1,default:""},color:{type:String,default:""},size:{type:String,default:"1em"}},setup(e){const n=e,p=s((()=>`#${n.prefix}-${n.iconClass}`));return(s,n)=>(i(),t("svg",{"aria-hidden":"true",class:"svg-icon",style:l("width:"+e.size+";height:"+e.size)},[r("use",{"xlink:href":a(p),fill:e.color},null,8,o)],4))}}),[["__scopeId","data-v-73782c74"]]);export{p as _}; 2 | //# sourceMappingURL=index.DMDxf-Di.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/index.DMDxf-Di.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.DMDxf-Di.js","sources":["../../../vue/src/components/SvgIcon/index.vue"],"sourcesContent":["\n\n\n\n\n"],"names":["props","__props","symbolId","computed","prefix","iconClass"],"mappings":"sWAWA,MAAMA,EAAQC,EAoBRC,EAAWC,GAAS,IAAM,IAAIH,EAAMI,UAAUJ,EAAMK"} -------------------------------------------------------------------------------- /resources/views/dist/js/index.FgtPyCZj.js: -------------------------------------------------------------------------------- 1 | import{d as a,h as e,b5 as s,aI as r,e as t}from"./index.3FmgA6sU.js";const p=a({__name:"index",setup(a){const p=s(),n=r(),{params:d,query:o}=p,{path:u}=d;return n.replace({path:"/"+u,query:o}),(a,s)=>(t(),e("div"))}});export{p as default}; 2 | //# sourceMappingURL=index.FgtPyCZj.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/index.FgtPyCZj.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.FgtPyCZj.js","sources":["../../../vue/src/views/redirect/index.vue"],"sourcesContent":["\n\n\n"],"names":["route","useRoute","router","useRouter","params","query","path","replace"],"mappings":"yGAOA,MAAMA,EAAQC,IACRC,EAASC,KAETC,OAAEA,EAAQC,MAAAA,GAAUL,GACpBM,KAAEA,GAASF,SAEjBF,EAAOK,QAAQ,CAAED,KAAM,IAAMA,EAAMD"} -------------------------------------------------------------------------------- /resources/views/dist/js/isUndefined.DgmxjSXK.js: -------------------------------------------------------------------------------- 1 | function i(i){return void 0===i}export{i}; 2 | //# sourceMappingURL=isUndefined.DgmxjSXK.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/isUndefined.DgmxjSXK.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"isUndefined.DgmxjSXK.js","sources":["../../../vue/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isUndefined.js"],"sourcesContent":["/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n"],"names":["isUndefined","value"],"mappings":"AAiBA,SAASA,EAAYC,GACnB,YAAiB,IAAVA,CACT","x_google_ignoreList":[0]} -------------------------------------------------------------------------------- /resources/views/dist/js/oauth.CVPlsWaw.js: -------------------------------------------------------------------------------- 1 | import{_ as t}from"./oauth.vue_vue_type_script_setup_true_lang.BHISIm4Y.js";import"./index.3FmgA6sU.js";import"./el-card.R72UYFc_.js";import"./el-tab-pane.ClbpsFZs.js";import"./strings.zoB2amMQ.js";import"./el-form.YCpBerBb.js";import"./_Uint8Array.BXE-IZF6.js";import"./el-form-item.l0sNRNKZ.js";import"./el-switch.F8zLIDGp.js";export{t as default}; 2 | //# sourceMappingURL=oauth.CVPlsWaw.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/oauth.CVPlsWaw.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"oauth.CVPlsWaw.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} -------------------------------------------------------------------------------- /resources/views/dist/js/plugins.B0Y3JA-_.js: -------------------------------------------------------------------------------- 1 | import{bf as t}from"./index.3FmgA6sU.js";var n="/api/plugins/";function a(a){return t({url:n+"PluginMarket",method:"post",data:a})}function o(a){return t({url:n+"GetPluginInfo",method:"post",data:a})}function r(a){return t({url:n+"InstallPlugin",method:"post",data:a})}function u(a){return t({url:n+"StarPlugin",method:"post",data:a})}function e(a){return t({url:n+"ImportEvKey",method:"post",data:a})}function s(a){return t({url:n+"UnInstallPlugin",method:"post",data:a})}function d(a){return t({url:n+"LikeComment",method:"post",data:a})}function i(a){return t({url:n+"ListComments",method:"post",data:a})}function l(a){return t({url:n+"AddComment",method:"post",data:a})}function m(a){return t({url:n+"GetWxArticleList",method:"post",data:a})}function p(a){return t({url:n+"GetLocalPluginList",method:"post",data:a})}export{l as A,m as G,r as I,d as L,a as P,u as S,s as U,p as a,e as b,o as c,i as d}; 2 | //# sourceMappingURL=plugins.B0Y3JA-_.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/refs.CMTy-Ge4.js: -------------------------------------------------------------------------------- 1 | import{ci as o}from"./index.3FmgA6sU.js";const a=(...a)=>c=>{a.forEach((a=>{o(a)?a(c):a.value=c}))};export{a as c}; 2 | //# sourceMappingURL=refs.CMTy-Ge4.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/refs.CMTy-Ge4.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"refs.CMTy-Ge4.js","sources":["../../../vue/node_modules/.pnpm/element-plus@2.7.8_vue@3.4.35_typescript@5.5.4_/node_modules/element-plus/es/utils/vue/refs.mjs"],"sourcesContent":["import '../types.mjs';\nimport { isFunction } from '@vue/shared';\n\nconst composeRefs = (...refs) => {\n return (el) => {\n refs.forEach((ref) => {\n if (isFunction(ref)) {\n ref(el);\n } else {\n ref.value = el;\n }\n });\n };\n};\n\nexport { composeRefs };\n//# sourceMappingURL=refs.mjs.map\n"],"names":["composeRefs","refs","el","forEach","ref","isFunction","value"],"mappings":"yCAGK,MAACA,EAAc,IAAIC,IACdC,IACDD,EAAAE,SAASC,IACRC,EAAWD,GACbA,EAAIF,GAEJE,EAAIE,MAAQJ,CACb,GACF","x_google_ignoreList":[0]} -------------------------------------------------------------------------------- /resources/views/dist/js/strings.zoB2amMQ.js: -------------------------------------------------------------------------------- 1 | import{dE as e}from"./index.3FmgA6sU.js";const a=(e="")=>e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d"),r=a=>e(a);export{r as c,a as e}; 2 | //# sourceMappingURL=strings.zoB2amMQ.js.map 3 | -------------------------------------------------------------------------------- /resources/views/dist/js/strings.zoB2amMQ.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"strings.zoB2amMQ.js","sources":["../../../vue/node_modules/.pnpm/element-plus@2.7.8_vue@3.4.35_typescript@5.5.4_/node_modules/element-plus/es/utils/strings.mjs"],"sourcesContent":["import { capitalize as capitalize$1 } from '@vue/shared';\nexport { camelize, hyphenate, hyphenate as kebabCase } from '@vue/shared';\n\nconst escapeStringRegexp = (string = \"\") => string.replace(/[|\\\\{}()[\\]^$+*?.]/g, \"\\\\$&\").replace(/-/g, \"\\\\x2d\");\nconst capitalize = (str) => capitalize$1(str);\n\nexport { capitalize, escapeStringRegexp };\n//# sourceMappingURL=strings.mjs.map\n"],"names":["escapeStringRegexp","string","replace","capitalize","str","capitalize$1"],"mappings":"yCAGK,MAACA,EAAqB,CAACC,EAAS,KAAOA,EAAOC,QAAQ,sBAAuB,QAAQA,QAAQ,KAAM,SAClGC,EAAcC,GAAQC,EAAaD","x_google_ignoreList":[0]} -------------------------------------------------------------------------------- /resources/views/fs.go: -------------------------------------------------------------------------------- 1 | package views 2 | 3 | import "embed" 4 | 5 | //go:embed dist/*.html 6 | var IndexFileTemplate embed.FS 7 | 8 | //go:embed dist/css/* 9 | var CssFs embed.FS 10 | 11 | //go:embed dist/js/* 12 | var JsFs embed.FS 13 | 14 | //go:embed dist/img/* 15 | var ImgFs embed.FS 16 | 17 | //go:embed dist/favicon.ico 18 | var FaviconFs embed.FS 19 | 20 | func GetFavicon() ([]byte, error) { 21 | return FaviconFs.ReadFile("dist/favicon.ico") 22 | } 23 | -------------------------------------------------------------------------------- /resources/vue/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | # 表示所有文件适用 5 | [*] 6 | charset = utf-8 # 设置文件字符集为 utf-8 7 | end_of_line = lf # 控制换行类型(lf | cr | crlf) 8 | indent_style = space # 缩进风格(tab | space) 9 | indent_size = 2 # 缩进大小 10 | insert_final_newline = true # 始终在文件末尾插入一个新行 11 | 12 | # 表示仅 md 文件适用以下规则 13 | [*.md] 14 | max_line_length = off # 关闭最大行长度限制 15 | trim_trailing_whitespace = false # 关闭末尾空格修剪 16 | -------------------------------------------------------------------------------- /resources/vue/.env.development: -------------------------------------------------------------------------------- 1 | # 应用端口 2 | VITE_APP_PORT = 3200 3 | VITE_ISPROD = false 4 | 5 | VITE_APPVersion = 'test' 6 | VITE_Lang = 'zh-cn' 7 | VITE_APPURL = '' 8 | VITE_APPSubUrl = '' 9 | VITE_WatermarkContent = 'ElasticView' 10 | VITE_APP_API_URL = http://127.0.0.1:8090/ 11 | -------------------------------------------------------------------------------- /resources/vue/.env.production: -------------------------------------------------------------------------------- 1 | # 代理前缀 2 | 3 | VITE_ISPROD = true 4 | VITE_APPURL = '{{.AppUrl}}' 5 | VITE_APPSubUrl = '{{.AppSubUrl}}' 6 | VITE_APPVersion = '{{.Version}}' 7 | VITE_Lang = '{{.Lang}}' 8 | VITE_WatermarkContent = '{{.WatermarkContent}}' 9 | -------------------------------------------------------------------------------- /resources/vue/.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | public 4 | .husky 5 | .vscode 6 | .idea 7 | *.sh 8 | *.md 9 | 10 | src/assets 11 | 12 | .eslintrc.cjs 13 | .prettierrc.cjs 14 | .stylelintrc.cjs 15 | -------------------------------------------------------------------------------- /resources/vue/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | .history 7 | 8 | # Editor directories and files 9 | .idea 10 | *.suo 11 | *.ntvs* 12 | *.njsproj 13 | *.sln 14 | *.local 15 | 16 | package-lock.json 17 | pnpm-lock.yaml 18 | stats.html 19 | -------------------------------------------------------------------------------- /resources/vue/.husky/commit-msg: -------------------------------------------------------------------------------- 1 | npx --no-install commitlint --edit $1 2 | -------------------------------------------------------------------------------- /resources/vue/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npm run lint:lint-staged 2 | -------------------------------------------------------------------------------- /resources/vue/.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | public 4 | .husky 5 | .vscode 6 | .idea 7 | *.sh 8 | *.md 9 | 10 | src/assets 11 | stats.html 12 | -------------------------------------------------------------------------------- /resources/vue/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always) 3 | arrowParens: "always", 4 | // 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false 5 | bracketSameLine: false, 6 | // 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar}) 7 | bracketSpacing: true, 8 | // 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto) 9 | embeddedLanguageFormatting: "auto", 10 | // 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css) 11 | htmlWhitespaceSensitivity: "ignore", 12 | // 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false 13 | insertPragma: false, 14 | // 在 JSX 中使用单引号替代双引号,默认false 15 | jsxSingleQuote: false, 16 | // 每行最多字符数量,超出换行(默认80) 17 | printWidth: 80, 18 | // 超出打印宽度 (always | never | preserve ) 19 | proseWrap: "preserve", 20 | // 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;) 21 | quoteProps: "as-needed", 22 | // 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false 23 | requirePragma: false, 24 | // 结尾添加分号 25 | semi: true, 26 | // 使用单引号 (true:单引号;false:双引号) 27 | singleQuote: false, 28 | // 缩进空格数,默认2个空格 29 | tabWidth: 2, 30 | // 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号 31 | trailingComma: "es5", 32 | // 指定缩进方式,空格或tab,默认false,即使用空格 33 | useTabs: false, 34 | // vue 文件中是否缩进 ", 19 | "" 20 | ], 21 | "description": "Vue3.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/vue/.vscode/vue3.2.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Vue3.2+快速生成模板": { 3 | "scope": "vue", 4 | "prefix": "Vue3.2+", 5 | "body": [ 6 | "", 7 | "", 8 | "", 11 | "", 12 | "", 13 | "" 14 | ], 15 | "description": "Vue3.2+" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/vue/.vscode/vue3.3.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Vue3.3+defineOptions快速生成模板": { 3 | "scope": "vue", 4 | "prefix": "Vue3.3+", 5 | "body": [ 6 | "", 11 | "", 12 | "", 15 | "", 16 | "", 17 | "" 18 | ], 19 | "description": "Vue3.3+defineOptions快速生成模板" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/vue/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-present 有来开源组织 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /resources/vue/licenses/vue-element-admin/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present PanJiaChen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /resources/vue/licenses/vue3-element-admin/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-present 有来开源组织 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /resources/vue/mock/base.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import { createDefineMock } from "vite-plugin-mock-dev-server"; 3 | 4 | export const defineMock = createDefineMock((mock) => { 5 | // 拼接url 6 | mock.url = path.join( 7 | import.meta.env.VITE_APP_BASE_API + "/api/v1/", 8 | mock.url 9 | ); 10 | }); 11 | -------------------------------------------------------------------------------- /resources/vue/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/public/favicon.ico -------------------------------------------------------------------------------- /resources/vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 48 | -------------------------------------------------------------------------------- /resources/vue/src/api/ai.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | var api = '/api/ai/' 4 | 5 | export function SearchBigMode(data: any) { 6 | return request({ 7 | url: api + 'SearchBigMode', 8 | method: 'post', 9 | data 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /resources/vue/src/api/api-rbac.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | var api = '/api/gm_user/' 4 | 5 | export function UrlConfig(data) { 6 | return request({ 7 | url: api + 'UrlConfig', 8 | method: 'post', 9 | data 10 | }) 11 | } 12 | 13 | export function SaveRbac(data) { 14 | return request({ 15 | url: api + 'SaveRbac', 16 | method: 'post', 17 | data 18 | }) 19 | } 20 | 21 | export function RbacList() { 22 | return request({ 23 | url: api + 'RbacList', 24 | method: 'post' 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /resources/vue/src/api/auth.ts: -------------------------------------------------------------------------------- 1 | import request from "@/utils/request"; 2 | 3 | class AuthAPI { 4 | /** 登录 接口*/ 5 | static login(data: LoginData) { 6 | return request({ 7 | url: `/api/gm_user/login`, 8 | method: "post", 9 | data: data, 10 | }); 11 | } 12 | 13 | /** 注销 接口*/ 14 | static logout() { 15 | return request({ 16 | url: `/api/gm_user/logout`, 17 | method: "delete", 18 | }); 19 | } 20 | 21 | } 22 | 23 | export default AuthAPI; 24 | 25 | /** 登录请求参数 */ 26 | export interface LoginData { 27 | /** 用户名 */ 28 | username: string; 29 | /** 密码 */ 30 | password: string; 31 | } 32 | -------------------------------------------------------------------------------- /resources/vue/src/api/es.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | const api = '/api/es/' 4 | 5 | export function PingAction(data) { 6 | return request({ 7 | url: api + `PingAction`, 8 | method: 'post', 9 | data 10 | }) 11 | } 12 | 13 | export function IndexsCountAction(data) { 14 | return request({ 15 | url: api + `IndexsCountAction`, 16 | method: 'post', 17 | data 18 | }) 19 | } 20 | 21 | export function CatAction(data) { 22 | return request({ 23 | url: api + `CatAction`, 24 | method: 'post', 25 | data 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /resources/vue/src/api/i18n.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | 4 | export function GetI18nCfg(data) { 5 | return request({ 6 | url: '/api/GetI18nCfg', 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /resources/vue/src/api/notice.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | const api = '/api/notice/' 4 | 5 | export function GetList(data) { 6 | return request({ 7 | url: api + `GetList`, 8 | method: 'post', 9 | data 10 | }) 11 | } 12 | 13 | export function MarkReadNotice(data) { 14 | return request({ 15 | url: api + `MarkReadNotice`, 16 | method: 'post', 17 | data 18 | }) 19 | } 20 | 21 | export function Truncate(data) { 22 | return request({ 23 | url: api + `Truncate`, 24 | method: 'post', 25 | data 26 | }) 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /resources/vue/src/api/operate.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getList(data) { 4 | return request({ 5 | url: '/api/operater_log/ListAction', 6 | method: 'post', 7 | data 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /resources/vue/src/api/plugin.js: -------------------------------------------------------------------------------- 1 | import request from "@/utils/request"; 2 | 3 | export function CallPluginApi(req) { 4 | let pluginId = req.pluginAlias 5 | let path = req.url 6 | let method = req.method 7 | let header = req.header 8 | let data = req.data 9 | let responseType = req.responseType 10 | let transformResponse = req.transformResponse 11 | console.log("req",req) 12 | if (path[0] !== '/'){ 13 | path = `/${path}` 14 | } 15 | 16 | method = method.toLowerCase() 17 | 18 | let cfg = { 19 | url: `/api/call_plugin/${pluginId}${path}`, 20 | method: method, 21 | responseType:responseType, 22 | } 23 | 24 | if (method == "post"){ 25 | cfg.data = data 26 | }else{ 27 | cfg.params = data 28 | } 29 | if (req.hasOwnProperty("transformResponse") ){ 30 | cfg.transformResponse = transformResponse 31 | } 32 | 33 | if (req.hasOwnProperty("header") && Object.keys(headers).length > 0 ){ 34 | cfg.header = header 35 | } 36 | 37 | return request(cfg) 38 | } 39 | -------------------------------------------------------------------------------- /resources/vue/src/api/role.ts: -------------------------------------------------------------------------------- 1 | import request from "@/utils/request"; 2 | 3 | export function getRoles(data) { 4 | return request({ 5 | url: '/api/gm_user/roles', 6 | method: 'post', 7 | data 8 | }) 9 | } 10 | 11 | export function addRole(data) { 12 | return request({ 13 | url: '/api/gm_user/role/add', 14 | method: 'post', 15 | data 16 | }) 17 | } 18 | 19 | export function updateRole(data) { 20 | return request({ 21 | url: `/api/gm_user/role/update`, 22 | method: 'post', 23 | data 24 | }) 25 | } 26 | 27 | export function deleteRole(data) { 28 | 29 | return request({ 30 | url: `/api/gm_user/role/delete`, 31 | method: 'post', 32 | data 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/backtop.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/cascader.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/client.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/close_all.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/close_left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/close_other.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/close_right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/collapse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/document.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/fullscreen-exit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/fullscreen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/homepage.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/ip.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/language.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/monitor.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/pv.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/refresh.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/role.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/setting.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/size.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/system.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/user.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/vue/src/assets/icons/uv.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/vue/src/assets/images/401.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/401.gif -------------------------------------------------------------------------------- /resources/vue/src/assets/images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/404.png -------------------------------------------------------------------------------- /resources/vue/src/assets/images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/404_cloud.png -------------------------------------------------------------------------------- /resources/vue/src/assets/images/login-background-dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/login-background-dark.jpg -------------------------------------------------------------------------------- /resources/vue/src/assets/images/login-background-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/login-background-light.jpg -------------------------------------------------------------------------------- /resources/vue/src/assets/images/login_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/login_bg.png -------------------------------------------------------------------------------- /resources/vue/src/assets/images/login_bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/login_bg2.png -------------------------------------------------------------------------------- /resources/vue/src/assets/images/login_dark_bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/login_dark_bg2.png -------------------------------------------------------------------------------- /resources/vue/src/assets/images/social_dingtalk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/social_dingtalk.png -------------------------------------------------------------------------------- /resources/vue/src/assets/images/social_lark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/social_lark.png -------------------------------------------------------------------------------- /resources/vue/src/assets/images/work_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/images/work_wechat.png -------------------------------------------------------------------------------- /resources/vue/src/assets/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/logo.jpg -------------------------------------------------------------------------------- /resources/vue/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/logo.png -------------------------------------------------------------------------------- /resources/vue/src/assets/zsxq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1340691923/ElasticView/66d401ea88d4fe125700b0c5a92749540149c667/resources/vue/src/assets/zsxq.jpg -------------------------------------------------------------------------------- /resources/vue/src/components/AppLink/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 39 | -------------------------------------------------------------------------------- /resources/vue/src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 28 | 29 | 40 | -------------------------------------------------------------------------------- /resources/vue/src/components/LangSelect/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 48 | -------------------------------------------------------------------------------- /resources/vue/src/components/MarkDownView/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 27 | -------------------------------------------------------------------------------- /resources/vue/src/components/SizeSelect/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 39 | -------------------------------------------------------------------------------- /resources/vue/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 34 | 35 | 46 | -------------------------------------------------------------------------------- /resources/vue/src/directive/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from "vue"; 2 | 3 | import { hasPerm } from "./permission"; 4 | 5 | // 全局注册 directive 6 | export function setupDirective(app: App) { 7 | // 使 v-hasPerm 在所有组件中都可用 8 | app.directive("hasPerm", hasPerm); 9 | } 10 | -------------------------------------------------------------------------------- /resources/vue/src/directive/permission/index.ts: -------------------------------------------------------------------------------- 1 | import { hasAuth } from "@/plugins/permission"; 2 | import { Directive, DirectiveBinding } from "vue"; 3 | 4 | /** 5 | * 按钮权限 6 | */ 7 | export const hasPerm: Directive = { 8 | mounted(el: HTMLElement, binding: DirectiveBinding) { 9 | // DOM绑定需要的按钮权限标识 10 | const { value: requiredPerms } = binding; 11 | if (requiredPerms) { 12 | if (!hasAuth(requiredPerms)) { 13 | el.parentNode && el.parentNode.removeChild(el); 14 | } 15 | } else { 16 | throw new Error( 17 | "need perms! Like v-has-perm=\"['sys:user:add','sys:user:edit']\"" 18 | ); 19 | } 20 | }, 21 | }; 22 | 23 | /** 24 | * 权限组权限 25 | */ 26 | export const hasRole: Directive = { 27 | mounted(el: HTMLElement, binding: DirectiveBinding) { 28 | // DOM绑定需要的权限组编码 29 | const { value: requiredRoles } = binding; 30 | if (requiredRoles) { 31 | if (!hasAuth(requiredRoles, "role")) { 32 | el.parentNode && el.parentNode.removeChild(el); 33 | } 34 | } else { 35 | throw new Error("need roles! Like v-has-role=\"['admin','test']\""); 36 | } 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /resources/vue/src/enums/CacheEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 令牌缓存Key 3 | */ 4 | export const TOKEN_KEY = "accessToken"; 5 | -------------------------------------------------------------------------------- /resources/vue/src/enums/DeviceEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 设备枚举 3 | */ 4 | export const enum DeviceEnum { 5 | /** 6 | * 宽屏设备 7 | */ 8 | DESKTOP = "desktop", 9 | 10 | /** 11 | * 窄屏设备 12 | */ 13 | MOBILE = "mobile", 14 | } 15 | -------------------------------------------------------------------------------- /resources/vue/src/enums/LanguageEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 语言枚举 3 | */ 4 | export const enum LanguageEnum { 5 | /** 6 | * 中文 7 | */ 8 | ZH_CN = "zh-cn", 9 | 10 | /** 11 | * 英文 12 | */ 13 | EN = "en", 14 | } 15 | -------------------------------------------------------------------------------- /resources/vue/src/enums/LayoutEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 菜单布局枚举 3 | */ 4 | export const enum LayoutEnum { 5 | /** 6 | * 左侧菜单布局 7 | */ 8 | LEFT = "left", 9 | /** 10 | * 顶部菜单布局 11 | */ 12 | TOP = "top", 13 | 14 | /** 15 | * 混合菜单布局 16 | */ 17 | MIX = "mix", 18 | } 19 | -------------------------------------------------------------------------------- /resources/vue/src/enums/MenuTypeEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 菜单类型枚举 3 | */ 4 | export const enum MenuTypeEnum { 5 | /** 6 | * 目录 7 | */ 8 | CATALOG = "CATALOG", 9 | /** 10 | * 菜单 11 | */ 12 | MENU = "MENU", 13 | 14 | /** 15 | * 按钮 16 | */ 17 | BUTTON = "BUTTON", 18 | /** 19 | * 外链 20 | */ 21 | EXTLINK = "EXTLINK", 22 | } 23 | -------------------------------------------------------------------------------- /resources/vue/src/enums/MessageTypeEnum.ts: -------------------------------------------------------------------------------- 1 | /* 消息类型枚举 */ 2 | export const enum MessageTypeEnum { 3 | /* 消息 */ 4 | MESSAGE = "MESSAGE", 5 | /* 通知 */ 6 | NOTICE = "NOTICE", 7 | /* 待办 */ 8 | TODO = "TODO", 9 | } 10 | 11 | export const MessageTypeLabels = { 12 | [MessageTypeEnum.MESSAGE]: "消息", 13 | [MessageTypeEnum.NOTICE]: "通知", 14 | [MessageTypeEnum.TODO]: "待办", 15 | }; 16 | -------------------------------------------------------------------------------- /resources/vue/src/enums/NoticeTypeEnum.ts: -------------------------------------------------------------------------------- 1 | /* 通知类型枚举 */ 2 | export const enum NoticeTypeEnum { 3 | /** 系统升级 */ 4 | SYSTEM_UPGRADE = "SYSTEM_UPGRADE", 5 | /** 系统维护 */ 6 | SYSTEM_MAINTENANCE = "SYSTEM_MAINTENANCE", 7 | /** 安全警告 */ 8 | SECURITY_ALERT = "SECURITY_ALERT", 9 | /** 假期通知 */ 10 | HOLIDAY_NOTICE = "HOLIDAY_NOTICE", 11 | /** 公司新闻 */ 12 | COMPANY_NEWS = "COMPANY_NEWS", 13 | /** 其他通知 */ 14 | OTHER = "OTHER", 15 | } 16 | 17 | // 定义标签映射 18 | const NoticeTypeLabels: Record = { 19 | [NoticeTypeEnum.SYSTEM_UPGRADE]: "系统升级", 20 | [NoticeTypeEnum.SYSTEM_MAINTENANCE]: "系统维护", 21 | [NoticeTypeEnum.SECURITY_ALERT]: "安全警告", 22 | [NoticeTypeEnum.HOLIDAY_NOTICE]: "假期通知", 23 | [NoticeTypeEnum.COMPANY_NEWS]: "公司新闻", 24 | [NoticeTypeEnum.OTHER]: "其他通知", 25 | }; 26 | 27 | // 导出获取标签函数 28 | export const getNoticeLabel = (type: NoticeTypeEnum): string => { 29 | return NoticeTypeLabels[type] || ""; 30 | }; 31 | -------------------------------------------------------------------------------- /resources/vue/src/enums/ResultEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 响应码枚举 3 | */ 4 | export const enum ResultEnum { 5 | /** 6 | * 成功 7 | */ 8 | SUCCESS = "00000", 9 | /** 10 | * 错误 11 | */ 12 | ERROR = "B0001", 13 | 14 | /** 15 | * 令牌无效或过期 16 | */ 17 | TOKEN_INVALID = "A0230", 18 | } 19 | -------------------------------------------------------------------------------- /resources/vue/src/enums/SidebarStatusEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 侧边栏状态枚举 3 | */ 4 | export const enum SidebarStatusEnum { 5 | /** 6 | * 展开 7 | */ 8 | OPENED = "opened", 9 | 10 | /** 11 | * 关闭 12 | */ 13 | CLOSED = "closed", 14 | } 15 | -------------------------------------------------------------------------------- /resources/vue/src/enums/SizeEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 布局大小枚举 3 | */ 4 | export const enum SizeEnum { 5 | /** 6 | * 默认 7 | */ 8 | DEFAULT = "default", 9 | 10 | /** 11 | * 大型 12 | */ 13 | LARGE = "large", 14 | 15 | /** 16 | * 小型 17 | */ 18 | SMALL = "small", 19 | } 20 | -------------------------------------------------------------------------------- /resources/vue/src/enums/ThemeEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 主题枚举 3 | */ 4 | export const enum ThemeEnum { 5 | /** 6 | * 明亮主题 7 | */ 8 | LIGHT = "light", 9 | /** 10 | * 暗黑主题 11 | */ 12 | DARK = "dark", 13 | 14 | /** 15 | * 系统自动 16 | */ 17 | AUTO = "auto", 18 | } 19 | 20 | 21 | /** 22 | * 浅色主题下的侧边栏配色方案枚举 23 | */ 24 | export const enum SidebarLightThemeEnum { 25 | /** 26 | * 深蓝色 27 | */ 28 | DARKBLUE = "light-darkBlue", 29 | /** 30 | * 白色 31 | */ 32 | WHITE = "light-white", 33 | } 34 | -------------------------------------------------------------------------------- /resources/vue/src/icons/svg/feishu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /resources/vue/src/layout/components/NavBar/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 25 | 26 | 34 | -------------------------------------------------------------------------------- /resources/vue/src/layout/components/Settings/components/ThemeColorPicker.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 36 | 37 | 42 | -------------------------------------------------------------------------------- /resources/vue/src/layout/components/Sidebar/components/SidebarMenuItemTitle.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 36 | 37 | 59 | -------------------------------------------------------------------------------- /resources/vue/src/layout/components/Sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 31 | 32 | 39 | -------------------------------------------------------------------------------- /resources/vue/src/plugins/icons.ts: -------------------------------------------------------------------------------- 1 | import type { App } from "vue"; 2 | import * as ElementPlusIconsVue from "@element-plus/icons-vue"; 3 | 4 | // 注册所有图标 5 | export function setupElIcons(app: App) { 6 | for (const [key, component] of Object.entries(ElementPlusIconsVue)) { 7 | app.component(key, component); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /resources/vue/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | import { setupDirective } from "@/directive"; 2 | import { setupRouter } from "@/router"; 3 | import { setupStore } from "@/store"; 4 | import type { App } from "vue"; 5 | import { setupElIcons } from "./icons"; 6 | import { setupPermission } from "./permission"; 7 | 8 | export default { 9 | async install(app: App) { 10 | // 自定义指令(directive) 11 | setupDirective(app); 12 | // 路由(router) 13 | 14 | // 状态管理(store) 15 | await setupStore(app); 16 | 17 | // 国际化 18 | //setupI18n(app); 19 | // Element-plus图标 20 | setupElIcons(app); 21 | 22 | 23 | setupRouter(app); 24 | // 路由守卫 25 | setupPermission(); 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /resources/vue/src/settings.ts: -------------------------------------------------------------------------------- 1 | import { SizeEnum } from "./enums/SizeEnum"; 2 | import { LayoutEnum } from "./enums/LayoutEnum"; 3 | import { ThemeEnum } from "./enums/ThemeEnum"; 4 | import { LanguageEnum } from "./enums/LanguageEnum"; 5 | 6 | const { pkg } = __APP_INFO__; 7 | 8 | const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); 9 | 10 | const defaultSettings: AppSettings = { 11 | title: pkg.name, 12 | version: pkg.version, 13 | showSettings: true, 14 | tagsView: true, 15 | fixedHeader: true, 16 | sidebarLogo: true, 17 | layout: LayoutEnum.MIX, 18 | theme: mediaQueryList.matches ? ThemeEnum.DARK : ThemeEnum.LIGHT, 19 | size: SizeEnum.DEFAULT, 20 | language: LanguageEnum.ZH_CN, 21 | themeColor: "#409EFF", 22 | watermarkEnabled: false, 23 | watermarkContent: pkg.name, 24 | sidebarColorScheme: "light-white", 25 | }; 26 | 27 | export default defaultSettings; 28 | -------------------------------------------------------------------------------- /resources/vue/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from "vue"; 2 | import { createPinia } from "pinia"; 3 | 4 | const store = createPinia(); 5 | 6 | // 全局注册 store 7 | export function setupStore(app: App) { 8 | app.use(store); 9 | } 10 | 11 | export * from "./modules/app"; 12 | export * from "./modules/permission"; 13 | export * from "./modules/settings"; 14 | export * from "./modules/tagsView"; 15 | export * from "./modules/user"; 16 | export * from "./modules/notice"; 17 | export { store }; 18 | -------------------------------------------------------------------------------- /resources/vue/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @use "./reset"; 2 | 3 | .app-container { 4 | padding: 15px; 5 | } 6 | 7 | .search-container { 8 | padding: 18px 0 0 10px; 9 | margin-bottom: 10px; 10 | background-color: var(--el-bg-color-overlay); 11 | border: 1px solid var(--el-border-color-light); 12 | border-radius: 4px; 13 | box-shadow: var(--el-box-shadow-light); 14 | } 15 | 16 | .table-container > .el-card__header { 17 | padding: calc(var(--el-card-padding) - 8px) var(--el-card-padding); 18 | } 19 | 20 | .link-type, 21 | .link-type:focus { 22 | color: #337ab7; 23 | cursor: pointer; 24 | 25 | &:hover { 26 | color: rgb(32 160 255); 27 | } 28 | } 29 | 30 | .el-message { 31 | top: 60px !important; 32 | } 33 | -------------------------------------------------------------------------------- /resources/vue/src/styles/reset.scss: -------------------------------------------------------------------------------- 1 | *, 2 | ::before, 3 | ::after { 4 | box-sizing: border-box; 5 | border-color: currentcolor; 6 | border-style: solid; 7 | border-width: 0; 8 | } 9 | 10 | #app { 11 | width: 100%; 12 | height: 100%; 13 | } 14 | 15 | html { 16 | box-sizing: border-box; 17 | width: 100%; 18 | height: 100%; 19 | line-height: 1.5; 20 | tab-size: 4; 21 | text-size-adjust: 100%; 22 | } 23 | 24 | body { 25 | width: 100%; 26 | height: 100%; 27 | margin: 0; 28 | font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", 29 | "Microsoft YaHei", "微软雅黑", Arial, sans-serif; 30 | line-height: inherit; 31 | -moz-osx-font-smoothing: grayscale; 32 | -webkit-font-smoothing: antialiased; 33 | text-rendering: optimizelegibility; 34 | } 35 | 36 | a { 37 | color: inherit; 38 | text-decoration: inherit; 39 | } 40 | 41 | img, 42 | svg { 43 | display: inline-block; 44 | } 45 | 46 | svg { 47 | // 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 48 | vertical-align: -0.15em; 49 | } 50 | 51 | ul, 52 | li { 53 | padding: 0; 54 | margin: 0; 55 | list-style: none; 56 | } 57 | 58 | *, 59 | *::before, 60 | *::after { 61 | box-sizing: inherit; 62 | } 63 | 64 | a, 65 | a:focus, 66 | a:hover { 67 | color: inherit; 68 | text-decoration: none; 69 | cursor: pointer; 70 | } 71 | 72 | a:focus, 73 | a:active, 74 | div:focus { 75 | outline: none; 76 | } 77 | -------------------------------------------------------------------------------- /resources/vue/src/styles/variables.module.scss: -------------------------------------------------------------------------------- 1 | /* stylelint-disable property-no-unknown */ 2 | :export { 3 | sidebar-width: $sidebar-width; 4 | navbar-height: $navbar-height; 5 | tags-view-height: $tags-view-height; 6 | menu-background: $menu-background; 7 | menu-text: $menu-text; 8 | menu-active-text: $menu-active-text; 9 | menu-hover: $menu-hover; 10 | } 11 | /* stylelint-enable property-no-unknown */ 12 | -------------------------------------------------------------------------------- /resources/vue/src/types/env.d.ts: -------------------------------------------------------------------------------- 1 | // https://cn.vitejs.dev/guide/env-and-mode 2 | 3 | declare module "*.vue" { 4 | import { DefineComponent } from "vue"; 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 6 | const component: DefineComponent<{}, {}, any>; 7 | export default component; 8 | } 9 | 10 | // TypeScript 类型提示都为 string: https://github.com/vitejs/vite/issues/6930 11 | interface ImportMetaEnv { 12 | /** 应用端口 */ 13 | VITE_APP_PORT: number; 14 | /** API 基础路径(代理前缀) */ 15 | VITE_APP_BASE_API: string; 16 | /** API 地址 */ 17 | VITE_APP_API_URL: string; 18 | /** 是否开启 Mock 服务 */ 19 | VITE_MOCK_DEV_SERVER: boolean; 20 | } 21 | 22 | interface ImportMeta { 23 | readonly env: ImportMetaEnv; 24 | } 25 | 26 | /** 27 | * 平台的名称、版本、运行所需的`node`版本、依赖、构建时间的类型提示 28 | */ 29 | declare const __APP_INFO__: { 30 | pkg: { 31 | name: string; 32 | version: string; 33 | engines: { 34 | node: string; 35 | }; 36 | dependencies: Record; 37 | devDependencies: Record; 38 | }; 39 | buildTimestamp: number; 40 | }; 41 | -------------------------------------------------------------------------------- /resources/vue/src/types/router.d.ts: -------------------------------------------------------------------------------- 1 | import "vue-router"; 2 | 3 | declare module "vue-router" { 4 | // https://router.vuejs.org/zh/guide/advanced/meta.html#typescript 5 | // 可以通过扩展 RouteMeta 接口来输入 meta 字段 6 | interface RouteMeta { 7 | /** 8 | * 菜单名称 9 | * @example 'Dashboard' 10 | */ 11 | title?: string; 12 | 13 | /** 14 | * 菜单图标 15 | * @example 'el-icon-edit' 16 | */ 17 | icon?: string; 18 | 19 | /** 20 | * 是否隐藏菜单项 21 | * true 隐藏, false 显示 22 | * @default false 23 | */ 24 | hidden?: boolean; 25 | 26 | /** 27 | * 始终显示父级菜单,即使只有一个子菜单 28 | * true 显示父级菜单, false 隐藏父级菜单,显示唯一子节点 29 | * @default false 30 | */ 31 | alwaysShow?: boolean; 32 | 33 | /** 34 | * 是否固定在页签上 35 | * true 固定, false 不固定 36 | * @default false 37 | */ 38 | affix?: boolean; 39 | 40 | /** 41 | * 是否缓存页面 42 | * true 缓存, false 不缓存 43 | * @default false 44 | */ 45 | keepAlive?: boolean; 46 | 47 | /** 48 | * 是否在面包屑导航中隐藏 49 | * true 隐藏, false 显示 50 | * @default false 51 | */ 52 | breadcrumb?: boolean; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /resources/vue/src/types/socket.d.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/sockjs/sockjs-client/issues/565 2 | 3 | declare module "sockjs-client/dist/sockjs.min.js" { 4 | import Client from "sockjs-client"; 5 | export default Client; 6 | } 7 | -------------------------------------------------------------------------------- /resources/vue/src/utils/auth.ts: -------------------------------------------------------------------------------- 1 | // 鉴权 token 相关函数 2 | 3 | const TokenKey = 'Admin-Token' 4 | 5 | export function getToken() { 6 | // return Cookies.get(TokenKey) 7 | return localStorage.getItem(TokenKey) 8 | } 9 | 10 | export function setToken(token) { 11 | return localStorage.setItem(TokenKey, token) 12 | } 13 | 14 | 15 | export function removeToken() { 16 | return localStorage.removeItem(TokenKey) 17 | } 18 | -------------------------------------------------------------------------------- /resources/vue/src/utils/clipboard.ts: -------------------------------------------------------------------------------- 1 | import { useClipboard,usePermission } from "@vueuse/core"; 2 | import {ElMessage} from "element-plus"; 3 | 4 | const clipboardSuccess = (text: any) => { 5 | 6 | ElMessage({ 7 | type: 'success',offset:32, 8 | message: `拷贝成功` 9 | }) 10 | } 11 | 12 | const clipboardError = (text: any) => { 13 | 14 | ElMessage({ 15 | type: 'error',offset:32, 16 | message: `拷贝${text}失败` 17 | }) 18 | } 19 | 20 | export default function handleClipboard(text: string) { 21 | const { isSupported, copy } = useClipboard() 22 | if (!isSupported) usePermission('clipboard-write') 23 | 24 | copy(text) 25 | .then(() => { 26 | clipboardSuccess(text) 27 | }) 28 | .catch(() => { 29 | clipboardError(text) 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /resources/vue/src/utils/es_link.ts: -------------------------------------------------------------------------------- 1 | export function SaveEsConnect(link){ 2 | sessionStorage.setItem('EsConnect', link) 3 | } 4 | 5 | export function GetEsConnect(){ 6 | let esConnect = sessionStorage.getItem('EsConnect') 7 | if(esConnect) { 8 | return Number(esConnect) 9 | } 10 | if(esConnect == null){ 11 | esConnect = 0 12 | } 13 | return esConnect 14 | } 15 | 16 | export function SaveEsConnectVer(ver){ 17 | sessionStorage.setItem('EsConnVersion', ver) 18 | } 19 | 20 | export function GetEsConnectVer(){ 21 | let esConnectVer = sessionStorage.getItem('EsConnVersion') 22 | if(esConnectVer) { 23 | return esConnectVer 24 | } 25 | if(esConnectVer == null || esConnectVer == undefined){ 26 | esConnectVer = "" 27 | } 28 | return esConnectVer 29 | } 30 | -------------------------------------------------------------------------------- /resources/vue/src/utils/i18n.ts: -------------------------------------------------------------------------------- 1 | 2 | export function translateRouteTitle(title: any) { 3 | const { te,t } = useI18n() 4 | // 判断是否存在国际化配置,如果没有原生返回 5 | const hasKey = te(title); 6 | if (hasKey) { 7 | const translatedTitle = t(title); 8 | return translatedTitle; 9 | } 10 | return title; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /resources/vue/src/utils/monaco.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'; 2 | import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution'; 3 | import 'monaco-editor/esm/vs/basic-languages/markdown/markdown.contribution'; 4 | import 'monaco-editor/esm/vs/editor/editor.all.js'; 5 | 6 | import 'monaco-editor/esm/vs/language/typescript/monaco.contribution'; 7 | import 'monaco-editor/esm/vs/language/json/monaco.contribution'; 8 | 9 | import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'; 10 | import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'; 11 | import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'; 12 | import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'; 13 | import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'; 14 | 15 | // @ts-ignore 16 | self.MonacoEnvironment = { 17 | getWorker(_, label) { 18 | if (label === 'json') { 19 | return new jsonWorker(); 20 | } 21 | if (label === 'css' || label === 'scss' || label === 'less') { 22 | return new cssWorker(); 23 | } 24 | if (label === 'html' || label === 'handlebars' || label === 'razor') { 25 | return new htmlWorker(); 26 | } 27 | if (label === 'typescript' || label === 'javascript') { 28 | return new tsWorker(); 29 | } 30 | return new editorWorker(); 31 | }, 32 | }; 33 | 34 | export { monaco }; 35 | -------------------------------------------------------------------------------- /resources/vue/src/utils/nprogress.ts: -------------------------------------------------------------------------------- 1 | import NProgress from "nprogress"; 2 | import "nprogress/nprogress.css"; 3 | 4 | // 进度条 5 | NProgress.configure({ 6 | // 动画方式 7 | easing: "ease", 8 | // 递增进度条的速度 9 | speed: 500, 10 | // 是否显示加载ico 11 | showSpinner: false, 12 | // 自动递增间隔 13 | trickleSpeed: 200, 14 | // 初始化时的最小百分比 15 | minimum: 0.3, 16 | }); 17 | 18 | export default NProgress; 19 | -------------------------------------------------------------------------------- /resources/vue/src/utils/ui.ts: -------------------------------------------------------------------------------- 1 | export function Message(){ 2 | 3 | } 4 | -------------------------------------------------------------------------------- /resources/vue/src/views/ai/config.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /resources/vue/src/views/redirect/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 16 | -------------------------------------------------------------------------------- /resources/vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "noLib": false, 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "esModuleInterop": true, 12 | "lib": ["esnext", "dom"], 13 | "baseUrl": ".", 14 | "allowJs": true, 15 | "skipLibCheck": true, 16 | "allowSyntheticDefaultImports": true, 17 | "forceConsistentCasingInFileNames": true, 18 | "jsx": "preserve", 19 | "jsxFactory": "h", 20 | "jsxFragmentFactory": "Fragment", 21 | "paths": { 22 | "@/*": ["src/*"] 23 | }, 24 | "types": ["vite/client", "unplugin-icons/types/vue", "element-plus/global"] 25 | }, 26 | "include": ["mock/**/*.ts", "src/**/*.ts", "src/**/*.vue", "vite.config.ts"], 27 | "exclude": ["node_modules", "dist", "**/*.js"] 28 | } 29 | -------------------------------------------------------------------------------- /resources/vue/uno.config.ts: -------------------------------------------------------------------------------- 1 | // uno.config.ts 2 | import { 3 | defineConfig, 4 | presetAttributify, 5 | presetIcons, 6 | presetTypography, 7 | presetUno, 8 | presetWebFonts, 9 | transformerDirectives, 10 | transformerVariantGroup, 11 | } from "unocss"; 12 | 13 | export default defineConfig({ 14 | shortcuts: { 15 | "flex-center": "flex justify-center items-center", 16 | "flex-x-center": "flex justify-center", 17 | "flex-y-center": "flex items-center", 18 | "wh-full": "w-full h-full", 19 | "flex-x-between": "flex items-center justify-between", 20 | "flex-x-end": "flex items-center justify-end", 21 | "absolute-lt": "absolute left-0 top-0", 22 | "absolute-rt": "absolute right-0 top-0 ", 23 | "fixed-lt": "fixed left-0 top-0", 24 | }, 25 | theme: { 26 | colors: { 27 | primary: "var(--el-color-primary)", 28 | primary_dark: "var(--el-color-primary-light-5)", 29 | }, 30 | }, 31 | presets: [ 32 | presetUno(), 33 | presetAttributify(), 34 | presetIcons(), 35 | presetTypography(), 36 | presetWebFonts({ 37 | fonts: { 38 | // ... 39 | }, 40 | }), 41 | ], 42 | transformers: [transformerDirectives(), transformerVariantGroup()], 43 | }); 44 | -------------------------------------------------------------------------------- /testing/logs/ev/info.log.20241022: -------------------------------------------------------------------------------- 1 | 2024-10-22 17:11:32 sqlstore/orm.go:42 sqlStore组件初始化成功 2 | 2024-10-22 17:12:28 sqlstore/orm.go:42 sqlStore组件初始化成功 3 | 2024-10-22 17:12:28 svr_log/svr_log.go:70 D:/eve/ev2/pkg/infrastructure/dao/gm_role_eslink_cfg_v2.go:36 4 | [1.097ms] [rows:0] SELECT * FROM `gm_role_eslink_cfg_v2` WHERE role_id = 1 5 | 2024-10-22 17:13:48 sqlstore/orm.go:42 sqlStore组件初始化成功 6 | 2024-10-22 17:13:48 svr_log/svr_log.go:70 D:/eve/ev2/pkg/infrastructure/dao/gm_role_eslink_cfg_v2.go:36 7 | [0.519ms] [rows:0] SELECT * FROM `gm_role_eslink_cfg_v2` WHERE role_id = 1 8 | 2024-10-22 17:14:55 sqlstore/orm.go:42 sqlStore组件初始化成功 9 | 2024-10-22 17:14:55 svr_log/svr_log.go:70 D:/eve/ev2/pkg/infrastructure/dao/gm_role_eslink_cfg_v2.go:36 10 | [1.594ms] [rows:0] SELECT * FROM `gm_role_eslink_cfg_v2` WHERE role_id = 1 11 | 2024-10-22 17:16:14 sqlstore/orm.go:42 sqlStore组件初始化成功 12 | 2024-10-22 17:16:14 svr_log/svr_log.go:68 D:/eve/ev2/pkg/infrastructure/dao/gm_role_eslink_cfg_v2.go:37 13 | [0.000ms] [rows:-] show tables 14 | 2024-10-22 17:16:14 svr_log/svr_log.go:70 D:/eve/ev2/pkg/infrastructure/dao/gm_role_eslink_cfg_v2.go:39 15 | [1.143ms] [rows:0] SELECT * FROM `gm_role_eslink_cfg_v2` WHERE role_id = 1 16 | --------------------------------------------------------------------------------