feat: 重构前端项目结构并优化代码

refactor: 迁移前端资源文件至web目录
feat: 新增多种图标资源
style: 统一代码风格和格式化配置
docs: 更新README和文档说明
chore: 更新依赖和配置文件
fix: 修复部分类型定义和枚举
perf: 优化路由和组件加载逻辑
This commit is contained in:
zhangtao
2026-04-29 00:02:09 +08:00
parent 10a35bb4b5
commit eb150bcede
887 changed files with 116514 additions and 33990 deletions
Binary file not shown.
+142
View File
@@ -0,0 +1,142 @@
Case:
- Test:
name: test_001_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_002_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_003_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_004_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_005_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_006_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_007_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_008_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_009_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
- Test:
name: test_010_yaml
run: yes
type: json
request:
method: POST
url: $host/gateway/traceplan/trackPlan/getData
headers:
Content-Type: application/json;charset=UTF-8
token: $token
data: {"staSelect":"09100101","startTime":"2025-10-14 00:00:00","endTime":"2025-10-14 00:30:00","page":1,"limit":50,"showApplication":true,"trackStatus":"4"}
expected:
code: 200
isSuccess: true
+66
View File
@@ -0,0 +1,66 @@
import time
from locust import HttpUser, task, between, User
from locust.runners import MasterRunner
from locust import events
@events.test_start.add_listener
def on_test_start(environment, **kwargs):
print("开始监听")
@events.test_stop.add_listener
def on_test_stop(environment, **kwargs):
print("结束监听")
@events.init.add_listener
def on_locust_init(environment, **kwargs):
if isinstance(environment.runner, MasterRunner):
print("我在master节点上")
else:
print("我在worker节点或独立节点上")
class QuickstartUser(HttpUser):
# 例如,让每个用户在每次任务执行之间等待0.5到10秒:
wait_time = between(0.5, 10)
# 例如,下一个用户类会睡一秒,然后两秒,再三秒,依此类推。
last_wait_time = 0
def wait_time(self):
self.last_wait_time += 1
return self.last_wait_time
# @task 会有一个可选的权重参数,可以用来指定任务的执行比率。在 以下示例,任务2被选中的概率是任务1的两倍:
@task(3)
def task1(self):
self.client.get("/hello")
self.client.get("/world")
@task(6)
def task2(self):
for item_id in range(10):
self.client.get(f"/item?id={item_id}", name="/item")
time.sleep(1)
@task
def my_task(self):
with self.client.get("/", catch_response=True) as response:
if response.text != "Success":
response.failure("Got wrong response")
elif response.elapsed.total_seconds() > 0.5:
response.failure("Request took too long")
elif response.status_code == 404:
raise RescheduleTask()
def on_start(self):
self.client.post("/login", json={"username":"foo", "password":"bar"})
# 例如,假设我们有一个WebUser类和一个MobileUser类,我们想让MobileUser类的用户权重为1,而WebUser类的用户权重为3。
class WebUser(User):
weight = 3
...
class MobileUser(User):
weight = 1
...
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+75
View File
@@ -0,0 +1,75 @@
# 在最佳情况下(在 -loop 内执行小请求),单个 Locust 进程(限制在一个 CPU 核心)
# 使用 FastHttpUser 可以每秒处理大约 16000 个请求,使用 HttpUser 可以执行 4000
# 个请求(测试于 2021 年 M1 MacBook Pro 和 Python 3.11 上)
from locust import TaskSet, task, HttpUser, run_single_user, FastHttpUser
from locust.clients import ResponseContextManager
from locust.runners import logger
from locust import HttpUser, task, between
class Task(TaskSet):
tasks = {ThreadPage:15, write_post:1}
@tag('thread')
@task(3)
def demo_api(self):
# 基于注释中的接口信息设置请求参数
payload = {}
# 设置请求头
headers = {
"Content-Type": "application/json",
"token": "xxxx"
}
path = "/gateway/xxx"
logger.info(f"请求路径 {path}")
with self.client.post(path, json=payload, headers=headers, catch_response=True) as res:
res: ResponseContextManager
if res.status_code != 200:
# 输出请求的完整 URL 和状态码
logger.error(f"请求失败. 接口地址: {res.request.url}, 状态码: {res.status_code}")
# 输出响应文本
logger.error(f"响应文本: {res.text}")
# 标记请求为失败
res.failure(res.text)
else:
# 检查响应内容是否包含预期的数据结构
try:
response_json = res.json()
if not response_json:
res.failure("响应体为空")
except ValueError:
res.failure("响应体不是有效的 JSON 格式")
def on_start(self):
logger.info('s'*10 + '测试开始' + 's'*10)
def on_stop(self):
logger.info('s'*10 + '测试结束' + 's'*10)
# class Test(HttpUser):
class Test(FastHttpUser):
wait_time = between(1, 5)
# 根据注释中的接口地址更新host配置
host = 'https://xxx.com'
tasks = [Task, ]
@task
def t(self):
with self.rest("POST", "/", json={"foo": 1}) as resp:
if resp.js is None:
pass # no need to do anything, already marked as failed
elif "bar" not in resp.js:
resp.failure(f"'bar' missing from response {resp.text}")
elif resp.js["bar"] != 42:
resp.failure(f"'bar' had an unexpected value: {resp.js['bar']}")
if __name__ == '__main__':
# 修复变量名错误,应该是Test类而不是test
run_single_user(Test)
# 启动 Locust 测试
# locust -f locust.py
View File
+81
View File
@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
from typing import Dict, Any
from playwright.sync_api import Page, expect
class BasePage:
def __init__(self, page: Page) -> None:
self.page = page
def login(self, test_data: Dict[str, Any]) -> bool:
# 设置页面加载超时
self.page.set_default_timeout(30000)
# 访问登录页面并等待页面完全加载
self.page.goto(test_data["url"])
self.page.wait_for_load_state("networkidle") # 等待网络活动空闲
# 等待用户名输入框可见且可交互
username_input = self.page.get_by_role("textbox", name="用户名")
username_input.wait_for(state="visible", timeout=10000)
username_input.click()
username_input.fill(test_data["username"])
# 等待密码输入框可见且可交互
password_input = self.page.get_by_role("textbox", name="请输入登录密码")
password_input.wait_for(state="visible", timeout=10000)
password_input.click()
password_input.fill(test_data["password"])
# 等待登录按钮可见且可交互
login_button = self.page.get_by_role("button", name="登录")
login_button.wait_for(state="visible", timeout=10000)
# 使用click()方法本身会等待元素可交互,不需要单独检查enabled状态
login_button.click()
# 等待登录后页面加载和弹窗出现
self.page.wait_for_load_state("networkidle")
# 等待SaaS系统使用引导文本出现
self.page.wait_for_selector("text=SaaS系统使用引导", timeout=15000)
expect(self.page.get_by_text("SaaS系统使用引导")).to_be_visible()
expect(self.page.get_by_text("登录成功")).to_be_visible()
# 等待关闭按钮可见且可交互
close_button = self.page.get_by_role("button", name="Close")
close_button.wait_for(state="visible", timeout=10000)
# 使用click()方法本身会等待元素可交互,不需要单独检查enabled状态
close_button.click()
# 关闭登录成功提示
self.page.locator(".el-icon.el-notification__closeBtn > svg").click()
# 等待弹窗关闭
self.page.wait_for_selector("text=SaaS系统使用引导", state="hidden", timeout=5000)
return True
def logout(self) -> bool:
# 等待用户名显示
expect(self.page.get_by_text("")).to_be_visible(timeout=20000)
self.page.get_by_text("").click()
# 等待退出登录选项显示
self.page.wait_for_selector("text=退出登录", state="visible", timeout=10000)
expect(self.page.get_by_text("退出登录")).to_be_visible(timeout=10000)
self.page.get_by_text("退出登录").click()
# 等待确认对话框显示
self.page.wait_for_selector("text=确定要退出登录吗?", state="visible", timeout=10000)
expect(self.page.get_by_text("确定要退出登录吗?")).to_be_visible(timeout=10000)
expect(self.page.get_by_role("button", name="确认")).to_be_visible(timeout=10000)
self.page.get_by_role("button", name="确认").click()
# 等待退出成功提示显示
self.page.wait_for_selector("text=退出成功", state="visible", timeout=10000)
expect(self.page.get_by_text("退出成功")).to_be_visible(timeout=10000)
# 关闭退出成功提示
self.page.get_by_role("img").nth(4).click()
return True