【调整】增加部署雨云
2
frontend/.cursorindexingignore
Normal file
@@ -0,0 +1,2 @@
|
||||
# Don't index SpecStory auto-save files, but allow explicit context inclusion via @ references
|
||||
.specstory/**
|
||||
73
frontend/.doc/plugin-replace-name.md
Normal file
@@ -0,0 +1,73 @@
|
||||
### Vite 文件名称替换插件设计方案
|
||||
|
||||
#### 一、插件核心目标
|
||||
实现一个基于 Vite 的文件名称替换插件,通过 Node.js 文件系统 API,在开发或构建过程中根据预设规则自动重命名指定文件,支持灵活的匹配与替换逻辑。
|
||||
|
||||
#### 二、核心功能设计
|
||||
1. **规则配置系统**
|
||||
- 支持多组替换规则(从字符串/正则到目标字符串的映射)
|
||||
- 支持路径过滤(include 包含规则、exclude 排除规则)
|
||||
- 可配置执行时机(开发模式/构建模式/Watch 模式)
|
||||
|
||||
2. **文件处理流程**
|
||||
- 基于 Vite 插件钩子(configureServer、buildStart、watchChange 等)触发文件扫描
|
||||
- 递归遍历目标目录,收集符合匹配规则的文件路径
|
||||
- 对文件路径应用替换规则,生成新文件名
|
||||
- 执行文件重命名操作(含冲突检测)
|
||||
|
||||
3. **冲突处理机制**
|
||||
- 重命名前检查目标路径是否已存在
|
||||
- 提供冲突处理策略配置(跳过/覆盖/报错)
|
||||
- 记录操作日志,便于问题追踪
|
||||
|
||||
#### 三、实现架构
|
||||
1. **配置解析层**
|
||||
- 定义配置schema(规则格式、匹配模式、执行时机等)
|
||||
- 合并默认配置与用户配置
|
||||
- 验证配置有效性
|
||||
|
||||
2. **文件扫描层**
|
||||
- 基于 glob 模式匹配文件
|
||||
- 处理 include/exclude 过滤逻辑
|
||||
- 区分文件/目录类型
|
||||
|
||||
3. **规则应用层**
|
||||
- 实现字符串替换引擎(支持普通字符串和正则表达式)
|
||||
- 处理路径分割与重组(区分目录名和文件名)
|
||||
- 支持链式规则应用(多规则依次执行)
|
||||
|
||||
4. **文件操作层**
|
||||
- 封装 Node.js fs 模块(rename、stat、access 等)
|
||||
- 实现异步操作队列(避免并发冲突)
|
||||
- 添加操作事务支持(失败可回滚)
|
||||
|
||||
#### 四、Vite 集成点
|
||||
1. **开发模式集成**
|
||||
- 通过 configureServer 钩子初始化插件
|
||||
- 监听 server.watcher 事件处理文件新增/修改
|
||||
- 在服务器启动完成后执行初始扫描
|
||||
|
||||
2. **构建模式集成**
|
||||
- 在 buildStart 钩子触发预处理扫描
|
||||
- 通过 writeBundle 钩子处理输出目录文件
|
||||
- 配合 rollup 的 asset 处理钩子拦截资源生成
|
||||
|
||||
3. **插件生命周期**
|
||||
- 初始化:解析配置、注册钩子
|
||||
- 运行时:响应文件变化、执行重命名
|
||||
- 销毁:清理缓存、释放资源
|
||||
|
||||
#### 五、使用场景
|
||||
1. 统一文件命名规范(如驼峰转下划线)
|
||||
2. 批量添加/移除文件前缀/后缀
|
||||
3. 根据环境变量动态调整文件名
|
||||
4. 处理国际化资源文件命名
|
||||
5. 构建时生成带哈希值的文件名(补充 Vite 内置功能)
|
||||
|
||||
#### 六、扩展能力
|
||||
1. 支持自定义替换函数(用户可编写复杂逻辑)
|
||||
2. 提供预览模式(仅显示替换结果不执行实际操作)
|
||||
3. 支持配置文件导出/导入
|
||||
4. 集成 Vite 配置的 resolve.alias 路径解析
|
||||
|
||||
该方案通过分层设计保证了插件的灵活性和可扩展性,既满足基础的文件名替换需求,又能应对复杂的自定义场景,同时遵循 Vite 插件开发最佳实践确保良好的兼容性。
|
||||
150
frontend/.doc/plugin-sftp.md
Normal file
@@ -0,0 +1,150 @@
|
||||
### Vite 自动部署插件(FTP/SFTP)开发辅助方案
|
||||
|
||||
该方案专注于为开发者提供便捷、可靠的前端项目自动部署工具,通过 Vite 插件形式集成,实现构建完成后自动上传到远程服务器,减少手动部署的重复劳动与出错概率。
|
||||
|
||||
|
||||
#### 一、核心价值(开发辅助定位)
|
||||
1. **无缝集成开发流程**:与 Vite 构建流程深度融合,无需离开开发环境即可完成部署
|
||||
2. **降低环境切换成本**:统一本地配置与远程部署规则,避免"本地正常,线上出错"的环境差异问题
|
||||
3. **安全管理敏感信息**:通过环境变量隔离认证信息,防止密钥泄露
|
||||
4. **可视化部署反馈**:实时展示上传进度与结果,问题定位更高效
|
||||
5. **支持多环境部署**:一键切换开发/测试/生产环境配置,适配不同阶段部署需求
|
||||
|
||||
|
||||
#### 二、功能模块设计
|
||||
|
||||
##### 1. 基础配置模块
|
||||
- **核心参数**(必选):
|
||||
- 协议类型(`protocol: 'ftp' | 'sftp'`)
|
||||
- 服务器地址(`host`)、端口(`port`)
|
||||
- 认证信息(用户名+密码/私钥)
|
||||
- 本地目录(`localDir`)与远程目录(`remoteDir`)
|
||||
|
||||
- **环境区分配置**:
|
||||
```javascript
|
||||
// 示例:多环境配置
|
||||
environments: {
|
||||
dev: { host: 'dev.server.com', remoteDir: '/dev' },
|
||||
test: { host: 'test.server.com', remoteDir: '/test' },
|
||||
prod: { host: 'prod.server.com', remoteDir: '/prod' }
|
||||
}
|
||||
```
|
||||
支持通过命令行参数(`--env=prod`)快速切换环境
|
||||
|
||||
|
||||
##### 2. 智能上传模块
|
||||
- **增量上传机制**:
|
||||
- 基于文件哈希比对(默认 MD5),仅上传变更文件
|
||||
- 本地缓存已上传文件信息(`.upload-cache`目录),提速二次部署
|
||||
- 支持强制全量上传(`--force`命令行参数)
|
||||
|
||||
- **文件过滤系统**:
|
||||
- 基础过滤:glob 模式匹配(`include`/`exclude`)
|
||||
- 高级过滤:自定义函数(如根据文件大小/类型过滤)
|
||||
- 内置排除项:`.git`、`.DS_Store`、`.map`等开发相关文件
|
||||
|
||||
- **传输优化**:
|
||||
- 并发控制(默认 5 个文件同时上传,可配置)
|
||||
- 大文件分片传输(>10MB 自动分片,支持断点续传)
|
||||
- 传输模式自动选择(文本/二进制)
|
||||
|
||||
|
||||
##### 3. 开发友好特性
|
||||
- **实时反馈机制**:
|
||||
- 进度条展示:总进度、当前文件、传输速度
|
||||
- 详细日志输出:包含文件名、大小、状态(成功/失败)
|
||||
- 错误提示:明确指出失败原因(权限不足/文件不存在等)
|
||||
|
||||
- **调试辅助**:
|
||||
- 模拟上传模式(`dryRun: true`):仅展示上传列表,不实际传输
|
||||
- 调试日志(`verbose: 'debug'`):输出完整协议交互信息
|
||||
- 本地文件校验:上传前检查本地文件完整性
|
||||
|
||||
- **快捷操作**:
|
||||
- 独立部署命令:`vite deploy`(无需重新构建)
|
||||
- 配置验证命令:`vite deploy --validate`(检查配置合法性)
|
||||
- VS Code 插件集成:提供部署按钮与状态显示
|
||||
|
||||
|
||||
##### 4. 安全与容错模块
|
||||
- **敏感信息保护**:
|
||||
- 环境变量注入:`process.env.SFTP_PASSWORD`
|
||||
- 配置加密:支持对敏感字段加密存储
|
||||
- 日志脱敏:密码/私钥在日志中显示为`***`
|
||||
|
||||
- **容错机制**:
|
||||
- 自动重试:连接失败/传输超时自动重试(默认 3 次)
|
||||
- 断线续传:网络中断恢复后继续未完成的上传
|
||||
- 部分失败处理:单个文件失败不阻断整体流程,最终汇总失败列表
|
||||
|
||||
|
||||
##### 5. 扩展能力
|
||||
- **生命周期钩子**:
|
||||
```javascript
|
||||
hooks: {
|
||||
beforeDeploy: (config) => { /* 部署前执行,如备份远程文件 */ },
|
||||
afterDeploy: (result) => { /* 部署后执行,如发送通知 */ },
|
||||
onFileUploaded: (file) => { /* 单个文件上传完成 */ }
|
||||
}
|
||||
```
|
||||
|
||||
- **自定义处理器**:
|
||||
- 上传前文件处理(如压缩、替换环境变量)
|
||||
- 自定义远程操作(如上传后执行远程命令)
|
||||
|
||||
|
||||
#### 三、使用流程(开发视角)
|
||||
|
||||
1. **安装配置**:
|
||||
```bash
|
||||
npm i vite-plugin-deploy --save-dev
|
||||
```
|
||||
```javascript
|
||||
// vite.config.js
|
||||
import deploy from 'vite-plugin-deploy';
|
||||
|
||||
export default {
|
||||
plugins: [
|
||||
deploy({
|
||||
protocol: 'sftp',
|
||||
host: 'your.server.com',
|
||||
username: 'deploy',
|
||||
privateKey: process.env.SSH_PRIVATE_KEY,
|
||||
localDir: 'dist',
|
||||
remoteDir: '/var/www/html',
|
||||
environments: { /* 多环境配置 */ }
|
||||
})
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
2. **日常开发部署**:
|
||||
```bash
|
||||
# 构建并部署到默认环境
|
||||
npm run build
|
||||
|
||||
# 构建并部署到测试环境
|
||||
npm run build -- --env=test
|
||||
|
||||
# 仅部署(使用上次构建结果)
|
||||
npx vite deploy --env=prod
|
||||
|
||||
# 模拟部署(不实际上传)
|
||||
npx vite deploy --dry-run
|
||||
```
|
||||
|
||||
3. **问题排查**:
|
||||
- 查看终端输出的错误信息
|
||||
- 启用调试模式:`npx vite deploy --verbose=debug`
|
||||
- 检查`.upload-cache`目录的缓存文件与远程文件差异
|
||||
|
||||
|
||||
#### 四、优势总结(开发体验)
|
||||
1. **零学习成本**:配置简洁直观,符合前端开发者习惯
|
||||
2. **减少重复工作**:一次配置,后续部署无需重复操作
|
||||
3. **安全可靠**:避免手动操作导致的误删文件/配置错误
|
||||
4. **适配多场景**:从个人开发调试到团队生产部署均适用
|
||||
5. **可扩展性**:支持根据团队流程定制化扩展
|
||||
|
||||
|
||||
该方案通过聚焦开发效率与使用体验,将部署环节从"手动操作负担"转化为"自动化辅助工具",让开发者更专注于代码开发而非部署流程。
|
||||
11
frontend/.editorconfig
Normal file
@@ -0,0 +1,11 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
# 表示是最顶层的 EditorConfig 配置文件
|
||||
root = true
|
||||
[*] # 表示所有文件适用
|
||||
charset = utf-8 # 设置文件字符集为 utf-8
|
||||
indent_style = space # 缩进风格(tab | space)
|
||||
indent_size = 2 # 缩进大小
|
||||
end_of_line = lf # 控制换行类型(lf | cr | crlf)
|
||||
trim_trailing_whitespace = true # 去除行首的任意空白字符
|
||||
insert_final_newline = true # 始终在文件末尾插入一个新行
|
||||
trim_trailing_whitespace = true # 删除一行中的前后空格
|
||||
1
frontend/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
51
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# Dependencies
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Testing
|
||||
coverage
|
||||
|
||||
# Turbo
|
||||
.turbo
|
||||
|
||||
# Vercel
|
||||
.vercel
|
||||
|
||||
# Build Outputs
|
||||
.next/
|
||||
out/
|
||||
build
|
||||
dist
|
||||
|
||||
|
||||
# Debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
|
||||
.turbo
|
||||
pnpm-lock.yaml
|
||||
.specstory/**、
|
||||
|
||||
.sync-log
|
||||
.sync-log/**
|
||||
|
||||
.sync-git
|
||||
.sync-git/**
|
||||
|
||||
.cursor/rules
|
||||
269
frontend/.kiro/specs/vite-html-to-php-plugin/design.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# Design Document
|
||||
|
||||
## Overview
|
||||
|
||||
The Vite HTML to PHP Template plugin is a post-build transformation tool that converts standard HTML files into PHP template format. The plugin integrates with Vite's build lifecycle, executing after the build process completes to perform secondary transformations on generated HTML files. It uses HTML parsing to extract specific content sections and reorganizes them into a structured PHP template format compatible with template engines like ThinkPHP.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Plugin Architecture
|
||||
|
||||
The plugin follows Vite's plugin architecture pattern and implements the following hooks:
|
||||
|
||||
- **closeBundle**: Executes after the build is complete and all files are written
|
||||
- **buildEnd**: Fallback hook for error handling and cleanup
|
||||
|
||||
### Core Components
|
||||
|
||||
```
|
||||
vite-plugin-html-to-php-template/
|
||||
├── src/
|
||||
│ ├── index.ts # Main plugin entry point
|
||||
│ ├── parser.ts # HTML parsing and content extraction
|
||||
│ ├── template-generator.ts # PHP template generation
|
||||
│ ├── file-processor.ts # File system operations
|
||||
│ └── types.ts # TypeScript type definitions
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Components and Interfaces
|
||||
|
||||
### Plugin Interface
|
||||
|
||||
```typescript
|
||||
interface PluginOptions {
|
||||
// Input directory containing HTML files (default: 'dist')
|
||||
inputDir?: string;
|
||||
|
||||
// Output directory for PHP templates (default: same as inputDir)
|
||||
outputDir?: string;
|
||||
|
||||
// Glob pattern for HTML files to process (default: '**/*.html')
|
||||
include?: string | string[];
|
||||
|
||||
// Glob pattern for files to exclude (default: [])
|
||||
exclude?: string | string[];
|
||||
|
||||
// Template configuration
|
||||
template?: {
|
||||
extend?: string; // Default: 'main/newMain'
|
||||
blocks?: BlockConfig; // Block name mappings
|
||||
footer?: string; // Default: 'footer2'
|
||||
};
|
||||
|
||||
// Processing options
|
||||
preserveOriginal?: boolean; // Keep original HTML files (default: false)
|
||||
encoding?: string; // File encoding (default: 'utf-8')
|
||||
}
|
||||
|
||||
interface BlockConfig {
|
||||
title?: string; // Default: 'title'
|
||||
keywords?: string; // Default: 'keywords'
|
||||
description?: string; // Default: 'description'
|
||||
csslink?: string; // Default: 'csslink'
|
||||
main?: string; // Default: 'main'
|
||||
script?: string; // Default: 'script'
|
||||
}
|
||||
```
|
||||
|
||||
### HTML Parser Interface
|
||||
|
||||
```typescript
|
||||
interface ParsedContent {
|
||||
title: string;
|
||||
keywords: string;
|
||||
description: string;
|
||||
stylesheets: string[];
|
||||
scripts: string[];
|
||||
bodyContent: string;
|
||||
}
|
||||
|
||||
interface ParserOptions {
|
||||
preserveComments?: boolean;
|
||||
minifyContent?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### Template Generator Interface
|
||||
|
||||
```typescript
|
||||
interface TemplateConfig {
|
||||
extend: string;
|
||||
blocks: BlockConfig;
|
||||
footer: string;
|
||||
}
|
||||
|
||||
interface GeneratedTemplate {
|
||||
content: string;
|
||||
blocks: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Data Models
|
||||
|
||||
### HTML Content Extraction Model
|
||||
|
||||
The parser extracts content using the following mapping:
|
||||
|
||||
1. **Title**: `<title>` element text content
|
||||
2. **Keywords**: `<meta name="keywords" content="...">` attribute value
|
||||
3. **Description**: `<meta name="description" content="...">` attribute value
|
||||
4. **Stylesheets**: All `<link rel="stylesheet" ...>` elements (complete tags)
|
||||
5. **Scripts**: All `<script>` elements with `type="text/javascript"` or `type="module"` (complete tags)
|
||||
6. **Body Content**: Complete innerHTML of `<body>` element
|
||||
|
||||
### PHP Template Structure Model
|
||||
|
||||
```php
|
||||
<!-- 引入公共 -->
|
||||
{extend name="main/newMain"/}
|
||||
<!-- 标题 -->
|
||||
{block name="title"}[TITLE_CONTENT]{/block}
|
||||
<!-- 关键字 -->
|
||||
{block name="keywords"}[KEYWORDS_CONTENT]{/block}
|
||||
<!-- 描述 -->
|
||||
{block name="description"}[DESCRIPTION_CONTENT]{/block}
|
||||
<!-- 自定义css -->
|
||||
{block name="csslink"}
|
||||
[STYLESHEET_LINKS]
|
||||
{/block}
|
||||
<!-- 主体内容 -->
|
||||
{block name="main"}
|
||||
[BODY_CONTENT]
|
||||
{/block}
|
||||
<!-- 自定义js -->
|
||||
{block name="script"}
|
||||
[SCRIPT_TAGS]
|
||||
{/block}
|
||||
|
||||
<!-- 底部 -->
|
||||
{block name="footer2"}{/block}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Error Categories
|
||||
|
||||
1. **File System Errors**
|
||||
- File not found
|
||||
- Permission denied
|
||||
- Disk space issues
|
||||
|
||||
2. **HTML Parsing Errors**
|
||||
- Malformed HTML
|
||||
- Missing required elements
|
||||
- Encoding issues
|
||||
|
||||
3. **Template Generation Errors**
|
||||
- Invalid template configuration
|
||||
- Content encoding issues
|
||||
|
||||
### Error Handling Strategy
|
||||
|
||||
```typescript
|
||||
class PluginError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public code: string,
|
||||
public file?: string,
|
||||
public cause?: Error
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'ViteHtmlToPhpPluginError';
|
||||
}
|
||||
}
|
||||
|
||||
// Error codes
|
||||
enum ErrorCodes {
|
||||
FILE_NOT_FOUND = 'FILE_NOT_FOUND',
|
||||
PARSE_ERROR = 'PARSE_ERROR',
|
||||
TEMPLATE_ERROR = 'TEMPLATE_ERROR',
|
||||
CONFIG_ERROR = 'CONFIG_ERROR'
|
||||
}
|
||||
```
|
||||
|
||||
### Recovery Mechanisms
|
||||
|
||||
- **Graceful Degradation**: Continue processing other files when one fails
|
||||
- **Detailed Logging**: Provide file paths and line numbers in error messages
|
||||
- **Validation**: Validate configuration and input files before processing
|
||||
- **Rollback**: Option to preserve original files during processing
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
|
||||
1. **HTML Parser Tests**
|
||||
- Test extraction of each content type
|
||||
- Test handling of missing elements
|
||||
- Test malformed HTML scenarios
|
||||
- Test different HTML structures
|
||||
|
||||
2. **Template Generator Tests**
|
||||
- Test PHP template generation
|
||||
- Test custom block configurations
|
||||
- Test content escaping and encoding
|
||||
- Test template structure validation
|
||||
|
||||
3. **File Processor Tests**
|
||||
- Test file reading/writing operations
|
||||
- Test glob pattern matching
|
||||
- Test directory creation
|
||||
- Test error handling
|
||||
|
||||
### Integration Tests
|
||||
|
||||
1. **Plugin Integration**
|
||||
- Test with Vite build process
|
||||
- Test with different Vite configurations
|
||||
- Test with various HTML structures
|
||||
- Test error scenarios in build context
|
||||
|
||||
2. **End-to-End Tests**
|
||||
- Test complete HTML to PHP conversion
|
||||
- Test with real-world HTML files
|
||||
- Test configuration variations
|
||||
- Test performance with large files
|
||||
|
||||
### Test Data
|
||||
|
||||
Create test fixtures with:
|
||||
- Simple HTML files
|
||||
- Complex HTML with multiple scripts/styles
|
||||
- Malformed HTML files
|
||||
- HTML files with missing elements
|
||||
- HTML files with special characters
|
||||
- Large HTML files for performance testing
|
||||
|
||||
## Implementation Considerations
|
||||
|
||||
### Performance
|
||||
|
||||
- **Streaming**: Use streaming for large files
|
||||
- **Parallel Processing**: Process multiple files concurrently
|
||||
- **Memory Management**: Avoid loading entire files into memory when possible
|
||||
- **Caching**: Cache parsed templates for repeated builds
|
||||
|
||||
### Security
|
||||
|
||||
- **Path Traversal**: Validate file paths to prevent directory traversal
|
||||
- **Content Sanitization**: Ensure extracted content doesn't contain malicious code
|
||||
- **File Permissions**: Respect file system permissions
|
||||
|
||||
### Compatibility
|
||||
|
||||
- **Node.js Versions**: Support Node.js 16+
|
||||
- **Vite Versions**: Support Vite 4+ and 5+
|
||||
- **HTML Standards**: Support HTML5 and XHTML
|
||||
- **Encoding**: Support UTF-8 and other common encodings
|
||||
|
||||
### Extensibility
|
||||
|
||||
- **Plugin Hooks**: Allow custom processing hooks
|
||||
- **Template Customization**: Support custom template formats
|
||||
- **Content Processors**: Allow custom content transformation functions
|
||||
- **Output Formats**: Support different template engine formats
|
||||
75
frontend/.kiro/specs/vite-html-to-php-plugin/requirements.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Requirements Document
|
||||
|
||||
## Introduction
|
||||
|
||||
This feature involves creating a Vite plugin that converts standard HTML files into PHP template format. The plugin should execute after the build process is complete to perform secondary transformations on the generated HTML files. The target PHP template format follows a specific structure with blocks for different content sections (title, keywords, description, CSS links, main content, and scripts).
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1
|
||||
|
||||
**User Story:** As a developer, I want to automatically convert HTML files to PHP template format during the build process, so that I can integrate static HTML builds with PHP-based template systems.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN the Vite build process completes THEN the plugin SHALL automatically process HTML files in the output directory
|
||||
2. WHEN processing HTML files THEN the plugin SHALL extract content from specific HTML elements and place them in corresponding PHP template blocks
|
||||
3. WHEN the plugin runs THEN it SHALL execute as a post-build hook to ensure all HTML files are fully generated before processing
|
||||
|
||||
### Requirement 2
|
||||
|
||||
**User Story:** As a developer, I want the plugin to extract and organize different types of content from HTML files, so that the resulting PHP template has properly structured blocks.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN processing an HTML file THEN the plugin SHALL extract the title element content and place it in a `{block name="title"}` block
|
||||
2. WHEN processing meta tags THEN the plugin SHALL extract keywords meta content and place it in a `{block name="keywords"}` block
|
||||
3. WHEN processing meta tags THEN the plugin SHALL extract description meta content and place it in a `{block name="description"}` block
|
||||
4. WHEN processing link elements THEN the plugin SHALL extract stylesheet links and place them in a `{block name="csslink"}` block
|
||||
5. WHEN processing script elements THEN the plugin SHALL extract JavaScript content (both inline and external) and place it in a `{block name="script"}` block
|
||||
6. WHEN processing the body element THEN the plugin SHALL extract all body content and place it in a `{block name="main"}` block
|
||||
|
||||
### Requirement 3
|
||||
|
||||
**User Story:** As a developer, I want the plugin to handle different types of script and link elements correctly, so that all assets are properly extracted and organized.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN encountering script elements with `type="text/javascript"` THEN the plugin SHALL extract and include them in the script block
|
||||
2. WHEN encountering script elements with `type="module"` THEN the plugin SHALL extract and include them in the script block
|
||||
3. WHEN encountering link elements with `rel="stylesheet"` THEN the plugin SHALL extract and include them in the csslink block
|
||||
4. WHEN processing script or link elements THEN the plugin SHALL preserve all attributes and content exactly as they appear in the original HTML
|
||||
|
||||
### Requirement 4
|
||||
|
||||
**User Story:** As a developer, I want the generated PHP template to follow a consistent structure, so that it integrates seamlessly with existing PHP template systems.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN generating the PHP template THEN the plugin SHALL start with the extend directive `{extend name="main/newMain"/}`
|
||||
2. WHEN generating blocks THEN the plugin SHALL use the exact block syntax `{block name="blockname"}content{/block}`
|
||||
3. WHEN generating the template THEN the plugin SHALL include HTML comments to identify each section
|
||||
4. WHEN generating the template THEN the plugin SHALL end with the footer block `{block name="footer2"}{/block}`
|
||||
5. WHEN no content exists for a specific block THEN the plugin SHALL still create the block structure but leave it empty
|
||||
|
||||
### Requirement 5
|
||||
|
||||
**User Story:** As a developer, I want the plugin to be configurable, so that I can customize its behavior for different projects.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN initializing the plugin THEN it SHALL accept configuration options for input/output directories
|
||||
2. WHEN configured THEN the plugin SHALL allow specifying which HTML files to process (via glob patterns)
|
||||
3. WHEN configured THEN the plugin SHALL allow customizing the PHP template structure and block names
|
||||
4. WHEN no configuration is provided THEN the plugin SHALL use sensible defaults for all options
|
||||
|
||||
### Requirement 6
|
||||
|
||||
**User Story:** As a developer, I want the plugin to handle errors gracefully, so that build failures are informative and recoverable.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN encountering malformed HTML THEN the plugin SHALL log a warning and continue processing other files
|
||||
2. WHEN file system operations fail THEN the plugin SHALL throw descriptive errors with file paths and operation details
|
||||
3. WHEN HTML parsing fails THEN the plugin SHALL provide clear error messages indicating the problematic file and location
|
||||
4. WHEN the plugin encounters unexpected content THEN it SHALL handle it gracefully without breaking the build process
|
||||
114
frontend/.kiro/specs/vite-html-to-php-plugin/tasks.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Implementation Plan
|
||||
|
||||
- [x] 1. Set up project structure and core interfaces
|
||||
- Create directory structure for the plugin with src/, tests/, and configuration files
|
||||
- Define TypeScript interfaces for plugin options, parsed content, and template configuration
|
||||
- Set up package.json with dependencies (jsdom, glob, vite) and build scripts
|
||||
- Configure tsconfig.json for TypeScript compilation
|
||||
- _Requirements: 1.1, 5.1, 5.4_
|
||||
|
||||
- [x] 2. Implement HTML content parser
|
||||
- [x] 2.1 Create HTML parsing utilities
|
||||
- Write functions to parse HTML using jsdom and extract title, meta tags, and body content
|
||||
- Implement content extraction for title element, keywords meta, and description meta
|
||||
- Create unit tests for HTML parsing with various HTML structures
|
||||
- _Requirements: 2.1, 2.2, 2.3_
|
||||
|
||||
- [x] 2.2 Implement asset extraction functionality
|
||||
- Write functions to extract stylesheet link elements with proper attribute preservation
|
||||
- Implement script element extraction for both type="text/javascript" and type="module"
|
||||
- Create tests for asset extraction with different script and link configurations
|
||||
- _Requirements: 2.4, 2.5, 3.1, 3.2, 3.3, 3.4_
|
||||
|
||||
- [x] 2.3 Add error handling for HTML parsing
|
||||
- Implement graceful handling of malformed HTML with warning logs
|
||||
- Add validation for required HTML elements and provide fallbacks
|
||||
- Create tests for error scenarios including missing elements and invalid HTML
|
||||
- _Requirements: 6.1, 6.3_
|
||||
|
||||
- [x] 3. Create PHP template generator
|
||||
- [x] 3.1 Implement template structure generation
|
||||
- Write functions to generate PHP template with extend directive and block structure
|
||||
- Implement block content insertion for title, keywords, description, csslink, main, and script blocks
|
||||
- Create tests for template generation with various content combinations
|
||||
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5_
|
||||
|
||||
- [x] 3.2 Add template customization support
|
||||
- Implement configuration options for custom block names and template structure
|
||||
- Add support for custom extend directive and footer block configuration
|
||||
- Create tests for template customization with different configuration options
|
||||
- _Requirements: 5.3_
|
||||
|
||||
- [x] 4. Implement file processing operations
|
||||
- [x] 4.1 Create file system utilities
|
||||
- Write functions for reading HTML files with proper encoding support
|
||||
- Implement file writing operations for generated PHP templates
|
||||
- Add directory creation and file path validation utilities
|
||||
- Create tests for file operations including error scenarios
|
||||
- _Requirements: 6.2_
|
||||
|
||||
- [x] 4.2 Implement glob pattern matching
|
||||
- Add support for include/exclude glob patterns to filter HTML files
|
||||
- Implement file discovery functionality using glob patterns
|
||||
- Create tests for pattern matching with various file structures
|
||||
- _Requirements: 5.2_
|
||||
|
||||
- [x] 5. Create main plugin implementation
|
||||
- [x] 5.1 Implement Vite plugin interface
|
||||
- Create main plugin function that returns Vite plugin object
|
||||
- Implement closeBundle hook to execute after build completion
|
||||
- Add buildEnd hook for error handling and cleanup
|
||||
- Create integration tests with Vite build process
|
||||
- _Requirements: 1.1, 1.3_
|
||||
|
||||
- [x] 5.2 Integrate all components
|
||||
- Wire together HTML parser, template generator, and file processor
|
||||
- Implement main processing workflow that handles multiple HTML files
|
||||
- Add configuration validation and default option handling
|
||||
- Create end-to-end tests with complete HTML to PHP conversion
|
||||
- _Requirements: 1.2, 5.4_
|
||||
|
||||
- [ ] 6. Add comprehensive error handling
|
||||
- [x] 6.1 Implement error classes and codes
|
||||
- Create custom error classes with specific error codes for different failure types
|
||||
- Add detailed error messages with file paths and operation context
|
||||
- Implement error recovery mechanisms for continuing processing after failures
|
||||
- Create tests for all error scenarios and recovery mechanisms
|
||||
- _Requirements: 6.1, 6.2, 6.3, 6.4_
|
||||
|
||||
- [x] 6.2 Add logging and debugging support
|
||||
- Implement structured logging for processing steps and errors
|
||||
- Add debug mode with verbose output for troubleshooting
|
||||
- Create performance monitoring for processing large files
|
||||
- Add tests for logging functionality
|
||||
- _Requirements: 6.1, 6.3_
|
||||
|
||||
- [ ] 7. Create comprehensive test suite
|
||||
- [-] 7.1 Write unit tests for all components
|
||||
- Create test fixtures with various HTML file structures and edge cases
|
||||
- Write comprehensive tests for HTML parser with malformed and complex HTML
|
||||
- Add tests for template generator with different configurations
|
||||
- Test file processor with various file system scenarios
|
||||
- _Requirements: All requirements validation_
|
||||
|
||||
- [ ] 7.2 Implement integration and performance tests
|
||||
- Create integration tests with real Vite projects and build processes
|
||||
- Add performance tests with large HTML files and multiple file processing
|
||||
- Test plugin with different Vite configurations and environments
|
||||
- Create tests for concurrent file processing
|
||||
- _Requirements: All requirements validation_
|
||||
|
||||
- [ ] 8. Add documentation and examples
|
||||
- [ ] 8.1 Create comprehensive README
|
||||
- Write installation and usage instructions with code examples
|
||||
- Document all configuration options with detailed explanations
|
||||
- Add troubleshooting guide for common issues
|
||||
- Include examples of input HTML and output PHP templates
|
||||
- _Requirements: 5.1, 5.2, 5.3_
|
||||
|
||||
- [ ] 8.2 Create example projects
|
||||
- Build example Vite project demonstrating plugin usage
|
||||
- Create examples with different HTML structures and configurations
|
||||
- Add example showing integration with PHP template systems
|
||||
- Document best practices for using the plugin
|
||||
- _Requirements: All requirements demonstration_
|
||||
23
frontend/.kiro/steering/product.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Product Overview
|
||||
|
||||
This is a Baota (宝塔) Turborepo monorepo containing multiple web applications and shared packages for domain management, SSL certificate management, and cloud control systems.
|
||||
|
||||
## Key Applications
|
||||
|
||||
- **allin-ssl**: SSL certificate management application
|
||||
- **cloud-control**: Cloud infrastructure control panel
|
||||
- **domain-management-backend**: Domain management backend interface
|
||||
- **domain-official**: Official domain registration website
|
||||
- **naive-template**: Reusable template based on Naive UI
|
||||
|
||||
## Target Users
|
||||
|
||||
System administrators and developers managing web infrastructure, SSL certificates, and domain registrations through web-based control panels.
|
||||
|
||||
## Core Features
|
||||
|
||||
- SSL certificate lifecycle management
|
||||
- Domain registration and management
|
||||
- Cloud infrastructure monitoring and control
|
||||
- Multi-language support (i18n)
|
||||
- Real-time monitoring and analytics
|
||||
84
frontend/.kiro/steering/structure.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Project Structure
|
||||
|
||||
## Monorepo Organization
|
||||
|
||||
```
|
||||
├── apps/ # Applications
|
||||
├── packages/ # Shared packages
|
||||
├── plugin/ # Custom Vite plugins
|
||||
├── scripts/ # Build and utility scripts
|
||||
├── types/ # Global type definitions
|
||||
└── environment/ # Environment configurations
|
||||
```
|
||||
|
||||
## Application Structure (`apps/`)
|
||||
|
||||
Each app follows a consistent structure:
|
||||
|
||||
```
|
||||
apps/app-name/
|
||||
├── src/
|
||||
│ ├── api/ # API layer and HTTP clients
|
||||
│ ├── assets/ # Static assets (images, icons, fonts)
|
||||
│ ├── components/ # Reusable Vue components
|
||||
│ ├── config/ # App configuration
|
||||
│ ├── lib/ # App-specific utilities
|
||||
│ ├── locales/ # i18n translation files
|
||||
│ ├── router/ # Vue Router configuration
|
||||
│ ├── styles/ # Global styles and themes
|
||||
│ ├── types/ # TypeScript type definitions
|
||||
│ ├── views/ # Page components
|
||||
│ ├── App.tsx # Root component
|
||||
│ └── main.ts # Application entry point
|
||||
├── public/ # Public static files
|
||||
├── types/ # Generated type definitions
|
||||
├── mock/ # Mock data for development
|
||||
├── package.json
|
||||
├── vite.config.ts
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
## Shared Packages (`packages/`)
|
||||
|
||||
- **@baota/utils**: Common utilities (browser, data, string, crypto, etc.)
|
||||
- **@baota/vue/**: Vue-specific packages
|
||||
- `hooks/`: Composable functions
|
||||
- `i18n/`: Internationalization utilities
|
||||
- `naive-ui/`: Naive UI components and themes
|
||||
- `pinia/`: State management utilities
|
||||
- `router/`: Router utilities
|
||||
- `vite/`: Vite configuration helpers
|
||||
|
||||
## Custom Plugins (`plugin/`)
|
||||
|
||||
- **vite-plugin-i18n**: Translation file generation
|
||||
- **vite-plugin-ftp-sync**: FTP deployment automation
|
||||
- **vite-plugin-turborepo-deploy**: Git synchronization
|
||||
- **vite-plugin-html-to-php-template**: HTML to PHP conversion
|
||||
- **vite-plugin-timestamp-cache**: Cache busting utilities
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
- **Files**: kebab-case for directories, camelCase for TypeScript files
|
||||
- **Components**: PascalCase for Vue components (`.tsx` preferred)
|
||||
- **Views**: Organized by feature in `src/views/`
|
||||
- **API**: Grouped by domain in `src/api/`
|
||||
- **Types**: Descriptive names ending in `.d.ts`
|
||||
|
||||
## Path Aliases
|
||||
|
||||
Standard aliases used across apps:
|
||||
- `@/`: `src/` directory
|
||||
- `@api/`: `src/api/`
|
||||
- `@components/`: `src/components/`
|
||||
- `@views/`: `src/views/`
|
||||
- `@assets/`: `src/assets/`
|
||||
- `@types/`: `src/types/`
|
||||
- Feature-specific aliases (e.g., `@login/`, `@certManage/`)
|
||||
|
||||
## Architecture Patterns
|
||||
|
||||
- **MVC Separation**: Separate state (stores), controllers (composables), and views
|
||||
- **Composition API**: Use `<script setup>` syntax
|
||||
- **TSX Components**: Prefer `.tsx` over `.vue` for complex components
|
||||
- **Feature-based Organization**: Group related files by feature/domain
|
||||
60
frontend/.kiro/steering/tech.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Technology Stack
|
||||
|
||||
## Build System & Package Management
|
||||
- **Monorepo**: Turborepo for build orchestration and caching
|
||||
- **Package Manager**: pnpm (v10.14.0+)
|
||||
- **Node.js**: >= 18
|
||||
- **Build Tool**: Vite for fast development and optimized builds
|
||||
|
||||
## Frontend Stack
|
||||
- **Framework**: Vue 3 with Composition API and `<script setup>` syntax
|
||||
- **Language**: TypeScript (ES2022 target)
|
||||
- **Syntax**: TSX for Vue components (`.tsx` files preferred)
|
||||
- **UI Library**: Naive UI
|
||||
- **Styling**: Tailwind CSS + CSS Modules
|
||||
- **State Management**: Pinia with persistence plugin
|
||||
- **Routing**: Vue Router
|
||||
- **Utilities**: VueUse, Axios for HTTP requests
|
||||
|
||||
## Development Tools
|
||||
- **Linting**: ESLint with Vue and TypeScript support
|
||||
- **Formatting**: Prettier
|
||||
- **Testing**: Vitest
|
||||
- **Type Checking**: vue-tsc
|
||||
- **Auto-imports**: unplugin-auto-import for Vue APIs
|
||||
- **Component Auto-import**: unplugin-vue-components with Naive UI resolver
|
||||
|
||||
## Custom Plugins
|
||||
- **@baota/vite-plugin-i18n**: Internationalization generator
|
||||
- **@baota/vite-plugin-ftp-sync**: FTP deployment synchronization
|
||||
- **@baota/vite-plugin-turborepo-deploy**: Git project synchronization
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Development
|
||||
pnpm dev # Start all apps
|
||||
pnpm dev --filter app-name # Start specific app
|
||||
|
||||
# Building
|
||||
pnpm build # Build all apps
|
||||
pnpm build --filter app-name # Build specific app
|
||||
|
||||
# Testing & Quality
|
||||
pnpm test # Run tests
|
||||
pnpm lint # Lint all code
|
||||
pnpm check-types # Type checking
|
||||
pnpm format # Format code
|
||||
|
||||
# Utilities
|
||||
pnpm clear # Clean temp files
|
||||
pnpm sync # Sync project files
|
||||
```
|
||||
|
||||
## Workspace Structure
|
||||
- Apps use `workspace:*` dependencies for internal packages
|
||||
- Shared packages under `@baota/` namespace
|
||||
- All packages support both ESM and CJS exports
|
||||
0
frontend/.npmrc
Normal file
20
frontend/.specstory/history/2025-04-09_02-41-untitled.md
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- Generated by SpecStory -->
|
||||
|
||||
# Untitled (2025-04-09 10:41:01)
|
||||
|
||||
_**User**_
|
||||
|
||||
帮我生成使用文档
|
||||
|
||||
---
|
||||
|
||||
_**Assistant**_
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
20
frontend/.specstory/history/2025-04-09_03-12-untitled.md
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- Generated by SpecStory -->
|
||||
|
||||
# Untitled (2025-04-09 11:12:11)
|
||||
|
||||
_**User**_
|
||||
|
||||
@c:\Users\bt.cn\Desktop\3.md @c:\Users\bt.cn\Desktop\185f44b4f7f1b369445fe4cbbb4fb2dd_e21ed6944c898de8a6346108a7a1bc00_8.md ,结合代码整洁之道,完善3.md的答案
|
||||
|
||||
---
|
||||
|
||||
_**Assistant**_
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
18
frontend/.sync-project-config.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# 工具配置
|
||||
config:
|
||||
parallel_build: false # 是否并行编译
|
||||
dry_run: false # 是否干运行
|
||||
|
||||
# 工作区配置
|
||||
workspaces:
|
||||
# 示例工作区配置
|
||||
# app-name:
|
||||
# sync_mappings:
|
||||
# - source:
|
||||
# git_url: "https://github.com/user/repo.git" # Git 仓库地址
|
||||
# branch: "main" # 分支名称
|
||||
# alias: "repo-name" # 仓库别名(可选)
|
||||
# target:
|
||||
# sync_dir: "dist" # 要同步的目录
|
||||
# git_dir: "dist" # Git 仓库中的目标目录
|
||||
|
||||
0
frontend/.sync-project-history
Normal file
0
frontend/.trae/.ignore
Normal file
0
frontend/.trae/rules/project_rules.md
Normal file
107
frontend/README.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# 宝塔 Turborepo 项目
|
||||
|
||||
基于 Turborepo 构建的多项目工作空间,包含多个应用和共享包。
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **构建工具**: Turborepo、Vite
|
||||
- **前端框架**: Vue 3
|
||||
- **语言**: TypeScript
|
||||
- **样式**: Tailwind CSS、CSS Modules
|
||||
- **UI 组件库**: Naive UI
|
||||
- **状态管理**: Pinia
|
||||
- **路由**: Vue Router
|
||||
- **工具库**: VueUse、Axios
|
||||
- **包管理器**: pnpm
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
.
|
||||
├── apps/ # 应用目录
|
||||
│ ├── allin-ssl/ # SSL 管理应用
|
||||
│ ├── cloud-control/ # 云控制应用
|
||||
│ ├── monorepo-docs/ # 项目文档应用
|
||||
│ ├── naive-template/ # Naive UI 模板
|
||||
│ └── vueFlow/ # Vue Flow 应用示例
|
||||
├── packages/ # 共享包目录
|
||||
│ ├── utils/ # 通用工具函数
|
||||
│ ├── vue/ # Vue 相关组件和工具
|
||||
│ ├── react/ # React 相关组件和工具
|
||||
│ ├── svelte/ # Svelte 相关组件和工具
|
||||
│ └── node/ # Node.js 相关工具
|
||||
├── environment/ # 环境配置
|
||||
├── plugin/ # 自定义插件
|
||||
├── scripts/ # 脚本工具
|
||||
├── types/ # 全局类型定义
|
||||
└── ...
|
||||
```
|
||||
|
||||
## 主要应用
|
||||
|
||||
### Cloud Control
|
||||
|
||||
云控制应用是本项目的主要应用之一,基于 Vue 3、TypeScript 和 Vite 构建。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Node.js >= 18
|
||||
- pnpm 9.0.0+
|
||||
|
||||
### 安装依赖
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### 启动开发环境
|
||||
|
||||
```bash
|
||||
# 初次运行,请先执行pnpm build 编译当前的整个应用包的依赖库
|
||||
pnpm build
|
||||
```
|
||||
|
||||
```bash
|
||||
# 启动所有应用
|
||||
pnpm dev
|
||||
|
||||
# 启动指定应用-例如allin-ssl
|
||||
pnpm dev --filter allin-ssl
|
||||
|
||||
|
||||
### 构建项目
|
||||
|
||||
```bash
|
||||
# 构建所有应用
|
||||
pnpm build
|
||||
|
||||
# 构建指定应用-例如allin-ssl
|
||||
pnpm build --filter allin-ssl
|
||||
|
||||
```
|
||||
|
||||
### 其他命令
|
||||
|
||||
```bash
|
||||
# 代码检查
|
||||
pnpm lint
|
||||
|
||||
# 清理项目包
|
||||
pnpm clear
|
||||
|
||||
```
|
||||
|
||||
## 开发规范
|
||||
|
||||
- 使用 TypeScript 编写所有代码
|
||||
- 遵循函数式编程和声明式编程模式
|
||||
- 使用 Vue 3 的 Composition API 和 `<script setup>` 语法
|
||||
- 遵循 MVC 分离模式,区分状态 (useStore.tsx)、控制器 (useController.tsx) 和视图 (index.tsx)
|
||||
- 使用 TSX 语法编写 Vue 组件,文件使用 .tsx 后缀
|
||||
- 使用 JSDoc 注释函数、参数和返回值
|
||||
|
||||
## 贡献指南
|
||||
|
||||
欢迎提交 Pull Request 或提出 Issue。在贡献代码前,请确保遵循项目的代码风格和开发规范。
|
||||
131
frontend/apps/allin-ssl/README.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# AllinSSL
|
||||
|
||||
AllinSSL 是一个基于 Vue 3 和 TypeScript 开发的 SSL 证书管理平台,旨在简化 SSL 证书的申请、部署、监控和管理流程。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- **证书管理**:集中管理所有 SSL 证书,包括证书信息查看、状态监控和到期提醒
|
||||
- **证书申请**:简化 SSL 证书申请流程,支持多种类型证书的快速申请
|
||||
- **自动部署**:支持证书的自动化部署到不同的服务器和环境
|
||||
- **监控系统**:实时监控证书状态,提供证书健康度和到期预警
|
||||
- **API 管理**:提供 API 接口管理功能,支持与其他系统集成
|
||||
- **多语言支持**:内置国际化支持,可扩展多种语言
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **前端框架**:Vue 3 + TypeScript + TSX
|
||||
- **状态管理**:Pinia
|
||||
- **路由管理**:Vue Router
|
||||
- **UI 组件库**:Naive UI
|
||||
- **工具库**:VueUse
|
||||
- **CSS 框架**:Tailwind CSS
|
||||
- **构建工具**:Vite
|
||||
- **包管理**:Turborepo (Monorepo 结构)
|
||||
|
||||
## 开发环境设置
|
||||
|
||||
### 前提条件
|
||||
|
||||
- Node.js (v16+)
|
||||
- npm 或 yarn 或 pnpm
|
||||
|
||||
### 安装依赖
|
||||
|
||||
```bash
|
||||
npm install
|
||||
# 或
|
||||
yarn install
|
||||
# 或
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### 开发服务器启动
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# 或
|
||||
yarn dev
|
||||
# 或
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
应用将在本地 `http://localhost:5173` 启动。
|
||||
|
||||
## 构建部署
|
||||
|
||||
### 构建生产版本
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
# 或
|
||||
yarn build
|
||||
# 或
|
||||
pnpm build
|
||||
```
|
||||
|
||||
构建后的文件将生成在 `dist` 目录中。
|
||||
|
||||
### 预览构建结果
|
||||
|
||||
```bash
|
||||
npm run preview
|
||||
# 或
|
||||
yarn preview
|
||||
# 或
|
||||
pnpm preview
|
||||
```
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── api/ # API 接口定义
|
||||
├── assets/ # 静态资源
|
||||
├── components/ # 公共组件
|
||||
├── config/ # 全局配置
|
||||
├── lib/ # 工具库和功能函数
|
||||
├── locales/ # 国际化语言文件
|
||||
├── router/ # 路由配置
|
||||
├── styles/ # 全局样式文件
|
||||
├── types/ # TypeScript 类型定义
|
||||
├── views/ # 页面视图组件
|
||||
│ ├── certApply/ # 证书申请
|
||||
│ ├── certManage/ # 证书管理
|
||||
│ ├── autoDeploy/ # 自动部署
|
||||
│ ├── monitor/ # 监控系统
|
||||
│ ├── settings/ # 系统设置
|
||||
│ ├── layout/ # 布局组件
|
||||
│ ├── login/ # 登录页面
|
||||
│ └── home/ # 首页
|
||||
├── App.tsx # 根组件
|
||||
└── main.ts # 应用入口
|
||||
```
|
||||
|
||||
## 代码规范
|
||||
|
||||
项目采用 ESLint 和 Prettier 进行代码规范控制,确保代码风格统一。
|
||||
|
||||
```bash
|
||||
# 运行代码检查
|
||||
npm run lint
|
||||
# 或
|
||||
yarn lint
|
||||
# 或
|
||||
pnpm lint
|
||||
```
|
||||
|
||||
## 项目特点
|
||||
|
||||
- 采用 Vue 3 Composition API 和 TSX 语法
|
||||
- MVC 分离模式:将状态 (useStore.tsx)、控制器 (useController.tsx) 和视图 (index.tsx) 区分开来
|
||||
- 使用 Tailwind CSS 实现响应式设计
|
||||
- 基于 Vite 的高性能构建系统
|
||||
- Monorepo 结构,便于多包协同开发
|
||||
|
||||
## 贡献指南
|
||||
|
||||
欢迎贡献代码,请确保遵循以下准则:
|
||||
|
||||
1. 遵循项目已有的代码风格和命名规范
|
||||
2. 提交前进行代码检查和测试
|
||||
3. 提交消息遵循规范化提交格式
|
||||
11748
frontend/apps/allin-ssl/cache/translation_cache.json
vendored
Normal file
22
frontend/apps/allin-ssl/eslint.config.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import vueConfig from '@baota/eslint/vue'
|
||||
import baseConfig from '@baota/eslint'
|
||||
|
||||
/** @type {import("eslint").Linter.Config[]} */
|
||||
const config = [
|
||||
// Vue 相关配置,包含 TypeScript 支持
|
||||
...vueConfig,
|
||||
|
||||
// 基础配置,用于通用的 JavaScript/TypeScript 规则
|
||||
...baseConfig,
|
||||
|
||||
// 项目特定的配置覆盖
|
||||
{
|
||||
files: ['**/*.{js,ts,tsx,jsx,vue}'],
|
||||
rules: {
|
||||
// 在此处添加项目特定的规则覆盖
|
||||
'vue/multi-word-component-names': 'off', // 关闭组件名称必须由多个单词组成的规则
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export default config
|
||||
13
frontend/apps/allin-ssl/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>AllinSSL</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
28
frontend/apps/allin-ssl/mardown/api.md
Normal file
@@ -0,0 +1,28 @@
|
||||
分别生成以下相关的类型文件,在 types/ 目录下,以及 api 文件,在 api/目录下
|
||||
|
||||
文件名称如下:
|
||||
home
|
||||
autoDeploy
|
||||
certManage
|
||||
certApply
|
||||
authAPIManage
|
||||
monitor
|
||||
settings
|
||||
|
||||
1、types文件命名方式:{视图名称}.d.ts
|
||||
|
||||
2、api文件命名方式:{视图名称}.ts
|
||||
|
||||
3、api文件结构如下:
|
||||
|
||||
```typescript
|
||||
import { useApi } from './index'
|
||||
import type { loginParams, loginResponse } from '@/types/public'
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param params 登录参数
|
||||
* @returns 登录
|
||||
*/
|
||||
export const loginCloudControl = (params?: loginParams) => useApi<loginResponse, loginParams>('/v1/user/login', params)
|
||||
```
|
||||
273
frontend/apps/allin-ssl/mardown/base.md
Normal file
@@ -0,0 +1,273 @@
|
||||
|
||||
|
||||
目前接口返回格式
|
||||
```ts
|
||||
export interface AxiosResponseData<T = unknown> {
|
||||
code: number
|
||||
count: number
|
||||
data: T
|
||||
message: string
|
||||
status: boolean
|
||||
}
|
||||
```
|
||||
|
||||
后端请求的协议方式,formdata 还是 json
|
||||
|
||||
登录的方式,使用那种方案jwt,以及加密方式
|
||||
|
||||
接口文档需要包含一下内容
|
||||
接口类型、接口返回值、以及其他需要处理的内容需要说清楚,例如登录失效,以及状态的判断
|
||||
|
||||
|
||||
|
||||
|
||||
基础要求
|
||||
1、基于vue3 的 tsx文件编写,并将业务和数据、视图分离成 mvc 模式,如果代码中没有包含业务和数据,可以移除该文件,确保结构单一和可维护性。
|
||||
2、视图文件文件入口为 index.tsx
|
||||
3、业务代码文件入口为 useController.tsx
|
||||
4、数据代码文件入口为 useStore.tsx
|
||||
5、使用hooks编写,如果存在表单、表格使用配置生成。参考如下
|
||||
|
||||
|
||||
视图文件内容要求
|
||||
1、所有的视图style,使用css module 编写,基于tailwind 的@apply 实现,如果行内元素少,可以省略创建css module。
|
||||
2、如果视图使用naiveui tsx 开发内容,如果没有相应的组件,则使用原生样式实现
|
||||
|
||||
业务代码内容要求
|
||||
1、包含 hooks 配置的生成方法,需要导出
|
||||
2、事件逻辑处理、dom 操作、生命周期、监听函数等,
|
||||
3、数据代码转发,支持将 sotre 数据直接转发
|
||||
|
||||
数据代码内容要求
|
||||
1、包含所有的数据内容,例如请求方法、表单数据处理
|
||||
2、响应式数据存储、持久化数据存储
|
||||
|
||||
国际化内容要求
|
||||
1、将文件中的中文文本未使用 $t 包裹的内容,使用 $t('中文内容') 包裹起来,如果存在则引入 $t,import { $t } from "@locales/index"
|
||||
|
||||
格式要求
|
||||
1、注释采用jsdoc格式,使用中文作为注释语言
|
||||
2、注释内容清晰,对同类的函数位置整理和功能使用注释分割线分
|
||||
3、方法名称规范化,根据类型和作用定义。
|
||||
|
||||
|
||||
|
||||
|
||||
基础视图参考:/Users/chudong/project/tools-monorepo/apps/allin-ssl/src/components/baseComponent/index.tsx
|
||||
|
||||
|
||||
首页模块设计
|
||||
1、界面设计
|
||||
包含三个模块,采用上下结构
|
||||
* 概览模块包含工作流、证书、监控模块,每个模块,都具备所有数量、启用/到期/异常数量、失败/到期数量,以及对应产品图标
|
||||
* 最近工作流执行列表,包含字段:
|
||||
* 名称
|
||||
* 执行状态
|
||||
* 执行时间
|
||||
* 快捷入口模块,提供常用的三个模块入口,工作流构建、申请证书、添加监控
|
||||
|
||||
2、接口设计包含
|
||||
* 概览数据接口
|
||||
* 最近工作流列表
|
||||
|
||||
工作流列表模块设计
|
||||
1、界面设计
|
||||
采用基础视图组件设计该页面,传入相关内容,
|
||||
* 添加按钮文本:新增工作流
|
||||
* 搜索框提示内容:请输入工作流名称
|
||||
* 表格包含字段:
|
||||
* 工作流名称
|
||||
* 触发方式(自动执行或手动可切换)
|
||||
* 启用状态(启用/停用)
|
||||
* 最后一次执行时间
|
||||
* 创建时间
|
||||
* 操作(包含日志、执行、编辑、删除)
|
||||
* 添加工作流按钮触发弹窗内容
|
||||
* 弹窗界面包含多个具备概览图的单选项
|
||||
* 常用SSL部署工作流
|
||||
* 自定义工作流
|
||||
|
||||
2、接口设计包含
|
||||
* 工作流列表
|
||||
* 获取指定工作流程数据
|
||||
* 新建自定义工作流程数据
|
||||
* 获取指定工作流执行日志
|
||||
* 执行指定工作流
|
||||
* 保存指定工作流程数据
|
||||
* 删除指定工作流程数据
|
||||
|
||||
|
||||
工作流设计模块设计
|
||||
1、界面设计
|
||||
采用流程图构建组建,设计页面,需要设计一下节点设计,所有节点采用
|
||||
* 申请SSL(表单设计)
|
||||
* 域名信息(input、必填)
|
||||
* 邮箱信息(input、非必填)
|
||||
* DNS 提供商(select,支持添加,添加调用 API 授权页面的添加表单)
|
||||
* 高级选项折叠
|
||||
* 数字证书算法(select,支持字段RSA2048\RSA3072\RSA4096\RSA8192\EC256\EC384,默认使用RSA2048\)
|
||||
* 指定DNS解析服务器(input,非必填,提示:申请证书过程中优先使用它)
|
||||
* DNS超时时间(input、非必填)
|
||||
* DNS解析TTL时间(input、非必填)
|
||||
* 关闭CNAME跟随(switch,默认关闭)
|
||||
* 关闭ARI续期(switch,默认关闭)
|
||||
* 续签间隔(input,当上次签发的证书距离到期时间超过xx天后,跳过续签,使用 )
|
||||
* 部署SSL到指定位置(表单设计,需要手动开发,使用 AI 生成消耗时间,而且基本上可用性低)
|
||||
*
|
||||
* 通知告警
|
||||
* 通知主题(input、必填)
|
||||
* 通知内容(textarea、必填)
|
||||
* 选择通知渠道(select,右侧支持添加渠道)
|
||||
*
|
||||
* 并行分支
|
||||
* 触发并行添加节点的功能
|
||||
* 执行结果分支(只有节点是申请SSL、部署SSL到指定位置、通知告警节点后面才出现此分支提供选择)
|
||||
* 触发条件判断分支,仅事件触发的节点支持添加该节点
|
||||
* 节点执行成功后
|
||||
* 节点执行失败后
|
||||
|
||||
2、接口设计包含
|
||||
* 获取API服务商列表
|
||||
* 获取证书列表
|
||||
* 获取网站列表(宝塔面板)
|
||||
* 获取 CDN 加速域名(仅腾讯、阿里相关密钥获取)
|
||||
* 获取 WAF 包含域名(仅腾讯、阿里相关密钥获取)
|
||||
|
||||
|
||||
证书管理列表模块设计
|
||||
1、界面设计
|
||||
采用基础视图组件设计该页面,传入相关内容,
|
||||
* 添加按钮文本:上传证书
|
||||
* 搜索框提示内容:请输入证书名称/类型
|
||||
* 表格包含字段:
|
||||
* 域名
|
||||
* 品牌
|
||||
* 剩余天数
|
||||
* 到期时间
|
||||
* 来源
|
||||
* 添加时间
|
||||
* 操作(下载、删除)
|
||||
* 上传证书按钮触发弹窗内容
|
||||
* 弹窗界面包含表单(支持证书压缩上传,识别腾讯、阿里下的证书压缩包文件)
|
||||
* 证书名称
|
||||
* 证书内容 (PEM 格式)
|
||||
* 私钥内容 (KEY 格式)
|
||||
|
||||
2、接口设计包含
|
||||
* 获取证书列表
|
||||
* 下载指定证书
|
||||
* 上传证书信息
|
||||
* 删除指定证书信息
|
||||
|
||||
|
||||
|
||||
申请证书模块模块设计
|
||||
1、界面设计
|
||||
采用 tab 页面切换,分为商业证书页面和免费证书页面
|
||||
* 商业证书采用,iframe 内嵌官网页面,官网页面需要新增一个界面作为兼容页面。
|
||||
* 免费证书采用,卡片式设计界面,以便于后期支持其他渠道
|
||||
* 证书申请表单
|
||||
* 手动申请和自动部署的选项卡片(包含 icon 和文件描述)
|
||||
* 手动申请,采用 DNS 验证自动认证的方式,参考面板的统一设计
|
||||
* 自动化部署,直接调用工作流的界面。
|
||||
|
||||
2、接口设计包含
|
||||
* 申请证书信息
|
||||
* 证书验证接口
|
||||
|
||||
|
||||
授权API管理列表模块设计
|
||||
1、界面设计
|
||||
采用基础视图组件设计该页面,传入相关内容,
|
||||
* 添加按钮文本:上传授权 API 管理
|
||||
* 搜索框提示内容:请输入授权api 名称或类型
|
||||
* 表格包含字段:
|
||||
* 名称
|
||||
* 授权API类型(提供商,如腾讯云,宝塔面板)
|
||||
* 创建时间
|
||||
* 操作(编辑、删除)
|
||||
* 上传证书按钮触发弹窗内容
|
||||
* 弹窗界面包含表单
|
||||
* 授权 API 类型(select,支持类型 SSH、宝塔、1panel、腾讯、阿里)
|
||||
* 不同的类型显示不同的东西
|
||||
* SSH
|
||||
* 服务器IP(input)
|
||||
* SSH端口(input,默认填充22)
|
||||
* 用户名(input,默认填充root)
|
||||
* 验证类型(radio-button)
|
||||
1. 密码
|
||||
2. SSH密钥
|
||||
1. SSH密钥口令
|
||||
* 宝塔
|
||||
* 地址(input,包含协议和端口)
|
||||
* api 密钥(input)
|
||||
* 1panel
|
||||
* 地址(input,包含协议和端口)
|
||||
* api 密钥(input)
|
||||
* 阿里云
|
||||
* AccessKeyId(input)
|
||||
* AccessKeySecret(input)
|
||||
* 腾讯云
|
||||
* SecretId(input)
|
||||
* SecretKey(input)
|
||||
|
||||
2、接口设计包含
|
||||
* 获取授权 api 列表
|
||||
* 新建授权 api 信息
|
||||
* 编辑指定授权 aai 信息
|
||||
* 删除指定授权 api 信息
|
||||
|
||||
|
||||
监控管理列表模块设计
|
||||
1、界面设计
|
||||
采用基础视图组件设计该页面,传入相关内容,
|
||||
* 添加按钮文本:添加监控
|
||||
* 搜索框提示内容:请输入监控名称和域名
|
||||
* 表格包含字段:
|
||||
* 名称
|
||||
* 授权API类型(提供商,如腾讯云,宝塔面板)
|
||||
* 创建时间
|
||||
* 操作(编辑、删除)
|
||||
* 上传证书按钮触发弹窗内容
|
||||
* 弹窗界面包含表单
|
||||
* 监控名称(input)
|
||||
* 域名/IP(input)
|
||||
* 检查周期(select,5/10/15/30/60分钟)
|
||||
* 告警渠道(多选,右侧支持添加渠道)
|
||||
2、接口设计包含
|
||||
* 获取监控管理列表
|
||||
* 设置指定监控启动状态
|
||||
* 添加监控信息
|
||||
* 编辑指定监控信息
|
||||
* 删除指定监控信息
|
||||
|
||||
|
||||
设置管理模块设置
|
||||
1、界面设置
|
||||
采用 tab 页面切换,分为三个界面常用设置、告警通知、更新版本,内容部分采用卡片设计
|
||||
* 常用设置(采用1:1 分栏设计,支持表单元素行显示),包含一下具体模块,采用统一保存的方式,保存按钮固定在顶部,避免设置过长的导致问题
|
||||
* 超时时间(input)
|
||||
* 管理员账号(input)
|
||||
* 管理员密码(input)
|
||||
* SSL 配置(switch,关闭,提供粘贴 key,pem 文本域输入,默认折叠隐藏)
|
||||
* 告警通知(采用上下结构),包含全局通知模块和通知渠道配置两个模块
|
||||
* 全局通知模块(表单)
|
||||
* 通知主题(input,默认文字)
|
||||
* 通知内容(textarea,默认文字)
|
||||
* 通知渠道(卡片列表,参考面板的设计)
|
||||
* 左侧图标名称(包含已配置数量,点击可查看)+右侧操作
|
||||
* 关于我们
|
||||
* 版本信息,支持更新版本
|
||||
* 客服二维码
|
||||
* 微信公众好
|
||||
* 关于产品介绍
|
||||
|
||||
2、接口设计包含
|
||||
* 获取基础设置信息
|
||||
* 保存基础设置信息
|
||||
* 获取告警通用模板配置
|
||||
* 设置告警通用模板配置
|
||||
* 获取告警渠道列表
|
||||
* 设置告警渠道
|
||||
* 获取更新信息
|
||||
* 更新版本版本
|
||||
70
frontend/apps/allin-ssl/mardown/flowChart.md
Normal file
@@ -0,0 +1,70 @@
|
||||
流程/工作流图拆封设计
|
||||
|
||||
- 基础节点
|
||||
- 初始化节点(不支持上传)
|
||||
- 并行节点
|
||||
- 执行结果节点(删除整个条件判断)
|
||||
|
||||
- 任务节点
|
||||
- 申请节点(支持执行结果判断)
|
||||
- 上传节点(不支持执行结果判断)
|
||||
- 部署节点(支持执行结果判断)
|
||||
- 通知节点(支持执行结果判断)
|
||||
|
||||
- 节点操作
|
||||
- 重命名
|
||||
- 删除
|
||||
|
||||
- 节点下一步配置
|
||||
- 申请
|
||||
- 上传
|
||||
- 部署
|
||||
- 通知
|
||||
- 执行结果判断(上传节点不支持)
|
||||
- 并行
|
||||
|
||||
- 节点辅助功能
|
||||
- 拖拽
|
||||
- 放大、缩小、还原
|
||||
|
||||
- 节点验证
|
||||
- 验证任务节点
|
||||
|
||||
结构规划
|
||||
- 状态存储(包含节点默认配置数据)
|
||||
- 基础节点
|
||||
- 任务节点(可以根据外部的机构自由的构建任务节点,主要有节点条件,节点操作方法)
|
||||
- 节点渲染器
|
||||
- 工具方法
|
||||
- 入口文件
|
||||
|
||||
|
||||
|
||||
|
||||
工作流图组件
|
||||
├─ 状态存储
|
||||
│ └─ 节点默认配置数据
|
||||
├─ 基础节点
|
||||
│ ├─ 初始化节点
|
||||
│ ├─ 并行节点
|
||||
│ └─ 执行结果节点
|
||||
├─ 任务节点
|
||||
│ ├─ 申请节点
|
||||
│ ├─ 上传节点
|
||||
│ ├─ 部署节点
|
||||
│ └─ 通知节点
|
||||
├─ 节点渲染器
|
||||
│ └─ 渲染节点到界面
|
||||
├─ 工具方法
|
||||
│ ├─ 创建节点
|
||||
│ ├─ 重命名节点
|
||||
│ ├─ 删除节点
|
||||
│ ├─ 配置节点下一步
|
||||
│ ├─ 视图缩放
|
||||
│ └─ 流程验证
|
||||
└─ 入口文件
|
||||
└─ 初始化工作流图组件
|
||||
|
||||
|
||||
|
||||
|
||||
172
frontend/apps/allin-ssl/mardown/test.json
Normal file
@@ -0,0 +1,172 @@
|
||||
[
|
||||
{
|
||||
"name": "获取ACME账户列表",
|
||||
"url": "/acme_account/get_list",
|
||||
"param": {
|
||||
"search": "-",
|
||||
"p": "1",
|
||||
"limit": "10",
|
||||
"ca": "-"
|
||||
},
|
||||
"response": {
|
||||
"code": 200,
|
||||
"count": 0,
|
||||
"data": [
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:10:48",
|
||||
"id": 3,
|
||||
"name": "vvvv",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:10:48"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:12:53",
|
||||
"id": 4,
|
||||
"name": "xxx",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:12:53"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:13:09",
|
||||
"id": 5,
|
||||
"name": "1111",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:13:09"
|
||||
}
|
||||
],
|
||||
"message": "success",
|
||||
"status": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "添加ACME账户",
|
||||
"url": "/acme_account/add_account",
|
||||
"param": {
|
||||
"email": "111@66.com",
|
||||
"ca": "buypass",
|
||||
"Kid": "-",
|
||||
"HmacEncoded": "-",
|
||||
"CADirURL": "-"
|
||||
},
|
||||
"response": {
|
||||
"code": 200,
|
||||
"count": 0,
|
||||
"data": [
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:10:48",
|
||||
"id": 3,
|
||||
"name": "vvvv",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:10:48"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:12:53",
|
||||
"id": 4,
|
||||
"name": "xxx",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:12:53"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:13:09",
|
||||
"id": 5,
|
||||
"name": "1111",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:13:09"
|
||||
}
|
||||
],
|
||||
"message": "success",
|
||||
"status": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "更新ACME账户",
|
||||
"url": "/acme_account/upd_account",
|
||||
"param": {
|
||||
"id": "7",
|
||||
"email": "dfas@66.com",
|
||||
"ca": "buypass",
|
||||
"Kid": "-",
|
||||
"HmacEncoded": "-",
|
||||
"CADirURL": "-"
|
||||
},
|
||||
"response": {
|
||||
"code": 200,
|
||||
"count": 0,
|
||||
"data": [
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:10:48",
|
||||
"id": 3,
|
||||
"name": "vvvv",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:10:48"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:12:53",
|
||||
"id": 4,
|
||||
"name": "xxx",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:12:53"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:13:09",
|
||||
"id": 5,
|
||||
"name": "1111",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:13:09"
|
||||
}
|
||||
],
|
||||
"message": "success",
|
||||
"status": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "删除ACME账户",
|
||||
"url": "/acme_account/del_account",
|
||||
"param": {
|
||||
"api_token": "{{api_token}}",
|
||||
"timestamp": "{{timestamp}}",
|
||||
"id": "7"
|
||||
},
|
||||
"response": {
|
||||
"code": 200,
|
||||
"count": 0,
|
||||
"data": [
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:10:48",
|
||||
"id": 3,
|
||||
"name": "vvvv",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:10:48"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:12:53",
|
||||
"id": 4,
|
||||
"name": "xxx",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:12:53"
|
||||
},
|
||||
{
|
||||
"config": "{\"secret_id\": \"xxxxxxx\", \"secret_key\": \"xxxxxxxx\"}",
|
||||
"create_time": "2025-04-21 11:13:09",
|
||||
"id": 5,
|
||||
"name": "1111",
|
||||
"type": "tencentcloud",
|
||||
"update_time": "2025-04-21 11:13:09"
|
||||
}
|
||||
],
|
||||
"message": "success",
|
||||
"status": true
|
||||
}
|
||||
}
|
||||
]
|
||||
4
frontend/apps/allin-ssl/mardown/test.md
Normal file
@@ -0,0 +1,4 @@
|
||||
根据当前接口替换当前模块的接口
|
||||
1、类型为 ssl.com 和 Google ,必填EAB和EAB HMAC参数
|
||||
2、类型为 zerossl和自定义时,选填EAB和EAB HMAC参数
|
||||
3、类型为 Buypass和Letsencrypt,不显示EAB和EAB HMAC参数
|
||||
95
frontend/apps/allin-ssl/mardown/view.md
Normal file
@@ -0,0 +1,95 @@
|
||||
以下是当前项目的视图结构,参考/src/view/test 的目录结构和内容,生成下述的文件和内容
|
||||
src/
|
||||
├── views/
|
||||
│ ├── home/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ ├── useStore.tsx
|
||||
│ ├── autoDeploy/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ ├── useStore.tsx
|
||||
│ │ └── children/
|
||||
│ │ └── pipeDesign/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ └── useStore.tsx
|
||||
│ ├── certManage/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ ├── useStore.tsx
|
||||
│ │ └── components/
|
||||
│ │ └── uploadCert/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ └── useStore.tsx
|
||||
│ ├── certApply/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ ├── useStore.tsx
|
||||
│ │ ├── components/
|
||||
│ │ │ └── certApplyForm/
|
||||
│ │ │ ├── index.tsx
|
||||
│ │ │ ├── index.model.css
|
||||
│ │ │ ├── useController.tsx
|
||||
│ │ │ └── useStore.tsx
|
||||
│ │ └── children/
|
||||
│ │ ├── commCert/
|
||||
│ │ │ ├── index.tsx
|
||||
│ │ │ ├── index.model.css
|
||||
│ │ │ ├── useController.tsx
|
||||
│ │ │ └── useStore.tsx
|
||||
│ │ └── freeSslCert/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ └── useStore.tsx
|
||||
│ ├── authApiManage/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ ├── useStore.tsx
|
||||
│ │ └── components/
|
||||
│ │ └── addAuthApi/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ └── useStore.tsx
|
||||
│ ├── monitor/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ ├── useStore.tsx
|
||||
│ │ └── components/
|
||||
│ │ └── addMonitor/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ └── useStore.tsx
|
||||
│ └── settings/
|
||||
│ ├── index.tsx
|
||||
│ ├── index.model.css
|
||||
│ ├── useController.tsx
|
||||
│ ├── useStore.tsx
|
||||
│ └── components/
|
||||
│ ├── commSettings/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ └── useStore.tsx
|
||||
│ ├── notifySettings/
|
||||
│ │ ├── index.tsx
|
||||
│ │ ├── index.model.css
|
||||
│ │ ├── useController.tsx
|
||||
│ │ └── useStore.tsx
|
||||
│ └── aboutUs/
|
||||
│ ├── index.tsx
|
||||
│ ├── index.model.css
|
||||
│ ├── useController.tsx
|
||||
│ └── useStore.tsx
|
||||
96
frontend/apps/allin-ssl/mock/access.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 授权列表
|
||||
export const getAccessList = Mock.mock(/\/access\/get_list/, 'post', () => {
|
||||
const list = []
|
||||
for (let i = 0; i < 10; i++) {
|
||||
list.push({
|
||||
id: Mock.Random.id(),
|
||||
name: `授权-${Mock.Random.ctitle(3, 5)}`,
|
||||
type: Mock.Random.pick(['ssh', 'btpanel', '1panel', 'aliyun', 'tencent']),
|
||||
status: Mock.Random.integer(0, 1),
|
||||
created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
|
||||
})
|
||||
}
|
||||
return {
|
||||
code: 0,
|
||||
count: list.length,
|
||||
data: {
|
||||
list,
|
||||
total: 18,
|
||||
},
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}
|
||||
})
|
||||
|
||||
// 授权类型列表
|
||||
export const getAccessTypes = Mock.mock(/\/access\/get_access_types/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 3,
|
||||
data: [
|
||||
{ key: 'ssh', name: 'SSH验证' },
|
||||
{ key: 'btpanel', name: '宝塔验证' },
|
||||
{ key: '1panel', name: '1Panel验证' },
|
||||
{ key: 'aliyun', name: '阿里云验证' },
|
||||
{ key: 'tencentcloud', name: '腾讯云验证' },
|
||||
],
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 新增授权
|
||||
export const addAccess = Mock.mock(/\/access\/add_access/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '添加成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 修改授权
|
||||
export const updateAccess = Mock.mock(/\/access\/upd_access/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '修改成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 删除授权
|
||||
export const deleteAccess = Mock.mock(/\/access\/del_access/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '删除成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 获取工作流 dns 配置
|
||||
|
||||
export const getAccessAllList = Mock.mock(/\/access\/get_all/, 'post', () => {
|
||||
const list: Array<{ id: string; name: string; type: string }> = []
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const group = Mock.Random.pick([
|
||||
{ name: '阿里云', type: 'aliyun' },
|
||||
{ name: '腾讯云', type: 'tencentcloud' },
|
||||
])
|
||||
list.push({
|
||||
id: Mock.Random.id(),
|
||||
name: `${group.name} DNS 配置`,
|
||||
type: group.type,
|
||||
})
|
||||
}
|
||||
return {
|
||||
code: 0,
|
||||
count: list.length,
|
||||
data: list,
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}
|
||||
})
|
||||
70
frontend/apps/allin-ssl/mock/cert.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 证书列表
|
||||
export const getCertList = Mock.mock(/\/cert\/get_list/, 'post', () => {
|
||||
const list = []
|
||||
for (let i = 0; i < 15; i++) {
|
||||
list.push({
|
||||
id: Mock.Random.id(),
|
||||
name: `${Mock.Random.domain()}证书`,
|
||||
domain: Mock.Random.domain(),
|
||||
expire_time: Mock.Random.datetime('yyyy-MM-dd'),
|
||||
status: Mock.Random.integer(0, 2),
|
||||
created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
|
||||
})
|
||||
}
|
||||
return {
|
||||
code: 0,
|
||||
count: list.length,
|
||||
data: {
|
||||
list,
|
||||
total: 32,
|
||||
},
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}
|
||||
})
|
||||
|
||||
// 申请证书
|
||||
export const applyCert = Mock.mock(/\/cert\/apply_cert/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '申请成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 上传证书
|
||||
export const uploadCert = Mock.mock(/\/cert\/upload_cert/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '上传成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 删除证书
|
||||
export const deleteCert = Mock.mock(/\/cert\/del_cert/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '删除成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 下载证书
|
||||
export const downloadCert = Mock.mock(/\/cert\/download_cert/, 'get', () => {
|
||||
// 二进制文件流模拟,实际上应该是从服务器获取的二进制数据
|
||||
return {
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: 'certificate-file-content',
|
||||
message: '下载成功',
|
||||
status: true,
|
||||
}
|
||||
})
|
||||
9
frontend/apps/allin-ssl/mock/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
// 导出所有模块
|
||||
export * from './userInfo' // 示例接口
|
||||
export * from './overview'
|
||||
export * from './workflow'
|
||||
export * from './cert'
|
||||
export * from './access'
|
||||
export * from './siteMonitor'
|
||||
export * from './setting'
|
||||
export * from './login'
|
||||
14
frontend/apps/allin-ssl/mock/login.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 登录
|
||||
export const login = Mock.mock(/\/login\/login/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjE0NjE5MDQ2LCJleHAiOjE2MTQ3MDU0NDZ9._QS2nQa2FRpqH7zJSnjYVBXCOp7-QR-zrXsHl6dTHaU',
|
||||
},
|
||||
message: '登录成功',
|
||||
status: true,
|
||||
}))
|
||||
58
frontend/apps/allin-ssl/mock/overview.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 获取首页概览
|
||||
export const getOverviews = Mock.mock(/\/overview\/get_overviews/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
workfolw: {
|
||||
count: Mock.Random.integer(150, 250),
|
||||
active: Mock.Random.integer(120, 200),
|
||||
failure: Mock.Random.integer(0, 10),
|
||||
},
|
||||
cert: {
|
||||
count: Mock.Random.integer(30, 80),
|
||||
will: Mock.Random.integer(5, 15),
|
||||
end: Mock.Random.integer(0, 5),
|
||||
},
|
||||
site_monitor: {
|
||||
count: Mock.Random.integer(80, 150),
|
||||
exception: Mock.Random.integer(0, 8),
|
||||
},
|
||||
workflow_history: [
|
||||
{
|
||||
name: '服务A部署流水线',
|
||||
state: Mock.Random.integer(-1, 1),
|
||||
mode: Mock.Random.pick(['定时触发', '手动触发']),
|
||||
exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
|
||||
},
|
||||
{
|
||||
name: '1panel 面板证书部署流水线',
|
||||
state: Mock.Random.integer(-1, 1),
|
||||
mode: Mock.Random.pick(['定时触发', '手动触发']),
|
||||
exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
|
||||
},
|
||||
{
|
||||
name: '网站证书申请流水线',
|
||||
state: Mock.Random.integer(-1, 1),
|
||||
mode: Mock.Random.pick(['定时触发', '手动触发']),
|
||||
exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
|
||||
},
|
||||
{
|
||||
name: '网站证书申请流水线',
|
||||
state: Mock.Random.integer(-1, 1),
|
||||
mode: Mock.Random.pick(['定时触发', '手动触发']),
|
||||
exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
|
||||
},
|
||||
{
|
||||
name: '网站证书申请流水线',
|
||||
state: Mock.Random.integer(-1, 1),
|
||||
mode: Mock.Random.pick(['定时触发', '手动触发']),
|
||||
exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
|
||||
},
|
||||
],
|
||||
},
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}))
|
||||
87
frontend/apps/allin-ssl/mock/setting.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 获取系统设置
|
||||
export const getSystemSetting = Mock.mock(/\/setting\/get_setting/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
auto_renew: true,
|
||||
renew_days: 30,
|
||||
notify_enable: true,
|
||||
notify_days: 15,
|
||||
},
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 保存系统设置
|
||||
export const saveSystemSetting = Mock.mock(/\/setting\/save_setting/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '保存成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 获取告警类型列表
|
||||
export const getReportTypes = Mock.mock(/\/setting\/get_report_types/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 4,
|
||||
data: [
|
||||
{ key: 'email', name: '邮件通知' },
|
||||
{ key: 'sms', name: '短信通知' },
|
||||
{ key: 'webhook', name: 'Webhook' },
|
||||
{ key: 'dingtalk', name: '钉钉通知' },
|
||||
],
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 配置告警
|
||||
export const setReport = Mock.mock(/\/setting\/set_report/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '配置成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 删除告警
|
||||
export const deleteReport = Mock.mock(/\/setting\/del_report/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '删除成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 获取证书过期通知模板
|
||||
export const getCertEndNoticeTemplate = Mock.mock(/\/setting\/get_certend_notice_temp/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
title: '证书即将过期通知',
|
||||
content: '您的证书 {{domain}} 将在 {{days}} 天后过期,请及时更新。',
|
||||
},
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 保存证书过期通知模板
|
||||
export const saveCertEndNoticeTemplate = Mock.mock(/\/setting\/save_certend_notice_temp/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '保存成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 系统更新
|
||||
export const systemUpdate = Mock.mock(/\/setting\/update/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '更新成功',
|
||||
status: true,
|
||||
}))
|
||||
68
frontend/apps/allin-ssl/mock/siteMonitor.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 站点监控列表
|
||||
export const getSiteMonitorList = Mock.mock(/\/siteMonitor\/get_list/, 'post', () => {
|
||||
const list = []
|
||||
for (let i = 0; i < 12; i++) {
|
||||
list.push({
|
||||
id: Mock.Random.id(),
|
||||
name: `${Mock.Random.ctitle(2, 5)}网站监控`,
|
||||
url: `https://${Mock.Random.domain()}/api/${Mock.Random.word(3, 8)}`,
|
||||
type: Mock.Random.pick(['HTTP', 'HTTPS', 'TCP', 'PING']),
|
||||
status: Mock.Random.integer(0, 1),
|
||||
check_result: Mock.Random.pick(['连接成功', '超时', '证书有效', '证书已过期']),
|
||||
created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
|
||||
})
|
||||
}
|
||||
return {
|
||||
code: 0,
|
||||
count: list.length,
|
||||
data: {
|
||||
list,
|
||||
total: 25,
|
||||
},
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}
|
||||
})
|
||||
|
||||
// 新增站点监控
|
||||
export const addSiteMonitor = Mock.mock(/\/siteMonitor\/add_site_monitor/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '添加成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 修改站点监控
|
||||
export const updateSiteMonitor = Mock.mock(/\/siteMonitor\/upd_site_monitor/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '修改成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 删除站点监控
|
||||
export const deleteSiteMonitor = Mock.mock(/\/monitor\/del_monitor/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '删除成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 启用/禁用站点监控
|
||||
export const setSiteMonitor = Mock.mock(/\/siteMonitor\/set_site_monitor/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '设置成功',
|
||||
status: true,
|
||||
}))
|
||||
24
frontend/apps/allin-ssl/mock/template.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @description 成功模板
|
||||
* @param {string} msg 消息
|
||||
* @returns
|
||||
*/
|
||||
export const listTemplate = <T>(data: T, count: number) => ({
|
||||
code: 200, // 状态码
|
||||
count, // 总数,仅data 为数组时有效
|
||||
data, // 数据
|
||||
message: '', // 消息
|
||||
status: true, // 消息状态,true 为成功,false 为失败
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 消息模板
|
||||
* @param {object} data 数据
|
||||
* @returns
|
||||
*/
|
||||
export const messageTemplate = (message: string, status: boolean) => ({
|
||||
code: 200, // 状态码
|
||||
count: 0, // 总数,仅data 为数组时有效
|
||||
message, // 消息
|
||||
status, // 消息状态,true 为成功,false 为失败
|
||||
})
|
||||
26
frontend/apps/allin-ssl/mock/userInfo.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 用户列表 (案例接口)
|
||||
export const listUser = Mock.mock(
|
||||
/\/api\/user\/list/,
|
||||
'post',
|
||||
listTemplate(
|
||||
{
|
||||
id: '@id',
|
||||
name: '@cname',
|
||||
avatar: '@image',
|
||||
'age|18-60': 18,
|
||||
'gender|1': ['男', '女'],
|
||||
phone: /^1[385][1-9]\d{8}/,
|
||||
email: '@EMAIL',
|
||||
address: '@county(true)',
|
||||
'role|1': ['admin', 'user'],
|
||||
},
|
||||
100,
|
||||
),
|
||||
)
|
||||
|
||||
// 用户详情 (案例接口)
|
||||
export const addUser = Mock.mock(/\/api\/user\/add/, 'post', messageTemplate('添加成功', true))
|
||||
|
||||
90
frontend/apps/allin-ssl/mock/workflow.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import Mock from 'mockjs'
|
||||
import { listTemplate, messageTemplate } from './template'
|
||||
|
||||
// 工作流列表
|
||||
export const getWorkflowList = Mock.mock(/\/workflow\/get_list/, 'post', () => {
|
||||
const list = []
|
||||
for (let i = 0; i < 10; i++) {
|
||||
list.push({
|
||||
id: Mock.Random.id(),
|
||||
name: `${Mock.Random.ctitle(3, 8)}部署流水线`,
|
||||
type: Mock.Random.pick(['auto', 'manual']),
|
||||
status: Mock.Random.integer(0, 1),
|
||||
created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
|
||||
updated_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
|
||||
})
|
||||
}
|
||||
return {
|
||||
code: 0,
|
||||
count: list.length,
|
||||
data: {
|
||||
list,
|
||||
total: 28,
|
||||
},
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}
|
||||
})
|
||||
|
||||
// 新增工作流
|
||||
export const addWorkflow = Mock.mock(/\/workflow\/add_workflow/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '添加成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 修改工作流
|
||||
export const updateWorkflow = Mock.mock(/\/workflow\/upd_workflow/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: {
|
||||
id: Mock.Random.id(),
|
||||
},
|
||||
message: '修改成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 删除工作流
|
||||
export const deleteWorkflow = Mock.mock(/\/workflow\/del_workflow/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '删除成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
// 获取工作流执行历史
|
||||
export const getWorkflowHistory = Mock.mock(/\/workflow\/get_workflow_history/, 'post', () => {
|
||||
const list = []
|
||||
for (let i = 0; i < 10; i++) {
|
||||
list.push({
|
||||
id: Mock.Random.id(),
|
||||
workflow_id: Mock.Random.id(),
|
||||
workflow_name: `${Mock.Random.ctitle(3, 8)}部署流水线`,
|
||||
state: Mock.Random.integer(-1, 1),
|
||||
mode: Mock.Random.pick(['定时触发', '手动触发']),
|
||||
exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
|
||||
})
|
||||
}
|
||||
return {
|
||||
code: 0,
|
||||
count: list.length,
|
||||
data: list,
|
||||
message: '获取成功',
|
||||
status: true,
|
||||
}
|
||||
})
|
||||
|
||||
// 手动执行工作流
|
||||
export const executeWorkflow = Mock.mock(/\/workflow\/execute_workflow/, 'post', () => ({
|
||||
code: 0,
|
||||
count: 0,
|
||||
data: null,
|
||||
message: '执行成功',
|
||||
status: true,
|
||||
}))
|
||||
|
||||
89
frontend/apps/allin-ssl/package.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"name": "allin-ssl",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "vite build --mode build",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest",
|
||||
"tsc": "vue-tsc -b --noEmit",
|
||||
"lint:ts": "eslint --ext .ts,.js src --fix",
|
||||
"lint:style": "stylelint --config .stylelintrc.cjs --fix",
|
||||
"lint": "npm run lint:ts && npm run lint:style"
|
||||
},
|
||||
"dependencies": {
|
||||
"@baota/hooks": "workspace:*",
|
||||
"@baota/i18n": "workspace:*",
|
||||
"@baota/naive-ui": "workspace:*",
|
||||
"@baota/pinia": "workspace:*",
|
||||
"@baota/router": "workspace:*",
|
||||
"@baota/utils": "workspace:*",
|
||||
"@vicons/antd": "^0.13.0",
|
||||
"@vicons/carbon": "^0.13.0",
|
||||
"@vicons/fa": "^0.13.0",
|
||||
"@vicons/fluent": "^0.13.0",
|
||||
"@vicons/ionicons5": "^0.13.0",
|
||||
"@vicons/tabler": "^0.13.0",
|
||||
"@vue-flow/background": "^1.3.2",
|
||||
"@vue-flow/controls": "^1.1.2",
|
||||
"@vue-flow/core": "^1.42.5",
|
||||
"@vue-flow/minimap": "^1.5.3",
|
||||
"@vue-flow/node-toolbar": "^1.1.1",
|
||||
"@vueuse/core": "^12.4.0",
|
||||
"@vueuse/integrations": "^12.4.0",
|
||||
"axios": "^1.7.9",
|
||||
"crypto-js": "^4.1.1",
|
||||
"echarts": "^5.6.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"jsoneditor": "^10.2.0",
|
||||
"naive-ui": "^2.41.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"particlesjs": "^2.2.3",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
"uuid": "^11.1.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-i18n": "^11.1.2",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@baota/eslint": "workspace:*",
|
||||
"@baota/prettier": "workspace:*",
|
||||
"@baota/stylelint": "workspace:*",
|
||||
"@baota/typescript": "workspace:*",
|
||||
"@baota/vite-plugin-ftp-sync": "workspace:*",
|
||||
"@baota/vite-plugin-i18n": "workspace:*",
|
||||
"@baota/vite-plugin-turborepo-deploy": "workspace:*",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/humps": "^2.0.6",
|
||||
"@types/md5": "^2.3.5",
|
||||
"@types/minimist": "^1.2.5",
|
||||
"@types/mockjs": "^1.0.10",
|
||||
"@types/node": "^22.10.7",
|
||||
"@types/ramda": "^0.30.2",
|
||||
"@vitejs/plugin-basic-ssl": "^1.2.0",
|
||||
"@vitejs/plugin-legacy": "^6.0.0",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"humps": "^2.0.1",
|
||||
"minimist": "^1.2.8",
|
||||
"mockjs": "^1.1.0",
|
||||
"postcss": "^8.5.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript-plugin-css-modules": "^5.1.0",
|
||||
"unplugin-auto-import": "^19.0.0",
|
||||
"unplugin-vue-components": "^28.0.0",
|
||||
"vite": "^6.0.5",
|
||||
"vite-plugin-compression2": "^1.3.3",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vite-plugin-vue-devtools": "^7.7.0",
|
||||
"vite-plugin-vue-mcp": "^0.3.2",
|
||||
"vitest": "^3.0.2",
|
||||
"vue-tsc": "^2.2.0"
|
||||
}
|
||||
}
|
||||
6
frontend/apps/allin-ssl/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
3
frontend/apps/allin-ssl/prettier.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import prettierConfig from '@baota/prettier'
|
||||
|
||||
export default prettierConfig
|
||||
BIN
frontend/apps/allin-ssl/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 66 KiB |
3
frontend/apps/allin-ssl/public/static/icons/btssl.svg
Normal file
|
After Width: | Height: | Size: 47 KiB |
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1413px" height="338px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g><path style="opacity:0.962" fill="#f8a11c" d="M 131.5,5.5 C 137.682,4.71925 142.182,7.05258 145,12.5C 145.667,26.8333 145.667,41.1667 145,55.5C 138.784,64.4081 132.117,64.7415 125,56.5C 124.333,41.5 124.333,26.5 125,11.5C 126.494,8.68648 128.66,6.68648 131.5,5.5 Z"/></g>
|
||||
<g><path style="opacity:0.938" fill="#f8a11c" d="M 40.5,42.5 C 44.3076,42.1632 47.9743,42.6632 51.5,44C 61.9591,52.1236 72.1257,60.6236 82,69.5C 85.5704,78.6939 82.5704,84.3605 73,86.5C 70.3658,86.0664 67.8658,85.233 65.5,84C 55.6667,75.5 45.8333,67 36,58.5C 33.1587,51.8715 34.6587,46.5382 40.5,42.5 Z"/></g>
|
||||
<g><path style="opacity:0.942" fill="#f8a11c" d="M 219.5,42.5 C 232.389,41.553 236.889,47.2196 233,59.5C 223.126,68.3764 212.959,76.8764 202.5,85C 191.172,87.675 186.005,83.175 187,71.5C 187.5,70.5 188,69.5 188.5,68.5C 198.878,59.7807 209.211,51.1141 219.5,42.5 Z"/></g>
|
||||
<g><path style="opacity:0.975" fill="#f8a01d" d="M 193.5,155.5 C 182.167,156.833 170.833,156.833 159.5,155.5C 159.666,148.825 159.5,142.158 159,135.5C 153.087,116.64 140.92,110.806 122.5,118C 116.571,122.02 112.738,127.52 111,134.5C 110.5,141.492 110.334,148.492 110.5,155.5C 98.8333,156.833 87.1667,156.833 75.5,155.5C 72.0122,130.118 79.6789,108.951 98.5,92C 118.363,78.9872 139.363,76.9872 161.5,86C 187.348,101.878 198.015,125.045 193.5,155.5 Z M 159.5,155.5 C 143.167,155.5 126.833,155.5 110.5,155.5C 110.334,148.492 110.5,141.492 111,134.5C 112.738,127.52 116.571,122.02 122.5,118C 140.92,110.806 153.087,116.64 159,135.5C 159.5,142.158 159.666,148.825 159.5,155.5 Z"/></g>
|
||||
<g><path style="opacity:0.966" fill="#f8a11c" d="M 9.5,119.5 C 23.8372,119.333 38.1705,119.5 52.5,120C 55,121.167 56.8333,123 58,125.5C 60.067,131.987 58.2337,136.82 52.5,140C 37.8333,140.667 23.1667,140.667 8.5,140C 0.496354,132.82 0.829687,125.987 9.5,119.5 Z"/></g>
|
||||
<g><path style="opacity:0.966" fill="#f8a11c" d="M 217.5,119.5 C 231.504,119.333 245.504,119.5 259.5,120C 266.053,122.73 268.22,127.563 266,134.5C 264.833,137 263,138.833 260.5,140C 245.833,140.667 231.167,140.667 216.5,140C 209.938,135.401 208.771,129.568 213,122.5C 214.652,121.601 216.152,120.601 217.5,119.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 601.5,152.5 C 609.624,152.31 615.79,155.644 620,162.5C 625.113,181.855 619.28,196.688 602.5,207C 598.312,208.631 593.979,209.464 589.5,209.5C 589.5,204.5 589.5,199.5 589.5,194.5C 596.098,193.906 600.765,190.573 603.5,184.5C 589.406,182.218 584.572,174.218 589,160.5C 590.833,158.667 592.667,156.833 594.5,155C 597.004,154.302 599.337,153.469 601.5,152.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 75.5,155.5 C 87.1667,156.833 98.8333,156.833 110.5,155.5C 126.833,155.5 143.167,155.5 159.5,155.5C 170.833,156.833 182.167,156.833 193.5,155.5C 198.844,155.334 204.177,155.501 209.5,156C 213.68,157.002 216.514,159.502 218,163.5C 218.982,202.56 218.649,241.56 217,280.5C 215.457,282.378 213.624,283.878 211.5,285C 160.5,285.667 109.5,285.667 58.5,285C 55.6667,283.5 53.5,281.333 52,278.5C 51.3333,239.833 51.3333,201.167 52,162.5C 53.668,158.835 56.5013,156.668 60.5,156C 65.4889,155.501 70.4889,155.334 75.5,155.5 Z M 130.5,199.5 C 145.643,199.162 151.143,206.162 147,220.5C 146,222.833 144.333,224.5 142,225.5C 141.667,231.167 141.333,236.833 141,242.5C 137.509,248.661 133.509,248.994 129,243.5C 128.83,237.472 128.33,231.472 127.5,225.5C 120.327,220.137 118.827,213.471 123,205.5C 125.134,202.847 127.634,200.847 130.5,199.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 318.5,155.5 C 329.5,155.5 340.5,155.5 351.5,155.5C 351.5,189.833 351.5,224.167 351.5,258.5C 368.167,258.5 384.833,258.5 401.5,258.5C 401.5,268.167 401.5,277.833 401.5,287.5C 373.833,287.5 346.167,287.5 318.5,287.5C 318.5,243.5 318.5,199.5 318.5,155.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 747.5,155.5 C 777.167,155.5 806.833,155.5 836.5,155.5C 836.5,164.833 836.5,174.167 836.5,183.5C 817.167,183.5 797.833,183.5 778.5,183.5C 778.5,191.167 778.5,198.833 778.5,206.5C 796.833,206.5 815.167,206.5 833.5,206.5C 833.5,215.5 833.5,224.5 833.5,233.5C 815.167,233.5 796.833,233.5 778.5,233.5C 778.5,242.167 778.5,250.833 778.5,259.5C 798.833,259.5 819.167,259.5 839.5,259.5C 839.5,268.833 839.5,278.167 839.5,287.5C 808.833,287.5 778.167,287.5 747.5,287.5C 747.5,243.5 747.5,199.5 747.5,155.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 524.5,169.5 C 534.833,169.5 545.167,169.5 555.5,169.5C 555.5,177.833 555.5,186.167 555.5,194.5C 562.5,194.5 569.5,194.5 576.5,194.5C 576.5,202.167 576.5,209.833 576.5,217.5C 569.5,217.5 562.5,217.5 555.5,217.5C 555.333,231.171 555.5,244.837 556,258.5C 557.792,263.161 561.292,265.494 566.5,265.5C 569.208,264.959 571.874,264.292 574.5,263.5C 575.498,271.472 575.831,279.472 575.5,287.5C 564.869,289.85 554.202,290.016 543.5,288C 532.555,284.042 526.388,276.209 525,264.5C 524.5,248.837 524.333,233.17 524.5,217.5C 519.5,217.5 514.5,217.5 509.5,217.5C 509.5,209.833 509.5,202.167 509.5,194.5C 514.5,194.5 519.5,194.5 524.5,194.5C 524.5,186.167 524.5,177.833 524.5,169.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 1357.5,169.5 C 1367.83,169.5 1378.17,169.5 1388.5,169.5C 1388.5,177.833 1388.5,186.167 1388.5,194.5C 1395.83,194.5 1403.17,194.5 1410.5,194.5C 1410.5,202.167 1410.5,209.833 1410.5,217.5C 1403.17,217.5 1395.83,217.5 1388.5,217.5C 1388.33,230.837 1388.5,244.171 1389,257.5C 1390.61,262.605 1394.11,265.271 1399.5,265.5C 1402.21,264.959 1404.87,264.292 1407.5,263.5C 1409.25,271.347 1409.59,279.181 1408.5,287C 1394.73,291.136 1381.4,290.136 1368.5,284C 1361.53,277.783 1358.03,269.95 1358,260.5C 1357.5,246.171 1357.33,231.837 1357.5,217.5C 1352.83,217.5 1348.17,217.5 1343.5,217.5C 1343.5,209.833 1343.5,202.167 1343.5,194.5C 1348.17,194.5 1352.83,194.5 1357.5,194.5C 1357.5,186.167 1357.5,177.833 1357.5,169.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 450.5,191.5 C 481.293,188.162 499.793,201.495 506,231.5C 506.499,237.491 506.666,243.491 506.5,249.5C 484.164,249.333 461.831,249.5 439.5,250C 444.872,263.187 454.538,268.187 468.5,265C 473.758,263.574 478.092,260.741 481.5,256.5C 489,260.749 496.334,265.249 503.5,270C 492.992,284.169 478.825,291.003 461,290.5C 425.452,288.622 408.452,269.955 410,234.5C 413.465,210.539 426.965,196.206 450.5,191.5 Z M 454.5,213.5 C 467.671,211.233 475.338,216.566 477.5,229.5C 464.829,229.667 452.162,229.5 439.5,229C 442.018,221.317 447.018,216.15 454.5,213.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 644.5,191.5 C 657.321,190.255 669.654,192.088 681.5,197C 685.282,198.954 688.615,201.454 691.5,204.5C 686.537,211.131 680.87,217.131 674.5,222.5C 670.461,219.481 666.128,216.981 661.5,215C 657.5,214.333 653.5,214.333 649.5,215C 643.81,217.782 643.143,221.449 647.5,226C 658.652,228.273 669.319,231.94 679.5,237C 691.608,248.015 693.774,260.848 686,275.5C 674.103,287.774 659.603,292.608 642.5,290C 629.937,288.881 618.937,284.215 609.5,276C 614.983,269.35 620.983,263.183 627.5,257.5C 634.692,264.73 643.358,267.897 653.5,267C 660.847,264.938 662.18,260.938 657.5,255C 649.32,251.871 640.987,249.205 632.5,247C 618.729,240.962 613.229,230.462 616,215.5C 617.834,207.998 622.001,202.165 628.5,198C 633.603,194.938 638.936,192.771 644.5,191.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 910.5,191.5 C 933.705,189.879 946.872,200.545 950,223.5C 950.5,244.831 950.667,266.164 950.5,287.5C 939.833,287.5 929.167,287.5 918.5,287.5C 918.667,267.831 918.5,248.164 918,228.5C 914.428,218.082 907.595,215.249 897.5,220C 894.131,222.365 891.964,225.532 891,229.5C 889.564,248.787 889.064,268.12 889.5,287.5C 879.167,287.5 868.833,287.5 858.5,287.5C 858.5,256.5 858.5,225.5 858.5,194.5C 868.5,194.5 878.5,194.5 888.5,194.5C 888.335,198.182 888.501,201.848 889,205.5C 894.479,198.181 901.645,193.515 910.5,191.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 1001.5,191.5 C 1014.5,190.001 1026.84,192.168 1038.5,198C 1041.19,199.698 1043.52,201.698 1045.5,204C 1039.79,211.24 1033.96,218.407 1028,225.5C 1017.28,214.846 1006.61,214.846 996,225.5C 988.734,237.131 989.567,248.298 998.5,259C 1009.29,265.565 1019.45,264.732 1029,256.5C 1034.33,263.167 1039.67,269.833 1045,276.5C 1045.71,278.367 1045.21,279.867 1043.5,281C 1021.83,293.667 1000.17,293.667 978.5,281C 962.28,268.02 956.113,251.187 960,230.5C 965.313,208.352 979.146,195.352 1001.5,191.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 1106.5,191.5 C 1110.24,191.241 1113.91,191.574 1117.5,192.5C 1118.27,201.836 1117.93,211.17 1116.5,220.5C 1101.47,217.091 1091.97,222.758 1088,237.5C 1087.5,254.163 1087.33,270.83 1087.5,287.5C 1077.17,287.5 1066.83,287.5 1056.5,287.5C 1056.5,256.5 1056.5,225.5 1056.5,194.5C 1066.5,194.5 1076.5,194.5 1086.5,194.5C 1086.33,198.182 1086.5,201.848 1087,205.5C 1091.76,198.222 1098.26,193.556 1106.5,191.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 1289.5,191.5 C 1321.74,191.732 1338.74,208.065 1340.5,240.5C 1340.2,261.627 1330.87,277.127 1312.5,287C 1300.72,291.528 1289.06,291.194 1277.5,286C 1273.76,284.262 1270.59,281.762 1268,278.5C 1267.5,296.164 1267.33,313.83 1267.5,331.5C 1257.17,331.5 1246.83,331.5 1236.5,331.5C 1236.5,285.833 1236.5,240.167 1236.5,194.5C 1246.5,194.5 1256.5,194.5 1266.5,194.5C 1266.33,197.85 1266.5,201.183 1267,204.5C 1273.17,197.673 1280.67,193.339 1289.5,191.5 Z M 1283.5,217.5 C 1302.24,217.405 1310.74,226.738 1309,245.5C 1303.81,262.899 1292.97,267.733 1276.5,260C 1263.56,247.638 1263.22,234.971 1275.5,222C 1278.1,220.205 1280.77,218.705 1283.5,217.5 Z"/></g>
|
||||
<g><path style="opacity:1" fill="#fefffe" d="M 1123.5,194.5 C 1135.19,194.168 1146.85,194.501 1158.5,195.5C 1165.1,214.129 1171.6,232.796 1178,251.5C 1184.38,233.012 1190.38,214.345 1196,195.5C 1207.11,194.18 1218.27,194.18 1229.5,195.5C 1214.9,232.794 1200.4,270.127 1186,307.5C 1181.11,320.357 1171.95,328.191 1158.5,331C 1149.45,331.846 1140.45,331.513 1131.5,330C 1130.9,328.938 1130.57,327.772 1130.5,326.5C 1131.59,318.837 1132.59,311.171 1133.5,303.5C 1140.39,305.314 1147.06,304.814 1153.5,302C 1157.1,296.969 1159.77,291.469 1161.5,285.5C 1148.83,255.148 1136.16,224.815 1123.5,194.5 Z"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
BIN
frontend/apps/allin-ssl/public/static/icons/letsencrypt-icon.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
BIN
frontend/apps/allin-ssl/public/static/icons/positive-ico.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 2258.5 538.1" style="enable-background:new 0 0 2258.5 538.1;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#00AF73;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M2083.3,123.5c0-10.6,2.6-20.5,7.8-29.6s12.4-16.3,21.6-21.5c9.2-5.2,19.1-7.9,29.8-7.9s20.6,2.6,29.7,7.9
|
||||
c9.2,5.2,16.3,12.4,21.5,21.5s7.8,19,7.8,29.6c0,10.4-2.5,20.1-7.5,29.1c-5,9.1-12.1,16.3-21.3,21.8s-19.3,8.3-30.3,8.3
|
||||
c-10.9,0-21-2.7-30.2-8.2c-9.2-5.4-16.3-12.7-21.4-21.8C2085.9,143.8,2083.3,134,2083.3,123.5z M2092.9,123.5
|
||||
c0,9,2.2,17.4,6.7,25.1c4.4,7.7,10.5,13.7,18.1,18.1c7.6,4.4,15.9,6.5,24.8,6.5c8.9,0,17.2-2.2,24.9-6.7s13.7-10.5,18-18.1
|
||||
c4.4-7.6,6.5-16,6.5-25s-2.2-17.3-6.5-24.9c-4.4-7.6-10.4-13.6-18-18s-16-6.6-24.9-6.6s-17.2,2.2-24.8,6.5
|
||||
c-7.7,4.3-13.7,10.4-18.1,18C2095.1,106.2,2092.9,114.5,2092.9,123.5z M2130.2,129.4v26.7h-11.7v-67h23c8.5,0,15.1,1.7,19.8,5.2
|
||||
c4.7,3.4,7,8.5,7,15s-3.6,11.4-10.7,14.8c6.8,2.6,10.2,8,10.2,16.1v4.8c0,4.5,0.5,7.8,1.4,9.8v1.3h-12.1
|
||||
c-0.8-1.9-1.2-5.3-1.2-10.1c0-4.9-0.1-7.8-0.2-8.6c-0.9-5.1-4.5-7.7-10.9-7.9h-14.6V129.4z M2130.2,119.3h13c4-0.1,7.2-1,9.7-2.8
|
||||
c2.4-1.7,3.7-4,3.7-6.8c0-3.8-1.1-6.5-3.2-8.1c-2.2-1.6-6-2.4-11.6-2.4h-11.5L2130.2,119.3L2130.2,119.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M365.2,83.8c5.7-8.5,0.5-19.3-9.4-19.3H266h-40h-29.4c-33.5,0-60.2,8.9-79.9,26.7
|
||||
c-19.7,17.7-31,43.1-34,76.3l0,0l-7.6,86.8l0,0c-2.8,33.2,4.1,58.6,20.7,76.3c16.7,17.8,41.8,26.7,75.3,26.7h36.4v-0.2
|
||||
c7.2-1,11.1-5.4,11.8-13.1l3.7-42.6c0.7-7.7-5-14-12.8-14H190c-13.1,0-22.3-2.9-27.6-8.6c-5.2-5.7-7.2-15.4-6.1-29l6.8-77.8
|
||||
c1.2-13.6,4.9-23.2,11.1-28.9c6.2-5.7,15.9-8.6,29.1-8.6h16.6h26.6h64.2c12.7,0,25-6.7,32.3-17.7L365.2,83.8z"/>
|
||||
<path class="st1" d="M59.3,454.3c-5.7,8.5-0.5,19.3,9.4,19.3h92.1h40h29.4c33.5,0,60.2-8.9,79.9-26.7c19.7-17.7,31-43.1,34-76.3
|
||||
l0,0l7.6-86.8l0,0c2.8-33.2-4.1-58.6-20.7-76.3c-16.7-17.8-41.8-26.7-75.3-26.7h-36.4v0.2c-7.2,1-11.1,5.4-11.8,13.1l-3.7,42.6
|
||||
c-0.7,7.7,5,14,12.8,14H237c13.1,0,22.3,2.9,27.6,8.6c5.2,5.7,7.2,15.4,6.1,28.9l-6.8,77.8c-1.2,13.6-4.9,23.2-11.1,28.9
|
||||
c-6.2,5.7-15.9,8.6-29.1,8.6H207h-26.6h-66.5c-12.7,0-25,6.7-32.3,17.7L59.3,454.3z"/>
|
||||
</g>
|
||||
<path class="st0" d="M607,473.6H399c-8.9,0-13-4.4-12.2-13.4l33.5-382.3c0.8-8.9,5.6-13.4,14.5-13.4h208c8.5,0,12.3,4.4,11.6,13.4
|
||||
l-3.8,43.3c-0.8,8.9-5.4,13.4-13.9,13.4h-133c-5.1,0-7.8,2.3-8.2,7l-7.2,82.7c-0.4,4.7,1.9,7,7,7h108.8c8.9,0,13,4.5,12.2,13.4
|
||||
l-3.8,43.3c-0.8,8.9-5.6,13.4-14.5,13.4H489.2c-5.1,0-7.8,2.3-8.2,7l-7.7,88.4c-0.4,4.7,1.9,7,7,7h132.9c8.5,0,12.3,4.5,11.6,13.4
|
||||
l-3.8,43.3C620.1,469.1,615.5,473.6,607,473.6"/>
|
||||
<path class="st0" d="M831.4,473.6h-69.3c-33.5,0-58.6-8.9-75.3-26.7c-16.7-17.8-23.6-43.5-20.6-77l17.6-201.7
|
||||
c2.9-33.5,14.3-59.2,34.1-77s46.4-26.7,79.9-26.7h69.3c33.1,0,58.1,9,74.9,27c16.9,18,23.9,43.6,21,76.6l-2.6,29.9
|
||||
c-0.8,9.3-5.9,14-15.2,14h-53.4c-8.9,0-13-4.7-12.1-14l2.3-26.1c1.2-13.6-0.8-23.2-6.1-28.9c-5.2-5.7-14.6-8.6-28.2-8.6h-43.3
|
||||
c-13.1,0-22.8,2.9-29.1,8.6c-6.2,5.7-9.9,15.4-11.1,28.9l-17,194c-1.2,13.6,0.8,23.2,6.1,28.9c5.2,5.7,14.4,8.6,27.6,8.6h43.3
|
||||
c13.6,0,23.5-2.9,29.7-8.6s9.9-15.4,11.1-28.9l2.3-26.1c0.8-9.3,5.7-14,14.6-14h53.4c9.3,0,13.6,4.7,12.8,14l-2.6,29.9
|
||||
c-2.9,33.1-14.4,58.6-34.4,76.6C891,464.6,864.5,473.6,831.4,473.6"/>
|
||||
<path class="st0" d="M1127,473.6h-53.4c-9.3,0-13.6-4.4-12.8-13.4l27.9-318.7c0.4-4.7-1.7-7-6.4-7h-72.5c-8.9,0-13-4.4-12.2-13.4
|
||||
l3.8-43.3c0.8-8.9,5.6-13.4,14.5-13.4h240.4c8.9,0,13,4.4,12.2,13.4l-3.8,43.3c-0.8,8.9-5.6,13.4-14.5,13.4h-72.5
|
||||
c-5.1,0-7.8,2.3-8.2,7l-27.9,318.7C1140.7,469.1,1135.9,473.6,1127,473.6"/>
|
||||
<path class="st0" d="M1390.5,77.9L1357,460.2c-0.8,8.9-5.6,13.4-14.5,13.4h-54.1c-8.9,0-13-4.5-12.2-13.4l33.5-382.3
|
||||
c0.8-8.9,5.6-13.4,14.5-13.4h54.1C1387.2,64.5,1391.3,69,1390.5,77.9"/>
|
||||
<path class="st0" d="M1857.4,403.6h45.2c13.6,0,23.5-2.9,29.7-8.6s9.9-15.4,11.1-28.9l17-194c1.2-13.6-0.8-23.2-6.1-28.9
|
||||
c-5.2-5.7-14.6-8.6-28.2-8.6h-45.2c-13.6,0-23.4,2.9-29.4,8.6c-6,5.7-9.6,15.4-10.8,28.9l-17,194c-1.2,13.6,0.7,23.2,5.7,28.9
|
||||
C1834.6,400.7,1843.8,403.6,1857.4,403.6 M1909.8,473.6h-71.2c-33.5,0-58.6-8.9-75.3-26.7c-16.7-17.8-23.6-43.5-20.6-77
|
||||
l17.6-201.7c2.9-33.5,14.3-59.2,34.1-77c19.8-17.8,46.4-26.7,79.9-26.7h71.2c33.5,0,58.6,8.9,75.3,26.7
|
||||
c16.7,17.8,23.6,43.5,20.6,77l-17.6,201.7c-2.9,33.5-14.3,59.2-34.1,77C1970,464.7,1943.3,473.6,1909.8,473.6"/>
|
||||
<path class="st0" d="M1639.5,201.3h54.1c8.9,0,13.8-4.7,14.6-14l1.7-19.1c2.9-33.1-4-58.6-20.6-76.7c-16.7-18-41.5-27-74.6-27
|
||||
h-67.4c-33.5,0-60.2,8.9-79.9,26.7c-19.8,17.8-31.2,43.5-34.1,77l-17.6,201.7c-2.9,33.5,3.9,59.2,20.6,77s41.8,26.7,75.3,26.7
|
||||
h67.4c33.1,0,59.5-9,79.3-27s31.2-43.6,34.1-76.7l9.3-106.2c0.9-9.8-3.6-14.6-13.4-14.6H1577h-14.6c-9.9,0-17,10.7-12.8,19.3
|
||||
l16.4,33c5.4,10.9,16.6,17.7,29.2,17.7h13.8c4.7,0,6.8,2.3,6.4,7l-3.5,40.1c-1.2,13.6-4.8,23.2-10.8,29c-6,5.7-15.8,8.6-29.4,8.6
|
||||
h-41.4c-13.1,0-22.3-2.9-27.6-8.6c-5.2-5.7-7.2-15.4-6.1-29l17-194c1.2-13.6,4.9-23.2,11.1-28.9s15.9-8.6,29.1-8.6h41.4
|
||||
c13.6,0,22.9,2.9,27.9,8.6c5,5.7,6.9,15.4,5.7,28.9l-1.3,15.3C1626.5,196.6,1630.6,201.3,1639.5,201.3"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
BIN
frontend/apps/allin-ssl/public/static/icons/sectigo-ico.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
60
frontend/apps/allin-ssl/public/static/icons/sectigo-ico.svg
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 2258.5 538.1" style="enable-background:new 0 0 2258.5 538.1;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#091B2A;}
|
||||
.st1{fill:#00AF73;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M2083.3,123.5c0-10.6,2.6-20.5,7.8-29.6s12.4-16.3,21.6-21.5c9.2-5.2,19.1-7.9,29.8-7.9s20.6,2.6,29.7,7.9
|
||||
c9.2,5.2,16.3,12.4,21.5,21.5s7.8,19,7.8,29.6c0,10.4-2.5,20.1-7.5,29.1c-5,9.1-12.1,16.3-21.3,21.8s-19.3,8.3-30.3,8.3
|
||||
c-10.9,0-21-2.7-30.2-8.2c-9.2-5.4-16.3-12.7-21.4-21.8C2085.9,143.8,2083.3,134,2083.3,123.5z M2092.9,123.5
|
||||
c0,9,2.2,17.4,6.7,25.1c4.4,7.7,10.5,13.7,18.1,18.1c7.6,4.4,15.9,6.5,24.8,6.5c8.9,0,17.2-2.2,24.9-6.7s13.7-10.5,18-18.1
|
||||
c4.4-7.6,6.5-16,6.5-25s-2.2-17.3-6.5-24.9c-4.4-7.6-10.4-13.6-18-18s-16-6.6-24.9-6.6s-17.2,2.2-24.8,6.5
|
||||
c-7.7,4.3-13.7,10.4-18.1,18C2095.1,106.2,2092.9,114.5,2092.9,123.5z M2130.2,129.4v26.7h-11.7v-67h23c8.5,0,15.1,1.7,19.8,5.2
|
||||
c4.7,3.4,7,8.5,7,15s-3.6,11.4-10.7,14.8c6.8,2.6,10.2,8,10.2,16.1v4.8c0,4.5,0.5,7.8,1.4,9.8v1.3h-12.1
|
||||
c-0.8-1.9-1.2-5.3-1.2-10.1c0-4.9-0.1-7.8-0.2-8.6c-0.9-5.1-4.5-7.7-10.9-7.9h-14.6V129.4z M2130.2,119.3h13c4-0.1,7.2-1,9.7-2.8
|
||||
c2.4-1.7,3.7-4,3.7-6.8c0-3.8-1.1-6.5-3.2-8.1c-2.2-1.6-6-2.4-11.6-2.4h-11.5L2130.2,119.3L2130.2,119.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M365.2,83.8c5.7-8.5,0.5-19.3-9.4-19.3H266h-40h-29.4c-33.5,0-60.2,8.9-79.9,26.7
|
||||
c-19.7,17.7-31,43.1-34,76.3l0,0l-7.6,86.8l0,0c-2.8,33.2,4.1,58.6,20.7,76.3c16.7,17.8,41.8,26.7,75.3,26.7h36.4v-0.2
|
||||
c7.2-1,11.1-5.4,11.8-13.1l3.7-42.6c0.7-7.7-5-14-12.8-14H190c-13.1,0-22.3-2.9-27.6-8.6c-5.2-5.7-7.2-15.4-6.1-29l6.8-77.8
|
||||
c1.2-13.6,4.9-23.2,11.1-28.9c6.2-5.7,15.9-8.6,29.1-8.6h16.6h26.6h64.2c12.7,0,25-6.7,32.3-17.7L365.2,83.8z"/>
|
||||
<path class="st1" d="M59.3,454.3c-5.7,8.5-0.5,19.3,9.4,19.3h92.1h40h29.4c33.5,0,60.2-8.9,79.9-26.7c19.7-17.7,31-43.1,34-76.3
|
||||
l0,0l7.6-86.8l0,0c2.8-33.2-4.1-58.6-20.7-76.3c-16.7-17.8-41.8-26.7-75.3-26.7h-36.4v0.2c-7.2,1-11.1,5.4-11.8,13.1l-3.7,42.6
|
||||
c-0.7,7.7,5,14,12.8,14H237c13.1,0,22.3,2.9,27.6,8.6c5.2,5.7,7.2,15.4,6.1,28.9l-6.8,77.8c-1.2,13.6-4.9,23.2-11.1,28.9
|
||||
c-6.2,5.7-15.9,8.6-29.1,8.6H207h-26.6h-66.5c-12.7,0-25,6.7-32.3,17.7L59.3,454.3z"/>
|
||||
</g>
|
||||
<path class="st0" d="M607,473.6H399c-8.9,0-13-4.4-12.2-13.4l33.5-382.3c0.8-8.9,5.6-13.4,14.5-13.4h208c8.5,0,12.3,4.4,11.6,13.4
|
||||
l-3.8,43.3c-0.8,8.9-5.4,13.4-13.9,13.4h-133c-5.1,0-7.8,2.3-8.2,7l-7.2,82.7c-0.4,4.7,1.9,7,7,7h108.8c8.9,0,13,4.5,12.2,13.4
|
||||
l-3.8,43.3c-0.8,8.9-5.6,13.4-14.5,13.4H489.2c-5.1,0-7.8,2.3-8.2,7l-7.7,88.4c-0.4,4.7,1.9,7,7,7h132.9c8.5,0,12.3,4.5,11.6,13.4
|
||||
l-3.8,43.3C620.1,469.1,615.5,473.6,607,473.6"/>
|
||||
<path class="st0" d="M831.4,473.6h-69.3c-33.5,0-58.6-8.9-75.3-26.7c-16.7-17.8-23.6-43.5-20.6-77l17.6-201.7
|
||||
c2.9-33.5,14.3-59.2,34.1-77s46.4-26.7,79.9-26.7h69.3c33.1,0,58.1,9,74.9,27c16.9,18,23.9,43.6,21,76.6l-2.6,29.9
|
||||
c-0.8,9.3-5.9,14-15.2,14h-53.4c-8.9,0-13-4.7-12.1-14l2.3-26.1c1.2-13.6-0.8-23.2-6.1-28.9c-5.2-5.7-14.6-8.6-28.2-8.6h-43.3
|
||||
c-13.1,0-22.8,2.9-29.1,8.6c-6.2,5.7-9.9,15.4-11.1,28.9l-17,194c-1.2,13.6,0.8,23.2,6.1,28.9c5.2,5.7,14.4,8.6,27.6,8.6h43.3
|
||||
c13.6,0,23.5-2.9,29.7-8.6s9.9-15.4,11.1-28.9l2.3-26.1c0.8-9.3,5.7-14,14.6-14h53.4c9.3,0,13.6,4.7,12.8,14l-2.6,29.9
|
||||
c-2.9,33.1-14.4,58.6-34.4,76.6C891,464.6,864.5,473.6,831.4,473.6"/>
|
||||
<path class="st0" d="M1127,473.6h-53.4c-9.3,0-13.6-4.4-12.8-13.4l27.9-318.7c0.4-4.7-1.7-7-6.4-7h-72.5c-8.9,0-13-4.4-12.2-13.4
|
||||
l3.8-43.3c0.8-8.9,5.6-13.4,14.5-13.4h240.4c8.9,0,13,4.4,12.2,13.4l-3.8,43.3c-0.8,8.9-5.6,13.4-14.5,13.4h-72.5
|
||||
c-5.1,0-7.8,2.3-8.2,7l-27.9,318.7C1140.7,469.1,1135.9,473.6,1127,473.6"/>
|
||||
<path class="st0" d="M1390.5,77.9L1357,460.2c-0.8,8.9-5.6,13.4-14.5,13.4h-54.1c-8.9,0-13-4.5-12.2-13.4l33.5-382.3
|
||||
c0.8-8.9,5.6-13.4,14.5-13.4h54.1C1387.2,64.5,1391.3,69,1390.5,77.9"/>
|
||||
<path class="st0" d="M1857.4,403.6h45.2c13.6,0,23.5-2.9,29.7-8.6s9.9-15.4,11.1-28.9l17-194c1.2-13.6-0.8-23.2-6.1-28.9
|
||||
c-5.2-5.7-14.6-8.6-28.2-8.6h-45.2c-13.6,0-23.4,2.9-29.4,8.6c-6,5.7-9.6,15.4-10.8,28.9l-17,194c-1.2,13.6,0.7,23.2,5.7,28.9
|
||||
C1834.6,400.7,1843.8,403.6,1857.4,403.6 M1909.8,473.6h-71.2c-33.5,0-58.6-8.9-75.3-26.7c-16.7-17.8-23.6-43.5-20.6-77
|
||||
l17.6-201.7c2.9-33.5,14.3-59.2,34.1-77c19.8-17.8,46.4-26.7,79.9-26.7h71.2c33.5,0,58.6,8.9,75.3,26.7
|
||||
c16.7,17.8,23.6,43.5,20.6,77l-17.6,201.7c-2.9,33.5-14.3,59.2-34.1,77C1970,464.7,1943.3,473.6,1909.8,473.6"/>
|
||||
<path class="st0" d="M1639.5,201.3h54.1c8.9,0,13.8-4.7,14.6-14l1.7-19.1c2.9-33.1-4-58.6-20.6-76.7c-16.7-18-41.5-27-74.6-27
|
||||
h-67.4c-33.5,0-60.2,8.9-79.9,26.7c-19.8,17.8-31.2,43.5-34.1,77l-17.6,201.7c-2.9,33.5,3.9,59.2,20.6,77s41.8,26.7,75.3,26.7
|
||||
h67.4c33.1,0,59.5-9,79.3-27s31.2-43.6,34.1-76.7l9.3-106.2c0.9-9.8-3.6-14.6-13.4-14.6H1577h-14.6c-9.9,0-17,10.7-12.8,19.3
|
||||
l16.4,33c5.4,10.9,16.6,17.7,29.2,17.7h13.8c4.7,0,6.8,2.3,6.4,7l-3.5,40.1c-1.2,13.6-4.8,23.2-10.8,29c-6,5.7-15.8,8.6-29.4,8.6
|
||||
h-41.4c-13.1,0-22.3-2.9-27.6-8.6c-5.2-5.7-7.2-15.4-6.1-29l17-194c1.2-13.6,4.9-23.2,11.1-28.9s15.9-8.6,29.1-8.6h41.4
|
||||
c13.6,0,22.9,2.9,27.9,8.6c5,5.7,6.9,15.4,5.7,28.9l-1.3,15.3C1626.5,196.6,1630.6,201.3,1639.5,201.3"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
BIN
frontend/apps/allin-ssl/public/static/icons/ssltrus-ico-dark.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
frontend/apps/allin-ssl/public/static/icons/ssltrus-ico.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.000000" height="16.000000" fill="none">
|
||||
<rect id="太阳1 1" width="16.000000" height="16.000000" x="0.000000" y="0.000000" />
|
||||
<path id="矢量 668" d="M7.99996 12.3333C10.3932 12.3333 12.3333 10.3932 12.3333 7.99996C12.3333 5.60673 10.3932 3.66663 7.99996 3.66663C5.60673 3.66663 3.66663 5.60673 3.66663 7.99996C3.66663 10.3932 5.60673 12.3333 7.99996 12.3333Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 668" d="M12.3333 7.99996C12.3333 5.60673 10.3932 3.66663 7.99996 3.66663C5.60673 3.66663 3.66663 5.60673 3.66663 7.99996C3.66663 10.3932 5.60673 12.3333 7.99996 12.3333C10.3932 12.3333 12.3333 10.3932 12.3333 7.99996Z" fill-rule="nonzero" stroke="rgb(255,255,255)" stroke-linejoin="round" stroke-width="1.5" />
|
||||
<path id="矢量 669" d="M7.99996 2.00004C8.46019 2.00004 8.83329 1.62694 8.83329 1.16671C8.83329 0.706471 8.46019 0.333374 7.99996 0.333374C7.53973 0.333374 7.16663 0.706471 7.16663 1.16671C7.16663 1.62694 7.53973 2.00004 7.99996 2.00004Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 670" d="M12.8333 4.00004C13.2936 4.00004 13.6667 3.62694 13.6667 3.16671C13.6667 2.70647 13.2936 2.33337 12.8333 2.33337C12.3731 2.33337 12 2.70647 12 3.16671C12 3.62694 12.3731 4.00004 12.8333 4.00004Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 671" d="M14.8333 8.83329C15.2936 8.83329 15.6667 8.46019 15.6667 7.99996C15.6667 7.53973 15.2936 7.16663 14.8333 7.16663C14.3731 7.16663 14 7.53973 14 7.99996C14 8.46019 14.3731 8.83329 14.8333 8.83329Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 672" d="M12.8333 13.6667C13.2936 13.6667 13.6667 13.2936 13.6667 12.8333C13.6667 12.3731 13.2936 12 12.8333 12C12.3731 12 12 12.3731 12 12.8333C12 13.2936 12.3731 13.6667 12.8333 13.6667Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 673" d="M7.99996 15.6667C8.46019 15.6667 8.83329 15.2936 8.83329 14.8333C8.83329 14.3731 8.46019 14 7.99996 14C7.53973 14 7.16663 14.3731 7.16663 14.8333C7.16663 15.2936 7.53973 15.6667 7.99996 15.6667Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 674" d="M3.16671 13.6667C3.62694 13.6667 4.00004 13.2936 4.00004 12.8333C4.00004 12.3731 3.62694 12 3.16671 12C2.70647 12 2.33337 12.3731 2.33337 12.8333C2.33337 13.2936 2.70647 13.6667 3.16671 13.6667Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 675" d="M1.16671 8.83329C1.62694 8.83329 2.00004 8.46019 2.00004 7.99996C2.00004 7.53973 1.62694 7.16663 1.16671 7.16663C0.706471 7.16663 0.333374 7.53973 0.333374 7.99996C0.333374 8.46019 0.706471 8.83329 1.16671 8.83329Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
<path id="矢量 676" d="M3.16671 4.00004C3.62694 4.00004 4.00004 3.62694 4.00004 3.16671C4.00004 2.70647 3.62694 2.33337 3.16671 2.33337C2.70647 2.33337 2.33337 2.70647 2.33337 3.16671C2.33337 3.62694 2.70647 4.00004 3.16671 4.00004Z" fill="rgb(255,255,255)" fill-rule="nonzero" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
13
frontend/apps/allin-ssl/public/static/icons/theme-icon.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.000000" height="16.000000" fill="none">
|
||||
<rect id="太阳1 1" width="16.000000" height="16.000000" x="0.000000" y="0.000000" />
|
||||
<path id="矢量 668" d="M7.99996 12.3333C10.3932 12.3333 12.3333 10.3932 12.3333 7.99999C12.3333 5.60676 10.3932 3.66666 7.99996 3.66666C5.60673 3.66666 3.66663 5.60676 3.66663 7.99999C3.66663 10.3932 5.60673 12.3333 7.99996 12.3333Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 668" d="M12.3333 7.99999C12.3333 5.60676 10.3932 3.66666 7.99996 3.66666C5.60673 3.66666 3.66663 5.60676 3.66663 7.99999C3.66663 10.3932 5.60673 12.3333 7.99996 12.3333C10.3932 12.3333 12.3333 10.3932 12.3333 7.99999Z" fill-rule="nonzero" stroke="rgb(0,0,0)" stroke-linejoin="round" stroke-width="1.5" />
|
||||
<path id="矢量 669" d="M7.99996 2.00001C8.46019 2.00001 8.83329 1.62691 8.83329 1.16668C8.83329 0.70644 8.46019 0.333344 7.99996 0.333344C7.53973 0.333344 7.16663 0.70644 7.16663 1.16668C7.16663 1.62691 7.53973 2.00001 7.99996 2.00001Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 670" d="M12.8333 4.00001C13.2936 4.00001 13.6667 3.62691 13.6667 3.16668C13.6667 2.70644 13.2936 2.33334 12.8333 2.33334C12.3731 2.33334 12 2.70644 12 3.16668C12 3.62691 12.3731 4.00001 12.8333 4.00001Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 671" d="M14.8333 8.83332C15.2936 8.83332 15.6667 8.46022 15.6667 7.99999C15.6667 7.53976 15.2936 7.16666 14.8333 7.16666C14.3731 7.16666 14 7.53976 14 7.99999C14 8.46022 14.3731 8.83332 14.8333 8.83332Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 672" d="M12.8333 13.6667C13.2936 13.6667 13.6667 13.2936 13.6667 12.8333C13.6667 12.3731 13.2936 12 12.8333 12C12.3731 12 12 12.3731 12 12.8333C12 13.2936 12.3731 13.6667 12.8333 13.6667Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 673" d="M7.99996 15.6667C8.46019 15.6667 8.83329 15.2936 8.83329 14.8333C8.83329 14.3731 8.46019 14 7.99996 14C7.53973 14 7.16663 14.3731 7.16663 14.8333C7.16663 15.2936 7.53973 15.6667 7.99996 15.6667Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 674" d="M3.16671 13.6667C3.62694 13.6667 4.00004 13.2936 4.00004 12.8333C4.00004 12.3731 3.62694 12 3.16671 12C2.70647 12 2.33337 12.3731 2.33337 12.8333C2.33337 13.2936 2.70647 13.6667 3.16671 13.6667Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 675" d="M1.16671 8.83332C1.62694 8.83332 2.00004 8.46022 2.00004 7.99999C2.00004 7.53976 1.62694 7.16666 1.16671 7.16666C0.706471 7.16666 0.333374 7.53976 0.333374 7.99999C0.333374 8.46022 0.706471 8.83332 1.16671 8.83332Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
<path id="矢量 676" d="M3.16671 4.00001C3.62694 4.00001 4.00004 3.62691 4.00004 3.16668C4.00004 2.70644 3.62694 2.33334 3.16671 2.33334C2.70647 2.33334 2.33337 2.70644 2.33337 3.16668C2.33337 3.62691 2.70647 4.00001 3.16671 4.00001Z" fill="rgb(0,0,0)" fill-rule="nonzero" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="1440.855" height="900.46" viewBox="0 0 1440.85 900.46" fill="none" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="0" y1="724" x2="442.31" y2="898.26" id="a" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset=".969" stop-color="#333" stop-opacity=".969"/><stop offset="1" stop-color="#E3E4E8" stop-opacity="0"/></linearGradient><linearGradient x1="995.427" y1="642.73" x2="466.927" y2="898.31" id="b" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset="1" stop-color="#333"/></linearGradient><linearGradient x1="0" y1="653.04" x2="1120.19" y2="653.04" id="c" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset="1" stop-color="#333"/></linearGradient><linearGradient x1=".7" y1="58.87" x2="382.18" y2="58.87" id="d" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset="1" stop-color="#333"/></linearGradient><linearGradient x1="1440.355" y1="665.73" x2="1152.355" y2="900.23" id="e" gradientUnits="userSpaceOnUse"><stop stop-color="#333"/><stop offset="1" stop-color="#121212"/></linearGradient><linearGradient x1="1206.355" y1="1.73" x2="1460.355" y2="314.73" id="f" gradientUnits="userSpaceOnUse"><stop stop-color="#121212"/><stop offset=".995" stop-color="#333" stop-opacity=".792"/></linearGradient></defs><path fill="#121212" d="M.7.46h1440v900H.7z"/><path d="M3.09 755.27 0 724.46l442.31 174.26h-79.56L3.09 755.27z" fill="url(#a)"/><path d="M532.78 898.72h83.62l526.16-259.19-22.38-27.13-587.4 286.32z" fill="url(#b)"/><path d="m3.09 585.09 470.03-177.73 647.06 205.04-587.4 286.32h-90.47L0 724.46l3.09-139.37z" fill="url(#c)"/><path d="m.7 79.92 88.22 37.37L382.18.45H.7v79.47z" fill="url(#d)"/><path d="M1440.35 665.73v234.5h-288l288-234.5z" fill="url(#e)" fill-opacity=".9" fill-rule="evenodd"/><path d="M1206.35 1.72h234.5v288.01L1206.35 1.72z" fill="url(#f)" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="1440.855" height="900.46" viewBox="0 0 1440.85 900.46" fill="none" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="0" y1="653.04" x2="1120.19" y2="653.04" id="a" gradientUnits="userSpaceOnUse"><stop stop-color="#F0F0F2"/><stop offset="1" stop-color="#F3F4F6"/></linearGradient><linearGradient x1=".7" y1="58.87" x2="382.18" y2="58.87" id="b" gradientUnits="userSpaceOnUse"><stop stop-color="#EBEBED"/><stop offset="1" stop-color="#F3F4F6"/></linearGradient><linearGradient x1="1506.855" y1="665.73" x2="1152.355" y2="900.23" id="c" gradientUnits="userSpaceOnUse"><stop stop-color="#EBECEE"/><stop offset="1" stop-color="#F2F3F5"/></linearGradient><linearGradient x1="1206.355" y1="1.73" x2="1460.355" y2="314.73" id="d" gradientUnits="userSpaceOnUse"><stop offset=".282" stop-color="#F1F2F3"/><stop offset="1" stop-color="#EBECEE" stop-opacity=".792"/></linearGradient></defs><path fill="#F3F4F6" d="M.7.46h1440v900H.7z"/><path d="M3.09 755.27 0 724.46l442.31 174.26h-79.56L3.09 755.27z" fill="#E3E4E8"/><path d="M532.78 898.72h83.62l526.16-259.19-22.38-27.13-587.4 286.32z" fill="#FBFBFC"/><path d="m3.09 585.09 470.03-177.73 647.06 205.04-587.4 286.32h-90.47L0 724.46l3.09-139.37z" fill="url(#a)"/><path d="m.7 79.92 88.22 37.37L382.18.45H.7v79.47z" fill="url(#b)"/><path d="M1440.35 665.73v234.5h-288l288-234.5z" fill="url(#c)" fill-opacity=".9" fill-rule="evenodd"/><path d="M1206.35 1.72h234.5v288.01L1206.35 1.72z" fill="url(#d)" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 13 KiB |
BIN
frontend/apps/allin-ssl/public/static/images/logo-dark.png
Normal file
|
After Width: | Height: | Size: 343 KiB |
BIN
frontend/apps/allin-ssl/public/static/images/logo.png
Normal file
|
After Width: | Height: | Size: 364 KiB |
145
frontend/apps/allin-ssl/script/create-alias.sh
Normal file
@@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 获取脚本所在目录的绝对路径
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# 项目根目录
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
# src 目录
|
||||
SRC_DIR="$PROJECT_ROOT/src"
|
||||
# tmp 目录
|
||||
TMP_DIR="$PROJECT_ROOT/.temp"
|
||||
|
||||
# 临时文件
|
||||
TEMP_PATHS_FILE="$TMP_DIR/tsconfig_paths.json"
|
||||
TEMP_ALIAS_FILE="$TMP_DIR/vite_alias.js"
|
||||
|
||||
# 清理函数
|
||||
cleanup() {
|
||||
echo "清理临时文件..."
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
|
||||
# 错误处理
|
||||
handle_error() {
|
||||
echo "错误: $1"
|
||||
cleanup
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 注册清理函数
|
||||
trap cleanup EXIT
|
||||
|
||||
# 检查并创建 tmp 目录
|
||||
if [ ! -d "$TMP_DIR" ]; then
|
||||
echo "创建临时目录: $TMP_DIR"
|
||||
mkdir -p "$TMP_DIR" || handle_error "无法创建临时目录"
|
||||
fi
|
||||
|
||||
# 初始化临时文件
|
||||
echo "{" > "$TEMP_PATHS_FILE"
|
||||
echo "import path from 'path'" > "$TEMP_ALIAS_FILE"
|
||||
echo "export default {" >> "$TEMP_ALIAS_FILE"
|
||||
|
||||
# 处理 views 目录下的第一层目录
|
||||
if [ -d "$SRC_DIR/views" ]; then
|
||||
echo "处理 views 目录..."
|
||||
# 确保没有尾随逗号的最后一个条目
|
||||
view_dirs=()
|
||||
while IFS= read -r dir; do
|
||||
if [ -d "$dir" ]; then
|
||||
dir_name=$(basename "$dir")
|
||||
view_dirs+=("$dir_name")
|
||||
fi
|
||||
done < <(find "$SRC_DIR/views" -mindepth 1 -maxdepth 1 -type d)
|
||||
|
||||
# 处理 views 子目录
|
||||
total=${#view_dirs[@]}
|
||||
for ((i=0; i<total; i++)); do
|
||||
dir_name=${view_dirs[$i]}
|
||||
echo " \"@$dir_name/*\": [\"./src/views/$dir_name/*\"]" >> "$TEMP_PATHS_FILE"
|
||||
echo " '@$dir_name': path.resolve(__dirname, 'src/views/$dir_name')," >> "$TEMP_ALIAS_FILE"
|
||||
# 如果不是最后一个元素,添加逗号
|
||||
if [ $i -lt $((total-1)) ]; then
|
||||
echo "," >> "$TEMP_PATHS_FILE"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# 处理 src 目录下的所有目录
|
||||
echo "处理 src 目录下的其他目录..."
|
||||
src_dirs=()
|
||||
while IFS= read -r dir; do
|
||||
if [ -d "$dir" ] && [ "$(basename "$dir")" != "views" ]; then
|
||||
dir_name=$(basename "$dir")
|
||||
src_dirs+=("$dir_name")
|
||||
fi
|
||||
done < <(find "$SRC_DIR" -mindepth 1 -maxdepth 1 -type d)
|
||||
|
||||
# 如果之前有 views 目录的条目,添加逗号
|
||||
if [ ${#view_dirs[@]} -gt 0 ] && [ ${#src_dirs[@]} -gt 0 ]; then
|
||||
echo "," >> "$TEMP_PATHS_FILE"
|
||||
fi
|
||||
|
||||
# 处理其他目录
|
||||
total=${#src_dirs[@]}
|
||||
for ((i=0; i<total; i++)); do
|
||||
dir_name=${src_dirs[$i]}
|
||||
echo " \"@$dir_name/*\": [\"./src/$dir_name/*\"]" >> "$TEMP_PATHS_FILE"
|
||||
echo " '@$dir_name': path.resolve(__dirname, 'src/$dir_name')," >> "$TEMP_ALIAS_FILE"
|
||||
# 如果不是最后一个元素,添加逗号
|
||||
if [ $i -lt $((total-1)) ]; then
|
||||
echo "," >> "$TEMP_PATHS_FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
# 添加根路径(确保添加逗号如果之前有其他条目)
|
||||
if [ ${#view_dirs[@]} -gt 0 ] || [ ${#src_dirs[@]} -gt 0 ]; then
|
||||
echo "," >> "$TEMP_PATHS_FILE"
|
||||
fi
|
||||
echo " \"@/*\": [\"./src/*\"]" >> "$TEMP_PATHS_FILE"
|
||||
echo "}" >> "$TEMP_PATHS_FILE"
|
||||
|
||||
# 添加根路径到 alias 配置
|
||||
echo " '@': path.resolve(__dirname, 'src')" >> "$TEMP_ALIAS_FILE"
|
||||
echo "}" >> "$TEMP_ALIAS_FILE"
|
||||
|
||||
# 更新 tsconfig.app.json
|
||||
echo "更新 tsconfig.app.json..."
|
||||
TSCONFIG="$PROJECT_ROOT/tsconfig.app.json"
|
||||
if [ -f "$TSCONFIG" ]; then
|
||||
# 创建临时文件
|
||||
TSCONFIG_TMP="${TSCONFIG}.tmp"
|
||||
|
||||
# 使用 jq 处理 JSON(如果可用)
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
jq --arg paths "$(cat "$TEMP_PATHS_FILE")" '.compilerOptions.paths = $paths' "$TSCONFIG" > "$TSCONFIG_TMP" \
|
||||
&& mv "$TSCONFIG_TMP" "$TSCONFIG" \
|
||||
|| handle_error "更新 tsconfig.app.json 失败"
|
||||
else
|
||||
# 回退到 sed 方案
|
||||
sed -e '/"paths":/,/}/c\ "paths": '"$(cat "$TEMP_PATHS_FILE")"',' "$TSCONFIG" > "$TSCONFIG_TMP" \
|
||||
&& mv "$TSCONFIG_TMP" "$TSCONFIG" \
|
||||
|| handle_error "更新 tsconfig.app.json 失败"
|
||||
fi
|
||||
echo "tsconfig.app.json 更新成功"
|
||||
else
|
||||
handle_error "找不到 tsconfig.app.json 文件"
|
||||
fi
|
||||
|
||||
# 更新 vite.config.ts
|
||||
echo "更新 vite.config.ts..."
|
||||
VITE_CONFIG="$PROJECT_ROOT/vite.config.ts"
|
||||
if [ -f "$VITE_CONFIG" ]; then
|
||||
VITE_CONFIG_TMP="${VITE_CONFIG}.tmp"
|
||||
|
||||
# 使用 sed 更新 alias 配置
|
||||
sed -e '/resolve: {/,/}/c\ resolve: {\n alias: '"$(cat "$TEMP_ALIAS_FILE")"'\n },' "$VITE_CONFIG" > "$VITE_CONFIG_TMP" \
|
||||
&& mv "$VITE_CONFIG_TMP" "$VITE_CONFIG" \
|
||||
|| handle_error "更新 vite.config.ts 失败"
|
||||
|
||||
echo "vite.config.ts 更新成功"
|
||||
else
|
||||
handle_error "找不到 vite.config.ts 文件"
|
||||
fi
|
||||
|
||||
echo "路径别名配置更新完成!"
|
||||
891
frontend/apps/allin-ssl/script/create-roles.sh
Normal file
@@ -0,0 +1,891 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 遇到错误时退出
|
||||
set -e
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
echo "使用方法: ./create-roles.sh [选项]"
|
||||
echo "选项:"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo
|
||||
echo "此脚本在 src/views 目录下创建角色管理相关的 Vue3 TSX 路由视图结构"
|
||||
echo "将生成以下结构:"
|
||||
echo "src/views/<角色名称>"
|
||||
echo "├── index.tsx # 入口文件"
|
||||
echo "├── useController.ts # 控制器"
|
||||
echo "├── useStore.ts # 状态管理"
|
||||
echo "├── index.module.css # 样式文件"
|
||||
echo "├── types.d.ts # 类型定义"
|
||||
echo "├── children/ # 子路由"
|
||||
echo "│ └── permissions # 权限管理子路由"
|
||||
echo "│ ├── index.tsx # 视图"
|
||||
echo "│ ├── index.module.css # 样式"
|
||||
echo "│ ├── useController.ts # 控制器"
|
||||
echo "│ ├── useStore.ts # 状态管理"
|
||||
echo "│ └── types.d.ts # 类型定义"
|
||||
echo "└── components/ # 组件"
|
||||
echo " └── role-form # 角色表单组件"
|
||||
echo " ├── index.tsx # 视图"
|
||||
echo " ├── index.module.css # 样式"
|
||||
echo " ├── useController.ts # 控制器"
|
||||
echo " ├── useStore.ts # 状态管理"
|
||||
echo " └── types.d.ts # 类型定义"
|
||||
echo
|
||||
echo "同时会创建:"
|
||||
echo "src/api/<角色名称>.ts # API 文件"
|
||||
echo "src/types/<角色名称>.d.ts # 类型定义文件"
|
||||
}
|
||||
|
||||
# 解析命令行参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "错误: 未知参数 $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 交互式选择函数
|
||||
select_option() {
|
||||
local prompt="$1"
|
||||
local options=("是" "否")
|
||||
local selected
|
||||
|
||||
echo "$prompt"
|
||||
select choice in "${options[@]}"; do
|
||||
case $REPLY in
|
||||
1|2)
|
||||
selected=$choice
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "请选择有效的选项 [1-2]"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ "$selected" == "是" ]] && return 0 || return 1
|
||||
}
|
||||
|
||||
# 交互式输入路由名称
|
||||
read -p "请输入路由名称 (routerName): " ROUTER_NAME
|
||||
if [ -z "$ROUTER_NAME" ]; then
|
||||
echo "错误: 路由名称不能为空"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 询问是否创建子路由
|
||||
if select_option "是否创建子路由?"; then
|
||||
read -p "请输入子路由名称 [默认: list]: " CHILD_ROUTER_NAME
|
||||
CHILD_ROUTER_NAME=${CHILD_ROUTER_NAME:-"list"}
|
||||
echo "将创建子路由: $CHILD_ROUTER_NAME"
|
||||
else
|
||||
CHILD_ROUTER_NAME=""
|
||||
echo "不创建子路由"
|
||||
fi
|
||||
|
||||
# 询问是否创建组件
|
||||
if select_option "是否创建组件?"; then
|
||||
read -p "请输入组件名称 [默认: todo-form]: " COMPONENT_NAME
|
||||
COMPONENT_NAME=${COMPONENT_NAME:-"todo-form"}
|
||||
echo "将创建组件: $COMPONENT_NAME"
|
||||
else
|
||||
COMPONENT_NAME=""
|
||||
echo "不创建组件"
|
||||
fi
|
||||
|
||||
# 获取脚本所在目录的绝对路径
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
# 获取项目根目录
|
||||
PROJECT_ROOT="$SCRIPT_DIR/../"
|
||||
|
||||
# 创建目录函数
|
||||
create_dir() {
|
||||
local dir="$1"
|
||||
mkdir -p "$PROJECT_ROOT/$dir"
|
||||
}
|
||||
|
||||
# 确保必需的目录存在
|
||||
create_dir "src/views"
|
||||
create_dir "src/api"
|
||||
create_dir "src/types"
|
||||
|
||||
# 创建主目录结构
|
||||
create_dir "src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME"
|
||||
create_dir "src/views/$ROUTER_NAME/components/$COMPONENT_NAME"
|
||||
|
||||
# 创建 API 文件
|
||||
cat > "$PROJECT_ROOT/src/api/${ROUTER_NAME}.ts" << ''
|
||||
|
||||
# 创建类型定义文件
|
||||
cat > "$PROJECT_ROOT/src/types/${ROUTER_NAME}.d.ts" << ''
|
||||
|
||||
# 创建主路由类型文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/types.d.ts" << EOL
|
||||
export interface Todo {
|
||||
id: string
|
||||
title: string
|
||||
completed: boolean
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export interface TodoState {
|
||||
todos: Todo[]
|
||||
loading: boolean
|
||||
error: string | null
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建主路由状态管理文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/useStore.ts" << EOL
|
||||
import { defineStore } from '@baota/pinia'
|
||||
import { ref } from 'vue'
|
||||
import type { Todo, TodoState } from './types'
|
||||
|
||||
const store = defineStore('todo-store', () => {
|
||||
const todos = ref<Todo[]>([])
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
const addTodo = (title: string) => {
|
||||
const newTodo: Todo = {
|
||||
id: Date.now().toString(),
|
||||
title,
|
||||
completed: false,
|
||||
createdAt: new Date().toISOString()
|
||||
}
|
||||
todos.value.push(newTodo)
|
||||
}
|
||||
|
||||
const toggleTodo = (id: string) => {
|
||||
const todo = todos.value.find(t => t.id === id)
|
||||
if (todo) {
|
||||
todo.completed = !todo.completed
|
||||
}
|
||||
}
|
||||
|
||||
const removeTodo = (id: string) => {
|
||||
todos.value = todos.value.filter(t => t.id !== id)
|
||||
}
|
||||
|
||||
return {
|
||||
todos,
|
||||
loading,
|
||||
error,
|
||||
addTodo,
|
||||
toggleTodo,
|
||||
removeTodo
|
||||
}
|
||||
})
|
||||
|
||||
export const useStore = () => store()
|
||||
EOL
|
||||
|
||||
# 创建主路由控制器文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/useController.ts" << EOL
|
||||
import { onMounted } from 'vue'
|
||||
import { storeToRefs } from '@baota/pinia'
|
||||
import { useStore } from './useStore'
|
||||
|
||||
export const useController = () => {
|
||||
const store = useStore()
|
||||
const { todos, loading, error } = storeToRefs(store)
|
||||
|
||||
const handleAddTodo = (title: string) => {
|
||||
if (title.trim()) {
|
||||
store.addTodo(title.trim())
|
||||
}
|
||||
}
|
||||
|
||||
const handleToggleTodo = (id: string) => {
|
||||
store.toggleTodo(id)
|
||||
}
|
||||
|
||||
const handleRemoveTodo = (id: string) => {
|
||||
store.removeTodo(id)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 可以在这里加载初始数据
|
||||
console.log('Todo List Component Mounted')
|
||||
})
|
||||
|
||||
return {
|
||||
todos,
|
||||
loading,
|
||||
error,
|
||||
handleAddTodo,
|
||||
handleToggleTodo,
|
||||
handleRemoveTodo
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建主路由样式文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/index.module.css" << EOL
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 32px;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.input {
|
||||
flex: 1;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 8px 16px;
|
||||
background: #42b883;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #3aa876;
|
||||
}
|
||||
|
||||
.todoList {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.todoItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.todoCheckbox {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.todoTitle {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.todoTitle.completed {
|
||||
text-decoration: line-through;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.deleteButton {
|
||||
padding: 4px 8px;
|
||||
background: #ff4757;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.deleteButton:hover {
|
||||
background: #ff3748;
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建主路由入口文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/index.tsx" << EOL
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { useController } from './useController'
|
||||
import styles from './index.module.css'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TodoList',
|
||||
|
||||
setup() {
|
||||
const { todos, handleAddTodo, handleToggleTodo, handleRemoveTodo } = useController()
|
||||
const newTodo = ref('')
|
||||
|
||||
const onSubmit = (e: Event) => {
|
||||
e.preventDefault()
|
||||
handleAddTodo(newTodo.value)
|
||||
newTodo.value = ''
|
||||
}
|
||||
|
||||
return () => (
|
||||
<div class={styles.container}>
|
||||
<header class={styles.header}>
|
||||
<h1 class={styles.title}>Todo List</h1>
|
||||
</header>
|
||||
|
||||
<form class={styles.form} onSubmit={onSubmit}>
|
||||
<input
|
||||
class={styles.input}
|
||||
type="text"
|
||||
v-model={newTodo.value}
|
||||
placeholder="添加新任务..."
|
||||
/>
|
||||
<button class={styles.button} type="submit">
|
||||
添加
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<ul class={styles.todoList}>
|
||||
{todos.value.map(todo => (
|
||||
<li key={todo.id} class={styles.todoItem}>
|
||||
<input
|
||||
type="checkbox"
|
||||
class={styles.todoCheckbox}
|
||||
checked={todo.completed}
|
||||
onChange={() => handleToggleTodo(todo.id)}
|
||||
/>
|
||||
<span class={[
|
||||
styles.todoTitle,
|
||||
todo.completed && styles.completed
|
||||
]}>
|
||||
{todo.title}
|
||||
</span>
|
||||
<button
|
||||
class={styles.deleteButton}
|
||||
onClick={() => handleRemoveTodo(todo.id)}
|
||||
>
|
||||
删除
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
EOL
|
||||
|
||||
# 在脚本开头添加大写转换函数
|
||||
to_upper_first() {
|
||||
local str="$1"
|
||||
local first_char=$(echo "${str:0:1}" | tr '[:lower:]' '[:upper:]')
|
||||
echo "$first_char${str:1}"
|
||||
}
|
||||
|
||||
# 存储转换后的变量
|
||||
ROUTER_NAME_PASCAL=$(to_upper_first "$ROUTER_NAME")
|
||||
|
||||
# 创建表单组件类型文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/types.d.ts" << EOL
|
||||
import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
|
||||
|
||||
export interface FormProps {
|
||||
data?: ${ROUTER_NAME_PASCAL}Data | null
|
||||
}
|
||||
|
||||
export interface FormEmits {
|
||||
(e: 'submit', data: ${ROUTER_NAME_PASCAL}Data): void
|
||||
(e: 'cancel'): void
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建表单组件状态管理文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/useStore.ts" << EOL
|
||||
import { defineStore } from '@baota/pinia'
|
||||
import { ref } from 'vue'
|
||||
import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
|
||||
|
||||
// 定义 store
|
||||
const store = defineStore('${ROUTER_NAME}-form-store', () => {
|
||||
const loading = ref(false)
|
||||
const formData = ref<${ROUTER_NAME_PASCAL}Data>({
|
||||
id: '',
|
||||
name: '',
|
||||
code: '',
|
||||
description: '',
|
||||
permissions: [],
|
||||
createdAt: '',
|
||||
updatedAt: ''
|
||||
})
|
||||
|
||||
return {
|
||||
loading,
|
||||
formData
|
||||
}
|
||||
})
|
||||
|
||||
export const useStore = () => store()
|
||||
EOL
|
||||
|
||||
# 创建表单组件控制器文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/useController.ts" << EOL
|
||||
import { onMounted } from 'vue'
|
||||
import { storeToRefs } from '@baota/pinia'
|
||||
import { useStore } from './useStore'
|
||||
import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
|
||||
|
||||
export const useController = (initialData?: ${ROUTER_NAME_PASCAL}Data | null) => {
|
||||
const store = useStore()
|
||||
const storeRef = storeToRefs(store)
|
||||
|
||||
onMounted(() => {
|
||||
if (initialData) {
|
||||
store.formData = { ...initialData }
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
...storeRef
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建表单组件样式文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/index.module.css" << EOL
|
||||
.form {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.formTitle {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.formItem {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.input:hover {
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
border-color: #1890ff;
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
|
||||
.textarea {
|
||||
composes: input;
|
||||
min-height: 100px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 8px 16px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.primaryButton {
|
||||
composes: button;
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.primaryButton:hover {
|
||||
background: #40a9ff;
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建表单组件入口文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/index.tsx" << EOL
|
||||
import { defineComponent } from 'vue'
|
||||
import { useController } from './useController'
|
||||
import type { FormProps, FormEmits } from './types'
|
||||
import styles from './index.module.css'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RoleForm',
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Object as PropType<FormProps['data']>,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['submit', 'cancel'],
|
||||
|
||||
setup(props, { emit }) {
|
||||
const { formData } = useController(props.data)
|
||||
|
||||
const handleSubmit = (e: Event) => {
|
||||
e.preventDefault()
|
||||
emit('submit', formData.value)
|
||||
}
|
||||
|
||||
return () => (
|
||||
<form class={styles.form} onSubmit={handleSubmit}>
|
||||
<h3 class={styles.formTitle}>
|
||||
{props.data ? '编辑角色' : '创建角色'}
|
||||
</h3>
|
||||
|
||||
<div class={styles.formItem}>
|
||||
<label class={styles.label}>角色名称</label>
|
||||
<input
|
||||
class={styles.input}
|
||||
type="text"
|
||||
v-model={formData.value.name}
|
||||
placeholder="请输入角色名称"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class={styles.formItem}>
|
||||
<label class={styles.label}>角色代码</label>
|
||||
<input
|
||||
class={styles.input}
|
||||
type="text"
|
||||
v-model={formData.value.code}
|
||||
placeholder="请输入角色代码"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class={styles.formItem}>
|
||||
<label class={styles.label}>描述</label>
|
||||
<textarea
|
||||
class={styles.textarea}
|
||||
v-model={formData.value.description}
|
||||
placeholder="请输入角色描述"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class={styles.actions}>
|
||||
<button
|
||||
type="button"
|
||||
class={styles.button}
|
||||
onClick={() => emit('cancel')}
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button type="submit" class={styles.primaryButton}>
|
||||
确定
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
})
|
||||
EOL
|
||||
|
||||
# 创建子路由类型文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/types.d.ts" << EOL
|
||||
import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
|
||||
|
||||
export interface Permission {
|
||||
code: string
|
||||
name: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export interface PermissionState {
|
||||
loading: boolean
|
||||
data: ${ROUTER_NAME_PASCAL}Data | null
|
||||
permissions: Permission[]
|
||||
selectedPermissions: string[]
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建子路由状态管理文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/useStore.ts" << EOL
|
||||
import { defineStore } from '@baota/pinia'
|
||||
import { ref } from 'vue'
|
||||
import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
|
||||
import type { Permission } from './types'
|
||||
|
||||
// 定义 store
|
||||
const store = defineStore('${ROUTER_NAME}-permissions-store', () => {
|
||||
const loading = ref(false)
|
||||
const data = ref<${ROUTER_NAME_PASCAL}Data | null>(null)
|
||||
const permissions = ref<Permission[]>([])
|
||||
const selectedPermissions = ref<string[]>([])
|
||||
|
||||
return {
|
||||
loading,
|
||||
data,
|
||||
permissions,
|
||||
selectedPermissions
|
||||
}
|
||||
})
|
||||
|
||||
// 导出 store
|
||||
export const useStore = () => store()
|
||||
EOL
|
||||
|
||||
# 创建子路由控制器文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/useController.ts" << EOL
|
||||
import { onMounted } from 'vue'
|
||||
import { storeToRefs } from '@baota/pinia'
|
||||
import { useStore } from './useStore'
|
||||
import { get${ROUTER_NAME_PASCAL}Data } from '@/api/${ROUTER_NAME}'
|
||||
|
||||
export const useController = (roleId: string) => {
|
||||
const store = useStore()
|
||||
const storeRef = storeToRefs(store)
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
store.loading = true
|
||||
const data = await get${ROUTER_NAME_PASCAL}Data(roleId)
|
||||
store.data = data
|
||||
store.selectedPermissions = data.permissions
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error)
|
||||
} finally {
|
||||
store.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
store.loading = true
|
||||
// 调用保存API
|
||||
store.loading = false
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
|
||||
return {
|
||||
...storeRef,
|
||||
handleSave
|
||||
}
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建子路由样式文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/index.module.css" << EOL
|
||||
.container {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.permissionList {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.permissionItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 8px 16px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.primaryButton {
|
||||
composes: button;
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.primaryButton:hover {
|
||||
background: #40a9ff;
|
||||
}
|
||||
EOL
|
||||
|
||||
# 创建子路由入口文件
|
||||
cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/index.tsx" << EOL
|
||||
import { defineComponent } from 'vue'
|
||||
import { useRoute, useRouter } from '@baota/router'
|
||||
import { useController } from './useController'
|
||||
import styles from './index.module.css'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RolePermissions',
|
||||
|
||||
setup() {
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const roleId = route.params.id as string
|
||||
|
||||
const {
|
||||
loading,
|
||||
data,
|
||||
permissions,
|
||||
selectedPermissions,
|
||||
handleSave
|
||||
} = useController(roleId)
|
||||
|
||||
const handleCancel = () => {
|
||||
router.push('/${ROUTER_NAME}')
|
||||
}
|
||||
|
||||
return () => (
|
||||
<div class={styles.container}>
|
||||
<div class={styles.header}>
|
||||
<h1 class={styles.title}>权限设置</h1>
|
||||
</div>
|
||||
|
||||
<div class={styles.content}>
|
||||
{loading.value ? (
|
||||
<div class={styles.loading}>加载中...</div>
|
||||
) : (
|
||||
<>
|
||||
<h2>{data.value?.name} - 权限配置</h2>
|
||||
|
||||
<div class={styles.permissionList}>
|
||||
{permissions.value.map(permission => (
|
||||
<label
|
||||
key={permission.code}
|
||||
class={styles.permissionItem}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
value={permission.code}
|
||||
v-model={selectedPermissions.value}
|
||||
/>
|
||||
<span>{permission.name}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div class={styles.actions}>
|
||||
<button
|
||||
class={styles.button}
|
||||
onClick={handleCancel}
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
class={styles.primaryButton}
|
||||
onClick={handleSave}
|
||||
>
|
||||
保存
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
EOL
|
||||
|
||||
echo "✨ 文件结构生成成功!"
|
||||
echo "📁 主路由: $PROJECT_ROOT/src/views/$ROUTER_NAME"
|
||||
echo "📁 子路由: $PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME"
|
||||
echo "📁 组件: $PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME"
|
||||
echo "📄 API文件: $PROJECT_ROOT/src/api/${ROUTER_NAME}.ts"
|
||||
echo "📄 类型文件: $PROJECT_ROOT/src/types/${ROUTER_NAME}.d.ts"
|
||||
echo
|
||||
echo "目录结构:"
|
||||
echo "├── src/views/$ROUTER_NAME"
|
||||
echo "│ ├── index.tsx"
|
||||
echo "│ ├── useController.ts"
|
||||
echo "│ ├── useStore.ts"
|
||||
echo "│ ├── index.module.css"
|
||||
echo "│ ├── types.d.ts"
|
||||
echo "│ ├── children"
|
||||
echo "│ │ └── $CHILD_ROUTER_NAME"
|
||||
echo "│ │ ├── index.tsx"
|
||||
echo "│ │ ├── index.module.css"
|
||||
echo "│ │ ├── useController.ts"
|
||||
echo "│ │ ├── useStore.ts"
|
||||
echo "│ │ └── types.d.ts"
|
||||
echo "│ └── components"
|
||||
echo "│ └── $COMPONENT_NAME"
|
||||
echo "│ ├── index.tsx"
|
||||
echo "│ ├── index.module.css"
|
||||
echo "│ ├── useController.ts"
|
||||
echo "│ ├── useStore.ts"
|
||||
echo "│ └── types.d.ts"
|
||||
echo "├── src/api"
|
||||
echo "│ └── ${ROUTER_NAME}.ts"
|
||||
echo "└── src/types"
|
||||
echo " └── ${ROUTER_NAME}.d.ts"
|
||||
21
frontend/apps/allin-ssl/src/App.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Transition, type Component as ComponentType, h } from 'vue'
|
||||
import { RouterView } from 'vue-router'
|
||||
import AllinSslThemeProvider from '@/components/AllinSslThemeProvider'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
setup() {
|
||||
return () => (
|
||||
<AllinSslThemeProvider>
|
||||
<RouterView>
|
||||
{({ Component }: { Component: ComponentType }) => (
|
||||
<Transition name="route-slide" mode="out-in">
|
||||
{Component && h(Component)}
|
||||
</Transition>
|
||||
)}
|
||||
</RouterView>
|
||||
</AllinSslThemeProvider>
|
||||
)
|
||||
},
|
||||
})
|
||||
154
frontend/apps/allin-ssl/src/api/access.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
// Type imports
|
||||
import type { useAxiosReturn } from '@baota/hooks/axios'
|
||||
import type {
|
||||
AccessListParams,
|
||||
AccessListResponse,
|
||||
AddAccessParams,
|
||||
DeleteAccessParams,
|
||||
GetAccessAllListParams,
|
||||
GetAccessAllListResponse,
|
||||
UpdateAccessParams,
|
||||
// CA授权相关类型
|
||||
EabListParams,
|
||||
EabListResponse,
|
||||
EabAddParams,
|
||||
EabUpdateParams,
|
||||
EabDeleteParams,
|
||||
EabGetAllListParams,
|
||||
EabGetAllListResponse,
|
||||
// 新增类型
|
||||
TestAccessParams,
|
||||
GetSitesParams,
|
||||
GetSitesResponse,
|
||||
GetPluginsActionsParams,
|
||||
GetPluginsResponse,
|
||||
GetPluginsActionsResponse,
|
||||
} from '@/types/access' // Sorted types
|
||||
import type { AxiosResponseData } from '@/types/public'
|
||||
|
||||
// Relative internal imports
|
||||
import { useApi } from '@api/index'
|
||||
|
||||
/**
|
||||
* @description 获取授权列表
|
||||
* @param {AccessListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AccessListResponse, AccessListParams>} 获取授权列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getAccessList = (params?: AccessListParams): useAxiosReturn<AccessListResponse, AccessListParams> =>
|
||||
useApi<AccessListResponse, AccessListParams>('/v1/access/get_list', params)
|
||||
|
||||
/**
|
||||
* @description 新增授权
|
||||
* @param {AddAccessParams<string>} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, AddAccessParams<string>>} 新增授权的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const addAccess = (
|
||||
params?: AddAccessParams<string>,
|
||||
): useAxiosReturn<AxiosResponseData, AddAccessParams<string>> =>
|
||||
useApi<AxiosResponseData, AddAccessParams<string>>('/v1/access/add_access', params)
|
||||
|
||||
/**
|
||||
* @description 修改授权
|
||||
* @param {UpdateAccessParams<string>} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, UpdateAccessParams<string>>} 修改授权的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const updateAccess = (
|
||||
params?: UpdateAccessParams<string>,
|
||||
): useAxiosReturn<AxiosResponseData, UpdateAccessParams<string>> =>
|
||||
useApi<AxiosResponseData, UpdateAccessParams<string>>('/v1/access/upd_access', params)
|
||||
|
||||
/**
|
||||
* @description 删除授权
|
||||
* @param {DeleteAccessParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, DeleteAccessParams>} 删除授权的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteAccess = (params?: DeleteAccessParams): useAxiosReturn<AxiosResponseData, DeleteAccessParams> =>
|
||||
useApi<AxiosResponseData, DeleteAccessParams>('/v1/access/del_access', params)
|
||||
|
||||
/**
|
||||
* @description 获取提供商列表
|
||||
* @param {GetAccessAllListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetAccessAllListResponse, GetAccessAllListParams>} 获取DNS提供商列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getAccessAllList = (
|
||||
params?: GetAccessAllListParams,
|
||||
): useAxiosReturn<GetAccessAllListResponse, GetAccessAllListParams> =>
|
||||
useApi<GetAccessAllListResponse, GetAccessAllListParams>('/v1/access/get_all', params)
|
||||
|
||||
/**
|
||||
* @description 获取ACME账户列表
|
||||
* @param {EabListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<EabListResponse, EabListParams>} 获取ACME账户列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getEabList = (params?: EabListParams): useAxiosReturn<EabListResponse, EabListParams> =>
|
||||
useApi<EabListResponse, EabListParams>('/v1/acme_account/get_list', params)
|
||||
|
||||
/**
|
||||
* @description 添加ACME账户
|
||||
* @param {EabAddParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, EabAddParams>} 添加ACME账户的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const addEab = (params?: EabAddParams): useAxiosReturn<AxiosResponseData, EabAddParams> =>
|
||||
useApi<AxiosResponseData, EabAddParams>('/v1/acme_account/add_account', params)
|
||||
|
||||
/**
|
||||
* @description 修改ACME账户
|
||||
* @param {EabUpdateParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, EabUpdateParams>} 修改ACME账户的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const updateEab = (params?: EabUpdateParams): useAxiosReturn<AxiosResponseData, EabUpdateParams> =>
|
||||
useApi<AxiosResponseData, EabUpdateParams>('/v1/acme_account/upd_account', params)
|
||||
|
||||
/**
|
||||
* @description 删除ACME账户
|
||||
* @param {EabDeleteParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, EabDeleteParams>} 删除ACME账户的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteEab = (params?: EabDeleteParams): useAxiosReturn<AxiosResponseData, EabDeleteParams> =>
|
||||
useApi<AxiosResponseData, EabDeleteParams>('/v1/acme_account/del_account', params)
|
||||
|
||||
/**
|
||||
* @description 获取CA授权列表下拉框
|
||||
* @param {EabGetAllListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<EabGetAllListResponse, EabGetAllListParams>} 获取CA授权列表下拉框的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getAllEabList = (
|
||||
params?: EabGetAllListParams,
|
||||
): useAxiosReturn<EabGetAllListResponse, EabGetAllListParams> =>
|
||||
useApi<EabGetAllListResponse, EabGetAllListParams>('/v1/access/get_all_eab', params)
|
||||
|
||||
/**
|
||||
* @description 测试授权API
|
||||
* @param {TestAccessParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, TestAccessParams>} 测试授权的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const testAccess = (params?: TestAccessParams): useAxiosReturn<AxiosResponseData, TestAccessParams> =>
|
||||
useApi<AxiosResponseData, TestAccessParams>('/v1/access/test_access', params)
|
||||
|
||||
/**
|
||||
* @description 获取网站列表
|
||||
* @param {GetSitesParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetSitesResponse, GetSitesParams>} 获取网站列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getSites = (params?: GetSitesParams): useAxiosReturn<GetSitesResponse, GetSitesParams> =>
|
||||
useApi<GetSitesResponse, GetSitesParams>('/v1/access/get_sites', params)
|
||||
|
||||
/**
|
||||
* @description 获取插件列表
|
||||
* @returns {useAxiosReturn<AxiosResponseData, void>} 获取插件列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getPlugins = (): useAxiosReturn<GetPluginsResponse, void> =>
|
||||
useApi<GetPluginsResponse, void>('/v1/access/get_plugins')
|
||||
|
||||
/**
|
||||
* @description 获取插件列表
|
||||
* @param {GetPluginsParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetPluginsResponse, GetPluginsActionsParams>} 获取插件列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getPluginsActions = (
|
||||
params: GetPluginsActionsParams,
|
||||
): useAxiosReturn<GetPluginsActionsResponse, GetPluginsActionsParams> =>
|
||||
useApi<GetPluginsActionsResponse, GetPluginsActionsParams>('/v1/access/get_plugin_actions', params)
|
||||
|
||||
|
||||
|
||||
79
frontend/apps/allin-ssl/src/api/ca.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
// External library dependencies
|
||||
import axios, { AxiosResponse } from 'axios'
|
||||
|
||||
// Type imports
|
||||
import type { useAxiosReturn } from '@baota/hooks/axios'
|
||||
import type {
|
||||
CreateRootCaParams,
|
||||
CreateRootCaResponse,
|
||||
CreateIntermediateCaParams,
|
||||
CreateIntermediateCaResponse,
|
||||
GetCaListParams,
|
||||
GetCaListResponse,
|
||||
DeleteCaParams,
|
||||
DeleteCaResponse,
|
||||
CreateLeafCertParams,
|
||||
CreateLeafCertResponse,
|
||||
GetLeafCertListParams,
|
||||
GetLeafCertListResponse,
|
||||
DeleteLeafCertParams,
|
||||
DeleteLeafCertResponse,
|
||||
} from '@/types/ca'
|
||||
|
||||
import { useApi } from "@api/index";
|
||||
|
||||
/**
|
||||
* @description 创建根证书
|
||||
* @param {CreateRootCaParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<CreateRootCaResponse, CreateRootCaParams>}
|
||||
*/
|
||||
export const createRootCa = (params?: CreateRootCaParams): useAxiosReturn<CreateRootCaResponse, CreateRootCaParams> =>
|
||||
useApi<CreateRootCaResponse, CreateRootCaParams>('/v1/private_ca/create_root_ca', params)
|
||||
|
||||
/**
|
||||
* @description 创建中间证书
|
||||
* @param {CreateIntermediateCaParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<CreateIntermediateCaResponse, CreateIntermediateCaParams>}
|
||||
*/
|
||||
export const createIntermediateCa = (params?: CreateIntermediateCaParams): useAxiosReturn<CreateIntermediateCaResponse, CreateIntermediateCaParams> =>
|
||||
useApi<CreateIntermediateCaResponse, CreateIntermediateCaParams>('/v1/private_ca/create_intermediate_ca', params)
|
||||
|
||||
/**
|
||||
* @description 获取CA列表
|
||||
* @param {GetCaListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetCaListResponse, GetCaListParams>} 获取CA列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getCaList = (params?: GetCaListParams): useAxiosReturn<GetCaListResponse, GetCaListParams> =>
|
||||
useApi<GetCaListResponse, GetCaListParams>('/v1/private_ca/get_ca_list', params)
|
||||
|
||||
/**
|
||||
* @description 删除CA
|
||||
* @param {DeleteCaParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<DeleteCaResponse, DeleteCaParams>} 删除CA的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteCa = (params?: DeleteCaParams): useAxiosReturn<DeleteCaResponse, DeleteCaParams> =>
|
||||
useApi<DeleteCaResponse, DeleteCaParams>('/v1/private_ca/del_ca', params)
|
||||
|
||||
/**
|
||||
* @description 创建叶子证书
|
||||
* @param {CreateLeafCertParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<CreateLeafCertResponse, CreateLeafCertParams>} 创建叶子证书的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const createLeafCert = (params?: CreateLeafCertParams): useAxiosReturn<CreateLeafCertResponse, CreateLeafCertParams> =>
|
||||
useApi<CreateLeafCertResponse, CreateLeafCertParams>('/v1/private_ca/create_leaf_cert', params)
|
||||
|
||||
/**
|
||||
* @description 获取叶子证书列表
|
||||
* @param {GetLeafCertListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetLeafCertListResponse, GetLeafCertListParams>} 获取叶子证书列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getLeafCertList = (params?: GetLeafCertListParams): useAxiosReturn<GetLeafCertListResponse, GetLeafCertListParams> =>
|
||||
useApi<GetLeafCertListResponse, GetLeafCertListParams>('/v1/private_ca/get_leaf_cert_list', params)
|
||||
|
||||
/**
|
||||
* @description 删除叶子证书
|
||||
* @param {DeleteLeafCertParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<DeleteLeafCertResponse, DeleteLeafCertParams>} 删除叶子证书的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteLeafCert = (params?: DeleteLeafCertParams): useAxiosReturn<DeleteLeafCertResponse, DeleteLeafCertParams> =>
|
||||
useApi<DeleteLeafCertResponse, DeleteLeafCertParams>('/v1/private_ca/del_leaf_cert', params)
|
||||
61
frontend/apps/allin-ssl/src/api/cert.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
// External library dependencies
|
||||
import axios, { AxiosResponse } from 'axios'
|
||||
|
||||
// Type imports
|
||||
import type { useAxiosReturn } from '@baota/hooks/axios'
|
||||
import type {
|
||||
ApplyCertParams,
|
||||
ApplyCertResponse,
|
||||
CertListParams,
|
||||
CertListResponse,
|
||||
DeleteCertParams,
|
||||
DeleteCertResponse,
|
||||
DownloadCertParams,
|
||||
DownloadCertResponse, // Ensuring this type is imported
|
||||
UploadCertParams,
|
||||
UploadCertResponse,
|
||||
} from '@/types/cert' // Path alias and sorted types
|
||||
|
||||
// Relative internal imports
|
||||
import { useApi } from '@api/index'
|
||||
|
||||
/**
|
||||
* @description 获取证书列表
|
||||
* @param {CertListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<CertListResponse, CertListParams>} 获取证书列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getCertList = (params?: CertListParams): useAxiosReturn<CertListResponse, CertListParams> =>
|
||||
useApi<CertListResponse, CertListParams>('/v1/cert/get_list', params)
|
||||
|
||||
/**
|
||||
* @description 申请证书
|
||||
* @param {ApplyCertParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<ApplyCertResponse, ApplyCertParams>} 申请证书的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const applyCert = (params?: ApplyCertParams): useAxiosReturn<ApplyCertResponse, ApplyCertParams> =>
|
||||
useApi<ApplyCertResponse, ApplyCertParams>('/v1/cert/apply_cert', params)
|
||||
|
||||
/**
|
||||
* @description 上传证书
|
||||
* @param {UploadCertParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<UploadCertResponse, UploadCertParams>} 上传证书的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const uploadCert = (params?: UploadCertParams): useAxiosReturn<UploadCertResponse, UploadCertParams> =>
|
||||
useApi<UploadCertResponse, UploadCertParams>('/v1/cert/upload_cert', params)
|
||||
|
||||
/**
|
||||
* @description 删除证书
|
||||
* @param {DeleteCertParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<DeleteCertResponse, DeleteCertParams>} 删除证书的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteCert = (params?: DeleteCertParams): useAxiosReturn<DeleteCertResponse, DeleteCertParams> =>
|
||||
useApi<DeleteCertResponse, DeleteCertParams>('/v1/cert/del_cert', params)
|
||||
|
||||
/**
|
||||
* @description 下载证书
|
||||
* @param {DownloadCertParams} [params] 请求参数
|
||||
* @returns {Promise<AxiosResponse<DownloadCertResponse>>} 下载结果的 Promise 对象。
|
||||
*/
|
||||
export const downloadCert = (params?: DownloadCertParams): Promise<AxiosResponse<DownloadCertResponse>> => {
|
||||
return axios.get<DownloadCertResponse>('/v1/cert/download', { params })
|
||||
}
|
||||
125
frontend/apps/allin-ssl/src/api/index.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
// External Libraries (sorted alphabetically by module path)
|
||||
import { HttpClient, useAxios, useAxiosReturn } from "@baota/hooks/axios";
|
||||
import { errorMiddleware } from "@baota/hooks/axios/model";
|
||||
import { isDev } from "@baota/utils/browser";
|
||||
import { AxiosError } from "axios";
|
||||
import MD5 from "crypto-js/md5";
|
||||
|
||||
// Type Imports (sorted alphabetically by module path)
|
||||
import type { AxiosResponseData } from "@/types/public";
|
||||
import type { Ref } from "vue";
|
||||
|
||||
// Relative Internal Imports (sorted alphabetically by module path)
|
||||
import { router } from "@router/index";
|
||||
|
||||
/**
|
||||
* @description 处理返回数据,如果状态码为 401 或 404
|
||||
* @param {AxiosError} error 错误对象
|
||||
* @returns {AxiosError} 错误对象
|
||||
*/
|
||||
export const responseHandleStatusCode = errorMiddleware((error: AxiosError) => {
|
||||
// 处理 401 状态码
|
||||
if (error.status === 401) {
|
||||
router.push(`/login`);
|
||||
}
|
||||
// 处理404状态码
|
||||
if (error.status === 404) {
|
||||
// router.go(0) // 刷新页面
|
||||
}
|
||||
return error;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description 返回数据
|
||||
* @param {T} data 数据
|
||||
* @returns {AxiosResponseData<T>} 返回数据
|
||||
*/
|
||||
export const useApiReturn = <T>(
|
||||
data: T,
|
||||
message?: string
|
||||
): AxiosResponseData<T> => {
|
||||
return {
|
||||
code: 200,
|
||||
count: 0,
|
||||
data,
|
||||
message: message || "请求返回值错误,请检查",
|
||||
status: false,
|
||||
} as AxiosResponseData<T>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 创建http客户端实例
|
||||
*/
|
||||
export const instance = new HttpClient({
|
||||
baseURL: isDev() ? "/api" : "/",
|
||||
timeout: 50000,
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
middlewares: [responseHandleStatusCode],
|
||||
});
|
||||
|
||||
/**
|
||||
* @description API Token 结构
|
||||
*/
|
||||
interface ApiTokenResult {
|
||||
api_token: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建api token
|
||||
* @returns {ApiTokenResult} 包含API token和时间戳的对象
|
||||
*/
|
||||
export const createApiToken = (): ApiTokenResult => {
|
||||
const now = new Date().getTime();
|
||||
const apiKey = "123456"; // 注意: 此处为硬编码密钥,建议后续优化
|
||||
const api_token = MD5(now + MD5(apiKey).toString()).toString();
|
||||
return { api_token, timestamp: now };
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 创建axios请求
|
||||
* @param {string} url 请求地址
|
||||
* @param {Z} [params] 请求参数
|
||||
* @returns {useAxiosReturn<T, Z>} 返回结果
|
||||
*/
|
||||
export const useApi = <T, Z = Record<string, unknown>>(
|
||||
url: string,
|
||||
params?: Z
|
||||
) => {
|
||||
const { urlRef, paramsRef, ...other } = useAxios<T>(instance);
|
||||
const apiParams = createApiToken();
|
||||
urlRef.value = url;
|
||||
paramsRef.value = isDev()
|
||||
? { ...(params || {}), ...apiParams }
|
||||
: params || {};
|
||||
return { urlRef, paramsRef: paramsRef as Ref<Z>, ...other } as useAxiosReturn<
|
||||
T,
|
||||
Z
|
||||
>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description get请求
|
||||
* @param {string} url 请求地址
|
||||
* @param {Z} [params] 请求参数
|
||||
* @returns {useAxiosReturn<T, Z>} 返回结果
|
||||
*/
|
||||
export const useGet = <T, Z = Record<string, unknown>>(
|
||||
url: string,
|
||||
params?: Z
|
||||
) => {
|
||||
return instance.get(url, {
|
||||
data: { ...createApiToken(), ...params },
|
||||
});
|
||||
};
|
||||
|
||||
// 导出所有模块
|
||||
export * from './public'
|
||||
export * from './workflow'
|
||||
export * from './cert'
|
||||
export * from "./ca";
|
||||
export * from './access'
|
||||
export * from './monitor'
|
||||
export * from './setting'
|
||||
118
frontend/apps/allin-ssl/src/api/monitor.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
// Type imports
|
||||
import type { useAxiosReturn } from '@baota/hooks/axios'
|
||||
import type {
|
||||
AddSiteMonitorParams,
|
||||
DeleteSiteMonitorParams,
|
||||
FileImportMonitorParams,
|
||||
FileImportMonitorResponse,
|
||||
GetErrorRecordParams,
|
||||
GetErrorRecordResponse,
|
||||
GetMonitorDetailParams,
|
||||
GetMonitorDetailResponse,
|
||||
SetSiteMonitorParams,
|
||||
SiteMonitorListParams,
|
||||
SiteMonitorListResponse,
|
||||
TemplateDownloadParams,
|
||||
UpdateSiteMonitorParams,
|
||||
} from '@/types/monitor' // Sorted types
|
||||
import type { AxiosResponseData } from '@/types/public'
|
||||
|
||||
// Relative internal imports
|
||||
import { useApi } from '@api/index'
|
||||
|
||||
/**
|
||||
* @description 获取站点监控列表
|
||||
* @param {SiteMonitorListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<SiteMonitorListResponse, SiteMonitorListParams>} 获取站点监控列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getSiteMonitorList = (
|
||||
params?: SiteMonitorListParams,
|
||||
): useAxiosReturn<SiteMonitorListResponse, SiteMonitorListParams> =>
|
||||
useApi<SiteMonitorListResponse, SiteMonitorListParams>('/v1/monitor/get_list', params)
|
||||
|
||||
/**
|
||||
* @description 新增站点监控
|
||||
* @param {AddSiteMonitorParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, AddSiteMonitorParams>} 新增站点监控的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const addSiteMonitor = (
|
||||
params?: AddSiteMonitorParams,
|
||||
): useAxiosReturn<AxiosResponseData, AddSiteMonitorParams> =>
|
||||
useApi<AxiosResponseData, AddSiteMonitorParams>('/v1/monitor/add_monitor', params)
|
||||
|
||||
/**
|
||||
* @description 修改站点监控
|
||||
* @param {UpdateSiteMonitorParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, UpdateSiteMonitorParams>} 修改站点监控的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const updateSiteMonitor = (
|
||||
params?: UpdateSiteMonitorParams,
|
||||
): useAxiosReturn<AxiosResponseData, UpdateSiteMonitorParams> =>
|
||||
useApi<AxiosResponseData, UpdateSiteMonitorParams>('/v1/monitor/upd_monitor', params)
|
||||
|
||||
/**
|
||||
* @description 删除站点监控
|
||||
* @param {DeleteSiteMonitorParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, DeleteSiteMonitorParams>} 删除站点监控的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteSiteMonitor = (
|
||||
params?: DeleteSiteMonitorParams,
|
||||
): useAxiosReturn<AxiosResponseData, DeleteSiteMonitorParams> =>
|
||||
useApi<AxiosResponseData, DeleteSiteMonitorParams>('/v1/monitor/del_monitor', params)
|
||||
|
||||
/**
|
||||
* @description 启用/禁用站点监控
|
||||
* @param {SetSiteMonitorParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, SetSiteMonitorParams>} 启用/禁用站点监控的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const setSiteMonitor = (
|
||||
params?: SetSiteMonitorParams,
|
||||
): useAxiosReturn<AxiosResponseData, SetSiteMonitorParams> =>
|
||||
useApi<AxiosResponseData, SetSiteMonitorParams>('/v1/monitor/set_monitor', params)
|
||||
|
||||
/**
|
||||
* @description 获取监控详情信息
|
||||
* @param {GetMonitorDetailParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetMonitorDetailResponse, GetMonitorDetailParams>} 获取监控详情信息的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getMonitorDetail = (
|
||||
params?: GetMonitorDetailParams,
|
||||
): useAxiosReturn<GetMonitorDetailResponse, GetMonitorDetailParams> =>
|
||||
useApi<GetMonitorDetailResponse, GetMonitorDetailParams>('/v1/monitor/get_monitor_info', params)
|
||||
|
||||
/**
|
||||
* @description 获取监控错误记录
|
||||
* @param {GetErrorRecordParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetErrorRecordResponse, GetErrorRecordParams>} 获取监控错误记录的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getMonitorErrorRecord = (
|
||||
params?: GetErrorRecordParams,
|
||||
): useAxiosReturn<GetErrorRecordResponse, GetErrorRecordParams> =>
|
||||
useApi<GetErrorRecordResponse, GetErrorRecordParams>('/v1/monitor/get_err_record', params)
|
||||
|
||||
/**
|
||||
* @description 文件导入监控
|
||||
* @param {FileImportMonitorParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<FileImportMonitorResponse, FileImportMonitorParams>} 文件导入监控的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const fileImportMonitor = (
|
||||
params?: FileImportMonitorParams,
|
||||
): useAxiosReturn<FileImportMonitorResponse, FileImportMonitorParams> =>
|
||||
useApi<FileImportMonitorResponse, FileImportMonitorParams>('/v1/monitor/file_add_monitor', params)
|
||||
|
||||
/**
|
||||
* @description 下载监控模板
|
||||
* @param {TemplateDownloadParams} params 请求参数
|
||||
* @returns {Promise<Blob>} 返回模板文件的Blob对象
|
||||
*/
|
||||
export const downloadMonitorTemplate = async (params: TemplateDownloadParams): Promise<Blob> => {
|
||||
const response = await fetch(`/v1/monitor/template?type=${params.type}`, {
|
||||
method: 'GET',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`下载模板失败: ${response.statusText}`)
|
||||
}
|
||||
|
||||
return response.blob()
|
||||
}
|
||||
47
frontend/apps/allin-ssl/src/api/public.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
// External library dependencies
|
||||
import axios, { type AxiosResponse } from 'axios'
|
||||
|
||||
// Type imports
|
||||
import type { useAxiosReturn } from '@baota/hooks/axios'
|
||||
import type {
|
||||
AxiosResponseData,
|
||||
GetOverviewsParams,
|
||||
GetOverviewsResponse,
|
||||
loginCodeResponse, // Added this type based on usage
|
||||
loginParams,
|
||||
loginResponse,
|
||||
} from '@/types/public' // Sorted types
|
||||
|
||||
// Relative internal imports
|
||||
import { useApi } from '@api/index'
|
||||
|
||||
/**
|
||||
* @description 登录
|
||||
* @param {loginParams} [params] 登录参数
|
||||
* @returns {useAxiosReturn<loginResponse, loginParams>} 登录操作的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const login = (params?: loginParams): useAxiosReturn<loginResponse, loginParams> =>
|
||||
useApi<loginResponse, loginParams>('/v1/login/sign', params)
|
||||
|
||||
/**
|
||||
* @description 获取登录验证码
|
||||
* @returns {Promise<AxiosResponse<loginCodeResponse>>} 获取登录验证码的 Promise 对象。
|
||||
*/
|
||||
export const getLoginCode = (): Promise<AxiosResponse<loginCodeResponse>> => {
|
||||
return axios.get<loginCodeResponse>('/v1/login/get_code')
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 登出
|
||||
* @returns {useAxiosReturn<AxiosResponseData, unknown>} 登出操作的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const signOut = (): useAxiosReturn<AxiosResponseData, unknown> =>
|
||||
useApi<AxiosResponseData, unknown>('/v1/login/sign-out', {})
|
||||
|
||||
/**
|
||||
* @description 获取首页概览
|
||||
* @param {GetOverviewsParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetOverviewsResponse, GetOverviewsParams>} 获取首页概览数据的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getOverviews = (params?: GetOverviewsParams): useAxiosReturn<GetOverviewsResponse, GetOverviewsParams> =>
|
||||
useApi<GetOverviewsResponse, GetOverviewsParams>('/v1/overview/get_overviews', params)
|
||||
118
frontend/apps/allin-ssl/src/api/setting.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
// Type imports
|
||||
import type { useAxiosReturn } from '@baota/hooks/axios'
|
||||
import type { AxiosResponseData } from '@/types/public'
|
||||
import type {
|
||||
AddReportParams,
|
||||
DeleteReportParams,
|
||||
GetReportListParams,
|
||||
GetReportListResponse,
|
||||
GetSettingParams,
|
||||
GetSettingResponse,
|
||||
GetVersionParams,
|
||||
GetVersionResponse,
|
||||
SaveSettingParams,
|
||||
TestReportParams,
|
||||
UpdateReportParams,
|
||||
} from '@/types/setting' // Sorted types
|
||||
|
||||
// Relative internal imports
|
||||
import { useApi, createApiToken } from "@api/index";
|
||||
import { isDev } from "@baota/utils/browser";
|
||||
|
||||
/**
|
||||
* @description 获取系统设置
|
||||
* @param {GetSettingParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetSettingResponse, GetSettingParams>} 获取系统设置的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getSystemSetting = (
|
||||
params?: GetSettingParams
|
||||
): useAxiosReturn<GetSettingResponse, GetSettingParams> =>
|
||||
useApi<GetSettingResponse, GetSettingParams>(
|
||||
"/v1/setting/get_setting",
|
||||
params
|
||||
);
|
||||
|
||||
/**
|
||||
* @description 保存系统设置
|
||||
* @param {SaveSettingParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, SaveSettingParams>} 保存系统设置的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const saveSystemSetting = (
|
||||
params?: SaveSettingParams
|
||||
): useAxiosReturn<AxiosResponseData, SaveSettingParams> =>
|
||||
useApi<AxiosResponseData, SaveSettingParams>(
|
||||
"/v1/setting/save_setting",
|
||||
params
|
||||
);
|
||||
|
||||
/**
|
||||
* @description 添加告警
|
||||
* @param {AddReportParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, AddReportParams>} 添加告警的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const addReport = (
|
||||
params?: AddReportParams
|
||||
): useAxiosReturn<AxiosResponseData, AddReportParams> =>
|
||||
useApi<AxiosResponseData, AddReportParams>("/v1/report/add_report", params);
|
||||
|
||||
/**
|
||||
* @description 更新告警
|
||||
* @param {UpdateReportParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, UpdateReportParams>} 更新告警的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const updateReport = (
|
||||
params?: UpdateReportParams
|
||||
): useAxiosReturn<AxiosResponseData, UpdateReportParams> =>
|
||||
useApi<AxiosResponseData, UpdateReportParams>(
|
||||
"/v1/report/upd_report",
|
||||
params
|
||||
);
|
||||
|
||||
/**
|
||||
* @description 删除告警
|
||||
* @param {DeleteReportParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, DeleteReportParams>} 删除告警的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteReport = (
|
||||
params?: DeleteReportParams
|
||||
): useAxiosReturn<AxiosResponseData, DeleteReportParams> =>
|
||||
useApi<AxiosResponseData, DeleteReportParams>(
|
||||
"/v1/report/del_report",
|
||||
params
|
||||
);
|
||||
|
||||
/**
|
||||
* @description 测试告警
|
||||
* @param {TestReportParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, TestReportParams>} 测试告警的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const testReport = (
|
||||
params?: TestReportParams
|
||||
): useAxiosReturn<AxiosResponseData, TestReportParams> =>
|
||||
useApi<AxiosResponseData, TestReportParams>("/v1/report/notify_test", params);
|
||||
|
||||
/**
|
||||
* @description 获取告警类型列表
|
||||
* @param {GetReportListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetReportListResponse, GetReportListParams>} 获取告警类型列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getReportList = (
|
||||
params?: GetReportListParams
|
||||
): useAxiosReturn<GetReportListResponse, GetReportListParams> =>
|
||||
useApi<GetReportListResponse, GetReportListParams>(
|
||||
"/v1/report/get_list",
|
||||
params
|
||||
);
|
||||
|
||||
/**
|
||||
* @description 获取版本信息
|
||||
* @param {GetVersionParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<GetVersionResponse, GetVersionParams>} 获取版本信息的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getVersion = (
|
||||
params?: GetVersionParams
|
||||
): useAxiosReturn<GetVersionResponse, GetVersionParams> =>
|
||||
useApi<GetVersionResponse, GetVersionParams>(
|
||||
"/v1/setting/get_version",
|
||||
params
|
||||
);
|
||||
116
frontend/apps/allin-ssl/src/api/workflow.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
// Type imports
|
||||
import type { useAxiosReturn } from '@baota/hooks/axios'
|
||||
import type { AxiosResponseData } from '@/types/public'
|
||||
import type {
|
||||
AddWorkflowParams,
|
||||
DeleteWorkflowParams,
|
||||
EnableWorkflowParams,
|
||||
ExecuteWorkflowParams,
|
||||
StopWorkflowParams,
|
||||
UpdateWorkflowExecTypeParams,
|
||||
UpdateWorkflowParams,
|
||||
WorkflowHistoryDetailParams,
|
||||
WorkflowHistoryParams,
|
||||
WorkflowHistoryResponse,
|
||||
WorkflowListParams,
|
||||
WorkflowListResponse,
|
||||
} from '@/types/workflow' // Sorted types
|
||||
|
||||
// Relative internal imports
|
||||
import { useApi } from '@api/index'
|
||||
|
||||
/**
|
||||
* @description 获取工作流列表
|
||||
* @param {WorkflowListParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<WorkflowListResponse, WorkflowListParams>} 获取工作流列表的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getWorkflowList = (
|
||||
params?: WorkflowListParams,
|
||||
): useAxiosReturn<WorkflowListResponse, WorkflowListParams> =>
|
||||
useApi<WorkflowListResponse, WorkflowListParams>('/v1/workflow/get_list', params)
|
||||
|
||||
/**
|
||||
* @description 新增工作流
|
||||
* @param {AddWorkflowParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, AddWorkflowParams>} 新增工作流的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const addWorkflow = (params?: AddWorkflowParams): useAxiosReturn<AxiosResponseData, AddWorkflowParams> =>
|
||||
useApi<AxiosResponseData, AddWorkflowParams>('/v1/workflow/add_workflow', params)
|
||||
|
||||
/**
|
||||
* @description 修改工作流
|
||||
* @param {UpdateWorkflowParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, UpdateWorkflowParams>} 修改工作流的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const updateWorkflow = (
|
||||
params?: UpdateWorkflowParams,
|
||||
): useAxiosReturn<AxiosResponseData, UpdateWorkflowParams> =>
|
||||
useApi<AxiosResponseData, UpdateWorkflowParams>('/v1/workflow/upd_workflow', params)
|
||||
|
||||
/**
|
||||
* @description 删除工作流
|
||||
* @param {DeleteWorkflowParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, DeleteWorkflowParams>} 删除工作流的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const deleteWorkflow = (
|
||||
params?: DeleteWorkflowParams,
|
||||
): useAxiosReturn<AxiosResponseData, DeleteWorkflowParams> =>
|
||||
useApi<AxiosResponseData, DeleteWorkflowParams>('/v1/workflow/del_workflow', params)
|
||||
|
||||
/**
|
||||
* @description 获取工作流执行历史
|
||||
* @param {WorkflowHistoryParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<WorkflowHistoryResponse, WorkflowHistoryParams>} 获取工作流执行历史的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getWorkflowHistory = (
|
||||
params?: WorkflowHistoryParams,
|
||||
): useAxiosReturn<WorkflowHistoryResponse, WorkflowHistoryParams> =>
|
||||
useApi<WorkflowHistoryResponse, WorkflowHistoryParams>('/v1/workflow/get_workflow_history', params)
|
||||
|
||||
/**
|
||||
* @description 获取工作流执行历史详情
|
||||
* @param {WorkflowHistoryDetailParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, WorkflowHistoryDetailParams>} 获取工作流执行历史详情的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const getWorkflowHistoryDetail = (
|
||||
params?: WorkflowHistoryDetailParams,
|
||||
): useAxiosReturn<AxiosResponseData, WorkflowHistoryDetailParams> =>
|
||||
useApi<AxiosResponseData, WorkflowHistoryDetailParams>('/v1/workflow/get_exec_log', params)
|
||||
|
||||
/**
|
||||
* @description 手动执行工作流
|
||||
* @param {ExecuteWorkflowParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, ExecuteWorkflowParams>} 手动执行工作流的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const executeWorkflow = (
|
||||
params?: ExecuteWorkflowParams,
|
||||
): useAxiosReturn<AxiosResponseData, ExecuteWorkflowParams> =>
|
||||
useApi<AxiosResponseData, ExecuteWorkflowParams>('/v1/workflow/execute_workflow', params)
|
||||
|
||||
/**
|
||||
* @description 修改工作流执行方式
|
||||
* @param {UpdateWorkflowExecTypeParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, UpdateWorkflowExecTypeParams>} 修改工作流执行方式的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const updateWorkflowExecType = (
|
||||
params?: UpdateWorkflowExecTypeParams,
|
||||
): useAxiosReturn<AxiosResponseData, UpdateWorkflowExecTypeParams> =>
|
||||
useApi<AxiosResponseData, UpdateWorkflowExecTypeParams>('/v1/workflow/exec_type', params)
|
||||
|
||||
/**
|
||||
* @description 启用工作流或禁用工作流
|
||||
* @param {EnableWorkflowParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, EnableWorkflowParams>} 启用或禁用工作流的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const enableWorkflow = (
|
||||
params?: EnableWorkflowParams,
|
||||
): useAxiosReturn<AxiosResponseData, EnableWorkflowParams> =>
|
||||
useApi<AxiosResponseData, EnableWorkflowParams>('/v1/workflow/active', params)
|
||||
|
||||
/**
|
||||
* @description 停止工作流执行
|
||||
* @param {StopWorkflowParams} [params] 请求参数
|
||||
* @returns {useAxiosReturn<AxiosResponseData, StopWorkflowParams>} 停止工作流执行的组合式 API 调用封装。包含响应数据、加载状态及执行函数。
|
||||
*/
|
||||
export const stopWorkflow = (params?: StopWorkflowParams): useAxiosReturn<AxiosResponseData, StopWorkflowParams> =>
|
||||
useApi<AxiosResponseData, StopWorkflowParams>('/v1/workflow/stop', params)
|
||||
@@ -0,0 +1,79 @@
|
||||
<svg width="64.000000pt" height="64.000000pt" viewBox="0 0 64.000000 64.000000" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" fill="#fefefe" stroke="none">
|
||||
<path d="M0 320 l0 -320 320 0 320 0 0 320 0 320 -320 0 -320 0 0 -320z m205
|
||||
184 c-11 -9 -27 -21 -35 -27 -9 -7 -26 -25 -38 -41 l-22 -29 0 -55 0 -55 34
|
||||
-31 c39 -37 94 -56 162 -56 l49 0 42 19 c64 30 82 82 42 122 l-22 22 -74 -7
|
||||
-75 -6 -29 29 -29 29 9 24 c4 13 26 33 47 45 l39 23 47 0 47 0 56 -21 56 -21
|
||||
34 -33 c18 -19 38 -49 45 -69 l11 -35 -11 -43 -12 -43 -48 -46 -47 -47 -54
|
||||
-17 c-108 -36 -230 -16 -308 51 -45 39 -81 100 -81 136 1 35 34 100 66 129 25
|
||||
23 100 68 114 68 3 0 -4 -7 -15 -15z" />
|
||||
</g>
|
||||
<g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" fill="#2470f0" stroke="none">
|
||||
<path d="M267 498 c-42 -21 -63 -55 -54 -90 10 -38 95 -75 111 -49 5 7 50 8
|
||||
98 2 4 -1 15 -12 23 -25 l16 -25 -11 -23 c-17 -32 -51 -58 -77 -58 -13 0 -23
|
||||
-4 -23 -10 l0 -10 -44 0 c-25 0 -48 5 -51 10 -3 6 -15 10 -26 10 -29 0 -87 41
|
||||
-98 70 -12 29 -14 44 -12 82 l1 27 30 34 c17 19 30 40 30 46 0 40 -99 -37
|
||||
-130 -101 l-18 -38 5 -42 6 -43 26 -35 c27 -36 71 -79 82 -80 4 0 24 -7 45
|
||||
-16 l39 -17 88 -1 c48 -1 87 2 87 7 0 4 8 7 18 7 27 0 117 56 135 84 9 14 23
|
||||
44 32 68 l14 43 -11 35 c-7 19 -23 50 -36 69 l-25 33 -46 22 c-25 11 -50 21
|
||||
-56 22 -5 1 -12 3 -15 4 -3 1 -30 3 -60 4 l-55 2 -38 -18z" />
|
||||
</g>
|
||||
<g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" fill="#2573f7" stroke="none">
|
||||
<path d="M159 505 c-25 -13 -60 -40 -77 -59 -30 -34 -52 -90 -52 -131 1 -38
|
||||
37 -101 81 -138 l43 -37 50 -15 c64 -19 169 -19 233 0 l50 15 45 40 c48 41 73
|
||||
86 65 117 l-4 18 -7 -20 c-4 -11 -15 -35 -24 -54 l-17 -35 -45 -28 c-25 -16
|
||||
-57 -32 -72 -35 -16 -3 -28 -8 -28 -12 0 -3 -35 -5 -78 -4 l-77 1 -45 18 c-25
|
||||
10 -46 17 -47 16 -6 -5 -103 105 -98 110 2 2 0 19 -4 38 l-7 35 14 30 c17 35
|
||||
69 92 97 107 l20 11 -26 -29 c-35 -38 -52 -72 -43 -85 l7 -12 13 29 c17 38 31
|
||||
54 77 88 20 16 37 32 37 37 0 16 -33 9 -81 -16z" />
|
||||
<path d="M277 506 c-49 -18 -67 -34 -67 -60 l0 -21 23 27 c12 15 36 33 52 39
|
||||
33 12 101 15 127 4 9 -4 22 -4 28 0 5 3 10 2 10 -2 0 -8 41 -27 63 -31 14 -1
|
||||
66 -76 67 -94 0 -9 5 -20 10 -23 l10 -6 0 23 c0 13 -11 40 -25 60 l-25 36 -53
|
||||
26 -53 26 -64 5 -65 5 -38 -14z" />
|
||||
<path d="M210 409 c0 -23 32 -48 65 -51 53 -3 95 2 95 12 0 13 -47 13 -54 1
|
||||
-4 -5 -12 -8 -19 -7 -20 3 -61 28 -74 45 l-12 16 -1 -16z" />
|
||||
<path d="M380 371 c0 -5 11 -12 25 -15 13 -3 30 -16 36 -27 l11 -22 -11 -23
|
||||
c-5 -13 -28 -32 -50 -44 l-40 -20 -51 0 -50 0 -45 21 c-48 22 -85 61 -85 87
|
||||
l0 16 -13 -13 -12 -13 13 -5 c6 -3 10 -8 7 -13 -5 -9 51 -67 60 -62 3 1 13 -4
|
||||
22 -13 8 -9 22 -14 29 -11 7 3 16 1 19 -4 4 -6 31 -10 61 -10 l54 0 0 11 c0 5
|
||||
5 7 10 4 16 -10 75 31 88 60 17 38 15 53 -13 80 -23 24 -65 34 -65 16z" />
|
||||
</g>
|
||||
<g transform="translate(0.000000,64.000000) scale(0.100000,-0.100000)" fill="#2a74f0" stroke="none">
|
||||
<path d="M164 504 l-19 -15 24 7 24 6 -7 -11 c-4 -6 -3 -11 3 -11 5 0 13 5 16
|
||||
10 3 6 1 10 -5 10 -6 0 -8 5 -5 10 9 15 -9 12 -31 -6z" />
|
||||
<path d="M290 510 c0 -5 4 -10 9 -10 6 0 13 5 16 10 l6 10 -15 0 c-9 0 -16 -4
|
||||
-16 -10z" />
|
||||
<path d="M395 510 c3 -5 10 -10 16 -10 5 0 9 5 9 10 0 6 -7 10 -16 10 l-15 0
|
||||
6 -10z" />
|
||||
<path d="M474 485 c11 -8 25 -15 30 -15 6 0 2 7 -8 15 -11 8 -25 15 -30 15 -6
|
||||
0 -2 -7 8 -15z" />
|
||||
<path d="M70 428 c-16 -22 -30 -46 -29 -52 0 -6 6 -2 12 8 7 11 25 34 41 53
|
||||
15 18 23 33 17 33 -6 0 -24 -19 -41 -42z" />
|
||||
<path d="M205 437 c-4 -10 -5 -21 -1 -24 10 -10 18 4 13 24 l-4 18 -8 -18z" />
|
||||
<path d="M120 420 c-6 -12 -9 -24 -7 -27 3 -2 11 5 17 17 6 12 9 24 7 27 -3 2
|
||||
-11 -5 -17 -17z" />
|
||||
<path d="M260 360 c0 -5 7 -10 16 -10 l15 0 -6 10 c-3 6 -10 10 -16 10 -5 0
|
||||
-9 -4 -9 -10z" />
|
||||
<path d="M100 351 c0 -6 5 -13 10 -16 l10 -6 0 15 c0 9 -4 16 -10 16 -5 0 -10
|
||||
-4 -10 -9z" />
|
||||
<path d="M592 330 c1 -16 5 -30 10 -30 4 0 8 14 8 30 0 17 -4 30 -9 30 -5 0
|
||||
-9 -13 -9 -30z" />
|
||||
<path d="M30 296 c0 -9 5 -16 10 -16 6 0 10 4 10 9 0 6 -4 13 -10 16 l-10 6 0
|
||||
-15z" />
|
||||
<path d="M130 282 c0 -12 19 -26 26 -19 2 2 -2 10 -11 17 l-15 12 0 -10z" />
|
||||
<path d="M425 260 c-10 -11 -13 -20 -8 -20 13 0 38 29 31 35 -3 3 -13 -4 -23
|
||||
-15z" />
|
||||
<path d="M566 234 c-10 -14 -16 -28 -13 -30 2 -3 12 7 21 22 10 14 16 28 13
|
||||
30 -2 3 -12 -7 -21 -22z" />
|
||||
<path d="M70 221 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5 3
|
||||
-10 2 -10 -4z" />
|
||||
<path d="M105 180 c3 -5 11 -10 16 -10 6 0 7 5 4 10 -3 6 -11 10 -16 10 -6 0
|
||||
-7 -4 -4 -10z" />
|
||||
<path d="M515 180 c-3 -5 -2 -10 4 -10 5 0 13 5 16 10 3 6 2 10 -4 10 -5 0
|
||||
-13 -4 -16 -10z" />
|
||||
<path d="M195 130 c3 -5 11 -10 16 -10 6 0 7 5 4 10 -3 6 -11 10 -16 10 -6 0
|
||||
-7 -4 -4 -10z" />
|
||||
<path d="M425 130 c-3 -5 -2 -10 4 -10 5 0 13 5 16 10 3 6 2 10 -4 10 -5 0
|
||||
-13 -4 -16 -10z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1750124792955" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12638" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M706.432 374.4c-75.946667 18.517333-75.946667 116.224 0 134.954667a666.517333 666.517333 0 0 1-25.877333 77.141333c-86.613333-20.970667-125.226667 58.026667-83.349334 109.056-5.738667 30.442667-35.690667 37.034667-57.450666 51.413333-44.544-53.482667-148.821333-35.370667-141.013334 51.669334h-90.133333c9.450667-81.066667-95.658667-110.912-134.250667-51.669334-29.141333-7.381333-49.877333-23.04-64.426666-44.821333 39.402667-55.978667 8.597333-136-83.349334-115.626667C17.130667 562.005333 7.893333 536.277333 1.130667 509.333333c72.853333-11.52 72.853333-123.413333 0-134.954666 6.762667-27.136 16-52.864 25.450666-77.354667 87.018667 21.205333 125.610667-58.24 83.328-109.034667 6.357333-30.656 36.117333-36.821333 57.898667-51.2C212.138667 190.293333 316.202667 171.946667 308.608 85.333333h90.112c-9.429333 80.853333 95.850667 110.677333 134.442667 51.434667 28.757333 7.616 49.706667 23.04 64.042666 44.650667-38.592 55.957333-8.618667 135.978667 83.349334 115.626666a656.490667 656.490667 0 0 1 25.877333 77.333334z m-352.661333 201.386667c73.472 0 133.632-60.053333 133.632-133.909334 0-74.069333-60.16-133.909333-133.632-133.909333a133.653333 133.653333 0 0 0-133.632 133.909333c0 73.856 59.733333 133.930667 133.632 133.930667z m669.781333 135.808c-41.664 5.141333-47.402667 56.768-8.618667 71.594666-5.525333 13.589333-11.882667 26.538667-18.261333 38.890667-44.757333-16.277333-69.781333 23.232-50.901333 52.864-5.333333 15.850667-21.333333 17.066667-33.877334 23.466667-20.117333-30.869333-76.586667-27.584-77.994666 18.901333a1126.613333 1126.613333 0 0 0-47.637334-5.333333c10.069333-42.794667-43.733333-65.002667-68.138666-36.202667-14.570667-5.76-24.426667-15.232-30.592-27.584 23.808-27.157333 12.736-71.573333-37.333334-66.645333a316.032 316.032 0 0 1-8.64-42.176c38.997333-1.429333 45.973333-61.098667 8.213334-71.808 5.333333-13.781333 11.690667-26.752 18.261333-39.082667 44.949333 16.469333 70.186667-23.04 51.114667-52.693333 5.12-15.616 20.928-17.258667 33.856-23.829334 20.117333 31.466667 76.586667 27.968 77.397333-18.133333 16.213333 1.877333 32 3.52 47.829333 5.568-10.453333 42.581333 44.138667 64.426667 67.946667 35.584a59.52 59.52 0 0 1 31.616 27.797333c-24.64 26.944-13.12 71.36 36.736 66.432 3.904 13.376 6.570667 27.584 9.024 42.389334z m-199.509333 84.757333c39.189333 4.522667 74.709333-23.466667 78.613333-62.549333 5.333333-39.509333-23.189333-74.666667-62.208-79.189334-39.189333-4.736-73.877333 23.466667-79.018667 62.336-4.309333 39.296 23.402667 74.88 62.613334 79.402667z" fill="#3ABCFB" p-id="12639"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1747902416932" class="icon" viewBox="0 0 1273 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10903" width="49.7265625" height="40" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M692.017327 292.268083l29.243926 0.499287 79.457889-79.457889 3.851639-33.666179A355.634679 355.634679 0 0 0 567.409668 89.300966c-164.621909 0-303.566225 112.011372-344.693171 263.737423 8.673321-6.0485 27.21825-1.512125 27.21825-1.512125l158.773124-26.105554s8.159769-13.509268 12.296714-12.838797A198.002782 198.002782 0 0 1 567.509525 247.86011c47.075589 0.099857 90.442193 16.733232 124.507802 44.251054z" fill="#EA4335" p-id="10904"></path><path d="M912.302554 353.352227a357.674622 357.674622 0 0 0-107.774569-173.708925l-112.510658 112.510658c45.078443 36.376592 73.994267 92.03991 73.994267 154.350872v19.85734c54.736072 0 99.201106 44.564891 99.201105 99.201105 0 54.736072-44.564891 99.201106-99.201105 99.201106H567.609383L547.752043 684.735845v119.058445l19.85734 19.757482h198.402211A258.345128 258.345128 0 0 0 1024.000089 565.577542c-0.099857-87.803107-44.222523-165.477829-111.697535-212.21105z" fill="#4285F4" p-id="10905"></path><path d="M369.007457 823.68016h198.288089V664.764383h-198.288089a98.288124 98.288124 0 0 1-40.827375-8.873036l-28.630517 8.773178-79.457889 79.457889-6.961481 26.818821a256.775942 256.775942 0 0 0 155.862997 52.624802z" fill="#34A853" p-id="10906"></path><path d="M369.007457 307.70317A258.345128 258.345128 0 0 0 111.018962 565.6774c0 83.780284 40.128374 158.273837 102.225356 205.463549l115.035622-115.035622a99.286697 99.286697 0 0 1-58.473588-90.427927c0-54.736072 44.564891-99.201106 99.201105-99.201106 40.228231 0 74.807391 24.251061 90.442193 58.487854l115.035622-115.035622c-47.175447-62.096982-121.683266-102.225355-205.46355-102.225356z" fill="#FBBC05" p-id="10907"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1747988020538" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5468" width="40" height="40" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M776.399 1023.968H247.664a41.194 41.194 0 0 1-41.053-41.021V591.801a41.18 41.18 0 0 1 41.053-41.053h49.661v-63.227c0-118.393 96.346-214.675 214.675-214.675s214.674 96.347 214.674 214.675v63.228h49.661a41.18 41.18 0 0 1 41.05 41.052v391.145a41.167 41.167 0 0 1-40.986 41.055zM538.785 807.565a54.36 54.36 0 0 0-26.686-101.722h-0.128a54.4 54.4 0 0 0-27.073 101.558l0.256 0.128v52.989a26.782 26.782 0 0 0 53.565 0zM420.454 550.75H603.61v-63.228a91.547 91.547 0 0 0-183.093 0z m-226.418-58.3H66.46a37.47 37.47 0 1 1 0-74.939h127.576a37.47 37.47 0 1 1 0 74.939z m89.882-200.691h-0.1a37.06 37.06 0 0 1-23.743-8.575l0.064 0.064-100.89-82.971a37.483 37.483 0 1 1 47.677-57.852l-0.064-0.064 100.89 82.971a37.468 37.468 0 0 1-23.767 66.426h-0.1z m228.082-88.218a37.458 37.458 0 0 1-37.47-37.47V37.47a37.47 37.47 0 0 1 74.939 0v128.6a37.458 37.458 0 0 1-37.47 37.47z m228.085 88.217h-0.16a37.42 37.42 0 0 1-23.742-66.332l0.064-0.064 100.89-82.971a37.471 37.471 0 0 1 47.677 57.82l-0.064 0.064-100.89 82.971a37.184 37.184 0 0 1-23.711 8.479h-0.064zM957.54 492.449H828.748a37.47 37.47 0 1 1 0-74.939H957.54a37.47 37.47 0 1 1 0 74.939z" fill="#003A70" p-id="5469"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1747901885171" class="icon" viewBox="0 0 1113 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5838" width="43.4765625" height="40" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M107.287 512.928c0-79.047-0.045-158.094 0.03-237.141 0.02-21.15 1.256-42.135 9.203-62.181 23.74-59.883 67.166-95.237 130.865-105.518 8.582-1.385 17.221-1.667 25.889-1.667 159.718 0.009 319.436-0.021 479.155 0.019 74.315 0.019 133.182 41.364 157.993 111.108 6.12 17.204 8.542 35.132 8.54 53.403-0.022 161.072 0.122 322.144-0.072 483.215-0.091 75.418-50.342 141.59-119.876 158.868-15.044 3.738-30.331 5.422-45.807 5.423-160.26 0.014-320.521 0.29-480.78-0.12-71.188-0.182-121.825-33.848-152.353-97.864-10.72-22.48-12.842-46.672-12.817-71.218 0.081-78.774 0.03-157.551 0.03-236.327z m283.66-4.813v136.454H254.062v138.583h138.402V645.64h138.004v137.437h138.576V644.705h137.443V505.977H668.339V367.658H530.496V229.98H391.685v138.154H254.216c-0.365 1.798-0.66 2.576-0.661 3.354-0.035 43.047 0.079 86.094-0.188 129.139-0.042 6.738 3.542 6.504 8.205 6.495 39.798-0.073 79.596-0.06 119.394-0.007 3.173 0.005 6.462-0.676 9.981 1z" fill="#4D70D4" p-id="5839"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
frontend/apps/allin-ssl/src/assets/icons/svg/close.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="m576 512 277.333 277.333-64 64L512 576 234.667 853.333l-64-64L448 512 170.667 234.667l64-64L512 448l277.333-277.333 64 64L576 512z"/></svg>
|
||||
|
After Width: | Height: | Size: 250 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="64 64 896 896" data-icon="solution" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M688 264c0-4.4-3.6-8-8-8H296c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48zm-8 136H296c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM480 544H296c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm-48 308H208V148h560v344c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V108c0-17.7-14.3-32-32-32H168c-17.7 0-32 14.3-32 32v784c0 17.7 14.3 32 32 32h264c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm356.8-74.4c29-26.3 47.2-64.3 47.2-106.6 0-79.5-64.5-144-144-144s-144 64.5-144 144c0 42.3 18.2 80.3 47.2 106.6-57 32.5-96.2 92.7-99.2 162.1-.2 4.5 3.5 8.3 8 8.3h48.1c4.2 0 7.7-3.3 8-7.6C564 871.2 621.7 816 692 816s128 55.2 131.9 124.4c.2 4.2 3.7 7.6 8 7.6H880c4.6 0 8.2-3.8 8-8.3-2.9-69.5-42.2-129.6-99.2-162.1zM692 591c44.2 0 80 35.8 80 80s-35.8 80-80 80-80-35.8-80-80 35.8-80 80-80z"/></svg>
|
||||
|
After Width: | Height: | Size: 958 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="64 64 896 896" data-icon="sisternode" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M672 432c-120.3 0-219.9 88.5-237.3 204H320c-15.5 0-28-12.5-28-28V244h291c14.2 35.2 48.7 60 89 60 53 0 96-43 96-96s-43-96-96-96c-40.3 0-74.8 24.8-89 60H112v72h108v364c0 55.2 44.8 100 100 100h114.7c17.4 115.5 117 204 237.3 204 132.5 0 240-107.5 240-240S804.5 432 672 432zm128 266c0 4.4-3.6 8-8 8h-86v86c0 4.4-3.6 8-8 8h-52c-4.4 0-8-3.6-8-8v-86h-86c-4.4 0-8-3.6-8-8v-52c0-4.4 3.6-8 8-8h86v-86c0-4.4 3.6-8 8-8h52c4.4 0 8 3.6 8 8v86h86c4.4 0 8 3.6 8 8v52z"/></svg>
|
||||
|
After Width: | Height: | Size: 584 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="64 64 896 896" data-icon="deployment-unit" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M888.3 693.2c-42.5-24.6-94.3-18-129.2 12.8l-53-30.7V523.6c0-15.7-8.4-30.3-22-38.1l-136-78.3v-67.1c44.2-15 76-56.8 76-106.1 0-61.9-50.1-112-112-112s-112 50.1-112 112c0 49.3 31.8 91.1 76 106.1v67.1l-136 78.3c-13.6 7.8-22 22.4-22 38.1v151.6l-53 30.7c-34.9-30.8-86.8-37.4-129.2-12.8-53.5 31-71.7 99.4-41 152.9 30.8 53.5 98.9 71.9 152.2 41 42.5-24.6 62.7-73 53.6-118.8l48.7-28.3 140.6 81c6.8 3.9 14.4 5.9 22 5.9s15.2-2 22-5.9L674.5 740l48.7 28.3c-9.1 45.7 11.2 94.2 53.6 118.8 53.3 30.9 121.5 12.6 152.2-41 30.8-53.6 12.6-122-40.7-152.9zm-673 138.4a47.6 47.6 0 0 1-65.2-17.6c-13.2-22.9-5.4-52.3 17.5-65.5a47.6 47.6 0 0 1 65.2 17.6c13.2 22.9 5.4 52.3-17.5 65.5zM522 463.8zM464 234a48.01 48.01 0 0 1 96 0 48.01 48.01 0 0 1-96 0zm170 446.2-122 70.3-122-70.3V539.8l122-70.3 122 70.3v140.4zm239.9 133.9c-13.2 22.9-42.4 30.8-65.2 17.6-22.8-13.2-30.7-42.6-17.5-65.5s42.4-30.8 65.2-17.6c22.9 13.2 30.7 42.5 17.5 65.5z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="40" height="40"><path d="M64 512a448 448 0 1 0 896 0 448 448 0 1 0-896 0z" fill="#FA5151"/><path d="m557.3 512 113.1-113.1c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L512 466.7 398.9 353.6c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L466.7 512 353.6 625.1c-12.5 12.5-12.5 32.8 0 45.3 6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4L512 557.3l113.1 113.1c6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4c12.5-12.5 12.5-32.8 0-45.3L557.3 512z" fill="#FFF"/></svg>
|
||||
|
After Width: | Height: | Size: 538 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="64 64 896 896" data-icon="send" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M931.4 498.9 94.9 79.5c-3.4-1.7-7.3-2.1-11-1.2a15.99 15.99 0 0 0-11.7 19.3l86.2 352.2c1.3 5.3 5.2 9.6 10.4 11.3l147.7 50.7-147.6 50.7c-5.2 1.8-9.1 6-10.3 11.3L72.2 926.5c-.9 3.7-.5 7.6 1.2 10.9 3.9 7.9 13.5 11.1 21.5 7.2l836.5-417c3.1-1.5 5.6-4.1 7.2-7.1 3.9-8 .7-17.6-7.2-21.6zM170.8 826.3l50.3-205.6 295.2-101.3c2.3-.8 4.2-2.6 5-5 1.4-4.2-.8-8.7-5-10.2L221.1 403 171 198.2l628 314.9-628.2 313.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
@@ -0,0 +1,4 @@
|
||||
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M566.446451 30.031087a467.343774 467.343774 0 0 0 234.783037 105.108804 711.977007 711.977007 0 0 0 109.012845 7.928207 31.592703 31.592703 0 0 1 31.472579 29.370403c3.964103 54.055956 1.561617 108.111913 2.522611 162.588304 0.660684 37.178486 0.54056 74.417033-1.861927 111.535457-6.426653 99.282773-22.763564 196.403308-66.909262 286.736817a518.937181 518.937181 0 0 1-184.991495 208.05537A755.462021 755.462021 0 0 1 523.862369 1022.017948a35.436683 35.436683 0 0 1-23.244061 0c-98.742214-34.235439-188.775412-82.8858-261.991202-159.044636C171.477596 792.820693 129.554199 709.334272 106.190013 615.817467A875.165933 875.165933 0 0 1 83.786822 473.59024C76.218989 380.433808 80.783714 287.217315 80.603527 194.000821a183.309754 183.309754 0 0 1 1.38143-18.979647 36.878175 36.878175 0 0 1 37.959294-31.712827A714.739867 714.739867 0 0 0 223.551501 135.260015 469.085577 469.085577 0 0 0 456.052175 31.592703 248.176902 248.176902 0 0 1 490.107428 6.006217a44.506071 44.506071 0 0 1 44.746319 0.54056A243.371928 243.371928 0 0 1 566.446451 30.031087zM155.320871 351.664027a960.274034 960.274034 0 0 0 3.723855 132.136782 687.291454 687.291454 0 0 0 32.793947 162.528243 440.135609 440.135609 0 0 0 136.641445 199.22623 601.642794 601.642794 0 0 0 176.582791 99.162649 20.661388 20.661388 0 0 0 15.496041-0.660684 658.221362 658.221362 0 0 0 127.992492-63.906153 446.742448 446.742448 0 0 0 183.850314-234.602851c28.229222-81.864743 35.37662-166.912781 38.019356-252.261129 1.681741-55.437386-1.861927-110.934835-1.681741-166.432284 0-7.267523-2.282363-9.730072-9.67001-10.150507a719.004282 719.004282 0 0 1-91.414628-10.931316 529.087688 529.087688 0 0 1-248.11684-117.841985 9.489823 9.489823 0 0 0-15.015544 0A527.105637 527.105637 0 0 1 388.662416 162.768491c-70.693178 33.754942-145.951082 48.650361-223.55141 53.455334-7.207461 0.480497-9.970321 2.522611-9.910259 9.970321 0.240249 41.923397 0.120124 83.666608 0.120124 125.469881z" fill="currentColor"/>
|
||||
<path d="M362.054873 472.328934A37.839169 37.839169 0 0 1 391.725587 485.302364c21.021761 21.081823 42.043522 42.043522 63.00522 63.245469 6.006217 6.006217 9.489823 5.585782 15.19573 0Q549.749166 467.944396 629.932168 388.001642c15.075606-15.075606 32.073201-24.024869 60.062174-4.14429a29.670714 29.670714 0 0 1 4.804974 43.665201c-15.73629 17.718341-33.034196 33.99519-49.73148 50.752536L493.230661 629.99214c-21.322072 21.26201-41.022465 21.26201-62.404599 0-30.751833-30.691771-61.683852-61.263417-92.135374-92.195436-20.72145-21.021761-15.435979-52.374215 10.030383-62.945158a28.169159 28.169159 0 0 1 13.333802-2.522612z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="40" height="40"><path d="M64 512a448 448 0 1 0 896 0 448 448 0 1 0-896 0z" fill="#07C160"/><path d="M466.7 679.8c-8.5 0-16.6-3.4-22.6-9.4l-181-181.1c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l158.4 158.5 249-249c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3L489.3 670.4c-6 6-14.1 9.4-22.6 9.4z" fill="#FFF"/></svg>
|
||||
|
After Width: | Height: | Size: 398 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="64 64 896 896" data-icon="cloud-upload" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M518.3 459a8 8 0 0 0-12.6 0l-112 141.7a7.98 7.98 0 0 0 6.3 12.9h73.9V856c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V613.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 459z"/><path d="M811.4 366.7C765.6 245.9 648.9 160 512.2 160S258.8 245.8 213 366.6C127.3 389.1 64 467.2 64 560c0 110.5 89.5 200 199.9 200H304c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8h-40.1c-33.7 0-65.4-13.4-89-37.7-23.5-24.2-36-56.8-34.9-90.6.9-26.4 9.9-51.2 26.2-72.1 16.7-21.3 40.1-36.8 66.1-43.7l37.9-9.9 13.9-36.6c8.6-22.8 20.6-44.1 35.7-63.4a245.6 245.6 0 0 1 52.4-49.9c41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.2c19.9 14 37.5 30.8 52.4 49.9 15.1 19.3 27.1 40.7 35.7 63.4l13.8 36.5 37.8 10C846.1 454.5 884 503.8 884 560c0 33.1-12.9 64.3-36.3 87.7a123.07 123.07 0 0 1-87.6 36.3H720c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h40.1C870.5 760 960 670.5 960 560c0-92.7-63.1-170.7-148.6-193.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 968 B |
@@ -0,0 +1,24 @@
|
||||
<svg viewBox="0 0 21 21" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="21.000000" height="21.000000" fill="none" customFrame="#000000">
|
||||
<defs>
|
||||
<clipPath id="clipPath_2">
|
||||
<rect width="13.000000" height="13.000000" x="4.000000" y="4.000000" fill="rgb(255,255,255)" />
|
||||
</clipPath>
|
||||
<clipPath id="clipPath_3">
|
||||
<rect width="13.000000" height="13.000000" x="4.000000" y="4.000000" fill="rgb(255,255,255)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="组合 54">
|
||||
<rect id="矩形 41" width="21.000000" height="21.000000" x="0.000000" y="0.000000" rx="6.000000" fill="rgb(244,209,180)" />
|
||||
<rect id="矩形 41" width="20.000000" height="20.000000" x="0.500000" y="0.500000" rx="5.500000" stroke="rgb(244,209,180)" stroke-width="1" />
|
||||
<g id="svg 10" clip-path="url(#clipPath_2)" customFrame="url(#clipPath_2)">
|
||||
<rect id="svg 10" width="13.000000" height="13.000000" x="4.000000" y="4.000000" />
|
||||
<g id="svg 10" clip-path="url(#clipPath_3)" customFrame="url(#clipPath_3)">
|
||||
<rect id="svg 10" width="13.000000" height="13.000000" x="4.000000" y="4.000000" />
|
||||
<path id="矢量 79" d="M10.4999 4.72217C7.32217 4.72217 4.72217 7.32217 4.72217 10.4999C4.72217 13.6777 7.32217 16.2777 10.4999 16.2777C13.6777 16.2777 16.2777 13.6777 16.2777 10.4999C16.2777 7.32217 13.6777 4.72217 10.4999 4.72217ZM10.4999 15.5555C7.68327 15.5555 5.44439 13.3166 5.44439 10.4999C5.44439 7.68327 7.68327 5.44439 10.4999 5.44439C13.3166 5.44439 15.5555 7.68327 15.5555 10.4999C15.5555 13.3166 13.3166 15.5555 10.4999 15.5555Z" fill="rgb(31,31,31)" fill-rule="nonzero" />
|
||||
<path id="矢量 79" d="M4.72217 10.4999C4.72217 13.6777 7.32217 16.2777 10.4999 16.2777C13.6777 16.2777 16.2777 13.6777 16.2777 10.4999C16.2777 7.32217 13.6777 4.72217 10.4999 4.72217C7.32217 4.72217 4.72217 7.32217 4.72217 10.4999ZM5.44439 10.4999C5.44439 7.68327 7.68327 5.44439 10.4999 5.44439C13.3166 5.44439 15.5555 7.68327 15.5555 10.4999C15.5555 13.3166 13.3166 15.5555 10.4999 15.5555C7.68327 15.5555 5.44439 13.3166 5.44439 10.4999Z" fill-rule="nonzero" stroke="rgb(31,31,31)" stroke-width="0.5" />
|
||||
<path id="矢量 80" d="M10.5001 12.6667C10.2834 12.6667 10.1389 12.7389 9.9945 12.8834C9.85006 13.0278 9.77783 13.1722 9.77783 13.3889C9.77783 13.6056 9.85006 13.75 9.9945 13.8945C10.1389 14.0389 10.2834 14.1111 10.5001 14.1111C10.7167 14.1111 10.8612 14.0389 11.0056 13.8945C11.1501 13.75 11.2223 13.6056 11.2223 13.3889C11.2223 13.1722 11.1501 13.0278 11.0056 12.8834C10.8612 12.7389 10.7167 12.6667 10.5001 12.6667L10.5001 12.6667ZM9.85005 6.88892L10.0667 12.0889L10.8612 12.0889L11.1501 6.88892L9.85005 6.88892Z" fill="rgb(31,31,31)" fill-rule="nonzero" />
|
||||
<path id="矢量 80" d="M9.9945 12.8834C9.85006 13.0278 9.77783 13.1722 9.77783 13.3889C9.77783 13.6056 9.85006 13.75 9.9945 13.8945C10.1389 14.0389 10.2834 14.1111 10.5001 14.1111C10.7167 14.1111 10.8612 14.0389 11.0056 13.8945C11.1501 13.75 11.2223 13.6056 11.2223 13.3889C11.2223 13.1722 11.1501 13.0278 11.0056 12.8834C10.8612 12.7389 10.7167 12.6667 10.5001 12.6667L10.5001 12.6667C10.2834 12.6667 10.1389 12.7389 9.9945 12.8834ZM10.0667 12.0889L10.8612 12.0889L11.1501 6.88892L9.85005 6.88892L10.0667 12.0889Z" fill-rule="nonzero" stroke="rgb(31,31,31)" stroke-width="0.300000012" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,24 @@
|
||||
<svg viewBox="0 0 21 21" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="21.000000" height="21.000000" fill="none" customFrame="#000000">
|
||||
<defs>
|
||||
<clipPath id="clipPath_2">
|
||||
<rect width="13.000000" height="13.000000" x="4.000000" y="4.000000" fill="rgb(255,255,255)" />
|
||||
</clipPath>
|
||||
<clipPath id="clipPath_3">
|
||||
<rect width="13.000000" height="13.000000" x="4.000000" y="4.000000" fill="rgb(255,255,255)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="组合 54">
|
||||
<rect id="矩形 41" width="21.000000" height="21.000000" x="0.000000" y="0.000000" rx="6.000000" fill="rgb(255,242,242)" fill-opacity="0" />
|
||||
<rect id="矩形 41" width="19.500000" height="19.500000" x="0.750000" y="0.750000" rx="5.250000" stroke="rgb(231,78,78)" stroke-width="1.5" />
|
||||
<g id="svg 10" clip-path="url(#clipPath_2)" customFrame="url(#clipPath_2)">
|
||||
<rect id="svg 10" width="13.000000" height="13.000000" x="4.000000" y="4.000000" />
|
||||
<g id="svg 10" clip-path="url(#clipPath_3)" customFrame="url(#clipPath_3)">
|
||||
<rect id="svg 10" width="13.000000" height="13.000000" x="4.000000" y="4.000000" />
|
||||
<path id="矢量 79" d="M10.4999 4.72223C7.32217 4.72223 4.72217 7.32223 4.72217 10.5C4.72217 13.6778 7.32217 16.2778 10.4999 16.2778C13.6777 16.2778 16.2777 13.6778 16.2777 10.5C16.2777 7.32223 13.6777 4.72223 10.4999 4.72223ZM10.4999 15.5556C7.68327 15.5556 5.44439 13.3167 5.44439 10.5C5.44439 7.68333 7.68327 5.44445 10.4999 5.44445C13.3166 5.44445 15.5555 7.68333 15.5555 10.5C15.5555 13.3167 13.3166 15.5556 10.4999 15.5556Z" fill="rgb(255,136,136)" fill-rule="nonzero" />
|
||||
<path id="矢量 79" d="M4.72217 10.5C4.72217 13.6778 7.32217 16.2778 10.4999 16.2778C13.6777 16.2778 16.2777 13.6778 16.2777 10.5C16.2777 7.32223 13.6777 4.72223 10.4999 4.72223C7.32217 4.72223 4.72217 7.32223 4.72217 10.5ZM5.44439 10.5C5.44439 7.68333 7.68327 5.44445 10.4999 5.44445C13.3166 5.44445 15.5555 7.68333 15.5555 10.5C15.5555 13.3167 13.3166 15.5556 10.4999 15.5556C7.68327 15.5556 5.44439 13.3167 5.44439 10.5Z" fill-rule="nonzero" stroke="rgb(255,136,136)" stroke-width="0.5" />
|
||||
<path id="矢量 80" d="M10.5001 12.6667C10.2834 12.6667 10.1389 12.7389 9.9945 12.8833C9.85006 13.0278 9.77783 13.1722 9.77783 13.3889C9.77783 13.6055 9.85006 13.75 9.9945 13.8944C10.1389 14.0389 10.2834 14.1111 10.5001 14.1111C10.7167 14.1111 10.8612 14.0389 11.0056 13.8944C11.1501 13.75 11.2223 13.6055 11.2223 13.3889C11.2223 13.1722 11.1501 13.0278 11.0056 12.8833C10.8612 12.7389 10.7167 12.6667 10.5001 12.6667L10.5001 12.6667ZM9.85005 6.88889L10.0667 12.0889L10.8612 12.0889L11.1501 6.88889L9.85005 6.88889Z" fill="rgb(255,136,136)" fill-rule="nonzero" />
|
||||
<path id="矢量 80" d="M9.9945 12.8833C9.85006 13.0278 9.77783 13.1722 9.77783 13.3889C9.77783 13.6055 9.85006 13.75 9.9945 13.8944C10.1389 14.0389 10.2834 14.1111 10.5001 14.1111C10.7167 14.1111 10.8612 14.0389 11.0056 13.8944C11.1501 13.75 11.2223 13.6055 11.2223 13.3889C11.2223 13.1722 11.1501 13.0278 11.0056 12.8833C10.8612 12.7389 10.7167 12.6667 10.5001 12.6667L10.5001 12.6667C10.2834 12.6667 10.1389 12.7389 9.9945 12.8833ZM10.0667 12.0889L10.8612 12.0889L11.1501 6.88889L9.85005 6.88889L10.0667 12.0889Z" fill-rule="nonzero" stroke="rgb(255,136,136)" stroke-width="0.300000012" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg viewBox="0 0 21 21" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="21.000000" height="21.000000" fill="none" customFrame="#000000">
|
||||
<defs>
|
||||
<clipPath id="clipPath_1">
|
||||
<rect width="13.000000" height="13.000000" x="4.000000" y="4.000000" fill="rgb(255,255,255)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="组合 53">
|
||||
<rect id="矩形 40" width="21.000000" height="21.000000" x="0.000000" y="0.000000" rx="6.000000" fill="rgb(244,209,180)" />
|
||||
<rect id="矩形 40" width="20.000000" height="20.000000" x="0.500000" y="0.500000" rx="5.500000" stroke="rgb(244,209,180)" stroke-width="1" />
|
||||
<g id="svg 9" clip-path="url(#clipPath_1)" customFrame="url(#clipPath_1)">
|
||||
<rect id="svg 9" width="13.000000" height="13.000000" x="4.000000" y="4.000000" />
|
||||
<path id="矢量 77" d="M15.7724 8.57917C15.5147 7.9698 15.1452 7.42136 14.6742 6.95164C14.2045 6.48191 13.6561 6.11248 13.0467 5.85349C12.4145 5.58689 11.7442 5.45105 11.0535 5.45105C10.3629 5.45105 9.69133 5.58689 9.05911 5.85349C8.44973 6.11121 7.90129 6.48064 7.43157 6.95164C6.96184 7.42136 6.59241 7.9698 6.33342 8.57917C6.06682 9.2114 5.93098 9.88171 5.93098 10.5723C5.93098 10.7653 5.94241 10.9595 5.96399 11.1512L5.2175 10.4378C5.11594 10.3413 4.95598 10.3438 4.85823 10.4454C4.76174 10.5469 4.76428 10.7069 4.86584 10.8047L6.17346 12.0552C6.22043 12.1009 6.28391 12.125 6.34866 12.125L6.35881 12.125C6.42737 12.1224 6.49211 12.0907 6.53782 12.0399L7.73752 10.6828C7.8302 10.5774 7.82004 10.4175 7.71594 10.3248C7.61057 10.2321 7.45061 10.2423 7.35793 10.3464L6.49719 11.3188C6.45784 11.0738 6.43752 10.8224 6.43752 10.5723C6.43752 8.0282 8.50686 5.95886 11.051 5.95886C13.5951 5.95886 15.6645 8.0282 15.6645 10.5723C15.6645 13.1165 13.5951 15.1858 11.051 15.1858C9.87795 15.1858 8.75949 14.7453 7.90256 13.9442C7.79973 13.849 7.63977 13.8541 7.54328 13.9569C7.4468 14.0597 7.45315 14.2197 7.55598 14.3162C8.50686 15.2049 9.74846 15.6949 11.051 15.6949C11.7429 15.6949 12.4132 15.5591 13.0442 15.2925C13.6535 15.0347 14.202 14.6653 14.6717 14.1943C15.1414 13.7246 15.5109 13.1761 15.7698 12.5668C16.0364 11.9345 16.1723 11.2642 16.1723 10.5736C16.1748 9.88171 16.039 9.21013 15.7724 8.57917L15.7724 8.57917Z" fill="rgb(31,31,31)" fill-rule="nonzero" />
|
||||
<path id="矢量 77" d="M14.6742 6.95164C14.2045 6.48191 13.6561 6.11248 13.0467 5.85349C12.4145 5.58689 11.7442 5.45105 11.0535 5.45105C10.3629 5.45105 9.69133 5.58689 9.05911 5.85349C8.44973 6.11121 7.90129 6.48064 7.43157 6.95164C6.96184 7.42136 6.59241 7.9698 6.33342 8.57917C6.06682 9.2114 5.93098 9.88171 5.93098 10.5723C5.93098 10.7653 5.94241 10.9595 5.96399 11.1512L5.2175 10.4378C5.11594 10.3413 4.95598 10.3438 4.85823 10.4454C4.76174 10.5469 4.76428 10.7069 4.86584 10.8047L6.17346 12.0552C6.22043 12.1009 6.28391 12.125 6.34866 12.125L6.35881 12.125C6.42737 12.1224 6.49211 12.0907 6.53782 12.0399L7.73752 10.6828C7.8302 10.5774 7.82004 10.4175 7.71594 10.3248C7.61057 10.2321 7.45061 10.2423 7.35793 10.3464L6.49719 11.3188C6.45784 11.0738 6.43752 10.8224 6.43752 10.5723C6.43752 8.0282 8.50686 5.95886 11.051 5.95886C13.5951 5.95886 15.6645 8.0282 15.6645 10.5723C15.6645 13.1165 13.5951 15.1858 11.051 15.1858C9.87795 15.1858 8.75949 14.7453 7.90256 13.9442C7.79973 13.849 7.63977 13.8541 7.54328 13.9569C7.4468 14.0597 7.45315 14.2197 7.55598 14.3162C8.50686 15.2049 9.74846 15.6949 11.051 15.6949C11.7429 15.6949 12.4132 15.5591 13.0442 15.2925C13.6535 15.0347 14.202 14.6653 14.6717 14.1943C15.1414 13.7246 15.5109 13.1761 15.7698 12.5668C16.0364 11.9345 16.1723 11.2642 16.1723 10.5736C16.1748 9.88171 16.039 9.21013 15.7724 8.57917L15.7724 8.57917C15.5147 7.9698 15.1452 7.42136 14.6742 6.95164Z" fill-rule="nonzero" stroke="rgb(31,31,31)" stroke-width="0.800000012" />
|
||||
<path id="矢量 78" d="M10.6777 7.49756C10.5089 7.49756 10.373 7.6334 10.373 7.80225L10.373 10.9583C10.373 11.1271 10.5089 11.263 10.6777 11.263L13.8338 11.263C14.0026 11.263 14.1385 11.1271 14.1385 10.9583C14.1385 10.7895 14.0026 10.6536 13.8338 10.6536L10.9824 10.6536L10.9824 7.80225C10.9824 7.63467 10.8466 7.49756 10.6777 7.49756Z" fill="rgb(31,31,31)" fill-rule="nonzero" />
|
||||
<path id="矢量 78" d="M10.373 7.80225L10.373 10.9583C10.373 11.1271 10.5089 11.263 10.6777 11.263L13.8338 11.263C14.0026 11.263 14.1385 11.1271 14.1385 10.9583C14.1385 10.7895 14.0026 10.6536 13.8338 10.6536L10.9824 10.6536L10.9824 7.80225C10.9824 7.63467 10.8466 7.49756 10.6777 7.49756C10.5089 7.49756 10.373 7.6334 10.373 7.80225Z" fill-rule="nonzero" stroke="rgb(31,31,31)" stroke-width="0.800000012" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg viewBox="0 0 21 21" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="21.000000" height="21.000000" fill="none" customFrame="#000000">
|
||||
<defs>
|
||||
<clipPath id="clipPath_1">
|
||||
<rect width="13.000000" height="13.000000" x="4.000000" y="4.000000" fill="rgb(255,255,255)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="组合 53">
|
||||
<rect id="矩形 40" width="21.000000" height="21.000000" x="0.000000" y="0.000000" rx="6.000000" fill="rgb(243,255,241)" fill-opacity="0" />
|
||||
<rect id="矩形 40" width="19.500000" height="19.500000" x="0.750000" y="0.750000" rx="5.250000" stroke="rgb(255,118,24)" stroke-width="1.5" />
|
||||
<g id="svg 9" clip-path="url(#clipPath_1)" customFrame="url(#clipPath_1)">
|
||||
<rect id="svg 9" width="13.000000" height="13.000000" x="4.000000" y="4.000000" />
|
||||
<path id="矢量 77" d="M15.7724 8.57921C15.5147 7.96983 15.1452 7.42139 14.6742 6.95167C14.2045 6.48194 13.6561 6.11251 13.0467 5.85352C12.4145 5.58692 11.7442 5.45108 11.0535 5.45108C10.3629 5.45108 9.69133 5.58692 9.05911 5.85352C8.44973 6.11124 7.90129 6.48067 7.43157 6.95167C6.96184 7.42139 6.59241 7.96983 6.33342 8.57921C6.06682 9.21143 5.93098 9.88174 5.93098 10.5724C5.93098 10.7653 5.94241 10.9596 5.96399 11.1513L5.2175 10.4378C5.11594 10.3413 4.95598 10.3439 4.85823 10.4454C4.76174 10.547 4.76428 10.7069 4.86584 10.8047L6.17346 12.0552C6.22043 12.1009 6.28391 12.125 6.34866 12.125L6.35881 12.125C6.42737 12.1225 6.49211 12.0907 6.53782 12.0399L7.73752 10.6828C7.8302 10.5774 7.82004 10.4175 7.71594 10.3248C7.61057 10.2321 7.45061 10.2423 7.35793 10.3464L6.49719 11.3189C6.45784 11.0738 6.43752 10.8225 6.43752 10.5724C6.43752 8.02823 8.50686 5.95889 11.051 5.95889C13.5951 5.95889 15.6645 8.02823 15.6645 10.5724C15.6645 13.1165 13.5951 15.1858 11.051 15.1858C9.87795 15.1858 8.75949 14.7453 7.90256 13.9442C7.79973 13.849 7.63977 13.8541 7.54328 13.9569C7.4468 14.0598 7.45315 14.2197 7.55598 14.3162C8.50686 15.2049 9.74846 15.6949 11.051 15.6949C11.7429 15.6949 12.4132 15.5591 13.0442 15.2925C13.6535 15.0348 14.202 14.6653 14.6717 14.1943C15.1414 13.7246 15.5109 13.1762 15.7698 12.5668C16.0364 11.9346 16.1723 11.2643 16.1723 10.5736C16.1748 9.88174 16.039 9.21016 15.7724 8.5792L15.7724 8.57921Z" fill="rgb(255,163,84)" fill-rule="nonzero" />
|
||||
<path id="矢量 77" d="M14.6742 6.95167C14.2045 6.48194 13.6561 6.11251 13.0467 5.85352C12.4145 5.58692 11.7442 5.45108 11.0535 5.45108C10.3629 5.45108 9.69133 5.58692 9.05911 5.85352C8.44973 6.11124 7.90129 6.48067 7.43157 6.95167C6.96184 7.42139 6.59241 7.96983 6.33342 8.57921C6.06682 9.21143 5.93098 9.88174 5.93098 10.5724C5.93098 10.7653 5.94241 10.9596 5.96399 11.1513L5.2175 10.4378C5.11594 10.3413 4.95598 10.3439 4.85823 10.4454C4.76174 10.547 4.76428 10.7069 4.86584 10.8047L6.17346 12.0552C6.22043 12.1009 6.28391 12.125 6.34866 12.125L6.35881 12.125C6.42737 12.1225 6.49211 12.0907 6.53782 12.0399L7.73752 10.6828C7.8302 10.5774 7.82004 10.4175 7.71594 10.3248C7.61057 10.2321 7.45061 10.2423 7.35793 10.3464L6.49719 11.3189C6.45784 11.0738 6.43752 10.8225 6.43752 10.5724C6.43752 8.02823 8.50686 5.95889 11.051 5.95889C13.5951 5.95889 15.6645 8.02823 15.6645 10.5724C15.6645 13.1165 13.5951 15.1858 11.051 15.1858C9.87795 15.1858 8.75949 14.7453 7.90256 13.9442C7.79973 13.849 7.63977 13.8541 7.54328 13.9569C7.4468 14.0598 7.45315 14.2197 7.55598 14.3162C8.50686 15.2049 9.74846 15.6949 11.051 15.6949C11.7429 15.6949 12.4132 15.5591 13.0442 15.2925C13.6535 15.0348 14.202 14.6653 14.6717 14.1943C15.1414 13.7246 15.5109 13.1762 15.7698 12.5668C16.0364 11.9346 16.1723 11.2643 16.1723 10.5736C16.1748 9.88174 16.039 9.21016 15.7724 8.5792L15.7724 8.57921C15.5147 7.96983 15.1452 7.42139 14.6742 6.95167Z" fill-rule="nonzero" stroke="rgb(255,163,84)" stroke-width="0.800000012" />
|
||||
<path id="矢量 78" d="M10.6777 7.49756C10.5089 7.49756 10.373 7.6334 10.373 7.80225L10.373 10.9583C10.373 11.1271 10.5089 11.263 10.6777 11.263L13.8338 11.263C14.0026 11.263 14.1385 11.1271 14.1385 10.9583C14.1385 10.7895 14.0026 10.6536 13.8338 10.6536L10.9824 10.6536L10.9824 7.80225C10.9824 7.63467 10.8466 7.49756 10.6777 7.49756Z" fill="rgb(255,163,84)" fill-rule="nonzero" />
|
||||
<path id="矢量 78" d="M10.373 7.80225L10.373 10.9583C10.373 11.1271 10.5089 11.263 10.6777 11.263L13.8338 11.263C14.0026 11.263 14.1385 11.1271 14.1385 10.9583C14.1385 10.7895 14.0026 10.6536 13.8338 10.6536L10.9824 10.6536L10.9824 7.80225C10.9824 7.63467 10.8466 7.49756 10.6777 7.49756C10.5089 7.49756 10.373 7.6334 10.373 7.80225Z" fill-rule="nonzero" stroke="rgb(255,163,84)" stroke-width="0.800000012" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1 @@
|
||||
<svg class="icon" width="30" height="30" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M717.62 682.138h116.582l-212.02 296.396-5.12-1.792 46.08-194.816h-91.136c10.24-47.257 20.07-91.648 30.72-140.185-25.907 7.782-48.537 12.288-69.17 21.299-44.698 19.456-84.89 11.162-121.14-17.613a455.68 455.68 0 0 1-66.97-63.232c-20.48-24.473-13.977-38.451 17.05-43.673 65.69-11.06 131.584-20.788 197.58-33.076h-41.42c-56.78-.563-113.613-1.484-170.394-1.69-34.867 0-59.443-18.175-80.486-43.468a272.589 272.589 0 0 1-54.989-110.848c-6.451-26.01.666-33.178 27.495-26.931 67.84 15.77 135.577 32.102 203.417 47.974a1030.195 1030.195 0 0 0 105.165 20.173c-40.96-13.62-82.74-26.112-123.34-40.96-61.953-22.938-122.88-47.923-184.833-71.68a66.56 66.56 0 0 1-38.963-37.376c-24.115-54.989-42.138-111.565-42.547-172.288 0-22.118 7.219-27.546 26.214-18.33C378.88 143.36 578.918 222.31 779.571 299.315a288.666 288.666 0 0 1 54.989 29.747c33.331 22.17 44.186 50.125 26.931 85.248-35.43 72.09-74.393 142.439-112.23 213.35-9.472 17.46-20.02 34.407-31.642 54.478z" fill="#59ADF8"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg class="icon" width="30" height="30" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M512 0q512 0 512 512t-512 512Q0 1024 0 512T512 0z" fill="#FFF"/><path d="M832.032 367.205c4.123.024 8.243.265 12.34.723a345.91 345.91 0 0 1 91.865 25.368c8.523 3.818 10.629 6.91 3.291 14.608a296.456 296.456 0 0 0-51.46 75.942c-14.15 29.776-29.614 58.928-44.09 88.576a190.048 190.048 0 0 1-43.992 58.567c-45.276 40.963-98.052 58.238-158.264 49.88-69.096-9.575-134.541-32.903-196.365-63.667-3.85-1.908-6.581-3.29-8.851-4.672a4.483 4.483 0 0 1-2.096-3.943 4.483 4.483 0 0 1 2.358-3.79l4.278-2.304c50.079-26.749 91.866-64.027 132.138-103.216 17.011-16.451 33.331-33.725 50.507-50.045a291.126 291.126 0 0 1 135.2-72.387c11.12-2.666 22.34-4.837 33.527-7.239h.528l23.82-2.204" fill="#133C9A"/><path d="M348.029 850.682c-7.6-.428-26.322-2.994-28.56-3.29a452.614 452.614 0 0 1-139.312-40.734c-25.466-11.91-49.98-25.96-74.559-39.648-16.155-9.016-23.492-23.032-23.328-42.05.528-70.347.528-140.704 0-211.074-.262-45.275-1.579-90.548-2.27-135.792a36.602 36.602 0 0 1 1.875-11.744c2.731-8.16 8.359-8.656 13.92-3.29 6.416 6.185 11.515 13.686 17.866 19.74 56.856 56 117.1 107.296 184.651 149.546a1017.56 1017.56 0 0 0 118.451 65.246c65.642 29.81 132.928 56.1 203.44 72.78 62.285 14.742 122.861 5.463 173.333-34.086 15.4-13.161 23.034-22.803 41.294-47.118a303.662 303.662 0 0 1-31.555 61.464c-11.745 18.491-38.2 43.168-58.368 62.515-30.633 29.613-70.677 53.632-108.253 73.901-40.963 22.078-83.54 39.714-129.044 49.354-23.328 5.824-57.023 12.504-68.637 13.161-2.04-.165-8.983 1.415-12.536 1.12-29.975 2.269-48.466 3.125-78.408 0z" fill="#3370FF"/><path d="M219.28 172.912a44.256 44.256 0 0 1 6.283 0c128.848 0 256.645 2.072 385.328 2.072.224 0 .443.069.626.198a303.498 303.498 0 0 1 33.133 33.856c29.054 28.89 50.704 78.968 65.51 109.503 7.371 21.091 18.491 41.26 23.757 64.752v.429a281.552 281.552 0 0 0-38.3 15.596c-37.214 18.887-54.126 32.672-85.022 63.108-16.813 16.45-31.192 31.29-53.533 52.348-7.008 6.581-24.841 23.264-25.137 22.736-5.923-10.464-106.08-206.4-307.283-360.552" fill="#00D6B9"/></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |