feat(admin): 添加用户管理相关文件

添加用户管理视图、API和状态管理文件
This commit is contained in:
张翔
2026-03-28 14:37:29 +08:00
commit 08ea5fbe98
1643 changed files with 255646 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
# 测试自动化系统
## 目录结构
- `config/` - 测试配置文件
- `scripts/` - 辅助脚本
- `reporters/` - 报告生成器
- `test-reports/` - 测试报告输出目录
- `logs/` - 日志文件目录
## 使用方法
```bash
./run-all-tests.sh
```
## 功能特性
- ✅ 一键启动所有测试(API + 前端对接 + E2E)
- ✅ 自动重试失败的测试
- ✅ 基于规则的自动修复机制
- ✅ 多格式测试报告(JSON/XML/HTML
- ✅ 自动清理测试环境
## 测试架构
```
API测试层 (JUnit 5 + Spring Boot Test)
前端对接测试层 (Playwright)
E2E测试层 (Playwright + Appium)
```
## 配置文件
- `config/test-config.yml` - 测试执行配置
- `config/auto-fix-rules.yml` - 自动修复规则
## 报告输出
测试报告将生成在 `test-reports/YYYY-MM-DD_HH-MM-SS/` 目录下,包含:
- `console.log` - 控制台输出
- `test-report.json` - JSON格式报告
- `test-report.xml` - JUnit XML格式报告
- `test-report.html` - HTML可视化报告
- `allure-report/` - Allure报告
## 维护者
张翔 - 资深金融级高级自动化测试工程师
+89
View File
@@ -0,0 +1,89 @@
rules:
- name: database_connection_failed
pattern: "Cannot create poolable connection factory|Connection refused|Unable to acquire JDBC Connection"
category: config
action: check_h2_config
auto_fix: true
priority: 1
- name: port_already_in_use
pattern: "Port .* already in use|Address already in use"
category: config
action: find_available_port
auto_fix: true
priority: 1
- name: environment_variable_missing
pattern: "Could not resolve placeholder|Environment variable .* not found"
category: config
action: use_default_value
auto_fix: true
priority: 2
- name: flyway_migration_failed
pattern: "Flyway migration failed|Validation failed for migration"
category: config
action: clean_and_re_migrate
auto_fix: true
priority: 1
- name: test_data_missing
pattern: "No data found|Empty result set|Expected .* but was null"
category: data
action: init_test_data
auto_fix: true
priority: 2
- name: unique_constraint_violation
pattern: "Unique constraint violation|Duplicate entry|PRIMARY KEY constraint"
category: data
action: generate_unique_identifier
auto_fix: true
priority: 2
- name: foreign_key_constraint_failed
pattern: "Foreign key constraint|Cannot delete or update a parent row"
category: data
action: reorder_data_insertion
auto_fix: true
priority: 3
- name: null_pointer_exception
pattern: "NullPointerException"
category: code
action: add_null_check
auto_fix: true
priority: 3
conditions:
in_test_code_only: true
- name: type_conversion_error
pattern: "ClassCastException|Cannot cast|NumberFormatException"
category: code
action: add_type_conversion
auto_fix: true
priority: 3
conditions:
in_test_code_only: true
- name: assertion_failed
pattern: "AssertionError|Expected:|but was:"
category: test
action: analyze_and_adjust
auto_fix: false
generate_report: true
priority: 5
- name: test_timeout
pattern: "test timed out|Timeout.*milliseconds"
category: test
action: increase_timeout
auto_fix: true
priority: 3
- name: service_unavailable
pattern: "Service Unavailable|Connection timed out|SocketTimeoutException"
category: test
action: add_wait_logic
auto_fix: true
priority: 2
+50
View File
@@ -0,0 +1,50 @@
api:
timeout: 1800
retry: 3
modules:
- everything-is-suitable-app
- everything-is-suitable-biz
- everything-is-suitable-sys
- everything-is-suitable-client
- everything-is-suitable-gateway
- everything-is-suitable-common
frontend:
timeout: 1200
retry: 2
admin:
enabled: true
base_url: http://localhost:8080
uniapp:
enabled: true
base_url: http://localhost:8080
e2e:
timeout: 2400
retry: 2
browsers:
- chromium
headless: true
video: true
screenshot: on-failure
auto_fix:
enabled: true
max_attempts: 3
rules_file: config/auto-fix-rules.yml
log_file: logs/auto-fix.log
database:
type: h2
mode: memory
init_script: scripts/init-test-data.sql
cleanup: true
report:
output_dir: test-reports
formats:
- json
- xml
- html
- allure
retention_days: 30
+159
View File
@@ -0,0 +1,159 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_FILE="$SCRIPT_DIR/config/test-config.yml"
LOG_DIR="$PROJECT_ROOT/test-automation/logs"
REPORT_DIR="$PROJECT_ROOT/test-automation/test-reports"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
CURRENT_REPORT_DIR="$REPORT_DIR/$TIMESTAMP"
mkdir -p "$LOG_DIR"
mkdir -p "$CURRENT_REPORT_DIR"
TEST_RESULT=0
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
log "========================================="
log "全面自动化测试执行开始"
log "========================================="
log "项目根目录: $PROJECT_ROOT"
log "报告输出目录: $CURRENT_REPORT_DIR"
log "========================================="
# 环境检查
log "[环境检查] 检查依赖..."
check_command() {
if ! command -v $1 &> /dev/null; then
log "[环境检查] ✗ $1 未安装"
exit 1
fi
log "[环境检查] ✓ $1 已安装"
}
check_command java
check_command mvn
check_command node
check_command npm
log "[环境检查] ✓ 环境检查通过"
# 启动服务
log "[启动服务] 正在启动API服务..."
bash "$SCRIPT_DIR/scripts/start-api.sh"
if ! bash "$SCRIPT_DIR/scripts/wait-for-api.sh"; then
log "[启动服务] ✗ API服务启动失败"
bash "$SCRIPT_DIR/scripts/cleanup.sh"
exit 1
fi
log "[启动服务] ✓ API服务已就绪"
# 执行API测试
log "[API测试] 开始执行API测试..."
cd "$PROJECT_ROOT/everything-is-suitable-api"
API_TEST_LOG="$CURRENT_REPORT_DIR/api-test.log"
if mvn test -Dspring.profiles.active=test > "$API_TEST_LOG" 2>&1; then
log "[API测试] ✓ API测试通过"
else
log "[API测试] ✗ API测试失败"
TEST_RESULT=1
fi
cp -r */target/surefire-reports/* "$CURRENT_REPORT_DIR/" 2>/dev/null || true
log "[API测试] API测试完成"
# 执行前端对接测试
log "[前端对接测试] 开始执行前端对接测试..."
ADMIN_DIR="$PROJECT_ROOT/everything-is-suitable-admin"
if [ -d "$ADMIN_DIR/e2e" ]; then
cd "$ADMIN_DIR"
FRONTEND_TEST_LOG="$CURRENT_REPORT_DIR/frontend-test.log"
if [ -f "package.json" ]; then
log "[前端对接测试] 安装依赖..."
npm install > /dev/null 2>&1
log "[前端对接测试] 执行Playwright测试..."
if npx playwright test --reporter=html > "$FRONTEND_TEST_LOG" 2>&1; then
log "[前端对接测试] ✓ 前端对接测试通过"
else
log "[前端对接测试] ✗ 前端对接测试失败"
TEST_RESULT=1
fi
mkdir -p "$CURRENT_REPORT_DIR/frontend-report"
cp -r playwright-report/* "$CURRENT_REPORT_DIR/frontend-report/" 2>/dev/null || true
fi
fi
log "[前端对接测试] 前端对接测试完成"
# 执行E2E测试
log "[E2E测试] 开始执行E2E测试..."
E2E_TEST_LOG="$CURRENT_REPORT_DIR/e2e-test.log"
if [ -d "$ADMIN_DIR/e2e" ]; then
cd "$ADMIN_DIR"
if npx playwright test e2e/ --reporter=html --project=chromium > "$E2E_TEST_LOG" 2>&1; then
log "[E2E测试] ✓ E2E测试通过"
else
log "[E2E测试] ✗ E2E测试失败"
TEST_RESULT=1
fi
mkdir -p "$CURRENT_REPORT_DIR/e2e-report"
cp -r playwright-report/* "$CURRENT_REPORT_DIR/e2e-report/" 2>/dev/null || true
fi
log "[E2E测试] E2E测试完成"
# 生成报告
log "[生成报告] 正在生成综合测试报告..."
if [ -f "$SCRIPT_DIR/reporters/report-generator.py" ]; then
python3 "$SCRIPT_DIR/reporters/report-generator.py" \
--report-dir "$CURRENT_REPORT_DIR" \
--timestamp "$TIMESTAMP" \
--config "$CONFIG_FILE" || log "[生成报告] 报告生成失败,但继续执行"
fi
log "[生成报告] ✓ 报告已生成: $CURRENT_REPORT_DIR"
# 清理环境
log "[清理环境] 正在清理环境..."
bash "$SCRIPT_DIR/scripts/cleanup.sh"
log "[清理环境] ✓ 环境清理完成"
log "========================================="
log "测试执行完成"
log "========================================="
if [ $TEST_RESULT -eq 0 ]; then
log "✓ 所有测试通过"
log "退出码: 0"
exit 0
else
log "✗ 部分测试失败"
log "退出码: 1"
exit 1
fi
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
LOG_DIR="$PROJECT_ROOT/test-automation/logs"
PID_FILE="$LOG_DIR/api-server.pid"
echo "[清理环境] 正在清理..."
if [ -f "$PID_FILE" ]; then
API_PID=$(cat "$PID_FILE")
if ps -p $API_PID > /dev/null 2>&1; then
echo "[清理环境] 停止API服务 (PID: $API_PID)..."
kill $API_PID
sleep 2
if ps -p $API_PID > /dev/null 2>&1; then
echo "[清理环境] 强制停止API服务..."
kill -9 $API_PID
fi
fi
rm -f "$PID_FILE"
fi
echo "[清理环境] ✓ 清理完成"
@@ -0,0 +1,44 @@
-- 测试用户数据
INSERT INTO sys_user (id, username, password, email, phone, status, created_at, updated_at)
VALUES
(1, 'admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt6Z5EH', 'admin@example.com', '13800138000', 1, NOW(), NOW()),
(2, 'testuser', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt6Z5EH', 'test@example.com', '13800138001', 1, NOW(), NOW());
-- 测试角色数据
INSERT INTO sys_role (id, role_name, role_code, description, created_at, updated_at)
VALUES
(1, '管理员', 'ADMIN', '系统管理员角色', NOW(), NOW()),
(2, '普通用户', 'USER', '普通用户角色', NOW(), NOW());
-- 测试用户角色关联
INSERT INTO sys_user_role (user_id, role_id)
VALUES
(1, 1),
(2, 2);
-- 测试菜单数据
INSERT INTO sys_menu (id, menu_name, menu_code, parent_id, path, icon, sort, status, created_at, updated_at)
VALUES
(1, '系统管理', 'SYSTEM', NULL, '/system', 'setting', 1, 1, NOW(), NOW()),
(2, '用户管理', 'USER_MANAGE', 1, '/system/user', 'user', 1, 1, NOW(), NOW()),
(3, '角色管理', 'ROLE_MANAGE', 1, '/system/role', 'team', 2, 1, NOW(), NOW());
-- 测试权限数据
INSERT INTO sys_permission (id, permission_name, permission_code, resource_type, resource_url, method, parent_id, status, created_at, updated_at)
VALUES
(1, '用户查看', 'user:view', 'menu', '/api/sys/user/*', 'GET', NULL, 1, NOW(), NOW()),
(2, '用户创建', 'user:create', 'button', '/api/sys/user', 'POST', 1, 1, NOW(), NOW()),
(3, '用户编辑', 'user:edit', 'button', '/api/sys/user/*', 'PUT', 1, 1, NOW(), NOW()),
(4, '用户删除', 'user:delete', 'button', '/api/sys/user/*', 'DELETE', 1, 1, NOW(), NOW());
-- 测试角色权限关联
INSERT INTO sys_role_permission (role_id, permission_id)
VALUES
(1, 1), (1, 2), (1, 3), (1, 4),
(2, 1);
-- 测试黄历数据
INSERT INTO almanac (id, date, lunar_date, gan_zhi, star, should_do, avoid_do, created_at, updated_at)
VALUES
(1, '2026-03-01', '丙午年正月十三', '丙午年 庚寅月 戊申日', '角木蛟', '祭祀,祈福,求嗣,斋醮,嫁娶,冠笄,出行,开市,交易,会亲友,教牛马', '动土,伐木,安葬,开生坟', NOW(), NOW()),
(2, '2026-03-02', '丙午年正月十四', '丙午年 庚寅月 己酉日', '亢金龙', '祭祀,祈福,求嗣,斋醮,嫁娶,冠笄,出行,开市,交易,会亲友,教牛马', '动土,伐木,安葬,开生坟', NOW(), NOW());
+66
View File
@@ -0,0 +1,66 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
API_DIR="$PROJECT_ROOT/everything-is-suitable-api"
REPORT_DIR="$PROJECT_ROOT/test-automation/test-reports"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
CURRENT_REPORT_DIR="$REPORT_DIR/$TIMESTAMP"
mkdir -p "$CURRENT_REPORT_DIR"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
log "========================================="
log "API测试执行开始"
log "========================================="
log "项目根目录: $PROJECT_ROOT"
log "报告输出目录: $CURRENT_REPORT_DIR"
log "========================================="
cd "$API_DIR"
TEST_RESULT=0
log "[API测试] 开始执行API测试..."
API_TEST_LOG="$CURRENT_REPORT_DIR/api-test.log"
if mvn clean test -Dspring.profiles.active=test > "$API_TEST_LOG" 2>&1; then
log "[API测试] ✓ API测试通过"
else
log "[API测试] ✗ API测试失败"
TEST_RESULT=1
fi
log "[API测试] 复制测试报告..."
find "$API_DIR" -name "TEST-*.xml" -exec cp {} "$CURRENT_REPORT_DIR/" \; 2>/dev/null || true
find "$API_DIR" -name "surefire-reports" -type d -exec cp -r {} "$CURRENT_REPORT_DIR/" \; 2>/dev/null || true
log "[API测试] 复制JaCoCo覆盖率报告..."
find "$API_DIR" -path "*/target/site/jacoco/*" -exec cp -r {} "$CURRENT_REPORT_DIR/jacoco/" \; 2>/dev/null || true
log "[API测试] 生成Allure报告..."
find "$API_DIR" -path "*/target/allure-results/*" -exec cp -r {} "$CURRENT_REPORT_DIR/allure-results/" \; 2>/dev/null || true
if [ -d "$CURRENT_REPORT_DIR/allure-results" ]; then
allure generate "$CURRENT_REPORT_DIR/allure-results" -o "$CURRENT_REPORT_DIR/allure-report" 2>/dev/null || log "[API测试] Allure报告生成失败,但继续执行"
fi
log "[API测试] API测试完成"
log "========================================="
if [ $TEST_RESULT -eq 0 ]; then
log "✓ API测试通过"
log "退出码: 0"
exit 0
else
log "✗ API测试失败"
log "退出码: 1"
exit 1
fi
+22
View File
@@ -0,0 +1,22 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
LOG_DIR="$PROJECT_ROOT/test-automation/logs"
PID_FILE="$LOG_DIR/api-server.pid"
mkdir -p "$LOG_DIR"
echo "[启动API服务] 正在启动..."
cd "$PROJECT_ROOT/everything-is-suitable-api/everything-is-suitable-app"
export GATEWAY_PUBLIC_PATHS="/api/client/auth/register,/api/client/auth/login,/api/sys/auth/register,/api/sys/auth/login,/api/sys/auth/refresh,/api/sys/auth/logout,/sys/auth/register,/sys/auth/login,/sys/auth/refresh,/sys/auth/logout,/api/health,/api/swagger-ui,/api/swagger-ui/**,/api/v3/api-docs,/api/v3/api-docs/**,/api/webjars/swagger-ui/**,/api/webjars/**,/api/actuator/**,/api/almanac,/api/almanac/**,/actuator/**,/swagger-ui,/swagger-ui/**,/v3/api-docs,/v3/api-docs/**,/webjars/swagger-ui/**,/webjars/**,/almanac,/almanac/**"
nohup mvn spring-boot:run -Dspring-boot.run.profiles=test > "$LOG_DIR/api-server.log" 2>&1 &
API_PID=$!
echo $API_PID > "$PID_FILE"
echo "[启动API服务] 服务启动中,PID: $API_PID"
echo "[启动API服务] 日志文件: $LOG_DIR/api-server.log"
+22
View File
@@ -0,0 +1,22 @@
#!/bin/bash
MAX_WAIT=60
INTERVAL=5
HEALTH_URL="http://localhost:8080/actuator/health"
echo "[等待服务] 等待API服务就绪..."
waited=0
while [ $waited -lt $MAX_WAIT ]; do
if curl -s -f "$HEALTH_URL" > /dev/null 2>&1; then
echo "[等待服务] ✓ API服务已就绪"
exit 0
fi
echo "[等待服务] 等待中... ${waited}s/${MAX_WAIT}s"
sleep $INTERVAL
waited=$((waited + INTERVAL))
done
echo "[等待服务] ✗ API服务启动超时"
exit 1