├── src-chrome ├── Readme.md ├── icons │ └── logo_200.png ├── doc │ └── multiple-es-head-bookmarks.png ├── _locales │ ├── zh_CN │ │ └── messages.json │ ├── ja │ │ └── messages.json │ ├── zh_TW │ │ └── messages.json │ ├── en │ │ └── messages.json │ └── de │ │ └── messages.json ├── src │ └── background.js └── manifest.json ├── src-edge ├── Readme.md ├── icons │ └── logo_200.png ├── doc │ └── multiple-es-head-bookmarks.png ├── _locales │ ├── zh_CN │ │ └── messages.json │ ├── ja │ │ └── messages.json │ ├── zh_TW │ │ └── messages.json │ ├── en │ │ └── messages.json │ └── de │ │ └── messages.json ├── src │ └── background.js └── manifest.json ├── src ├── core │ ├── entity │ │ ├── index.ts │ │ └── components │ │ │ └── CoreUrl.ts │ ├── elasticsearch-client │ │ ├── utils │ │ │ ├── index.ts │ │ │ ├── ElasticsearchType.ts │ │ │ └── BuildUrlWithVersion.ts │ │ ├── index.ts │ │ ├── types │ │ │ ├── DevToolSearch.ts │ │ │ ├── ShardInfo.ts │ │ │ ├── ElasticsearchClientProp.ts │ │ │ ├── index.ts │ │ │ ├── TableViewColumnConfig.ts │ │ │ ├── Overview.ts │ │ │ ├── ClusterHealth.ts │ │ │ ├── AllocationExplain.ts │ │ │ └── DataSearch.ts │ │ ├── domain │ │ │ ├── index.ts │ │ │ ├── Analyze.ts │ │ │ ├── IlmExplainResponse.ts │ │ │ ├── IndexInfo.ts │ │ │ ├── IndexTemplate.ts │ │ │ └── IndexOpenOrCloseProp.ts │ │ ├── components │ │ │ ├── IndexTypeBuild.ts │ │ │ └── SearchResultToTable.ts │ │ └── factory.ts │ ├── shared │ │ ├── common │ │ │ ├── TaskEvent.ts │ │ │ ├── type.ts │ │ │ ├── TableRecord.ts │ │ │ ├── SelectOption.ts │ │ │ ├── PageResponse.ts │ │ │ ├── index.ts │ │ │ ├── ActivateData.ts │ │ │ ├── EsRequestError.ts │ │ │ ├── ServiceEvent.ts │ │ │ ├── TableColumn.ts │ │ │ ├── LicenseState.ts │ │ │ ├── VerifyData.ts │ │ │ ├── Result.ts │ │ │ └── GlobalSetting.ts │ │ ├── index.ts │ │ └── elasticsearch │ │ │ ├── index.ts │ │ │ └── IndexCreate.ts │ └── util │ │ ├── file │ │ ├── index.ts │ │ └── WebPath.ts │ │ ├── index.ts │ │ ├── FormatUtil.ts │ │ ├── lang │ │ ├── RecordUtil.ts │ │ ├── PromiseUtil.ts │ │ └── StrUtil.ts │ │ └── Snowflake.ts ├── assets │ ├── logo.png │ ├── JetBrainsMono-Regular.woff2 │ └── less │ │ ├── index.ts │ │ └── customer.less ├── api │ ├── index.ts │ ├── DataBrowser │ │ └── DataBrowserViewService.ts │ ├── SeniorSearchRecordService.ts │ ├── DevToolFileService.ts │ └── BaseSearchRecordService.ts ├── domain │ ├── common │ │ └── SelectOption.ts │ ├── core │ │ ├── index.ts │ │ ├── TableRecord.ts │ │ ├── TableColumn.ts │ │ └── DataSearch.ts │ ├── es │ │ ├── IndexCreate.ts │ │ ├── Analyze.ts │ │ ├── Search.ts │ │ ├── Overview.ts │ │ ├── ClusterHealth.ts │ │ ├── DocumentSearchResult.ts │ │ ├── IndexHealth.ts │ │ ├── IndexInfo.ts │ │ ├── IndexBase.ts │ │ └── DocumentSearchQuery.ts │ ├── PageResult.ts │ ├── IndexInstance.ts │ ├── Schema.ts │ └── EditorSetting.ts ├── entity │ ├── index.ts │ ├── setting │ │ ├── BackupSetting.ts │ │ ├── DbSetting.ts │ │ └── BaseSearchSetting.ts │ ├── DevTool │ │ ├── DevToolContent.ts │ │ └── DevToolFileItem.ts │ ├── record │ │ ├── SeniorSearchRecord.ts │ │ └── BaseSearchRecord.ts │ ├── Base.ts │ ├── event │ │ ├── SeniorSearchJumpEvent.ts │ │ ├── ConditionExportEvent.ts │ │ ├── BaseSearchJumpEvent.ts │ │ └── RequestRecordEvent.ts │ ├── BaseOrder.ts │ ├── DataBrowser │ │ ├── DataBrowserView.ts │ │ └── DataBrowserQuery.ts │ ├── history │ │ ├── SeniorSearchHistory.ts │ │ ├── SeniorSearchRequest.ts │ │ └── BaseSearchHistory.ts │ └── Url.ts ├── enumeration │ ├── TableHeaderModeEnum.ts │ ├── UrlAuthTypeEnum.ts │ ├── PluginModeEnum.ts │ ├── EventBusEnum.ts │ ├── ViewTypeEnum.ts │ ├── TableNameEnum.ts │ └── PageNameEnum.ts ├── view │ ├── Param.ts │ ├── Field.ts │ ├── Header.ts │ └── Data.ts ├── page │ ├── dashboard │ │ ├── index.vue │ │ ├── Analysis │ │ │ ├── ShowQuestion.tsx │ │ │ └── index.vue │ │ └── components │ │ │ └── DashboardCard.vue │ ├── setting │ │ ├── pages │ │ │ └── link │ │ │ │ └── components │ │ │ │ ├── EditLink.less │ │ │ │ └── LinkTableColumn.tsx │ │ └── index.vue │ ├── more │ │ ├── index.vue │ │ └── components │ │ │ ├── update.vue │ │ │ └── privacy.vue │ ├── data-browse │ │ ├── index.vue │ │ ├── tab │ │ │ ├── DataBrowserIndexTab.vue │ │ │ └── DataBrowserQueryTab.vue │ │ ├── component │ │ │ ├── DbHeader │ │ │ │ └── components │ │ │ │ │ ├── DbPage.vue │ │ │ │ │ ├── DbSimpleItem.vue │ │ │ │ │ └── DbTableHeader.vue │ │ │ ├── DbInput.vue │ │ │ └── DbCondition │ │ │ │ └── DbCondition.vue │ │ └── layouts │ │ │ └── DataBrowserRight.vue │ ├── dev-tool │ │ ├── func.ts │ │ ├── index.vue │ │ └── components │ │ │ └── SsFileContent.vue │ ├── senior-search │ │ ├── layout │ │ │ ├── senior-search-editor │ │ │ │ ├── index.vue │ │ │ │ └── components │ │ │ │ │ └── ss-option │ │ │ │ │ └── SeniorSearchSetting.tsx │ │ │ └── senior-search-display │ │ │ │ └── SsDisplayQuick.vue │ │ ├── index.vue │ │ └── index.less │ ├── base-search │ │ ├── index.vue │ │ ├── components │ │ │ └── filed-order │ │ │ │ └── container.vue │ │ └── layout │ │ │ ├── BaseSearchHeader │ │ │ └── operator │ │ │ │ └── BsOperator.vue │ │ │ └── BaseSearchView │ │ │ └── BaseSearchView.vue │ └── home │ │ ├── components │ │ └── IndexAliasAdd.tsx │ │ └── index.vue ├── store │ ├── index.ts │ ├── components │ │ ├── BaseSearchStore.ts │ │ └── HomeStore.ts │ ├── GlobalStore.ts │ └── setting │ │ └── EditorSettingStore.ts ├── vite-env.d.ts ├── components │ ├── SystemNotify │ │ ├── AnnouncementTypes.ts │ │ └── AnnouncementApi.ts │ ├── AppExtend │ │ └── AlertExtend.vue │ ├── version-manager │ │ └── updateTo3.ts │ ├── AppLink │ │ └── AppLink.vue │ ├── SqlEditor │ │ └── language │ │ │ ├── configuration.ts │ │ │ └── codelens.ts │ ├── RestClientEditor │ │ ├── configuration.ts │ │ ├── index.ts │ │ └── codelens.ts │ ├── view │ │ └── MonacoView │ │ │ └── index.vue │ └── es │ │ └── ClusterApi.ts ├── hooks │ ├── index.ts │ ├── UseState.ts │ ├── UseQuery.ts │ ├── UseQueryApi.ts │ └── UseLoading.tsx ├── plugins │ ├── dexie.ts │ └── Statistics.ts ├── icon │ ├── RunIcon.vue │ ├── TableIcon.vue │ ├── MoonIcon.vue │ ├── TagIcon.vue │ ├── SaveIcon.vue │ ├── Translate.vue │ ├── StructureIcon.vue │ ├── InfoIcon.vue │ ├── FormatIcon.vue │ └── JsonIcon.vue ├── strategy │ └── VersionStrategy │ │ ├── VersionStrategy.ts │ │ └── impl │ │ ├── V7VersionStrategyImpl.ts │ │ ├── V8VersionStrategyImpl.ts │ │ └── V6VersionStrategyImpl.ts ├── module │ └── version-update │ │ └── index.tsx ├── i18n │ ├── locales │ │ └── zh-TW.ts │ └── index.ts ├── main.ts ├── global │ └── BeanFactory.ts ├── data │ ├── EsUrl.ts │ └── JsonTheme.ts └── utils │ ├── model │ └── MessageUtil.ts │ └── StrUtil.ts ├── src-tauri ├── build.rs ├── icons │ ├── 32x32.png │ ├── 64x64.png │ ├── icon.icns │ ├── icon.ico │ ├── icon.png │ ├── 128x128.png │ ├── 128x128@2x.png │ ├── StoreLogo.png │ ├── Square30x30Logo.png │ ├── Square44x44Logo.png │ ├── Square71x71Logo.png │ ├── Square89x89Logo.png │ ├── Square107x107Logo.png │ ├── Square142x142Logo.png │ ├── Square150x150Logo.png │ ├── Square284x284Logo.png │ ├── Square310x310Logo.png │ ├── ios │ │ ├── AppIcon-512@2x.png │ │ ├── AppIcon-20x20@1x.png │ │ ├── AppIcon-20x20@2x.png │ │ ├── AppIcon-20x20@3x.png │ │ ├── AppIcon-29x29@1x.png │ │ ├── AppIcon-29x29@2x.png │ │ ├── AppIcon-29x29@3x.png │ │ ├── AppIcon-40x40@1x.png │ │ ├── AppIcon-40x40@2x.png │ │ ├── AppIcon-40x40@3x.png │ │ ├── AppIcon-60x60@2x.png │ │ ├── AppIcon-60x60@3x.png │ │ ├── AppIcon-76x76@1x.png │ │ ├── AppIcon-76x76@2x.png │ │ ├── AppIcon-20x20@2x-1.png │ │ ├── AppIcon-29x29@2x-1.png │ │ ├── AppIcon-40x40@2x-1.png │ │ └── AppIcon-83.5x83.5@2x.png │ └── android │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── ic_launcher_foreground.png │ │ ├── values │ │ └── ic_launcher_background.xml │ │ └── mipmap-anydpi-v26 │ │ └── ic_launcher.xml ├── .gitignore ├── src │ ├── main.rs │ └── lib.rs ├── capabilities │ └── default.json ├── Cargo.toml └── tauri.conf.json ├── .vscode ├── extensions.json ├── tasks.json ├── settings.json └── launch.json ├── img ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png └── logo1024.png ├── public ├── logo.png ├── favicon.ico ├── logo256.png └── highlight.js │ └── styles │ ├── github.css │ └── github-dark.css ├── src-firefox ├── icons │ └── logo_16.png ├── src │ └── index.js └── manifest.json ├── env ├── .env.tauri ├── .env ├── .env.chrome └── .env.edge ├── uno.config.ts ├── index.html ├── .gitignore ├── test └── SqlParser.ts └── tsconfig.json /src-chrome/Readme.md: -------------------------------------------------------------------------------- 1 | # es-client 2 | 3 | es搜索客户端 4 | -------------------------------------------------------------------------------- /src-edge/Readme.md: -------------------------------------------------------------------------------- 1 | # es-client 2 | 3 | es搜索客户端 4 | -------------------------------------------------------------------------------- /src/core/entity/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./components/CoreUrl"; -------------------------------------------------------------------------------- /src-tauri/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | tauri_build::build() 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/img/1.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/img/2.png -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/img/3.png -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/img/4.png -------------------------------------------------------------------------------- /img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/img/5.png -------------------------------------------------------------------------------- /img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/img/6.png -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/public/logo.png -------------------------------------------------------------------------------- /src/core/elasticsearch-client/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./BuildUrlWithVersion"; 2 | -------------------------------------------------------------------------------- /img/logo1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/img/logo1024.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/public/logo256.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /src/core/shared/common/TaskEvent.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 任务事件 3 | */ 4 | export const TaskEvent = {}; 5 | -------------------------------------------------------------------------------- /src/core/shared/common/type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 是或否 3 | */ 4 | export type YesOrNoType = 1 | 0; 5 | -------------------------------------------------------------------------------- /src-tauri/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/32x32.png -------------------------------------------------------------------------------- /src-tauri/icons/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/64x64.png -------------------------------------------------------------------------------- /src-tauri/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/icon.icns -------------------------------------------------------------------------------- /src-tauri/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/icon.ico -------------------------------------------------------------------------------- /src-tauri/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/icon.png -------------------------------------------------------------------------------- /src-edge/icons/logo_200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-edge/icons/logo_200.png -------------------------------------------------------------------------------- /src-tauri/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/128x128.png -------------------------------------------------------------------------------- /src-chrome/icons/logo_200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-chrome/icons/logo_200.png -------------------------------------------------------------------------------- /src-firefox/icons/logo_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-firefox/icons/logo_16.png -------------------------------------------------------------------------------- /src-tauri/icons/128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/128x128@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/StoreLogo.png -------------------------------------------------------------------------------- /src/core/util/file/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./json"; 2 | export * from "./rest"; 3 | export * from "./JsonParser"; 4 | -------------------------------------------------------------------------------- /src-tauri/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | /gen/schemas 5 | -------------------------------------------------------------------------------- /src-tauri/icons/Square30x30Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square30x30Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square44x44Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square44x44Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square71x71Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square71x71Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square89x89Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square89x89Logo.png -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./DataBrowser/DataBrowserViewService" 2 | export * from "./DataBrowser/DataBrwoserQueryService" -------------------------------------------------------------------------------- /src/core/elasticsearch-client/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./types"; 2 | export * from "./client"; 3 | export * from "./factory"; 4 | -------------------------------------------------------------------------------- /src/domain/common/SelectOption.ts: -------------------------------------------------------------------------------- 1 | export interface SelectOptionData { 2 | label: string; 3 | value: string | number; 4 | } -------------------------------------------------------------------------------- /src/domain/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./DataSearch"; 2 | export * from "./TableColumn"; 3 | export * from "./TableRecord"; 4 | -------------------------------------------------------------------------------- /src-tauri/icons/Square107x107Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square107x107Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square142x142Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square142x142Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square150x150Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square284x284Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square284x284Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square310x310Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/Square310x310Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-512@2x.png -------------------------------------------------------------------------------- /src/assets/JetBrainsMono-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src/assets/JetBrainsMono-Regular.woff2 -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-20x20@1x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-20x20@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-20x20@3x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-29x29@1x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-29x29@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-29x29@3x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-40x40@1x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-40x40@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-40x40@3x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-60x60@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-60x60@3x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-76x76@1x.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-76x76@2x.png -------------------------------------------------------------------------------- /src-edge/doc/multiple-es-head-bookmarks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-edge/doc/multiple-es-head-bookmarks.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-20x20@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-20x20@2x-1.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-29x29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-29x29@2x-1.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-40x40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-40x40@2x-1.png -------------------------------------------------------------------------------- /src-chrome/doc/multiple-es-head-bookmarks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-chrome/doc/multiple-es-head-bookmarks.png -------------------------------------------------------------------------------- /src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png -------------------------------------------------------------------------------- /src/domain/core/TableRecord.ts: -------------------------------------------------------------------------------- 1 | export interface TableRecord extends Record { 2 | // 树表格 3 | children?: Array; 4 | } 5 | -------------------------------------------------------------------------------- /src/domain/es/IndexCreate.ts: -------------------------------------------------------------------------------- 1 | import {IndexBase} from "@/domain/es/IndexBase"; 2 | 3 | export interface IndexCreate extends IndexBase { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/core/shared/common/TableRecord.ts: -------------------------------------------------------------------------------- 1 | export interface TableRecord extends Record { 2 | // 树表格 3 | children?: Array; 4 | } 5 | -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src/assets/less/index.ts: -------------------------------------------------------------------------------- 1 | import '@/assets/less/main.less'; 2 | import '@/assets/less/post.css'; 3 | import '@/assets/less/customer.less'; 4 | import "./tdesign-theme.css"; -------------------------------------------------------------------------------- /src/core/shared/common/SelectOption.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 选择项,支持select、radio、checkbox 3 | */ 4 | export interface SelectOption { 5 | label: string; 6 | value: string; 7 | } 8 | -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src/core/shared/common/PageResponse.ts: -------------------------------------------------------------------------------- 1 | export interface PageResponse { 2 | total: number; 3 | records: Array; 4 | pageNum: number; 5 | pageSize: number; 6 | } 7 | -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q2316367743/es-client/HEAD/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src-tauri/icons/android/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #fff 4 | -------------------------------------------------------------------------------- /src/core/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./common/type"; 2 | export * from "./common/Result"; 3 | export * from "./common/PageResponse"; 4 | export * from "./common/EsRequestError"; 5 | -------------------------------------------------------------------------------- /env/.env.tauri: -------------------------------------------------------------------------------- 1 | VITE_FEEDBACK_URL=https://f.kdocs.cn/g/23ZimGdx?channel=41pag0 2 | VITE_MODE=tauri 3 | VITE_PLATFORM=tauri 4 | VITE_REFERRER=https://tauri.app 5 | VITE_HOMENAME=tauri.app 6 | -------------------------------------------------------------------------------- /src/core/shared/elasticsearch/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IndexMapping"; 2 | export * from "./IndexSettings"; 3 | export * from "./IndexAliasOptions"; 4 | export * from "./IndexNodeState"; 5 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/DevToolSearch.ts: -------------------------------------------------------------------------------- 1 | export interface DevToolProp { 2 | method: string; 3 | url: string; 4 | headers: Record; 5 | body?: string; 6 | } 7 | -------------------------------------------------------------------------------- /env/.env: -------------------------------------------------------------------------------- 1 | VITE_FEEDBACK_URL=https://f.kdocs.cn/g/23ZimGdx?channel=41pag0 2 | VITE_MODE=browser 3 | VITE_PLATFORM=default 4 | VITE_REFERRER=https://es-client.esion.xyz 5 | VITE_HOMENAME=es-client.esion.xyz -------------------------------------------------------------------------------- /env/.env.chrome: -------------------------------------------------------------------------------- 1 | VITE_FEEDBACK_URL=https://f.kdocs.cn/g/23ZimGdx?channel=41pag0 2 | VITE_MODE=browser 3 | VITE_PLATFORM=chrome 4 | VITE_REFERRER=https://www.google.com 5 | VITE_HOMENAME=www.google.com 6 | -------------------------------------------------------------------------------- /env/.env.edge: -------------------------------------------------------------------------------- 1 | VITE_FEEDBACK_URL=https://f.kdocs.cn/g/23ZimGdx?channel=41pag0 2 | VITE_MODE=browser 3 | VITE_PLATFORM=edge 4 | VITE_REFERRER=https://www.microsoft.com 5 | VITE_HOMENAME=www.microsoft.com 6 | -------------------------------------------------------------------------------- /src/core/shared/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./SelectOption"; 2 | export * from "./ActivateData"; 3 | export * from "./VerifyData"; 4 | export * from "./LicenseState"; 5 | export * from "./GlobalSetting"; 6 | -------------------------------------------------------------------------------- /src/entity/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./DevTool/DevToolFileItem"; 2 | export * from "./DevTool/DevToolContent"; 3 | 4 | export * from "./DataBrowser/DataBrowserView"; 5 | export * from "./DataBrowser/DataBrowserQuery"; -------------------------------------------------------------------------------- /src/entity/setting/BackupSetting.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 备份设置 3 | */ 4 | export default interface BackupSetting { 5 | 6 | url: string; 7 | 8 | username: string; 9 | 10 | password: string; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src-tauri/src/main.rs: -------------------------------------------------------------------------------- 1 | // Prevents additional console window on Windows in release, DO NOT REMOVE!! 2 | #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] 3 | 4 | fn main() { 5 | app_lib::run(); 6 | } 7 | -------------------------------------------------------------------------------- /src/core/shared/common/ActivateData.ts: -------------------------------------------------------------------------------- 1 | export interface ActivateData { 2 | token: string; 3 | licenseType: "online" | "offline"; 4 | validFrom: number; 5 | validUntil: number; 6 | durationDays: number; 7 | isNewActivation: boolean; 8 | } 9 | -------------------------------------------------------------------------------- /src/entity/DevTool/DevToolContent.ts: -------------------------------------------------------------------------------- 1 | export interface DevToolContent { 2 | id: string; 3 | 4 | /** 5 | * 文件内容 6 | */ 7 | content: string; 8 | /** 9 | * 编辑器宽度 10 | * @default 30 11 | */ 12 | size: number; 13 | } 14 | -------------------------------------------------------------------------------- /src/enumeration/TableHeaderModeEnum.ts: -------------------------------------------------------------------------------- 1 | enum TableHeaderModeEnum { 2 | 3 | /** 4 | * 来自映射 5 | */ 6 | MAPPING = 1, 7 | 8 | /** 9 | * 实时渲染 10 | */ 11 | RENDER = 2 12 | 13 | } 14 | 15 | export default TableHeaderModeEnum; -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/ShardInfo.ts: -------------------------------------------------------------------------------- 1 | export interface ShardInfo { 2 | index: string; 3 | shard: string; 4 | prirep: string; 5 | state: string; 6 | docs?: string; 7 | store?: string; 8 | ip?: string; 9 | node?: string; 10 | } 11 | -------------------------------------------------------------------------------- /src/view/Param.ts: -------------------------------------------------------------------------------- 1 | export default interface Param { 2 | 3 | /** 4 | * 标识,时间戳 5 | */ 6 | id: number 7 | 8 | /** 9 | * 键 10 | */ 11 | key: string; 12 | 13 | /** 14 | * 值 15 | */ 16 | value: string; 17 | 18 | } -------------------------------------------------------------------------------- /src/page/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | 14 | -------------------------------------------------------------------------------- /src-chrome/_locales/zh_CN/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch 开发者工具", 4 | "description": "扩展名称" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch 管理客户端", 8 | "description": "扩展描述" 9 | } 10 | } -------------------------------------------------------------------------------- /src-edge/_locales/zh_CN/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch 开发者工具", 4 | "description": "扩展名称" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch 管理客户端", 8 | "description": "扩展描述" 9 | } 10 | } -------------------------------------------------------------------------------- /src-chrome/_locales/ja/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "拡張機能名" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch 管理クライアント", 8 | "description": "拡張機能の説明" 9 | } 10 | } -------------------------------------------------------------------------------- /src-chrome/_locales/zh_TW/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "擴充功能名稱" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch 管理客戶端", 8 | "description": "擴充功能描述" 9 | } 10 | } -------------------------------------------------------------------------------- /src-edge/_locales/ja/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "拡張機能名" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch 管理クライアント", 8 | "description": "拡張機能の説明" 9 | } 10 | } -------------------------------------------------------------------------------- /src-edge/_locales/zh_TW/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "擴充功能名稱" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch 管理客戶端", 8 | "description": "擴充功能描述" 9 | } 10 | } -------------------------------------------------------------------------------- /src/core/shared/common/EsRequestError.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * es请求错误 3 | */ 4 | export class EsRequestError extends Error { 5 | body: string; 6 | 7 | constructor(message: string, body: string) { 8 | super(message); 9 | this.name = "EsRequestError"; 10 | this.body = body; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/entity/record/SeniorSearchRecord.ts: -------------------------------------------------------------------------------- 1 | import Base from "@/entity/Base"; 2 | 3 | /** 4 | * 高级查询历史记录 5 | */ 6 | export interface SeniorSearchRecord extends Base { 7 | 8 | urlId: number | undefined; 9 | 10 | method: string; 11 | 12 | link: string; 13 | 14 | body: string; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./UrlStore"; 2 | export * from "./IndexStore"; 3 | export * from "./GlobalStore"; 4 | export * from "./setting/GlobalSettingStore"; 5 | export * from "./setting/EditorSettingStore"; 6 | export * from "./db/DevToolFileItemStore"; 7 | export * from "./components/DevToolStore"; 8 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | interface Window { 3 | mode: string, 4 | referrer: string, 5 | } 6 | 7 | interface ImportMetaEnv { 8 | // 发行版 9 | VITE_MODE: string; 10 | VITE_PLATFORM: string; 11 | VITE_REFERRER: string; 12 | VITE_HOMENAME: string; 13 | } 14 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/domain/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 领域文件夹,此文件夹中的接口只是在数据传输过程中使用到,不对外提供 3 | */ 4 | 5 | export * from "./ClusterState"; 6 | export * from "./Stats"; 7 | export * from "./Analyze"; 8 | export * from "./IndexTemplate"; 9 | export * from "./IndexOpenOrCloseProp"; 10 | export * from "./IndexInfo"; 11 | -------------------------------------------------------------------------------- /src/enumeration/UrlAuthTypeEnum.ts: -------------------------------------------------------------------------------- 1 | enum UrlAuthTypeEnum{ 2 | 3 | /** 4 | * Basic认证 5 | */ 6 | BASIC = 1, 7 | 8 | /** 9 | * 请求头认证 10 | */ 11 | HEADER = 2, 12 | 13 | /** 14 | * Cookie认证 15 | */ 16 | COOKIE = 3 17 | 18 | } 19 | 20 | export default UrlAuthTypeEnum; -------------------------------------------------------------------------------- /src/core/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Snowflake"; 2 | export * from "./FormatUtil"; 3 | 4 | export * from "./file"; 5 | 6 | export * from "./lang/ArrayUtil"; 7 | export * from "./lang/FieldUtil"; 8 | export * from "./lang/PromiseUtil"; 9 | export * from "./lang/RecordUtil"; 10 | export * from "./lang/StrUtil"; 11 | -------------------------------------------------------------------------------- /src/page/setting/pages/link/components/EditLink.less: -------------------------------------------------------------------------------- 1 | .edit-link-content { 2 | background-color: var(--td-bg-color-container); 3 | border-radius: 20%; 4 | box-shadow: 0 0 6px var(--td-border-level-2-color); 5 | color: var(--td-text-color-primary); 6 | 7 | .lucene { 8 | margin-top: 10px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src-chrome/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "Extension name" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch management client", 8 | "description": "Extension description" 9 | } 10 | } -------------------------------------------------------------------------------- /src-chrome/src/background.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef,no-unused-vars 2 | // 图标点击事件:跳转指定网页 3 | chrome.action.onClicked.addListener(() => { 4 | chrome.tabs.create({'url': chrome.runtime.getURL('es-client/index.html?td_channelid=chrome')}, function (tab) { 5 | }); 6 | }); 7 | 8 | console.log(chrome.browserAction) 9 | -------------------------------------------------------------------------------- /src-edge/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "Extension name" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch management client", 8 | "description": "Extension description" 9 | } 10 | } -------------------------------------------------------------------------------- /src-edge/src/background.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef,no-unused-vars 2 | // 图标点击事件:跳转指定网页 3 | chrome.action.onClicked.addListener(() => { 4 | chrome.tabs.create({'url': chrome.runtime.getURL('es-client/index.html?td_channelid=chrome')}, function (tab) { 5 | }); 6 | }); 7 | 8 | console.log(chrome.browserAction) 9 | -------------------------------------------------------------------------------- /src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/components/SystemNotify/AnnouncementTypes.ts: -------------------------------------------------------------------------------- 1 | export interface Announcement { 2 | id: string; 3 | title: string; 4 | description: string; 5 | link: string; 6 | type: string; 7 | status: string; 8 | app_slug: string; 9 | published_at: string; 10 | expires_at: string | null; 11 | updated_at: string; 12 | } -------------------------------------------------------------------------------- /src/entity/Base.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 基础字段 3 | */ 4 | export default interface Base { 5 | 6 | /** 7 | * ID 8 | */ 9 | id: number; 10 | 11 | /** 12 | * 创建时间 13 | */ 14 | createTime: Date | string | number; 15 | 16 | /** 17 | * 更新时间 18 | */ 19 | updateTime: Date | string | number; 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src-chrome/_locales/de/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "Erweiterungsname" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch-Verwaltungsclient", 8 | "description": "Beschreibung der Erweiterung" 9 | } 10 | } -------------------------------------------------------------------------------- /src-edge/_locales/de/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "ES Client – Elasticsearch Browser Tool for Devs", 4 | "description": "Erweiterungsname" 5 | }, 6 | "extensionDescription": { 7 | "message": "Elasticsearch-Verwaltungsclient", 8 | "description": "Beschreibung der Erweiterung" 9 | } 10 | } -------------------------------------------------------------------------------- /src/core/shared/elasticsearch/IndexCreate.ts: -------------------------------------------------------------------------------- 1 | import { IndexAliasOptions, IndexMapping, IndexSettings } from "$/shared/elasticsearch"; 2 | 3 | /** 4 | * 索引创建参数 5 | */ 6 | export interface IndexCreate { 7 | settings: IndexSettings; 8 | 9 | mappings: IndexMapping; 10 | 11 | aliases: Record; 12 | } 13 | -------------------------------------------------------------------------------- /src-firefox/src/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef,no-unused-vars 2 | browser.browserAction.onClicked.addListener(function (tab) { 3 | // eslint-disable-next-line no-undef,no-unused-vars 4 | browser.tabs.create({'url': browser.extension.getURL('es-client/index.html?td_channelid=firefox')}, function (tab) { 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/ElasticsearchClientProp.ts: -------------------------------------------------------------------------------- 1 | import { AxiosRequestConfig } from "axios"; 2 | import { Url } from "$/entity"; 3 | 4 | export interface ElasticsearchClientProp extends Url { 5 | /** 6 | * 请求适配器 7 | * @param config 请求参数 8 | */ 9 | adapter: (config: AxiosRequestConfig) => Promise; 10 | } 11 | -------------------------------------------------------------------------------- /src/core/shared/common/ServiceEvent.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 服务端事件 3 | */ 4 | export enum ServiceEvent { 5 | // url重新载入 6 | URL_RELOAD = "/url/reload", 7 | 8 | /** 9 | * 任务完成 10 | */ 11 | TASK_COMPLETE = "/task/complete", 12 | 13 | // 任务失败 14 | TASK_FAIL = "/task/fail", 15 | 16 | // 任务取消 17 | TASK_CANCEL = "/task/cancel" 18 | } 19 | -------------------------------------------------------------------------------- /src/domain/es/Analyze.ts: -------------------------------------------------------------------------------- 1 | export interface Analyze { 2 | tokens: Token[]; 3 | } 4 | 5 | export interface Token { 6 | token: string; 7 | start_offset: number; 8 | end_offset: number; 9 | type: TokenType; 10 | position: number; 11 | } 12 | 13 | export type TokenType = 'word' | 'LETTER' | 'ENGLISH' | 'ARABIC' | '' | ''; 14 | -------------------------------------------------------------------------------- /src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ColorMode"; 2 | 3 | export * from "./query/DataBrowserInstance"; 4 | export * from "./query/BaseSearchInstance"; 5 | export * from "./query/DataBrowserQueryContent"; 6 | export * from "./query/DevToolFileItemContent"; 7 | 8 | export * from "./UseState"; 9 | export * from "./UseQuery"; 10 | export * from "./UseQueryApi"; 11 | -------------------------------------------------------------------------------- /src/view/Field.ts: -------------------------------------------------------------------------------- 1 | export default interface Field { 2 | 3 | /** 4 | * 显示名称 5 | */ 6 | label: string; 7 | 8 | /** 9 | * 字段名称 10 | */ 11 | name: string; 12 | 13 | /** 14 | * 数据索引,仅用于确保唯一 15 | */ 16 | dataIndex: string; 17 | 18 | /** 19 | * 字段类型 20 | */ 21 | type: string; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'unocss' 2 | 3 | export default defineConfig({ 4 | // ...UnoCSS options 5 | rules: [ 6 | [/^abs-(\d+)$/, ([, size]) => ({ 7 | 'position': 'absolute', 8 | 'top': `${size}px`, 9 | 'left': `${size}px`, 10 | 'right': `${size}px`, 11 | 'bottom': `${size}px` 12 | })], 13 | ] 14 | }) -------------------------------------------------------------------------------- /src/domain/PageResult.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 分页结果集 3 | */ 4 | export default interface PageResult { 5 | 6 | /** 7 | * 当前页面 8 | */ 9 | current: number; 10 | 11 | /** 12 | * 页面大小 13 | */ 14 | size: number; 15 | 16 | /** 17 | * 总数 18 | */ 19 | total: number; 20 | 21 | /** 22 | * 记录 23 | */ 24 | records: Array; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/domain/Analyze.ts: -------------------------------------------------------------------------------- 1 | export interface Analyze { 2 | tokens: Token[]; 3 | } 4 | 5 | export interface Token { 6 | token: string; 7 | start_offset: number; 8 | end_offset: number; 9 | type: TokenType; 10 | position: number; 11 | } 12 | 13 | export type TokenType = "word" | "LETTER" | "ENGLISH" | "ARABIC" | "" | ""; 14 | -------------------------------------------------------------------------------- /src/page/setting/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 21 | -------------------------------------------------------------------------------- /src/view/Header.ts: -------------------------------------------------------------------------------- 1 | export default interface Header { 2 | 3 | /** 4 | * ID 5 | */ 6 | id: number; 7 | 8 | /** 9 | * 字段名称 10 | */ 11 | field: string; 12 | 13 | /** 14 | * 最小宽度 15 | */ 16 | minWidth: number; 17 | 18 | /** 19 | * 提示信息 20 | */ 21 | help?: { 22 | content: string 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | es-client 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/page/more/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 21 | -------------------------------------------------------------------------------- /src/entity/event/SeniorSearchJumpEvent.ts: -------------------------------------------------------------------------------- 1 | import {Method} from "axios"; 2 | 3 | /** 4 | * 高级查询 - 页面跳转事件 5 | */ 6 | export default interface SeniorSearchJumpEvent { 7 | 8 | /** 9 | * 请求方法 10 | */ 11 | method: Method; 12 | 13 | /** 14 | * 请求链接 15 | */ 16 | link: string; 17 | 18 | /** 19 | /** 20 | * 请求体,存在会替代上面参数 21 | */ 22 | body?: string; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/hooks/UseState.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from "vue"; 2 | 3 | type UseStateReturn = [state: Ref, setState: (newState: T) => void]; 4 | 5 | export const useState = (initialState: T): UseStateReturn => { 6 | const state = ref(initialState) as Ref; 7 | return [ 8 | state, 9 | (newState: T) => { 10 | state.value = newState; 11 | } 12 | ] as const; 13 | }; 14 | -------------------------------------------------------------------------------- /src/plugins/dexie.ts: -------------------------------------------------------------------------------- 1 | import Dexie from 'dexie'; 2 | 3 | export class DexieInstance extends Dexie { 4 | 5 | constructor(tableName: string) { 6 | super(tableName); 7 | this.version(1).stores({ 8 | baseSearchRecord: '++id, urlId', 9 | seniorSearchRecord: '++id, urlId' 10 | }) 11 | } 12 | 13 | } 14 | 15 | export const dexieInstance = new DexieInstance('rain-es-client'); 16 | -------------------------------------------------------------------------------- /src/entity/event/ConditionExportEvent.ts: -------------------------------------------------------------------------------- 1 | import {DocumentSearchQuery} from "@/domain/es/DocumentSearchQuery"; 2 | 3 | export default interface ConditionExportEvent { 4 | 5 | /** 6 | * 使用的索引 7 | */ 8 | name: string; 9 | 10 | /** 11 | * 使用的索引 12 | */ 13 | index: string; 14 | 15 | /** 16 | * 查询条件 17 | */ 18 | search: DocumentSearchQuery; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/entity/BaseOrder.ts: -------------------------------------------------------------------------------- 1 | import {SortConditionType} from "@/domain/es/DocumentSearchQuery"; 2 | 3 | /** 4 | * 基础排序 5 | */ 6 | export default interface BaseOrder { 7 | 8 | id: number; 9 | 10 | /** 11 | * 排序的字段 12 | */ 13 | field: string; 14 | 15 | /** 16 | * 排序的方式 17 | */ 18 | type: SortConditionType; 19 | 20 | /** 21 | * 是否启用 22 | */ 23 | isEnable: boolean; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/entity/setting/DbSetting.ts: -------------------------------------------------------------------------------- 1 | export interface DbSetting { 2 | 3 | /** 4 | * 是否启用track_total_hits 5 | */ 6 | enableTrackTotalHits: boolean; 7 | 8 | /** 9 | * 是否固定ID 10 | */ 11 | fixId: boolean; 12 | 13 | } 14 | 15 | export function getDefaultDbSetting(): DbSetting { 16 | return { 17 | enableTrackTotalHits: false, 18 | fixId: true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./BaseSearch"; 2 | export * from "./DataSearch"; 3 | export * from "./DevToolSearch"; 4 | export * from "./ElasticsearchClientProp"; 5 | export * from "./TableViewColumnConfig"; 6 | 7 | export * from "./IndexItem"; 8 | export * from "./ClusterHealth"; 9 | export * from "./Overview"; 10 | export * from "./ShardInfo"; 11 | export * from "./AllocationExplain"; 12 | -------------------------------------------------------------------------------- /src/store/components/BaseSearchStore.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | import { BaseSearchInstanceResult, useBaseSearchInstance } from "@/hooks"; 3 | 4 | export const useBaseSearchStore = defineStore("base-search", () => { 5 | const tabs = shallowRef([]) as Ref>; 6 | const self = useBaseSearchInstance(); 7 | tabs.value.push(self); 8 | return { 9 | tabs 10 | }; 11 | }); 12 | -------------------------------------------------------------------------------- /src/components/AppExtend/AlertExtend.vue: -------------------------------------------------------------------------------- 1 | 8 | 18 | 21 | -------------------------------------------------------------------------------- /src/core/shared/common/TableColumn.ts: -------------------------------------------------------------------------------- 1 | export interface TableColumnSortable { 2 | sortDirections: ("ascend" | "descend")[]; 3 | } 4 | 5 | export interface TableColumn { 6 | field: string; 7 | title: string; 8 | width?: number; 9 | fixed?: "left" | "right"; 10 | ellipsis?: boolean; 11 | tooltip?: boolean | Record; 12 | sortable?: TableColumnSortable; 13 | cellClass?: string; 14 | show?: boolean; 15 | } 16 | -------------------------------------------------------------------------------- /src/enumeration/PluginModeEnum.ts: -------------------------------------------------------------------------------- 1 | enum PluginModeEnum { 2 | 3 | /** 4 | * @deprecated 5 | */ 6 | TAURI = 'tauri', 7 | 8 | /** 9 | * @deprecated 10 | */ 11 | ELECTRON = 'electron', 12 | 13 | BROWSER = 'browser', 14 | 15 | /** 16 | * @deprecated 17 | */ 18 | SERVER = 'server', 19 | 20 | /** 21 | * @deprecated 22 | */ 23 | UTOOLS = 'utools' 24 | 25 | } 26 | 27 | export default PluginModeEnum; 28 | -------------------------------------------------------------------------------- /src/icon/RunIcon.vue: -------------------------------------------------------------------------------- 1 | 7 | 13 | -------------------------------------------------------------------------------- /src/enumeration/EventBusEnum.ts: -------------------------------------------------------------------------------- 1 | enum EventBusEnum { 2 | 3 | /** 4 | * 链接编辑 5 | */ 6 | URL_EDIT = 'url-edit', 7 | 8 | /** 9 | * 索引管理 10 | */ 11 | INDEX_MANAGE = 'index-manage', 12 | 13 | /** 14 | * 高级查询显示结果页 15 | */ 16 | SENIOR_SHOW_RESULT = 'senior-show-result', 17 | 18 | /** 19 | * 条件导出 20 | */ 21 | CONDITION_EXPORT = 'condition-export' 22 | 23 | 24 | } 25 | 26 | export default EventBusEnum; 27 | -------------------------------------------------------------------------------- /src/entity/setting/BaseSearchSetting.ts: -------------------------------------------------------------------------------- 1 | import ViewTypeEnum from "@/enumeration/ViewTypeEnum"; 2 | 3 | export default interface BaseSearchSetting { 4 | 5 | /** 6 | * 默认参数 7 | */ 8 | defaultParams: string; 9 | 10 | /** 11 | * 是否启用track_total_hits 12 | */ 13 | enableTrackTotalHits: boolean; 14 | 15 | /** 16 | * track_total_hits 17 | */ 18 | trackTotalHits: boolean; 19 | 20 | /** 21 | * 默认视图 22 | */ 23 | defaultView: ViewTypeEnum; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/enumeration/ViewTypeEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 视图类型 3 | * 1:基础视图 4 | * 2:JSON视图 5 | * 3:表格视图 6 | * 4:JSON树视图 7 | * 5:编辑器视图 8 | */ 9 | enum ViewTypeEnum { 10 | 11 | /** 12 | * @deprecated 不要了,不好用 13 | */ 14 | BASE = 1, 15 | 16 | /** 17 | * @deprecated 不要了,不好用 18 | */ 19 | JSON = 2, 20 | 21 | TABLE = 3, 22 | 23 | /** 24 | * @deprecated 不要了,不好用 25 | */ 26 | JSON_TREE = 4, 27 | 28 | EDITOR = 5 29 | 30 | } 31 | 32 | export default ViewTypeEnum; 33 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/TableViewColumnConfig.ts: -------------------------------------------------------------------------------- 1 | export interface TableViewSortable { 2 | sortDirections: ("ascend" | "descend")[]; 3 | } 4 | 5 | /** 6 | * 表格视图列配置 7 | */ 8 | export interface TableViewColumnConfig { 9 | field: string; 10 | title: string; 11 | width: number; 12 | fixed?: "left" | "right"; 13 | ellipsis: boolean; 14 | tooltip?: boolean | Record; 15 | sortable?: TableViewSortable; 16 | cellClass: string; 17 | show: boolean; 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | }, 18 | "path": "src-vscode" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /src/domain/es/Search.ts: -------------------------------------------------------------------------------- 1 | export interface Search { 2 | 3 | from?: number; 4 | 5 | size?: number; 6 | 7 | query?: Query 8 | 9 | /** 10 | * 其他字段 11 | */ 12 | [name: string]: any; 13 | 14 | } 15 | 16 | export interface Query { 17 | 18 | bool?: Bool; 19 | 20 | } 21 | 22 | export interface Bool { 23 | 24 | must?: Array>> 25 | 26 | } 27 | 28 | export type Condition = "term" | "match" | "wildcard" | "range" -------------------------------------------------------------------------------- /src/domain/es/Overview.ts: -------------------------------------------------------------------------------- 1 | export interface Overview { 2 | name: string; 3 | cluster_name: string; 4 | cluster_uuid: string; 5 | version: Version; 6 | tagline: string; 7 | } 8 | 9 | interface Version { 10 | number: string; 11 | build_flavor: string; 12 | build_type: string; 13 | build_hash: string; 14 | build_date: string; 15 | build_snapshot: boolean; 16 | lucene_version: string; 17 | minimum_wire_compatibility_version: string; 18 | minimum_index_compatibility_version: string; 19 | } 20 | -------------------------------------------------------------------------------- /src/entity/record/BaseSearchRecord.ts: -------------------------------------------------------------------------------- 1 | import Base from "@/entity/Base"; 2 | import {BaseQuery} from "@/entity/BaseQuery"; 3 | import BaseOrder from "@/entity/BaseOrder"; 4 | 5 | export interface BaseSearchRecord extends Base { 6 | 7 | /** 8 | * URL的id,可能存在 9 | */ 10 | urlId?: number 11 | 12 | /** 13 | * 索引 14 | */ 15 | index: string; 16 | 17 | /** 18 | * 条件 19 | */ 20 | conditions: Array; 21 | 22 | /** 23 | * 排序 24 | */ 25 | orders: Array; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/Overview.ts: -------------------------------------------------------------------------------- 1 | export interface Overview { 2 | name: string; 3 | cluster_name: string; 4 | cluster_uuid: string; 5 | version: Version; 6 | tagline: string; 7 | } 8 | 9 | interface Version { 10 | number: string; 11 | build_flavor: string; 12 | build_type: string; 13 | build_hash: string; 14 | build_date: string; 15 | build_snapshot: boolean; 16 | lucene_version: string; 17 | minimum_wire_compatibility_version: string; 18 | minimum_index_compatibility_version: string; 19 | } 20 | -------------------------------------------------------------------------------- /src/enumeration/TableNameEnum.ts: -------------------------------------------------------------------------------- 1 | enum TableNameEnum { 2 | 3 | /** 4 | * 基础搜索记录 5 | */ 6 | BASE_SEARCH_RECORD = 'baseSearchRecord', 7 | 8 | /** 9 | * 高级搜索记录 10 | */ 11 | SENIOR_SEARCH_RECORD = 'seniorSearchRecord', 12 | 13 | /** 14 | * 高级查询请求 15 | */ 16 | SENIOR_SEARCH_REQUEST = '/list/senior-search-request', 17 | 18 | /** 19 | * 高级查询请求 20 | */ 21 | SENIOR_SEARCH_REQUEST_ITEM = '/item/senior-search-request' 22 | 23 | } 24 | 25 | export default TableNameEnum; 26 | -------------------------------------------------------------------------------- /src/entity/DataBrowser/DataBrowserView.ts: -------------------------------------------------------------------------------- 1 | import LocalNameEnum from "@/enumeration/LocalNameEnum"; 2 | 3 | export const DATA_BROWSER_VIEW_KEY = (urlId: string) => `${LocalNameEnum.ITEM_DATA_BROWSER_VIEW}/${urlId}`; 4 | 5 | /** 6 | * 数据浏览 - 视图 7 | * 8 | * @id /item/data-browser/view/${urlId} 9 | */ 10 | export interface DataBrowserView { 11 | id: string; 12 | created_at: number; 13 | updated_at: number; 14 | 15 | url_id: string; 16 | 17 | name: string; 18 | /** 19 | * 匹配模式 20 | */ 21 | pattern: string; 22 | } 23 | -------------------------------------------------------------------------------- /src/entity/DevTool/DevToolFileItem.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface DevToolFileCreateProp { 3 | 4 | /** 5 | * 名称 6 | */ 7 | name: string; 8 | 9 | /** 10 | * 是否是文件夹 11 | */ 12 | folder: boolean; 13 | 14 | /** 15 | * 父ID,没有是空 16 | */ 17 | parentId: string; 18 | 19 | /** 20 | * 排序 21 | */ 22 | sequence?: number; 23 | 24 | } 25 | 26 | /** 27 | * 开发者工具 - 文件列表 28 | */ 29 | export interface DevToolFileItem extends DevToolFileCreateProp { 30 | id: string; 31 | createTime: number; 32 | updateTime: number; 33 | } -------------------------------------------------------------------------------- /src/entity/event/BaseSearchJumpEvent.ts: -------------------------------------------------------------------------------- 1 | import {BaseQuery} from "@/entity/BaseQuery"; 2 | import BaseOrder from "@/entity/BaseOrder"; 3 | 4 | /** 5 | * 基础查询 - 页面跳转事件 6 | */ 7 | export default interface BaseSearchJumpEvent { 8 | 9 | /** 10 | * 索引 11 | */ 12 | index: string; 13 | 14 | /** 15 | * 条件 16 | */ 17 | conditions: Array; 18 | 19 | /** 20 | * 排序 21 | */ 22 | orders: Array; 23 | 24 | /** 25 | * 是否立即执行 26 | */ 27 | execute: boolean; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/strategy/VersionStrategy/VersionStrategy.ts: -------------------------------------------------------------------------------- 1 | import {IndexInstance} from "@/domain/IndexInstance"; 2 | import {IndexCreate} from "@/domain/es/IndexCreate"; 3 | 4 | /** 5 | * 版本策略 6 | */ 7 | export default interface VersionStrategy { 8 | 9 | /** 10 | * 获取适用的版本 11 | */ 12 | getVersionExp(): RegExp; 13 | 14 | /** 15 | * 是否存在类型 16 | */ 17 | hasType(): boolean; 18 | 19 | /** 20 | * 索引创建构造器 21 | * @param index 索引实例 22 | */ 23 | indexCreateBuild(index: IndexInstance): IndexCreate; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/store/GlobalStore.ts: -------------------------------------------------------------------------------- 1 | import {defineStore} from "pinia"; 2 | import {useColorMode} from "@/hooks"; 3 | 4 | export const useGlobalStore = defineStore('global', () => { 5 | const size = useWindowSize(); 6 | const loading = ref(false); 7 | const loadingText = ref(''); 8 | 9 | const height = computed(() => size.height); 10 | const width = computed(() => size.width); 11 | 12 | const { isDark } = useColorMode(); 13 | 14 | return { 15 | size, 16 | loading, 17 | loadingText, 18 | height, 19 | width, 20 | isDark 21 | }; 22 | }); 23 | -------------------------------------------------------------------------------- /src/core/shared/common/LicenseState.ts: -------------------------------------------------------------------------------- 1 | import { ActivateData, VerifyData } from "$/shared/common"; 2 | 3 | export interface LicenseState { 4 | isValid: boolean; 5 | isPaid: boolean; 6 | licenseType: "online" | "offline"; 7 | lastCheck: number; 8 | payload: VerifyData | ActivateData | LicensePayload; 9 | } 10 | 11 | export interface LicensePayload { 12 | sub: string; 13 | licenseId: string; 14 | deviceId: string; 15 | licenseType: "online" | "offline"; 16 | orderId: string; 17 | validFrom: number; 18 | validUntil: number; 19 | exp: number; 20 | } 21 | -------------------------------------------------------------------------------- /src/domain/core/TableColumn.ts: -------------------------------------------------------------------------------- 1 | export interface TableColumnSortable { 2 | sortDirections: ("ascend" | "descend")[]; 3 | } 4 | 5 | export interface TableColumn { 6 | /** 7 | * 使用的字段 8 | */ 9 | field: string; 10 | // 列名 11 | title: string; 12 | // 宽度 13 | width: number; 14 | // 是否固定 15 | fixed?: "left" | "right"; 16 | // 是否省略 17 | ellipsis?: boolean; 18 | // 是否显示提示 19 | tooltip?: boolean | Record; 20 | // 排序 21 | sortable?: TableColumnSortable; 22 | // 单元格样式 23 | cellClass?: string; 24 | // 是否显示 25 | show: boolean; 26 | } 27 | -------------------------------------------------------------------------------- /src/core/util/FormatUtil.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 美化数据单位 3 | * 4 | * @param {number} value 需要美化的值 5 | */ 6 | export function prettyDataUnit(value: number) { 7 | let gb = 1024 * 1024 * 1024.0; 8 | if (value > gb) { 9 | let temp = value / gb; 10 | return temp.toFixed(2) + "GB"; 11 | } 12 | let mb = 1024 * 1024.0; 13 | if (value > mb) { 14 | let temp = value / mb; 15 | return temp.toFixed(2) + "MB"; 16 | } 17 | let b = 1024.0; 18 | if (value > b) { 19 | let temp = value / b; 20 | return temp.toFixed(2) + "KB"; 21 | } 22 | return value + "B"; 23 | } 24 | -------------------------------------------------------------------------------- /src/core/shared/common/VerifyData.ts: -------------------------------------------------------------------------------- 1 | interface JwtPayload { 2 | [key: string]: any; 3 | iss?: string | undefined; 4 | sub?: string | undefined; 5 | aud?: string | string[] | undefined; 6 | exp?: number | undefined; 7 | nbf?: number | undefined; 8 | iat?: number | undefined; 9 | jti?: string | undefined; 10 | } 11 | 12 | export interface VerifyData extends JwtPayload { 13 | valid: boolean; 14 | licenseId: string; 15 | deviceId: string; 16 | licenseType: "online" | "offline"; 17 | validFrom?: number; 18 | validUntil?: number; 19 | remainingDays?: number; 20 | } 21 | -------------------------------------------------------------------------------- /src/entity/history/SeniorSearchHistory.ts: -------------------------------------------------------------------------------- 1 | import Base from "@/entity/Base"; 2 | 3 | export interface SeniorSearchHistoryIndex extends Base { 4 | 5 | /** 6 | * 名字。唯一 7 | */ 8 | name: string; 9 | 10 | } 11 | 12 | /** 13 | * 历史记录 14 | * */ 15 | export interface SeniorSearchHistoryRecord { 16 | 17 | id: number; 18 | 19 | /** 20 | * 内容 21 | */ 22 | body: string; 23 | 24 | } 25 | 26 | 27 | export function getDefaultSeniorSearchHistoryRecord(): SeniorSearchHistoryRecord { 28 | return { 29 | id: 0, 30 | body: '', 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/components/version-manager/updateTo3.ts: -------------------------------------------------------------------------------- 1 | import {useUrlStore} from "@/store"; 2 | import Dexie from "dexie"; 3 | 4 | 5 | class DexieInstance extends Dexie { 6 | constructor(tableName: string) { 7 | super(tableName); 8 | this.version(5).stores({ 9 | url: '++id, &name, &value, sequence', 10 | }) 11 | } 12 | 13 | } 14 | 15 | export async function updateTo3ByWeb() { 16 | const instance = new DexieInstance('es-client'); 17 | const items = await instance.table('url').toArray(); 18 | for (let item of items) { 19 | await useUrlStore().add(item.value); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/ClusterHealth.ts: -------------------------------------------------------------------------------- 1 | export interface ClusterHealth { 2 | cluster_name: string; 3 | status: string; 4 | timed_out: boolean; 5 | number_of_nodes: number; 6 | number_of_data_nodes: number; 7 | active_primary_shards: number; 8 | active_shards: number; 9 | relocating_shards: number; 10 | initializing_shards: number; 11 | unassigned_shards: number; 12 | delayed_unassigned_shards: number; 13 | number_of_pending_tasks: number; 14 | number_of_in_flight_fetch: number; 15 | task_max_waiting_in_queue_millis: number; 16 | active_shards_percent_as_number: string; 17 | } 18 | -------------------------------------------------------------------------------- /src/domain/es/ClusterHealth.ts: -------------------------------------------------------------------------------- 1 | export interface ClusterHealth { 2 | cluster_name: string; 3 | status: string; 4 | timed_out: boolean; 5 | number_of_nodes: number; 6 | number_of_data_nodes: number; 7 | active_primary_shards: number; 8 | active_shards: number; 9 | relocating_shards: number; 10 | initializing_shards: number; 11 | unassigned_shards: number; 12 | delayed_unassigned_shards: number; 13 | number_of_pending_tasks: number; 14 | number_of_in_flight_fetch: number; 15 | task_max_waiting_in_queue_millis: number; 16 | active_shards_percent_as_number: string; 17 | } 18 | -------------------------------------------------------------------------------- /src/entity/history/SeniorSearchRequest.ts: -------------------------------------------------------------------------------- 1 | export interface SeniorSearchRequest { 2 | id: number; 3 | // 最大64 4 | name: string; 5 | // 最大255 6 | description: string; 7 | } 8 | 9 | export interface SeniorSearchRequestContent extends SeniorSearchRequest { 10 | method: string; 11 | url: string; 12 | body: string; 13 | } 14 | 15 | export function createSeniorSearchRequestContent(): SeniorSearchRequestContent { 16 | return { 17 | id: Date.now(), 18 | name: '', 19 | description: '', 20 | method: 'POST', 21 | url: '', 22 | body: '' 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/core/util/lang/RecordUtil.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 删除对象中的空值 3 | * @param obj 4 | * @param filter 5 | */ 6 | export const shake = ( 7 | obj: Record, 8 | filter?: (value: any) => boolean 9 | ): Record => { 10 | if (!filter) { 11 | filter = (e) => e === undefined; 12 | } 13 | if (!obj) return {}; 14 | const keys = Object.keys(obj); 15 | return keys.reduce( 16 | (acc, key) => { 17 | if (filter(obj[key])) { 18 | return acc; 19 | } else { 20 | acc[key] = obj[key]; 21 | return acc; 22 | } 23 | }, 24 | {} as Record 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /src-tauri/capabilities/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../gen/schemas/desktop-schema.json", 3 | "identifier": "default", 4 | "description": "enables the default permissions", 5 | "windows": [ 6 | "main" 7 | ], 8 | "permissions": [ 9 | "core:default", 10 | "http:default", 11 | { 12 | "identifier": "http:default", 13 | "allow": [ 14 | { 15 | "url": "https://*" 16 | }, 17 | { 18 | "url": "http://*" 19 | }, 20 | { 21 | "url": "http://*:*/*" 22 | } 23 | ] 24 | }, 25 | "updater:default", 26 | "process:default" 27 | ] 28 | } -------------------------------------------------------------------------------- /src/domain/es/DocumentSearchResult.ts: -------------------------------------------------------------------------------- 1 | export interface DocumentSearchResult { 2 | _scroll_id?: string; 3 | took: number; 4 | timed_out: boolean; 5 | _shards: Shards; 6 | hits: Hits; 7 | } 8 | 9 | export interface Hits { 10 | total: number | { 11 | value: number 12 | }; 13 | max_score: number; 14 | hits: Array>; 15 | } 16 | 17 | export interface Hit { 18 | _index: string; 19 | _type: string; 20 | _id: string; 21 | _score: number; 22 | _source: T; 23 | } 24 | 25 | 26 | interface Shards { 27 | total: number; 28 | successful: number; 29 | skipped: number; 30 | failed: number; 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist* 4 | /out 5 | src-edge/es-client 6 | chrome.crx 7 | chrome.pem 8 | src-firefox/es-client 9 | 10 | 11 | # local env files 12 | .env.local 13 | .env.*.local 14 | 15 | # Log files 16 | npm-debug.log* 17 | yarn-debug.log* 18 | yarn-error.log* 19 | pnpm-debug.log* 20 | 21 | # Editor directories and files 22 | .idea 23 | *.suo 24 | *.ntvs* 25 | *.njsproj 26 | *.sln 27 | *.sw? 28 | 29 | # 依赖分析 30 | /stats.html 31 | 32 | 33 | # 谷歌浏览器V3 34 | /src-chrome/es-client 35 | /src-chrome/src-chrome.zip 36 | 37 | # edge浏览器 38 | 39 | /src-edge/es-client 40 | /src-edge/src-edge.zip 41 | 42 | # web 43 | /dist 44 | 45 | -------------------------------------------------------------------------------- /src-edge/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "__MSG_extensionName__", 4 | "description": "__MSG_extensionDescription__", 5 | "default_locale": "en", 6 | "version": "3.2.2", 7 | "content_security_policy": { 8 | }, 9 | "icons": { 10 | "96": "icons/logo_200.png", 11 | "128": "icons/logo_200.png" 12 | }, 13 | "action": { 14 | "default_title": "es-client", 15 | "default_icon": "icons/logo_200.png" 16 | }, 17 | "background": { 18 | "service_worker": "src/background.js", 19 | "type": "module" 20 | }, 21 | "permissions": [ 22 | ], 23 | "host_permissions": [ 24 | "*://*/" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /src-chrome/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "version": "3.2.2", 4 | "name": "__MSG_extensionName__", 5 | "description": "__MSG_extensionDescription__", 6 | "default_locale": "en", 7 | "content_security_policy": { 8 | }, 9 | "icons": { 10 | "96": "icons/logo_200.png", 11 | "128": "icons/logo_200.png" 12 | }, 13 | "action": { 14 | "default_title": "es-client", 15 | "default_icon": "icons/logo_200.png" 16 | }, 17 | "background": { 18 | "service_worker": "src/background.js", 19 | "type": "module" 20 | }, 21 | "permissions": [ 22 | ], 23 | "host_permissions": [ 24 | "*://*/" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /src/entity/history/BaseSearchHistory.ts: -------------------------------------------------------------------------------- 1 | import {BaseQuery} from "@/entity/BaseQuery"; 2 | import BaseOrder from "@/entity/BaseOrder"; 3 | import Base from "@/entity/Base"; 4 | 5 | /** 6 | * 历史记录 7 | * */ 8 | export default interface BaseSearchHistory extends Base{ 9 | 10 | /** 11 | * URL的id 12 | */ 13 | urlId: number 14 | 15 | /** 16 | * 名字。唯一 17 | */ 18 | name: string; 19 | 20 | /** 21 | * 索引 22 | */ 23 | index: string; 24 | 25 | /** 26 | * 条件 27 | */ 28 | conditions: Array; 29 | 30 | /** 31 | * 排序 32 | */ 33 | orders: Array; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/page/data-browse/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 18 | 21 | -------------------------------------------------------------------------------- /src/page/dev-tool/func.ts: -------------------------------------------------------------------------------- 1 | import { TreeOptionData } from "tdesign-vue-next"; 2 | import { DevToolFileItem } from "@/entity"; 3 | import { ListToTree } from "$/util/lang/TreeUtil"; 4 | 5 | export function listToTree(list: Array): Array { 6 | const transformer = new ListToTree({ 7 | idKey: "id", 8 | parentIdKey: "parentId", 9 | labelKey: "name", 10 | rootNodeId: "0", 11 | handle: (item: DevToolFileItem) => { 12 | return { 13 | icon: item.folder ? "folder" : "file", 14 | _source: item 15 | }; 16 | } 17 | }); 18 | 19 | return transformer.transform(list); 20 | } 21 | -------------------------------------------------------------------------------- /src/module/version-update/index.tsx: -------------------------------------------------------------------------------- 1 | import {showDialog} from "@/utils/model/DialogUtil"; 2 | import {Constant} from "@/global/Constant"; 3 | import UpdateItem from "@/components/update-item/index.vue"; 4 | 5 | export function showVersionUpdateDialog() { 6 | const log = Constant.logs[0]; 7 | showDialog("版本更新", () => 8 |
9 |
10 | 恭喜你成功更新到 11 | {Constant.version} 12 |
13 |
本次更新如下
14 | 15 |
, { 16 | width: "600px" 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/utils/ElasticsearchType.ts: -------------------------------------------------------------------------------- 1 | export function encodeIndexType(index: string, type: string): string { 2 | return `${type}:${index}`; 3 | } 4 | 5 | export function decodeIndexType(indexType: string): { index: string; type: string } { 6 | const [type, ...index] = indexType.split(":"); 7 | return { type, index: index.join(":") }; 8 | } 9 | 10 | export function encodeTypeField(type: string, field: string): string { 11 | return `${type}:${field}`; 12 | } 13 | 14 | export function decodeTypeField(typeField: string): { type: string; field: string } { 15 | const [type, ...field] = typeField.split(":"); 16 | return { type, field: field.join(":") }; 17 | } 18 | -------------------------------------------------------------------------------- /src/entity/event/RequestRecordEvent.ts: -------------------------------------------------------------------------------- 1 | export default interface RequestRecordEvent { 2 | 3 | id: number; 4 | 5 | /** 6 | * 创建时间 7 | */ 8 | createTime: Date; 9 | 10 | /** 11 | * 请求连接 12 | */ 13 | url: string; 14 | 15 | /** 16 | * 请求方法 17 | */ 18 | method: string; 19 | 20 | /** 21 | * 请求体 22 | */ 23 | body: string; 24 | 25 | /** 26 | * 状态码 27 | */ 28 | code: number; 29 | 30 | /** 31 | * 响应内容 32 | */ 33 | response: any; 34 | 35 | /** 36 | * 请求耗时,毫秒 37 | */ 38 | time: number; 39 | 40 | /** 41 | * 消息 42 | */ 43 | message: string; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/components/AppLink/AppLink.vue: -------------------------------------------------------------------------------- 1 | 4 | 23 | 26 | -------------------------------------------------------------------------------- /src/domain/IndexInstance.ts: -------------------------------------------------------------------------------- 1 | import {Setting} from "@/domain/es/IndexBase"; 2 | import {useGlobalSettingStore} from "@/store"; 3 | 4 | /** 5 | * 索引实体类 6 | */ 7 | export interface IndexInstance { 8 | 9 | /** 10 | * 索引名称 11 | */ 12 | name: string; 13 | 14 | /** 15 | * 设置 16 | */ 17 | settings: Setting; 18 | 19 | /** 20 | * 映射 21 | */ 22 | mappings: string; 23 | } 24 | 25 | export function getDefaultIndexInstance(): IndexInstance { 26 | return { 27 | name: '', 28 | settings: { 29 | number_of_shards: useGlobalSettingStore().getDefaultShard, 30 | number_of_replicas: useGlobalSettingStore().getDefaultReplica 31 | }, 32 | mappings: "{}" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/page/dev-tool/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 20 | 22 | -------------------------------------------------------------------------------- /src/core/util/file/WebPath.ts: -------------------------------------------------------------------------------- 1 | export function extname(path: string): string { 2 | const items = path.split("."); 3 | if (items.length === 1) { 4 | return ""; 5 | } 6 | return items[items.length - 1]; 7 | } 8 | 9 | export function basename(path: string): string { 10 | const items = path.split("/"); 11 | if (items.length > 1) { 12 | return items.pop()!; 13 | } 14 | return path; 15 | } 16 | 17 | export function getFolder(path: string): string { 18 | const lastIndex = path.lastIndexOf("/"); 19 | if (lastIndex === -1) { 20 | return "/"; 21 | } 22 | return path.substring(0, lastIndex); 23 | } 24 | 25 | export function joinPath(folder: string, name: string): string { 26 | return `${folder}/${name}`; 27 | } 28 | -------------------------------------------------------------------------------- /src-tauri/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg_attr(mobile, tauri::mobile_entry_point)] 2 | pub fn run() { 3 | tauri::Builder::default() 4 | .plugin(tauri_plugin_updater::Builder::new().build()) 5 | .plugin(tauri_plugin_process::init()) 6 | .plugin(tauri_plugin_http::init()) 7 | .setup(|app| { 8 | if cfg!(debug_assertions) { 9 | app.handle().plugin( 10 | tauri_plugin_log::Builder::default() 11 | .level(log::LevelFilter::Info) 12 | .build(), 13 | )?; 14 | } 15 | Ok(()) 16 | }) 17 | .run(tauri::generate_context!()) 18 | .expect("error while running tauri application"); 19 | } 20 | -------------------------------------------------------------------------------- /src/components/SqlEditor/language/configuration.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from "monaco-editor"; 2 | 3 | export const configuration: monaco.languages.LanguageConfiguration = { 4 | comments: { 5 | // blockComment: [""], 6 | lineComment: "--" 7 | }, 8 | brackets: [ 9 | ["{", "}"], 10 | ["[", "]"] 11 | ], 12 | autoClosingPairs: [ 13 | { open: "{", close: "}" }, 14 | { open: "[", close: "]" }, 15 | { open: '"', close: '"' } 16 | ], 17 | surroundingPairs: [ 18 | { open: "(", close: ")" }, 19 | { open: "[", close: "]" } 20 | ], 21 | folding: { 22 | markers: { 23 | start: new RegExp("^\\s*"), 24 | end: new RegExp("^\\s*") 25 | } 26 | } 27 | }; -------------------------------------------------------------------------------- /src/core/elasticsearch-client/components/IndexTypeBuild.ts: -------------------------------------------------------------------------------- 1 | import { IndexMapping } from "$/shared/elasticsearch"; 2 | 3 | /** 4 | * 索引类型构造器,将索引类型扁平化 5 | * 至少存在一个_doc的类型 6 | * 7 | * @param mappings 索引映射 8 | * @param version 当前版本 9 | */ 10 | export const indexTypeBuild = ( 11 | mappings: Record | IndexMapping, 12 | version: number 13 | ): Array => { 14 | if (version <= 6) { 15 | // es版本小于6.0.0,则一定有类型 16 | // 全部类型 17 | return Object.keys(mappings); 18 | } else if (version >= 8) { 19 | return ["_doc"]; 20 | } else { 21 | if (mappings.properties && typeof mappings.properties === "object") { 22 | return Object.keys(mappings); 23 | } else { 24 | return ["_doc"]; 25 | } 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /src/domain/Schema.ts: -------------------------------------------------------------------------------- 1 | export default interface Schema { 2 | 3 | /** 4 | * The URI of the schema, which is also the identifier of the schema. 5 | */ 6 | readonly uri: string; 7 | /** 8 | * A list of glob patterns that describe for which file URIs the JSON schema will be used. 9 | * '*' and '**' wildcards are supported. Exclusion patterns start with '!'. 10 | * For example '*.schema.json', 'package.json', '!foo*.schema.json', 'foo/**\/BADRESP.json'. 11 | * A match succeeds when there is at least one pattern matching and last matching pattern does not start with '!'. 12 | */ 13 | readonly fileMatch?: string[]; 14 | /** 15 | * The schema for the given URI. 16 | */ 17 | readonly schema?: any; 18 | 19 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off", 11 | "cSpell.words": [ 12 | "codemirror", 13 | "doption", 14 | "lodis", 15 | "popconfirm", 16 | "sortablejs", 17 | "tauri", 18 | "tsbrowser", 19 | "unplugin", 20 | "utools", 21 | "vueuse" 22 | ], 23 | "editor.suggest.snippetsPreventQuickSuggestions": false, 24 | "aiXcoder.showTrayIcon": true 25 | } -------------------------------------------------------------------------------- /src/domain/es/IndexHealth.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 索引健康值 3 | */ 4 | export default interface IndexHealth { 5 | 6 | /** 7 | * 集群名称 8 | */ 9 | cluster_name: string; 10 | 11 | /** 12 | * 状态 13 | */ 14 | status: string; 15 | 16 | /** 17 | * 是否超时 18 | */ 19 | timed_out: boolean; 20 | 21 | /** 22 | * 节点数 23 | */ 24 | number_of_nodes: number; 25 | number_of_data_nodes: number; 26 | active_primary_shards: number; 27 | active_shards: number; 28 | relocating_shards: number; 29 | initializing_shards: number; 30 | unassigned_shards: number; 31 | delayed_unassigned_shards: number; 32 | number_of_pending_tasks: number; 33 | number_of_in_flight_fetch: number; 34 | task_max_waiting_in_queue_millis: number; 35 | active_shards_percent_as_number: number; 36 | } -------------------------------------------------------------------------------- /src/domain/es/IndexInfo.ts: -------------------------------------------------------------------------------- 1 | import {Mapping, Setting} from "@/domain/es/IndexBase"; 2 | 3 | export interface IndexInfo { 4 | 5 | /** 6 | * 状态 7 | */ 8 | state: string; 9 | 10 | /** 11 | * 别名 12 | */ 13 | aliases: Array; 14 | 15 | /** 16 | * 映射 17 | */ 18 | mappings: Record; 19 | 20 | /** 21 | * 设置 22 | */ 23 | settings: SettingInfo; 24 | 25 | } 26 | 27 | export interface SettingInfo extends Setting { 28 | 29 | /** 30 | * 创建日期,时间戳 31 | */ 32 | creation_date: string; 33 | 34 | /** 35 | * UUID 36 | */ 37 | uuid: string; 38 | 39 | /** 40 | * 版本 41 | */ 42 | version: { 43 | created: string; 44 | }; 45 | 46 | /** 47 | * 名字 48 | */ 49 | provided_name: string; 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/components/RestClientEditor/configuration.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from "monaco-editor"; 2 | 3 | const configuration = { 4 | comments: { 5 | blockComment: [""], 6 | lineComment: "#" 7 | }, 8 | brackets: [ 9 | ["{", "}"], 10 | ["[", "]"] 11 | ], 12 | autoClosingPairs: [ 13 | { open: "{", close: "}" }, 14 | { open: "[", close: "]" }, 15 | { open: '"', close: '"' } 16 | ], 17 | surroundingPairs: [ 18 | { open: "(", close: ")" }, 19 | { open: "[", close: "]" } 20 | ], 21 | folding: { 22 | markers: { 23 | start: new RegExp("^\\s*"), 24 | end: new RegExp("^\\s*") 25 | } 26 | } 27 | } as monaco.languages.LanguageConfiguration; 28 | 29 | export default configuration; 30 | -------------------------------------------------------------------------------- /src/store/components/HomeStore.ts: -------------------------------------------------------------------------------- 1 | export enum OrderType { 2 | NAME_ASC = 1, 3 | NAME_DESC = 2, 4 | /** 5 | * @deprecated 6 | */ 7 | SIZE_ASC = 3, 8 | /** 9 | * @deprecated 10 | */ 11 | SIZE_DESC = 4, 12 | /** 13 | * @deprecated 14 | */ 15 | DOCS_ASC = 5, 16 | /** 17 | * @deprecated 18 | */ 19 | DOCS_DESC = 6 20 | } 21 | 22 | export enum Status { 23 | 24 | NONE = 0, 25 | 26 | OPEN = 1, 27 | 28 | CLOSE = 2 29 | 30 | } 31 | 32 | // useSessionStorage('home-search-keyword', '') 33 | export const useHomeStore = createGlobalState( 34 | () => { 35 | // state 36 | const keyword = ref(''); 37 | const order = ref(1); 38 | const status = ref(Status.NONE) 39 | 40 | return {keyword, order, status} 41 | } 42 | ) 43 | -------------------------------------------------------------------------------- /src/icon/TableIcon.vue: -------------------------------------------------------------------------------- 1 | 9 | 15 | -------------------------------------------------------------------------------- /src/components/SystemNotify/AnnouncementApi.ts: -------------------------------------------------------------------------------- 1 | import {useRequestJson} from "@/plugins/native/axios"; 2 | import {Announcement} from "./AnnouncementTypes"; 3 | 4 | export interface AnnouncementResponse { 5 | success: boolean; 6 | message: string; 7 | data: { 8 | announcements: Announcement[]; 9 | count: number; 10 | }; 11 | code: number; 12 | } 13 | 14 | export async function getAnnouncements(offset: number = 0, limit: number = 10): Promise { 15 | if (import.meta.env.DEV) { 16 | return {success: true, message: '', code: 200, data: {announcements: [], count: 0}} 17 | } 18 | return useRequestJson( 19 | `https://es-client.esion.xyz/api/announcement/list?offset=${offset}&limit=${limit}`, 20 | { 21 | method: 'GET' 22 | } 23 | ); 24 | } -------------------------------------------------------------------------------- /src/page/more/components/update.vue: -------------------------------------------------------------------------------- 1 | 17 | 23 | 26 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/domain/IlmExplainResponse.ts: -------------------------------------------------------------------------------- 1 | export interface IlmExplainResponse { 2 | indices: { 3 | [indexName: string]: IlmExplainIndexInfo; 4 | }; 5 | } 6 | 7 | interface IlmExplainIndexInfo { 8 | index: string; 9 | managed: boolean; 10 | 11 | // 以下字段仅当 managed === true 时存在 12 | policy?: string; 13 | lifecycle_date_millis?: number; 14 | phase?: string; 15 | action?: string; 16 | step?: string; 17 | phase_time_millis?: number; 18 | action_time_millis?: number; 19 | step_time_millis?: number; 20 | 21 | // 可选:错误或步骤详情(取决于版本和状态) 22 | failed_step?: string; 23 | step_info?: { 24 | type?: string; 25 | message?: string; 26 | cause?: { 27 | type: string; 28 | reason: string; 29 | }; 30 | }; 31 | // 注意:某些版本可能还会包含 'index_creation_date_millis' 等字段 32 | } 33 | -------------------------------------------------------------------------------- /src/page/dashboard/Analysis/ShowQuestion.tsx: -------------------------------------------------------------------------------- 1 | import { DialogPlugin, Paragraph } from "tdesign-vue-next"; 2 | import i18n from "@/i18n"; 3 | 4 | const t = (key: string) => i18n.global.t(key); 5 | 6 | export function showFieldType() { 7 | DialogPlugin({ 8 | header: t('module.dashboard.field_type_analysis'), 9 | placement: "center", 10 | default: () => ( 11 | {t('module.dashboard.analysis_help')} 12 | ), 13 | draggable: true, 14 | footer: false 15 | }); 16 | } 17 | 18 | export function showAnalyzer() { 19 | DialogPlugin({ 20 | header: t('module.dashboard.analyzer_analysis'), 21 | placement: "center", 22 | default: () => ( 23 | {t('module.dashboard.analysis_help')} 24 | ), 25 | draggable: true, 26 | footer: false 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/domain/IndexInfo.ts: -------------------------------------------------------------------------------- 1 | import { IndexMapping, IndexSettings } from "$/shared/elasticsearch"; 2 | 3 | export interface IndexInfo { 4 | /** 5 | * 状态 6 | */ 7 | state: "open" | "close"; 8 | 9 | /** 10 | * 别名 11 | */ 12 | aliases: Array; 13 | 14 | /** 15 | * 映射,类型 => mapping,对于v7及以上,只有一个,且为_doc 16 | */ 17 | mappings: Record | IndexMapping; 18 | 19 | /** 20 | * 设置 21 | */ 22 | settings: SettingInfo; 23 | } 24 | 25 | export interface SettingInfo extends IndexSettings { 26 | /** 27 | * 创建日期,时间戳 28 | */ 29 | creation_date: string; 30 | 31 | /** 32 | * UUID 33 | */ 34 | uuid: string; 35 | 36 | /** 37 | * 版本 38 | */ 39 | version: { 40 | created: string; 41 | }; 42 | 43 | /** 44 | * 名字 45 | */ 46 | provided_name: string; 47 | } 48 | -------------------------------------------------------------------------------- /src/page/data-browse/tab/DataBrowserIndexTab.vue: -------------------------------------------------------------------------------- 1 | 11 | 24 | 29 | -------------------------------------------------------------------------------- /src/page/senior-search/layout/senior-search-editor/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 23 | 26 | -------------------------------------------------------------------------------- /src/hooks/UseQuery.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from "vue"; 2 | 3 | export interface UseQueryResult { 4 | data: Ref; 5 | loading: Ref; 6 | error: Ref; 7 | reload: (...args: any[]) => void; 8 | } 9 | 10 | export function useQuery( 11 | defaultValue: T, 12 | queryFn: (...args: any[]) => Promise 13 | ): UseQueryResult { 14 | const data = ref(defaultValue) as Ref; 15 | const loading = ref(true); 16 | const error = ref(null); 17 | 18 | const reload = async (...args: any[]) => { 19 | loading.value = true; 20 | error.value = null; 21 | try { 22 | data.value = await queryFn(...args); 23 | } catch (e) { 24 | error.value = e as Error; 25 | } 26 | loading.value = false; 27 | }; 28 | 29 | reload().then(() => console.debug("初始化查询")); 30 | 31 | return { data, loading, error, reload }; 32 | } 33 | -------------------------------------------------------------------------------- /src/components/RestClientEditor/index.ts: -------------------------------------------------------------------------------- 1 | import * as monaco from "monaco-editor"; 2 | import {language} from "@/components/RestClientEditor/language"; 3 | import configuration from "@/components/RestClientEditor/configuration"; 4 | import provider from "@/components/RestClientEditor/provider"; 5 | import {restFoldingRangeProvider} from "@/components/RestClientEditor/foldingRange"; 6 | 7 | export {default as RestClientEditor} from "./index.vue"; 8 | 9 | export function registerLanguageForHttp() { 10 | monaco.languages.register({id: 'http'}); 11 | // 语法高亮 12 | monaco.languages.setMonarchTokensProvider('http', language); 13 | // 语言括号配置 14 | monaco.languages.setLanguageConfiguration('http', configuration); 15 | // 语法提示 16 | monaco.languages.registerCompletionItemProvider('http', provider); 17 | // 代码折叠 18 | monaco.languages.registerFoldingRangeProvider('http', restFoldingRangeProvider) 19 | } -------------------------------------------------------------------------------- /src/components/view/MonacoView/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 29 | 34 | 35 | -------------------------------------------------------------------------------- /src-firefox/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "es-client", 4 | "version": "3.2.2", 5 | "description": "elasticsearch管理客户端", 6 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", 7 | "icons": { 8 | "16": "icons/logo_16.png", 9 | "48": "icons/logo_16.png" 10 | }, 11 | "homepage_url": "https://gitee.com/qiaoshengda/es-client", 12 | "permissions": [ 13 | "http://*/*", 14 | "https://*/*" 15 | ], 16 | "browser_specific_settings": { 17 | "gecko": { 18 | "id": "es-client@esion.xyz" 19 | } 20 | }, 21 | "browser_action": { 22 | "default_icon": "icons/logo_16.png", 23 | "default_title": "es-client" 24 | }, 25 | "background": { 26 | "scripts": [ 27 | "src/index.js" 28 | ] 29 | }, 30 | "author": "云落天都" 31 | } 32 | -------------------------------------------------------------------------------- /src-tauri/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "es-client" 3 | version = "3.2.2" 4 | description = "elasticsearch gui client" 5 | authors = ["落雨不悔"] 6 | license = "Apache-2.0" 7 | repository = "https://github.com/q2316367743/es-client" 8 | edition = "2021" 9 | rust-version = "1.77.2" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [lib] 14 | name = "app_lib" 15 | crate-type = ["staticlib", "cdylib", "rlib"] 16 | 17 | [build-dependencies] 18 | tauri-build = { version = "2.5.3", features = [] } 19 | 20 | [dependencies] 21 | serde_json = "1.0" 22 | serde = { version = "1.0", features = ["derive"] } 23 | log = "0.4" 24 | tauri = { version = "2.9.5", features = [] } 25 | tauri-plugin-log = "2" 26 | tauri-plugin-http = "2" 27 | tauri-plugin-process = "2" 28 | 29 | [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] 30 | tauri-plugin-updater = "2" 31 | -------------------------------------------------------------------------------- /src/core/util/lang/PromiseUtil.ts: -------------------------------------------------------------------------------- 1 | function sleep(ms: number) { 2 | return new Promise((resolve) => setTimeout(resolve, ms)); 3 | } 4 | 5 | export async function promiseRetry( 6 | fn: () => Promise, 7 | options: { 8 | attempts?: number; // 最多重试次数(含第一次) 9 | delay?: number; // 第一次重试间隔(ms) 10 | backoff?: number; // 退避系数,默认 2 11 | onRetry?: (err: Error, left: number) => void; 12 | } = {} 13 | ): Promise { 14 | const { attempts = 3, delay = 100, backoff = 2, onRetry = () => {} } = options; 15 | 16 | let left = attempts; 17 | let currentDelay = delay; 18 | 19 | while (left > 0) { 20 | try { 21 | return await fn(); 22 | } catch (err) { 23 | left--; 24 | if (left === 0) throw err; // 最后一次也失败就抛出去 25 | onRetry(err as Error, left); 26 | await sleep(currentDelay); 27 | currentDelay *= backoff; 28 | } 29 | } 30 | throw new Error("unreachable"); 31 | } 32 | -------------------------------------------------------------------------------- /src/icon/MoonIcon.vue: -------------------------------------------------------------------------------- 1 | 9 | 15 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/AllocationExplain.ts: -------------------------------------------------------------------------------- 1 | export interface AllocationExplainBody { 2 | index: string; 3 | shard: number; 4 | primary: boolean; 5 | } 6 | 7 | export interface AllocationExplainResult { 8 | index: string; 9 | shard: number; 10 | primary: boolean; 11 | current_state: string; 12 | unassigned_info?: { 13 | reason: string; 14 | at: string; 15 | last_allocation_status: string; 16 | }; 17 | can_allocate: "yes" | "no" | "throttled"; 18 | // ⬇️ 正确字段名是 allocate_explanation,不是 explanation! 19 | allocate_explanation?: string; 20 | 21 | node_allocation_decisions?: Array<{ 22 | node_id: string; 23 | node_name: string; 24 | transport_address: string; 25 | node_attributes: Record; 26 | node_decision: "yes" | "no" | "throttled"; 27 | deciders?: Array<{ 28 | decider: string; 29 | decision: string; 30 | explanation: string; // 节点级解释 31 | }>; 32 | }>; 33 | } 34 | -------------------------------------------------------------------------------- /src/page/data-browse/component/DbHeader/components/DbPage.vue: -------------------------------------------------------------------------------- 1 | 4 | 32 | 33 | -------------------------------------------------------------------------------- /test/SqlParser.ts: -------------------------------------------------------------------------------- 1 | import { parseSQL, conditionToES } from '../src/core/util/file/SqlParser'; 2 | 3 | // bun 环境测试 4 | const testSQL = ` 5 | SELECT CONCAT(name, '!!') AS \`full name\`, DATE_FORMAT(created_at, '%Y') 6 | FROM users 7 | WHERE (age >= 18 AND status TERM 'active') 8 | AND (role = 'admin' OR role = 'moderator') 9 | AND email IS NOT NULL 10 | AND name LIKE 'john%' 11 | ORDER BY created_at DESC 12 | LIMIT 10 OFFSET 20 13 | `; 14 | 15 | try { 16 | const ast = parseSQL(testSQL); 17 | console.log('✅ AST:', JSON.stringify(ast, null, 2)); 18 | if (ast.where) { 19 | console.log('✅ ES DSL:', JSON.stringify(conditionToES(ast.where), null, 2)); 20 | } 21 | } catch (e) { 22 | console.error('❌ Parse error:', e); 23 | } 24 | 25 | // try { 26 | // const ast = parseSQL("select *, b as `ss` from users") 27 | // console.log('✅ AST:', JSON.stringify(ast, null, 2)); 28 | // } catch (e) { 29 | // console.error('❌ Parse error:', e); 30 | // } -------------------------------------------------------------------------------- /src/core/elasticsearch-client/utils/BuildUrlWithVersion.ts: -------------------------------------------------------------------------------- 1 | import { Url } from "$/entity"; 2 | 3 | export const getVersionFirst = (url: Url) => { 4 | const [r1] = (url.version || "").split("."); 5 | if (r1) return Number(r1); 6 | else return 0; 7 | }; 8 | 9 | /** 10 | * 构建搜索URL 11 | * @param url 12 | * @param index 13 | * @param type 14 | */ 15 | export function buildSearchUrl(url: Url, index: string, type: string) { 16 | return getVersionFirst(url) >= 8 ? `/${index}/_search` : `/${index}/${type || "_doc"}/_search`; 17 | } 18 | 19 | export function buildDeleteByQueryUrl(url: Url, index: string, type: string) { 20 | return getVersionFirst(url) >= 8 21 | ? `/${index}/_delete_by_query` 22 | : `/${index}/${type || "_doc"}/_delete_by_query`; 23 | } 24 | 25 | export function buildUpdateByQueryUrl(url: Url, index: string, type: string) { 26 | return getVersionFirst(url) >= 8 27 | ? `/${index}/_update_by_query` 28 | : `/${index}/${type || "_doc"}/_update_by_query`; 29 | } 30 | -------------------------------------------------------------------------------- /src/page/data-browse/component/DbHeader/components/DbSimpleItem.vue: -------------------------------------------------------------------------------- 1 | 17 | 43 | 44 | -------------------------------------------------------------------------------- /src/domain/EditorSetting.ts: -------------------------------------------------------------------------------- 1 | export interface EditorSetting { 2 | 3 | /** 4 | * 编辑器字体大小 5 | */ 6 | fontSize: number; 7 | 8 | /** 9 | * 小地图是否展示 10 | */ 11 | minimap: boolean; 12 | 13 | /** 14 | * Control the wrapping of the editor. 15 | * When `wordWrap` = "off", the lines will never wrap. 16 | * When `wordWrap` = "on", the lines will wrap at the viewport width. 17 | * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. 18 | * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). 19 | * Defaults to "off". 20 | */ 21 | wordWrap: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; 22 | 23 | /** 24 | * 运行文字颜色 25 | */ 26 | runColor: string; 27 | 28 | } 29 | 30 | export function getDefaultEditorSettingValue(): EditorSetting { 31 | return { 32 | fontSize: 14, 33 | minimap: false, 34 | wordWrap: 'on' as 'off' | 'on' | 'wordWrapColumn' | 'bounded', 35 | runColor: '#0d7d6c' 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "esModuleInterop": true, 12 | "skipLibCheck": true, 13 | "jsxImportSource": "vue", 14 | "lib": [ 15 | "esnext", 16 | "dom" 17 | ], 18 | "baseUrl": "./", 19 | "paths": { 20 | "@/*": [ 21 | "./src/*" 22 | ], 23 | "$/*": [ 24 | "./src/core/*" 25 | ] 26 | }, 27 | }, 28 | "include": [ 29 | "src/**/*.ts", 30 | "src/**/*.d.ts", 31 | "src/**/*.tsx", 32 | "src/**/*.vue", 33 | "auto-imports.d.ts", 34 | "components.d.ts" 35 | ], 36 | "exclude": [ 37 | "node_modules", 38 | "electron", 39 | "src-edge", 40 | "src-firefox", 41 | "src-server", 42 | "src-electron", 43 | "src-tauri" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /src/core/entity/components/CoreUrl.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 实例平台 3 | */ 4 | export type UrlPlatform = "elasticsearch" | "opensearch" | "easysearch"; 5 | 6 | export interface Url { 7 | /** 8 | * ID 9 | */ 10 | id: string; 11 | 12 | /** 13 | * 创建时间 14 | */ 15 | created_at: number; 16 | 17 | /** 18 | * 更新时间 19 | */ 20 | updated_at: number; 21 | 22 | /** 23 | * 链接名称 24 | */ 25 | name: string; 26 | 27 | /** 28 | * 链接值 29 | */ 30 | value: string; 31 | 32 | /** 33 | * 排序 34 | */ 35 | sequence: number; 36 | /** 37 | * 是否需要认证 38 | */ 39 | is_auth: 0 | 1; 40 | 41 | /** 42 | * 认证类型那个,默认Basic认证 43 | * 1-Basic认证,2-请求头认证,3-Cookie认证 44 | */ 45 | auth_type: 1 | 2 | 3; 46 | 47 | /** 48 | * 用户名 49 | */ 50 | auth_user: string; 51 | 52 | /** 53 | * 密码 54 | */ 55 | auth_password: string; 56 | 57 | /** 58 | * 实例平台 59 | */ 60 | platform: UrlPlatform; 61 | 62 | /** 63 | * 版本信息 64 | */ 65 | version: string; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/hooks/UseQueryApi.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from "vue"; 2 | import { EsRequestError } from "$/shared"; 3 | 4 | export interface UseQueryApiResult { 5 | data: Ref; 6 | loading: Ref; 7 | error: Ref; 8 | reload: (...args: any[]) => Promise; 9 | } 10 | 11 | export function useQueryApi(queryFn: (...args: any[]) => Promise): UseQueryApiResult { 12 | const data = ref(""); 13 | const loading = ref(false); 14 | const error = ref(null); 15 | 16 | const reload = async (...args: any[]) => { 17 | loading.value = true; 18 | error.value = null; 19 | try { 20 | data.value = await queryFn(...args); 21 | } catch (e) { 22 | error.value = e as Error; 23 | if (e instanceof EsRequestError) { 24 | data.value = e.body; 25 | } 26 | throw e; 27 | } finally { 28 | loading.value = false; 29 | } 30 | }; 31 | 32 | // reload().then(() => console.debug("初始化查询")); 33 | 34 | return { data, loading, error, reload }; 35 | } 36 | -------------------------------------------------------------------------------- /src/page/data-browse/tab/DataBrowserQueryTab.vue: -------------------------------------------------------------------------------- 1 | 13 | 32 | -------------------------------------------------------------------------------- /src/page/senior-search/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/strategy/VersionStrategy/impl/V7VersionStrategyImpl.ts: -------------------------------------------------------------------------------- 1 | import VersionStrategy from "@/strategy/VersionStrategy/VersionStrategy"; 2 | import {IndexInstance} from "@/domain/IndexInstance"; 3 | import {IndexCreate} from "@/domain/es/IndexCreate"; 4 | import {Setting} from "@/domain/es/IndexBase"; 5 | 6 | /** 7 | * v6版本策略 8 | */ 9 | export default class V7VersionStrategyImpl implements VersionStrategy { 10 | getVersionExp(): RegExp { 11 | return /^7\.\d+\.\d+$/; 12 | } 13 | 14 | hasType(): boolean { 15 | return false; 16 | } 17 | 18 | private getDefaultBody(setting: Setting): any { 19 | return { 20 | settings: { 21 | number_of_shards: setting.number_of_shards, 22 | number_of_replicas: setting.number_of_replicas 23 | }, 24 | mappings: { 25 | properties: {} 26 | } 27 | } 28 | } 29 | 30 | indexCreateBuild(index: IndexInstance): IndexCreate { 31 | return this.getDefaultBody(index.settings); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/strategy/VersionStrategy/impl/V8VersionStrategyImpl.ts: -------------------------------------------------------------------------------- 1 | import VersionStrategy from "@/strategy/VersionStrategy/VersionStrategy"; 2 | import {IndexInstance} from "@/domain/IndexInstance"; 3 | import {IndexCreate} from "@/domain/es/IndexCreate"; 4 | import {Setting} from "@/domain/es/IndexBase"; 5 | 6 | /** 7 | * v6版本策略 8 | */ 9 | export default class V8VersionStrategyImpl implements VersionStrategy { 10 | getVersionExp(): RegExp { 11 | return /^8\.\d+\.\d+$/; 12 | } 13 | 14 | hasType(): boolean { 15 | return false; 16 | } 17 | 18 | private getDefaultBody(setting: Setting): any { 19 | return { 20 | settings: { 21 | number_of_shards: setting.number_of_shards, 22 | number_of_replicas: setting.number_of_replicas 23 | }, 24 | mappings: { 25 | properties: {} 26 | } 27 | } 28 | } 29 | 30 | indexCreateBuild(index: IndexInstance): IndexCreate { 31 | return this.getDefaultBody(index.settings); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/entity/DataBrowser/DataBrowserQuery.ts: -------------------------------------------------------------------------------- 1 | import LocalNameEnum from "@/enumeration/LocalNameEnum"; 2 | 3 | export const DATA_BROWSER_QUERY_KEY = (urlId: string) => `${LocalNameEnum.LIST_DATA_BROWSER_QUERY}/${urlId}`; 4 | export const DATA_BROWSER_QUERY_ITEM_KEY = ( id: string) => `${LocalNameEnum.ITEM_DATA_BROWSER_QUERY}/${id}`; 5 | 6 | /** 7 | * 数据浏览 - 查询 8 | */ 9 | export interface DataBrowserQueryItem { 10 | id: string; 11 | created_at: number; 12 | updated_at: number; 13 | 14 | url_id: string; 15 | 16 | /** 17 | * 文件名 18 | */ 19 | name: string; 20 | } 21 | 22 | export type DataBrowserQueryBodyMode = "SQL" | "ES|QL"; 23 | 24 | export interface DataBrowserQueryBody { 25 | id: string; 26 | url_id: string; 27 | /** 28 | * 文件内容 29 | */ 30 | content: string; 31 | /** 32 | * 最近50条查询记录 33 | * @type Array 34 | */ 35 | records: Array; 36 | /** 37 | * 查询模式 38 | */ 39 | mode: DataBrowserQueryBodyMode; 40 | } 41 | 42 | export interface DataBrowserQuery extends DataBrowserQueryItem, DataBrowserQueryBody { 43 | } 44 | -------------------------------------------------------------------------------- /src/plugins/Statistics.ts: -------------------------------------------------------------------------------- 1 | import {useUmami} from "@/plugins/umami"; 2 | 3 | export type EventIdentificationEnum = 'update' | 'page_jump' | 'es_version' | 4 | 'func_data_browser' | 'func_base_search' | 'func_senior_search' | 5 | 'func_dashboard'; 6 | 7 | 8 | export class Statistics { 9 | 10 | login() { 11 | useUmami.track('login'); 12 | } 13 | 14 | register() { 15 | useUmami.track('register'); 16 | } 17 | 18 | /** 19 | * 访问某个标签 20 | * @param event 操作 21 | * @param additional 附加 22 | */ 23 | access(event: EventIdentificationEnum, additional?: string) { 24 | this.track(event, additional ? { 25 | additional: additional 26 | } : undefined); 27 | } 28 | 29 | /** 30 | * 时间埋点 31 | * @param event 操作 32 | * @param params 附加参数 33 | */ 34 | track(event: EventIdentificationEnum, params?: Record) { 35 | if (import.meta.env.DEV) { 36 | return; 37 | } 38 | try { 39 | useUmami.track(event, params) 40 | } catch (e) { 41 | console.error("自定义埋点统计失败", e); 42 | } 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/icon/TagIcon.vue: -------------------------------------------------------------------------------- 1 | 9 | 15 | -------------------------------------------------------------------------------- /src/enumeration/PageNameEnum.ts: -------------------------------------------------------------------------------- 1 | enum PageNameEnum { 2 | 3 | HOME = "/home", 4 | 5 | DATA_BROWSE = "/data-browse", 6 | 7 | BASE_SEARCH = "/base-search", 8 | 9 | SENIOR_SEARCH = "/senior-search", 10 | 11 | DEV_TOOL = "/dev-tool", 12 | 13 | TOOL = "/tool", 14 | 15 | TOOL_WATCH = "/tool/watch", 16 | 17 | TOOL_SQL = "/tool/sql", 18 | 19 | 20 | DASHBOARD = '/dashboard', 21 | 22 | DASHBOARD_INFO = '/dashboard/info', 23 | 24 | DASHBOARD_NODE = '/dashboard/node', 25 | 26 | DASHBOARD_SHARD_AND_REPLICA = '/dashboard/shard-and-replica', 27 | 28 | DASHBOARD_CAT = '/dashboard/cat', 29 | 30 | DASHBOARD_ANALYSIS = '/dashboard/analysis', 31 | 32 | SETTING = "/setting", 33 | 34 | SETTING_GLOBAL = "/setting/global", 35 | 36 | SETTING_LINK = "/setting/link", 37 | 38 | 39 | SETTING_SENIOR_FILTER_RECORD = "/setting/senior-filter-record", 40 | 41 | MORE = "/more", 42 | 43 | MORE_UPDATE = "/more/update", 44 | 45 | MORE_PRIVACY = "/more/privacy", 46 | 47 | MORE_ABOUT = "/more/about" 48 | 49 | } 50 | 51 | export default PageNameEnum; 52 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/factory.ts: -------------------------------------------------------------------------------- 1 | import { ElasticsearchClientProp } from "./types"; 2 | import { ElasticsearchClientV6 } from "./builder/v6"; 3 | import { ElasticsearchClientV7 } from "./builder/v7"; 4 | import { ElasticsearchClientV8 } from "./builder/v8"; 5 | import { ElasticsearchClient } from "./client"; 6 | import { compareVersion } from "$/util"; 7 | 8 | export function createElasticsearchClient(props: ElasticsearchClientProp): ElasticsearchClient { 9 | const { version } = props; 10 | if (/^7\.\d+\.\d+/.test(version)) { 11 | // V7 12 | return new ElasticsearchClientV7(props); 13 | } else if (/^6\.\d+\.\d+/.test(version)) { 14 | // V6 15 | return new ElasticsearchClientV6(props); 16 | } else if (/^8\.\d+\.\d+/.test(version)) { 17 | // V6 18 | return new ElasticsearchClientV8(props); 19 | } else if (compareVersion(version, "6.0.0") < 0) { 20 | return new ElasticsearchClientV6(props); 21 | } else if (compareVersion(version, "9.0.0") >= 0) { 22 | return new ElasticsearchClientV8(props); 23 | } 24 | 25 | // 默认返回v7版本 26 | return new ElasticsearchClientV7(props); 27 | } 28 | -------------------------------------------------------------------------------- /src/page/base-search/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 29 | 30 | 33 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/domain/IndexTemplate.ts: -------------------------------------------------------------------------------- 1 | import { IndexAliasOptions, IndexMapping, IndexSettings } from "$/shared/elasticsearch"; 2 | 3 | export interface IndexTemplateListItem { 4 | name: string; 5 | type: "legacy" | "composable"; 6 | } 7 | 8 | export interface IndexTemplate { 9 | /** 10 | * 索引模板名称 11 | */ 12 | name: string; 13 | 14 | /** 15 | * 索引模式 16 | */ 17 | indexPatterns: string[]; 18 | 19 | /** 20 | * 设置 21 | */ 22 | settings: { index: IndexSettings }; 23 | 24 | /** 25 | * 映射,默认是_doc,为了兼容v7一下版本,如果是v7以上,直接就是_doc即可,内部会自适应实现 26 | * 27 | * 类型 => 映射 28 | */ 29 | mappings: Record; 30 | 31 | /** 32 | * 别名 33 | */ 34 | aliases: Record; 35 | 36 | /** 37 | * 优先级 38 | */ 39 | priority: number; 40 | 41 | /** 42 | * 版本 43 | */ 44 | version: number; 45 | 46 | // ------------------------------------- 仅v7.8以上有效 ------------------------------------- 47 | 48 | /** 49 | * 元数据 50 | */ 51 | meta: Record; 52 | 53 | /** 54 | * 引用的组件模板 55 | */ 56 | composedOf: Array; 57 | } 58 | -------------------------------------------------------------------------------- /src/strategy/VersionStrategy/impl/V6VersionStrategyImpl.ts: -------------------------------------------------------------------------------- 1 | import VersionStrategy from "@/strategy/VersionStrategy/VersionStrategy"; 2 | import {IndexInstance} from "@/domain/IndexInstance"; 3 | import {IndexCreate} from "@/domain/es/IndexCreate"; 4 | import {Setting} from "@/domain/es/IndexBase"; 5 | 6 | /** 7 | * v6版本策略 8 | */ 9 | export default class V6VersionStrategyImpl implements VersionStrategy { 10 | getVersionExp(): RegExp { 11 | return /^6\.\d+\.\d+$/; 12 | } 13 | 14 | hasType(): boolean { 15 | return true; 16 | } 17 | 18 | private getDefaultBody(setting: Setting): any { 19 | return { 20 | settings: { 21 | number_of_shards: setting.number_of_shards, 22 | number_of_replicas: setting.number_of_replicas 23 | }, 24 | mappings: { 25 | _doc: { 26 | properties: {} 27 | } 28 | } 29 | } 30 | } 31 | 32 | indexCreateBuild(index: IndexInstance): IndexCreate { 33 | // TODO:此处需要处理 34 | return this.getDefaultBody(index.settings); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/core/util/lang/StrUtil.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 仅替换字符串开头的指定子串 3 | * @param source 原始字符串 4 | * @param search 要查找的子串(仅匹配开头) 5 | * @param replacement 替换为的子串 6 | * @returns 替换后的字符串 7 | */ 8 | export function replaceStart(source: string, search: string, replacement: string): string { 9 | if (source.startsWith(search)) { 10 | return replacement + source.slice(search.length); 11 | } 12 | return source; 13 | } 14 | 15 | /** 16 | * 比较两个语义化版本号 17 | * @param v1 第一个版本号(如 "1.10.5") 18 | * @param v2 第二个版本号(如 "1.9.0") 19 | * @returns 若 v1 > v2 返回 1;v1 < v2 返回 -1;相等返回 0 20 | */ 21 | export function compareVersion(v1: string, v2: string): number { 22 | // 移除可能的前导/尾随空格,并按 '.' 拆分 23 | const parts1 = v1.trim().split(".").map(Number); 24 | const parts2 = v2.trim().split(".").map(Number); 25 | 26 | // 获取最大长度,用于补齐较短的版本号 27 | const len = Math.max(parts1.length, parts2.length); 28 | 29 | for (let i = 0; i < len; i++) { 30 | // 如果某一段不存在,默认为 0(例如 1.9 等价于 1.9.0) 31 | const num1 = i < parts1.length ? parts1[i] : 0; 32 | const num2 = i < parts2.length ? parts2[i] : 0; 33 | 34 | if (num1 > num2) return 1; 35 | if (num1 < num2) return -1; 36 | } 37 | 38 | return 0; // 所有段都相等 39 | } 40 | -------------------------------------------------------------------------------- /src/entity/Url.ts: -------------------------------------------------------------------------------- 1 | import Base from "@/entity/Base"; 2 | import UrlAuthTypeEnum from "@/enumeration/UrlAuthTypeEnum"; 3 | 4 | export interface Url extends Base { 5 | 6 | /** 7 | * 链接名称 8 | */ 9 | name: string; 10 | 11 | /** 12 | * 链接值 13 | */ 14 | value: string; 15 | 16 | /** 17 | * 排序 18 | */ 19 | sequence: number; 20 | /** 21 | * 是否需要认证 22 | */ 23 | isAuth: boolean; 24 | 25 | /** 26 | * 认证类型那个,默认Basic认证 27 | */ 28 | authType: UrlAuthTypeEnum; 29 | 30 | /** 31 | * 用户名 32 | */ 33 | authUser: string; 34 | 35 | /** 36 | * 密码 37 | */ 38 | authPassword: string; 39 | 40 | /** 41 | * 版本信息 42 | */ 43 | version: string; 44 | 45 | platform: "elasticsearch" | "opensearch" | "easysearch" 46 | 47 | } 48 | 49 | export function getDefaultUrl(source?: Partial): Url { 50 | return Object.assign>({ 51 | id: 0, 52 | version: '', 53 | updateTime: new Date(), 54 | createTime: new Date(), 55 | name: '', 56 | value: 'http://', 57 | sequence: 0, 58 | isAuth: false, 59 | authType: UrlAuthTypeEnum.BASIC as UrlAuthTypeEnum, 60 | authUser: '', 61 | authPassword: '', 62 | platform: "elasticsearch" 63 | }, source || {}); 64 | } 65 | -------------------------------------------------------------------------------- /src/components/RestClientEditor/codelens.ts: -------------------------------------------------------------------------------- 1 | import {editor, languages} from 'monaco-editor'; 2 | import {URL_REGEX} from "@/data/EsUrl"; 3 | 4 | export default function build(commandId: string): languages.CodeLensProvider { 5 | return { 6 | provideCodeLenses(model: editor.ITextModel): languages.ProviderResult { 7 | 8 | let codeLens = new Array(); 9 | let lines = model.getValue().split("\n"); 10 | let index = 0; 11 | for (let i = 0; i < lines.length; i++) { 12 | let line = lines[i]; 13 | if (line.match(URL_REGEX)) { 14 | codeLens.push({ 15 | range: { 16 | startLineNumber: i + 1, 17 | startColumn: 1, 18 | endLineNumber: i + 2, 19 | endColumn: 1, 20 | }, 21 | id: `执行-${new Date().getTime() + i}`, 22 | command: { 23 | id: commandId, 24 | title: '执行', 25 | tooltip: '执行此请求', 26 | arguments: [index] 27 | }, 28 | }); 29 | index += 1; 30 | } 31 | } 32 | return { 33 | lenses: codeLens, 34 | dispose() { 35 | } 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/components/SqlEditor/language/codelens.ts: -------------------------------------------------------------------------------- 1 | import {editor, languages} from 'monaco-editor'; 2 | import {SQL_REGEX} from "@/data/EsUrl"; 3 | 4 | export function SqlCodelens(commandId: string): languages.CodeLensProvider { 5 | return { 6 | provideCodeLenses(model: editor.ITextModel): languages.ProviderResult { 7 | 8 | let codeLens = new Array(); 9 | let lines = model.getValue().split("\n"); 10 | let index = 0; 11 | for (let i = 0; i < lines.length; i++) { 12 | let line = lines[i]; 13 | if (line.match(SQL_REGEX)) { 14 | codeLens.push({ 15 | range: { 16 | startLineNumber: i + 1, 17 | startColumn: 1, 18 | endLineNumber: i + 2, 19 | endColumn: 1, 20 | }, 21 | id: `执行-${new Date().getTime() + i}`, 22 | command: { 23 | id: commandId, 24 | title: '执行', 25 | tooltip: '执行此请求', 26 | arguments: [index] 27 | }, 28 | }); 29 | index += 1; 30 | } 31 | } 32 | return { 33 | lenses: codeLens, 34 | dispose() { 35 | } 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/hooks/UseLoading.tsx: -------------------------------------------------------------------------------- 1 | import NotificationUtil from "@/utils/model/NotificationUtil"; 2 | import {LoadingPlugin} from "tdesign-vue-next"; 3 | 4 | export interface UseLoadingResult { 5 | close: () => void; 6 | start: (text: string) => void; 7 | } 8 | 9 | export const useLoading = (text = '加载中'): UseLoadingResult => { 10 | 11 | const value = ref(text); 12 | 13 | const plugin = LoadingPlugin({ 14 | text: () => {value.value}, 15 | }); 16 | let timer: ReturnType | null = null; 17 | 18 | // 创建新的定时器 19 | function addTimeout(timeout: number) { 20 | if (timer) clearTimeout(timer); 21 | timer = setTimeout(() => { 22 | timer = null; 23 | NotificationUtil.confirm("检测到全局加载已超过10秒,是否立即关闭全局加载框", "警告", { 24 | confirmButtonText: '关闭', 25 | cancelButtonText: '忽略' 26 | }).catch(() => { 27 | console.log('忽略提示'); 28 | addTimeout(20); 29 | }) 30 | }, timeout * 1000); 31 | } 32 | 33 | addTimeout(10); 34 | 35 | return { 36 | close: () => { 37 | plugin.hide(); 38 | if (timer != null) { 39 | clearTimeout(timer); 40 | } 41 | }, 42 | start: (text: string) => { 43 | value.value = text; 44 | addTimeout(10); 45 | }, 46 | } 47 | } -------------------------------------------------------------------------------- /src/page/base-search/components/filed-order/container.vue: -------------------------------------------------------------------------------- 1 | 15 | 45 | 46 | -------------------------------------------------------------------------------- /src/page/dashboard/components/DashboardCard.vue: -------------------------------------------------------------------------------- 1 | 20 | 33 | 48 | -------------------------------------------------------------------------------- /src/i18n/locales/zh-TW.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | action: { 3 | add: '新增', 4 | delete: '刪除', 5 | update: '更新', 6 | query: '查詢', 7 | save: '保存', 8 | confirm: '確認', 9 | cancel: '取消', 10 | refresh: '刷新', 11 | add_link: '新增鏈接', 12 | feedback: '問題反饋', 13 | changelog: '更新日誌', 14 | repository: '代碼倉庫', 15 | about: '關於', 16 | check_update: '檢查更新', 17 | }, 18 | placeholder: { 19 | select_link: '請選擇鏈接', 20 | }, 21 | error: { 22 | link_not_found: '鏈接未找到', 23 | }, 24 | theme: { 25 | light: '日間', 26 | dark: '黑夜', 27 | auto: '跟隨系統', 28 | }, 29 | menu: { 30 | home: '概覽', 31 | data_browser: '數據瀏覽', 32 | base_search: '基礎搜索', 33 | dev_tools: '開發者工具', 34 | dashboard: '儀表盤', 35 | dashboard_info: '信息', 36 | dashboard_node: '節點', 37 | dashboard_shards: '副本與分片', 38 | dashboard_cat: '_cat', 39 | dashboard_analysis: '分析', 40 | setting: '設置', 41 | setting_global: '全局設置', 42 | setting_link: '鏈接管理', 43 | more: '更多', 44 | more_changelog: '更新日誌', 45 | more_privacy: '隱私協議', 46 | more_about: '關於', 47 | senior_search: '高級搜索', 48 | }, 49 | result: { 50 | success: '成功', 51 | failed: '失敗', 52 | }, 53 | response: { 54 | operate: '{action}{result}', 55 | }, 56 | } 57 | -------------------------------------------------------------------------------- /src/api/DataBrowser/DataBrowserViewService.ts: -------------------------------------------------------------------------------- 1 | import {DATA_BROWSER_VIEW_KEY, DataBrowserView} from "@/entity/DataBrowser/DataBrowserView"; 2 | import {listByAsync, removeOneByAsync, saveListByAsync} from "@/utils/utools/DbStorageUtil"; 3 | import {useSnowflake} from "$/util"; 4 | 5 | export async function listDataBrowserViews(id: string) { 6 | const {list} = await listByAsync(DATA_BROWSER_VIEW_KEY(id)); 7 | return list; 8 | } 9 | 10 | export async function addDataBrowserView(id: string, view: Pick) { 11 | const {list} = await listByAsync(DATA_BROWSER_VIEW_KEY(id)); 12 | list.push({ 13 | ...view, 14 | id: useSnowflake().nextId(), 15 | created_at: Date.now(), 16 | updated_at: Date.now(), 17 | url_id: id 18 | }); 19 | await saveListByAsync(DATA_BROWSER_VIEW_KEY(id), list); 20 | } 21 | 22 | export async function deleteDataBrowserView(id: string, viewId: string) { 23 | const {list} = await listByAsync(DATA_BROWSER_VIEW_KEY(id)); 24 | list.splice(list.findIndex(e => e.id === viewId), 1); 25 | await saveListByAsync(DATA_BROWSER_VIEW_KEY(id), list); 26 | } 27 | 28 | export function clearDataBrowserViews(id: string | number) { 29 | return removeOneByAsync(DATA_BROWSER_VIEW_KEY(`${id}`)); 30 | } 31 | -------------------------------------------------------------------------------- /src/page/base-search/layout/BaseSearchHeader/operator/BsOperator.vue: -------------------------------------------------------------------------------- 1 | 12 | 40 | 41 | -------------------------------------------------------------------------------- /src/page/home/components/IndexAliasAdd.tsx: -------------------------------------------------------------------------------- 1 | import {Alert, Input, DialogPlugin} from "tdesign-vue-next"; 2 | import AppLink from "@/components/AppLink/AppLink.vue"; 3 | import i18n from "@/i18n"; 4 | 5 | export function indexAliasAdd(): Promise { 6 | return new Promise((resolve, reject) => { 7 | const name = ref('') 8 | const d = DialogPlugin.confirm({ 9 | default: () =>
10 |
{i18n.global.t('home.index_alias.input_new_alias')}
11 | 12 | 13 | ⚙️ 14 | 15 | {i18n.global.t('home.index_alias.advanced_desc')} 16 | 17 |
, 18 | header: i18n.global.t('home.index_alias.prompt'), 19 | placement: "center", 20 | draggable: true, 21 | onConfirm: () => { 22 | resolve(name.value); 23 | d.destroy(); 24 | }, 25 | onCancel: () => { 26 | reject('cancel'); 27 | d.destroy(); 28 | }, 29 | onClose: () => { 30 | reject('close'); 31 | d.destroy(); 32 | } 33 | }) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /public/highlight.js/styles/github.css: -------------------------------------------------------------------------------- 1 | pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! 2 | Theme: GitHub 3 | Description: Light theme as seen on github.com 4 | Author: github.com 5 | Maintainer: @Hirse 6 | Updated: 2021-05-15 7 | 8 | Outdated base version: https://github.com/primer/github-syntax-light 9 | Current colors taken from GitHub's CSS 10 | */.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} -------------------------------------------------------------------------------- /public/highlight.js/styles/github-dark.css: -------------------------------------------------------------------------------- 1 | pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! 2 | Theme: GitHub Dark 3 | Description: Dark theme as seen on github.com 4 | Author: github.com 5 | Maintainer: @Hirse 6 | Updated: 2021-05-15 7 | 8 | Outdated base version: https://github.com/primer/github-syntax-dark 9 | Current colors taken from GitHub's CSS 10 | */.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c} -------------------------------------------------------------------------------- /src/core/elasticsearch-client/domain/IndexOpenOrCloseProp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 表示 Elasticsearch 中的时间值类型。 3 | * 必须是一个字符串,格式为数字 + 时间单位(如 "30s", "5m", "100ms")。 4 | * 不能是纯数字(如 30),也不能是 ISO 8601 时间字符串。 5 | * 6 | * 支持的单位包括: 7 | * - 纳秒: 'nanos', 'nanosecond', 'nanoseconds' 8 | * - 微秒: 'micros', 'microsecond', 'microseconds' 9 | * - 毫秒: 'ms', 'millisecond', 'milliseconds' 10 | * - 秒: 's', 'second', 'seconds' 11 | * - 分钟: 'm', 'minute', 'minutes' 12 | * - 小时: 'h', 'hour', 'hours' 13 | * - 天: 'd', 'day', 'days' 14 | * 15 | * 示例有效值: "10s", "2m", "500ms", "1d" 16 | */ 17 | type ElasticsearchTimeValue = string & { readonly __elasticsearchTimeBrand: unique symbol }; 18 | 19 | // 辅助函数:用于在运行时构造合法的 time 值(可选) 20 | export function createTimeValue( 21 | value: number, 22 | unit: "ms" | "s" | "m" | "h" | "d" 23 | ): ElasticsearchTimeValue { 24 | return `${value}${unit}` as ElasticsearchTimeValue; 25 | } 26 | 27 | // 使用示例接口 28 | export interface IndexOpenOrCloseProp { 29 | /** 30 | * 请求超时时间,默认为 "30s"。 31 | * 指定等待每个节点响应的最长时间。 32 | */ 33 | timeout?: ElasticsearchTimeValue; 34 | 35 | /** 36 | * 主节点超时时间,默认为 "30s"。 37 | * 指定等待主节点执行操作的最长时间。 38 | */ 39 | master_timeout?: ElasticsearchTimeValue; 40 | 41 | /** 42 | * 如果索引不存在是否忽略错误,默认为 false。 43 | */ 44 | ignore_unavailable?: boolean; 45 | 46 | /** 47 | * 当使用通配符且未匹配到任何索引时,是否不报错,默认为 true。 48 | */ 49 | allow_no_indices?: boolean; 50 | } 51 | -------------------------------------------------------------------------------- /src/icon/SaveIcon.vue: -------------------------------------------------------------------------------- 1 | 9 | 15 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import AppInstance from './App.vue'; 2 | import router from "@/plugins/router"; 3 | import {createPinia} from "pinia"; 4 | import "@/assets/less" 5 | import VxeUIBase from 'vxe-pc-ui' 6 | import 'vxe-pc-ui/es/style.css' 7 | import VxeUITable from 'vxe-table' 8 | import 'vxe-table/es/style.css' 9 | import 'virtual:uno.css' 10 | import {registerLanguageForSql} from "@/components/SqlEditor"; 11 | import {registerLanguageForHttp} from "@/components/RestClientEditor"; 12 | import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css' 13 | import i18n from '@/i18n' 14 | import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' 15 | import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' 16 | // @ts-ignore: worker 导入方式可以参考vite官网 https://cn.vitejs.dev/guide/features.html#web-workers 17 | self.MonacoEnvironment = { // 提供一个定义worker路径的全局变量 18 | getWorker(_: string, label: string) { 19 | if (label === 'json') { 20 | return new JsonWorker() 21 | } 22 | return new EditorWorker() 23 | } 24 | }; 25 | 26 | // 注册语言服务器 27 | registerLanguageForHttp(); 28 | registerLanguageForSql(); 29 | 30 | 31 | // 插件 32 | createApp(AppInstance) 33 | .use(createPinia()) 34 | .use(router) 35 | .use(i18n) 36 | .use(VxeUIBase).use(VxeUITable) 37 | .mount('#app'); 38 | 39 | // 变量挂载 40 | window.mode = import.meta.env.VITE_MODE; 41 | window.referrer = import.meta.env.VITE_REFERRER; 42 | -------------------------------------------------------------------------------- /src/core/shared/common/Result.ts: -------------------------------------------------------------------------------- 1 | import { EsRequestError } from "$/shared"; 2 | 3 | export class Result { 4 | /** 5 | * 200: 成功 6 | * 500: 错误 7 | * 501:es请求错误 8 | */ 9 | code: number; 10 | msg: string; 11 | data?: T; 12 | 13 | constructor(code: number, msg: string, data?: T) { 14 | this.code = code; 15 | this.msg = msg; 16 | this.data = data; 17 | } 18 | 19 | public static success(data?: T) { 20 | return new Result(200, "success", data); 21 | } 22 | 23 | public static error(msg: string) { 24 | return new Result(500, msg, null); 25 | } 26 | 27 | public static fail(error: Error | any) { 28 | if (error instanceof EsRequestError) { 29 | return new Result(501, error.message, error.body); 30 | } 31 | return new Result(500, error instanceof Error ? error.message : String(error), null); 32 | } 33 | 34 | public static errorWithData(msg: string, data: T) { 35 | return new Result(500, msg, data); 36 | } 37 | 38 | public static notAuth() { 39 | return new Result(401, "未登录", null); 40 | } 41 | 42 | // 登录过期 43 | public static tokenExpired() { 44 | return new Result(403, "登录过期", null); 45 | } 46 | 47 | // 认证信息错误 48 | public static authError() { 49 | return new Result(402, "认证信息错误", null); 50 | } 51 | 52 | // 认证信息错误 53 | public static notFound() { 54 | return new Result(404, "未找到", null); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/view/Data.ts: -------------------------------------------------------------------------------- 1 | export interface Repository { 2 | 3 | name: string; 4 | 5 | url: string; 6 | 7 | } 8 | 9 | export interface Log { 10 | 11 | version: string; 12 | 13 | sign: number; 14 | 15 | time: string; 16 | 17 | items: Array> 18 | 19 | title?: string; 20 | 21 | /** 22 | * 文档地址 23 | */ 24 | doc?: string; 25 | 26 | /** 27 | * 描述 28 | */ 29 | remark: string; 30 | 31 | } 32 | 33 | export interface LogItem { 34 | 35 | label: LogItemEnum; 36 | 37 | content: string; 38 | 39 | /** 40 | * 兔小巢反馈 41 | */ 42 | txc?: string 43 | 44 | /** 45 | * gitee反馈 46 | */ 47 | gitee?: { 48 | 49 | title: string; 50 | 51 | content: string; 52 | } 53 | 54 | /** 55 | * pull request 56 | */ 57 | pull?: { 58 | 59 | name: string; 60 | 61 | url: string; 62 | } 63 | 64 | } 65 | 66 | export enum LogItemEnum { 67 | 68 | /** 69 | * 新增 70 | */ 71 | ADD = 1, 72 | 73 | /** 74 | * 优化 75 | */ 76 | OPTIMIZATION = 2, 77 | 78 | /** 79 | * 修复 80 | */ 81 | REPAIR = 3, 82 | 83 | /** 84 | * 更新/改版 85 | */ 86 | UPDATE = 4 87 | 88 | } 89 | 90 | export interface Item { 91 | 92 | type: ItemType, 93 | 94 | value: string; 95 | 96 | addon?: string 97 | 98 | } 99 | 100 | export type ItemType = 'string' | 'link'; -------------------------------------------------------------------------------- /src/domain/es/IndexBase.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 索引信息 3 | */ 4 | export interface IndexBase { 5 | 6 | /** 7 | * 设置 8 | */ 9 | settings: Setting; 10 | 11 | /** 12 | * 映射: 13 | * 14 | * 类型 => 映射 15 | */ 16 | mappings: Record; 17 | 18 | } 19 | 20 | export interface Setting { 21 | 22 | /** 23 | * 分片数 24 | */ 25 | number_of_shards: number; 26 | 27 | /** 28 | * 副本数 29 | */ 30 | number_of_replicas: number; 31 | 32 | } 33 | 34 | export interface Mapping { 35 | 36 | /** 37 | * 38 | */ 39 | properties?: Record; 40 | 41 | dynamic?: string; 42 | 43 | } 44 | 45 | export interface Property { 46 | 47 | /** 48 | * 字段类型 49 | */ 50 | type?: Type; 51 | 52 | /** 53 | * keyword独有字段 54 | */ 55 | fields?: { keyword: Keyword }; 56 | 57 | /** 58 | * 属性 59 | */ 60 | properties?: Record; 61 | 62 | search_analyzer?: string; 63 | 64 | analyzer?: string; 65 | 66 | /** 67 | * 日期类型的格式化 68 | */ 69 | format?: string; 70 | 71 | /** 72 | * 动态 73 | */ 74 | dynamic?: Dynamic; 75 | 76 | } 77 | 78 | export type Dynamic = 'true' | 'false' | 'strict'; 79 | 80 | export type Type = 'text' | 81 | 'long' | 82 | 'date' | 83 | 'keyword' | 84 | 'short' | 85 | 'integer' | 86 | 'nested'; 87 | 88 | export interface Keyword { 89 | 90 | ignore_above: number; 91 | 92 | /** 93 | * 字段类型 94 | */ 95 | type: string; 96 | 97 | } -------------------------------------------------------------------------------- /src/page/dashboard/Analysis/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 41 | 42 | -------------------------------------------------------------------------------- /src/store/setting/EditorSettingStore.ts: -------------------------------------------------------------------------------- 1 | import {defineStore} from "pinia"; 2 | import {EditorSetting, getDefaultEditorSettingValue} from "@/domain/EditorSetting"; 3 | import Optional from "@/utils/Optional"; 4 | import {getFromOneByAsync, saveOneByAsync} from "@/utils/utools/DbStorageUtil"; 5 | import LocalNameEnum from "@/enumeration/LocalNameEnum"; 6 | 7 | export const useEditorSettingStore = defineStore('editor-setting', { 8 | state: () => ({ 9 | instance: getDefaultEditorSettingValue(), 10 | }), 11 | getters: { 12 | getSetting: (state): EditorSetting => state.instance, 13 | getFontSize: (state): number => Optional.ofNullable(state.instance.fontSize).orElse(16), 14 | getMinimap: (state): boolean => Optional.ofNullable(state.instance.minimap).orElse(false), 15 | getWordWrap: (state): 'off' | 'on' | 'wordWrapColumn' | 'bounded' => Optional.ofNullable(state.instance.wordWrap).orElse("on"), 16 | getRunColor: (state): string => Optional.ofNullable(state.instance.runColor).orElse("#0d7d6c"), 17 | }, 18 | actions: { 19 | async init(): Promise { 20 | const res = await getFromOneByAsync(LocalNameEnum.SETTING_EDITOR, getDefaultEditorSettingValue()); 21 | this.instance = res.record; 22 | }, 23 | async save(editorSetting: EditorSetting): Promise { 24 | this.instance = editorSetting; 25 | // 保存 26 | await saveOneByAsync(LocalNameEnum.SETTING_EDITOR, this.instance); 27 | } 28 | } 29 | }); 30 | 31 | export default useEditorSettingStore; 32 | -------------------------------------------------------------------------------- /src/icon/Translate.vue: -------------------------------------------------------------------------------- 1 | 9 | 15 | -------------------------------------------------------------------------------- /src/api/SeniorSearchRecordService.ts: -------------------------------------------------------------------------------- 1 | import {SeniorSearchRecord} from "@/entity/record/SeniorSearchRecord"; 2 | import TableNameEnum from "@/enumeration/TableNameEnum"; 3 | import BaseService from "@/api/BaseService"; 4 | import PageResult from "@/domain/PageResult"; 5 | 6 | export class SeniorSearchRecordService { 7 | 8 | private readonly baseService: BaseService; 9 | 10 | constructor() { 11 | this.baseService = new BaseService(TableNameEnum.SENIOR_SEARCH_RECORD); 12 | } 13 | 14 | async page(current: number, size: number, urlId?: number): Promise> { 15 | return this.baseService.page(current, size, {urlId}); 16 | } 17 | 18 | async list(urlId?: number): Promise> { 19 | return this.baseService.list({urlId}); 20 | } 21 | 22 | async save(record: Omit): Promise { 23 | return this.baseService.insert({ 24 | urlId: record.urlId, 25 | method: record.method, 26 | link: record.link, 27 | body: record.body 28 | }); 29 | } 30 | 31 | async update(record: Omit): Promise { 32 | return this.baseService.update(record.id, record); 33 | } 34 | 35 | removeById(id: number): Promise { 36 | return this.baseService.delete(id); 37 | } 38 | 39 | clear(): Promise { 40 | return this.baseService.clear(); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/icon/StructureIcon.vue: -------------------------------------------------------------------------------- 1 | 12 | 18 | -------------------------------------------------------------------------------- /src/page/data-browse/component/DbHeader/components/DbTableHeader.vue: -------------------------------------------------------------------------------- 1 | 26 | 40 | 41 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/components/SearchResultToTable.ts: -------------------------------------------------------------------------------- 1 | import { DataSearchResult } from "$/elasticsearch-client"; 2 | import { flattenObject, parseJsonWithBigIntSupport, stringifyJsonWithBigIntSupport } from "$/util"; 3 | 4 | /** 5 | * 搜索结果转为表格 6 | * @param response 搜索结果 7 | */ 8 | export function searchResultToTable(response: string): DataSearchResult { 9 | const result = parseJsonWithBigIntSupport(response); 10 | const hits = result.hits.hits || []; 11 | 12 | // 提取所有字段名 13 | const allFields = new Set(); 14 | hits.forEach((hit: any) => { 15 | if (hit._source) { 16 | // 扁平化对象后加入集合 17 | Object.keys(flattenObject(hit._source)).forEach((key) => allFields.add(key)); 18 | } 19 | }); 20 | 21 | // 构建列配置 22 | const columns = Array.from(allFields).map((field) => ({ 23 | field, 24 | title: field, 25 | width: Math.max(field.length * 16, 80), 26 | ellipsis: true, 27 | cellClass: "", 28 | show: true, 29 | sortable: { 30 | sortDirections: ["ascend", "descend"] as ("ascend" | "descend")[] 31 | } 32 | })); 33 | 34 | // 构建记录数据 35 | const records = hits.map((hit: any) => ({ 36 | _id: hit._id, 37 | _index: hit._index, 38 | _type: hit._type, 39 | _score: hit._score, 40 | _source: stringifyJsonWithBigIntSupport(hit._source), 41 | ...flattenObject(hit._source) 42 | })); 43 | 44 | return { 45 | columns, 46 | records, 47 | total: 48 | typeof result.hits.total.value === "undefined" ? result.hits.total : result.hits.total.value, 49 | source: response 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /src/global/BeanFactory.ts: -------------------------------------------------------------------------------- 1 | 2 | import {BaseSearchRecordService} from "@/api/BaseSearchRecordService"; 3 | 4 | import EventBusEnum from "@/enumeration/EventBusEnum"; 5 | 6 | import highlight from "highlight.js/lib/core"; 7 | import highlightJson from "highlight.js/lib/languages/json"; 8 | 9 | // 策略 10 | import VersionStrategyContext from "@/strategy/VersionStrategy/VersionStrategyContext"; 11 | import V6VersionStrategyImpl from "@/strategy/VersionStrategy/impl/V6VersionStrategyImpl"; 12 | import V7VersionStrategyImpl from "@/strategy/VersionStrategy/impl/V7VersionStrategyImpl"; 13 | import V8VersionStrategyImpl from "@/strategy/VersionStrategy/impl/V8VersionStrategyImpl"; 14 | import {SeniorSearchRecordService} from "@/api/SeniorSearchRecordService"; 15 | // 插件 16 | import {Statistics} from "@/plugins/Statistics"; 17 | 18 | export const baseSearchRecordService = new BaseSearchRecordService(); 19 | export const seniorSearchRecordService = new SeniorSearchRecordService(); 20 | 21 | // 版本策略 22 | export const versionStrategyContext = new VersionStrategyContext(); 23 | versionStrategyContext.register(new V6VersionStrategyImpl()); 24 | versionStrategyContext.register(new V7VersionStrategyImpl()); 25 | versionStrategyContext.register(new V8VersionStrategyImpl()); 26 | 27 | // 事件 28 | export const useIndexManageEvent = useEventBus(EventBusEnum.INDEX_MANAGE); 29 | export const useSeniorShowResultEvent = useEventBus(EventBusEnum.SENIOR_SHOW_RESULT); 30 | 31 | // 代码高亮 32 | highlight.registerLanguage('json', highlightJson); 33 | export {highlight}; 34 | 35 | export const statistics = new Statistics(); 36 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "dev", 10 | "request": "launch", 11 | "runtimeArgs": [ 12 | "dev" 13 | ], 14 | "runtimeExecutable": "yarn", 15 | "skipFiles": [ 16 | "**/node_modules/**" 17 | ], 18 | "type": "node" 19 | }, 20 | { 21 | "name": "tauri dev", 22 | "request": "launch", 23 | "runtimeArgs": [ 24 | "tauri", 25 | "dev" 26 | ], 27 | "runtimeExecutable": "yarn", 28 | "skipFiles": [ 29 | "**/node_modules/**" 30 | ], 31 | "type": "node" 32 | }, 33 | { 34 | "name": "Run Extension", 35 | "type": "extensionHost", 36 | "request": "launch", 37 | "args": [ 38 | "--extensionDevelopmentPath=${workspaceFolder}/src-vscode" 39 | ], 40 | "outFiles": [ 41 | "${workspaceFolder}/src-vscode/out/**/*.js" 42 | ], 43 | "preLaunchTask": "${defaultBuildTask}" 44 | }, 45 | { 46 | "name": "Extension Tests", 47 | "type": "extensionHost", 48 | "request": "launch", 49 | "args": [ 50 | "--extensionDevelopmentPath=${workspaceFolder}/src-vscode", 51 | "--extensionTestsPath=${workspaceFolder}/src-vscode/out/test/suite/index" 52 | ], 53 | "outFiles": [ 54 | "${workspaceFolder}/src-vscode/out/test/**/*.js" 55 | ], 56 | "preLaunchTask": "${defaultBuildTask}" 57 | } 58 | ] 59 | } -------------------------------------------------------------------------------- /src/page/senior-search/index.less: -------------------------------------------------------------------------------- 1 | .senior-search { 2 | position: absolute; 3 | top: 7px; 4 | left: 7px; 5 | right: 7px; 6 | bottom: 7px; 7 | 8 | .senior-main { 9 | position: absolute; 10 | top: 0; 11 | left: 0; 12 | right: 0; 13 | bottom: 0; 14 | 15 | .senior-search-side { 16 | height: 100%; 17 | } 18 | 19 | .senior-search-editor { 20 | display: flex; 21 | height: 100%; 22 | 23 | .editor { 24 | width: calc(100% - 33px); 25 | height: 100%; 26 | position: relative; 27 | 28 | .js-option { 29 | position: absolute; 30 | left: 0; 31 | top: 0; 32 | right: 0; 33 | height: 40px; 34 | padding-left: 64px; 35 | display: flex; 36 | justify-content: space-between; 37 | 38 | } 39 | 40 | .js-editor-wrapper { 41 | position: absolute; 42 | top: 40px; 43 | left: 0; 44 | right: 0; 45 | bottom: 0; 46 | 47 | .js-editor { 48 | position: absolute; 49 | top: 0; 50 | left: 0; 51 | right: 0; 52 | bottom: 0; 53 | } 54 | } 55 | } 56 | } 57 | 58 | 59 | } 60 | 61 | 62 | .senior-display { 63 | width: calc(100% - 30px); 64 | height: 100%; 65 | margin: 0 15px; 66 | position: relative; 67 | overflow: hidden; 68 | 69 | .senior-display-content { 70 | position: absolute; 71 | top: 48px; 72 | left: 0; 73 | right: 0; 74 | bottom: 0; 75 | } 76 | } 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src-tauri/tauri.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", 3 | "productName": "es-client", 4 | "version": "3.2.2", 5 | "identifier": "es-client-open.esion.xyz", 6 | "build": { 7 | "frontendDist": "../dist", 8 | "devUrl": "http://localhost:7743", 9 | "beforeDevCommand": "pnpm dev:tauri", 10 | "beforeBuildCommand": "pnpm build:tauri" 11 | }, 12 | "app": { 13 | "windows": [ 14 | { 15 | "title": "es-client", 16 | "width": 1200, 17 | "height": 800, 18 | "minHeight": 800, 19 | "minWidth": 600, 20 | "resizable": true, 21 | "fullscreen": false 22 | } 23 | ], 24 | "security": { 25 | "csp": null 26 | } 27 | }, 28 | "bundle": { 29 | "active": true, 30 | "targets": "all", 31 | "icon": [ 32 | "icons/32x32.png", 33 | "icons/128x128.png", 34 | "icons/128x128@2x.png", 35 | "icons/icon.icns", 36 | "icons/icon.ico" 37 | ], 38 | "createUpdaterArtifacts": true, 39 | "publisher": "落雨不悔" 40 | }, 41 | "plugins": { 42 | "updater": { 43 | "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEU2REQ1MzFDMjg1RTEwMEYKUldRUEVGNG9IRlBkNW1BUHQyR2ZMemlLNmpSRGd2eFA3eWJ0OHhjMFFidzhlYjBpSytzaGJwS1cK", 44 | "endpoints": [ 45 | "https://api.upgrade.toolsetlink.com/v1/tauri/upgrade?tauriKey=CHKetajqYBEyxdQKNFevqQ&versionName={{current_version}}&appointVersionName=&devModelKey=&devKey=&target={{target}}&arch={{arch}}" 46 | ], 47 | "windows": { 48 | "installMode": "basicUi" 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | import {createI18n} from 'vue-i18n' 2 | import zhCN from './locales/zh-CN' 3 | import zhTW from './locales/zh-TW' 4 | import en from './locales/en' 5 | import ja from './locales/ja' 6 | import de from './locales/de' 7 | import LocalNameEnum from "@/enumeration/LocalNameEnum"; 8 | 9 | // 映射:Chrome 语言标签 → Vue I18n 语言标签 10 | function mapChromeLangToVueLang(chromeLang: string): string { 11 | if (chromeLang === 'zh-CN' || chromeLang === 'zh') return 'zh-CN'; 12 | if (chromeLang === 'zh-TW') return 'zh-TW'; 13 | if (chromeLang.startsWith('zh')) return 'zh-CN'; // 兜底简体 14 | if (chromeLang.startsWith('en')) return 'en'; 15 | if (chromeLang.startsWith('ja')) return 'ja'; 16 | if (chromeLang.startsWith('de')) return 'de'; 17 | return 'en'; 18 | } 19 | 20 | const SUPPORT_LANGUAGE = ['zh-CN', 'zh-TW', 'en', 'ja', 'de']; 21 | 22 | let initialLocale = localStorage.getItem(LocalNameEnum.KEY_LOCAL); 23 | 24 | try { 25 | // 没有设置语言,尝试获取 chrome 的语言 26 | if (window.chrome && !initialLocale) { 27 | const chromeLanguage = chrome.i18n.getUILanguage(); 28 | initialLocale = mapChromeLangToVueLang(chromeLanguage); 29 | } 30 | } catch (e) { 31 | console.error("初始化语言失败", e); 32 | } 33 | 34 | 35 | const i18n = createI18n({ 36 | legacy: true, // support Options API 37 | allowComposition: true, // support Composition API 38 | locale: (initialLocale && SUPPORT_LANGUAGE.includes(initialLocale)) ? initialLocale : "en", 39 | fallbackLocale: 'en', 40 | messages: { 41 | 'zh-CN': zhCN, 42 | 'zh-TW': zhTW, 43 | 'en': en, 44 | 'ja': ja, 45 | 'de': de, 46 | }, 47 | }); 48 | 49 | export default i18n 50 | -------------------------------------------------------------------------------- /src/api/DevToolFileService.ts: -------------------------------------------------------------------------------- 1 | import {listByAsync, saveListByAsync} from "@/utils/utools/DbStorageUtil"; 2 | import LocalNameEnum from "@/enumeration/LocalNameEnum"; 3 | import {DevToolFileCreateProp, DevToolFileItem} from "@/entity"; 4 | import {useSnowflake} from "$/util"; 5 | 6 | export async function devToolFileList(urlId: number) { 7 | const {list} = await listByAsync(`${LocalNameEnum.LIST_DEV_TOOL_FILE_ITEM}/${urlId}`); 8 | return list; 9 | } 10 | 11 | export async function devToolFileCreate(urlId: number, prop: DevToolFileCreateProp) { 12 | const list = await devToolFileList(urlId); 13 | list.push({...prop, createTime: Date.now(), updateTime: Date.now(), id: useSnowflake().nextId()}); 14 | await saveListByAsync(`${LocalNameEnum.LIST_DEV_TOOL_FILE_ITEM}/${urlId}`, list); 15 | } 16 | 17 | export async function devToolFileRename(urlId: number, id: string, name: string) { 18 | const list = await devToolFileList(urlId); 19 | const index = list.findIndex(item => item.id === id); 20 | if (index === -1) { 21 | return Promise.reject(new Error("未找到该文件")); 22 | } 23 | list[index].name = name; 24 | list[index].updateTime = Date.now(); 25 | await saveListByAsync(`${LocalNameEnum.LIST_DEV_TOOL_FILE_ITEM}/${urlId}`, list); 26 | } 27 | 28 | export async function devToolFileDelete(urlId: number, id: string) { 29 | const list = await devToolFileList(urlId); 30 | const index = list.findIndex(item => item.id === id); 31 | if (index === -1) { 32 | return Promise.reject(new Error("未找到该文件")); 33 | } 34 | list.splice(index, 1); 35 | await saveListByAsync(`${LocalNameEnum.LIST_DEV_TOOL_FILE_ITEM}/${urlId}`, list); 36 | } -------------------------------------------------------------------------------- /src/icon/InfoIcon.vue: -------------------------------------------------------------------------------- 1 | 14 | 20 | -------------------------------------------------------------------------------- /src/domain/es/DocumentSearchQuery.ts: -------------------------------------------------------------------------------- 1 | import {useGlobalSettingStore} from "@/store"; 2 | import {stringifyJsonWithBigIntSupport} from "$/util"; 3 | 4 | /** 5 | * 文档搜索条件 6 | */ 7 | export interface DocumentSearchQuery { 8 | from?: number; 9 | size?: number; 10 | sort?: QuerySort; 11 | query?: Query; 12 | aggs?: any; 13 | /** 14 | * 跟踪总命中数 15 | * @since 7.0.0 16 | */ 17 | track_total_hits?: boolean | number; 18 | } 19 | 20 | export type QuerySort = Record; 21 | 22 | export type SortCondition = Record<'order', SortConditionType>; 23 | 24 | export type SortConditionType = 'asc' | 'desc'; 25 | 26 | /** 27 | * 查询条件 28 | */ 29 | interface Query { 30 | bool: Bool; 31 | } 32 | 33 | /** 34 | * bool条件查询 35 | */ 36 | interface Bool { 37 | must?: Array>>; 38 | must_not?: Array>>; 39 | should?: Array>>; 40 | } 41 | 42 | export type ConditionArray = Array>>; 43 | 44 | export type ConditionKey = 'match' | 'term' | 'terms' | 'exists' | 'wildcard' | 'range'; 45 | 46 | export const getDefaultDocumentSearchQuery = (): DocumentSearchQuery => ({ 47 | sort: {}, 48 | query: { 49 | bool: { 50 | must: [], 51 | should: [], 52 | must_not: [] 53 | } 54 | }, 55 | aggs: {}, 56 | from: 0, 57 | size: useGlobalSettingStore().getPageSize 58 | }); 59 | 60 | const defaultDocumentSearchQueryStr = stringifyJsonWithBigIntSupport(getDefaultDocumentSearchQuery()); 61 | 62 | export const getDefaultDocumentSearchQueryStr = (): string => defaultDocumentSearchQueryStr; 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/assets/less/customer.less: -------------------------------------------------------------------------------- 1 | pre { 2 | font-family: JetBrainsMono, Console, '微软雅黑', Courier, monospace !important; 3 | } 4 | 5 | .table-view-cell { 6 | font-family: JetBrainsMono, 微软雅黑, Courier, monospace !important; 7 | } 8 | 9 | 10 | .ͼ1 .cm-scroller { 11 | font-family: JetBrainsMono, 微软雅黑, Courier, monospace !important; 12 | } 13 | 14 | html { 15 | /*滚动条整体部分*/ 16 | ::-webkit-scrollbar { 17 | width: 10px; 18 | height: 5px; 19 | } 20 | 21 | /*滚动条的轨道*/ 22 | ::-webkit-scrollbar-track { 23 | background-color: transparent; 24 | } 25 | 26 | ::-webkit-scrollbar-track-piece { 27 | background-color: transparent; 28 | } 29 | 30 | /*滚动条里面的小方块,能向上向下移动*/ 31 | ::-webkit-scrollbar-thumb { 32 | background-color: #9b97a2; 33 | border-radius: 1px; 34 | border: 1px solid #9b97a2; 35 | box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); 36 | } 37 | 38 | ::-webkit-scrollbar-thumb:hover { 39 | background-color: #676e77; 40 | border: 1px solid #676e77; 41 | } 42 | 43 | ::-webkit-scrollbar-thumb:active { 44 | background-color: #4E5969; 45 | border: 1px solid #4E5969; 46 | } 47 | 48 | /*边角,即两个滚动条的交汇处*/ 49 | ::-webkit-scrollbar-corner { 50 | background-color: transparent; 51 | } 52 | } 53 | 54 | .abs-07 { 55 | position: absolute; 56 | top: 0; 57 | left: 7px; 58 | right: 7px; 59 | bottom: 7px; 60 | } 61 | .abs-70 { 62 | position: absolute; 63 | top: 7px; 64 | left: 0; 65 | right: 0; 66 | bottom: 7px; 67 | } 68 | 69 | .container-47 { 70 | position: absolute; 71 | top: 47px; 72 | left: 0; 73 | right: 0; 74 | bottom: 0; 75 | overflow: auto; 76 | } 77 | -------------------------------------------------------------------------------- /src/core/util/Snowflake.ts: -------------------------------------------------------------------------------- 1 | class CustomSnowflake { 2 | private readonly workerId: number; 3 | private sequence: number; 4 | private lastTimestamp: number; 5 | private epoch: number; 6 | 7 | constructor(workerId: number, epoch = 1609459200000) { 8 | this.workerId = workerId; // 机器ID 9 | this.sequence = 0; // 序列号 10 | this.lastTimestamp = -1; // 上次生成ID的时间戳 11 | this.epoch = epoch; // 初始时间戳,可自定义 12 | } 13 | 14 | // 生成下一个ID的方法 15 | nextId() { 16 | let timestamp = Date.now(); 17 | 18 | // 如果当前时间小于上次生成ID的时间,抛出异常 19 | if (timestamp < this.lastTimestamp) { 20 | throw new Error("Clock moved backwards, refusing to generate id"); 21 | } 22 | 23 | // 如果当前时间与上次生成ID的时间相同,则递增序列号 24 | if (timestamp === this.lastTimestamp) { 25 | this.sequence = (this.sequence + 1) & 4095; // 12位序列号 26 | // 如果序列号达到最大值,等待下一毫秒 27 | if (this.sequence === 0) { 28 | timestamp = this.waitNextMillis(timestamp); 29 | } 30 | } else { 31 | this.sequence = 0; // 重置序列号 32 | } 33 | 34 | this.lastTimestamp = timestamp; // 更新上次生成ID的时间戳 35 | 36 | // 生成ID,包括时间戳、机器ID和序列号 37 | return ( 38 | (BigInt(timestamp - this.epoch) << 22n) | 39 | (BigInt(this.workerId) << 10n) | 40 | BigInt(this.sequence) 41 | ).toString(); 42 | } 43 | 44 | // 等待下一毫秒的方法 45 | private waitNextMillis(timestamp: number) { 46 | while (timestamp <= this.lastTimestamp) { 47 | timestamp = Date.now(); 48 | } 49 | return timestamp; 50 | } 51 | } 52 | 53 | // 使用示例 54 | let customSnowflake: CustomSnowflake | null = null; 55 | 56 | export function useSnowflake() { 57 | if (!customSnowflake) { 58 | customSnowflake = new CustomSnowflake(1); 59 | } 60 | return customSnowflake; 61 | } 62 | -------------------------------------------------------------------------------- /src/page/base-search/layout/BaseSearchView/BaseSearchView.vue: -------------------------------------------------------------------------------- 1 | 7 | 27 | 63 | -------------------------------------------------------------------------------- /src/domain/core/DataSearch.ts: -------------------------------------------------------------------------------- 1 | import { TableColumn } from "./TableColumn"; 2 | import { TableRecord } from "./TableRecord"; 3 | 4 | export interface DataSearchQueryItem { 5 | /** 6 | * 字段 7 | */ 8 | field: string; 9 | /** 10 | * 操作符 11 | */ 12 | operator: string; 13 | /** 14 | * 值 15 | */ 16 | value: string; 17 | /** 18 | * 值类型 19 | */ 20 | valueType: "string" | "number" | "boolean"; 21 | } 22 | export interface DataSearchOrderItem { 23 | /** 24 | * 字段 25 | */ 26 | field: string; 27 | /** 28 | * 操作符 29 | */ 30 | operator: "asc" | "desc"; 31 | } 32 | 33 | /** 34 | * 表格视图列配置 35 | */ 36 | export interface DataSearchColumnConfig extends TableColumn {} 37 | 38 | export interface DataSourceRecord extends TableRecord { 39 | _source: string; 40 | } 41 | 42 | export interface DataSearchResult { 43 | // 表头 44 | columns: Array; 45 | // 记录 46 | records: Array; 47 | // 总数 48 | total: number; 49 | // 原始数据 50 | source: string; 51 | /** 52 | * 解析后的结果 53 | */ 54 | result: Record; 55 | } 56 | 57 | export interface DataSearchProp { 58 | must: Array; 59 | should: Array; 60 | mustNot: Array; 61 | order: Array; 62 | index: string; 63 | pageNum: number; 64 | pageSize: number; 65 | /** 66 | * 索引类型,v6之前必须 67 | */ 68 | type?: string; 69 | 70 | /*--------------------------------- track_total_hits设置 ---------------------------------*/ 71 | 72 | /** 73 | * track_total_hits模式 74 | */ 75 | trackTotalHitsMode: "true" | "false" | "custom"; 76 | 77 | /** 78 | * 当模式为custom时,track_total_hits值 79 | */ 80 | trackTotalHitsValue: number; 81 | } 82 | -------------------------------------------------------------------------------- /src/page/more/components/privacy.vue: -------------------------------------------------------------------------------- 1 | 43 | 48 | 51 | -------------------------------------------------------------------------------- /src/data/EsUrl.ts: -------------------------------------------------------------------------------- 1 | export const supportMethods = ['HEAD', 'head', 'GET', 'get', 'POST', 'post', 'PUT', 'put', 'DELETE', 'delete']; 2 | export const signMethods = ['HEAD', 'GET', 'POST', 'PUT', 'DELETE']; 3 | 4 | export const optionsForGet = ['', '_search', '_mapping']; 5 | export const optionsForPost = ['_doc', '_search', '_setting', '_mapping']; 6 | 7 | export const signs = ['/', '/_cluster/settings', '/_cat/allocation?v', '/_cat/shards?v', '/_cat/shards/', '/_cat/master?v', 8 | '/_cat/nodes?v', '/_cat/indices?v', '/_cat/indices/', '/_cat/segments?v', '/_cat/segments/', '/_cat/count', 9 | '/_cat/count/', '/_cat/recovery?v', '/_cat/recovery/', '/_cat/health?v', '/_cat/pending_tasks?v', '/_cat/aliases?v', 10 | '/_cat/aliases/', '/_cat/thread_pool?v', '/_cat/plugins?v', '/_cat/fielddata?v', '/_cat/fielddata/', '/_cat/nodeattrs?v', 11 | '/_cat/repositories?v', '/_cat/snapshots/', '/_cat/allocation?help', '/_cat/shards?help', '/_cat/shards/', '/_cat/master?help', 12 | '/_cat/nodes?help', '/_cat/indices?help', '/_cat/indices/', '/_cat/segments?help', '/_cat/segments/', '/_cat/count', 13 | '/_cat/count/', '/_cat/recovery?help', '/_cat/recovery?help', '/_cat/health?help', '/_cat/pending_tasks?help', '/_cat/aliases?help', 14 | '/_cat/aliases/', '/_cat/thread_pool?help', '/_cat/plugins?help', '/_cat/fielddata?help', '/_cat/fielddata/', '/_cat/nodeattrs?help', 15 | '/_cat/repositories?help', '/_cat/snapshots/']; 16 | 17 | // URL正则匹配 18 | export const URL_REGEX = /^\s*(HEAD|head|GET|get|POST|post|PUT|put|DELETE|delete)\s+(.+)\s*/; 19 | // JSON格式正则匹配 20 | export const JSON_REGEX = /^\s*(\{[\s\S]*}|\[[\s\S]*])\s*$/; 21 | export const COMMENT_REGEX = /^\s*\/\/.*/; 22 | export const BLANK_REGEX = /^\s*$/; 23 | 24 | 25 | // URL正则匹配 26 | export const SQL_REGEX = /^\s*(SELECT)\s+(.+)\s*/i; -------------------------------------------------------------------------------- /src/utils/model/MessageUtil.ts: -------------------------------------------------------------------------------- 1 | import { MessagePlugin } from "tdesign-vue-next"; 2 | import Optional from "@/utils/Optional"; 3 | import { stringifyJsonWithBigIntSupport } from "$/util"; 4 | 5 | function render(message: string, e?: any) { 6 | if (e instanceof Error) { 7 | return Optional.ofNullable(e) 8 | .map((e) => `${message},${e.message}`) 9 | .orElse(message); 10 | } else { 11 | return Optional.ofNullable(e) 12 | .map((e) => `${message},${e}`) 13 | .orElse(message); 14 | } 15 | } 16 | 17 | function success(message: any): void; 18 | function success(message: any, callback: () => void): void; 19 | function success(message: any, callback?: () => void): void { 20 | MessagePlugin.success({ 21 | closeBtn: true, 22 | content: typeof message === "string" ? message : stringifyJsonWithBigIntSupport(message) 23 | }); 24 | callback && callback(); 25 | } 26 | 27 | function warning(message: string, e?: any): void { 28 | MessagePlugin.warning({ 29 | closeBtn: true, 30 | content: render(message, e) 31 | }); 32 | console.error(message, e); 33 | } 34 | 35 | function error(message: string): void; 36 | function error(message: string, e: any): void; 37 | function error(message: string, e: any, callback: () => void): void; 38 | function error(message: string, e?: any, callback?: () => void): void { 39 | MessagePlugin.error({ 40 | closeBtn: true, 41 | content: render(message, e) 42 | }); 43 | console.error(message, e); 44 | callback && callback(); 45 | } 46 | 47 | export default { 48 | success, 49 | info(message: any) { 50 | MessagePlugin.info({ 51 | closeBtn: true, 52 | content: typeof message === "string" ? message : stringifyJsonWithBigIntSupport(message) 53 | }); 54 | }, 55 | warning, 56 | error 57 | }; 58 | -------------------------------------------------------------------------------- /src/core/elasticsearch-client/types/DataSearch.ts: -------------------------------------------------------------------------------- 1 | import { TableColumn } from "$/shared/common/TableColumn"; 2 | import { TableRecord } from "$/shared/common/TableRecord"; 3 | 4 | export interface DataSearchQueryItem { 5 | /** 6 | * 字段 7 | */ 8 | field: string; 9 | /** 10 | * 操作符 11 | */ 12 | operator: string; 13 | /** 14 | * 值 15 | */ 16 | value: string; 17 | /** 18 | * 值类型 19 | */ 20 | valueType: "string" | "number" | "boolean"; 21 | } 22 | 23 | export interface DataSearchOrderItem { 24 | /** 25 | * 字段 26 | */ 27 | field: string; 28 | /** 29 | * 操作符 30 | */ 31 | operator: "asc" | "desc"; 32 | } 33 | 34 | /** 35 | * 表格视图列配置 36 | */ 37 | export interface DataSearchColumnConfig extends TableColumn {} 38 | 39 | export interface DataSourceRecord extends TableRecord { 40 | _id: string; 41 | // 元数据 42 | _type?: string; 43 | _store: string; 44 | _index: string; 45 | // 原始数据 46 | _source: string; 47 | } 48 | 49 | export interface DataSearchResult { 50 | // 表头 51 | columns: Array; 52 | // 记录 53 | records: Array; 54 | // 总数 55 | total: number; 56 | // 原始数据 57 | source: string; 58 | } 59 | 60 | export interface DataSearchProp { 61 | must: Array; 62 | should: Array; 63 | mustNot: Array; 64 | order: Array; 65 | index: string; 66 | pageNum: number; 67 | pageSize: number; 68 | 69 | /*--------------------------------- track_total_hits设置 ---------------------------------*/ 70 | 71 | /** 72 | * track_total_hits模式 73 | */ 74 | trackTotalHitsMode: "true" | "false" | "custom"; 75 | 76 | /** 77 | * 当模式为custom时,track_total_hits值 78 | */ 79 | trackTotalHitsValue: number; 80 | } 81 | -------------------------------------------------------------------------------- /src/api/BaseSearchRecordService.ts: -------------------------------------------------------------------------------- 1 | import {BaseSearchRecord} from "@/entity/record/BaseSearchRecord"; 2 | import TableNameEnum from "@/enumeration/TableNameEnum"; 3 | import BaseService from "@/api/BaseService"; 4 | import PageResult from "@/domain/PageResult"; 5 | 6 | export class BaseSearchRecordService { 7 | 8 | private readonly baseService: BaseService; 9 | 10 | constructor() { 11 | this.baseService = new BaseService(TableNameEnum.BASE_SEARCH_RECORD); 12 | } 13 | 14 | async page(current: number, size: number, urlId?: number): Promise> { 15 | return this.baseService.page(current, size, {urlId}); 16 | } 17 | 18 | async list(urlId?: number): Promise> { 19 | return this.baseService.list({urlId}); 20 | } 21 | 22 | async save(record: Omit): Promise { 23 | return this.baseService.insert({ 24 | urlId: record.urlId, 25 | index: record.index, 26 | conditions: record.conditions, 27 | orders: record.orders 28 | }); 29 | } 30 | 31 | async update(record: Omit): Promise { 32 | if (!record.id) { 33 | return Promise.reject('ID不存在,无法更新'); 34 | } 35 | let history = await this.baseService.one(record.id); 36 | if (!history) { 37 | return Promise.reject('未找到该历史,请选择新增到历史'); 38 | } 39 | let item = Object.assign(history, record); 40 | item.updateTime = new Date(); 41 | return this.baseService.update(record.id, item); 42 | } 43 | 44 | removeById(id: number): Promise { 45 | return this.baseService.delete(id); 46 | } 47 | 48 | clear(): Promise { 49 | return this.baseService.clear(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/icon/FormatIcon.vue: -------------------------------------------------------------------------------- 1 | 16 | 22 | -------------------------------------------------------------------------------- /src/components/es/ClusterApi.ts: -------------------------------------------------------------------------------- 1 | import {NodeState} from "@/domain/es/NodeState"; 2 | import {Stats} from "@/domain/es/Stats"; 3 | import {ClusterState} from "@/domain/es/ClusterState"; 4 | import {Nodes} from "@/domain/es/Nodes"; 5 | import {useEsRequestJson} from "@/plugins/native/axios"; 6 | import {ClusterHealth} from "@/domain/es/ClusterHealth"; 7 | import {Overview} from "@/domain/es/Overview"; 8 | 9 | /** 10 | * 与集群相关的API 11 | */ 12 | export default { 13 | /** 14 | * 集群基本信息 15 | */ 16 | info(): Promise { 17 | return useEsRequestJson({ 18 | method: 'GET', 19 | url: '/' 20 | }); 21 | }, 22 | /** 23 | * _cluster_state 24 | */ 25 | _cluster_state(): Promise { 26 | return useEsRequestJson({ 27 | method: 'GET', 28 | url: '/_cluster/state' 29 | }) 30 | }, 31 | /** 32 | * _stats 33 | */ 34 | _stats(): Promise { 35 | return useEsRequestJson({ 36 | method: 'GET', 37 | url: '/_stats' 38 | }) 39 | }, 40 | _nodes_stats(): Promise { 41 | return useEsRequestJson({ 42 | method: 'GET', 43 | url: '/_nodes/stats' 44 | }) 45 | }, 46 | _nodes(): Promise { 47 | return useEsRequestJson({ 48 | method: 'GET', 49 | url: '/_nodes' 50 | }) 51 | }, 52 | _nodes_plugins(): Promise { 53 | return useEsRequestJson({ 54 | method: 'GET', 55 | url: '/_nodes/plugins' 56 | }) 57 | }, 58 | _cluster_health(): Promise { 59 | return useEsRequestJson({ 60 | method: 'GET', 61 | url: '/_cluster/health' 62 | }) 63 | }, 64 | _template(): Promise { 65 | return useEsRequestJson({ 66 | method: 'GET', 67 | url: '/_template' 68 | }) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/page/home/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 49 | 50 | 52 | -------------------------------------------------------------------------------- /src/icon/JsonIcon.vue: -------------------------------------------------------------------------------- 1 | 9 | 15 | -------------------------------------------------------------------------------- /src/page/data-browse/layouts/DataBrowserRight.vue: -------------------------------------------------------------------------------- 1 | 19 | 37 | 46 | -------------------------------------------------------------------------------- /src/page/senior-search/layout/senior-search-display/SsDisplayQuick.vue: -------------------------------------------------------------------------------- 1 | 30 | 44 | 52 | -------------------------------------------------------------------------------- /src/page/dev-tool/components/SsFileContent.vue: -------------------------------------------------------------------------------- 1 | 21 | 60 | 66 | -------------------------------------------------------------------------------- /src/utils/StrUtil.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | matchAll(str: string, regexes: Array): boolean { 4 | if (!regexes || regexes.length === 0 || !str || str === '') { 5 | return false; 6 | } 7 | for (let regex of regexes) { 8 | if (str.match(regex)) { 9 | return true; 10 | } 11 | } 12 | return false; 13 | }, 14 | 15 | splitAll(str: string, splitChar: string): Array { 16 | let items = new Array(); 17 | let temp = ''; 18 | for (let item of str) { 19 | if (item === splitChar) { 20 | if (temp !== '') { 21 | items.push(temp); 22 | temp = ''; 23 | } 24 | } else { 25 | temp += item; 26 | } 27 | } 28 | if (temp !== '') { 29 | items.push(temp); 30 | } 31 | return items; 32 | }, 33 | 34 | notBlank(str: string): boolean { 35 | if (str === '') { 36 | return false; 37 | } 38 | for (let char of str) { 39 | if (char !== ' ' && char !== '\t' && char !== '\n') { 40 | return true; 41 | } 42 | } 43 | return false; 44 | }, 45 | 46 | /** 47 | * 是否以指定数组中任意一个字符串为开头 48 | * @param str 字符串 49 | * @param arr 字符数组 50 | * @param ignoreCase 是否忽略大小写,默认不忽略 51 | */ 52 | startWithArr(str: string, arr: Array, ignoreCase: boolean = false): boolean { 53 | for (let item of arr) { 54 | if (ignoreCase) { 55 | if (str.toUpperCase().startsWith(item.toUpperCase())) { 56 | return true; 57 | } 58 | } else { 59 | if (str.startsWith(item)) { 60 | return true; 61 | } 62 | } 63 | } 64 | return false; 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /src/data/JsonTheme.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | light: [ 3 | 'github', 4 | 'a11y-light', 5 | 'arduino-light', 6 | 'ascetic', 7 | 'atom-one-light', 8 | 'brown-paper', 9 | 'color-brewer', 10 | 'default', 11 | 'docco', 12 | 'foundation', 13 | 'googlecode', 14 | 'gradient-light', 15 | 'grayscale', 16 | 'idea', 17 | 'intellij-light', 18 | 'isbl-editor-light', 19 | 'kimbie-light', 20 | 'lightfair', 21 | 'magula', 22 | 'mono-blue', 23 | 'nnfx-light', 24 | 'panda-syntax-light', 25 | 'paraiso-light', 26 | 'purebasic', 27 | 'qtcreator-light', 28 | 'routeros', 29 | 'school-book', 30 | 'stackoverflow-light', 31 | 'tokyo-night-light', 32 | 'vs', 33 | 'xcode' 34 | ], 35 | dark: [ 36 | 'github-dark', 37 | 'a11y-dark', 38 | 'agate', 39 | 'an-old-hope', 40 | 'androidstudio', 41 | 'arta', 42 | 'atom-one-dark', 43 | 'atom-one-dark-reasonable', 44 | 'codepen-embed', 45 | 'dark', 46 | 'devibeans', 47 | 'felipec', 48 | 'github-dark-dimmed', 49 | 'gml', 50 | 'gradient-dark', 51 | 'hybrid', 52 | 'ir-black', 53 | 'isbl-editor-dark', 54 | 'kimbie-dark', 55 | 'lioshi', 56 | 'monokai', 57 | 'monokai-sublime', 58 | 'night-owl', 59 | 'nnfx-dark', 60 | 'nord', 61 | 'obsidian', 62 | 'panda-syntax-dark', 63 | 'paraiso-dark', 64 | 'qtcreator-dark', 65 | 'rainbow', 66 | 'shades-of-purple', 67 | 'srcery', 68 | 'stackoverflow-dark', 69 | 'sunburst', 70 | 'tokyo-night-dark', 71 | 'tomorrow-night-bright', 72 | 'tomorrow-night-blue', 73 | 'vs2015', 74 | 'xt256' 75 | ] 76 | } -------------------------------------------------------------------------------- /src/page/setting/pages/link/components/LinkTableColumn.tsx: -------------------------------------------------------------------------------- 1 | import {Button, Link, Popconfirm, Space, Tag, TdPrimaryTableProps} from "tdesign-vue-next"; 2 | import { openUpdateLink } from "@/page/setting/pages/link/components/EditLink"; 3 | import MessageUtil from "@/utils/model/MessageUtil"; 4 | import {copyText} from "@/utils/BrowserUtil"; 5 | import i18n from "@/i18n"; 6 | 7 | const t = (key: string) => i18n.global.t(key); 8 | 9 | export const linkTableColumn: TdPrimaryTableProps["columns"] = [ 10 | { 11 | title: t('setting.name'), 12 | colKey: "name", 13 | width: 120, 14 | fixed: "left" 15 | }, 16 | { 17 | title: t('setting.link'), 18 | colKey: "value", 19 | cell: (_h, { row }) => ( 20 | { 22 | copyText(row.value); 23 | MessageUtil.success(t('setting.copied')); 24 | }} 25 | > 26 | {row.value} 27 | 28 | ) 29 | }, 30 | { 31 | title: t('setting.platform'), 32 | colKey: "platform", 33 | cell: (_h, { row }) => ( 34 | {row.platform || 'elasticsearch'} 35 | ) 36 | }, 37 | { 38 | title: t('setting.version'), 39 | colKey: "version" 40 | }, 41 | { 42 | title: t('setting.auth'), 43 | colKey: "isAuth", 44 | width: 100, 45 | cell: (_h, { row }) =>
{row.isAuth ? t('setting.yes') : t('setting.no')}
46 | }, 47 | { 48 | title: t('setting.operation'), 49 | colKey: "action", 50 | width: 170, 51 | fixed: "right", 52 | 53 | cell: (_h, { row }) => ( 54 | 55 | 58 | 59 | 60 | 61 | 62 | ) 63 | } 64 | ]; 65 | -------------------------------------------------------------------------------- /src/page/data-browse/component/DbInput.vue: -------------------------------------------------------------------------------- 1 | 13 | 37 | 42 | 85 | -------------------------------------------------------------------------------- /src/page/senior-search/layout/senior-search-editor/components/ss-option/SeniorSearchSetting.tsx: -------------------------------------------------------------------------------- 1 | import {Button, DialogPlugin, Form, FormItem, Input, InputNumber, Option, Select, Switch} from "tdesign-vue-next"; 2 | import useEditorSettingStore from "@/store/setting/EditorSettingStore"; 3 | import MessageUtil from "@/utils/model/MessageUtil"; 4 | 5 | export function useSeniorSearchSetting() { 6 | const instance = ref(useEditorSettingStore().getSetting); 7 | 8 | function save() { 9 | useEditorSettingStore().save(instance.value).then(() => { 10 | MessageUtil.success('保存成功,重启插件后生效'); 11 | modalReturn.destroy(); 12 | }); 13 | } 14 | 15 | const modalReturn = DialogPlugin({ 16 | header: "编辑器设置", 17 | placement: "center", 18 | width: 600, 19 | footer: false, 20 | default: () =>
21 | 22 | 23 | 24 | 25 | 26 | {{ 27 | label: (check: { value: boolean }) => {check.value ? '显示' : '隐藏'}, 28 | }} 29 | 30 | 31 | 32 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | 45 |
46 |
47 | }); 48 | } 49 | -------------------------------------------------------------------------------- /src/page/data-browse/component/DbCondition/DbCondition.vue: -------------------------------------------------------------------------------- 1 | 41 | 54 | 70 | -------------------------------------------------------------------------------- /src/core/shared/common/GlobalSetting.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 全局设置 3 | */ 4 | export interface GlobalSetting { 5 | /*--------------------------------- 系统设置 ---------------------------------*/ 6 | 7 | /** 8 | * 保存上次选择的连接 9 | */ 10 | lastUrl: boolean; 11 | 12 | /*--------------------------------- 全局索引查询条件 ---------------------------------*/ 13 | 14 | /** 15 | * 概览 => 搜索 => 状态 16 | */ 17 | homeSearchState: number; 18 | 19 | /** 20 | * 概览 => 搜索 => 排除的索引 21 | */ 22 | homeExcludeIndices: Array; 23 | 24 | /** 25 | * 概览 => 搜索 => 显示的索引 26 | */ 27 | homeIncludeIndices: Array; 28 | 29 | /** 30 | * 索引排序 31 | */ 32 | indexOrderBy: "asc" | "desc"; 33 | 34 | /** 35 | * 索引分组内排序 36 | */ 37 | indexGroupOrderBy: "asc" | "desc"; 38 | 39 | /** 40 | * 索引显示模式:group-分组,list-列表 41 | */ 42 | indexShowMode: "group" | "list"; 43 | 44 | /*--------------------------------- 新建索引 ---------------------------------*/ 45 | 46 | /** 47 | * 默认分片 48 | */ 49 | defaultShard: number; 50 | 51 | /** 52 | * 默认副本 53 | */ 54 | defaultReplica: number; 55 | 56 | /*--------------------------------- 请求 ---------------------------------*/ 57 | 58 | /** 59 | * 超时时间 60 | */ 61 | timeout: number; 62 | 63 | /** 64 | * 通知关闭时间 65 | */ 66 | notificationTime: number; 67 | 68 | /*--------------------------------- track_total_hits设置 ---------------------------------*/ 69 | 70 | /** 71 | * track_total_hits模式 72 | */ 73 | trackTotalHitsMode: "true" | "false" | "custom"; 74 | 75 | /** 76 | * 当模式为custom时,track_total_hits值 77 | */ 78 | trackTotalHitsValue: number; 79 | 80 | /*--------------------------------- 显示设置 ---------------------------------*/ 81 | 82 | /** 83 | * 默认分页大小 84 | */ 85 | pageSize: number; 86 | 87 | /** 88 | * 字体大小,单位px,默认14 89 | */ 90 | fontSize: number; 91 | 92 | /** 93 | * JSON是否自动换行 94 | */ 95 | wrap: boolean; 96 | 97 | /** 98 | * 表格表头渲染模式 99 | */ 100 | tableHeaderMode: number; 101 | } 102 | --------------------------------------------------------------------------------