samwaf-web前端代码

master
wangxy 1 month ago
commit 425a42b6cb

@ -0,0 +1,14 @@
root = true
[*]
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.{ts,js,vue,css}]
indent_size = 2

@ -0,0 +1,3 @@
VITE_SOME_KEY=123
# 打包路径 根据项目不同按需配置
VITE_BASE_URL = ./

@ -0,0 +1,3 @@
VITE_SOME_KEY=456
# 打包路径
VITE_BASE_URL = ./

@ -0,0 +1,3 @@
dist
node_modules
!.prettierrc.js

@ -0,0 +1,76 @@
{
"extends": ["airbnb-base", "prettier", "plugin:@typescript-eslint/recommended", "plugin:vue/essential"],
"env": {
"browser": true,
"node": true,
"jest": true,
"es6": true
},
"globals": {
"cy": "readonly"
},
"plugins": ["vue", "@typescript-eslint"],
"parserOptions": {
"parser": "@typescript-eslint/parser",
"sourceType": "module",
"allowImportExportEverywhere": true,
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"@typescript-eslint/ban-ts-ignore": 0,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-require-imports": 0,
"@typescript-eslint/no-var-requires": 0,
"@typescript-eslint/prefer-for-of": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"import/no-extraneous-dependencies": 0,
"import/extensions": 0,
"import/no-unresolved": 0,
"indent": [2, 2],
"camelcase": 0,
"class-methods-use-this": 0,
"new-cap": 0,
"no-new": 1,
"no-shadow": 0,
"no-console": 0,
"no-underscore-dangle": 0,
"no-confusing-arrow": 0,
"no-plusplus": [
"error",
{
"allowForLoopAfterthoughts": true
}
],
"no-param-reassign": 0,
"func-style": 0,
"prefer-default-export": 0,
"max-len": 0,
"consistent-return": 0
},
"overrides": [
{
"files": ["*.vue"],
"rules": {
"vue/return-in-computed-property": 1,
"vue/order-in-components": 2,
"vue/component-name-in-template-casing": [2, "kebab-case"],
"vue/require-default-prop": 0,
"@typescript-eslint/explicit-module-boundary-types": "off",
"import/order": "off"
}
},
{
"files": ["src/*", "*.js"],
"rules": {
"no-var-requires": 0,
"no-console": 0,
"no-unused-expressions": 0,
"@typescript-eslint/explicit-module-boundary-types": "off",
"import/order": "off"
}
}
]
}

@ -0,0 +1,84 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
name: SamWafWeb CI
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.20.4]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
- name: Get version from package.json
id: get_version
run: |
VERSION=$(node -p "require('./package.json').version")
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Create .zip package
run: |
zip -r dist.zip dist
- name: Create .tar.gz package
run: |
tar -czvf dist.tar.gz dist
- name: Upload artifacts dist.zip
uses: actions/upload-artifact@v4
with:
name: dist.zip
path: |
dist.zip
- name: Upload artifacts dist.tar.gz
uses: actions/upload-artifact@v4
with:
name: dist.tar.gz
path: |
dist.tar.gz
- name: Create GitHub Release
id: create_release
uses: actions/create-release@v1.1.4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v${{ env.VERSION }}
release_name: v${{ env.VERSION }}
draft: false
prerelease: false
- name: Upload Release Assets dist.zip
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: dist.zip
asset_name: dist.zip
asset_content_type: application/octet-stream
- name: Upload Release Assets dist.tar.gz
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: dist.tar.gz
asset_name: dist.tar.gz
asset_content_type: application/octet-stream

13
.gitignore vendored

@ -0,0 +1,13 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
.vscode
.history
README.html
.stylelintcache
.idea
yarn.lock

@ -0,0 +1,39 @@
module.exports = {
// 一行最多 120 字符
printWidth: 120,
// 使用 2 个空格缩进
tabWidth: 2,
// 不使用缩进符,而使用空格
useTabs: false,
// 行尾需要有分号
semi: true,
// 使用单引号
singleQuote: true,
// 对象的 key 仅在必要时用引号
quoteProps: 'as-needed',
// jsx 不使用单引号,而使用双引号
jsxSingleQuote: false,
// 末尾需要有逗号
trailingComma: 'all',
// 大括号内的首尾需要空格
bracketSpacing: true,
// jsx 标签的反尖括号需要换行
jsxBracketSameLine: false,
// 箭头函数,只有一个参数的时候,也需要括号
arrowParens: 'always',
// 每个文件格式化的范围是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 不需要写文件开头的 @prettier
requirePragma: false,
// 不需要自动在文件开头插入 @prettier
insertPragma: false,
// 使用默认的折行标准
proseWrap: 'preserve',
// 根据显示样式决定 html 要不要折行
htmlWhitespaceSensitivity: 'css',
// vue 文件中的 script 和 style 内不用缩进
vueIndentScriptAndStyle: false,
// 换行符使用 lf
endOfLine: 'lf',
};

@ -0,0 +1,8 @@
# .stylelintignore
# 旧的不需打包的样式库
*.min.css
# 其他类型文件
*.js
*.jpg
*.woff

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,33 @@
# SamWafWeb
## QuickStart
1.
```
npm install
```
2.
```
npm run dev
```
3.
```
npm run build
```
# License
SamWaf is licensed under the Apache License 2.0. Refer to [LICENSE](./LICENSE) for more details.
For third-party software usage notice:
TDesign (https://github.com/Tencent/tdesign-vue-starter).
# Contribution
Thanks for the following contributors!
<a href="https://github.com/samwafgo/SamWafWeb/graphs/contributors">
<img src="https://contrib.rocks/image?repo=samwafgo/SamWafWeb" />
</a>

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 打包Web工程生成dist文件。
echo.
%~d0
cd %~dp0
cd ..
npm run build
pause

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 安装Web工程生成node_modules文件。
echo.
%~d0
cd %~dp0
cd ..
npm install --registry=https://registry.npmmirror.com
pause

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 使用 Vue CLI 命令运行 Web 工程。
echo.
%~d0
cd %~dp0
cd ..
npm run dev
pause

@ -0,0 +1,15 @@
# 选择一个 Base 镜像
FROM node:12
# 设置工作目录
WORKDIR /space
# 将 by 中的文件列表 COPY 过来
COPY . .
# 根据 COPY 过来的文件进行依赖的安装
RUN npm i
# 设置好需要的环境变量
ENV NODE_PATH=/space/node_modules

@ -0,0 +1 @@
module.exports = { extends: ['@commitlint/config-conventional'] };

@ -0,0 +1,20 @@
server {
if ($request_method = HEAD) {
return 200;
}
location / {
alias /usr/share/nginx/html/;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log error;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

13
globals.d.ts vendored

@ -0,0 +1,13 @@
// 通用声明
declare type ClassName = { [className: string]: any } | ClassName[] | string;
declare interface ImportMeta {
env: {
MODE: 'mock' | 'development' | 'test' | 'release';
};
}
declare module '*.svg' {
const content: string;
export default content;
}

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
<script>
window.global = window;
</script>
</html>

13
jsx.d.ts vendored

@ -0,0 +1,13 @@
import Vue, { VNode } from 'vue';
declare global {
namespace JSX {
type Element = VNode;
type ElementClass = Vue;
interface IntrinsicElements {
[elem: string]: any;
}
type IntrinsicAttributes = any;
}
}

@ -0,0 +1,147 @@
import { MockMethod } from 'vite-plugin-mock';
import Mock from 'mockjs';
export default [
{
url: '/api/get-purchase-list',
method: 'get',
response: () => ({
code: 0,
data: {
...Mock.mock({
'list|1-100': [
{
index: /S20201228115950[0-9][0-9][0-9]/,
pdName: 'Macbook',
pdNum: 'p_tmp_60a637cd0d',
'purchaseNum|1-100': 100,
adminName: '财务部111',
updateTime: '2020-05-20@date("HH:mm:ss")',
pdType: '电子产品',
},
{
index: /S20201228115950[0-9][0-9][0-9]/,
pdName: 'Macbook',
pdNum: 'p_tmp_60a637cd0d',
'purchaseNum|1-100': 100,
adminName: '财务部',
updateTime: '2020-05-20@date("HH:mm:ss")',
},
],
}),
},
}),
},
{
url: '/api/get-list',
method: 'get',
response: () => ({
code: 0,
data: {
...Mock.mock({
'list|1-100': [
{
'index|+1': 1,
'status|1': '@natural(0, 4)',
no: 'BH00@natural(01, 100)',
name: '@city()办公用品采购项目',
'paymentType|1': '@natural(0, 1)',
'contractType|1': '@natural(0, 2)',
updateTime: '2020-05-30 @date("HH:mm:ss")',
amount: '@natural(10, 500),000,000',
adminName: '@cname()',
},
],
}),
},
}),
},
{
url: '/api/detail-basic',
method: 'get',
response: () => ({
code: 0,
data: {
...Mock.mock({
name: 'td_20023747',
loginType: 'Web',
currentRole: 'Admin',
rightsList: '通用权限',
userStatus: '启用',
language: '简体中文',
timeZone: '(GMT+08:00)中国时区—北京Asia/Beijing',
}),
},
}),
},
{
url: '/api/get-card-list',
method: 'get',
response: () => ({
code: 0,
data: {
...Mock.mock({
'list|48-50': [
{
'index|+1': 1,
isSetup: '@boolean',
'type|1': '@natural(1, 5)',
'banner|1': [
'https://tdesign.gtimg.com/starter/cloud-db.jpg',
'https://tdesign.gtimg.com/starter/cloud-server.jpg',
'https://tdesign.gtimg.com/starter/ssl.jpg',
'https://tdesign.gtimg.com/starter/t-sec.jpg',
'https://tdesign.gtimg.com/starter/face-recognition.jpg',
],
'name|1': ['人脸识别', 'SSL证书', 'CVM', '云数据库', 'T-Sec 云防火墙'],
'description|1': [
'基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸',
'云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗',
'SSL证书又叫服务器证书腾讯云为您提供证书的一站式服务包括免费、付费证书的申请、管理及部',
'腾讯安全云防火墙产品是腾讯云安全团队结合云原生的优势自主研发的SaaS化防火墙产品无需客无需客无需客无需客无需客无需客无需客',
'云数据库MySQL为用户提供安全可靠性能卓越、易于维护的企业级云数据库服务。',
],
},
],
}),
},
}),
},
{
url: '/api/get-project-list',
method: 'get',
response: () => ({
code: 0,
data: {
...Mock.mock({
'list|1-50': [
{
'index|+1': 1,
adminPhone: '+86 13587609955',
updateTime: '2020-05-30 @date("HH:mm:ss")',
'adminName|1': ['顾娟 ', '常刚', '郑洋'],
'name|1': [
'沧州市办公用品采购项目',
'红河哈尼族彝族自治州办公用品采购项目 ',
'铜川市办公用品采购项目',
'陇南市办公用品采购项目 ',
'六安市办公用品采购项目 ',
],
},
],
}),
},
}),
},
{
url: '/api/post',
method: 'post',
timeout: 2000,
response: {
code: 0,
data: {
name: 'vben',
},
},
},
] as MockMethod[];

17443
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,100 @@
{
"name": "localwaf",
"version": "1.3.64",
"scripts": {
"dev:mock": "vite --open --mode mock",
"dev": "vite --open --mode development",
"dev:linux": "vite --mode development",
"build:test": "vite build --mode test",
"build": "vite build --mode release",
"site:preview": "npm run build && cp -r dist _site",
"preview": "vite preview",
"lint": "eslint --ext .vue,.js,.jsx,.ts,.tsx ./ --max-warnings 0",
"lint:fix": "eslint --ext .vue,.js,jsx,.ts,.tsx ./ --max-warnings 0 --fix",
"stylelint": "stylelint src/**/*.{html,vue,sass,less}",
"stylelint:fix": "stylelint --cache --fix src/**/*.{html,vue,vss,sass,less}",
"prepare": "node -e \"if(require('fs').existsSync('.git')){process.exit(1)}\" || is-ci || husky install",
"test": "echo \"no test specified,work in process\"",
"test:coverage": "echo \"no test:coverage specified,work in process\""
},
"dependencies": {
"@microsoft/fetch-event-source": "^2.0.1",
"axios": "^0.27.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.10.8",
"dompurify": "^3.2.4",
"echarts": "~5.1.2",
"echarts-wordcloud": "^2.0.0",
"marked": "^15.0.7",
"nprogress": "^0.2.0",
"qrcode.vue": "^1.7.0",
"tdesign-icons-vue": "^0.2.5",
"tdesign-vue": "^1.10.5",
"tvision-color": "~1.6.0",
"typescript": "^4.2.4",
"uuid": "^9.0.0",
"vue": "~2.6.14",
"vue-baidu-map": "^0.21.22",
"vue-clipboard2": "^0.3.1",
"vue-codemirror": "^4.0.6",
"vue-i18n": "^8.28.2",
"vue-meta": "^2.4.0",
"vue-router": "^3.5.1",
"vuex": "^3.6.2",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
"@commitlint/cli": "^17.0.3",
"@commitlint/config-conventional": "^17.1.0",
"@types/vue-color": "^2.4.3",
"@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0",
"commitizen": "^4.2.3",
"eslint": "^7.22.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-vue": "^7.8.0",
"husky": "^8.0.1",
"less": "^4.1.0",
"lint-staged": "^13.0.3",
"mockjs": "^1.1.0",
"prettier": "^2.6.0",
"stylelint": "~13.13.1",
"stylelint-config-prettier": "~9.0.3",
"stylelint-less": "1.0.5",
"stylelint-order": "~4.1.0",
"vite": "^2.7.10",
"vite-plugin-mock": "^2.3.0",
"vite-plugin-require-transform": "^1.0.4",
"vite-plugin-theme": "^0.8.1",
"vite-plugin-vue2": "^2.0.1",
"vite-plugin-vue2-svg": "~0.3.0",
"vue-template-compiler": "~2.6.14"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"prepare-commit-msg": "exec < /dev/tty && git cz --hook || true",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"prettier --write",
"npm run lint:fix",
"git add ."
],
"*.{html,vue,vss,sass,less}": [
"npm run stylelint:fix",
"git add ."
]
},
"description": "localwaf"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,2 @@
User-agent:*
Disallow:/

5
shims-vue.d.ts vendored

@ -0,0 +1,5 @@
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}

@ -0,0 +1,148 @@
<template>
<router-view :class="[mode]" />
</template>
<script>
import Vue from 'vue';
import config from '@/config/style';
import websocket from "@/utils/websocket.js";
import { DialogPlugin } from 'tdesign-vue';
import {AesDecrypt} from './utils/usuallytool'
const env = import.meta.env.MODE || 'development';
export default Vue.extend({
computed: {
mode() {
return this.$store.getters['setting/mode'];
},
},
data() {
return {
ws: null, // ws
disConnectTimer: null, //
mydialog: null,
}
},
mounted() {
this.$store.dispatch('setting/changeTheme', { ...config });
},
created() {
this.initWebSocket();
},
methods:{
initWebSocket() {
console.log("log",window.location.host)
if(!this.ws) {
// url
let url = env=="development"? "ws://127.0.0.1:26666/samwaf/ws" : "ws://"+window.location.host+"/samwaf/ws"
this.ws = websocket.useWebSocket(
url, // url
localStorage.getItem("access_token"),
this.wsOnOpen, //
this.wsOnMessage, //
this.wsOnClose, //
this.wsOnError, //
[], //
null, //
true, //
);
}
},
wsOnOpen() {
console.log('开始连接')
},
wsOnError(e) {
console.log(e,'消息通知错误回调,重新连接')
this.ws.close();
this.ws = null;
this.initWebSocket();
},
wsOnMessage(e) {
let wsData = JSON.parse(e.data)
if(wsData.msg_code=="200"){
console.log('接口返回信息',wsData)
let msgDataEnstr =wsData.msg_data
console.log('msgDataEnstr',msgDataEnstr)
let tmpSrcContent = AesDecrypt(msgDataEnstr)
console.log('tmpSrcContent',tmpSrcContent)
let msgData = JSON.parse(tmpSrcContent)
console.log('msgData',msgData)
wsData.msg_data = msgData
if(wsData.msg_cmd_type=="RELOAD_PAGE"){
if(this.mydialog){
this.mydialog.hide()
this.mydialog =null
}
this.mydialog = this.$dialog({
header: wsData.msg_data.message_type,
body: wsData.msg_data.message_data,
className: 't-dialog-new-class1 t-dialog-new-class2',
style: 'color: rgba(0, 0, 0, 0.6)',
confirmBtn:'确认并刷新',
onConfirm: ({ e }) => {
window.location.reload()
this.mydialog.hide();
},
});
return
}else if(wsData.msg_cmd_type=="DOWNLOAD_LOG"){
let token =localStorage.getItem("access_token")? localStorage.getItem("access_token"):""
//
let downloadUrl = env=="development"? "http://127.0.0.1:26666/samwaf/waflog/attack/download" : "http://"+window.location.host+"/samwaf/waflog/attack/download"
downloadUrl = downloadUrl +"?X-Token="+token
console.log(downloadUrl)
window.open(downloadUrl)
}
this.$store.commit('notification/addMsgData', wsData.msg_data);
}else if(wsData.msg_code=="-999"){
Object.keys(localStorage).forEach(key => {
if (key !== "lang") {
localStorage.removeItem(key);
}
});
console.log("鉴权失败")
}
},
wsOnClose() {
console.log('关闭')
//
if(!this.disConnectTimer) {
//this.ws.close();
this.ws = null;
this.disConnectTimer = setTimeout(() => {
this.initWebSocket()
this.disConnectTimer = null
}, 10000)
}
}
}
});
/*
var ws = new WebSocket("ws://127.0.0.1:26666/samwaf/ws",[localStorage.getItem("access_token")]);
//
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("ping");
};
//
ws.onmessage = function(evt) {
console.log("Received Message: " + evt.data);
};
//
ws.onclose = function(evt) {
console.log("Connection closed.");
}; */
</script>
<style>
.tdesign-starter-side-nav-logo-tdesign-logo{
padding: 0 0px;
}
</style>

@ -0,0 +1,27 @@
import request from '@/utils/request'
//查询所有账号列表
export function account_list_api(data) {
return request({
url: 'account/list',
method: 'post',
data: data
})
}
//查询所有账号操作日志列表
export function account_log_list_api(params) {
return request({
url: 'account_log/list',
method: 'get',
params: params
})
}
// 重置2Fa
export function account_reset_2fa_api(data) {
return request({
url: 'account/resetotp',
method: 'post',
data: data
})
}

@ -0,0 +1,65 @@
import request from '@/utils/request'
//查看抵御CC攻击列表
export function wafAntiCCListApi(params) {
return request({
url: '/wafhost/anticc/list',
method: 'post',
data: params
})
}
//删除抵御CC攻击
export function wafAntiCCDelApi(params) {
return request({
url: '/wafhost/anticc/del',
method: 'get',
params: params
})
}
//编辑抵御CC攻击
export function wafAntiCCEditApi(params) {
return request({
url: '/wafhost/anticc/edit',
method: 'post',
data: params
})
}
//添加抵御CC攻击
export function wafAntiCCAddApi(params) {
return request({
url: '/wafhost/anticc/add',
method: 'post',
data: params
})
}
//详细抵御CC攻击
export function wafAntiCCDetailApi(params) {
return request({
url: '/wafhost/anticc/detail',
method: 'get',
params: params
})
}
/**
* ip
* @param params
*/
export function wafAntiCCBanIPListApi(params) {
return request({
url: '/wafhost/anticc/baniplist',
method: 'get',
params: params
})
}
/**
* ip
* @param params
*/
export function wafAntiCCRemoveBanIpApi(params) {
return request({
url: '/wafhost/anticc/removebanip',
method: 'post',
data: params
})
}

@ -0,0 +1,55 @@
import request from '@/utils/request'
// 批量任务配置-列表
export function batchTaskListApi(params) {
return request({
url: '/batch_task/list',
method: 'post',
data: params
})
}
// 批量任务配置 - 删除
export function batchTaskDelApi(params) {
return request({
url: '/batch_task/del',
method: 'get',
params: params
})
}
// 批量任务配置 - 编辑
export function batchTaskEditApi(params) {
return request({
url: '/batch_task/edit',
method: 'post',
data: params
})
}
// 批量任务配置 - 添加
export function batchTaskAddApi(params) {
return request({
url: '/batch_task/add',
method: 'post',
data: params
})
}
// 批量任务配置 - 详情
export function batchTaskDetailApi(params) {
return request({
url: '/batch_task/detail',
method: 'get',
params: params
})
}
// 批量任务配置 - 手工触发
export function batchTaskManualApi(params) {
return request({
url: '/batch_task/manual',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//列表
export function wafBlockingPageListApi(params) {
return request({
url: '/wafhost/blockingpage/list',
method: 'post',
data: params
})
}
//删除
export function wafBlockingPageDelApi(params) {
return request({
url: '/wafhost/blockingpage/del',
method: 'get',
params: params
})
}
//编辑
export function wafBlockingPageEditApi(params) {
return request({
url: '/wafhost/blockingpage/edit',
method: 'post',
data: params
})
}
//添加
export function wafBlockingPageAddApi(params) {
return request({
url: '/wafhost/blockingpage/add',
method: 'post',
data: params
})
}
//详细
export function wafBlockingPageDetailApi(params) {
return request({
url: '/wafhost/blockingpage/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,17 @@
import request from '@/utils/request'
//查看控制中心列表
export function centerListApi(params) {
return request({
url: '/center/list',
method: 'post',
data: params
})
}
//详细控制中心详情
export function centerDetailApi(params) {
return request({
url: '/center/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,13 @@
import request from '@/utils/request'
//导出excel文件
export function export_api(params) {
return request({
url: 'export',
method: 'get',
responseType: 'blob',
timeout: 20000,
params: params
})
}

@ -0,0 +1,88 @@
import request from '@/utils/request'
//查询所有主机列表
export function allhost(params) {
return request({
url: 'wafhost/host/allhost',
method: 'get',
params: params
})
}
//通过主机Code查询所有主机域名信息
export function alldomainbyhostcode(params) {
return request({
url: 'wafhost/host/alldomainbyhostcode',
method: 'get',
params: params
})
}
//查询主机列表
export function hostlist(data) {
return request({
url: 'wafhost/host/list',
method: 'post',
data: data
})
}
//更改防护状态
export function changeGuardStatus(params) {
return request({
url: 'wafhost/host/guardstatus',
method: 'get',
params: params
})
}
//更改启动状态
export function changeStartStatus(params) {
return request({
url: 'wafhost/host/startstatus',
method: 'get',
params: params
})
}
//加载详情
export function getHostDetail(params) {
return request({
url: 'wafhost/host/detail',
method: 'get',
params: params
})
}
//删除主机
export function delHost(params) {
return request({
url: 'wafhost/host/del',
method: 'get',
params: params
})
}
//添加主机
export function addHost(data) {
return request({
url: 'wafhost/host/add',
method: 'post',
data: data
})
}
//编辑主机
export function editHost(data) {
return request({
url: 'wafhost/host/edit',
method: 'post',
data: data
})
}
//修改所有主机的防护状态
export function modifyAllGuardStatus(data) {
return request({
url: 'wafhost/host/modfiyallstatus',
method: 'post',
data: data
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//列表
export function wafHttpAuthBaseListApi(params) {
return request({
url: '/wafhost/httpauthbase/list',
method: 'post',
data: params
})
}
//删除
export function wafHttpAuthBaseDelApi(params) {
return request({
url: '/wafhost/httpauthbase/del',
method: 'get',
params: params
})
}
//编辑
export function wafHttpAuthBaseEditApi(params) {
return request({
url: '/wafhost/httpauthbase/edit',
method: 'post',
data: params
})
}
//添加
export function wafHttpAuthBaseAddApi(params) {
return request({
url: '/wafhost/httpauthbase/add',
method: 'post',
data: params
})
}
//详细
export function wafHttpAuthBaseDetailApi(params) {
return request({
url: '/wafhost/httpauthbase/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//查看IP白名单列表
export function wafIPBlockListApi(params) {
return request({
url: '/wafhost/ipblock/list',
method: 'post',
data: params
})
}
//删除IP黑名单
export function wafIPBlockDelApi(params) {
return request({
url: '/wafhost/ipblock/del',
method: 'get',
params: params
})
}
//编辑IP黑名单
export function wafIPBlockEditApi(params) {
return request({
url: '/wafhost/ipblock/edit',
method: 'post',
data: params
})
}
//添加IP黑名单
export function wafIPBlockAddApi(params) {
return request({
url: '/wafhost/ipblock/add',
method: 'post',
data: params
})
}
//详细IP黑名单
export function wafIPBlockDetailApi(params) {
return request({
url: '/wafhost/ipblock/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//查看IP白名单列表
export function wafIPWhiteListApi(params) {
return request({
url: '/wafhost/ipwhite/list',
method: 'post',
data: params
})
}
//删除IP白名单
export function wafIPWhiteDelApi(params) {
return request({
url: '/wafhost/ipwhite/del',
method: 'get',
params: params
})
}
//编辑IP白名单
export function wafIPWhiteEditApi(params) {
return request({
url: '/wafhost/ipwhite/edit',
method: 'post',
data: params
})
}
//添加IP白名单
export function wafIPWhiteAddApi(params) {
return request({
url: '/wafhost/ipwhite/add',
method: 'post',
data: params
})
}
//详细IP白名单
export function wafIPWhiteDetailApi(params) {
return request({
url: '/wafhost/ipwhite/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//查看隐私保护URL列表
export function wafLdpURLListApi(params) {
return request({
url: '/wafhost/ldpurl/list',
method: 'post',
data: params
})
}
//删除隐私保护URL
export function wafLdpURLDelApi(params) {
return request({
url: '/wafhost/ldpurl/del',
method: 'get',
params: params
})
}
//编辑隐私保护URL
export function wafLdpURLEditApi(params) {
return request({
url: '/wafhost/ldpurl/edit',
method: 'post',
data: params
})
}
//添加隐私保护URL
export function wafLdpURLAddApi(params) {
return request({
url: '/wafhost/ldpurl/add',
method: 'post',
data: params
})
}
//详细隐私保护URL
export function wafLdpURLDetailApi(params) {
return request({
url: '/wafhost/ldpurl/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,22 @@
import request from '@/utils/request'
/**
*
*/
//获取授权详情
export function getLicenseDetailApi(params) {
return request({
url: '/license/detail',
method: 'get',
params: params
})
}
//确认刚刚输入的文件
export function confirmLicenseApi(params) {
return request({
url: '/license/confirm',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//查看负载列表
export function wafLoadBalanceListApi(params) {
return request({
url: '/wafhost/loadbalance/list',
method: 'post',
data: params
})
}
//删除负载
export function wafLoadBalanceDelApi(params) {
return request({
url: '/wafhost/loadbalance/del',
method: 'get',
params: params
})
}
//编辑负载
export function wafLoadBalanceEditApi(params) {
return request({
url: '/wafhost/loadbalance/edit',
method: 'post',
data: params
})
}
//添加负载
export function wafLoadBalanceAddApi(params) {
return request({
url: '/wafhost/loadbalance/add',
method: 'post',
data: params
})
}
//详细负载
export function wafLoadBalanceDetailApi(params) {
return request({
url: '/wafhost/loadbalance/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,18 @@
import request from '@/utils/request'
//登录
export function loginapi(params) {
return request({
url: 'public/login',
method: 'post',
data: params
})
}
//注销
export function logoutapi(params) {
return request({
url: 'logout',
method: 'post',
data: params
})
}

@ -0,0 +1,33 @@
import request from '@/utils/request'
//查看一键修改记录列表
export function wafOneKeyModListApi(params) {
return request({
url: '/wafhost/onekeymod/list',
method: 'post',
data: params
})
}
//删除一键修改记录
export function wafOneKeyModDelApi(params) {
return request({
url: '/wafhost/onekeymod/del',
method: 'get',
params: params
})
}
//详细一键修改记录
export function wafOneKeyModDetailApi(params) {
return request({
url: '/wafhost/onekeymod/detail',
method: 'get',
params: params
})
}
//触发一键修改
export function wafDoOneKeyModApi(params) {
return request({
url: '/wafhost/onekeymod/doModify',
method: 'post',
data: params
})
}

@ -0,0 +1,27 @@
import request from '@/utils/request'
//初始化
export function wafOtpInitApi(params) {
return request({
url: '/wafhost/otp/init',
method: 'get',
params: params
})
}
// 绑定OTP
export function wafOtpBindApi(params) {
return request({
url: '/wafhost/otp/bind',
method: 'post',
data: params
})
}
//解绑OTP
export function wafOtpUnBindApi(params) {
return request({
url: '/wafhost/otp/unbind',
method: 'post',
data: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//查看规则列表
export function wafRuleListApi(params) {
return request({
url: '/wafhost/rule/list',
method: 'post',
data: params
})
}
//删除规则
export function wafRuleDelApi(params) {
return request({
url: '/wafhost/rule/del',
method: 'get',
params: params
})
}
//编辑规则
export function wafRuleEditApi(params) {
return request({
url: '/wafhost/rule/edit',
method: 'post',
data: params
})
}
//添加规则
export function wafRuleAddApi(params) {
return request({
url: '/wafhost/rule/add',
method: 'post',
data: params
})
}
//详细规则
export function wafRuleDetailApi(params) {
return request({
url: '/wafhost/rule/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//Sensitive Manage
export function wafSensitiveListApi(params) {
return request({
url: '/wafhost/sensitive/list',
method: 'post',
data: params
})
}
//Delete Sensitive
export function wafSensitiveDelApi(params) {
return request({
url: '/wafhost/sensitive/del',
method: 'get',
params: params
})
}
//Edit Sensitive
export function wafSensitiveEditApi(params) {
return request({
url: '/wafhost/sensitive/edit',
method: 'post',
data: params
})
}
//Add Sensitive
export function wafSensitiveAddApi(params) {
return request({
url: '/wafhost/sensitive/add',
method: 'post',
data: params
})
}
//Detail Sensitive
export function wafSensitiveDetailApi(params) {
return request({
url: '/wafhost/sensitive/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,57 @@
import request from '@/utils/request'
//列表
export function wafSslExpireListApi(params) {
return request({
url: '/wafhost/sslexpire/list',
method: 'post',
data: params
})
}
//删除
export function wafSslExpireDelApi(params) {
return request({
url: '/wafhost/sslexpire/del',
method: 'get',
params: params
})
}
//编辑
export function wafSslExpireEditApi(params) {
return request({
url: '/wafhost/sslexpire/edit',
method: 'post',
data: params
})
}
//添加
export function wafSslExpireAddApi(params) {
return request({
url: '/wafhost/sslexpire/add',
method: 'post',
data: params
})
}
//详细
export function wafSslExpireDetailApi(params) {
return request({
url: '/wafhost/sslexpire/detail',
method: 'get',
params: params
})
}
//发起检测
export function wafSslExpireNowCheckApi(params) {
return request({
url: '/wafhost/sslexpire/nowcheck',
method: 'get',
params: params
})
}
//同步已有域名
export function wafSslExpireSyncHostApi(params) {
return request({
url: '/wafhost/sslexpire/sync_host',
method: 'get',
params: params
})
}

@ -0,0 +1,46 @@
import request from '@/utils/request'
// SSL 配置管理 - 获取 SSL 配置列表
export function sslConfigListApi(params) {
return request({
url: '/sslconfig/list',
method: 'post',
data: params
})
}
// SSL 配置管理 - 删除 SSL 配置
export function sslConfigDelApi(params) {
return request({
url: '/sslconfig/del',
method: 'get',
params: params
})
}
// SSL 配置管理 - 编辑 SSL 配置
export function sslConfigEditApi(params) {
return request({
url: '/sslconfig/edit',
method: 'post',
data: params
})
}
// SSL 配置管理 - 添加 SSL 配置
export function sslConfigAddApi(params) {
return request({
url: '/sslconfig/add',
method: 'post',
data: params
})
}
// SSL 配置管理 - 获取 SSL 配置详情
export function sslConfigDetailApi(params) {
return request({
url: '/sslconfig/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,46 @@
import request from '@/utils/request'
// SSL 订单列表
export function sslOrderListApi(params) {
return request({
url: '/wafhost/sslorder/list',
method: 'post',
data: params
})
}
// SSL 订单 - 删除
export function sslOrderDelApi(params) {
return request({
url: '/wafhost/sslorder/del',
method: 'get',
params: params
})
}
// SSL 订单 - 编辑
export function sslOrderEditApi(params) {
return request({
url: '/wafhost/sslorder/edit',
method: 'post',
data: params
})
}
// SSL 订单 - 添加
export function sslOrderAddApi(params) {
return request({
url: '/wafhost/sslorder/add',
method: 'post',
data: params
})
}
// SSL 订单 - 获取详情
export function sslOrderDetailApi(params) {
return request({
url: '/wafhost/sslorder/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,51 @@
import request from '@/utils/request'
//查询顶部的汇总天信息
export function wafstatsumdayapi(params) {
return request({
url: 'wafstatsumday',
method: 'get',
params: params
})
}
//查询周期区间的攻击和正常信息
export function wafstatsumdayrangeapi(params) {
return request({
url: 'wafstatsumdayrange',
method: 'get',
params: params
})
}
//查询周期区间的IP攻击和正常信息
export function wafstatsumdaytopiprangeapi(params) {
return request({
url: 'wafstatsumdaytopiprange',
method: 'get',
params: params
})
}
//首页获取基本信息
export function wafStatSysinfoapi(params) {
return request({
url: 'statsysinfo',
method: 'get',
params: params
})
}
//首页获取运行基本信息
export function wafStatRuntimeSysinfoapi(params) {
return request({
url: 'statrumtimesysinfo',
method: 'get',
params: params
})
}
//【数据分析】查询周期区间国家级别攻击和正常信息
export function wafanalysisdaycountryrange(params) {
return request({
url: 'wafanalysisdaycountryrange',
method: 'get',
params: params
})
}

@ -0,0 +1,28 @@
import request from '@/utils/request'
//查询版本信息
export function SysVersionApi(params) {
return request({
url: 'sysinfo/version',
method: 'get',
params: params
})
}
//查询是否需要升级版本信息
export function CheckVersionApi(params) {
return request({
url: 'sysinfo/checkversion',
method: 'get',
params: params
})
}
//升级
export function DoUpdateApi(params) {
return request({
url: 'sysinfo/update',
method: 'get',
params: params
})
}

@ -0,0 +1,10 @@
import request from '@/utils/request'
//查询所有系统操作日志列表
export function sys_log_list_api(params) {
return request({
url: 'sys_log/list',
method: 'get',
params: params
})
}

@ -0,0 +1,9 @@
import request from '@/utils/request'
//查询所有系统配置列表
export function system_config_list_api(data) {
return request({
url: 'systemconfig/list',
method: 'post',
data: data
})
}

@ -0,0 +1,49 @@
import request from '@/utils/request'
//列表
export function wafTaskListApi(params) {
return request({
url: '/wafhost/task/list',
method: 'post',
data: params
})
}
//删除
export function wafTaskDelApi(params) {
return request({
url: '/wafhost/task/del',
method: 'get',
params: params
})
}
//编辑
export function wafTaskEditApi(params) {
return request({
url: '/wafhost/task/edit',
method: 'post',
data: params
})
}
//添加
export function wafTaskAddApi(params) {
return request({
url: '/wafhost/task/add',
method: 'post',
data: params
})
}
//详细
export function wafTaskDetailApi(params) {
return request({
url: '/wafhost/task/detail',
method: 'get',
params: params
})
}
//手工执行
export function wafTaskManualExecApi(params) {
return request({
url: '/wafhost/task/manual_exec',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//查看URL黑名单列表
export function wafURLBlockListApi(params) {
return request({
url: '/wafhost/urlblock/list',
method: 'post',
data: params
})
}
//删除URL黑名单
export function wafURLBlockDelApi(params) {
return request({
url: '/wafhost/urlblock/del',
method: 'get',
params: params
})
}
//编辑URL黑名单
export function wafURLBlockEditApi(params) {
return request({
url: '/wafhost/urlblock/edit',
method: 'post',
data: params
})
}
//添加URL黑名单
export function wafURLBlockAddApi(params) {
return request({
url: '/wafhost/urlblock/add',
method: 'post',
data: params
})
}
//详细URL黑名单
export function wafURLBlockDetailApi(params) {
return request({
url: '/wafhost/urlblock/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,41 @@
import request from '@/utils/request'
//查看URL白名单列表
export function wafURLWhiteListApi(params) {
return request({
url: '/wafhost/urlwhite/list',
method: 'post',
data: params
})
}
//删除URL白名单
export function wafURLWhiteDelApi(params) {
return request({
url: '/wafhost/urlwhite/del',
method: 'get',
params: params
})
}
//编辑URL白名单
export function wafURLWhiteEditApi(params) {
return request({
url: '/wafhost/urlwhite/edit',
method: 'post',
data: params
})
}
//添加URL白名单
export function wafURLWhiteAddApi(params) {
return request({
url: '/wafhost/urlwhite/add',
method: 'post',
data: params
})
}
//详细URL白名单
export function wafURLWhiteDetailApi(params) {
return request({
url: '/wafhost/urlwhite/detail',
method: 'get',
params: params
})
}

@ -0,0 +1,64 @@
import request from '@/utils/request'
//查询攻击日志列表
export function attacklogList(params) {
return request({
url: '/waflog/attacklog/list',
method: 'get',
params: params
})
}
//查询存档日志库列表
export function allsharedblist(params) {
return request({
url: 'waflog/attack/allsharedb',
method: 'get',
params: params
})
}
//导出json数据
export function exportlog(data) {
return request({
url: 'waflog/attack/export',
method: 'get',
})
}
//下载已经生成好的数据
export function downloadlog() {
return request({
url: 'waflog/attack/download',
method: 'get',
})
}
//查看日志详情
export function geWebLogDetail(params) {
return request({
url: 'waflog/attack/detail',
method: 'get',
params: params
})
}
// 复制脱敏后数据
export function getHeaderCopyDetail(params) {
return request({
url: 'waflog/attack/httpcopymask',
method: 'get',
params: params
})
}
// 危险ip列表
export function attackIpListApi(data) {
return request({
url: 'waflog/attack/attackiplist',
method: 'post',
data: data
})
}
//查询攻击iptag列表
export function allattacktaglist(params) {
return request({
url: 'waflog/attack/alliptag',
method: 'get',
params: params
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 KiB

@ -0,0 +1,17 @@
<svg width="188" height="26" xmlns="http://www.w3.org/2000/svg">
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<text stroke="null" transform="matrix(1.2871849536895752,0,0,1.2871849536895752,-3.0751162828919405,-8.653814704284287) " font-weight="bold" xml:space="preserve" text-anchor="start" font-family="Georgia, Times, 'Times New Roman', serif" font-size="24" id="svg_22" y="25.964596" x="22.266319" fill-opacity="null" stroke-opacity="null" stroke-width="0" fill="#000000">S</text>
<text stroke="null" transform="matrix(1.2411721719383566,0,0,1.2411721719383566,-8.635913129480075,-2.7951452434870627) " font-weight="bold" xml:space="preserve" text-anchor="start" font-family="Georgia, Times, 'Times New Roman', serif" font-size="24" id="svg_24" y="22.144262" x="45.739661" fill-opacity="null" stroke-opacity="null" stroke-width="0" fill="#000000">a</text>
<text stroke="null" transform="matrix(1.1481808746615183,0,0,1.1481808746615183,-10.730071457223458,-5.248758659216681) " font-weight="bold" xml:space="preserve" text-anchor="start" font-family="Georgia, Times, 'Times New Roman', serif" font-size="24" id="svg_25" y="26.124672" x="69.58158" fill-opacity="null" stroke-opacity="null" stroke-width="0" fill="#000000">m</text>
<text stroke="null" transform="matrix(1.1605311632156372,0,0,1.1605311632156372,-17.458730331852166,-5.1980439399667375) " font-weight="bold" xml:space="preserve" text-anchor="start" font-family="Georgia, Times, 'Times New Roman', serif" font-size="24" id="svg_26" y="26.495707" x="104.13242" stroke-opacity="null" stroke-width="0" fill="#3f7f00">W</text>
<text stroke="null" transform="matrix(1.1959863220075186,0,0,1.1959863220075186,-23.226857702338318,6.675934022609251) " font-weight="bold" xml:space="preserve" text-anchor="start" font-family="Georgia, Times, 'Times New Roman', serif" font-size="24" id="svg_27" y="15.399398" x="132.532516" stroke-opacity="null" stroke-width="0" fill="#3f7f00">A</text>
<text stroke="null" transform="matrix(1.1846589530291358,0,0,1.1846589530291358,-35.29946937381119,-6.692523365802941) " font-weight="bold" xml:space="preserve" text-anchor="start" font-family="Georgia, Times, 'Times New Roman', serif" font-size="24" id="svg_28" y="27.098539" x="165.439258" stroke-opacity="null" stroke-width="0" fill="#3f7f00">F</text>
<path id="svg_33" d="m10.667462,0.68552c2.499489,0 4.527217,1.885843 4.527217,4.2082c0,2.322358 -2.027728,4.206386 -4.527217,4.206386c-2.49949,0 -4.527218,1.885845 -4.527218,4.208201c0,2.322357 2.027728,4.206386 4.527218,4.206386c4.998977,0 9.056386,-3.769874 9.056386,-8.414587c0,-4.644714 -4.057408,-8.414586 -9.056386,-8.414586l0,0.000001zm0,2.893137c-0.781492,0 -1.415367,0.588951 -1.415367,1.315062c0,0.726112 0.633872,1.315062 1.415367,1.315062c0.781493,0 1.415365,-0.588951 1.415365,-1.315062c0,-0.726111 -0.633871,-1.315062 -1.415365,-1.315062zm0,8.414587c0.781089,0 1.415365,0.589325 1.415365,1.315062c0,0.725735 -0.634275,1.315063 -1.415365,1.315063c-0.78109,0 -1.415367,-0.589328 -1.415367,-1.315063c0,-0.725735 0.634276,-1.315062 1.415367,-1.315062zm8.853257,-2.887777c0,4.641263 -4.04946,8.40375 -9.044726,8.40375c-4.995264,0 -9.044726,-3.762487 -9.044726,-8.40375c0,-4.641265 4.049462,-8.403753 9.044726,-8.403753c4.995267,0 9.044726,3.762488 9.044726,8.403753z" fill-opacity="null" stroke-opacity="null" stroke-width="null" stroke="null" fill="#007f00"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -0,0 +1,5 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="49" height="49" rx="24.5" fill="#0052D9" stroke="none"/>
<path d="M23.9219 31H26.0859L22.0781 19.7266H19.8125L15.8125 31H17.8516L18.8203 28.1172H22.9688L23.9219 31ZM20.8359 21.875H20.9688L22.5 26.5234H19.2891L20.8359 21.875ZM30.6328 29.6172C29.7734 29.6172 29.1562 29.1875 29.1562 28.4688C29.1562 27.7734 29.6641 27.3828 30.75 27.3125L32.6797 27.1875V27.8672C32.6797 28.8594 31.8047 29.6172 30.6328 29.6172ZM30.0625 31.1406C31.1797 31.1406 32.1172 30.6562 32.5938 29.8281H32.7266V31H34.5938V25.1641C34.5938 23.3516 33.3594 22.2812 31.1641 22.2812C29.1328 22.2812 27.7188 23.2422 27.5625 24.75H29.3906C29.5703 24.1719 30.1797 23.8594 31.0703 23.8594C32.1172 23.8594 32.6797 24.3281 32.6797 25.1641V25.8828L30.4766 26.0156C28.3984 26.1406 27.2344 27.0312 27.2344 28.5781C27.2344 30.1406 28.4141 31.1406 30.0625 31.1406Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 979 B

@ -0,0 +1,5 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="49" height="49" rx="24.5" fill="#0594FA" stroke="none"/>
<path d="M20.6641 31C23.0703 31 24.5391 29.7734 24.5391 27.7969C24.5391 26.3281 23.4922 25.2344 21.9766 25.0938V24.9531C23.1094 24.7734 23.9844 23.7266 23.9844 22.5391C23.9844 20.8047 22.6953 19.7266 20.5547 19.7266H15.8438V31H20.6641ZM17.8594 21.3281H20.0625C21.2812 21.3281 21.9922 21.9062 21.9922 22.8984C21.9922 23.9141 21.2344 24.4688 19.8047 24.4688H17.8594V21.3281ZM17.8594 29.3984V25.9219H20.125C21.6641 25.9219 22.4766 26.5156 22.4766 27.6406C22.4766 28.7891 21.6875 29.3984 20.2031 29.3984H17.8594ZM31.2812 31.1406C33.4375 31.1406 34.7891 29.4453 34.7891 26.7266C34.7891 23.9922 33.4453 22.3125 31.2812 22.3125C30.1094 22.3125 29.125 22.8828 28.6797 23.8125H28.5469V19.1484H26.6094V31H28.4766V29.6484H28.6094C29.0938 30.5859 30.0859 31.1406 31.2812 31.1406ZM30.6719 23.9609C31.9922 23.9609 32.7969 25.0078 32.7969 26.7266C32.7969 28.4453 32 29.4922 30.6719 29.4922C29.3438 29.4922 28.5156 28.4297 28.5156 26.7266C28.5156 25.0234 29.3516 23.9609 30.6719 23.9609Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,5 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="49" height="49" rx="24.5" fill="#7587DB" stroke="none"/>
<path d="M21.1172 31.2812C23.7188 31.2812 25.625 29.7266 25.8906 27.4219H23.9062C23.6328 28.6875 22.5469 29.4844 21.1172 29.4844C19.1953 29.4844 18 27.9062 18 25.3594C18 22.8203 19.1953 21.2422 21.1094 21.2422C22.5312 21.2422 23.6172 22.1172 23.8984 23.4688H25.8828C25.6484 21.1172 23.6719 19.4453 21.1094 19.4453C17.9141 19.4453 15.9375 21.7031 15.9375 25.3672C15.9375 29.0156 17.9219 31.2812 21.1172 31.2812ZM35.3125 25.3281C35.1094 23.5312 33.7812 22.2812 31.5859 22.2812C29.0156 22.2812 27.5078 23.9297 27.5078 26.7031C27.5078 29.5156 29.0234 31.1719 31.5938 31.1719C33.7578 31.1719 35.1016 29.9688 35.3125 28.1797H33.4688C33.2656 29.0703 32.5938 29.5469 31.5859 29.5469C30.2656 29.5469 29.4688 28.5 29.4688 26.7031C29.4688 24.9297 30.2578 23.9062 31.5859 23.9062C32.6484 23.9062 33.2891 24.5 33.4688 25.3281H35.3125Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,5 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="49" height="49" rx="24.5" fill="#00A870" stroke="none"/>
<path d="M15.875 19.7266V31H20.1016C23.4766 31 25.4062 28.9297 25.4062 25.3125C25.4062 21.7734 23.4531 19.7266 20.1016 19.7266H15.875ZM17.8906 21.4688H19.8359C22.0469 21.4688 23.3516 22.8828 23.3516 25.3438C23.3516 27.8594 22.0781 29.2578 19.8359 29.2578H17.8906V21.4688ZM30.5938 31.1406C31.7812 31.1406 32.7656 30.5859 33.25 29.6484H33.3828V31H35.2578V19.1484H33.3203V23.8125H33.1875C32.7344 22.875 31.7656 22.3125 30.5938 22.3125C28.4375 22.3125 27.0781 24.0156 27.0781 26.7188C27.0781 29.4375 28.4297 31.1406 30.5938 31.1406ZM31.1953 23.9609C32.5234 23.9609 33.3438 25.0234 33.3438 26.7266C33.3438 28.4453 32.5312 29.4922 31.1953 29.4922C29.8672 29.4922 29.0625 28.4531 29.0625 26.7266C29.0625 25.0078 29.875 23.9609 31.1953 23.9609Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 958 B

@ -0,0 +1,32 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<g mask="url(#mask0_17_619)">
<path d="M30 62H118V122H30V62Z" fill="#97A3B7" />
<g filter="url(#filter0_f_17_619)">
<rect x="12" y="84" width="80" height="60" fill="#E3E6EB" />
</g>
<g filter="url(#filter1_f_17_619)">
<rect x="80" y="54" width="80" height="60" fill="#E3E6EB" />
</g>
<rect x="46" y="105" width="32" height="2" fill="white" />
<rect x="46" y="98" width="32" height="2" fill="white" />
<rect x="46" y="88" width="16" height="2" fill="white" />
</g>
<path opacity="0.9" d="M63 20H151V30H63V20Z" fill="currentcolor" />
<mask id="mask1_17_619" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="63" y="30" width="88" height="50">
<path d="M63 30H151V80H63V30Z" fill="currentcolor" />
</mask>
<g mask="url(#mask1_17_619)">
<path d="M63 30H151V80H63V30Z" fill="currentcolor" />
<g opacity="0.3" filter="url(#filter2_f_17_619)">
<path d="M30 62H118V122H30V62Z" fill="#97A3B7" />
</g>
</g>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M95.6863 40.8577L105.964 51.1345C106.295 51.0466 106.642 50.9998 107 50.9998C109.213 50.9998 111 52.7865 111 54.9998C111 55.3574 110.953 55.7038 110.866 56.0333L121.142 66.3135L118.314 69.1419L113.716 64.5448C111.653 65.423 109.384 65.9089 107 65.9089C99.7273 65.9089 93.5164 61.3853 91 54.9998C92.1785 52.0093 94.1673 49.4271 96.6961 47.5268L92.8579 43.6861L95.6863 40.8577ZM99 54.9998C99 59.4158 102.584 62.9998 107 62.9998C108.483 62.9998 109.872 62.5957 111.063 61.8917L108.034 58.8657C107.704 58.9532 107.358 58.9998 107 58.9998C104.787 58.9998 103 57.2131 103 54.9998C103 54.6423 103.047 54.2958 103.134 53.9663L100.107 50.9389C99.4037 52.1295 99 53.5178 99 54.9998ZM107 44.0907C114.273 44.0907 120.484 48.6143 123 54.9998C122.071 57.3574 120.638 59.4612 118.834 61.1773L114.729 57.0717C114.906 56.4108 115 55.7162 115 54.9998C115 50.5838 111.416 46.9998 107 46.9998C106.284 46.9998 105.589 47.0941 104.928 47.2711L102.378 44.7205C103.848 44.3101 105.398 44.0907 107 44.0907Z"
fill="white" />
<rect x="68" y="24" width="2" height="2" fill="white" />
<rect x="74" y="24" width="2" height="2" fill="white" />
<rect x="80" y="24" width="66" height="2" fill="white" />
<path d="M157 53.9998L181.249 95.9998H132.751L157 53.9998Z" fill="white" stroke="black" />
<path d="M157 88.9998L157 70.9998" stroke="black" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -0,0 +1,36 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<g mask="url(#mask0_16559_24301)">
<path d="M30 62H118V122H30V62Z" fill="#97A3B7" />
<g filter="url(#filter0_f_16559_24301)">
<rect x="12" y="84" width="80" height="60" fill="#E3E6EB" />
</g>
<g filter="url(#filter1_f_16559_24301)">
<rect x="80" y="54" width="80" height="60" fill="#E3E6EB" />
</g>
<path d="M49 93L42 100L49 107" stroke="white" stroke-width="2" />
<path d="M69 107L76 100L69 93" stroke="white" stroke-width="2" />
<path d="M62.3647 87.4431L55.6355 112.557" stroke="white" stroke-width="2" />
</g>
<path opacity="0.9" d="M63 20H151V30H63V20Z" fill="currentcolor" />
<mask id="mask1_16559_24301" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="63" y="30" width="88" height="50">
<path d="M63 30H151V80H63V30Z" fill="currentcolor" />
</mask>
<g mask="url(#mask1_16559_24301)">
<path d="M63 30H151V80H63V30Z" fill="currentcolor" />
<g opacity="0.3" filter="url(#filter2_f_16559_24301)">
<path d="M30 62H118V122H30V62Z" fill="#97A3B7" />
</g>
</g>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M105.25 41C112.015 41 117.5 46.4845 117.5 53.25C117.5 55.6827 116.791 57.9498 115.568 59.8558L121 65.2877L117.288 69L111.856 63.5681C109.95 64.7909 107.683 65.5 105.25 65.5C98.4845 65.5 93 60.0155 93 53.25C93 46.4845 98.4845 41 105.25 41ZM105.25 44.5C100.418 44.5 96.5 48.4175 96.5 53.25C96.5 58.0825 100.418 62 105.25 62C110.082 62 114 58.0825 114 53.25C114 48.4175 110.082 44.5 105.25 44.5Z"
fill="white" />
<rect x="68" y="24" width="2" height="2" fill="white" />
<rect x="74" y="24" width="2" height="2" fill="white" />
<rect x="80" y="24" width="66" height="2" fill="white" />
<path fill-rule="evenodd" clip-rule="evenodd"
d="M153 56C140.85 56 131 65.8497 131 78C131 82.6039 132.414 86.8776 134.832 90.4102L127 98.5L139.495 95.3681C143.222 98.2709 147.909 100 153 100C165.15 100 175 90.1503 175 78C175 65.8497 165.15 56 153 56Z"
fill="white" />
<path
d="M131 78L131.5 78V78L131 78ZM134.832 90.4102L135.191 90.758L135.475 90.4647L135.245 90.1278L134.832 90.4102ZM127 98.5L126.641 98.1522L125.422 99.411L127.122 98.985L127 98.5ZM139.495 95.3681L139.802 94.9736L139.61 94.8238L139.373 94.8831L139.495 95.3681ZM153 100L153 100.5L153 100.5L153 100ZM175 78L174.5 78L174.5 78L175 78ZM131.5 78C131.5 66.1259 141.126 56.5 153 56.5V55.5C140.574 55.5 130.5 65.5736 130.5 78L131.5 78ZM135.245 90.1278C132.882 86.6757 131.5 82.5 131.5 78H130.5C130.5 82.7079 131.946 87.0794 134.419 90.6926L135.245 90.1278ZM134.473 90.0624L126.641 98.1522L127.359 98.8478L135.191 90.758L134.473 90.0624ZM127.122 98.985L139.616 95.8531L139.373 94.8831L126.878 98.015L127.122 98.985ZM153 99.5C148.024 99.5 143.445 97.8105 139.802 94.9736L139.187 95.7626C143 98.7314 147.794 100.5 153 100.5V99.5ZM174.5 78C174.5 89.8741 164.874 99.5 153 99.5L153 100.5C165.426 100.5 175.5 90.4264 175.5 78L174.5 78ZM153 56.5C164.874 56.5 174.5 66.1259 174.5 78H175.5C175.5 65.5736 165.426 55.5 153 55.5V56.5Z"
fill="black" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -0,0 +1,32 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<g mask="url(#mask0_16559_24251)">
<path d="M68 48L106.105 70V114L68 136L29.8949 114V70L68 48Z" fill="#97A3B7" />
<g filter="url(#filter0_f_16559_24251)">
<rect x="46.3911" y="92" width="80" height="60" fill="#E3E6EB" />
</g>
<g filter="url(#filter1_f_16559_24251)">
<rect y="23" width="80" height="60" fill="#E3E6EB" />
</g>
</g>
<mask id="mask1_16559_24251" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="80" y="9" width="78" height="88">
<path d="M119 9L157.105 31V75L119 97L80.8949 75V31L119 9Z" fill="currentcolor" />
</mask>
<g mask="url(#mask1_16559_24251)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M80.895 31V75L119 97L157.105 75V31L119 53L80.895 31Z"
fill="currentcolor" />
<path opacity="0.9" d="M119 -35L157.105 -13L157.105 31.5L119 53.5L80.8952 31.5L80.895 -13L119 -35Z"
fill="currentcolor" />
<g opacity="0.3" filter="url(#filter2_f_16559_24251)">
<path d="M68 48L106.105 70V114L68 136L29.8949 114V70L68 48Z" fill="#97A3B7" />
</g>
</g>
<path
d="M143 68.822L147.867 85.875L148 86.3405L148.469 86.2228L165.671 81.911L153.336 94.6522L152.999 95L153.336 95.3478L165.671 108.089L148.469 103.777L148 103.659L147.867 104.125L143 121.178L138.133 104.125L138 103.659L137.531 103.777L120.329 108.089L132.664 95.3478L133.001 95L132.664 94.6522L120.329 81.911L137.531 86.2228L138 86.3405L138.133 85.875L143 68.822Z"
fill="white" stroke="black" />
<path fill-rule="evenodd" clip-rule="evenodd"
d="M123.243 35.0821L126.071 33.4493L123.243 31.8164L120.414 33.4493L123.243 35.0821ZM119 32.6329L121.828 31L114.757 26.9179L111.929 28.5507L119 32.6329ZM127.485 35.8986C122.806 38.6001 115.194 38.6001 110.515 35.8986C105.835 33.197 105.835 28.803 110.515 26.1014C115.194 23.3999 122.806 23.3999 127.485 26.1014C132.165 28.803 132.165 33.197 127.485 35.8986ZM107.686 24.4686C101.438 28.0756 101.438 33.9244 107.686 37.5314C113.934 41.1384 124.066 41.1384 130.314 37.5314C136.562 33.9244 136.562 28.0756 130.314 24.4686C124.066 20.8616 113.934 20.8616 107.686 24.4686Z"
fill="white" />
<path fill-rule="evenodd" clip-rule="evenodd"
d="M41.8989 86.2863L44.7272 87.9193L44.7275 94.4512L41.8992 92.8181L41.8989 86.2863ZM53.9194 93.2269L56.7477 94.86L56.7479 101.392L53.9196 99.7587L53.9194 93.2269ZM44.7281 107.515L41.8999 105.882L41.9 109.148L44.7283 110.781L44.7282 107.515L53.92 112.822L53.9201 116.088L56.7484 117.721L56.7483 114.455L53.9201 112.822L53.92 109.556L44.728 104.249L44.7281 107.515Z"
fill="white" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,33 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<g mask="url(#mask0_22_990)">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M144.569 105.61L96.5692 133.322L48.5693 105.61V83.7121L96.569 55.9995L144.569 83.7122V105.61Z"
fill="#97A3B7" />
<g filter="url(#filter0_f_22_990)">
<rect x="-3" y="33.9995" width="80" height="60" fill="#E3E6EB" />
</g>
<g filter="url(#filter1_f_22_990)">
<rect x="97" y="97.9995" width="80" height="60" fill="#E3E6EB" />
</g>
</g>
<mask id="mask1_22_990" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="53" y="16" width="86" height="69">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M113.357 42.715L129.829 33.2059C128.859 32.4995 127.789 31.823 126.643 31.1615C121.268 28.0584 114.723 26.0153 107.758 25.023C103.549 19.4606 97.5775 16.1248 90.4344 16.1945C83.6788 16.2821 74.9482 21.9412 68.9271 30.5602C68.096 30.975 67.2847 31.4099 66.4949 31.8659C52.1168 40.1664 49.5542 52.6155 59.0218 61.9309C57.9871 56.1259 58.712 51.0657 62.1231 45.7161C62.0653 46.3482 61.9127 50.143 61.8906 50.7834C61.2209 69.6969 76.9107 84.8409 88.03 84.7113C96.4806 84.6119 103.595 79.6976 108.349 72.0797C114.563 70.8487 120.438 68.786 125.443 65.8968C138.919 58.1167 142.01 46.7146 134.547 37.629L117.948 47.2113C119.71 50.8655 117.997 55.034 112.87 57.9936C107.744 60.9532 100.523 61.9424 94.1928 60.9252C91.3499 60.4563 88.6706 59.5834 86.4524 58.3029L86.4042 58.275L113.357 42.715ZM78.6546 53.7727C72.5285 49.7965 72.9717 43.5469 79.8498 39.5762C86.7276 35.6056 97.5532 35.3496 104.441 38.8864L78.6546 53.7727ZM93.5561 18.1703C98.1657 18.1302 102.284 20.5752 105.496 24.7401C97.0486 23.8219 88.1122 24.4143 79.9732 26.5054C83.672 21.3809 88.444 18.2301 93.5561 18.1703ZM91.3238 81.6169C85.471 81.685 80.3525 77.691 76.9473 71.2848C85.7921 73.6267 95.8719 74.0599 105.374 72.6022C101.618 78.1222 96.6601 81.5531 91.3238 81.6169Z"
fill="currentcolor" />
</mask>
<g mask="url(#mask1_22_990)">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M113.357 42.715L129.829 33.2059C128.859 32.4995 127.789 31.823 126.643 31.1615C121.268 28.0584 114.723 26.0153 107.758 25.023C103.549 19.4606 97.5775 16.1248 90.4344 16.1945C83.6788 16.2821 74.9482 21.9412 68.9271 30.5602C68.096 30.975 67.2847 31.4099 66.4949 31.8659C52.1168 40.1664 49.5542 52.6155 59.0218 61.9309C57.9871 56.1259 58.712 51.0657 62.1231 45.7161C62.0653 46.3482 61.9127 50.143 61.8906 50.7834C61.2209 69.6969 76.9107 84.8409 88.03 84.7113C96.4806 84.6119 103.595 79.6976 108.349 72.0797C114.563 70.8487 120.438 68.786 125.443 65.8968C138.919 58.1167 142.01 46.7146 134.547 37.629L117.948 47.2113C119.71 50.8655 117.997 55.034 112.87 57.9936C107.744 60.9532 100.523 61.9424 94.1928 60.9252C91.3499 60.4563 88.6706 59.5834 86.4524 58.3029L86.4042 58.275L113.357 42.715ZM78.6546 53.7727C72.5285 49.7965 72.9717 43.5469 79.8498 39.5762C86.7276 35.6056 97.5532 35.3496 104.441 38.8864L78.6546 53.7727ZM93.5561 18.1703C98.1657 18.1302 102.284 20.5752 105.496 24.7401C97.0486 23.8219 88.1122 24.4143 79.9732 26.5054C83.672 21.3809 88.444 18.2301 93.5561 18.1703ZM91.3238 81.6169C85.471 81.685 80.3525 77.691 76.9473 71.2848C85.7921 73.6267 95.8719 74.0599 105.374 72.6022C101.618 78.1222 96.6601 81.5531 91.3238 81.6169Z"
fill="currentcolor" />
<g opacity="0.3" filter="url(#filter2_f_22_990)">
<path d="M96.569 55.9995L144.569 83.7122V139.138L96.569 166.85L48.5692 139.138V83.7122L96.569 55.9995Z"
fill="#97A3B7" />
</g>
</g>
<ellipse cx="155" cy="78" rx="22" ry="22" transform="rotate(180 155 78)" fill="white" stroke="black" />
<path d="M155 83L155 65" stroke="black" />
<rect x="155" y="87" width="0.00390625" height="0.00390625" fill="#C4C4C4" stroke="black" stroke-width="2"
stroke-linejoin="round" />
<path d="M96.5693 112L96.5693 87.9995" stroke="white" stroke-width="2" />
<path d="M86.5693 97.9995L96.5693 87.9995L106.569 97.9995" stroke="white" stroke-width="2" />
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

@ -0,0 +1,49 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_216_313" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="80" y="9" width="78" height="88">
<path d="M119 9L157.105 31V75L119 97L80.8949 75V31L119 9Z" fill="currentColor"/>
</mask>
<g mask="url(#mask0_216_313)">
<path d="M119 9L157.105 31V75L119 97L80.8949 75V31L119 9Z" fill="currentColor"/>
<path opacity="0.9" d="M119 -35L157.105 -13V31L119 53L80.8949 31V-13L119 -35Z" fill="currentColor" />
<g opacity="0.3" filter="url(#filter0_f_216_313)">
<path d="M68 48L106.105 70V114L68 136L29.8949 114V70L68 48Z" fill="#97A3B7"/>
</g>
</g>
<mask id="mask1_216_313" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="29" y="48" width="78" height="88">
<path d="M68 48L106.105 70V114L68 136L29.8949 114V70L68 48Z" fill="#97A3B7"/>
</mask>
<g mask="url(#mask1_216_313)">
<path d="M68 48L106.105 70V114L68 136L29.8949 114V70L68 48Z" fill="#97A3B7"/>
<g filter="url(#filter1_f_216_313)">
<rect x="46.3906" y="92" width="80" height="60" fill="#E3E6EB"/>
</g>
<g filter="url(#filter2_f_216_313)">
<rect y="23" width="80" height="60" fill="#E3E6EB"/>
</g>
</g>
<path d="M41.8984 86.2866L44.7267 87.9197L44.727 94.4515L41.8987 92.8185L41.8984 86.2866Z" fill="white"/>
<path d="M53.9189 93.2273L56.7472 94.8603L56.7474 101.392L53.9191 99.7591L53.9189 93.2273Z" fill="white"/>
<path d="M44.7276 107.515L41.8994 105.882L41.8995 109.148L44.7278 110.781L44.7276 107.515L53.9195 112.823L53.9196 116.088L56.7479 117.721L56.7478 114.455L53.9195 112.823L53.9195 109.557L44.7275 104.249L44.7276 107.515Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M108.348 23.4792C106.188 25.9904 106.535 29.3829 109.395 31.5604C112.66 34.0461 117.963 34.007 121.24 31.4731C124.516 28.9392 124.526 24.8699 121.261 22.3841C118.401 20.2066 113.977 19.9666 110.721 21.6439L115.923 25.6047L113.55 27.4399L108.348 23.4792Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M120.865 33.0087L129.83 39.8346L132.203 37.9994L123.238 31.1735C122.917 31.521 122.554 31.8531 122.149 32.1657C121.745 32.4784 121.315 32.7594 120.865 33.0087ZM119.662 32.0932C120.123 31.8557 120.561 31.5798 120.967 31.2655C121.373 30.9513 121.73 30.6134 122.035 30.2579L122.035 30.2579C121.73 30.6134 121.373 30.9513 120.967 31.2655C120.561 31.5798 120.123 31.8557 119.662 32.0931L119.662 32.0932Z" fill="white"/>
<path d="M144 70L168.249 112H119.751L144 70Z" fill="white" stroke="#181818"/>
<path d="M144 100L144 82" stroke="#181818"/>
<path d="M144 105H144.004V105.004H144V105Z" stroke="#181818" stroke-width="2" stroke-linejoin="round"/>
<defs>
<filter id="filter0_f_216_313" x="23.8949" y="42" width="88.2102" height="100" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="3" result="effect1_foregroundBlur_216_313"/>
</filter>
<filter id="filter1_f_216_313" x="-3.60938" y="42" width="180" height="160" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="25" result="effect1_foregroundBlur_216_313"/>
</filter>
<filter id="filter2_f_216_313" x="-50" y="-27" width="180" height="160" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="25" result="effect1_foregroundBlur_216_313"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

@ -0,0 +1,23 @@
<svg width="200" height="140" viewBox="0 0 200 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<g mask="url(#mask0_21_716)">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M33 46.843L96.3214 119L159.643 46.843C142.742 31.9998 120.583 23 96.3214 23C72.0601 23 49.9009 31.9998 33 46.843Z"
fill="#97A3B7" />
<g filter="url(#filter0_f_21_716)">
<rect x="95" y="21" width="80" height="60" fill="#E3E6EB" />
</g>
<g filter="url(#filter1_f_21_716)">
<rect x="-7" y="43" width="80" height="60" fill="#E3E6EB" />
</g>
</g>
<path
d="M72.8122 63.6882L69.6548 66.8455L75.9009 73.0916C71.2469 75.1648 66.9663 77.925 63.188 81.2433L96.3213 119L108.234 105.425L114.647 111.837L117.804 108.68L80.4504 71.3261C80.4505 71.3261 80.4503 71.3261 80.4504 71.3261L72.8122 63.6882Z"
fill="currentcolor" />
<path
d="M129.455 81.2433L114.137 98.6982L85.3974 69.9585C88.9142 69.1786 92.5697 68.7674 96.3213 68.7674C109.016 68.7674 120.611 73.4766 129.455 81.2433Z"
fill="currentcolor" />
<path
d="M152 21.822L156.867 38.875L157 39.3405L157.469 39.2228L174.671 34.911L162.336 47.6522L161.999 48L162.336 48.3478L174.671 61.089L157.469 56.7772L157 56.6595L156.867 57.125L152 74.178L147.133 57.125L147 56.6595L146.531 56.7772L129.329 61.089L141.664 48.3478L142.001 48L141.664 47.6522L129.329 34.911L146.531 39.2228L147 39.3405L147.133 38.875L152 21.822Z"
fill="white" stroke="black" />
<path d="M101 31L90 42L101 53L93 61" stroke="white" stroke-width="2" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,13 @@
<svg width="88" height="48" viewBox="0 0 88 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0H88V48H0V0Z" fill="var(--td-component-border)"/>
<path d="M42.8627 14.0518V16.7601H44.4877V14.0518H42.8627Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.3488 23.9824C38.3488 21.0407 40.7335 18.656 43.6752 18.656C46.6168 18.656 49.0015 21.0407 49.0015 23.9824C49.0015 26.9241 46.6168 29.3088 43.6752 29.3088C40.7335 29.3088 38.3488 26.9241 38.3488 23.9824ZM43.6752 20.281C41.6309 20.281 39.9738 21.9382 39.9738 23.9824C39.9738 26.0266 41.6309 27.6838 43.6752 27.6838C45.7194 27.6838 47.3766 26.0266 47.3766 23.9824C47.3766 21.9382 45.7194 20.281 43.6752 20.281Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M52.208 26.781H49.5867L47.5262 33.48L49.0794 33.9577L49.5903 32.2968H52.2045L52.7154 33.9577L54.2686 33.48L52.208 26.781ZM51.7047 30.6718L51.0077 28.406H50.787L50.0901 30.6718H51.7047Z" fill="var(--td-text-color-primary)"/>
<path d="M48.2077 18.3009L50.1225 16.3861L51.2715 17.5351L49.3567 19.4499L48.2077 18.3009Z" fill="var(--td-text-color-primary)"/>
<path d="M53.6057 23.1699H50.8974V24.7949H53.6057V23.1699Z" fill="var(--td-text-color-primary)"/>
<path d="M44.4877 31.2045V33.9129H42.8627V31.2045H44.4877Z" fill="var(--td-text-color-primary)"/>
<path d="M37.2279 31.5786L39.1427 29.6638L37.9936 28.5147L36.0788 30.4295L37.2279 31.5786Z" fill="var(--td-text-color-primary)"/>
<path d="M36.453 24.7949H33.7446V23.1699H36.453V24.7949Z" fill="var(--td-text-color-primary)"/>
<path d="M36.0788 17.5351L37.9936 19.4499L39.1427 18.3009L37.2279 16.3861L36.0788 17.5351Z" fill="var(--td-text-color-primary)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,5 @@
<svg width="88" height="48" viewBox="0 0 88 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0H88V48H0V0Z" fill="#13161B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M52.5327 26.8699C52.0346 26.9554 51.5225 26.9999 51 26.9999C46.0294 26.9999 42 22.9705 42 17.9999C42 16.9964 42.1642 16.0313 42.4673 15.1299C38.2268 15.8574 35 19.5518 35 23.9999C35 28.9705 39.0294 32.9999 44 32.9999C47.9671 32.9999 51.3346 30.4332 52.5327 26.8699Z" fill="#949EAA"/>
</svg>

After

Width:  |  Height:  |  Size: 495 B

@ -0,0 +1,13 @@
<svg width="88" height="48" viewBox="0 0 88 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="88" height="48" fill="var(--td-component-border)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.9999 20.583C42.1129 20.583 40.5832 22.1127 40.5832 23.9997C40.5832 25.8867 42.1129 27.4163 43.9999 27.4163C45.8869 27.4163 47.4166 25.8867 47.4166 23.9997C47.4166 22.1127 45.8869 20.583 43.9999 20.583ZM39.0832 23.9997C39.0832 21.2843 41.2845 19.083 43.9999 19.083C46.7153 19.083 48.9166 21.2843 48.9166 23.9997C48.9166 26.7151 46.7153 28.9163 43.9999 28.9163C41.2845 28.9163 39.0832 26.7151 39.0832 23.9997Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.2499 17.333V14.833H44.7499V17.333H43.2499Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.1838 18.7552L49.9513 16.9877L51.0119 18.0483L49.2444 19.8158L48.1838 18.7552Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M50.6666 23.2497H53.1666V24.7497H50.6666V23.2497Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M49.2444 28.1835L51.0119 29.951L49.9513 31.0117L48.1838 29.2442L49.2444 28.1835Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M44.7499 30.6663V33.1663H43.2499V30.6663H44.7499Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M39.8162 29.2442L38.0487 31.0117L36.988 29.951L38.7555 28.1835L39.8162 29.2442Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M37.3333 24.7497H34.8333V23.2497H37.3333V24.7497Z" fill="var(--td-text-color-primary)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.7555 19.8158L36.988 18.0483L38.0487 16.9877L39.8162 18.7552L38.7555 19.8158Z" fill="var(--td-text-color-primary)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,15 @@
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip0_2557_23660">
<rect id="svg_1" x="2.97754" y="2" fill="white" height="25.72" width="25.1407"/>
</clipPath>
</defs>
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<path id="svg_7" d="m15.746835,3.869737c3.260914,0 5.906354,2.647988 5.906354,5.908902c0,3.260916 -2.64544,5.906355 -5.906354,5.906355c-3.260916,0 -5.906356,2.64799 -5.906356,5.908903c0,3.260915 2.64544,5.906355 5.906356,5.906355c6.521828,0 11.815254,-5.293431 11.815254,-11.81526c0,-6.521829 -5.293427,-11.815257 -11.815254,-11.815257l0,0.000001zm0,4.06237c-1.01956,0 -1.846533,0.82697 -1.846533,1.846532c0,1.019563 0.826971,1.846532 1.846533,1.846532c1.019562,0 1.846531,-0.82697 1.846531,-1.846532c0,-1.019562 -0.826969,-1.846532 -1.846531,-1.846532zm0,11.81526c1.019034,0 1.846531,0.827495 1.846531,1.846532c0,1.019034 -0.827496,1.846533 -1.846531,1.846533c-1.019036,0 -1.846533,-0.827498 -1.846533,-1.846533c0,-1.019034 0.827498,-1.846532 1.846533,-1.846532zm11.550246,-4.054844c0,6.516983 -5.283056,11.800043 -11.800043,11.800043c-6.516984,0 -11.800043,-5.283059 -11.800043,-11.800043c0,-6.516986 5.28306,-11.800047 11.800043,-11.800047c6.516987,0 11.800043,5.283061 11.800043,11.800047z" fill-opacity="null" stroke-opacity="null" stroke-width="null" stroke="null" fill="#007f00"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,216 @@
{
"Canada": "加拿大",
"Turkmenistan": "土库曼斯坦",
"Saint Helena": "圣赫勒拿",
"Lao PDR": "老挝",
"Lithuania": "立陶宛",
"Cambodia": "柬埔寨",
"Ethiopia": "埃塞俄比亚",
"Faeroe Is.": "法罗群岛",
"Swaziland": "斯威士兰",
"Palestine": "巴勒斯坦",
"Belize": "伯利兹",
"Argentina": "阿根廷",
"Bolivia": "玻利维亚",
"Cameroon": "喀麦隆",
"Burkina Faso": "布基纳法索",
"Aland": "奥兰群岛",
"Bahrain": "巴林",
"Saudi Arabia": "沙特阿拉伯",
"Fr. Polynesia": "法属波利尼西亚",
"Cape Verde": "佛得角",
"W. Sahara": "西撒哈拉",
"Slovenia": "斯洛文尼亚",
"Guatemala": "危地马拉",
"Guinea": "几内亚",
"Dem. Rep. Congo": "刚果(金)",
"Germany": "德国",
"Spain": "西班牙",
"Liberia": "利比里亚",
"Netherlands": "荷兰",
"Jamaica": "牙买加",
"Solomon Is.": "所罗门群岛",
"Oman": "阿曼",
"Tanzania": "坦桑尼亚",
"Costa Rica": "哥斯达黎加",
"Isle of Man": "曼岛",
"Gabon": "加蓬",
"Niue": "纽埃",
"Bahamas": "巴哈马",
"New Zealand": "新西兰",
"Yemen": "也门",
"Jersey": "泽西岛",
"Pakistan": "巴基斯坦",
"Albania": "阿尔巴尼亚",
"Samoa": "萨摩亚",
"Czech Rep.": "捷克",
"United Arab Emirates": "阿拉伯联合酋长国",
"Guam": "关岛",
"India": "印度",
"Azerbaijan": "阿塞拜疆",
"N. Mariana Is.": "北马里亚纳群岛",
"Lesotho": "莱索托",
"Kenya": "肯尼亚",
"Belarus": "白俄罗斯",
"Tajikistan": "塔吉克斯坦",
"Turkey": "土耳其",
"Afghanistan": "阿富汗",
"Bangladesh": "孟加拉国",
"Mauritania": "毛里塔尼亚",
"Dem. Rep. Korea": "朝鲜",
"Saint Lucia": "圣卢西亚",
"Br. Indian Ocean Ter.": "英属印度洋领地",
"Mongolia": "蒙古国",
"France": "法国",
"Cura?ao": "库拉索岛",
"S. Sudan": "南苏丹",
"Rwanda": "卢旺达",
"Slovakia": "斯洛伐克",
"Somalia": "索马里",
"Peru": "秘鲁",
"Vanuatu": "瓦努阿图",
"Norway": "挪威",
"Malawi": "马拉维",
"Benin": "贝宁",
"St. Vin. and Gren.": "圣文森特和格林纳丁斯",
"Korea": "韩国",
"Singapore": "新加坡",
"Montenegro": "黑山",
"Cayman Is.": "开曼群岛",
"Togo": "多哥",
"China": "中国",
"Heard I. and McDonald Is.": "赫德岛和麦克唐纳群岛",
"Armenia": "亚美尼亚",
"Falkland Is.": "马尔维纳斯群岛(福克兰)",
"Ukraine": "乌克兰",
"Ghana": "加纳",
"Tonga": "汤加",
"Finland": "芬兰",
"Libya": "利比亚",
"Dominican Rep.": "多米尼加",
"Indonesia": "印度尼西亚",
"Mauritius": "毛里求斯",
"Eq. Guinea": "赤道几内亚",
"Sweden": "瑞典",
"Vietnam": "越南",
"Mali": "马里",
"Russia": "俄罗斯",
"Bulgaria": "保加利亚",
"United States": "美国",
"Romania": "罗马尼亚",
"Angola": "安哥拉",
"Chad": "乍得",
"South Africa": "南非",
"Fiji": "斐济",
"Liechtenstein": "列支敦士登",
"Malaysia": "马来西亚",
"Austria": "奥地利",
"Mozambique": "莫桑比克",
"Uganda": "乌干达",
"Japan": "日本",
"Niger": "尼日尔",
"Brazil": "巴西",
"Kuwait": "科威特",
"Panama": "巴拿马",
"Guyana": "圭亚那合作共和国",
"Madagascar": "马达加斯加",
"Luxembourg": "卢森堡",
"American Samoa": "美属萨摩亚",
"Andorra": "安道尔",
"Ireland": "爱尔兰",
"Italy": "意大利",
"Nigeria": "尼日利亚",
"Turks and Caicos Is.": "特克斯和凯科斯群岛",
"Ecuador": "厄瓜多尔",
"U.S. Virgin Is.": "美属维尔京群岛",
"Brunei": "文莱",
"Australia": "澳大利亚",
"Iran": "伊朗",
"Algeria": "阿尔及利亚",
"El Salvador": "萨尔瓦多",
"Côte d'Ivoire": "科特迪瓦",
"Chile": "智利",
"Puerto Rico": "波多黎各",
"Belgium": "比利时",
"Thailand": "泰国",
"Haiti": "海地",
"Iraq": "伊拉克",
"S?o Tomé and Principe": "圣多美和普林西比",
"Sierra Leone": "塞拉利昂",
"Georgia": "格鲁吉亚",
"Denmark": "丹麦",
"Philippines": "菲律宾",
"S. Geo. and S. Sandw. Is.": "南乔治亚岛和南桑威奇群岛",
"Moldova": "摩尔多瓦",
"Morocco": "摩洛哥",
"Namibia": "纳米比亚",
"Malta": "马耳他",
"Guinea-Bissau": "几内亚比绍",
"Kiribati": "基里巴斯",
"Switzerland": "瑞士",
"Grenada": "格林纳达",
"Seychelles": "塞舌尔",
"Portugal": "葡萄牙",
"Estonia": "爱沙尼亚",
"Uruguay": "乌拉圭",
"Antigua and Barb.": "安提瓜和巴布达",
"Lebanon": "黎巴嫩",
"Uzbekistan": "乌兹别克斯坦",
"Tunisia": "突尼斯",
"Djibouti": "吉布提",
"Greenland": "丹麦",
"Timor-Leste": "东帝汶",
"Dominica": "多米尼克",
"Colombia": "哥伦比亚",
"Burundi": "布隆迪",
"Bosnia and Herz.": "波斯尼亚和黑塞哥维那",
"Cyprus": "塞浦路斯",
"Barbados": "巴巴多斯",
"Qatar": "卡塔尔",
"Palau": "帕劳",
"Bhutan": "不丹",
"Sudan": "苏丹",
"Nepal": "尼泊尔",
"Micronesia": "密克罗尼西亚",
"Bermuda": "百慕大",
"Suriname": "苏里南",
"Venezuela": "委内瑞拉",
"Israel": "以色列",
"St. Pierre and Miquelon": "圣皮埃尔和密克隆群岛",
"Central African Rep.": "中非共和国",
"Iceland": "冰岛",
"Zambia": "赞比亚",
"Senegal": "塞内加尔",
"Papua New Guinea": "巴布亚新几内亚",
"Trinidad and Tobago": "特立尼达和多巴哥",
"Zimbabwe": "津巴布韦",
"Jordan": "约旦",
"Gambia": "冈比亚",
"Kazakhstan": "哈萨克斯坦",
"Poland": "波兰",
"Eritrea": "厄立特里亚",
"Kyrgyzstan": "吉尔吉斯斯坦",
"Montserrat": "蒙特塞拉特",
"New Caledonia": "新喀里多尼亚",
"Macedonia": "马其顿",
"Paraguay": "巴拉圭",
"Latvia": "拉脱维亚",
"Hungary": "匈牙利",
"Syria": "叙利亚",
"Honduras": "洪都拉斯",
"Myanmar": "缅甸",
"Mexico": "墨西哥",
"Egypt": "埃及",
"Nicaragua": "尼加拉瓜",
"Cuba": "古巴",
"Serbia": "塞尔维亚",
"Comoros": "科摩罗",
"United Kingdom": "英国",
"Fr. S. Antarctic Lands": "南极洲",
"Congo": "刚果(布)",
"Greece": "希腊",
"Sri Lanka": "斯里兰卡",
"Croatia": "克罗地亚",
"Botswana": "博茨瓦纳",
"Siachen Glacier": "锡亚琴冰川地区"
}

@ -0,0 +1,4 @@
// bus.js
import Vue from 'vue';
const bus = new Vue();
export default bus

@ -0,0 +1,35 @@
<template>
<div :style="style" class="color-container" />
</template>
<script lang="ts">
import { getBrandColor } from '@/config/color';
const panelColor =
'conic-gradient(from 90deg at 50% 50%, #FF0000 -19.41deg, #FF0000 18.76deg, #FF8A00 59.32deg, #FFE600 99.87deg, #14FF00 141.65deg, #00A3FF 177.72deg, #0500FF 220.23deg, #AD00FF 260.13deg, #FF00C7 300.69deg, #FF0000 340.59deg, #FF0000 378.76deg)';
export default {
name: 'Color',
props: {
value: {
type: String,
default: 'default',
},
},
computed: {
style() {
const { colorList } = this.$store.state.setting;
return {
background: this.value !== 'dynamic' ? getBrandColor(this.value, colorList)['--td-brand-color'] : panelColor,
};
},
},
};
</script>
<style lang="less" scoped>
.color-container {
width: 24px;
height: 24px;
border-radius: 50%;
display: inline-block;
}
</style>

@ -0,0 +1,44 @@
<template>
<div>
<!-- 负载均衡模式 -->
<div v-if="isLoadBalance">
<load-balance-status
v-if="healthyStatus && healthyStatus.length > 0"
:healthyStatusList="healthyStatus"
/>
<t-tag v-else theme="default" variant="light">{{ $t('page.host.healthy_status_unknown') }}</t-tag>
</div>
<!-- 单服务器模式 -->
<div v-else>
<single-server-status
v-if="healthyStatus && healthyStatus.length > 0"
:healthyStatus="healthyStatus[0]"
/>
<t-tag v-else theme="default" variant="light">{{ $t('page.host.healthy_status_unknown') }}</t-tag>
</div>
</div>
</template>
<script>
import SingleServerStatus from './SingleServerStatus.vue';
import LoadBalanceStatus from './LoadBalanceStatus.vue';
export default {
name: 'HealthStatus',
components: {
SingleServerStatus,
LoadBalanceStatus
},
props: {
healthyStatus: {
type: [Array, Object],
default: () => []
},
isLoadBalance: {
type: Boolean,
default: false
}
}
}
</script>

@ -0,0 +1,174 @@
<template>
<div class="health-status-container">
<t-tooltip placement="top" theme="light">
<t-tag
theme="primary"
:variant="hasUnhealthyServer ? 'dark' : 'light'"
:style="{
backgroundColor: hasUnhealthyServer ? '#fbe9e7' : '#e8f4ff',
color: hasUnhealthyServer ? '#e34d59' : '#00a870'
}"
>
{{ unhealthyCount === 0 ? $t('page.host.healthy_status_normal') : `${healthyStatusList.length}/${unhealthyCount}` }}
</t-tag>
<template #content>
<div class="health-status-tooltip">
<div class="tooltip-content-wrapper">
<!-- 每个服务器的详细信息 -->
<div v-for="(status, index) in healthyStatusList" :key="index" class="server-section">
<div class="server-title" :class="status.IsHealthy ? 'healthy-text' : 'unhealthy-text'">
{{ getServerInfo(status, index) }}: {{ status.IsHealthy ? $t('page.host.healthy_status_normal') : $t('page.host.healthy_status_abnormal') }}
</div>
<table class="status-table">
<tr>
<td class="label">{{ $t('page.host.healthy_status_detail.check_time') }}</td>
<td class="value">{{ formatTime(status.LastCheckTime) }}</td>
</tr>
<tr v-if="!status.IsHealthy">
<td class="label">{{ $t('page.host.healthy_status_detail.success_cnt') }}</td>
<td class="value">{{ status.SuccessCount || 0 }}</td>
</tr>
<tr v-if="!status.IsHealthy">
<td class="label">{{ $t('page.host.healthy_status_detail.failure_cnt') }}</td>
<td class="value">{{ status.FailCount }}</td>
</tr>
<tr v-if="!status.IsHealthy && status.LastErrorReason">
<td class="label error-text">{{ $t('page.host.healthy_status_detail.error_reason') }}</td>
<td class="value error-text">{{ status.LastErrorReason }}</td>
</tr>
</table>
</div>
</div>
</div>
</template>
</t-tooltip>
</div>
</template>
<script>
export default {
name: 'LoadBalanceStatus',
props: {
healthyStatusList: {
type: Array,
required: true
}
},
computed: {
hasUnhealthyServer() {
return this.healthyStatusList.some(status => !status.IsHealthy);
},
unhealthyCount() {
return this.healthyStatusList.filter(status => !status.IsHealthy).length;
},
healthyCount() {
return this.healthyStatusList.filter(status => status.IsHealthy).length;
}
},
methods: {
formatTime(time) {
return new Date(time).toLocaleString();
},
getServerInfo(status, index) {
return `${status.BackIP}:${status.BackPort}`;
}
}
}
</script>
<style lang="less" scoped>
.health-status-container {
display: inline-block;
}
.health-status-tooltip {
min-width: 400px;
}
.tooltip-content-wrapper {
max-height: 400px;
overflow-y: auto;
padding-right: 5px;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb:hover {
background: #aaa;
}
}
.section-title {
font-weight: bold;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px solid #eee;
}
.server-section {
margin-top: 16px;
padding-top: 8px;
border-top: 1px dashed #ddd;
&:first-child {
margin-top: 0;
padding-top: 0;
border-top: none;
}
}
.server-title {
font-weight: bold;
margin-bottom: 8px;
}
.status-table {
width: 100%;
border-collapse: collapse;
tr {
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
}
.label {
padding: 6px;
font-weight: 500;
width: 40%;
}
.value {
padding: 6px;
text-align: right;
width: 60%;
}
}
.healthy-text {
color: #00a870;
}
.unhealthy-text {
color: #e34d59;
}
.error-text {
color: #e34d59;
}
</style>

@ -0,0 +1,99 @@
<template>
<div class="health-status-container">
<t-tooltip placement="top" theme="light">
<t-tag
theme="primary"
:variant="healthyStatus.IsHealthy ? 'light' : 'dark'"
:style="{
backgroundColor: healthyStatus.IsHealthy ? '#e8f4ff' : '#fbe9e7',
color: healthyStatus.IsHealthy ? '#00a870' : '#e34d59'
}"
>
{{ healthyStatus.IsHealthy ? $t('page.host.healthy_status_normal') : $t('page.host.healthy_status_abnormal') }}
</t-tag>
<template #content>
<div class="health-status-tooltip">
<table class="status-table">
<tr>
<td class="label">{{ $t('page.host.healthy_status_detail.check_time') }}</td>
<td class="value">{{ formatTime(healthyStatus.LastCheckTime) }}</td>
</tr>
<tr v-if="!healthyStatus.IsHealthy">
<td class="label">{{ $t('page.host.healthy_status_detail.success_cnt') }}</td>
<td class="value">{{ healthyStatus.SuccessCount || 0 }}</td>
</tr>
<tr v-if="!healthyStatus.IsHealthy">
<td class="label">{{ $t('page.host.healthy_status_detail.failure_cnt') }}</td>
<td class="value">{{ healthyStatus.FailCount }}</td>
</tr>
<tr v-if="!healthyStatus.IsHealthy && healthyStatus.LastErrorReason">
<td class="label error-text">{{ $t('page.host.healthy_status_detail.error_reason') }}</td>
<td class="value error-text">{{ healthyStatus.LastErrorReason }}</td>
</tr>
</table>
</div>
</template>
</t-tooltip>
</div>
</template>
<script>
export default {
name: 'SingleServerStatus',
props: {
healthyStatus: {
type: Object,
required: true
}
},
methods: {
formatTime(time) {
return new Date(time).toLocaleString();
}
}
}
</script>
<style lang="less" scoped>
.health-status-container {
display: inline-block;
}
.health-status-tooltip {
min-width: 300px;
}
.status-table {
width: 100%;
border-collapse: collapse;
tr {
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
}
.label {
padding: 6px;
font-weight: 500;
width: 40%;
}
.value {
padding: 6px;
text-align: right;
width: 60%;
}
.healthy-text {
color: #00a870;
}
.unhealthy-text {
color: #e34d59;
}
.error-text {
color: #e34d59;
}
}
</style>

@ -0,0 +1,121 @@
<template>
<t-card theme="poster2">
<template #avatar>
<t-avatar size="56px">
<template #icon>
<shop-icon v-if="product.type === 1" />
<calendar-icon v-if="product.type === 2" />
<service-icon v-if="product.type === 3" />
<user-avatar-icon v-if="product.type === 4" />
<laptop-icon v-if="product.type === 5" />
</template>
</t-avatar>
</template>
<template #status>
<t-tag :theme="product.isSetup ? 'success' : 'default'" :disabled="!product.isSetup">{{
product.isSetup ? '已启用' : '已停用'
}}</t-tag>
</template>
<template #content>
<p class="list-card-item_detail--name">{{ product.name }}</p>
<p class="list-card-item_detail--desc">{{ product.description }}</p>
</template>
<template #footer>
<t-avatar-group cascading="left-up" :max="2">
<t-avatar>{{ typeMap[product.type - 1] }}</t-avatar>
<t-avatar
><template #icon>
<add-icon />
</template>
</t-avatar>
</t-avatar-group>
</template>
<template #actions>
<t-dropdown
:disabled="!product.isSetup"
trigger="click"
:options="[
{
content: '管理',
value: 'manage',
onClick: () => handleManageProduct(product),
},
{
content: '删除',
value: 'delete',
onClick: () => handleDeleteItem(product),
},
]"
>
<t-button theme="default" :disabled="!product.isSetup" shape="square" variant="text">
<more-icon />
</t-button>
</t-dropdown>
</template>
</t-card>
</template>
<script lang="ts">
import { ShopIcon, CalendarIcon, ServiceIcon, UserAvatarIcon, LaptopIcon, MoreIcon, AddIcon } from 'tdesign-icons-vue';
export default {
name: 'ListCard',
components: {
ShopIcon,
CalendarIcon,
ServiceIcon,
UserAvatarIcon,
LaptopIcon,
MoreIcon,
AddIcon,
},
props: {
product: {
type: Object,
},
},
data() {
return { typeMap: ['A', 'B', 'C', 'D', 'E'] };
},
methods: {
handleClickManage(product) {
this.$emit('manage-product', product);
},
handleClickDelete(product) {
this.$emit('delete-item', product);
},
},
};
</script>
<style lang="less" scoped>
@import '@/style/variables';
.list-card-item {
display: flex;
flex-direction: column;
cursor: pointer;
&_detail {
min-height: 140px;
&--name {
margin-bottom: 8px;
font-size: 16px;
font-weight: 400;
color: var(--td-text-color-primary);
}
&--desc {
color: var(--td-text-color-secondary);
font-size: 12px;
line-height: 20px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
height: 40px;
}
}
}
</style>

@ -0,0 +1,121 @@
<template>
<div class="result-container">
<div class="result-bg-img">
<component :is="dynamicComponent"></component>
</div>
<div class="result-title">{{ title }}</div>
<div class="result-tip">{{ tip }}</div>
<slot />
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import Result403Icon from '@/assets/assets-result-403.svg';
import Result404Icon from '@/assets/assets-result-404.svg';
import Result500Icon from '@/assets/assets-result-500.svg';
import ResultIeIcon from '@/assets/assets-result-ie.svg';
import ResultWifiIcon from '@/assets/assets-result-wifi.svg';
import ResultMaintenanceIcon from '@/assets/assets-result-maintenance.svg';
export default Vue.extend({
name: 'Result',
props: {
bgUrl: {
type: String,
default: '',
},
title: {
type: String,
default: '',
},
tip: {
type: String,
default: '',
},
type: {
type: String,
default: '',
},
},
computed: {
dynamicComponent() {
switch (this.type) {
case '403':
return Result403Icon;
case '404':
return Result404Icon;
case '500':
return Result500Icon;
case 'ie':
return ResultIeIcon;
case 'wifi':
return ResultWifiIcon;
case 'maintenance':
return ResultMaintenanceIcon;
default:
return Result403Icon;
}
},
},
});
</script>
<style lang="less" scoped>
@import '@/style/variables';
.result {
&-link {
color: var(--td-brand-color);
text-decoration: none;
cursor: pointer;
&:hover {
color: var(--td-brand-color);
}
&:active {
color: var(--td-brand-color);
}
&--active {
color: var(--td-brand-color);
}
&:focus {
text-decoration: none;
}
}
&-container {
min-height: 400px;
height: 75vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 24px;
}
&-bg-img {
width: 200px;
color: var(--td-brand-color);
}
&-title {
font-style: normal;
font-weight: 500;
margin-top: 8px;
color: var(--td-text-color-primary);
font-size: @font-size-xl;
line-height: @text-line-height-xl;
}
&-tip {
margin: 8px 0 32px;
font-size: @font-size-base;
color: var(--td-text-color-secondary);
line-height: @text-line-height-base;
}
}
</style>

@ -0,0 +1,49 @@
<template>
<img :class="className" :src="url" />
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'thumbnail',
props: {
url: {
type: String,
default: '',
},
type: {
type: String,
default: 'layout',
},
},
computed: {
className() {
return [
'thumbnail-container',
{
'thumbnail-circle': this.type === 'circle',
'thumbnail-layout': this.type === 'layout',
},
];
},
},
});
</script>
<style lang="less" scoped>
@import url('@/style/index.less');
.thumbnail {
&-container {
display: inline-block;
}
&-circle {
border-radius: @border-radius-50;
}
&-layout {
width: 88px;
height: 48px;
}
}
</style>

@ -0,0 +1,105 @@
<template>
<span :class="containerCls">
<span :class="iconCls">
<svg
v-if="type === 'down'"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M11.5 8L8 11.5L4.5 8" stroke="currentColor" stroke-width="1.5" />
<path d="M8 11L8 4" stroke="currentColor" stroke-width="1.5" />
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" v-else>
<path d="M4.5 8L8 4.5L11.5 8" stroke="currentColor" stroke-width="1.5" />
<path d="M8 5V12" stroke="currentColor" stroke-width="1.5" />
</svg>
</span>
<span>{{ describe }}</span>
</span>
</template>
<script>
import Vue from 'vue';
export default Vue.extend({
name: 'Trend',
props: {
type: String,
describe: [String, Number],
isReverseColor: Boolean,
},
computed: {
containerCls() {
return [
'trend-container',
{
'trend-container__reverse': this.isReverseColor,
'trend-container__up': !this.isReverseColor && this.type === 'up',
'trend-container__down': !this.isReverseColor && this.type === 'down',
},
];
},
iconCls() {
return ['trend-icon-container'];
},
},
});
</script>
<style lang="less" scoped>
@import '@/style/variables.less';
.trend {
&-container {
&__up {
color: var(--td-error-color);
display: inline-flex;
align-items: center;
justify-content: center;
.trend-icon-container {
background: var(--td-error-color-2);
margin-right: 8px;
}
}
&__down {
color: var(--td-success-color);
display: inline-flex;
align-items: center;
justify-content: center;
.trend-icon-container {
background: var(--td-success-color-2);
margin-right: 8px;
}
}
&__reverse {
color: #ffffff;
display: inline-flex;
align-items: center;
justify-content: center;
.trend-icon-container {
background: var(--td-brand-color-5);
margin-right: 8px;
}
}
.trend-icon-container {
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
}
}
}
</style>

@ -0,0 +1,145 @@
<template>
<div class="in-coder-panel">
<textarea ref="mycode" v-model="code" class="text_cls" ></textarea>
</div>
</template>
<script>
import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/hint/show-hint.css'
const CodeMirror = require('codemirror/lib/codemirror')
require('codemirror/addon/edit/matchbrackets')
require('codemirror/addon/selection/active-line')
require('codemirror/mode/sql/sql')
require('codemirror/addon/hint/show-hint')
require('codemirror/addon/hint/sql-hint')
export default {
props: {
//
valuecontent:{
type:String,
} ,
//
language: {
type: String,
default: null,
},
},
watch: {
valuecontent(newVal) {
console.log('valuecontent',newVal)
//SELECT * FROM student
this.editor.setValue(newVal)
},
},
data() {
return {
code: '',
editor: null,
content: '',
}
},
mounted() {
//
this._initialize()
let that = this
that.$bus.$on('showcodeedit', (e) => {
console.log('消息总线 来自父组件e', e)
that.code = e
that.editor.setValue(that.code)
})
},
methods: {
send_msg_to_parent () {
console.log(this.$parent)
//this.$parent.edtinput("asdfadf")
//this.$emit('edtinput',"sdsdsd" )
console.log("ssss")
},
//
resetData() {
this.editor.setValue('')
},
//
_initialize() {
const mime = 'text/x-mariadb'
// let theme = 'ambiance'//使
this.editor = CodeMirror.fromTextArea(this.$refs.mycode, {
//
mode: mime,
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
extraKeys: {
//
Ctrl: 'autocomplete',
},
hintOptions: {
//
completeSingle: false, //
tables: {}, //
},
})
this.editor.setValue(this.value || this.code)
//
let that = this
this.editor.on('change', (coder) => {
this.code = coder.getValue()
if (this.$emit) {
// Inputcode
//this.$emit('edtinput', this.code)
console.log('在子组件里面edtinput', this.code)
//this.$emit('update:valuecontent', this.code)
/* setTimeout(() => {
}, 0) */
console.log(that.$parent)
that.$bus.$emit("codeedit",this.code)
}
})
this.editor.on('inputRead', () => {
this.editor.showHint()
})
},
},
}
</script>
<style lang="less">
.CodeMirror {
height: 180px !important;
}
.in-coder-panel {
border-radius: 5px;
flex-grow: 1;
display: flex;
position: relative;
.text_cls {
}
.cm-variable {
font-size: 18px;
}
}
.CodeMirror {
flex-grow: 1;
z-index: 1;
}
.CodeMirror-code {
line-height: 19px;
}
.code-mode-select {
position: absolute;
z-index: 2;
right: 10px;
top: 10px;
max-width: 130px;
}
</style>

@ -0,0 +1,228 @@
import { Color } from 'tvision-color';
/* eslint-disable indent */
export type ColorToken = Record<string, string>;
export type ColorSeries = Record<string, ColorToken>;
export const defaultLightColor = [
'#0052d9',
'#0594fa',
'#00a870',
'#ebb105',
'#ed7b2f',
'#e34d59',
'#ed49b4',
'#834ec2',
];
export const defaultDarkColor = [
'#4582e6',
'#29a4fb',
'#03a56f',
'#ca8d03',
'#ed7b2f',
'#ea7b84',
'#f172c5',
'#ab87d5',
];
export const COLOR_TOKEN: ColorSeries = {
DEFAULT: {
'--td-brand-color': '#0052D9',
'--td-brand-color-1': '#e0ebff',
'--td-brand-color-2': '#c0d8ff',
'--td-brand-color-3': '#a1c4ff',
'--td-brand-color-4': '#81b1ff',
'--td-brand-color-5': '#5f9bff',
'--td-brand-color-6': '#3d87ff',
'--td-brand-color-7': '#176eff',
'--td-brand-color-8': '#0052D9',
'--td-brand-color-9': '#0048cd',
'--td-brand-color-10': '#0035b5',
},
CYAN: {
'--td-brand-color': '#0594FA',
'--td-brand-color-1': '#d7eefe',
'--td-brand-color-2': '#aeddfd',
'--td-brand-color-3': '#84cafd',
'--td-brand-color-4': '#58b8fc',
'--td-brand-color-5': '#29a4fb',
'--td-brand-color-6': '#0594FA',
'--td-brand-color-7': '#29a4fb',
'--td-brand-color-8': '#0594FA',
'--td-brand-color-9': '#0378df',
'--td-brand-color-10': '#01409b',
},
GREEN: {
'--td-brand-color': '#00A870',
'--td-brand-color-1': '#8dffd9',
'--td-brand-color-2': '#00f2a2',
'--td-brand-color-3': '#00dc92',
'--td-brand-color-4': '#00c583',
'--td-brand-color-5': '#00A870',
'--td-brand-color-6': '#009a5d',
'--td-brand-color-7': '#00c583',
'--td-brand-color-8': '#00A870',
'--td-brand-color-9': '#009a5d',
'--td-brand-color-10': '#004a14',
},
ORANGE: {
'--td-brand-color': '#ED7B2F',
'--td-brand-color-1': '#fce5d7',
'--td-brand-color-2': '#f8cdaf',
'--td-brand-color-3': '#f4b285',
'--td-brand-color-4': '#f19659',
'--td-brand-color-5': '#ED7B2F',
'--td-brand-color-6': '#e75510',
'--td-brand-color-7': '#f19659',
'--td-brand-color-8': '#ED7B2F',
'--td-brand-color-9': '#e75510',
'--td-brand-color-10': '#7f0a02',
},
RED: {
'--td-brand-color': '#E34D59',
'--td-brand-color-1': '#fbe5e7',
'--td-brand-color-2': '#f7ccd0',
'--td-brand-color-3': '#f3b2b8',
'--td-brand-color-4': '#ef989f',
'--td-brand-color-5': '#ea7b84',
'--td-brand-color-6': '#E34D59',
'--td-brand-color-7': '#ea7b84',
'--td-brand-color-8': '#E34D59',
'--td-brand-color-9': '#e42c3a',
'--td-brand-color-10': '#8d0309',
},
PINK: {
'--td-brand-color': '#ED49B4',
'--td-brand-color-1': '#fce5f4',
'--td-brand-color-2': '#facae9',
'--td-brand-color-3': '#f7aede',
'--td-brand-color-4': '#f491d2',
'--td-brand-color-5': '#f172c5',
'--td-brand-color-6': '#ED49B4',
'--td-brand-color-7': '#f172c5',
'--td-brand-color-8': '#ED49B4',
'--td-brand-color-9': '#e80f9d',
'--td-brand-color-10': '#8f025e',
},
PURPLE: {
'--td-brand-color': '#834EC2',
'--td-brand-color-1': '#eee6f7',
'--td-brand-color-2': '#ddceee',
'--td-brand-color-3': '#ccb6e6',
'--td-brand-color-4': '#bb9edc',
'--td-brand-color-5': '#ab87d5',
'--td-brand-color-6': '#9a6fce',
'--td-brand-color-7': '#9a6fce',
'--td-brand-color-8': '#834EC2',
'--td-brand-color-9': '#783ac3',
'--td-brand-color-10': '#4c1397',
},
YELLOW: {
'--td-brand-color': '#EBB105',
'--td-brand-color-1': '#fde9ab',
'--td-brand-color-2': '#fbd152',
'--td-brand-color-3': '#EBB105',
'--td-brand-color-4': '#dda204',
'--td-brand-color-5': '#ca8d03',
'--td-brand-color-6': '#b67803',
'--td-brand-color-7': '#fbd152',
'--td-brand-color-8': '#EBB105',
'--td-brand-color-9': '#dda204',
'--td-brand-color-10': '#603100',
},
};
export const LIGHT_CHART_COLORS: ColorToken = {
textColor: 'rgba(0, 0, 0, 0.9)',
placeholderColor: 'rgba(0, 0, 0, 0.35)',
borderColor: '#dcdcdc',
containerColor: '#fff',
};
export const DARK_CHART_COLORS: ColorToken = {
textColor: 'rgba(255, 255, 255, 0.9)',
placeholderColor: 'rgba(255, 255, 255, 0.35)',
borderColor: '#5e5e5e',
containerColor: '#242424',
};
function toUnderline(name: string): string {
return name.replace(/([A-Z])/g, '_$1').toUpperCase();
}
export function getBrandColor(type: string, colorList: ColorSeries): ColorToken {
const name = /^#[A-F\d]{6}$/i.test(type) ? type : toUnderline(type);
return colorList[name || 'DEFAULT'];
}
export function getColorList(colorArray: Array<ColorToken>): Array<string> {
const pureColorList = [];
colorArray.map((colorToken) => Object.keys(colorToken).map((key) => pureColorList.push(colorToken[key])));
return pureColorList;
}
// inspired by https://stackoverflow.com/questions/36721830/convert-hsl-to-rgb-and-hex
export function hslToHex(h: number, s: number, l: number) {
l /= 100;
const a = (s * Math.min(l, 1 - l)) / 100;
const f = (n: number) => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color)
.toString(16)
.padStart(2, '0');
};
return `#${f(0)}${f(8)}${f(4)}`;
}
export function generateColorMap(theme: string, colorPalette: Array<string>, mode: 'light' | 'dark') {
const isDarkMode = mode === 'dark';
let brandColorIdx = colorPalette.indexOf(theme);
if (isDarkMode) {
// eslint-disable-next-line no-use-before-define
colorPalette.reverse().map((color) => {
const [h, s, l] = Color.colorTransform(color, 'hex', 'hsl');
return Color.colorTransform([h, Number(s) - 4, l], 'hsl', 'hex');
});
brandColorIdx = 5;
colorPalette[0] = `${colorPalette[brandColorIdx]}20`;
}
const colorMap = {
'--td-brand-color': colorPalette[brandColorIdx], // 主题色
'--td-brand-color-1': colorPalette[0], // light
'--td-brand-color-2': colorPalette[1], // focus
'--td-brand-color-3': colorPalette[2], // disabled
'--td-brand-color-4': colorPalette[3],
'--td-brand-color-5': colorPalette[4],
'--td-brand-color-6': colorPalette[5],
'--td-brand-color-7': brandColorIdx > 0 ? colorPalette[brandColorIdx - 1] : theme, // hover
'--td-brand-color-8': colorPalette[brandColorIdx], // 主题色
'--td-brand-color-9': brandColorIdx > 8 ? theme : colorPalette[brandColorIdx + 1], // click
'--td-brand-color-10': colorPalette[9],
};
return colorMap;
}
export function insertThemeStylesheet(theme: string, colorMap: ColorToken, mode: 'light' | 'dark') {
const isDarkMode = mode === 'dark';
const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;
const styleSheet = document.createElement('style');
styleSheet.type = 'text/css';
styleSheet.innerText = `${root}{
--td-brand-color: ${colorMap['--td-brand-color']};
--td-brand-color-1: ${colorMap['--td-brand-color-1']};
--td-brand-color-2: ${colorMap['--td-brand-color-2']};
--td-brand-color-3: ${colorMap['--td-brand-color-3']};
--td-brand-color-4: ${colorMap['--td-brand-color-4']};
--td-brand-color-5: ${colorMap['--td-brand-color-5']};
--td-brand-color-6: ${colorMap['--td-brand-color-6']};
--td-brand-color-7: ${colorMap['--td-brand-color-7']};
--td-brand-color-8: ${colorMap['--td-brand-color-8']};
--td-brand-color-9: ${colorMap['--td-brand-color-9']};
--td-brand-color-10: ${colorMap['--td-brand-color-10']};
}`;
document.head.appendChild(styleSheet);
}

@ -0,0 +1,2 @@
export const prefix = 'tdesign-starter';
export const TOKEN_NAME = 'tdesign-starter';

@ -0,0 +1,20 @@
export default {
development: {
// 开发环境接口请求
API: 'http://127.0.0.1:26666/samwaf',
// 开发环境 cdn 路径
CDN: '',
},
test: {
// 测试环境接口地址
API: 'https://service-exndqyuk-1257786608.gz.apigw.tencentcs.com',
// 测试环境 cdn 路径
CDN: '',
},
release: {
// 正式环境接口地址
API: '/samwaf',
// 正式环境 cdn 路径
CDN: '',
},
};

@ -0,0 +1,15 @@
export default {
"showFooter": true,
"isSidebarCompact": false,
"showBreadcrumb": true,
"mode": "auto",
"layout": "side",
"splitMenu": false,
"isFooterAside": false,
"isSidebarFixed": true,
"isHeaderFixed": true,
"isUseTabsRouter": false,
"showHeader": true,
"backgroundTheme": "blueGrey",
"brandTheme": "default"
};

@ -0,0 +1,74 @@
interface IOption {
value: number | string;
label: string;
}
// 规则状态枚举
export const RULE_STATUS = {
STOPPING: 0,
RUNNING: 1,
};
// 防护状态枚举
export const GUARD_STATUS = {
UN_GUARDDING: 0,
GUARDDING: 1,
};
// SSL证书状态枚举
export const SSL_STATUS = {
NOT_SSL: 0,
SSL: 1,
};
// 启动状态枚举
export const START_STATUS = {
START: 0,
NOT_START: 1,
};
// 合同状态枚举
export const CONTRACT_STATUS = {
FAIL: 0,
AUDIT_PENDING: 1,
EXEC_PENDING: 2,
EXECUTING: 3,
FINISH: 4,
};
export const CONTRACT_STATUS_OPTIONS: Array<IOption> = [
{ value: CONTRACT_STATUS.FAIL, label: '审核失败' },
{ value: CONTRACT_STATUS.AUDIT_PENDING, label: '待审核' },
{ value: CONTRACT_STATUS.EXEC_PENDING, label: '待履行' },
{ value: CONTRACT_STATUS.EXECUTING, label: '审核成功' },
{ value: CONTRACT_STATUS.FINISH, label: '已完成' },
];
// 合同类型枚举
export const CONTRACT_TYPES = {
MAIN: 0,
SUB: 1,
SUPPLEMENT: 2,
};
export const CONTRACT_TYPE_OPTIONS: Array<IOption> = [
{ value: CONTRACT_TYPES.MAIN, label: '主合同' },
{ value: CONTRACT_TYPES.SUB, label: '子合同' },
{ value: CONTRACT_TYPES.SUPPLEMENT, label: '补充合同' },
];
// 合同收付类型枚举
export const CONTRACT_PAYMENT_TYPES = {
PAYMENT: 0,
RECIPT: 1,
};
// 通知的优先级对应的TAG类型
export const NOTIFICATION_TYPES = {
low: 'primary',
middle: 'warning',
high: 'danger',
};
// 攻击类型TAG类型
export const ATTACK_TYPES = {
CC: 0,
CMD: 1,
WEBUPLOAD: 2,
};

@ -0,0 +1,840 @@
/**
* SamWaf English Language Pack
*
* common - Common fields
* menu - Left menu
* page - Fields for specific functional pages
*/
export default {
common:{
confirm: "Confirm",
cancel: "Cancel",
close: "Close",
search: "Search",
refresh:"Refresh",
all: "All",
details: "Details",
new: "New",
add:"Add",
copy: "Copy",
edit: "Edit",
delete: "Delete",
reset: "Reset",
submit: "Submit",
export: "Export",
return: "Return",
status: "Status",
remarks: "Remarks",
renew:"Renew",
select_placeholder: "Please select ",
placeholder: "Please enter ",
placeholder_content: "Please enter content ",
debug: "Debug",
confirm_delete: "Confirm delete the selected data?",
data_delete_warning: "After deletion, the data will be removed and cannot be recovered",
create_time: "Creation Time",
update_time: "Update Time",
op: "Operation Content",
date: "Date",
online_document: "Online Document",
defense_status:{
all: "All",
stop: "Block",
pass: "Allow",
forbid: "Forbid",
},
on: "On",
off: "Off",
http_header:{
name:"Name",
value:"Value",
},
success: "Success",
failed: "Fail",
loading: "Loading...",
},
login:{
login_title: "Login",
login_sub_title: "zhky Website Firewall Management",
login_has_question: "Having trouble?",
login_online_document: "SamWaf Online Documentation",
input_account_placeholder: "Please enter your account:",
input_password_placeholder: "Please enter your password:",
input_secret_code_placeholder: "Please enter your secret code:",
login_btn_title: "Login",
rule:{
phone: "Phone number is required",
account: "Account is required",
password: "Password is required",
verifyCode: "Verification code is required"
},
login_success: "Login successful",
},
topNav:{
update:{
has_new_version: "New version available",
},
contract: "Contact SamWaf",
help_document: "Help Document",
current_server: "Current Server",
system_config: "System Configuration",
dropdown_person_center: "Personal",
dropdown_update: "Update",
dropdown_reboot_waf: "Reboot",
dropdown_logout: "Logout",
},
dashboard:{
tip_create_website_title: "You have not created a protected website, click to create one",
tip_create_website_link: "Create now",
tip_modify_pwd_title: "You are still using the default account and password, please change it soon",
tip_modify_pwd_link: "Change now",
tip_empty_otp_title: "You have not bound 2FA yet. It is recommended to bind as soon as possible",
tip_empty_otp_link: "Bind Now",
counter:{
today_of_attack_count: "Today's Attack Count",
all_visit_count: "Total Visits Today",
not_normal_visit_count: "Abnormal IPs Today (count)",
qps: "Current QPS",
},
cycle_title: "Comparison of Attacks and Normal Access Over Time",
cycle_subtitle: "(times)",
cycle_normal_count: "Normal Count This Period",
cycle_attack_count: "Attack Count This Period",
cycle_percent_title: "Proportion of Normal to Attack",
cycle_percent_subtitle: "In the Period",
ip_rank:{
normal_title:"IP Normal Rank",
attack_title:"IP Attack Rank",
ip:"IP",
counter:"Counter",
rank:"Rank",
tag:"Tag",
ip_belong:"IP Belong",
day:"Today",
week:"Week",
}
},
menu:{
dashboard: {
parent_title: "Dashboard",
dashboard_title: "Overview Dashboard",
},
host:{
parent_title: "Website Protection",
host_title: "Website Protection",
host_detail: "Host Protection Details",
host_protect_rule: "Protection Rules",
host_protect_rule_edit: "Edit Protection Rules",
allow_ip: "IP Allow List",
allow_url: "URL Allow List",
deny_ip: "IP Block List",
deny_url: "URL Block List",
ldp_url: "Protection URL",
cc: "CC Protection",
sensitive:"Sensitive",
sslconfig:"SSL Folder",
batchtask:"Batch Task",
sslorder:"SSL Apply Result",
ssl_expire:"SSL Expire Check",
blocking_page:"Custom Blocking Page",
},
analysis:{
parent_title: "Data Analysis",
analysis_title: "Data Analysis",
},
visit_log:{
parent_title: "Protection Logs",
visit_title: "Visit Logs",
visit_detail_title: "Protection Details",
attack_title: "Attack Logs",
},
account:{
parent_title: "Account",
otp_title:"Two-factor auth (2FA)",
account_list_title: "Account List",
account_log_title: "Account Logs",
},
system:{
parent_title: "System Settings",
system_log_title: "System Logs",
system_config_title: "Parameter Settings",
system_runtime_title: "Runtime Parameters",
system_one_key_modify_title: "Quick Modification",
task:"Task Manager",
},
pc:{
parent_title: "Device",
pc_list_title: "Device List",
}
},
page:{
account: {
create_account: "Create Account",
login_account_label: "Login Account",
reset_password: "Reset Password",
reset_otp: "Reset 2FA",
role: "Role",
role_super_admin: "Super Administrator",
role_admin: "Administrator",
login_password: "Login Password",
super_admin_password: "Super Administrator Password",
new_password: "New Password",
confirm_password: "Confirm Password",
password_mismatch_warning: "The passwords do not match, please check",
admin_delete_warning: "The default admin account cannot be deleted",
},
otp:{
alert_message: "SamWaf Two-Factor Authentication (2FA) is a secure login verification technology. It requires users to provide additional authentication information during login, in addition to their password, to enhance account security.",
secret_code: "Enter Security Code",
bind_success_tip: "Successfully bound. If you need to unbind, please click More to expand",
bind: "Bind",
unbind: "Unbind",
cannot_scan: "Scan failed?",
},
account_log:{
export_logs: "Export Logs",
view_log_dialog_title: "View Log",
operation_account: "Operation Account",
operation_type: "Operation Type",
operation_content: "Operation Content",
cancel: "Cancel",
operation_time: "Operation Time"
},
analysis:{
},
cc:{
new_cc_protection: "New CC Protection",
selected_count: "Selected {count} items",
website: "Website",
url: "URL",
rate: "Rate",
limit: "Limit Access Times",
lock_minutes:"Lock Time(Minutes)",
samwaf_cc_protection: "SamWaf Firewall Resists CC Attacks",
input_url_placeholder: "Enter URL (optional)",
show_cc_ban_ip: "Show CC Ban IP",
ban_ip:"Ban IP",
ban_remain_time:"Ban Remain Ip",
ban_ip_belong:"IP Belong",
remove_ban_ip:"Remove Ban IP",
},
visit_log:{
visit_log: "Protection Logs",
online_document: "Online Document",
website: "Website",
rule_name: "Rule Name",
access_status: "Access Status",
response_code: "Response Code",
access_ip: "Access IP",
access_date: "Access Date",
access_method: "Access Method",
log_archive_db: "Log Archive Database",
guest_identity: "Identity",
time_spent: "Time Spent (ms)",
risk_level: "Risk Level",
trigger_rule: "Trigger Rule",
time: "Time",
domain: "Domain",
request: "Request",
source_ip: "Source IP",
country: "Country",
province: "Province",
city: "City",
access_url: "Access URL",
header: "Header",
status_code: "Response Code",
search_placeholder: "Please enter rule name",
select_placeholder: "Please select defense status",
input_placeholder: "Please enter access method",
date_range_today: "Today",
date_range_last_3_days: "Last 3 Days",
date_range_last_7_days: "Last 7 Days",
date_range_last_300_days: "Last 300 Days",
export_db_file_header: "Export the currently selected log file(SQLITE)",
export_db_file_content: "The historical file may be large, to avoid affecting bandwidth, please export during off-peak hours.",
pop_detail_header:"Visit Detail",
detail:{
defense_status: "Defense Status",
visit_time: "Visit",
detection_time: "Detection",
defense_status_step: "Defense Status",
response_status: "Response Status",
request_identifier: "Request Identifier",
request_time: "Request Time",
request_domain: "Request Domain",
request_method: "Request Method",
request_content_size: "Request Content Size",
visitor_ip: "Visitor IP",
add_to_deny_list: "Add to Block List",
visitor_port: "Visitor Port",
request_region: "Request Region",
response_code: "Response Code",
more_info:"More Information",
request_path: "Request Path",
request_header: "Request Header",
request_user_browser: "Request User Browser",
request_cookies: "Request Cookies",
request_body: "Request BODY",
request_form: "Request Form",
response_data: "Response Data",
quick_add_rule: "Quickly Add Rule",
open: "Open",
close: "Close",
add_to_deny_list_confirm_header: "Add to Block List",
add_to_deny_list_confirm_body: "Are you sure you want to add this IP to the block list?",
website_not_exist_warning: "The website does not exist",
back: "Back",
mouse_select_tooltip: "Select the content you want to add with the mouse, then click on the page's blank area",
http_copy_mask: "False Positive",
http_copy_mask_tip: "If you encounter a false positive, please copy the text below and send it to samwafgo@gmail.com. Common sensitive information has already been masked: header fields such as Authorization, Token, Api-Key, Secret, Access-Token, X-Api-Key, X-Access-Token, X-Secret, Session-Key, Set-Cookie; cookies such as sessionid, auth, token, key, secret. If there are other sensitive fields, please mask them yourself or feel free to submit an issue.",
ai:{
title: "AI",
log_ai_analysis: "AI Analysis",
before_send_ai :"Before you send content to ai",
before_send_ai_tip:"Before you send content to ai,Common sensitive information has already been masked: header fields such as Authorization, Token, Api-Key, Secret, Access-Token, X-Api-Key, X-Access-Token, X-Secret, Session-Key, Set-Cookie; cookies such as sessionid, auth, token, key, secret. If there are other sensitive fields, please mask them yourself or feel free to submit an issue. ",
},
time_cost:{
title: "Time Cost(ms)",
total_cost:"Total Time Cost",
pre_check_cost:"Req Check Cost",
forward_cost:"Forward Cost",
backend_check_cost:"Response Check Cost",
},response:{
response_title: "Response Content",
response_body: "Response Body",
response_header: "Response Header",
response_status: "Response Status",
}
}
},
attack_log:{
attack_log: "Risk Log",
online_document: "Online Documentation",
rule_name: "Triggered Rule",
source_ip: "IP",
deny_num: "Blocked Count",
pass_num: "Allowed Count",
first_time: "First Access Time",
latest_time: "Latest Access Time",
ip_total_tag: "Triggered Rule Set",
attack_ip_visit_detail_list_header: "Access IP Details",
},
center:{
switch_local: "Switch to Local (No Remote Access)",
server_switch_button: "Switch Server",
recent_visit_time: "Recent Visit Time",
client_server_name: "Client Name",
client_system_type: "Operating System Type",
client_ip: "IP",
client_port: "Port",
client_new_version: "Version Number",
client_new_version_desc: "Version",
last_visit_time: "Last Visit Time",
},
host: {
new_protection: "New Protection",
website_protection: "Website Protection",
export_data: "Export Data",
import_data: "Import Data",
website: "Website",
url: "URL",
ssl_auto_apply: "SSL Auto Apply",
search_placeholder: "Please enter",
search_button: "Search",
core_features: "SamWaf Core Features, All website information, Protection features enabled, etc.",
host: "Website",
host_tips: "Enter the domain name of the website you want to protect: e.g., www.samwaf.com,*.samwaf.com",
host_placeholder: "Please enter the website URL",
host_validation: "Please enter a valid hostname or IP address, such as www.samwaf.com or 8.8.8.8.",
port: "Port",
port_placeholder: "Please enter the website port, usually 80/443",
port_tips: "Enter the port of the website you want to protect. 1. HTTP is 80, HTTPS is 443. 2. If you have installed Baota, Nginx, IIS, etc., you need to manually change the port to non-80 or non-443.",
bind_more_port: " Bind More Port(optional):",
bind_more_port_placeholder: "Ports should be separated by commas, e.g., 80,8080",
bind_more_port_tips: "Applicable situations: 1. For example, if the main port 443 has a certificate, you need port 80 for automated certificate application (file verification method) 2. Suitable for serving multiple ports for the same website without SSL at the same time",
ssl: "SSL",
ssl_folder: "SSL Folder",
ssl_tips: "If it is HTTPS, you need to select an encryption certificate. Port 80 does not require one.",
ssl_yes: "Yes",
ssl_no: "No",
add_new_ssl:"Add New SSL",
edit_ssl:"Edit SSL",
bind_empty_ssl_tips:"Current Cannot Bind SSL",
ssl_not_found_tips:"Ssl Not Found",
ssl_option_yes: "Encryption Certificate (requires certificate upload)",
ssl_option_no: "Non-encrypted",
guard_status_on: "Protected",
guard_status_off: "Not Protected",
auto_start_on: "Auto Start",
auto_start_off: "Manual Start",
tab_base: "Basic Information",
tab_engine: "Engine Built-in Protection",
tab_other: "Other Configurations",
tab_more_domain:"Bind More Domain",
tab_password:"Web Password Visit",
tab_health_check: 'Health Check',
tab_captcha: 'Captcha Settings',
more_domain:"Bind More Domain",
more_domain_tips:"Enter multiple domain names, each on a new line, without including the port.",
start_status: "Start Status",
guard_status: "Protection Status",
start_status_content: "This feature selects whether to start directly.",
health_check: {
is_enable_healthy: 'Enable Health Check',
is_enable_healthy_tips: 'When enabled, the health status of backend servers will be checked regularly',
check_method: 'Check Method',
check_method_tips: 'HTTP request method used for health check',
check_path: 'Check Path',
check_path_tips: 'URL path used for health check, e.g. / or /health',
check_path_placeholder: 'Enter check path, default is /',
expected_codes: 'Expected Status Codes',
expected_codes_tips: 'Expected HTTP status codes for health check, separate multiple codes with commas',
expected_codes_placeholder: 'Enter expected status codes, e.g. 200,201,202',
response_time: 'Response Timeout',
response_time_tips: 'Maximum waiting time for health check requests',
seconds: 'seconds',
fail_count: 'Consecutive Failures',
fail_count_tips: 'After reaching this count, the server will be marked as unhealthy',
success_count: 'Consecutive Successes',
success_count_tips: 'After reaching this count, an unhealthy server will be marked as healthy again',
times: 'times'
},
healthy_status: "Health Status",
healthy_status_normal: "Normal",
healthy_status_abnormal: "Abnormal",
healthy_status_unknown: "",
healthy_status_detail: {
ip: "Backend IP",
port: "Backend Port",
check_time: "Last Checked",
error_reason: "Error Reason",
success_cnt: "Success Count",
failure_cnt: "Failure Count",
total_servers: "Total Servers",
healthy_servers: "Healthy Servers",
unhealthy_servers: "Unhealthy Servers",
},
captcha: {
alert:"Note: For payment callbacks, refund notifications, open platform notifications, and other callback-related communications, please ensure the following IP addresses are added to your network whitelist or configure URL exceptions in your security/firewall settings",
is_enable: 'Enable Captcha',
is_enable_tips: 'Require captcha verification for website access',
exclude_urls: 'Exclude URLs',
exclude_urls_tips: 'These URLs will not require captcha verification, one URL per line',
exclude_urls_placeholder: 'e.g.: /api/',
expire_time: 'Verification Period',
expire_time_tips: 'How long the verification remains valid',
hours: 'hours'
},
keyfile: "Key String",
keyfile_content: "Usually filename: *.key Content format: -----BEGIN RSA PRIVATE KEY----- Copy all and fill in",
certfile: "Certificate String",
certfile_content: "Usually filename: *.crt Content format: -----BEGIN CERTIFICATE----- Copy all and fill in",
remote_host: "Backend Host",
remote_host_content: "The Backend host is usually the same as the domain name of the first website (make sure to include the protocol http:// or https://).",
remote_host_validation: "Must start with http:// or https:// and must not contain a port number.",
is_trans_back_domain: "Trans backend domain",
is_trans_back_domain_content: "Off by default. On this option if the protected domain and backend domain are different.",
remote_ip: "Backend IP(Dynamic Domain)",
remote_ip_content: "If SamWaf and the website are on the same server, fill in 127.0.0.1. If on different servers, please fill in the actual IP or Dynamic domain.",
remote_port: "Backend Port",
remote_port_content: "Situation 1: If SamWaf and the website are on the same server, the port needs to be changed to 81 or other ports. Situation 2: If on different servers, this can be the original port.",
remarks: "Remarks",
exclude_url_log: "Exclude URL When Logging",
exclude_url_log_tips: "Exclude URL prefix data when logging",
response_time_out: "Response timeout (in seconds)",
response_time_out_tips: "If set to 0, it will wait indefinitely, which is not recommended.",
insecure_skip_verify: 'Skip HTTPS Certificate Verification',
insecure_skip_verify_tips: 'When enabled, the validity of backend HTTPS server certificates will not be verified, which may pose security risks',
bot_detection: "Bot Detection",
bot_detection_tips: "Detect if search engines are disguised",
sql_injection_detection: "SQL Injection Detection",
sql_injection_detection_tips: "Detect if there is SQL injection",
xss_detection: "XSS Detection",
xss_detection_tips: "Detect if there is XSS attack",
scan_detection: "Scanning Tool Detection",
scan_detection_tips: "Detect if scanning tools are present",
rce_detection: "RCE Detection",
rce_detection_tips: "RCE Remote Attack Detection",
sensitive_detection: "Sensitive Detection",
sensitive_detection_tips: "Sensitive Detection",
dir_traversal_detection: "Dir Traversal Detection",
dir_traversal_detection_tips: "Dir Traversal Detection",
engine_protection: "Engine Built-in Protection",
other_config: "Other Configurations",
guard_status_confirm: "Protection Status Reminder",
guard_status_confirm_content: "Protection Status [On] means real-time protection for this website. Protection Status [Off] means real-time protection is turned off for this website.",
start_status_confirm: "Start Status Reminder",
start_status_confirm_content: "Start Status [On] will normally accept user requests. Start Status [Off] will stop user requests.",
import_file: "Import File",
upload_file: "Upload File",
upload_file_limit_size: "Upload file size within 5MB",
upload_tips: "No file selected",
file_upload_success: "File uploaded successfully",
file_upload_fail: "File upload failed",
file_safety: "File Safety",
upload:{
import_auto_create_code:"Import new host code (for new data)",
import_remain_code:"Import retained host code (for old data)",
},
back_system_type_baota: "Baota",
back_system_type_phpstudy: "Xiao Pi Panel (phpstudy)",
back_system_type_phpnow: "PHPnow",
back_system_type_default: "Default",
back_system_biz_website: "Pure Website",
back_system_biz_api: "API Business System",
back_system_biz_mange: "Business and Management",
back_system_biz_default: "Default",
delete_confirm_clear_relation: "After deletion, the website information and rules will be cleared and cannot be restored.",
forbid_for_global_site: "Global websites cannot be operated",
forbid_for_global_site_only_change_guard_status: "Global websites can only configure protection status",
host_rule_msg: "Do not fill in HTTP and HTTPS, just enter the domain name.",
real_time:"Real Time",
real_qps:"QPS",
real_active:"Active Count",
loadbalance: {
label_loadbalance_is_enable: "Enable Load Balancing",
label_loadbalance_type: "Load Balancing Type",
label_loadbalance_type_weight_round_robin: "Weighted Round Robin (WRR)",
label_loadbalance_type_least_connections: "Least Connections",
label_loadbalance_type_ip_hash: "IP Hash",
label_loadbalance_type_source_hash: "Source Address Hash",
label_loadbalance_type_url_hash: "URL Hash",
label_loadbalance_type_least_time: "Minimum Response Time",
label_is_enable_load_balance_on: "Enable Load Balancing",
label_is_enable_load_balance_off: "Disable Load Balancing",
label_add_loadbalance: "Add Load Balancer",
website: "Website",
remote_ip: "Remote IP",
remote_port: "Remote Port",
weight: "Weight"
},
unrestricted_port: {
label_unrestricted_port_is_enable: "Strict Source Port",
label_unrestricted_port_is_enable_on: "Enable",
label_unrestricted_port_is_enable_off: "Disable",
unrestricted_port_tip: "If disabled, suitable when using an external CDN or Nginx, it only matches the protected domain and not the source port."
},
auto_jump_https:{
label_autu_jump_https: "Force 80 redirect HTTPS",
label_autu_jump_https_on: "On",
label_autu_jump_https_off: "Off",
autu_jump_https_tip:"If enabled, SamWaf will force automatic redirection to HTTPS; if disabled, SamWaf will not perform automatic redirection."
},
is_enable_http_auth_base:"Web Password Visit",
is_enable_http_auth_base_tips: "After enabled, the website will require a password for access. Please add a username and password.",
modify_all_guard_status: 'Batch Protection Switch',
confirm_modify_all_guard_status: 'Are you sure you want to modify the protection status of all websites?',
select_guard_status: 'Please select protection status',
},
one_key_mod: {
one_key_placeholder: "Due to the fact that only one program can use Web (port 80, port 443) on a single server, if you need to set Waf as a proxy, you need to change 80 to 81 and 443 to 444 here.\nSamWaf has added a one-click modification of Baota Web port for user convenience. Available only on Linux.",
baota_placeholder: "Baota Nginx configuration default path",
button_one_key_modify: "One-click Modify",
modify_logs: "SamWaf One-click Modification Records",
title_file_path: "File Path",
title_create_time: "Creation Time",
label_op_system: "Operating System",
label_file_path: "File Path",
label_before_content: "Original Content",
label_after_content: "Modified Content",
confirm_delete: "Are you sure you want to delete?",
success_modify_message: "Operation successful",
warning_modify_message: "Operation warning"
},
ipallow: {
button_add_ip: "Add Allowlist IP",
label_website: "Website",
label_ip: "IP",
alert_message: "SamWaf firewall will ignore IPs or CIDR in the allowlist."
},
ipblock: {
button_add_ip: "Add Blocklist IP",
label_website: "Website",
label_ip: "IP",
alert_message: "SamWaf firewall will block access from IPs or CIDR in the blocklist."
},
ldpurl: {
new_privacy_url: "Add New Privacy Protection URL",
label_website: "Website",
label_url: "URL",
label_compare_type: "Match Type",
alert_message: "SamWaf will process sensitive data in the specified URL to hide parts of it, such as phone numbers.",
compare_type_option_equal: "Equal",
compare_type_option_pre: "Prefix Match",
compare_type_option_end: "Suffix Match",
compare_type_option_contain: "Contains Match"
},
urlallow: {
button_add_url: "Add Allowlist URL",
label_website: "Website",
label_url: "URL",
label_compare_type: "Match Type",
alert_message: "SamWaf firewall will ignore URLs in the allowlist during protection.",
compare_type_option_equal: "Equal",
compare_type_option_pre: "Prefix Match",
compare_type_option_end: "Suffix Match",
compare_type_option_contain: "Contains Match"
},
urlblock: {
button_add_url: "Add Blocklist URL",
label_website: "Website",
label_url: "URL",
label_compare_type: "Match Type",
alert_message: "SamWaf firewall will block access to URLs in the blocklist.",
compare_type_option_equal: "Equal",
compare_type_option_pre: "Prefix Match",
compare_type_option_end: "Suffix Match",
compare_type_option_contain: "Contains Match"
},
sensitive:{
button_add_sensitive: "Add Sensitive Word",
label_type: "Type",
label_content: "Content",
alert_message: "SamWaf firewall will block sensitive content",
type_option_0: "Not Selected",
type_option_1: "Type 1",
type_option_2: "Type 2",
type_option_3: "Type 3",
label_check_direction:"Detection Direction",
label_action:"Action",
check_direction_type:{
in:"Request",
out:"Response",
all:"All",
},
action_type:{
deny:"Deny",
replace:"Replace",
},
},
systemconfig: {
new_system_configuration: "Add New System Configuration",
label_configuration_item: "Configuration Item",
label_configuration_value: "Configuration Value"
},
ssl: {
alert_message: "SamWaf manages all certificate information",
label_cert_content: "Certificate file content (.crt file)",
label_key_content: "Key file content (.key file)",
button_submit: "Submit",
alert_success: "Submission successful!",
alert_error: "Submission failed!",
label_serial_no: "Certificate serial number",
label_subject: "Certificate subject",
label_issuer: "Issuer",
label_valid_from: "Certificate validity start time",
label_valid_to: "Certificate validity end time",
label_expire_time: "Expiration time",
label_domains: "Applicable domain names for the certificate",
label_auto_tip: "SamWaf will automatically extract the certificate information from the SSL file storage path below at 3 AM every day and back up the current certificate.",
label_auto_key_path: "Key File Path",
label_auto_crt_path: "Crt File Path",
},
batchtask: {
alert_message: "Automatically execute some batch operations, sequentially executed daily at 5 AM",
label_batch_task_name: "Task Name",
label_website: "Website",
label_batch_type: "Task Type",
label_batch_source_type: "Source Type",
label_batch_source: "Source Value",
label_batch_execute_method: "Execution Method",
label_remark: "Remarks",
label_btn_manual: "Manual Trigger",
label_confirm_message: "Are you sure you want to trigger manually?",
batch_type: {
add_ipallow: "Add Whitelist IP",
add_ipdeny: "Add DenyList IP",
},
batch_source_type: {
local: "Local Path",
remote: "Remote URL",
},
batch_execute_method: {
append: "Append",
overwrite: "Overwrite",
},
},
sslorder:{
alert_message:"Apply for a free certificate, the certificate is valid for 90 days. By default, it will automatically renew 30 days before expiration, or you can manually initiate renewal.",
label_website:"Host",
label_apply_status:"Application Status",
label_result_error:"Error Information",
label_apply_platform:"Application Platform",
label_apply_method:"Application Method",
label_apply_domain:"Application Domain",
label_apply_email:"Application Mail",
sslorder_status_type:{
submitted: "Submitted",
applying: "In Progress",
fail:"Failed",
success: "Successful",
renewed:"Renewed",
expired:"Expired",
},
sslorder_platform_type:{
letsencrypt: "Let's Encrypt",
},
sslorder_apply_method_type:{
http01: "File Verification Method",
},
error_domain_not_match_method: "Wildcard domains are not allowed under the file verification method",
},
ssl_expire:{
alert_message: "SamWaf domain certificate expiration check, scheduled to check all domains once every day at midnight.",
button_add_ssl_expire: "New",
button_check:"Check",
button_sync_host:"Sync Exist Host",
domain: "Domain",
port: "Port",
valid_to:"Valid Time",
visit_log: "VisitLog",
status: "Status",
},
blocking_page:{
alert_message: "SamWaf Custom Blocking Page",
button_add_blocking_page: "Create New",
blocking_page_name: "Custom Blocking Page Name",
blocking_type: "Custom Type",
host_code: "Website",
response_code: "Response Code",
response_header: "Response Header Information",
response_content: "Response Content",
},
http_auth_base:{
alert_message: "After enabled website password, please access with the password.",
button_add_http_auth_base: "New",
host_code: "Host",
user_name: "UserName",
password: "Password",
password_validation:"Password Not Normal"
},
task:{
alert_message: "SamWaf Task",
button_add_task: "New",
button_manual_execute: "Manual Execute",
task_name: "TaskName",
task_unit: "TaskUnit",
task_value: "TaskValue",
task_at: "TaskAt",
task_method: "TaskMethod",
task_unit_type:{
second:"Second",
minute:"Minute",
hour:"Hour",
day:"Day",
}
},
syslog: {
syslog: "System Log",
label_op_type: "Operation Type",
label_op_content: "Operation Content"
},
rule: {
button_add_rule: "Add New Rule",
label_website: "Website",
label_rule_name: "Rule Name",
label_rule_version: "Rule Version",
label_rule_status: "Rule Status",
alert_message: "SamWaf defense rules can be edited via scripts (preferred) or interface.",
rule_online_document: "Rule Editing Online Documentation",
rule_on: "Active",
rule_off: "Inactive",
detail: {
recommend_message: "It is recommended to automatically edit defense scripts by selecting feature values from (Log Details) with one click.",
jump_visit_log: "Go to Log List",
jump_online_document: "Defense Rules Online Documentation",
base_info: "Basic Information",
rule_name: "Rule Name",
rule_domain_code: "Protected Website",
rule_salience: "Protection Level",
rule_manual: "Protection Arrangement Method",
rule_dyn_add: "Add New",
relation: "Relation",
condition: "Condition",
built_in_entity_name: "Built-in Entity Name",
scope: "Scope",
value_type: "Value Type",
judgment: "Judgment",
value: "Value",
function_judgment_result: "Function Judgment Result",
assignment: "Assignment",
assignment_area: "Assignment Area",
assignment_detail: "Assignment Details",
method_execution: "Method Execution",
method_execution_area: "Method Execution Area",
method_details: "Method Details",
inner_method: "Built-in Method",
parameter: "Parameters",
write_rule: "Rule Arrangement",
system_variable: "System Variable",
ui_rule_edit: "UI Arrangement",
manual_code_rule_edit: "Manual Code Arrangement",
mf_option_default: "Default",
method_option: "Perform Action",
inner_option_host: "Host",
inner_option_url: "URL",
inner_option_referrer: "Referrer",
inner_option_user_agent: "User-Agent",
inner_option_method: "METHOD",
inner_option_cookies: "Cookies",
inner_option_body: "Body",
inner_option_port: "Request Port",
inner_option_src_ip: "Visitor IP",
inner_option_country: "Visitor Country",
inner_option_province: "Visitor Province",
inner_option_city: "Visitor City",
attr_type_text: "Text",
attr_type_int: "Number",
judge_equal: "Judge if Equal",
judge_not_equal: "Judge if Not Equal",
judge_greater_than: "Judge if Greater Than",
judge_less_than: "Judge if Less Than",
judge_greater_than_equal: "Judge if Greater Than or Equal",
judge_less_than_equal: "Judge if Less Than or Equal",
judge_contain: "Judge if Contains (Function)",
judge_has_prefix: "Judge if Starts With (Function)",
judge_has_suffix: "Judge if Ends With (Function)",
judge_logic_and: "And",
judge_logic_or: "Or",
variable_name: 'Variable Name',
variable_key: 'Variable Key',
tutorial_online:'Online Tutorial',
example_code: 'Rule Example Code',
}
},
notice: {
notice_title: "Notice",
clear: "Clear",
set_read: "Mark as Read",
empty: "No Notifications",
all: "View All"
},
gpt:{
assistant:"AI",
chat:{
chat_title: "Chat",
chat_placeholder: "Enter Content",
chat_send:"Send",
}
},
right_setting: {
page_setting: "Page Configuration",
theme_mode: "Theme Mode",
theme_color: "Theme Color",
navigation_layout: "Navigation Layout",
element_switches: "Element Switches",
fix_header: "Fixed Header",
fix_sidebar: "Fixed Sidebar",
show_header: "Show Header",
show_breadcrumb: "Show Breadcrumbs",
show_footer: "Show Footer",
use_tabs_router: "Use Multiple Tab Pages",
footer_position: "Footer Inner Collapse",
split_menu: "Split Menu (Effective in Mixed Mode)",
theme_mode_color_light:"Light",
theme_mode_color_dark:"Dark",
theme_mode_color_auto:"Auto",
}
},
};

@ -0,0 +1,15 @@
import Vue from "vue";
import VueI18n from "vue-i18n";
import zh_CN from "./zh_CN";
import en_US from "./en_US";
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: localStorage.getItem("lang") || "zh_CN", // 语言标识
messages: {
zh_CN, // 中文语言包
en_US, // 英文语言包
},
});
export default i18n;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save