代码优化指南

387 浏览
39 试用
11 购买
Nov 24, 2025更新

一键优化代码结构,升级现代写法,标注改进收益,让代码更规范、更易维护!

下面给出基于 Django 的重构版本,并逐条标注改动与收益。示例使用类视图(CBV)、Django ORM、分页、JSON/CSV 双输出、类型标注、结构化日志与异常处理等现代特性。

重构后的代码

from typing import Iterable, Iterator, List, Dict import logging import csv import io from pathlib import Path

from django.contrib.auth import get_user_model from django.core.paginator import Paginator, EmptyPage from django.http import JsonResponse, StreamingHttpResponse, HttpRequest, HttpResponse from django.views import View

logger = logging.getLogger(name)

新式工具函数:类型标注与内置 sum,避免手写循环

def compute(x: Iterable[int]) -> int: return sum(x)

class UserListView(View): default_page_size: int = 20 max_page_size: int = 100

def get(self, request: HttpRequest) -> HttpResponse:
    fmt = (request.GET.get('format') or 'json').lower()
    page_str = request.GET.get('page', '1')
    per_page_str = request.GET.get('per_page', str(self.default_page_size))

    # 参数校验与默认值处理
    try:
        page = max(1, int(page_str))
    except ValueError:
        return JsonResponse({'error': 'Invalid page parameter'}, status=400)

    try:
        per_page = max(1, int(per_page_str))
        per_page = min(per_page, self.max_page_size)
    except ValueError:
        per_page = self.default_page_size

    if fmt not in {'json', 'csv'}:
        return JsonResponse({'error': 'Invalid format parameter'}, status=400)

    try:
        User = get_user_model()
        # ORM + values:仅取必要字段,避免加载不需要的列
        qs = (
            User.objects
            .values('id', 'email', 'first_name', 'last_name', 'username')
            .order_by('id')
        )

        paginator = Paginator(qs, per_page)
        try:
            page_obj = paginator.page(page)
        except EmptyPage:
            return JsonResponse(
                {'error': 'Page out of range', 'total_pages': paginator.num_pages},
                status=404
            )

        # 列表推导 + 轻量序列化
        data: List[Dict] = [self._serialize_user(u) for u in page_obj.object_list]

        logger.info(
            'User list requested',
            extra={'page': page, 'per_page': per_page, 'format': fmt, 'count': len(data)}
        )

        if fmt == 'csv':
            # Streaming CSV,避免一次性拼接大字符串造成内存压力
            filename = Path(f'users_page_{page}.csv').name
            response = StreamingHttpResponse(
                self._csv_row_generator(data),
                content_type='text/csv; charset=utf-8'
            )
            response['Content-Disposition'] = f'attachment; filename="{filename}"'
            return response

        # 标准 JSON 响应
        return JsonResponse(
            {
                'data': data,
                'count': paginator.count,
                'page': page_obj.number,
                'total_pages': paginator.num_pages,
                'per_page': per_page,
            },
            json_dumps_params={'ensure_ascii': False}
        )

    except Exception as exc:
        # 结构化日志 + 统一错误响应
        logger.exception('Failed to fetch user list', extra={'page': page, 'per_page': per_page, 'format': fmt})
        return JsonResponse({'error': 'Internal server error'}, status=500)

@staticmethod
def _serialize_user(u: Dict) -> Dict:
    full_name = f"{u.get('first_name', '')} {u.get('last_name', '')}".strip()
    name = full_name or u.get('username', '')
    return {'id': u['id'], 'name': name, 'email': u.get('email', '')}

@staticmethod
def _csv_row_generator(users: List[Dict]) -> Iterator[str]:
    # 使用 csv.writer 保证正确的 CSV 转义;with 上下文管理器管理临时缓冲
    yield 'id,name,email\n'
    for u in users:
        with io.StringIO() as s:
            writer = csv.writer(s)
            writer.writerow([u['id'], u['name'], u['email']])
            yield s.getvalue()

更改点与带来的好处

  • 将函数视图重构为类视图(CBV,UserListView)
    • 好处:更易扩展(支持不同 HTTP 方法)、可复用性强,符合 Django 最佳实践。
  • 使用 Django ORM 替代原生 SQL(get_user_model + values + order_by)
    • 好处:防止 SQL 注入、统一数据访问、只取必要字段提升性能与内存占用。
  • 使用 values/select_related/prefetch_related 的思想优化查询(此处 values 即足够)
    • 好处:减少不必要的字段/关系加载;在有外键场景可继续扩展 select_related/prefetch_related。
  • 引入 Paginator 分页,参数校验和默认值处理(page/per_page,范围限制)
    • 好处:避免全表查询一次性返回;保证健壮性与可控的响应大小。
  • 标准化响应:JsonResponse;CSV 使用 StreamingHttpResponse 流式输出
    • 好处:正确的 Content-Type;流式 CSV 避免一次性构建大型字符串造成内存峰值。
  • 类型标注与现代语法(类型注解、列表推导、f-strings、with 上下文管理器)
    • 好处:提高可读性与静态检查效果;减少低级错误(资源泄露、拼接错误)。
  • 统一文件/路径处理(pathlib 构建导出文件名)
    • 好处:避免硬编码字符串;跨平台一致的路径/文件名处理方式。
  • 结构化日志与异常处理(logger.info/exception,统一 400/404/500 返回)
    • 好处:便于排查问题与监控;避免裸露 print 与不规范异常,提升可观测性。
  • 安全与性能改进
    • 好处:使用 ORM 防注入;分页与 values 减少 IO 与内存;列表推导提升速度;CSV 用 writer 确保正确转义。
  • 可扩展的缓存(可选)
    • 好处:热点页可以用 Django cache 缓存 JSON 输出(例如短期 60s),进一步降低数据库压力。
  • 计算函数 compute 重写为 sum + 类型标注
    • 好处:语义清晰、性能更优、代码更简洁。

测试建议(示例用例)

  • 分页与参数校验
    • 请求 /users/?page=1&per_page=20 返回 200,数据条数不超过 20,包含 count/page/total_pages。
    • 请求 /users/?page=abc 返回 400。
    • 请求 /users/?page=9999 返回 404,包含 total_pages。
  • 格式切换与 CSV 导出
    • 请求 /users/?format=csv 返回 200,Content-Type 为 text/csv;响应头包含 Content-Disposition,文件名含 page。
    • CSV 内容首行为 id,name,email;字段正确转义(包含逗号、引号的姓名能正确输出)。
  • 性能与选择字段
    • 断言视图使用 values 只拉取 id/email/first_name/last_name/username,不访问多余字段。
  • 错误处理与日志
    • 模拟数据库异常,视图返回 500 且 logger 捕获 exception。

路由示例(urls.py)

from django.urls import path from .views import UserListView

urlpatterns = [ path('users/', UserListView.as_view(), name='user-list'), ]

备注

  • 如果项目中已有自定义 User 模型并包含 name 字段,可将 _serialize_user 中的 name 组装逻辑改为直接读取 u['name']。
  • 如需 DRF 风格,可将视图改为继承 rest_framework.views.APIView,并使用 Response/renderer;思路与实现基本一致。

下面是按现代 React 最佳实践重构后的代码,并在关键位置用注释标注了改动与原因。随后附上改动说明与收益。

重构后的代码(函数组件 + Hooks + async/await + AbortController + 子组件拆分) import React from 'react';

// 可单元测试的纯函数:数据规范化 export function normalizeItems(data) { const array = Array.isArray(data) ? data : []; return array.map(d => ({ ...d, // 使用可选链与空值合并,确保 name 有值 name: d?.name ?? 'unknown', })); }

// 可单元测试的纯函数:过滤逻辑 export function filterItems(items, filter) { if (!filter) return items; const f = filter.toString(); return items.filter(i => (i?.name ?? '').includes(f)); }

// 子组件拆分,便于复用与测试;React.memo 避免不必要重渲染 const Item = React.memo(function Item({ item }) { return

  • {item?.name ?? 'unknown'}
  • ; });

    export default function Dashboard() { // 1) 类组件 -> 函数组件;使用 useState 管理状态 const [items, setItems] = React.useState([]); const [filter, setFilter] = React.useState(''); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null);

    // 2) 事件监听在 useEffect 中注册/清理,避免泄漏 React.useEffect(() => { const onResize = () => { console.log('resize'); }; window.addEventListener('resize', onResize); return () => { window.removeEventListener('resize', onResize); // 清理 }; }, []);

    // 3) 数据获取:使用 async/await + AbortController;在卸载时取消请求 React.useEffect(() => { let cancelled = false; const controller = new AbortController();

    async function fetchData() {
      try {
        setLoading(true);
        setError(null);
        const res = await fetch('/api/items', { signal: controller.signal });
        const json = await res.json();
        const normalized = normalizeItems(json);
        if (!cancelled) {
          setItems(normalized); // 保证不可变数据更新
        }
      } catch (e) {
        // 统一错误处理与日志;忽略主动取消错误
        if (e.name !== 'AbortError') {
          console.error('fetch /api/items error:', e);
          if (!cancelled) setError(e);
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    
    fetchData();
    
    return () => {
      cancelled = true;      // 标记,防止卸载后 setState
      controller.abort();    // 取消进行中的请求
    };
    

    }, []);

    // 4) 用 useMemo 对过滤结果进行计算与缓存 const filteredList = React.useMemo(() => { return filterItems(items, filter); }, [items, filter]);

    // 5) 用 useCallback 稳定事件处理函数引用 const handleFilterChange = React.useCallback((e) => { setFilter(e.target?.value ?? ''); }, []);

    return (

    {/* 受控输入,禁止直接修改 state /} {/ 统一错误展示,提升可观测性 */} {error ? <span style={{ color: 'red' }}>出错了,请稍后重试 : null} {loading ? loading... : null}
      {filteredList.map((item) => ( // key 采用更稳健的回退策略 <Item key={item?.id ?? item?.name ?? Math.random()} item={item} /> ))}
    ); }

    更改点标注与好处

    • 将类组件重写为函数组件,使用 useState/useEffect/useMemo/useCallback:

      • 改动:Dashboard 改为函数组件;使用 useState 管理 items/filter/loading/error;用 useEffect 管理副作用;用 useMemo 缓存过滤结果;用 useCallback 稳定事件处理函数。
      • 好处:现代 React 写法更简洁可维护;副作用管理清晰;在依赖变更时精确触发,减少不必要渲染。
    • then 回调改为 async/await,并使用 AbortController 支持请求取消与组件卸载清理:

      • 改动:fetchData 逻辑在 useEffect 内用 async/await;引入 AbortController,并在清理函数中 controller.abort();增加 cancelled 标记避免卸载后 setState。
      • 好处:异步流程更直观;避免组件卸载后仍更新状态导致的内存泄漏与警告;请求可取消,消除竞态条件。
    • 在 useEffect 中注册/清理事件监听,避免内存泄漏;移除不必要的全局监听:

      • 改动:window.resize 监听在 useEffect 中注册,并在返回的清理函数中移除。
      • 好处:消除全局事件泄漏风险;组件生命周期内自洽。
    • 禁止直接修改 state,保证不可变数据;对过滤结果使用 useMemo 提升性能:

      • 改动:去掉 this.state.items = data 的直接赋值;改用 setItems(normalized);用 useMemo 对 filter 计算缓存。
      • 好处:遵守 React 状态不可变原则,确保正确触发渲染与优化;大列表或频繁输入时性能更好。
    • 使用可选链 ?. 与空值合并 ?? 提高健壮性;统一错误处理与日志:

      • 改动:对 name 使用 d?.name ?? 'unknown';读取 e.target?.value ?? '';map key 使用可选链与回退;catch 中统一 console.error 并设置 error 状态。
      • 好处:应对后端不完整数据与边界情况更稳健;错误更易定位与观察。
    • 拆分子组件(列表项)提升复用与可测试性:

      • 改动:新增 Item 子组件,并用 React.memo 包裹;将纯函数 normalizeItems 与 filterItems 独立导出。
      • 好处:列表项可复用并独立测试;通过 React.memo 减少子项不必要渲染;数据处理逻辑可进行单元测试。
    • 单元测试建议(示例思路):

      • normalizeItems:输入包含 undefined/null 的 name,断言输出 name 都为 'unknown'。
      • filterItems:输入不同 filter 与大小写场景,断言返回的列表正确。
      • Dashboard 行为测试:mock fetch 返回数据,验证 loading 状态切换、错误处理、AbortController 在卸载时被调用;输入框修改时 filteredList 变化正确。

    总结 本次重构遵循现代 React 最佳实践,明确副作用边界、避免状态直接变更、引入请求取消与清理机制、提升渲染与数据处理性能,并通过子组件与纯函数拆分提升复用与可测试性。整体代码更健壮、可维护、易扩展。

    下面给出基于 Spring Boot + Spring Data JPA 的重构版本,并在代码内用注释标注关键修改点。最后附上变更清单与收益说明,以及可选的测试骨架。

    重构后的代码

    1. 持久化模型与仓库 // Entity:由手写 JDBC 结果集映射改为 JPA 实体映射 // 好处:少写样板代码、类型安全、便于分页/排序/事务管理 import jakarta.persistence.*;

    @Entity @Table(name = "report") public class Report { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;

    @Column(nullable = false) // 可根据实际字段约束调整
    private String name;
    
    @Column(nullable = false)
    private int score;
    
    public Report() {}
    public Report(Long id, String name, int score) {
        this.id = id;
        this.name = name;
        this.score = score;
    }
    public Long getId() { return id; }
    public String getName() { return name; }
    public int getScore() { return score; }
    public void setId(Long id) { this.id = id; }
    public void setName(String name) { this.name = name; }
    public void setScore(int score) { this.score = score; }
    

    }

    // Repository:由手写 SQL 改为 Spring Data JPA 方法查询 + 分页 // 好处:无需手写 JDBC/SQL 与资源关闭;内置分页/排序 import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository;

    public interface ReportRepository extends JpaRepository<Report, Long> { Page findByNameContainingIgnoreCase(String name, Pageable pageable); }

    1. DTO(不可变,使用 record) // 由可变 POJO 改为 record,不可变更安全 public record ReportDto(Long id, String name, int score) { public static ReportDto from(Report e) { return new ReportDto(e.getId(), e.getName(), e.getScore()); } }

    2. Service(构造器注入 + 事务 + JPA + Page.map) // 由手动 DataSource/JDBC 改为仓库;readOnly 事务;构造器注入 import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;

    @Service @Transactional(readOnly = true) // 变更点:开启只读事务,保证一致性与性能 public class ReportService { private final ReportRepository repository; // 变更点:构造器注入替代字段注入

    public ReportService(ReportRepository repository) {
        this.repository = repository;
    }
    
    public Page<ReportDto> findReports(String q, Pageable pageable) {
        // 变更点:分页与排序交给数据库;使用 Page.map 转 DTO
        return repository.findByNameContainingIgnoreCase(q, pageable)
                         .map(ReportDto::from);
    }
    

    }

    1. Controller(RestController + ResponseEntity + 校验 + 日志) // 由 @Controller + @ResponseBody 改为 @RestController // 由 System.out 改为 slf4j 日志 // 增加 Bean Validation 与 Pageable 支持 import jakarta.validation.constraints.NotBlank; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*;

    import org.springframework.data.domain.Page;

    @RestController @RequestMapping("/reports") // 统一前缀 @Validated // 变更点:启用参数校验 public class ReportController { private static final Logger log = LoggerFactory.getLogger(ReportController.class);

    private final ReportService service; // 变更点:构造器注入
    
    public ReportController(ReportService service) {
        this.service = service;
    }
    
    @GetMapping
    public ResponseEntity<Page<ReportDto>> reports(
            @RequestParam("q") @NotBlank String q, // 变更点:参数校验
            @PageableDefault(size = 20, sort = "score", direction = Sort.Direction.ASC) Pageable pageable // 变更点:分页与默认排序
    ) {
        log.info("Searching reports, q={}", q); // 变更点:统一使用 slf4j 日志
        return ResponseEntity.ok(service.findReports(q, pageable));
    }
    

    }

    说明与变更点汇总

    • 数据访问层:手写 JDBC → Spring Data JPA Repository

      • 变更:增加 Report 实体与 ReportRepository;通过方法命名查询 findByNameContainingIgnoreCase + Pageable。
      • 好处:无需手写 SQL/资源关闭,分页/排序/事务内置,代码简洁可维护。
    • 依赖注入:字段注入 + 手动构建 DataSource → 构造器注入 + 框架管理 DataSource

      • 变更:Service/Controller 使用构造器注入,删除手动创建 DataSource。
      • 好处:可测试性更强;生命周期清晰;遵循 DI/IoC。
    • 控制器:@Controller + @ResponseBody → @RestController + ResponseEntity

      • 变更:统一 REST 风格返回 ResponseEntity,集中化序列化与状态码管理。
      • 好处:响应更规范,易于统一异常与返回格式。
    • DTO:可变 POJO → Java record 不可变对象

      • 变更:ReportDto 改为 record,并提供静态映射方法。
      • 好处:线程安全、语义明确、减少样板代码。
    • 日志:System.out.println → slf4j Logger

      • 变更:使用 LoggerFactory.getLogger 并 log.info。
      • 好处:可配置级别与输出,生产可用。
    • 事务与资源:try-finally 关闭资源 → @Transactional(readOnly = true)

      • 变更:在 Service 层标注事务,JPA 管理连接与会话。
      • 好处:更安全的事务边界与连接管理,减少资源泄漏风险。
    • 集合处理:手写 Comparator → 数据库排序或 Streams

      • 变更:默认通过 Pageable 的 Sort 在数据库层按 score 升序排序;如需内存排序可使用 Comparator.comparingInt。
      • 好处:将排序下推数据库,减少内存占用,提高性能与可读性。
    • 参数校验与分页:Bean Validation + Pageable

      • 变更:@NotBlank 校验 q;@PageableDefault 提供默认分页与排序。
      • 好处:早期失败、接口更健壮;统一分页能力,避免一次性拉取全量数据。

    可选:若暂时仍需 JDBC,使用 try-with-resources // 只作示例,推荐优先使用 JPA try (Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement("SELECT id,name,score FROM report WHERE name LIKE ?")) { ps.setString(1, "%" + q + "%"); try (ResultSet rs = ps.executeQuery()) { List list = new ArrayList<>(); while (rs.next()) { list.add(new ReportDto(rs.getLong("id"), rs.getString("name"), rs.getInt("score"))); } // 使用 Streams/Comparator return list.stream() .sorted(java.util.Comparator.comparingInt(ReportDto::score)) .toList(); } }

    测试建议(骨架)

    • Repository 层(查询与分页/排序)
      • 使用 @DataJpaTest
      • 验证 findByNameContainingIgnoreCase 返回正确分页大小与顺序(按 score 升序)
    • Controller 层(参数校验与响应)
      • 使用 @SpringBootTest + @AutoConfigureMockMvc
      • 断言 GET /reports?q=xx 返回 200,内容包含期望字段;q 为空返回 400

    示例(极简伪代码): @DataJpaTest class ReportRepositoryTest { @Autowired ReportRepository repo; @Test void should_query_by_name_with_pagination() { // 给定测试数据... var page = repo.findByNameContainingIgnoreCase("abc", org.springframework.data.domain.PageRequest.of(0, 10, Sort.by("score"))); org.assertj.core.api.Assertions.assertThat(page.getContent()).isSortedAccordingTo(java.util.Comparator.comparingInt(Report::getScore)); } }

    @org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc @org.springframework.boot.test.context.SpringBootTest class ReportControllerTest { @Autowired org.springframework.test.web.servlet.MockMvc mockMvc; @org.junit.jupiter.api.Test void should_validate_params_and_return_page() throws Exception { mockMvc.perform(org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get("/reports").param("q", "abc")) .andExpect(org.springframework.test.web.servlet.result.MockMvcResultMatchers.status().isOk()); mockMvc.perform(org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get("/reports").param("q", "")) .andExpect(org.springframework.test.web.servlet.result.MockMvcResultMatchers.status().isBadRequest()); } }

    依赖提示

    • 引入 spring-boot-starter-web、spring-boot-starter-data-jpa、spring-boot-starter-validation、数据库驱动(如 mysql-connector-j)、可选 lombok。
    • application.yml 配置数据源与 JPA 方言/DDL 策略。

    以上重构将数据访问、事务、日志、校验、分页/排序与响应格式系统化、现代化,减少样板与易错点,显著提升可维护性与可测试性。

    示例详情

    解决的问题

    开发者的工作场景描述

    解决的问题

    针对 代码优化与重构 的日常工作场景,该工具旨在解决以下问题:

    • 遗留代码难以维护,不符合现代编程规范
    • 代码性能瓶颈影响系统运行效率
    • 代码可读性差,团队协作效率低下

    工具介绍

    工具名称: 代码优化指南
    功能简介: 将现有代码转换为更符合指定语言或框架习惯的写法,或重构为使用现代语言特性,并标注修改点与改进收益,帮助开发者提升代码质量和可维护性。

    协同场景

    使用场景描述:

    完整的代码质量提升流程,从代码审查到优化重构,再到测试验证的全链路协作。

    具体协作步骤:
    1. 代码审查与问题识别 + 代码审查与缺陷识别:全面检测代码中的潜在问题和改进点
    2. 性能瓶颈分析 + 性能瓶颈分析:识别代码中的性能问题和优化空间
    3. 安全编码规范检查 + 安全编码规范:确保优化后的代码符合安全编码标准
    4. 单元测试生成 + 单元测试生成:为优化后的代码生成配套测试用例,确保功能正确性
    5. 提交信息规范 + 提交信息规范:生成规范的提交信息,记录优化过程和收益

    适用用户

    软件工程师

    通过提示词快速重构代码,实现规范化并利用最新技术特性,让代码质量和效率显著提升。

    技术团队负责人

    应用提示词优化现有项目代码,减少技术债,推进整个团队技术栈现代化演进。

    自由开发者

    快速提升个人项目的代码质量,无需查阅大量文档即可高效使用现代特性和框架。

    特征总结

    将代码转换为符合特定编程语言习惯,提高代码可读性和规范性。
    支持现代化重构,利用更先进的语言特性,提升代码执行效率与维护性。
    适配主流框架需求,快速完成代码标准迁移,节省研发团队调整时间。
    明确标注代码优化内容,提供清晰的改进提示,帮助开发者理解并掌握优化方法。
    自动解释优化收益,从性能提升到可维护性,全方位展现优化价值。
    灵活应用于多种编程语言与框架,无论是经典语言还是最新技术生态均可支持。
    降低笨重的代码解析和改造工作量,一键生成高质量的代码优化方案。
    助力开发团队快速升级项目技术栈,保持技术的前沿性和竞争力。
    自然融入研发流程,适合代码审查、重构决策或技术债清理的场景。

    如何使用购买的提示词模板

    1. 直接在外部 Chat 应用中使用

    将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。

    2. 发布为 API 接口调用

    把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。

    3. 在 MCP Client 中配置使用

    在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。

    AI 提示词价格
    ¥20.00元
    先用后买,用好了再付款,超安全!

    您购买后可以获得什么

    获得完整提示词模板
    - 共 114 tokens
    - 4 个可调节参数
    { 编程语言 } { 框架名称 } { 现代特性应用 } { 代码片段 }
    获得社区贡献内容的使用权
    - 精选社区优质案例,助您快速上手提示词
    限时免费

    不要错过!

    免费获取高级提示词-优惠即将到期

    17
    :
    23
    小时
    :
    59
    分钟
    :
    59