Compare commits

..

2 Commits

Author SHA1 Message Date
xiaoxia 17c2cceaa8 Merge branch 'develop' into refactor/subscription-api
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 8s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m1s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 37s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 55s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 14s
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m36s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 1m4s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m53s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 47s
AI Code Review / AI Code Review (pull_request) Successful in 2m7s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m33s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 15m41s
CI/CD Pipeline / CI Gate (pull_request) 失败: CI/CD Pipeline / Validate - Code Quality (pull_request) [frontend-only]
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 18s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 16s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
2026-07-27 12:34:52 +08:00
xiaoxia 0661b443a1 refactor(api): 拆分 subscription.ts 为目录结构(types/subscription/index)
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 24s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 30s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m12s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m17s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 42s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m18s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 57s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 48s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 31s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m35s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 2m12s
AI Code Review / AI Code Review (pull_request) Successful in 1m38s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 30s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
将 106 行的 subscription.ts 拆分为目录化结构:
- types.ts: 类型定义(Plan/SubscriptionInfo/BillingRecord 等)
- subscription.ts: 全部 5 个 API 函数
- index.ts: 统一入口 re-export,保持 @/api/subscription 路径向后兼容
2026-07-26 17:15:38 +08:00
7 changed files with 137 additions and 139 deletions
+26
View File
@@ -0,0 +1,26 @@
/**
* 订阅 API — 目录化入口
* 保持与原 subscription.ts 相同导出,向后兼容
*/
// 类型
export type {
PlanType,
SubscriptionStatus,
BillingStatus,
BillingCycle,
Plan,
SubscriptionInfo,
BillingRecord,
ChangePlanRequest,
ChangePlanResponse,
} from "./types"
// API 函数
export {
getCurrentSubscription,
getBillingRecords,
changePlan,
cancelSubscription,
toggleAutoRenew,
} from "./subscription"
@@ -0,0 +1,47 @@
/**
* 订阅相关 API 函数
*/
import apiClient from "../client"
import type {
BillingRecord,
ChangePlanRequest,
ChangePlanResponse,
SubscriptionInfo,
} from "./types"
/** 获取当前订阅信息 */
export const getCurrentSubscription = async (): Promise<SubscriptionInfo> => {
const response = await apiClient.get("/subscription/current")
return response.data
}
/** 获取账单记录列表 */
export const getBillingRecords = async (): Promise<BillingRecord[]> => {
const response = await apiClient.get("/subscription/billing-records")
return response.data
}
/** 升级/降级套餐 */
export const changePlan = async (request: ChangePlanRequest): Promise<ChangePlanResponse> => {
const response = await apiClient.post("/subscription/change-plan", request)
return response.data
}
/** 取消订阅 */
export const cancelSubscription = async (): Promise<{
success: boolean
message: string
}> => {
const response = await apiClient.post("/subscription/cancel")
return response.data
}
/** 切换自动续费 */
export const toggleAutoRenew = async (
enabled: boolean,
): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.post("/subscription/toggle-auto-renew", {
enabled,
})
return response.data
}
@@ -1,8 +1,6 @@
/**
* API
*
*
*/
import apiClient from "./client"
/** 套餐类型 */
export type PlanType = "free" | "standard" | "pro" | "enterprise"
@@ -65,42 +63,3 @@ export interface ChangePlanResponse {
message: string
new_subscription?: SubscriptionInfo
}
// ============ API 函数 ============
/** 获取当前订阅信息 */
export const getCurrentSubscription = async (): Promise<SubscriptionInfo> => {
const response = await apiClient.get("/subscription/current")
return response.data
}
/** 获取账单记录列表 */
export const getBillingRecords = async (): Promise<BillingRecord[]> => {
const response = await apiClient.get("/subscription/billing-records")
return response.data
}
/** 升级/降级套餐 */
export const changePlan = async (request: ChangePlanRequest): Promise<ChangePlanResponse> => {
const response = await apiClient.post("/subscription/change-plan", request)
return response.data
}
/** 取消订阅 */
export const cancelSubscription = async (): Promise<{
success: boolean
message: string
}> => {
const response = await apiClient.post("/subscription/cancel")
return response.data
}
/** 切换自动续费 */
export const toggleAutoRenew = async (
enabled: boolean,
): Promise<{ success: boolean; message: string }> => {
const response = await apiClient.post("/subscription/toggle-auto-renew", {
enabled,
})
return response.data
}
@@ -1,17 +1,70 @@
/**
* API
* API
* Phase 1
* schema 使 name + text UI content
*/
import apiClient from "../client"
import type {
BackendCreateTitleRequest,
BackendTitleResponse,
BackendUpdateTitleRequest,
CreateTitleRequest,
TitleItem,
} from "./types"
import { toTitleItem } from "./utils"
import apiClient from "./client"
/** 标题条目(前端展示用) */
export interface TitleItem {
id: string
content: string
category?: string
source?: string
word_count?: number
is_favorite?: boolean
created_at?: string
updated_at?: string
}
/** 后端标题响应格式 */
interface BackendTitleResponse {
id: string
user_id: string
name: string
text: string
category: string
description: string
tags: string[]
usage_count: number
is_active: boolean
created_at: string
updated_at: string
}
/** 后端创建标题请求格式 */
interface BackendCreateTitleRequest {
name: string
text: string
category: string
description?: string
tags?: string[]
}
/** 后端更新标题请求格式 */
interface BackendUpdateTitleRequest {
name?: string
text?: string
category?: string
description?: string
tags?: string[]
}
/** 将后端响应映射为前端 TitleItem */
const toTitleItem = (item: BackendTitleResponse): TitleItem => ({
id: item.id,
content: item.text,
category: item.category,
word_count: item.text?.length || 0,
created_at: item.created_at,
updated_at: item.updated_at,
})
/** 创建标题请求(前端接口,保持向后兼容) */
export interface CreateTitleRequest {
content: string
category?: string
}
/** 获取当前用户的所有标题 */
export const getTitles = async (): Promise<TitleItem[]> => {
-19
View File
@@ -1,19 +0,0 @@
/**
* 标题相关 API — 目录化入口
* 保持与原 titles.ts 相同导出,向后兼容
*/
// 类型
export type {
TitleItem,
BackendTitleResponse,
BackendCreateTitleRequest,
BackendUpdateTitleRequest,
CreateTitleRequest,
} from "./types"
// 工具函数
export { toTitleItem } from "./utils"
// API 函数
export { getTitles, createTitle, updateTitle, deleteTitle, batchImportTitles } from "./titles"
-54
View File
@@ -1,54 +0,0 @@
/**
* 标题相关类型定义
*/
/** 标题条目(前端展示用) */
export interface TitleItem {
id: string
content: string
category?: string
source?: string
word_count?: number
is_favorite?: boolean
created_at?: string
updated_at?: string
}
/** 后端标题响应格式 */
export interface BackendTitleResponse {
id: string
user_id: string
name: string
text: string
category: string
description: string
tags: string[]
usage_count: number
is_active: boolean
created_at: string
updated_at: string
}
/** 后端创建标题请求格式 */
export interface BackendCreateTitleRequest {
name: string
text: string
category: string
description?: string
tags?: string[]
}
/** 后端更新标题请求格式 */
export interface BackendUpdateTitleRequest {
name?: string
text?: string
category?: string
description?: string
tags?: string[]
}
/** 创建标题请求(前端接口,保持向后兼容) */
export interface CreateTitleRequest {
content: string
category?: string
}
-14
View File
@@ -1,14 +0,0 @@
/**
* 标题数据转换工具函数
*/
import type { BackendTitleResponse, TitleItem } from "./types"
/** 将后端响应映射为前端 TitleItem */
export const toTitleItem = (item: BackendTitleResponse): TitleItem => ({
id: item.id,
content: item.text,
category: item.category,
word_count: item.text?.length || 0,
created_at: item.created_at,
updated_at: item.updated_at,
})