# 测试文档 ## 版本历史 | 版本 | 日期 | 作者 | 变更说明 | |------|------|------|----------| | 1.0 | 2024-01-20 | 测试团队 | 初始版本 | | 1.1 | 2024-09-21 | 测试团队 | 更新测试策略,与实际项目保持一致 | ## 1. 测试概述 ### 1.1 测试目标 确保畜牧养殖管理平台的功能完整性、性能稳定性、安全可靠性,为用户提供高质量的软件产品。 ### 1.2 测试范围 - **功能测试**:验证系统功能是否符合需求规格说明 - **性能测试**:验证系统在各种负载下的性能表现 - **安全测试**:验证系统的安全防护能力 - **兼容性测试**:验证系统在不同环境下的兼容性 - **用户体验测试**:验证系统的易用性和用户体验 ### 1.3 测试策略 采用分层测试策略,包括单元测试、集成测试、系统测试和验收测试。 ```mermaid graph TD A[验收测试] --> B[系统测试] B --> C[集成测试] C --> D[单元测试] D --> D1[前端单元测试] D --> D2[后端单元测试] D --> D3[小程序单元测试] C --> C1[API集成测试] C --> C2[数据库集成测试] C --> C3[第三方服务集成测试] B --> B1[功能测试] B --> B2[性能测试] B --> B3[安全测试] A --> A1[用户验收测试] A --> A2[业务验收测试] ``` ## 2. 测试环境 ### 2.1 测试环境配置 | 环境类型 | 服务器配置 | 数据库 | 域名 | 用途 | |----------|------------|--------|------|------| | 开发测试环境 | 2核4G | MySQL 8.0 | dev-test.xlxumu.com | 开发阶段测试 | | 集成测试环境 | 4核8G | MySQL 8.0 + Redis | test.xlxumu.com | 集成测试 | | 性能测试环境 | 8核16G | MySQL 8.0 + Redis | perf.xlxumu.com | 性能测试 | | 预生产环境 | 8核16G | MySQL 8.0 + Redis | pre.xlxumu.com | 生产前验证 | ### 2.2 测试数据准备 ```sql -- 测试数据初始化脚本 -- 用户测试数据 INSERT INTO users (username, password, role, status) VALUES ('test_admin', 'hashed_password', 'admin', 'active'), ('test_farmer', 'hashed_password', 'farmer', 'active'), ('test_trader', 'hashed_password', 'trader', 'active'); -- 养殖场测试数据 INSERT INTO farms (name, owner_id, location, area, status) VALUES ('测试养殖场1', 1, '北京市朝阳区', 1000, 'active'), ('测试养殖场2', 2, '河北省承德市', 2000, 'active'); -- 动物测试数据 INSERT INTO animals (farm_id, breed, birth_date, gender, status) VALUES (1, '安格斯牛', '2023-01-15', 'male', 'healthy'), (1, '西门塔尔牛', '2023-02-20', 'female', 'healthy'), (2, '夏洛莱牛', '2023-03-10', 'male', 'healthy'); ``` ## 3. 单元测试 ### 3.1 前端单元测试 #### 3.1.1 Vue组件测试 ```javascript // tests/unit/components/AnimalCard.spec.js import { mount } from '@vue/test-utils' import AnimalCard from '@/components/AnimalCard.vue' describe('AnimalCard.vue', () => { it('renders animal information correctly', () => { const animal = { id: 1, breed: '安格斯牛', age: 12, weight: 450, status: 'healthy' } const wrapper = mount(AnimalCard, { props: { animal } }) expect(wrapper.text()).toContain('安格斯牛') expect(wrapper.text()).toContain('12') expect(wrapper.text()).toContain('450') expect(wrapper.find('.status-healthy')).toBeTruthy() }) it('emits edit event when edit button clicked', async () => { const animal = { id: 1, breed: '安格斯牛' } const wrapper = mount(AnimalCard, { props: { animal } }) await wrapper.find('.edit-btn').trigger('click') expect(wrapper.emitted().edit).toBeTruthy() expect(wrapper.emitted().edit[0]).toEqual([animal]) }) }) ``` #### 3.1.2 Vuex Store测试 ```javascript // tests/unit/store/animals.spec.js import { createStore } from 'vuex' import animalsModule from '@/store/modules/animals' describe('animals store module', () => { let store beforeEach(() => { store = createStore({ modules: { animals: animalsModule } }) }) it('should fetch animals list', async () => { const mockAnimals = [ { id: 1, breed: '安格斯牛' }, { id: 2, breed: '西门塔尔牛' } ] // Mock API response jest.spyOn(api, 'getAnimals').mockResolvedValue(mockAnimals) await store.dispatch('animals/fetchAnimals') expect(store.state.animals.list).toEqual(mockAnimals) expect(store.state.animals.loading).toBe(false) }) }) ``` ### 3.2 后端单元测试 #### 3.2.1 API接口测试 ```javascript // tests/unit/controllers/animals.test.js const request = require('supertest') const app = require('../../../app') const { Animal } = require('../../../models') describe('Animals API', () => { beforeEach(async () => { await Animal.destroy({ where: {} }) }) describe('GET /api/animals', () => { it('should return animals list', async () => { // 创建测试数据 await Animal.create({ breed: '安格斯牛', age: 12, weight: 450, status: 'healthy' }) const response = await request(app) .get('/api/animals') .expect(200) expect(response.body.success).toBe(true) expect(response.body.data).toHaveLength(1) expect(response.body.data[0].breed).toBe('安格斯牛') }) }) describe('POST /api/animals', () => { it('should create new animal', async () => { const animalData = { breed: '西门塔尔牛', age: 10, weight: 400, status: 'healthy' } const response = await request(app) .post('/api/animals') .send(animalData) .expect(201) expect(response.body.success).toBe(true) expect(response.body.data.breed).toBe('西门塔尔牛') // 验证数据库中是否创建成功 const animal = await Animal.findByPk(response.body.data.id) expect(animal).toBeTruthy() expect(animal.breed).toBe('西门塔尔牛') }) it('should validate required fields', async () => { const response = await request(app) .post('/api/animals') .send({}) .expect(400) expect(response.body.success).toBe(false) expect(response.body.message).toContain('breed is required') }) }) }) ``` #### 3.2.2 业务逻辑测试 ```javascript // tests/unit/services/animalService.test.js const AnimalService = require('../../../services/animalService') const { Animal } = require('../../../models') describe('AnimalService', () => { describe('calculateAge', () => { it('should calculate age correctly', () => { const birthDate = new Date('2022-01-01') const age = AnimalService.calculateAge(birthDate) expect(age).toBeGreaterThan(0) expect(typeof age).toBe('number') }) }) describe('getHealthStatus', () => { it('should return healthy status for normal weight', () => { const animal = { breed: '安格斯牛', weight: 450, age: 12 } const status = AnimalService.getHealthStatus(animal) expect(status).toBe('healthy') }) it('should return underweight status for low weight', () => { const animal = { breed: '安格斯牛', weight: 200, age: 12 } const status = AnimalService.getHealthStatus(animal) expect(status).toBe('underweight') }) }) }) ``` ### 3.3 小程序单元测试 ```javascript // miniprogram/tests/utils/formatDate.test.js const { formatDate } = require('../../utils/formatDate') describe('formatDate', () => { it('should format date correctly', () => { const date = new Date('2024-01-15T10:30:00') const formatted = formatDate(date, 'YYYY-MM-DD') expect(formatted).toBe('2024-01-15') }) it('should handle invalid date', () => { const formatted = formatDate(null, 'YYYY-MM-DD') expect(formatted).toBe('') }) }) ``` ## 4. 集成测试 ### 4.1 API集成测试 ```javascript // tests/integration/api.test.js const request = require('supertest') const app = require('../../app') describe('API Integration Tests', () => { let authToken beforeAll(async () => { // 登录获取token const loginResponse = await request(app) .post('/api/auth/login') .send({ username: 'test_admin', password: 'test_password' }) authToken = loginResponse.body.data.token }) describe('Animals CRUD Operations', () => { let animalId it('should create animal', async () => { const response = await request(app) .post('/api/animals') .set('Authorization', `Bearer ${authToken}`) .send({ breed: '安格斯牛', farmId: 1, birthDate: '2023-01-15', gender: 'male' }) .expect(201) animalId = response.body.data.id expect(response.body.success).toBe(true) }) it('should get animal details', async () => { const response = await request(app) .get(`/api/animals/${animalId}`) .set('Authorization', `Bearer ${authToken}`) .expect(200) expect(response.body.data.breed).toBe('安格斯牛') }) it('should update animal', async () => { const response = await request(app) .put(`/api/animals/${animalId}`) .set('Authorization', `Bearer ${authToken}`) .send({ weight: 450 }) .expect(200) expect(response.body.data.weight).toBe(450) }) it('should delete animal', async () => { await request(app) .delete(`/api/animals/${animalId}`) .set('Authorization', `Bearer ${authToken}`) .expect(200) // 验证删除成功 await request(app) .get(`/api/animals/${animalId}`) .set('Authorization', `Bearer ${authToken}`) .expect(404) }) }) }) ``` ### 4.2 数据库集成测试 ```javascript // tests/integration/database.test.js const { sequelize, User, Farm, Animal } = require('../../models') describe('Database Integration Tests', () => { beforeAll(async () => { await sequelize.sync({ force: true }) }) afterAll(async () => { await sequelize.close() }) describe('Model Associations', () => { it('should create user with farm and animals', async () => { // 创建用户 const user = await User.create({ username: 'test_farmer', email: 'farmer@test.com', password: 'hashed_password', role: 'farmer' }) // 创建养殖场 const farm = await Farm.create({ name: '测试养殖场', ownerId: user.id, location: '北京市朝阳区', area: 1000 }) // 创建动物 const animal = await Animal.create({ farmId: farm.id, breed: '安格斯牛', birthDate: new Date('2023-01-15'), gender: 'male' }) // 验证关联关系 const userWithFarms = await User.findByPk(user.id, { include: [{ model: Farm, include: [Animal] }] }) expect(userWithFarms.Farms).toHaveLength(1) expect(userWithFarms.Farms[0].Animals).toHaveLength(1) expect(userWithFarms.Farms[0].Animals[0].breed).toBe('安格斯牛') }) }) }) ``` ## 5. 系统测试 ### 5.1 功能测试用例 #### 5.1.1 用户管理功能测试 | 测试用例ID | 测试场景 | 测试步骤 | 预期结果 | |------------|----------|----------|----------| | TC_USER_001 | 用户注册 | 1. 访问注册页面
2. 填写用户信息
3. 点击注册按钮 | 注册成功,跳转到登录页面 | | TC_USER_002 | 用户登录 | 1. 访问登录页面
2. 输入用户名密码
3. 点击登录按钮 | 登录成功,跳转到首页 | | TC_USER_003 | 密码重置 | 1. 点击忘记密码
2. 输入邮箱
3. 查收邮件重置密码 | 密码重置成功 | #### 5.1.2 养殖管理功能测试 | 测试用例ID | 测试场景 | 测试步骤 | 预期结果 | |------------|----------|----------|----------| | TC_FARM_001 | 添加养殖场 | 1. 进入养殖场管理
2. 点击添加养殖场
3. 填写养殖场信息
4. 保存 | 养殖场添加成功 | | TC_ANIMAL_001 | 添加动物档案 | 1. 进入动物管理
2. 点击添加动物
3. 填写动物信息
4. 保存 | 动物档案创建成功 | | TC_HEALTH_001 | 健康记录管理 | 1. 选择动物
2. 添加健康记录
3. 填写检查结果
4. 保存 | 健康记录保存成功 | ### 5.2 自动化测试脚本 #### 5.2.1 Selenium Web自动化测试 ```python # tests/e2e/test_user_login.py from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import unittest class TestUserLogin(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.get("http://test.xlxumu.com") def tearDown(self): self.driver.quit() def test_successful_login(self): # 点击登录按钮 login_btn = self.driver.find_element(By.ID, "login-btn") login_btn.click() # 输入用户名 username_input = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.ID, "username")) ) username_input.send_keys("test_admin") # 输入密码 password_input = self.driver.find_element(By.ID, "password") password_input.send_keys("test_password") # 点击登录 submit_btn = self.driver.find_element(By.ID, "submit-btn") submit_btn.click() # 验证登录成功 WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "dashboard")) ) self.assertIn("仪表板", self.driver.title) def test_invalid_credentials(self): # 输入错误的用户名密码 login_btn = self.driver.find_element(By.ID, "login-btn") login_btn.click() username_input = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.ID, "username")) ) username_input.send_keys("invalid_user") password_input = self.driver.find_element(By.ID, "password") password_input.send_keys("invalid_password") submit_btn = self.driver.find_element(By.ID, "submit-btn") submit_btn.click() # 验证错误提示 error_message = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "error-message")) ) self.assertIn("用户名或密码错误", error_message.text) if __name__ == "__main__": unittest.main() ``` #### 5.2.2 小程序自动化测试 ```javascript // tests/e2e/miniprogram/login.test.js const automator = require('miniprogram-automator') describe('小程序登录测试', () => { let miniProgram let page beforeAll(async () => { miniProgram = await automator.launch({ cliPath: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli', projectPath: './miniprogram' }) page = await miniProgram.reLaunch('/pages/login/login') }) afterAll(async () => { await miniProgram.close() }) it('should login successfully with valid credentials', async () => { // 输入用户名 const usernameInput = await page.$('.username-input') await usernameInput.input('test_user') // 输入密码 const passwordInput = await page.$('.password-input') await passwordInput.input('test_password') // 点击登录按钮 const loginBtn = await page.$('.login-btn') await loginBtn.tap() // 等待跳转到首页 await page.waitFor(2000) // 验证当前页面 const currentPath = await page.path expect(currentPath).toBe('pages/index/index') }) }) ``` ## 6. 性能测试 ### 6.1 性能测试指标 | 指标类型 | 指标名称 | 目标值 | 测试方法 | |----------|----------|--------|----------| | 响应时间 | 页面加载时间 | < 3秒 | 浏览器性能测试 | | 响应时间 | API响应时间 | < 500ms | 接口压力测试 | | 吞吐量 | 并发用户数 | 1000+ | 负载测试 | | 吞吐量 | 每秒请求数 | 500+ | 压力测试 | | 资源使用 | CPU使用率 | < 70% | 系统监控 | | 资源使用 | 内存使用率 | < 80% | 系统监控 | ### 6.2 JMeter性能测试脚本 ```xml false false continue false 10 100 60 false {"username":"test_user","password":"test_password"} = test.xlxumu.com 80 http /api/auth/login POST true Assertion.response_data false 2 ``` ### 6.3 性能监控脚本 ```bash #!/bin/bash # performance-monitor.sh # 性能监控脚本 echo "开始性能监控..." # 监控CPU使用率 echo "CPU使用率:" top -l 1 | grep "CPU usage" # 监控内存使用率 echo "内存使用率:" vm_stat | grep "Pages free\|Pages active\|Pages inactive\|Pages speculative\|Pages wired down" # 监控磁盘使用率 echo "磁盘使用率:" df -h # 监控网络连接 echo "网络连接数:" netstat -an | grep ESTABLISHED | wc -l # 监控数据库连接 echo "数据库连接数:" mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';" # 监控Redis连接 echo "Redis连接数:" redis-cli info clients | grep connected_clients ``` ## 7. 安全测试 ### 7.1 安全测试检查项 | 安全类型 | 检查项 | 测试方法 | 风险等级 | |----------|--------|----------|----------| | 身份认证 | 弱密码检测 | 密码策略测试 | 高 | | 身份认证 | 会话管理 | 会话超时测试 | 中 | | 授权控制 | 权限绕过 | 越权访问测试 | 高 | | 数据验证 | SQL注入 | 注入攻击测试 | 高 | | 数据验证 | XSS攻击 | 脚本注入测试 | 中 | | 数据传输 | HTTPS加密 | 传输加密测试 | 高 | | 数据存储 | 敏感数据加密 | 数据加密测试 | 高 | ### 7.2 安全测试工具 #### 7.2.1 OWASP ZAP自动化扫描 ```python # security_scan.py from zapv2 import ZAPv2 import time # ZAP代理配置 zap = ZAPv2(proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}) # 目标URL target = 'http://test.xlxumu.com' # 开始爬虫扫描 print('开始爬虫扫描...') scanid = zap.spider.scan(target) time.sleep(2) while int(zap.spider.status(scanid)) < 100: print(f'爬虫进度: {zap.spider.status(scanid)}%') time.sleep(2) print('爬虫扫描完成') # 开始主动扫描 print('开始主动安全扫描...') scanid = zap.ascan.scan(target) while int(zap.ascan.status(scanid)) < 100: print(f'扫描进度: {zap.ascan.status(scanid)}%') time.sleep(5) print('安全扫描完成') # 生成报告 print('生成安全报告...') with open('security_report.html', 'w') as f: f.write(zap.core.htmlreport()) print('安全报告已生成: security_report.html') ``` #### 7.2.2 SQL注入测试 ```python # sql_injection_test.py import requests import json def test_sql_injection(): """SQL注入测试""" base_url = "http://test.xlxumu.com/api" # 测试用例 injection_payloads = [ "' OR '1'='1", "'; DROP TABLE users; --", "' UNION SELECT * FROM users --", "1' AND (SELECT COUNT(*) FROM users) > 0 --" ] # 测试登录接口 for payload in injection_payloads: data = { "username": payload, "password": "test" } response = requests.post(f"{base_url}/auth/login", json=data) if response.status_code == 200: result = response.json() if result.get('success'): print(f"⚠️ 可能存在SQL注入漏洞: {payload}") else: print(f"✅ 防护正常: {payload}") else: print(f"✅ 请求被拒绝: {payload}") if __name__ == "__main__": test_sql_injection() ``` ## 8. 测试报告 ### 8.1 测试执行报告模板 ```markdown # 测试执行报告 ## 基本信息 - **项目名称**: 畜牧养殖管理平台 - **测试版本**: v1.0.0 - **测试环境**: 测试环境 - **测试时间**: 2024-01-20 ~ 2024-01-25 - **测试负责人**: 张三 ## 测试概况 - **计划测试用例**: 150个 - **实际执行用例**: 148个 - **通过用例**: 142个 - **失败用例**: 6个 - **阻塞用例**: 2个 - **测试通过率**: 95.9% ## 功能测试结果 | 功能模块 | 计划用例 | 执行用例 | 通过用例 | 失败用例 | 通过率 | |----------|----------|----------|----------|----------|--------| | 用户管理 | 25 | 25 | 24 | 1 | 96% | | 养殖管理 | 40 | 40 | 38 | 2 | 95% | | 交易管理 | 30 | 30 | 29 | 1 | 97% | | 财务管理 | 20 | 20 | 19 | 1 | 95% | | 系统管理 | 15 | 15 | 15 | 0 | 100% | | 数据统计 | 20 | 18 | 17 | 1 | 94% | ## 性能测试结果 | 测试指标 | 目标值 | 实际值 | 是否达标 | |----------|--------|--------|----------| | 页面加载时间 | < 3秒 | 2.1秒 | ✅ | | API响应时间 | < 500ms | 320ms | ✅ | | 并发用户数 | 1000+ | 1200 | ✅ | | CPU使用率 | < 70% | 65% | ✅ | | 内存使用率 | < 80% | 72% | ✅ | ## 安全测试结果 | 安全项目 | 测试结果 | 风险等级 | 处理状态 | |----------|----------|----------|----------| | SQL注入 | 无漏洞 | 无 | ✅ | | XSS攻击 | 发现1个 | 中 | 🔄 修复中 | | 权限控制 | 无问题 | 无 | ✅ | | 数据加密 | 符合要求 | 无 | ✅ | ## 缺陷统计 | 缺陷等级 | 数量 | 已修复 | 待修复 | |----------|------|--------|--------| | 严重 | 2 | 1 | 1 | | 一般 | 4 | 3 | 1 | | 轻微 | 8 | 6 | 2 | | 建议 | 5 | 2 | 3 | ## 测试结论 系统整体功能完整,性能表现良好,安全防护到位。建议修复剩余缺陷后发布。 ``` ### 8.2 自动化测试报告生成 ```javascript // generate-test-report.js const fs = require('fs') const path = require('path') class TestReporter { constructor() { this.results = { total: 0, passed: 0, failed: 0, skipped: 0, suites: [] } } addSuite(suite) { this.results.suites.push(suite) this.results.total += suite.tests.length this.results.passed += suite.tests.filter(t => t.status === 'passed').length this.results.failed += suite.tests.filter(t => t.status === 'failed').length this.results.skipped += suite.tests.filter(t => t.status === 'skipped').length } generateHTML() { const template = ` 测试报告

测试执行报告

测试概况

总用例数: ${this.results.total}

通过: ${this.results.passed}

失败: ${this.results.failed}

跳过: ${this.results.skipped}

通过率: ${((this.results.passed / this.results.total) * 100).toFixed(2)}%

详细结果

${this.results.suites.map(suite => suite.tests.map(test => ` `).join('') ).join('')}
测试套件 测试用例 状态 执行时间 错误信息
${suite.name} ${test.name} ${test.status} ${test.duration}ms ${test.error || ''}

报告生成时间: ${new Date().toLocaleString()}

` return template } saveReport(filename = 'test-report.html') { const html = this.generateHTML() fs.writeFileSync(filename, html) console.log(`测试报告已生成: ${filename}`) } } module.exports = TestReporter ``` ## 9. 测试工具和环境 ### 9.1 测试工具清单 | 工具类型 | 工具名称 | 版本 | 用途 | |----------|----------|------|------| | 单元测试 | Jest | 29.x | JavaScript单元测试 | | 单元测试 | Vue Test Utils | 2.x | Vue组件测试 | | 集成测试 | Supertest | 6.x | API集成测试 | | E2E测试 | Selenium | 4.x | Web自动化测试 | | E2E测试 | Miniprogram Automator | 0.x | 小程序自动化测试 | | 性能测试 | JMeter | 5.x | 性能压力测试 | | 安全测试 | OWASP ZAP | 2.x | 安全漏洞扫描 | | 测试管理 | TestRail | - | 测试用例管理 | ### 9.2 CI/CD集成 ```yaml # .github/workflows/test.yml name: 自动化测试 on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: test: runs-on: ubuntu-latest services: mysql: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: test_db options: >- --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 redis: image: redis:6-alpine options: >- --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Run unit tests run: npm run test:unit - name: Run integration tests run: npm run test:integration env: DATABASE_URL: mysql://root:root@localhost:3306/test_db REDIS_URL: redis://localhost:6379 - name: Run E2E tests run: npm run test:e2e - name: Generate test report run: npm run test:report - name: Upload test results uses: actions/upload-artifact@v3 with: name: test-results path: test-results/ ``` ## 10. 总结 ### 10.1 测试策略总结 本测试文档建立了完整的测试体系,包括: 1. **多层次测试**:从单元测试到系统测试的完整覆盖 2. **自动化测试**:提高测试效率和准确性 3. **性能测试**:确保系统性能满足要求 4. **安全测试**:保障系统安全可靠 5. **持续集成**:自动化测试流程 ### 10.2 测试质量保证 - **测试覆盖率**:代码覆盖率 > 80% - **自动化率**:自动化测试覆盖率 > 70% - **缺陷密度**:< 2个缺陷/KLOC - **测试效率**:回归测试时间 < 2小时 ### 10.3 持续改进 1. **测试工具升级**:定期更新测试工具和框架 2. **测试流程优化**:持续优化测试流程和方法 3. **团队技能提升**:加强测试团队技能培训 4. **质量度量**:建立完善的质量度量体系 --- **文档版本**: v1.0.0 **最后更新**: 2024年12月 **维护团队**: 测试团队