Merge branch 'main' into feature/distribution-system

合入 main 的推广追踪(adtracking)模块,并解决与分销业务的 8 处冲突。

冲突解决原则:两边的字段、菜单与路由全部保留,不删任何一方。

后端:
- model/order.go:保留分销字段注释块,追加 SourceTrackCode
- model/user.go:追加 RegisterTrackCode;TokenVersion 默认值保持 1
  (与本库 users.token_version 列默认值一致)
- auth/repository.go:两处建号结构体同时写入 RegisterTrackCode 与 TokenVersion
- order/dto.go:OrderDTO 同时暴露 distribution_site_id 与 source_track_code;
  CreateRequest 同时接受 distribution_site_code 与 track_code
- order/presenter.go:同时映射 DistributionSiteID 与 SourceTrackCode

前端:
- orders/api/orders.ts:createOrder 同时携带 distribution_site_code 与 track_code
- layouts/AdminLayout.vue:分销管理菜单组与推广追踪菜单组并列保留
- router/adminRoutes.ts:分销 4 条路由与 tracking-links 路由并列保留

迁移:feature 侧 000064-000067 已在前一提交顺延为 000065-000068,
为 main 的 000064_ad_tracking 让号,合并后编号 000063→000068 连续无重复。
This commit is contained in:
yml2213
2026-09-10 13:06:18 +08:00
28 changed files with 2461 additions and 55 deletions
@@ -0,0 +1,110 @@
import { apiClient } from '@/shared/api/client'
import type { ApiResponse } from '@/shared/types/types'
export interface TrackingLinkItem {
id: number
name: string
code: string
channel_type: string
target_url: string
short_url: string
status: 'active' | 'disabled'
cost_cent: number
notes: string
created_by: number
created_at: string
updated_at: string
click_pv: number
click_uv: number
click_ip: number
register_count: number
order_count: number
paid_order_count: number
paid_gmv_cent: number
conversion_rate: number
}
export interface TrackingOverviewStats {
total_links: number
active_links: number
total_pv: number
total_uv: number
total_ip: number
total_registers: number
total_orders: number
total_paid_orders: number
total_paid_gmv_cent: number
today_pv: number
today_uv: number
today_registers: number
today_orders: number
today_paid_gmv_cent: number
}
export interface ListTrackingLinksParams {
keyword?: string
channel_type?: string
status?: string
page?: number
page_size?: number
}
export interface CreateTrackingLinkPayload {
name: string
code: string
channel_type?: string
target_url?: string
cost_cent?: number
notes?: string
}
export interface UpdateTrackingLinkPayload {
name: string
channel_type?: string
target_url?: string
cost_cent?: number
notes?: string
}
export async function fetchTrackingOverview(): Promise<TrackingOverviewStats> {
const { data } = await apiClient.get<ApiResponse<TrackingOverviewStats>>(
'/admin/tracking-links/overview'
)
return data.data
}
export async function fetchTrackingLinks(
params: ListTrackingLinksParams
): Promise<{ items: TrackingLinkItem[]; total: number }> {
const { data } = await apiClient.get<ApiResponse<{ items: TrackingLinkItem[]; total: number }>>(
'/admin/tracking-links',
{ params }
)
return data.data
}
export async function createTrackingLink(
payload: CreateTrackingLinkPayload
): Promise<TrackingLinkItem> {
const { data } = await apiClient.post<ApiResponse<TrackingLinkItem>>(
'/admin/tracking-links',
payload
)
return data.data
}
export async function updateTrackingLink(
id: number,
payload: UpdateTrackingLinkPayload
): Promise<void> {
await apiClient.put(`/admin/tracking-links/${id}`, payload)
}
export async function updateTrackingLinkStatus(
id: number,
status: 'active' | 'disabled'
): Promise<void> {
await apiClient.put(`/admin/tracking-links/${id}/status`, { status })
}
@@ -112,6 +112,7 @@ const resourceLabels: Record<string, string> = {
role: '角色管理',
system_config: '系统配置',
audit_log: '审计日志',
ad_tracking: '推广追踪',
}
</script>
File diff suppressed because it is too large Load Diff