Commit 14984ae5 authored by 王曜嵚 Wang Yaoqin's avatar 王曜嵚 Wang Yaoqin

dev: 结构设计

parents
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example
# Nuxt 3 Minimal Starter
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install the dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
# bun
bun install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm run dev
# yarn
yarn dev
# bun
bun run dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm run build
# yarn
yarn build
# bun
bun run build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm run preview
# yarn
yarn preview
# bun
bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
<template>
<div class='container'>
<NuxtPage />
</div>
</template>
<style scoped>
.container{
height: 100vh;
}
</style>
/* 颜色 */
:root{
--color-canvas-default-transparent: rgba(255,255,255,0);
--color-page-header-bg: #f6f8fa;
--color-marketing-icon-primary: #218bff;
--color-marketing-icon-secondary: #54aeff;
--color-diff-blob-addition-num-text: #24292f;
--color-diff-blob-addition-fg: #24292f;
--color-diff-blob-addition-num-bg: #ccffd8;
--color-diff-blob-addition-line-bg: #e6ffec;
--color-diff-blob-addition-word-bg: #abf2bc;
--color-diff-blob-deletion-num-text: #24292f;
--color-diff-blob-deletion-fg: #24292f;
--color-diff-blob-deletion-num-bg: #ffd7d5;
--color-diff-blob-deletion-line-bg: #ffebe9;
--color-diff-blob-deletion-word-bg: rgba(255,129,130,0.4);
--color-diff-blob-hunk-num-bg: rgba(84,174,255,0.4);
--color-diff-blob-expander-icon: #57606a;
--color-diff-blob-selected-line-highlight-mix-blend-mode: multiply;
--color-diffstat-deletion-border: rgba(27,31,36,0.15);
--color-diffstat-addition-border: rgba(27,31,36,0.15);
--color-diffstat-addition-bg: #2da44e;
--color-search-keyword-hl: #fff8c5;
--color-prettylights-syntax-comment: #6e7781;
--color-prettylights-syntax-constant: #0550ae;
--color-prettylights-syntax-entity: #8250df;
--color-prettylights-syntax-storage-modifier-import: #24292f;
--color-prettylights-syntax-entity-tag: #116329;
--color-prettylights-syntax-keyword: #cf222e;
--color-prettylights-syntax-string: #0a3069;
--color-prettylights-syntax-variable: #953800;
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
--color-prettylights-syntax-carriage-return-bg: #cf222e;
--color-prettylights-syntax-string-regexp: #116329;
--color-prettylights-syntax-markup-list: #3b2300;
--color-prettylights-syntax-markup-heading: #0550ae;
--color-prettylights-syntax-markup-italic: #24292f;
--color-prettylights-syntax-markup-bold: #24292f;
--color-prettylights-syntax-markup-deleted-text: #82071e;
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
--color-prettylights-syntax-markup-inserted-text: #116329;
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
--color-prettylights-syntax-markup-changed-text: #953800;
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
--color-prettylights-syntax-meta-diff-range: #8250df;
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
--color-codemirror-text: #24292f;
--color-codemirror-bg: #ffffff;
--color-codemirror-gutters-bg: #ffffff;
--color-codemirror-guttermarker-text: #ffffff;
--color-codemirror-guttermarker-subtle-text: #6e7781;
--color-codemirror-linenumber-text: #57606a;
--color-codemirror-cursor: #24292f;
--color-codemirror-selection-bg: rgba(84,174,255,0.4);
--color-codemirror-activeline-bg: rgba(234,238,242,0.5);
--color-codemirror-matchingbracket-text: #24292f;
--color-codemirror-lines-bg: #ffffff;
--color-codemirror-syntax-comment: #24292f;
--color-codemirror-syntax-constant: #0550ae;
--color-codemirror-syntax-entity: #8250df;
--color-codemirror-syntax-keyword: #cf222e;
--color-codemirror-syntax-storage: #cf222e;
--color-codemirror-syntax-string: #0a3069;
--color-codemirror-syntax-support: #0550ae;
--color-codemirror-syntax-variable: #953800;
--color-checks-bg: #24292f;
--color-checks-run-border-width: 0px;
--color-checks-container-border-width: 0px;
--color-checks-text-primary: #f6f8fa;
--color-checks-text-secondary: #8c959f;
--color-checks-text-link: #54aeff;
--color-checks-btn-icon: #afb8c1;
--color-checks-btn-hover-icon: #f6f8fa;
--color-checks-btn-hover-bg: rgba(255,255,255,0.125);
--color-checks-input-text: #eaeef2;
--color-checks-input-placeholder-text: #8c959f;
--color-checks-input-focus-text: #8c959f;
--color-checks-input-bg: #32383f;
--color-checks-input-shadow: none;
--color-checks-donut-error: #fa4549;
--color-checks-donut-pending: #bf8700;
--color-checks-donut-success: #2da44e;
--color-checks-donut-neutral: #afb8c1;
--color-checks-dropdown-text: #afb8c1;
--color-checks-dropdown-bg: #32383f;
--color-checks-dropdown-border: #424a53;
--color-checks-dropdown-shadow: rgba(27,31,36,0.3);
--color-checks-dropdown-hover-text: #f6f8fa;
--color-checks-dropdown-hover-bg: #424a53;
--color-checks-dropdown-btn-hover-text: #f6f8fa;
--color-checks-dropdown-btn-hover-bg: #32383f;
--color-checks-scrollbar-thumb-bg: #57606a;
--color-checks-header-label-text: #d0d7de;
--color-checks-header-label-open-text: #f6f8fa;
--color-checks-header-border: #32383f;
--color-checks-header-icon: #8c959f;
--color-checks-line-text: #d0d7de;
--color-checks-line-num-text: rgba(140,149,159,0.75);
--color-checks-line-timestamp-text: #8c959f;
--color-checks-line-hover-bg: #32383f;
--color-checks-line-selected-bg: rgba(33,139,255,0.15);
--color-checks-line-selected-num-text: #54aeff;
--color-checks-line-dt-fm-text: #24292f;
--color-checks-line-dt-fm-bg: #9a6700;
--color-checks-gate-bg: rgba(125,78,0,0.15);
--color-checks-gate-text: #d0d7de;
--color-checks-gate-waiting-text: #d4a72c;
--color-checks-step-header-open-bg: #32383f;
--color-checks-step-error-text: #ff8182;
--color-checks-step-warning-text: #d4a72c;
--color-checks-logline-text: #8c959f;
--color-checks-logline-num-text: rgba(140,149,159,0.75);
--color-checks-logline-debug-text: #c297ff;
--color-checks-logline-error-text: #d0d7de;
--color-checks-logline-error-num-text: #ff8182;
--color-checks-logline-error-bg: rgba(164,14,38,0.15);
--color-checks-logline-warning-text: #d0d7de;
--color-checks-logline-warning-num-text: #d4a72c;
--color-checks-logline-warning-bg: rgba(125,78,0,0.15);
--color-checks-logline-command-text: #54aeff;
--color-checks-logline-section-text: #4ac26b;
--color-checks-ansi-black: #24292f;
--color-checks-ansi-black-bright: #32383f;
--color-checks-ansi-white: #d0d7de;
--color-checks-ansi-white-bright: #d0d7de;
--color-checks-ansi-gray: #8c959f;
--color-checks-ansi-red: #ff8182;
--color-checks-ansi-red-bright: #ffaba8;
--color-checks-ansi-green: #4ac26b;
--color-checks-ansi-green-bright: #6fdd8b;
--color-checks-ansi-yellow: #d4a72c;
--color-checks-ansi-yellow-bright: #eac54f;
--color-checks-ansi-blue: #54aeff;
--color-checks-ansi-blue-bright: #80ccff;
--color-checks-ansi-magenta: #c297ff;
--color-checks-ansi-magenta-bright: #d8b9ff;
--color-checks-ansi-cyan: #76e3ea;
--color-checks-ansi-cyan-bright: #b3f0ff;
--color-project-header-bg: #24292f;
--color-project-sidebar-bg: #ffffff;
--color-project-gradient-in: #ffffff;
--color-project-gradient-out: rgba(255,255,255,0);
--color-mktg-btn-bg: #1b1f23;
--color-mktg-btn-shadow-outline: rgb(0 0 0 / 15%) 0 0 0 1px inset;
--color-mktg-btn-shadow-focus: rgb(0 0 0 / 15%) 0 0 0 4px;
--color-mktg-btn-shadow-hover: 0 3px 2px rgba(0, 0, 0, 0.07), 0 7px 5px rgba(0, 0, 0, 0.04), 0 12px 10px rgba(0, 0, 0, 0.03), 0 22px 18px rgba(0, 0, 0, 0.03), 0 42px 33px rgba(0, 0, 0, 0.02), 0 100px 80px rgba(0, 0, 0, 0.02);
--color-mktg-btn-shadow-hover-muted: rgb(0 0 0 / 70%) 0 0 0 2px inset;
--color-avatar-bg: #ffffff;
--color-avatar-border: rgba(27,31,36,0.15);
--color-avatar-stack-fade: #afb8c1;
--color-avatar-stack-fade-more: #d0d7de;
--color-avatar-child-shadow: -2px -2px 0 rgba(255,255,255,0.8);
--color-topic-tag-border: rgba(0,0,0,0);
--color-counter-border: rgba(0,0,0,0);
--color-select-menu-backdrop-border: rgba(0,0,0,0);
--color-select-menu-tap-highlight: rgba(175,184,193,0.5);
--color-select-menu-tap-focus-bg: #b6e3ff;
--color-overlay-shadow: 0 1px 3px rgba(27,31,36,0.12), 0 8px 24px rgba(66,74,83,0.12);
--color-header-text: rgba(255,255,255,0.7);
--color-header-bg: #24292f;
--color-header-divider: #57606a;
--color-header-logo: #ffffff;
--color-header-search-bg: #24292f;
--color-header-search-border: #57606a;
--color-sidenav-selected-bg: #ffffff;
--color-menu-bg-active: rgba(0,0,0,0);
--color-input-disabled-bg: rgba(175,184,193,0.2);
--color-timeline-badge-bg: #eaeef2;
--color-ansi-black: #24292f;
--color-ansi-black-bright: #57606a;
--color-ansi-white: #6e7781;
--color-ansi-white-bright: #8c959f;
--color-ansi-gray: #6e7781;
--color-ansi-red: #cf222e;
--color-ansi-red-bright: #a40e26;
--color-ansi-green: #116329;
--color-ansi-green-bright: #1a7f37;
--color-ansi-yellow: #4d2d00;
--color-ansi-yellow-bright: #633c01;
--color-ansi-blue: #0969da;
--color-ansi-blue-bright: #218bff;
--color-ansi-magenta: #8250df;
--color-ansi-magenta-bright: #a475f9;
--color-ansi-cyan: #1b7c83;
--color-ansi-cyan-bright: #3192aa;
--color-btn-text: #24292f;
--color-btn-bg: #f6f8fa;
--color-btn-border: rgba(27,31,36,0.15);
--color-btn-shadow: 0 1px 0 rgba(27,31,36,0.04);
--color-btn-inset-shadow: inset 0 1px 0 rgba(255,255,255,0.25);
--color-btn-hover-bg: #f3f4f6;
--color-btn-hover-border: rgba(27,31,36,0.15);
--color-btn-active-bg: hsla(220,14%,93%,1);
--color-btn-active-border: rgba(27,31,36,0.15);
--color-btn-selected-bg: hsla(220,14%,94%,1);
--color-btn-focus-bg: #f6f8fa;
--color-btn-focus-border: rgba(27,31,36,0.15);
--color-btn-focus-shadow: 0 0 0 3px rgba(9,105,218,0.3);
--color-btn-shadow-active: inset 0 0.15em 0.3em rgba(27,31,36,0.15);
--color-btn-shadow-input-focus: 0 0 0 0.2em rgba(9,105,218,0.3);
--color-btn-counter-bg: rgba(27,31,36,0.08);
--color-btn-primary-text: #ffffff;
--color-btn-primary-bg: #2da44e;
--color-btn-primary-border: rgba(27,31,36,0.15);
--color-btn-primary-shadow: 0 1px 0 rgba(27,31,36,0.1);
--color-btn-primary-inset-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
--color-btn-primary-hover-bg: #2c974b;
--color-btn-primary-hover-border: rgba(27,31,36,0.15);
--color-btn-primary-selected-bg: hsla(137,55%,36%,1);
--color-btn-primary-selected-shadow: inset 0 1px 0 rgba(0,45,17,0.2);
--color-btn-primary-disabled-text: rgba(255,255,255,0.8);
--color-btn-primary-disabled-bg: #94d3a2;
--color-btn-primary-disabled-border: rgba(27,31,36,0.15);
--color-btn-primary-focus-bg: #2da44e;
--color-btn-primary-focus-border: rgba(27,31,36,0.15);
--color-btn-primary-focus-shadow: 0 0 0 3px rgba(45,164,78,0.4);
--color-btn-primary-icon: rgba(255,255,255,0.8);
--color-btn-primary-counter-bg: rgba(255,255,255,0.2);
--color-btn-outline-text: #0969da;
--color-btn-outline-hover-text: #ffffff;
--color-btn-outline-hover-bg: #0969da;
--color-btn-outline-hover-border: rgba(27,31,36,0.15);
--color-btn-outline-hover-shadow: 0 1px 0 rgba(27,31,36,0.1);
--color-btn-outline-hover-inset-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
--color-btn-outline-hover-counter-bg: rgba(255,255,255,0.2);
--color-btn-outline-selected-text: #ffffff;
--color-btn-outline-selected-bg: hsla(212,92%,42%,1);
--color-btn-outline-selected-border: rgba(27,31,36,0.15);
--color-btn-outline-selected-shadow: inset 0 1px 0 rgba(0,33,85,0.2);
--color-btn-outline-disabled-text: rgba(9,105,218,0.5);
--color-btn-outline-disabled-bg: #f6f8fa;
--color-btn-outline-disabled-counter-bg: rgba(9,105,218,0.05);
--color-btn-outline-focus-border: rgba(27,31,36,0.15);
--color-btn-outline-focus-shadow: 0 0 0 3px rgba(5,80,174,0.4);
--color-btn-outline-counter-bg: rgba(9,105,218,0.1);
--color-btn-danger-text: #cf222e;
--color-btn-danger-hover-text: #ffffff;
--color-btn-danger-hover-bg: #a40e26;
--color-btn-danger-hover-border: rgba(27,31,36,0.15);
--color-btn-danger-hover-shadow: 0 1px 0 rgba(27,31,36,0.1);
--color-btn-danger-hover-inset-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
--color-btn-danger-hover-counter-bg: rgba(255,255,255,0.2);
--color-btn-danger-selected-text: #ffffff;
--color-btn-danger-selected-bg: hsla(356,72%,44%,1);
--color-btn-danger-selected-border: rgba(27,31,36,0.15);
--color-btn-danger-selected-shadow: inset 0 1px 0 rgba(76,0,20,0.2);
--color-btn-danger-disabled-text: rgba(207,34,46,0.5);
--color-btn-danger-disabled-bg: #f6f8fa;
--color-btn-danger-disabled-counter-bg: rgba(207,34,46,0.05);
--color-btn-danger-focus-border: rgba(27,31,36,0.15);
--color-btn-danger-focus-shadow: 0 0 0 3px rgba(164,14,38,0.4);
--color-btn-danger-counter-bg: rgba(207,34,46,0.1);
--color-btn-danger-icon: #cf222e;
--color-btn-danger-hover-icon: #ffffff;
--color-underlinenav-icon: #6e7781;
--color-underlinenav-border-hover: rgba(175,184,193,0.2);
--color-action-list-item-inline-divider: rgba(208,215,222,0.48);
--color-action-list-item-default-hover-bg: rgba(208,215,222,0.32);
--color-action-list-item-default-hover-border: rgba(0,0,0,0);
--color-action-list-item-default-active-bg: rgba(208,215,222,0.48);
--color-action-list-item-default-active-border: rgba(0,0,0,0);
--color-action-list-item-default-selected-bg: rgba(208,215,222,0.24);
--color-action-list-item-danger-hover-bg: rgba(255,235,233,0.64);
--color-action-list-item-danger-active-bg: #ffebe9;
--color-action-list-item-danger-hover-text: #cf222e;
--color-switch-track-bg: #eaeef2;
--color-switch-track-border: #afb8c1;
--color-switch-track-checked-bg: #ddf4ff;
--color-switch-track-checked-hover-bg: #b6e3ff;
--color-switch-track-checked-active-bg: #80ccff;
--color-switch-track-checked-border: #54aeff;
--color-switch-knob-checked-bg: #0969da;
--color-switch-knob-checked-disabled-bg: #6e7781;
--color-segmented-control-bg: #eaeef2;
--color-segmented-control-button-hover-bg: rgba(175,184,193,0.2);
--color-segmented-control-button-active-bg: rgba(175,184,193,0.4);
--color-segmented-control-button-selected-border: #6e7781;
--color-tree-view-item-chevron-hover-bg: rgba(208,215,222,0.32);
--color-tree-view-item-directory-fill: #54aeff;
--color-fg-default: #24292f;
--color-fg-muted: #57606a;
--color-fg-subtle: #6e7781;
--color-fg-on-emphasis: #ffffff;
--color-canvas-default: #ffffff;
--color-canvas-overlay: #ffffff;
--color-canvas-inset: #f6f8fa;
--color-canvas-subtle: #f6f8fa;
--color-border-default: #d0d7de;
--color-border-muted: hsla(210,18%,87%,1);
--color-border-subtle: rgba(27,31,36,0.15);
--color-shadow-small: 0 1px 0 rgba(27,31,36,0.04);
--color-shadow-medium: 0 3px 6px rgba(140,149,159,0.15);
--color-shadow-large: 0 8px 24px rgba(140,149,159,0.2);
--color-shadow-extra-large: 0 12px 28px rgba(140,149,159,0.3);
--color-neutral-emphasis-plus: #24292f;
--color-neutral-emphasis: #6e7781;
--color-neutral-muted: rgba(175,184,193,0.2);
--color-neutral-subtle: rgba(234,238,242,0.5);
--color-accent-fg: #0969da;
--color-accent-emphasis: #0969da;
--color-accent-muted: rgba(84,174,255,0.4);
--color-accent-subtle: #ddf4ff;
--color-success-fg: #1a7f37;
--color-success-emphasis: #2da44e;
--color-success-muted: rgba(74,194,107,0.4);
--color-success-subtle: #dafbe1;
--color-attention-fg: #9a6700;
--color-attention-emphasis: #bf8700;
--color-attention-muted: rgba(212,167,44,0.4);
--color-attention-subtle: #fff8c5;
--color-severe-fg: #bc4c00;
--color-severe-emphasis: #bc4c00;
--color-severe-muted: rgba(251,143,68,0.4);
--color-severe-subtle: #fff1e5;
--color-danger-fg: #cf222e;
--color-danger-emphasis: #cf222e;
--color-danger-muted: rgba(255,129,130,0.4);
--color-danger-subtle: #ffebe9;
--color-open-fg: #1a7f37;
--color-open-emphasis: #2da44e;
--color-open-muted: rgba(74,194,107,0.4);
--color-open-subtle: #dafbe1;
--color-closed-fg: #cf222e;
--color-closed-emphasis: #cf222e;
--color-closed-muted: rgba(255,129,130,0.4);
--color-closed-subtle: #ffebe9;
--color-done-fg: #8250df;
--color-done-emphasis: #8250df;
--color-done-muted: rgba(194,151,255,0.4);
--color-done-subtle: #fbefff;
--color-sponsors-fg: #bf3989;
--color-sponsors-emphasis: #bf3989;
--color-sponsors-muted: rgba(255,128,200,0.4);
--color-sponsors-subtle: #ffeff7;
--color-primer-fg-disabled: #8c959f;
--color-primer-canvas-backdrop: rgba(27,31,36,0.5);
--color-primer-canvas-sticky: rgba(255,255,255,0.95);
--color-primer-border-active: #fd8c73;
--color-primer-border-contrast: rgba(27,31,36,0.1);
--color-primer-shadow-highlight: inset 0 1px 0 rgba(255,255,255,0.25);
--color-primer-shadow-inset: inset 0 1px 0 rgba(208,215,222,0.2);
--color-primer-shadow-focus: 0 0 0 3px rgba(9,105,218,0.3);
--color-scale-black: #1b1f24;
--color-scale-white: #ffffff;
--color-scale-gray-0: #f6f8fa;
--color-scale-gray-1: #eaeef2;
--color-scale-gray-2: #d0d7de;
--color-scale-gray-3: #afb8c1;
--color-scale-gray-4: #8c959f;
--color-scale-gray-5: #6e7781;
--color-scale-gray-6: #57606a;
--color-scale-gray-7: #424a53;
--color-scale-gray-8: #32383f;
--color-scale-gray-9: #24292f;
--color-scale-blue-0: #ddf4ff;
--color-scale-blue-1: #b6e3ff;
--color-scale-blue-2: #80ccff;
--color-scale-blue-3: #54aeff;
--color-scale-blue-4: #218bff;
--color-scale-blue-5: #0969da;
--color-scale-blue-6: #0550ae;
--color-scale-blue-7: #033d8b;
--color-scale-blue-8: #0a3069;
--color-scale-blue-9: #002155;
--color-scale-green-0: #dafbe1;
--color-scale-green-1: #aceebb;
--color-scale-green-2: #6fdd8b;
--color-scale-green-3: #4ac26b;
--color-scale-green-4: #2da44e;
--color-scale-green-5: #1a7f37;
--color-scale-green-6: #116329;
--color-scale-green-7: #044f1e;
--color-scale-green-8: #003d16;
--color-scale-green-9: #002d11;
--color-scale-yellow-0: #fff8c5;
--color-scale-yellow-1: #fae17d;
--color-scale-yellow-2: #eac54f;
--color-scale-yellow-3: #d4a72c;
--color-scale-yellow-4: #bf8700;
--color-scale-yellow-5: #9a6700;
--color-scale-yellow-6: #7d4e00;
--color-scale-yellow-7: #633c01;
--color-scale-yellow-8: #4d2d00;
--color-scale-yellow-9: #3b2300;
--color-scale-orange-0: #fff1e5;
--color-scale-orange-1: #ffd8b5;
--color-scale-orange-2: #ffb77c;
--color-scale-orange-3: #fb8f44;
--color-scale-orange-4: #e16f24;
--color-scale-orange-5: #bc4c00;
--color-scale-orange-6: #953800;
--color-scale-orange-7: #762c00;
--color-scale-orange-8: #5c2200;
--color-scale-orange-9: #471700;
--color-scale-red-0: #ffebe9;
--color-scale-red-1: #ffcecb;
--color-scale-red-2: #ffaba8;
--color-scale-red-3: #ff8182;
--color-scale-red-4: #fa4549;
--color-scale-red-5: #cf222e;
--color-scale-red-6: #a40e26;
--color-scale-red-7: #82071e;
--color-scale-red-8: #660018;
--color-scale-red-9: #4c0014;
--color-scale-purple-0: #fbefff;
--color-scale-purple-1: #ecd8ff;
--color-scale-purple-2: #d8b9ff;
--color-scale-purple-3: #c297ff;
--color-scale-purple-4: #a475f9;
--color-scale-purple-5: #8250df;
--color-scale-purple-6: #6639ba;
--color-scale-purple-7: #512a97;
--color-scale-purple-8: #3e1f79;
--color-scale-purple-9: #2e1461;
--color-scale-pink-0: #ffeff7;
--color-scale-pink-1: #ffd3eb;
--color-scale-pink-2: #ffadda;
--color-scale-pink-3: #ff80c8;
--color-scale-pink-4: #e85aad;
--color-scale-pink-5: #bf3989;
--color-scale-pink-6: #99286e;
--color-scale-pink-7: #772057;
--color-scale-pink-8: #611347;
--color-scale-pink-9: #4d0336;
--color-scale-coral-0: #fff0eb;
--color-scale-coral-1: #ffd6cc;
--color-scale-coral-2: #ffb4a1;
--color-scale-coral-3: #fd8c73;
--color-scale-coral-4: #ec6547;
--color-scale-coral-5: #c4432b;
--color-scale-coral-6: #9e2f1c;
--color-scale-coral-7: #801f0f;
--color-scale-coral-8: #691105;
--color-scale-coral-9: #510901;
}
\ No newline at end of file
* {
margin: 0;
padding: 0;
}
.content{
background-color: #EFEFEF;
overflow: hidden;
height: 100%;
padding: 24px;
box-sizing: border-box;
}
.content .container{
/* border: 1px solid #BBBBBB; */
/* background-color: #ffffff; */
margin: 10px;
}
.content .container .form{
width: 100%;
}
.content .container .form .form-group {
width: 100%;
}
.content .container .form .form-group:nth-child(n+1) {
margin-top: 40px;
}
.content .container .form .form-group .form-group__label label{
font-size: 24px;
width: 100%;
border-bottom: 1px solid #ccc;
padding-bottom: 8px;
margin-bottom: 16px;
}
.content .container .form .form-group .form-group__label p{
font-size: 14px;
margin: 0 0 8px 0 ;
}
/* 表单组件 */
.form-group {}
.form-group .form-group__label > label {
display: flex;
justify-content: space-between;
}
.form-group .form-group__body {}
.form-group .form-group__body .form-group__item {
margin: 15px 0;
}
.form-group .form-group__body .form-group__item span:nth-of-type(1) {
display: block;
font-weight: bold;
margin-bottom: 6px;
}
.form-group .form-group__body .form-group__item span:nth-of-type(2) {}
/* Input 组件 */
input{
padding: 5px 12px;
font-size: 14px;
line-height: 20px;
color: #24292f;
vertical-align: middle;
border-radius: 6px;
background-color: #f6f8fa;
border: 1px solid #d0d7de;
}
input[disabled]{
color: var(--color-primer-fg-disabled);
background-color: var(--color-input-disabled-bg);
border-color: var(--color-border-default);
-webkit-text-fill-color: var(--color-primer-fg-disabled);
opacity: 1;
}
/* Button 组件 */
button{
position: relative;
display: inline-block;
padding: 5px 16px;
font-size: 14px;
font-weight: 500;
line-height: 20px;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
border: 1px solid;
border-radius: 6px;
-webkit-appearance: none;
appearance: none;
}
button{
background-color: #f6f8fa;
color: #24292f;
border-color: rgba(27,31,36,.15);
}
button:hover{
background-color: #f3f4f6;
border-color: rgba(27,31,36,.15);
}
button.primary{
color: #fff;
background-color:#2c974b;
border-color: rgba(27,31,36,.15);
}
button[disabled] {
cursor:not-allowed;
background-color: #eee;
}
\ No newline at end of file
<template>
<span>
<slot />
</span>
</template>
\ No newline at end of file
<template>
<div id="app">
<div class='sidebar'>
<div class='logo'></div>
<div class='item'><NuxtLink to="/home">Home</NuxtLink></div>
<div class='item'><NuxtLink to="/git">Git</NuxtLink></div>
<div class='item'><NuxtLink to="/v2">V2</NuxtLink></div>
<div class='item'><NuxtLink to="/v1">V1</NuxtLink></div>
</div>
<div class='maintab'>
<slot></slot>
</div>
</div>
</template>
<style scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
height: 100vh;
display: flex;
}
#app .sidebar{
width: 300px;
background-color: #333;
color: #fff;
}
#app .sidebar .logo{
height: 150px;
}
#app .sidebar .item {
height: 32px;
line-height: 32px;
font-size: 16px;
text-align: center;
cursor: pointer;
}
#app .sidebar a{
color: #fff;
text-decoration: none;
}
#app .sidebar .item:hover {
background-color: #6C6C6C;
}
#app .maintab{
flex: 1;
overflow: hidden;
}
</style>
import { useUserStore } from "~/store/user"
export default defineNuxtRouteMiddleware((to, from) => {
const user = useUserStore()
if (!user.username && to.path !== '/login') {
return navigateTo('/login')
}
})
\ No newline at end of file
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
modules: ['@pinia/nuxt'],
css: ['~/assets/css/main.css', '~/assets/css/color.css']
})
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@pinia/nuxt": "^0.5.1",
"lodash": "^4.17.21",
"nuxt": "^3.11.1",
"pinia": "^2.1.7",
"telnet-client": "^2.2.0",
"vue": "^3.4.21",
"vue-router": "^4.3.0"
},
"devDependencies": {
"@types/lodash": "^4.17.0"
}
}
<template>
<section>
<p>此页面将显示在 /about 路由。</p>
</section>
</template>
\ No newline at end of file
<template>
<NuxtLayout>
<div class='content'>
<div class='header container'>
<div class='row'>
<div class='avatar'>
{{ username.substring(0, 1) }}
</div>
<p>
{{ username }}
<span v-if='port !== 0'>[容器端口: <b>{{ port }}</b>]</span>
</p>
</div>
<div class='row'>
<span style="display: inline-block; width: 150px;">V2: {{ getStatusLabel(status) }}</span>
<button v-if='status === "null" || status === "creating"' :disabled='loading'
@click='handleInstall'>初始化</button>
<button v-if='status === "created" || status === "stopped" || status === "compiling"' :disabled='loading'
@click='handleCompile'>编译</button>
<button v-if='status === "created" || status === "stopped" || status === "compiling"' :disabled='loading'
@click='handleExecute'>运行</button>
<button v-if='status === "created" || status === "stopped" || status === "compiling"' :disabled='loading'
@click='handleDebug'>调试</button>
<button v-else-if='status === "running"' :disabled='loading' @click='handleStop'>停止</button>
<button v-if="status === 'running'" :disabled="loading" @click="handleZip">打包微信压缩文件</button>
<button @click="test">测试</button>
</div>
<div class='row'>
<span style="display: inline-block; width: 150px;">V1: {{ getStatusLabel(statusV1) }}</span>
<button v-if='statusV1 === "null" || statusV1 === "creating"' :disabled='loading'
@click='handleInstallV1'>初始化</button>
<button v-if='statusV1 === "created" || statusV1 === "stopped" || statusV1 === "compiling"' :disabled='loading'
@click='handleCompileV1'>编译</button>
<button v-if='statusV1 === "created" || statusV1 === "stopped" || statusV1 === "compiling"' :disabled='loading'
@click='handleExecuteV1'>运行</button>
<button v-else-if='statusV1 === "running"' :disabled='loading' @click='handleStopV1'>停止</button>
</div>
</div>
<div class='main'>
<div class='tools container'>
<div class='row'>
常用工具
</div>
<div class='row'>
<div class='tool' @click='handleOpenVscode'>
<svg t="1676878506818" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="3085" width="16" height="16">
<path
d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z"
fill="#FFFFFF" p-id="3086"></path>
<path
d="M708.82304 161.9968l137.46176 67.24608c20.81792 10.62912 23.7056 18.28864 23.7056 29.29664l0.60416 506.23488c0 13.50656-7.30112 18.82112-27.42272 30.1568l-133.8368 67.08224c-5.5808 2.60096-10.04544 5.76512-43.47904 5.76512 0 0 28.93824 0.24576 28.93824-22.87616v-662.87616a25.15968 25.15968 0 0 0-24.13568-25.76384c29.6448 0 38.16448 5.7344 38.16448 5.7344z"
fill="#4B9AE9" p-id="3087"></path>
<path
d="M163.34848 613.02784a29.21472 29.21472 0 0 0 0 38.98368s35.11296 32.62464 45.4656 41.984 25.7024 5.12 35.64544-2.37568 450.29376-343.64416 450.29376-343.64416v-165.94944a25.06752 25.06752 0 0 0-24.13568-25.76384 18.11456 18.11456 0 0 0-12.3392 5.376z"
fill="#2A63A4" p-id="3088"></path>
<path
d="M208.92672 331.74528a23.17312 23.17312 0 0 1 32.45056 0l453.4272 343.61344v169.55392c0 23.25504-28.9792 22.8352-28.9792 22.8352a17.00864 17.00864 0 0 1-10.11712-5.53984l-495.77984-454.13376a22.31296 22.31296 0 0 1 0-31.54944z"
fill="#3478C6" p-id="3089"></path>
</svg>
<p>Vscode Web V2</p>
</div>
<div class='tool' @click='handleOpenVscodeV1'>
<svg t="1676878506818" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="3085" width="16" height="16">
<path
d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z"
fill="#FFFFFF" p-id="3086"></path>
<path
d="M708.82304 161.9968l137.46176 67.24608c20.81792 10.62912 23.7056 18.28864 23.7056 29.29664l0.60416 506.23488c0 13.50656-7.30112 18.82112-27.42272 30.1568l-133.8368 67.08224c-5.5808 2.60096-10.04544 5.76512-43.47904 5.76512 0 0 28.93824 0.24576 28.93824-22.87616v-662.87616a25.15968 25.15968 0 0 0-24.13568-25.76384c29.6448 0 38.16448 5.7344 38.16448 5.7344z"
fill="#4B9AE9" p-id="3087"></path>
<path
d="M163.34848 613.02784a29.21472 29.21472 0 0 0 0 38.98368s35.11296 32.62464 45.4656 41.984 25.7024 5.12 35.64544-2.37568 450.29376-343.64416 450.29376-343.64416v-165.94944a25.06752 25.06752 0 0 0-24.13568-25.76384 18.11456 18.11456 0 0 0-12.3392 5.376z"
fill="#2A63A4" p-id="3088"></path>
<path
d="M208.92672 331.74528a23.17312 23.17312 0 0 1 32.45056 0l453.4272 343.61344v169.55392c0 23.25504-28.9792 22.8352-28.9792 22.8352a17.00864 17.00864 0 0 1-10.11712-5.53984l-495.77984-454.13376a22.31296 22.31296 0 0 1 0-31.54944z"
fill="#3478C6" p-id="3089"></path>
</svg>
<p>Vscode Web V1</p>
</div>
</div>
</div>
<div class='logs container'>
<div class='row'>
日志
</div>
<div class='row logs-content' style='overflow: auto;flex: 1;'>
<div v-for='item in renderLogs' :key='item'>
<p v-html='item'></p>
</div>
</div>
</div>
</div>
</div>
</NuxtLayout>
</template>
<script lang="ts" setup>
import { useUserStore } from '~/store/user';
const username = ref(useUserStore().username)
const status = ref('null') // null | created | stopped | running | creating | compiling
const statusV1 = ref('null')
const loading = ref(false)
const logLevel = ref('progress') // info | progress
const logs = ref([])
const port = ref(0)
const renderLogs = computed(() => {
let str = logs.value.join('')
return str.split('\n').map((o: string) => addColorfulTag(o))
})
onMounted(() => {
// socket = io({
// path: '/api/socket',
// auth: {
// username: username
// }
// });
// // eslint-disable-next-line no-control-regex
// const removeLogPrefix = (log) => log.replace(/^\[.*?\]\s/, '').replace(/[\u0000-\u0009]/g, '').replace(/[\u000B-\u001F]/g, '')
// const replaceLineFlag = (log) => log.replaceAll('\n', '<br />')
// socket.on('Log', (log) => {
// if (logLevel === 'info') {
// logs.push(replaceLineFlag(removeLogPrefix(log)))
// } else {
// if (!log.startsWith('[info]')) {
// logs.push(replaceLineFlag(removeLogPrefix(log)))
// }
// }
// if (log === '[progress] [[1;31mSuccess[m]] installed') {
// loading = false
// handleGetStatus()
// }
// })
handleGetStatus()
checkAndRestartDocker()
})
function getStatusLabel(status: string) {
return status === 'null' ? "未初始化"
: status === 'creating' ? '创建中'
: status === 'created' ? "已创建"
: status === 'running' ? '运行中'
: status === 'stopped' ? '已停止'
: status === 'compiling' ? '编译中'
: ''
}
function checkAndRestartDocker() {
$fetch('/api/checkAndRestartDocker', { method: 'post' })
}
function addColorfulTag(log: string) {
let value = log
.replace(/\[1;34m(.*?)\[m/g, '<span style="color: #5a74f5;">$1</span>')
.replace(/\[1;31m(.*?)\[m/g, '<span style="color: red">$1</span>')
.replace(/\[1m(.*?)\[m/g, '<span style="color: gray">$1</span>')
return value
}
function handleGetStatus() {
return $fetch('/api/user/getProjectInfo').then((res: any) => {
status.value = res.status || 'null'
statusV1.value = res['v1-status'] || 'null'
port.value = res['node-port']
if (status.value === 'creating' || status.value === 'compiling') {
loading.value = true
}
if (statusV1.value === 'creating' || statusV1.value === 'compiling') {
loading.value = true
}
})
}
function handleInstall() {
if (loading.value) return
logs.value = []
loading.value = true
status.value = 'creating'
$fetch('/api/installProject', { method: 'post' })
.then(handleGetStatus, handleGetStatus)
.finally(() => {
loading.value = false
})
}
function handleInstallV1() {
if (loading.value) return
logs.value = []
loading.value = true
statusV1.value = 'creating'
$fetch('/api/installProject-v1', { method: 'post' })
.then(handleGetStatus, handleGetStatus)
.finally(() => {
loading.value = false
})
}
function handleCompile() {
if (loading.value) return
loading.value = true
logs.value = []
resetV1()
$fetch('/api/backend/compile', { method: 'post'}).then(() => {
return handleGetStatus()
}).finally(() => {
loading.value = false
})
}
function handleCompileV1() {
if (loading.value) return
loading.value = true
logs.value = []
resetV2()
$fetch('/api/backend/compile-v1', { method: 'post'}).then(() => {
return handleGetStatus()
}).finally(() => {
loading.value = false
})
}
function handleExecute() {
if (loading.value) return
loading.value = true
logs.value = []
resetV1()
$fetch('/api/backend/execute').then(() => {
return handleGetStatus()
}).finally(() => {
loading.value = false
})
}
function handleExecuteV1() {
if (loading.value) return
loading.value = true
logs.value = []
resetV2()
$fetch('/api/backend/execute-v1', { method: 'post'}).then(() => {
return handleGetStatus()
}).finally(() => {
loading.value = false
})
}
function handleStop() {
if (loading.value) return
logs.value = []
loading.value = true
$fetch('/api/backend/stop', { method: 'post' }).then(() => {
return handleGetStatus()
}).finally(() => {
loading.value = false
})
}
function handleStopV1() {
if (loading.value) return
logs.value = []
loading.value = true
$fetch('/api/backend/stop-v1', { method: 'post'}).then(() => {
return handleGetStatus()
}).finally(() => {
loading.value = false
})
}
function handleZip() {
if (loading.value) return
loading.value = true
logs.value = []
$fetch('/api/backend/downloadWeApp', { method: 'post' }).finally(() => {
loading.value = false
})
}
function handleOpenVscode() {
window.open(window.location.protocol + '//' + window.location.hostname + ':' + port + '/vscode?folder=/var/logwire-backend', '_blank')
}
function handleOpenVscodeV1() {
window.open(window.location.protocol + '//' + window.location.hostname + ':' + port + '/vscode?folder=/var/logwire-platform', '_blank')
}
function handleDebug() {
if (loading.value) return
loading.value = true
logs.value = []
$fetch('/api/backend/debug', { method: 'post'}).then(() => {
return handleGetStatus()
}).finally(() => {
loading.value = false
})
}
function test() {
$fetch('/api/test/putArchive', { method: 'post' }).then(() => {
alert('测试成功')
}).catch(() => {
alert('测试失败')
})
}
function resetV1() {
statusV1.value = 'created'
}
function resetV2() {
status.value = 'created'
}
</script>
<style scoped>
.tool {
display: inline-block;
margin-right: 50px;
margin-top: 10px;
cursor: pointer;
}
.tool svg {
width: 100px;
height: 100px;
}
.content {
display: flex;
flex-direction: column;
}
.content .container .row {
border-bottom: 1px solid #BBB;
overflow: hidden;
}
.content .container .row:nth-last-of-type(1) {
border-bottom: none;
}
.content .header.container .avatar {
float: left;
width: 56px;
height: 56px;
line-height: 50px;
text-align: center;
font-size: 56px;
background-color: rgb(158, 199, 143);
color: #eee;
border-radius: 50%;
margin-top: 15px;
margin-right: 10px;
}
.content>.main {
display: flex;
overflow: hidden;
flex: 1;
}
.content>.main>.tools.container {
width: 372px;
}
.content>.main>.logs {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
</style>
\ No newline at end of file
<template>
<div>
<NuxtLayout />
</div>
</template>
\ No newline at end of file
<template>
<div class='login'>
<div class='logo'>
Welcome to Logwire Development
</div>
<div class='input'>
<input v-model='username' placeholder="请输入用户名"
@keydown.enter='handleLogin'
/>
</div>
<div class='button' @click='handleLogin'>
登录
</div>
</div>
</template>
<script lang="ts" setup>
import { useUserStore } from "@/store/user"
const username = ref('')
const userStore = useUserStore()
onMounted(() => {
username.value = localStorage.getItem('username') || ''
})
function handleLogin () {
if (/^[a-zA-Z]*$/.test(username.value) === false) {
alert('用户名只允许英文字母')
return
}
$fetch('/api/user/login', {
method: 'post',
body: { username: username.value }
}).then((value) => {
userStore.setUserName(username.value)
navigateTo('/home')
})
}
</script>
<style scoped>
.login{
height: 100%;
background-color: #101010;
text-align: center;
}
.logo{
color: #ccc;
font-size: 36px;
padding-top: 30vh;
margin-bottom: 50px;
}
.input{
width: 363px;
height: 32px;
margin: 0 auto;
margin-bottom: 68px;
}
.input input{
background-color: #333333;
border: 1xp solid #bbb;
color: #fff;
width: 100%;
outline: none;
box-sizing: border-box;
}
.button{
cursor: pointer;
width: 363px;
height: 32px;
line-height: 32px;
font-size: 16px;
color: #fff;
background-color: #6C6C6C;
border: 1px solid #BBBBBB;
margin: 0 auto;
}
</style>
\ No newline at end of file
<template>
<div>Post</div>
</template>
\ No newline at end of file
export default defineEventHandler((event) => {
let username = req.session.user as string || '1234'
let docker = createDockerFactory(username)
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
if (!container) {
// 不存在容器,则说明用户还没初始化
res.sendStatus(200)
return
}
let info = await container.inspect()
if (info.State.Running) {
// 正在运行,则认为正常
res.sendStatus(200)
} else {
LogUtil.print(username, `[progress] [[1;34mInfo[m] 服务器异常关闭,正在重启...... \n`)
await docker.startContainer({ container })
// 依次打开 nginx, 后端服务,vscode-web
try {
await docker.execContainerCommand({ container, cmd: 'lsof -i:80' })
} catch (err) {
try {
await docker.execContainerCommand({ container, cmd: 'nginx' })
LogUtil.print(username, `[progress] [[1;34mInfo[m] Nginx 重启成功...... \n`)
} catch (err) {
res.status(500).send(err)
}
}
try {
await docker.execContainerCommand({ container, cmd: 'lsof -i:8000' })
} catch (err) {
try {
docker.execContainerCommand({ container, cmd: 'code-server --bind-addr 127.0.0.1:8000 --auth none' })
LogUtil.print(username, `[progress] [[1;34mInfo[m] Vscode 重启成功...... \n`)
} catch (err) {
res.status(500).send(err)
}
}
try {
await docker.execContainerCommand({ container, cmd: 'pm2 delete backend' })
await docker.execContainerCommand({ container, cmd: 'pm2 delete gateway' })
} catch (err) {
}
await docker.execContainerCommand({ container, cmd: 'pm2 start --name gateway --no-autorestart java -- -Xms128m -Xmx128m -XX:+UseG1GC --add-opens java.base/sun.util.locale.provider=ALL-UNNAMED -jar logwire-gateway-starter.jar', dir: '/var/logwire-backend/build-output/gateway', quiet: true })
await docker.execContainerCommand({ container, cmd: `pm2 start --name backend --no-autorestart java -- -Xms128m -Xmx128m -XX:+UseG1GC -DVALIDATE_XML_ENABLED=false --add-opens java.base/sun.util.locale.provider=ALL-UNNAMED -jar logwire-backend-starter.jar`, dir: '/var/logwire-backend/build-output/backend', quiet: true })
LogUtil.print(username, `[progress] [[1;34mInfo[m] 服务重启成功...... \n`)
res.sendStatus(200)
}
})
\ No newline at end of file
export default defineEventHandler(async (event) => {
const session = await getSession(event, { password: '123456abcdefghijklmnopqrstuvwxyz'})
const username = 'wyq'
console.log('session', session)
let configs = getUserAllConfigs(username)
return configs
})
\ No newline at end of file
import { readJson, writeJson } from "../../utils"
import { getAvailableNodePort, getUserAllConfigs, getUserConfig } from "../../utils/server"
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
const username = body.username
// 当用户数据文件没有 node-port 时,认为该用户还没有注册过
if (getUserConfig(username, 'node-port') === undefined) {
let host = process.env.NODE_ENV?.trim() === 'production' ? '192.168.0.4' : 'localhost'
const port = await getAvailableNodePort(host)
const userDefaultSetting = readJson('./server/files/default-user-setting.json')
const userSetting = Object.assign({}, userDefaultSetting, { "node-port": port })
userSetting['postgres']['database'] = username
userSetting['tenants']['id'] = username
userSetting['tenants']['host'] = `a.test.com:${23333+ (port - 30000)*2},a.test.com:${23334+(port-30000)*2}`
const userDataPath = `./server/data/${username}.json`
writeJson(userDataPath, userSetting)
}
return useSession(event, { name: username, password: '123456abcdefghijklmnopqrstuvwxyz' })
} catch (err) {
console.log(err)
throw createError({
statusCode: 500,
statusMessage: '登录失败'
})
}
})
\ No newline at end of file
{
"postgres": {
"visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": {
"username": "wyq"
},
"schema": "library"
},
"redis": {
"visible": false,
"ip": "192.168.0.4",
"port": "25557"
},
"zookeeper": {
"visible": false,
"ip": "192.168.0.4",
"port": "2182"
},
"rocketmq": {
"visible": false,
"ip": "192.168.0.4",
"port": "9876"
},
"tenants": {
"visible": false,
"id": {
"username": "wyq"
},
"host": "a.test.com:23333,a.test.com:23334",
"database-schema": "library",
"primary-namespace": "library"
},
"postgresV1": {
"visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": "logwirev2",
"schema": "library"
},
"redisV1": {
"visible": false,
"ip": "192.168.0.4",
"port": "25557"
},
"tenantsV1": {
"visible": false,
"id": "wongyaqi",
"port": 8080
},
"debug": {
"host": "192.168.1.94"
},
"node-port": 30000
}
\ No newline at end of file
{
"postgres": {
"visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": "wyq",
"schema": "library"
},
"redis": {
"visible": false,
"ip": "192.168.0.4",
"port": "25557"
},
"zookeeper": {
"visible": false,
"ip": "192.168.0.4",
"port": "2182"
},
"rocketmq": {
"visible": false,
"ip": "192.168.0.4",
"port": "9876"
},
"tenants": {
"visible": false,
"id": "wyq",
"host": "a.test.com:23335,a.test.com:23336,a.test.com:29000",
"database-schema": "library",
"primary-namespace": "library"
},
"node-port": 30001,
"status": "running",
"InstallSteps": [
"创建 node 容器",
"检查 SSH Key",
"创建 postgres 容器",
"创建 redis 容器",
"创建 zookeeper 容器",
"创建 rocketmq serv 容器",
"创建 rocketmq broker 容器",
"创建 node 容器",
"检查 SSH Key",
"创建 postgres 容器",
"创建 redis 容器",
"创建 zookeeper 容器",
"创建 rocketmq serv 容器",
"创建 rocketmq broker 容器",
"克隆仓库",
"更新源",
"安装 openjdk ",
"安装 maven ",
"修改 maven 源",
"安装 Wetty",
"安装 code-server ",
"安装 nginx ",
"安装 pm2 ",
"配置 nginx ",
"启动 wetty",
"启动 code-server ",
"启动 nginx ",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"v1-创建 postgres 容器",
"v1-克隆仓库",
"v1-创建 postgres 容器",
"v1-克隆仓库",
"v1-安装 openjdk ",
"v1-更换JDK"
],
"debug": {
"host": "192.168.1.94"
},
"serverProperties": [
{
"id": 0.9830334059659578,
"key": "logwire.security.encryption.key-management-system",
"value": "logwire-kms"
},
{
"id": 0.7282073911484346,
"key": "logwire.security.encryption.logwire-kms.master-key-passwords[0]",
"value": "logwire"
}
],
"v1-status": "created",
"postgresV1": {
"visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": "wyq_v1",
"schema": "library"
},
"serverPropertiesV1": [
{
"id": 0.7463455633624243,
"key": "logwire.tenants[0].designer.password",
"value": "c4ca4238a0b923820dcc509a6f75849b"
}
]
}
# 网关服务端口
server.port=9000
# 文件上传最大大小
spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=100MB
# 默认错误处理 url
server.error.path=/error
#定制管理功能的 port, 如果端口为 -1 代表不暴露管理功能 over HTTP
management.server.port=-1
# 设定 /actuator 入口路径
management.endpoints.web.base-path=/actuator
management.endpoints.enabled-by-default=false
management.endpoints.web.exposure.include=health,prometheus,metrics,backend-prometheus
management.endpoint.health.enabled=true
management.endpoint.metrics.enabled=true
management.endpoint.prometheus.enabled=true
# 日志相关配置
logging.level.org.springframework=INFO
logging.level.io.netty=INFO
logging.level.com.zaxxer.hikari=INFO
logging.level.com.alibaba.excel=INFO
logging.level.io.lettuce=INFO
logging.level.org.hibernate=INFO
logging.level.org.eclipse=INFO
logging.level.org.apache.zookeeper=INFO
logging.level.org.springframework.boot.autoconfigure.logging=error
# MQ 相关配置
# MQ name service address; 默认值:localhost:9876
gateway.mq.name-srv-address=192.168.0.190:9876
# Gateway 请求 Backend 超时时间; 默认值:60000; 单位:毫秒
gateway.router-timeout=60000
# 环境类型; 默认值:dev; 可选值:dev; uat; prod;
gateway.environment-type=dev
# 是否开启 WebSocket 服务
gateway.web-socket-enabled=
# 注册中心地址; 默认值:127.0.0.1:2181
gateway.register-center-server-list=192.168.0.190:30003
# Coopwire 相关配置
# 是否连接到 Coopwire; 默认值:false
gateway.coopwire.connected=false
# 访问 Coopwire ClientId
gateway.coopwire.client-key=
# 访问 Coopwire security
gateway.coopwire.client-security=
# 异步请求回调 Coopwire 地址
gateway.coopwire.callback-url=
# 租户信息变更时通知 Coopwire 地址
gateway.coopwire.update-instances-url=
# 数据库连接 url
spring.datasource.url=jdbc:postgresql://192.168.0.190:30001/logwirev2
# 数据库连接用户名
spring.datasource.username=postgres
# 数据连接密码
spring.datasource.password=postgres
# 数据库连接驱动
spring.datasource.driver-class-name=org.postgresql.Driver
# 数据库连接池
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
# 连接池最小连接数
spring.datasource.hikari.minimum-idle=5
# 连接池最大连接数
spring.datasource.hikari.maximum-pool-size=50
# 连接建立超时时间
spring.datasource.hikari.connection-timeout=3000
# redis 数据库默认使用db0
spring.redis.database=0
# redis 密码
spring.redis.password=
# redis 端口
spring.redis.port=30002
# redis host
spring.redis.host=192.168.0.190
# 连接超时时间(单位:毫秒)
spring.redis.timeout=3000
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=10
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=10
# 连接池最大阻塞等待时间(单位:毫秒,使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=1000
# 在关闭客户端连接之前等待任务处理完成的最长时间(单位:毫秒),在这之后,无论任务是否执行完成,都会被执行器关闭,默认100ms
spring.redis.lettuce.shutdown-timeout=100
# 是否缓存空值
spring.cache.redis.cache-null-values=false
# 日志相关配置
logging.level.org.springframework=INFO
logging.level.io.netty=INFO
logging.level.com.zaxxer.hikari=INFO
logging.level.com.alibaba.excel=INFO
logging.level.io.lettuce=INFO
logging.level.org.hibernate=INFO
logging.level.org.eclipse=INFO
logging.level.org.apache.zookeeper=INFO
logging.level.org.apache.http=INFO
logging.level.org.elasticsearch=INFO
logging.level.com.obs=INFO
logging.level.org.quartz.core=INFO
logging.level.net.sf.jasperreports=INFO
logging.level.logwire=DEBUG
logging.level.org.springframework.boot.autoconfigure.logging=error
# MQ 相关配置
# MQ name service address; 默认值:localhost:9876
logwire.mq.name-srv-address=192.168.0.190:9876
# Backend 服务端口; 默认值:8091
logwire.server-port=9001
# 前端资源路径; 默认值:./frontend
logwire.frontend-path=./frontend
# 环境类型; 默认值:dev; 可选值:dev; uat; prod;
logwire.environment-type=dev
# 是否开启 CSRF 校验; 默认值:true
logwire.csrf-check-enabled=true
# 注册中心地址; 默认值:127.0.0.1:2181
logwire.register-center-server-list=192.168.0.190:30003
# 共享线程池大小; 默认值:C*2
logwire.shared-thread-pool-size=
# 检测到白名单之外的代码时是否抛出异常; 默认值:false
logwire.java-files-check-enabled=false
# Document 配置
# 是否开启客户端直连文件存储服务器; 默认值:false
logwire.document.client-direct-access-storage-service=false
# 文件存储服务器类型; 默认值:db; 可选值:db; obs; oss; azure-blob; aws-s3; dir;
logwire.document.storage-type=obs
# 当 storage-type 类型为 dir 时,配置该参数,值为文件存储目录
logwire.document.storage-dir=
logwire.document.obs.bucket-name=saas-platform-dev
logwire.document.obs.end-point=obs.cn-east-2.myhuaweicloud.com
logwire.document.obs.access-key=EFM5GPM1R9JOJYHE5VM6
logwire.document.obs.secret-key=7SaE5ZiADGywxWcJSvYEqr5nLgh2dcfG1Bm08bIk
# 华为云 OBS 相关配置
# 阿里云 OSS 相关配置
# 微软 Azure Blob 相关配置
# 亚马逊云 AWS-S3 相关配置
# 审计相关配置
# 是否开启审计日志; 默认值:false
logwire.model-audit.enabled=false
# 默认使用用户操作日志记录审计内容
#logwire.model-audit.audit-type=log
# 监控配置
# 记录 SQL 耗时阈值,当 SQL 耗时超过该阈值时将 SQL MD5 记录到 Prometheus; 默认值:2000; 单位:毫秒
logwire.monitor.sql-cost-threshold=2000
# 记录 Process(Action, OpenApi, Task) 耗时阈值,当 Process 耗时超过该阈值时将 Process 名称记录到 Prometheus; 默认值:2000; 单位:毫秒
logwire.monitor.process-cost-threshold=2000
# 设计器 Git 认证配置
# 设计器证书根目录; 默认值:config/git-ssh/
logwire.git-ssh.certificate-path=/root/wongyaqi
# Gitlab 公钥; 默认值:host-key.pub
logwire.git-ssh.host-key-filename=host-key.pub
# 是否直接信任 Gitlab 公钥,开启时忽略对 Gitlab 公钥的校验; 默认值:true
logwire.git-ssh.trust-all-remote=true
# 设计器私钥; 默认值:client-key.pri
logwire.git-ssh.private-key-filename=client-key.pri
# 设计器公钥; 默认值:client-key.pub
logwire.git-ssh.public-key-filename=client-key.pub
# Coopwire 配置
# 是否连接到 Coopwire; 默认值:false
logwire.coopwire.connected=false
# 设计器单点登录跳转 URL; 默认值:https://coop.logwire.cn/logwire/authorize
logwire.coopwire.sso-login-redirect-url=https://coop.logwire.cn/logwire/authorize
# 设计器单点登录获取用户信息 URL; 默认值:https://coop.logwire.cn/rest/auth/logwire/userInfo
logwire.coopwire.sso-get-user-info-url=https://coop.logwire.cn/rest/auth/logwire/userInfo
# 从 Coopwire 下载依赖 jar 包 URL; 默认值:https://coop.logwire.cn/getFile
logwire.coopwire.download-jar-url=https://coop.logwire.cn/getFile
# 访问 Coopwire ClientId
logwire.coopwire.client-key=
# 访问 Coopwire security
logwire.coopwire.client-security=
# 资源限制配置
# Query 分页查询最多允许数据条数; 默认值:1000
logwire.limit.query-max-row-size=1000
# Query 查询默认超时时间; 默认值:15; 单位:秒
logwire.limit.query-timeout-seconds=15
# Jod Office 转换配置
# 归档配置
# 归档数据库标题
# logwire.archives[ds1].title={i18n}archive.ds1
# logwire.archives[ds1].datasource.url=jdbc:postgresql://192.168.0.4:5432/archive_data
# logwire.archives[ds1].datasource.username=postgres
# logwire.archives[ds1].datasource.password=123456
# 归档数据库
# 文件归档相关配置
# 是否开启客户端直连文件存储服务器; 默认值:false
#logwire.archives[demo].document.client-direct-access-storage-service=false
# 文件存储服务器类型; 默认值:db; 可选值:db; obs; oss; azure-blob; aws-s3; dir;
#logwire.archives[demo].document.storage-type=db
# 当 storage-type 类型为 dir 时,配置该参数,值为文件存储目录
#logwire.archives[demo].document.storage-dir=
# 华为云 OBS 相关配置
# 阿里云 OSS 相关配置
# 微软 Azure Blob 相关配置
# 亚马逊云 AWS-S3 相关配置
# 第二数据源配置
# 第二数据源标题
logwire.secondary-data-sources[demo].title=测试
# 第二数据源类型,可选值为:postgresql, mysql, oracle, sqlserver, clickhouse; 可选值:postgresql; mysql; oracle; sqlserver; clickhouse;
logwire.secondary-data-sources[demo].db-type=clickhouse
# 第二数据源 hikari 配置
# 第二数据源 clickhouse 配置
logwire.secondary-data-sources[demo].click-house.mode=cluster
logwire.secondary-data-sources[demo].click-house.url=jdbc:clickhouse://192.168.0.4:8123
# Logwire 安全相关配置
# 数据库数据加解密相关配置
# 数据密钥管理系统类型; 默认值:logwire-kms; 可选值:logwire-kms; huaweicloud-dew; aliyun-kms;
logwire.security.encryption.key-management-system=logwire-kms
# Logwire KMS 相关配置
# 主密钥口令列表,需要包含历史上的主密钥口令(只能新增不能删除或修改)
#logwire.security.encryption.logwire-kms.master-key-passwords[0]=
# 华为云 KMS DEW 相关配置
# 阿里云 KMS 相关配置
# 租户列表
# 租户 Id, 如 t01
logwire.tenants[0].id=wongyaqi
# 租户 host, 根据浏览器地址栏中的 host 进行租户匹配,如 t01.com:8080
logwire.tenants[0].host=a.test.com:23333,a.test.com:23334
# 租户依赖产品及第三方包路径; 默认值:./products
logwire.tenants[0].lib-path=./products
# 租户数据库 schema, 如果为空则默认使用租户 id; 默认值:{租户 Id}
logwire.tenants[0].database-schema=library
# 租户配置路径; 默认值:./tenants_config
logwire.tenants[0].config-path=./tenants_config
# 租户主要命名空间,一般是项目命名空间,如 dhl
logwire.tenants[0].primary-namespace=library
# 设计器 Git 地址
#logwire.tenants[0].git-ssh-url=ssh://git@gitlab.logwire.cn:13389/kyle.wang/wk-demo.git
# 租户启动时默认分支,为空则使用当前分支
#logwire.tenants[0].default-branch=
# 当前节点堆外提供哪些 process 服务
#logwire.tenants[0].exposed-processes=
# Default Admin 用户邮箱地址,如果不为空则在系统初始化时向该邮箱发送 Admin 的激活邮件,如果为空则使用 defaultAdminPassword 作为 Admin 密码
#logwire.tenants[0].default-admin-email=
# Default Admin 密码,与 defaultAdminEmail 至少一个配置有值
#logwire.tenants[0].default-admin-password=
# 租户加载时是否根据 Model 配置同步数据库表结构; 默认值:true
#logwire.tenants[0].install-on-boot=true
# 是否允许用户在多处(相同设备)登录; 默认值:true
#logwire.tenants[0].allow-multiple-login=true
# Action 线程池大小; 默认值:max(32, C*16)
#logwire.tenants[0].action-thread-pool-size=
# Action 线程池队列大小; 默认值:action thread size
#logwire.tenants[0].action-thread-pool-queue-size=
# OpenApi 线程池大小; 默认值:max(32, C*16)
#logwire.tenants[0].open-api-thread-pool-size=
# OpenApi 线程池队列大小; 默认值:openApi thread size
#logwire.tenants[0].open-api-thread-pool-queue-size=
# Background 线程池大小; 默认值:max(32, C*16)
#logwire.tenants[0].background-thread-pool-size=
# Background 线程池队列大小; 默认值:background thread size
#logwire.tenants[0].background-thread-pool-queue-size=
# 默认事务超时时间; 默认值:60; 单位:秒
#logwire.tenants[0].default-transaction-timeout-second=60
# 浏览器端登录超时时间; 默认值:60 * 60 * 24 * 7; 单位:秒
#logwire.tenants[0].browser-login-expire-time-second=
# 手机端登录超时时间; 默认值:60 * 60 * 24 * 30; 单位:秒
#logwire.tenants[0].mobile-login-expire-time-second=
# 单点登录配置
# 是否开启 sso 登录
#logwire.tenants[0].sso.enabled=
# 默认使用的 sso 方式
#logwire.tenants[0].sso.default-idp=
# sso 配置
# IDP 类型
#logwire.tenants[0].sso.idp[demo].protocol=
# 标题
#logwire.tenants[0].sso.idp[demo].title=
# 显示图标
#logwire.tenants[0].sso.idp[demo].icon=
# OIDC 配置
# 是否同步用户信息
# 退出登录时页面跳转方式
#logwire.tenants[0].sso.idp[demo].oidc.logout-mode=
# 钉钉配置
# Client Secret
#logwire.tenants[0].sso.idp[demo].dt.client-secret=
# Client Id
#logwire.tenants[0].sso.idp[demo].dt.client-id=
# QQ 配置
# 微信配置
# Client Secret
#logwire.tenants[0].sso.idp[demo].wechat.client-secret=
# Client Id
#logwire.tenants[0].sso.idp[demo].wechat.client-id=
# 租户自定义参数配置
#logwire.tenants[0].ext[demo]=
# 客户端配置
#logwire.tenants[0].client[demo]=
# 业务编号相关配置
# 生成业务编号使用时区; 默认值:Asia/Shanghai
#logwire.tenants[0].model.biz-no-timezone-id=Asia/Shanghai
# MQ 相关配置
# 最大 MQ 消费队列数量; 默认值:64
#logwire.tenants[0].mq.max-consumer-size=64
# 任务相关配置
# 任务队列配置,如 logwire.tenants[].task.consumer-queues[order]=5
#logwire.tenants[0].task.consumer-queues[demo]=
# 任务处理默认使用时区,为空时使用操作系统当前时区
#logwire.tenants[0].task.default-time-zone=
# Quartz 相关配置
# Quartz 线程数量; 默认值:4
#logwire.tenants[0].quartz.thread-count=4
# 邮箱相关配置
# 邮箱协议; 默认值:smtps
#logwire.tenants[0].mail[demo].protocol=smtps
# SMTP 授权用户名(同时也是邮件作者)
#logwire.tenants[0].mail[demo].user=
# 邮件发送人,如果未指定,则使用username
#logwire.tenants[0].mail[demo].from=
# 指定 smtp 服务器地址
#logwire.tenants[0].mail[demo].host=
# 指定 smtp 服务器端口; 默认值:465
#logwire.tenants[0].mail[demo].port=465
# 指定发件箱的登陆密码
#logwire.tenants[0].mail[demo].password=
# 连接邮件服务器超时时间; 默认值:10000; 单位:毫秒
#logwire.tenants[0].mail[demo].connectiontimeout=10000
# 发送邮件超时时间; 默认值:10000; 单位:毫秒
#logwire.tenants[0].mail[demo].timeout=10000
# 其他配置
#logwire.tenants[0].mail[demo].more[demo]=
# 租户安全相关配置
# Content Security Policy 配置
# Content Security Policy Script src 配置; 默认值:'self' 'unsafe-eval' 'nonce-logwire'
#logwire.tenants[0].security.csp.script-src='self' 'unsafe-eval' 'nonce-logwire'
# Content Security Policy Child src 配置; 默认值:'self' blob:'
#logwire.tenants[0].security.csp.child-src='self' blob:'
# Content Security Policy Frame Ancestors 配置; 默认值:'self'
#logwire.tenants[0].security.csp.frame-ancestors='self'
# 设计器密码
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
brokerIP1 = 192.168.0.190
\ No newline at end of file
{
"postgres": {
"visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": "logwirev2",
"schema": "library"
},
"redis": {
"visible": false,
"ip": "192.168.0.4",
"port": "25557"
},
"zookeeper": {
"visible": false,
"ip": "192.168.0.4",
"port": "2182"
},
"rocketmq": {
"visible": false,
"ip": "192.168.0.4",
"port": "9876"
},
"tenants": {
"visible": false,
"id": "wongyaqi",
"host": "a.test.com:23333,a.test.com:23334",
"database-schema": "library",
"primary-namespace": "library"
},
"postgresV1": {
"visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": "logwirev2",
"schema": "library"
},
"redisV1": {
"visible": false,
"ip": "192.168.0.4",
"port": "25557"
},
"tenantsV1": {
"visible": false,
"id": "wongyaqi",
"port": 8080
},
"debug": {
"host": "192.168.1.94"
}
}
\ No newline at end of file
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
stream {
upstream tcp {
server 127.0.0.1:8090;
}
upstream java {
server 127.0.0.1:6666;
}
map $remote_addr $upstream {
default tcp;
192.168.1.94 java;
}
server {
listen 8080;
proxy_pass $upstream;
ssl_preread on;
}
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 8090;
server_name localhost;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /download {
alias /var/logwire-backend/build-output;
sendfile on;
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
charset utf-8;
}
location /wetty {
proxy_pass http://127.0.0.1:3001;
}
location /api/ {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /vscode {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Accept-Encoding gzip;
}
# v1
location /message {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /api {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /logout {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /assets {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /otm-dev {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /password {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /auth {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /t/t01 {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /sso {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /handler {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
location /checkServiceTicket {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
client_max_body_size 0;
}
}
}
console
console
\ No newline at end of file
<settingsSecurity>
<master>{7CLISaeYZroH4Y3HBeEfUKAzjPE+gH9GS21IzKThGRw=}</master>
</settingsSecurity>
\ No newline at end of file
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>nexus.grea.member</id>
<mirrorOf>*</mirrorOf>
<url>https://nexus.logwire.cn/repository/member/</url>
</mirror>
</mirrors>
<servers>
<server>
<id>nexus.grea.member</id>
<username>wongyaqi</username>
<password>{Nlckr1Vtk3YHhlCpns97jtI6uuSzilAw/wpj7MGHuZQ=}</password>
</server>
<server>
<id>nexus.grea.releases</id>
<username>wongyaqi</username>
<password>{Nlckr1Vtk3YHhlCpns97jtI6uuSzilAw/wpj7MGHuZQ=}</password>
</server>
<server>
<id>nexus.grea.snapshots</id>
<username>wongyaqi</username>
<password>{Nlckr1Vtk3YHhlCpns97jtI6uuSzilAw/wpj7MGHuZQ=}</password>
</server>
<server>
<id>nexus.grea.thirdparty</id>
<username>wongyaqi</username>
<password>{Nlckr1Vtk3YHhlCpns97jtI6uuSzilAw/wpj7MGHuZQ=}</password>
</server>
</servers>
</settings>
\ No newline at end of file
# Spring DataSource
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/tms
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jta.atomikos.datasource.test-query=select 1
#spring.datasource.url=jdbc:oracle:thin:@192.168.0.16:1521:orcl
#spring.datasource.username=cevademo
#spring.datasource.password=cevademo
#spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
#spring.jta.atomikos.datasource.test-query=select 1 from dual
#spring.datasource.url=jdbc:oracle:thin:@139.196.102.147:1521:otmppt
#spring.datasource.username=CMTOWNER
#spring.datasource.password=CMTOWNER
#spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
#spring.jta.atomikos.datasource.test-query=select 1 from dual
#logwire.otm-single-sign-on-urls[0]=http://139.196.136.1:7779/GC3/bridge.jsp
#logwire.otm-single-sign-on-urls[1]=http://139.196.136.2:7779/GC3/bridge.jsp
logwire.otm-vpd-aware=true
logwire.otm-vpd-call=LW_SET_USER
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/world
#spring.datasource.username=root
#spring.datasource.password=password
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.jta.atomikos.datasource.test-query=select 1
# JTA connection pool
# Properties of com.atomikos.jdbc.AbstractDataSourceBean
spring.jta.atomikos.datasource.max-pool-size=20
spring.jta.atomikos.datasource.min-pool-size=2
# Spring Web
spring.mvc.staticPathPattern=/static/**
# Spring Resources for development
spring.resources.staticLocations=file:./src/main/resources/static/,classpath:/static/
# Spring Jackson
spring.jackson.deserialization.USE_BIG_DECIMAL_FOR_FLOATS=true
# Spring FreeMarker
spring.freemarker.cache=false
spring.freemarker.prefer-file-system-access=false
spring.freemarker.template-loader-path=file:./src/main/resources/templates/,classpath:/templates/
# Spring http upload
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
# Spring Logging
logging.file=./logs/logwire-web.log
logging.pattern.level=%5p/%5X{tenant}
logging.level.org.springframework=INFO
logging.level.com.atomikos=WARN
logging.level.com.atomikos.jdbc.AtomikosDataSourceBean=INFO
logging.level.logwire=DEBUG
# JTA
spring.jta.atomikos.properties.enable-logging=false
# default 30000 ms
spring.jta.atomikos.properties.default-jta-timeout=300000
spring.jta.atomikos.properties.max-timeout=300000
spring.jta.atomikos.properties.console-log-level=WARN
spring.jta.atomikos.properties.console-file-count=10
# 10 mb
spring.jta.atomikos.properties.console-file-limit=10485760
## SQLs to grant, log on sys as sysdba to grant
## grant select on sys.dba_pending_transactions to <user name>;
## grant select on sys.pending_trans$ to <user name>;
## grant select on sys.dba_2pc_pending to <user name>;
## grant execute on sys.dbms_system to <user name>;
# JWT
jwt.header=Authentication
jwt.secret=my-secret
jwt.expiration=3600
jwt.route.authentication.login=/api/auth/login
jwt.route.authentication.refresh=/api/auth/refresh
jwt.route.authentication.role=/api/auth/role
jwt.weixin.header=WeixinAuthentication
jwt.weixin.secret=my-secret-weixin
jwt.weixin.expiration=3600
# Web Server
# server.port = 8080
server.compression.enabled=true
server.compression.min-response-size=2048
server.compression.mime-types=application/json,application/javascript,text/css,text/csv
# LogWire Properties class
logwire.enable-vpd=false
logwire.task-schedule-mode=redisson
logwire.admin-user-gid=DEFAULT.ADMIN
logwire.weixin-oauth-access-token-uri=https://api.weixin.qq.com/sns/oauth2/access_token
logwire.weixin-cgi-bin-material-uri=https://api.weixin.qq.com/cgi-bin/media/get
# logwire.otm-single-sign-on-url=http://139.196.136.1:7779/GC3/bridge.jsp
logwire.default-tenant-id=t01
logwire.projects-base-dir=./projects
logwire.tenants[0].id=t01
logwire.tenants[0].dir=./projects/t01,./projects/core
#logwire.tenants[0].dir=/Users/gang/Git/grea/QFKD
#logwire.tenants[0].id=ac
#logwire.tenants[0].dir=C:/Users/jerry.deng/git/anjiceva
#logwire.tenants[0].id=cmt
#logwire.tenants[0].dir=D:/Projects/cmt/project
#logwire.tenants[0].id=ceva
#logwire.tenants[0].dir=C:/Users/jerry.deng/git/anjiceva
server.port=9000
# pg??
spring.datasource.url=jdbc:postgresql://192.168.0.4:25556/wongyaqi
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.servlet.multipart.max-file-size=1024KB
# redis ???????db0
spring.redis.database=0
# redis ??
#spring.redis.password=
# redis ??
spring.redis.port=25557
# redis host
spring.redis.host=192.168.0.4
# ??????
logwire.jod-converter.enabled=false
logwire.jod-converter.host=192.168.0.25
logwire.jod-converter.port=2002
logwire.projects-base-dir=./projects
# ?????
logwire.multiple-tenants=false
# ??????
logwire.use-multi-db-schemas=true
#????
logwire.default-tenant-id=t01
logwire.tenants[0].id=t01
logwire.tenants[0].host=t01.com:8080
logwire.tenants[0].dir=./projects/demo
logwire.tenants[0].lib-dir=./product
logwire.tenants[0].designer.username=admin
logwire.tenants[0].designer.password=21232F297A57A5A743894A0E4A801FC3
# op-manager ???????
# admin/admin
logwire.tenants[0].op-manager.username=admin
logwire.tenants[0].op-manager.password=21232F297A57A5A743894A0E4A801FC3
# ????
logwire.production-mode=false
logwire.install-on-boot=true
logwire.enable-task-schedule=true
#??????????(????)
logwire.tenants[0].password-recover-enabled=true
#????
logwire.tenants[0].application-name=\u6d4b\u8bd5
logwire.tenants[0].mail.username=zhenglechao@logwirecloud.com
logwire.tenants[0].mail.host=smtp.mxhichina.com
logwire.tenants[0].mail.password=flzx.3qc
logwire.tenants[0].mail.protocol=smtp
logwire.tenants[0].mail.encoding=utf-8
#obs
logwire.document-storage-type=obs
logwire.obs.bucket-name=platform-dev
logwire.obs.end-point=obs.cn-east-3.myhuaweicloud.com
logwire.obs.access-key-id=BLVYTFIPDZDN57ZTCQ5K
logwire.obs.access-key-secret=kPaWoZdyaLQVGYQo0PPTIpwHQi0SaDIE1pmE0itZ
#azure-blob
#logwire.document-storage-type=blob
#logwire.blob.account-name=logwireblob
#logwire.blob.account-key=/5R7rO6JY8zCeXOnk212TB6CQsgLzBtXQLtb1MEg3DzKWuwzqAbUTWQgHjbpt97R5oQNoy2us6J+OnfwO5UO2g==
#logwire.blob.end-point=core.chinacloudapi.cn
#logwire.blob.protocol=https
# jwt???
#logwire.tenants[0].jwt-config.black-list-enabled=true
#logwire.max-content-size=1B
#logwire.tenants[0].max-content-size=1B
logwire.security.master-key.password=abc
jwt.secret=1234
# 6.x elasticsearch ??
#logwire.record-operation-log=true
#spring.data.elasticsearch.cluster-name=elasticsearch
#spring.data.elasticsearch.cluster-nodes=192.168.0.25:9300
# 7.x elasticsearch ??
#spring.elasticsearch.rest.uris=192.168.0.4:9200,192.168.0.4:9202,192.168.0.4:9203
#spring.elasticsearch.rest.username=elastic
#spring.elasticsearch.rest.password=Welc0me1
# logwire??????
# ????????????
logwire.memory-monitor.enabled=true
# dump???????????
logwire.memory-monitor.dump-path=./
# ?????????? 70%
logwire.memory-monitor.heap-percent-limit=70
# ??????????? 80%
logwire.memory-monitor.non-heap-percent-limit=80
# ?? gc ????????
logwire.gc-monitor.enabled=true
# dump???????????
logwire.gc-monitor.dump-path=./
logwire.tenants[0].coopwire.feedback-enabled=false
logwire.coopwire.auth-url=https://auth.local.logwire.cn:52006
logwire.coopwire.base-url=https://dev9302.local.logwire.cn:52006
logwire.tenants[0].coopwire.client-id=63f46933a4136d3a9d052b88
logwire.tenants[0].coopwire.client-secret=t9iaLzqOZdsenHUpmmeFpx6cOgnDSd80
logwire.tenants[0].weixin-config[wyq].appid=wxf9d16cb9cb3d28b4
logwire.tenants[0].weixin-config[wyq].secret=98cbc45201345f40182e4bd018d00487
logwire.tenants[0].weixin-config[default].appid=wxf9d16cb9cb3d28b4
logwire.tenants[0].weixin-config[default].secret=98cbc45201345f40182e4bd018d00487
logwire.tenants[0].weixin-config[gongzhonghao].appid=wxf9d16cb9cb3d28b4
logwire.tenants[0].weixin-config[gongzhonghao].secret=98cbc45201345f40182e4bd018d00487
\ No newline at end of file
zh_CN.UTF-8 UTF-8
\ No newline at end of file
export default defineEventHandler((event) => {
// console.log(event)
})
\ No newline at end of file
{
"extends": "../.nuxt/tsconfig.server.json"
}
import fs from 'fs'
import path from 'path'
export function readJson(path: string): Record<string, any> {
try {
const text = fs.readFileSync(path, { encoding: 'utf-8'})
const obj = JSON.parse(text)
return obj
} catch (err) {
return {}
}
}
export function writeJson(path: string, obj: Record<string, string>) {
fs.writeFileSync(
path,
JSON.stringify(obj, null, 2)
)
}
\ No newline at end of file
import path from 'path'
import fs from 'fs'
import lodash from 'lodash'
import { Telnet } from 'telnet-client'
export function getUserConfig (username: string, config: string) {
let jsonPath = path.resolve('./server/data/' + username + '.json')
try {
let jsonStr = fs.readFileSync(jsonPath, { encoding: 'utf-8' })
let json = JSON.parse(jsonStr) || {}
return lodash.get(json, config)
} catch (err: any) {
console.log(err)
}
}
// 在目标服务器上,获取 node 可用的端口
export async function getAvailableNodePort (ip: string, startPort = 30000) {
const tryPortAvailable = async function (port: number): Promise<number> {
let telnet = new Telnet()
const params = {
host: ip,
port: port,
negotiationMandatory: false,
timeout: 1500
}
try {
await telnet.connect(params)
telnet.end()
return tryPortAvailable(port + 1)
} catch (err) {
return port
}
}
return tryPortAvailable(startPort)
}
export function getUserAllConfigs (username: string): Record<string, string> {
let jsonPath = path.resolve('./server/data/' + username + '.json')
let jsonStr = fs.readFileSync(jsonPath, { encoding: 'utf-8' })
let json = JSON.parse(jsonStr) || {}
return json
}
\ No newline at end of file
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', () => {
const username = ref('')
const config = ref({})
function setUserName (name: string) {
username.value = name
}
function setUserConfig (name: string, obj: Object) {
config.value = obj
username.value = name
}
return { username, config, setUserName, setUserConfig }
})
\ No newline at end of file
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment