TAOCARTS 知识

跨境独立站用户行为统计模块全栈开发:多维度用户分层数据可视化落地-CSDN博客

2026-06-26 系统功能介绍

精细化用户运营是跨境独立站、反向海淘平台提升复购率的核心抓手,而用户行为统计看板是运营分层运营的数据底座。我在完善 Taocarts 后台用户概况统计页面时发现,早期版本仅能统计累计用户总数,缺失访客流量、浏览量、新增用户、成交用户、地域分布、性别占比等核心分析维度,运营完全无法区分新老用户消费潜力,无法精准投放优惠券、定向营销活动。结合截图中用户趋势折线图、地域 TOP 表格、性别环形饼图的落地过程,本文完整分享跨境电商平台用户行为统计模块前后端开发流程,包含用户时序埋点聚合、地域数据分组、饼图环形可视化、环比增长率计算逻辑,附带完整可复用业务代码,解决绝大多数代购源码用户统计功能简陋、无分层分析能力的痛点。

先梳理跨境独立站用户统计的专属业务需求,和国内电商系统存在明显区别:

第一,用户地域无法精准识别国内省市,大量海外用户属地标记为 “未知”,统计逻辑需要兼容未知地域分组;

第二,用户访问流量分散全球,访客、浏览量数据需要独立时序存储,不能和订单数据混合统计;

第三,需要区分订单成交用户、运单成交用户两类转化群体,分别统计环比增长;

第四,性别数据存在大量未知字段,饼图渲染时需要做占比加权处理,避免未知用户数据挤占可视化图表;

第五,环比增长率计算需要自动获取上一同期周期数据,减少运营手动切换日期对比的操作成本。

整套模块分为三层实现:前端用户行为埋点上报、后端定时聚合时序用户数据、后台可视化统计看板。前端页面加载、商品点击、下单操作时自动上报埋点数据存入日志表,每日凌晨定时任务汇总当日访客数、浏览量、新增注册用户、成交用户数据,写入用户时序统计表;后台接口根据起止日期读取预聚合数据,自动计算环比增减比例,同时按用户注册属地分组统计 TOP 地域数据,分别返回折线图、表格、饼图所需结构化数据。

后端用户统计环比、地域分组核心代码

// src/modules/statistics/service/user-stat.service.ts

import

{

Injectable

}

from

'@nestjs/common'

;

import

{

InjectRepository

}

from

'@nestjs/typeorm'

;

import

{

Repository

,

Between

}

from

'typeorm'

;

import

{

UserStatDaily

}

from

'src/modules/statistics/entities/user-stat-daily.entity'

;

import

{

User

}

from

'src/modules/user/entities/user.entity'

;

@

Injectable

(

)

export

class

UserStatService

{

constructor

(

@

InjectRepository

(

UserStatDaily

)

private

userStatRepo

:

Repository

<

UserStatDaily

>

,

@

InjectRepository

(

User

)

private

userRepo

:

Repository

<

User

>

)

{

}

// 计算周期用户汇总+环比增长率

async

getUserOverview

(

start

:

Date

,

end

:

Date

)

{

// 当前周期聚合数据

const

currStat

=

await

this

.

userStatRepo

.

createQueryBuilder

(

'stat'

)

.

select

(

'SUM(stat.visitNum)'

,

'totalVisit'

)

.

addSelect

(

'SUM(stat.viewNum)'

,

'totalView'

)

.

addSelect

(

'SUM(stat.newUser)'

,

'totalNewUser'

)

.

addSelect

(

'SUM(stat.orderPayUser)'

,

'orderPayUser'

)

.

addSelect

(

'SUM(stat.transPayUser)'

,

'transPayUser'

)

.

where

(

'stat.statDate BETWEEN :start AND :end'

,

{

start

,

end

}

)

.

getRawOne

(

)

;

// 计算同期上一周期,用于环比计算

const

dayDiff

=

Math

.

ceil

(

(

end

.

getTime

(

)

-

start

.

getTime

(

)

)

/

(

1000

*

3600

*

24

)

)

;

const

lastStart

=

new

Date

(

start

.

getTime

(

)

-

dayDiff

*

24

*

3600

*

1000

)

;

const

lastEnd

=

new

Date

(

end

.

getTime

(

)

-

dayDiff

*

24

*

3600

*

1000

)

;

const

lastStat

=

await

this

.

userStatRepo

.

createQueryBuilder

(

'stat'

)

.

select

(

'SUM(stat.newUser)'

,

'lastNewUser'

)

.

addSelect

(

'SUM(stat.orderPayUser)'

,

'lastOrderUser'

)

.

addSelect

(

'SUM(stat.transPayUser)'

,

'lastTransUser'

)

.

where

(

'stat.statDate BETWEEN :lStart AND :lEnd'

,

{

lStart

:

lastStart

,

lEnd

:

lastEnd

}

)

.

getRawOne

(

)

;

// 环比增长率计算,避免除0报错

const

calcRate

=

(

curr

:

number

,

last

:

number

)

=>

{

if

(

last

===

0

)

return

curr

>

0

?

'-100.00'

:

'0.00'

;

return

(

(

(

curr

-

last

)

/

last

)

*

100

)

.

toFixed

(

2

)

;

}

const

totalUser

=

await

this

.

userRepo

.

count

(

)

;

return

{

totalUser

,

visitNum

:

Number

(

currStat

.

totalVisit

||

0

)

,

viewNum

:

Number

(

currStat

.

totalView

||

0

)

,

newUser

:

Number

(

currStat

.

totalNewUser

||

0

)

,

orderPayUser

:

Number

(

currStat

.

orderPayUser

||

0

)

,

transPayUser

:

Number

(

currStat

.

transPayUser

||

0

)

,

rateNewUser

:

calcRate

(

Number

(

currStat

.

totalNewUser

||

0

)

,

Number

(

lastStat

.

lastNewUser

||

0

)

)

,

rateOrderUser

:

calcRate

(

Number

(

currStat

.

orderPayUser

||

0

)

,

Number

(

lastStat

.

lastOrderUser

||

0

)

)

,

rateTransUser

:

calcRate

(

Number

(

currStat

.

transPayUser

||

0

)

,

Number

(

lastStat

.

lastTransUser

||

0

)

)

}

}

// 用户地域TOP数据统计

async

getUserAreaTop

(

start

:

Date

,

end

:

Date

)

{

return

this

.

userRepo

.

createQueryBuilder

(

'user'

)

.

select

(

'IFNULL(user.province, "未知")'

,

'areaName'

)

.

addSelect

(

'COUNT(user.id)'

,

'totalUser'

)

.

addSelect

(

"SUM(CASE WHEN user.createTime BETWEEN :start AND :end THEN 1 ELSE 0 END)"

,

'newUser'

)

.

groupBy

(

'areaName'

)

.

orderBy

(

'totalUser'

,

'DESC'

)

.

setParameters

(

{

start

,

end

}

)

.

getRawMany

(

)

;

}

}

前端可视化分为三块:顶部指标卡片展示全部汇总数据并标注环比增减;中间多指标折线图展示每日访客、新增用户、成交用户波动;下方左侧地域分布表格、右侧环形饼图展示用户性别占比。饼图自动合并占比过小的类目,优化可视化展示效果,适配海外用户性别数据大量未知的业务场景。

ECharts 环形饼图渲染代码

const

renderGenderPie

=

(

userList

)

=>

{

const

genderMap

=

{

man

:

0

,

woman

:

0

,

unknown

:

0

}

;

userList

.

forEach

(

item

=>

{

if

(

item

.

gender

===

1

)

genderMap

.

man

+=

1

;

else

if

(

item

.

gender

===

2

)

genderMap

.

woman

+=

1

;

else

genderMap

.

unknown

+=

1

;

}

)

pieChart

.

setOption

(

{

tooltip

:

{

trigger

:

'item'

}

,

series

:

[

{

type

:

'pie'

,

radius

:

[

'40%'

,

'70%'

]

,

avoidLabelOverlap

:

false

,

label

:

{

show

:

true

,

position

:

'outside'

}

,

data

:

[

{

name

:

'男'

,

value

:

genderMap

.

man

}

,

{

name

:

'女'

,

value

:

genderMap

.

woman

}

,

{

name

:

'未知'

,

value

:

genderMap

.

unknown

}

]

}

]

}

)

}

这套用户统计模块上线后,运营可以精准定位高转化用户地域、分析新老用户成交占比,针对性开展定向营销活动,大幅提升反向海淘跨境独立站的用户复购。市面上绝大多数代购源码仅提供简单用户列表,缺失完整行为统计与可视化分析能力,这套全栈开发方案可以直接嵌入淘宝 1688 代购系统、跨境转运平台二次开发,完整支撑精细化用户运营的数据需求。