修改登录获取信息脚本
This commit is contained in:
@@ -102,3 +102,13 @@ func (*Twitter) Test(ctx *gin.Context) {
|
|||||||
"data": "",
|
"data": "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Twitter) Export(ctx *gin.Context) {
|
||||||
|
var TwitterService services.TwitterService
|
||||||
|
code, msg, files := TwitterService.ExportAccounts()
|
||||||
|
ctx.JSON(http.StatusOK, gin.H{
|
||||||
|
"code": code,
|
||||||
|
"msg": msg,
|
||||||
|
"files": files,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
14
go.mod
14
go.mod
@@ -49,17 +49,23 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||||
|
github.com/richardlehane/msoleps v1.0.4 // indirect
|
||||||
|
github.com/tiendc/go-deepcopy v1.7.1 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
|
github.com/xuri/efp v0.0.1 // indirect
|
||||||
|
github.com/xuri/excelize/v2 v2.10.0 // indirect
|
||||||
|
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect
|
||||||
github.com/ysmood/fetchup v0.2.3 // indirect
|
github.com/ysmood/fetchup v0.2.3 // indirect
|
||||||
github.com/ysmood/goob v0.4.0 // indirect
|
github.com/ysmood/goob v0.4.0 // indirect
|
||||||
github.com/ysmood/got v0.40.0 // indirect
|
github.com/ysmood/got v0.40.0 // indirect
|
||||||
github.com/ysmood/gson v0.7.3 // indirect
|
github.com/ysmood/gson v0.7.3 // indirect
|
||||||
github.com/ysmood/leakless v0.9.0 // indirect
|
github.com/ysmood/leakless v0.9.0 // indirect
|
||||||
golang.org/x/arch v0.8.0 // indirect
|
golang.org/x/arch v0.8.0 // indirect
|
||||||
golang.org/x/crypto v0.37.0 // indirect
|
golang.org/x/crypto v0.43.0 // indirect
|
||||||
golang.org/x/net v0.39.0 // indirect
|
golang.org/x/net v0.46.0 // indirect
|
||||||
golang.org/x/sys v0.32.0 // indirect
|
golang.org/x/sys v0.37.0 // indirect
|
||||||
golang.org/x/text v0.29.0 // indirect
|
golang.org/x/text v0.30.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.1 // indirect
|
google.golang.org/protobuf v1.34.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
21
go.sum
21
go.sum
@@ -96,6 +96,11 @@ github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs=
|
|||||||
github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||||
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
|
github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE=
|
||||||
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||||
|
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
||||||
|
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||||
|
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||||
|
github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
|
||||||
|
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
@@ -108,10 +113,18 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
|
|||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/tiendc/go-deepcopy v1.7.1 h1:LnubftI6nYaaMOcaz0LphzwraqN8jiWTwm416sitff4=
|
||||||
|
github.com/tiendc/go-deepcopy v1.7.1/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
github.com/xuri/efp v0.0.1 h1:fws5Rv3myXyYni8uwj2qKjVaRP30PdjeYe2Y6FDsCL8=
|
||||||
|
github.com/xuri/efp v0.0.1/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||||
|
github.com/xuri/excelize/v2 v2.10.0 h1:8aKsP7JD39iKLc6dH5Tw3dgV3sPRh8uRVXu/fMstfW4=
|
||||||
|
github.com/xuri/excelize/v2 v2.10.0/go.mod h1:SC5TzhQkaOsTWpANfm+7bJCldzcnU/jrhqkTi/iBHBU=
|
||||||
|
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBLbf3WdLgC29pgyhTjAT/0nuE=
|
||||||
|
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||||
github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
|
github.com/ysmood/fetchup v0.2.3 h1:ulX+SonA0Vma5zUFXtv52Kzip/xe7aj4vqT5AJwQ+ZQ=
|
||||||
github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
|
github.com/ysmood/fetchup v0.2.3/go.mod h1:xhibcRKziSvol0H1/pj33dnKrYyI2ebIvz5cOOkYGns=
|
||||||
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
||||||
@@ -141,6 +154,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v
|
|||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||||
|
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||||
|
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||||
golang.org/x/image v0.31.0 h1:mLChjE2MV6g1S7oqbXC0/UcKijjm5fnJLUYKIYrLESA=
|
golang.org/x/image v0.31.0 h1:mLChjE2MV6g1S7oqbXC0/UcKijjm5fnJLUYKIYrLESA=
|
||||||
golang.org/x/image v0.31.0/go.mod h1:R9ec5Lcp96v9FTF+ajwaH3uGxPH4fKfHHAVbUILxghA=
|
golang.org/x/image v0.31.0/go.mod h1:R9ec5Lcp96v9FTF+ajwaH3uGxPH4fKfHHAVbUILxghA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
@@ -159,6 +174,8 @@ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
|||||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||||
|
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||||
|
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -180,6 +197,8 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||||
|
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -201,6 +220,8 @@ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
|||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||||
|
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||||
|
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ type TwitterAccount struct {
|
|||||||
Proxy string `gorm:"proxy"`
|
Proxy string `gorm:"proxy"`
|
||||||
BrowserId string `gorm:"browser_id"`
|
BrowserId string `gorm:"browser_id"`
|
||||||
BrowserUrl string `gorm:"browser_url"`
|
BrowserUrl string `gorm:"browser_url"`
|
||||||
|
RegisterDate string `gorm:"register_date"`
|
||||||
|
RegisterAddress string `gorm:"register_address"`
|
||||||
|
RegisterIp string `gorm:"register_ip"`
|
||||||
UpdateTime int64 `gorm:"update_time"`
|
UpdateTime int64 `gorm:"update_time"`
|
||||||
CreateTime int64 `gorm:"create_time"`
|
CreateTime int64 `gorm:"create_time"`
|
||||||
}
|
}
|
||||||
|
|||||||
101
plugin/task-get-plugin.go
Normal file
101
plugin/task-get-plugin.go
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go-account-register/config"
|
||||||
|
"go-account-register/models"
|
||||||
|
"go-account-register/services"
|
||||||
|
paramsTypes "go-account-register/types"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
"runtime/debug"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TaskGetPlugin struct{}
|
||||||
|
|
||||||
|
func (*TaskGetPlugin) Run(task *paramsTypes.Task) {
|
||||||
|
|
||||||
|
// 查询当前所有账号
|
||||||
|
userService := services.InitTwitterAccountService()
|
||||||
|
// 判断是否是补偿任务
|
||||||
|
var userList []models.TwitterAccount
|
||||||
|
userList = userService.GetAvailableAccount(&models.TwitterAccount{
|
||||||
|
Type: "get",
|
||||||
|
})
|
||||||
|
|
||||||
|
if task.Data.Compensate == 1 {
|
||||||
|
// 补偿任务
|
||||||
|
userList = userService.GetAccountListByStatus(&models.TwitterAccount{
|
||||||
|
Status: "成功",
|
||||||
|
Type: "get",
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 清空当前运行的账号状态
|
||||||
|
userService.ClearAccountStatus(&models.TwitterAccount{
|
||||||
|
Type: "get",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
log.Println("可用账号数量:", len(userList))
|
||||||
|
// 获取并发数
|
||||||
|
appConfig, _ := config.LoadConfig()
|
||||||
|
num := math.Ceil(float64(len(userList)) / float64(appConfig.Limit.BrowserRunMax))
|
||||||
|
sem := make(chan struct{}, appConfig.Limit.BrowserRunMax) // 全局并发上限
|
||||||
|
var globalWait sync.WaitGroup
|
||||||
|
for i := 0; i < int(num); i++ {
|
||||||
|
select {
|
||||||
|
case <-task.Ctx.Done():
|
||||||
|
log.Println("中断任务")
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
log.Println("批次:", i+1)
|
||||||
|
for j := 0; j < appConfig.Limit.BrowserRunMax; j++ {
|
||||||
|
log.Println(i*appConfig.Limit.BrowserRunMax + j)
|
||||||
|
taskIndex := i*appConfig.Limit.BrowserRunMax + j
|
||||||
|
if taskIndex >= len(userList) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
globalWait.Add(1)
|
||||||
|
sem <- struct{}{} // 阻塞直到有空位
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
<-sem // 释放信号量
|
||||||
|
globalWait.Done()
|
||||||
|
}()
|
||||||
|
getAccountWork(task, userList[taskIndex].ID)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalWait.Wait()
|
||||||
|
|
||||||
|
task.Message <- "Success"
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAccountWork(task *paramsTypes.Task, id int64) {
|
||||||
|
UserService := services.InitTwitterAccountService()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Printf("Goroutine panic: %v\nStack: %s", r, debug.Stack())
|
||||||
|
UserService.ChangeAccountLoginStatus(int(id), "账号下线")
|
||||||
|
TwitterService.Logout(int(id))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 开始登录
|
||||||
|
|
||||||
|
res := TwitterService.Login(int(id))
|
||||||
|
UserService.ChangeAccountLoginStatus(int(id), res.Msg)
|
||||||
|
if res.Code == 200 {
|
||||||
|
// 开始拟人
|
||||||
|
// res = TwitterService.LoopViewPost(int(id))
|
||||||
|
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
UserService.ChangeAccountStatus(int(id), "成功")
|
||||||
|
TwitterService.Logout(int(id))
|
||||||
|
UserService.ChangeAccountLoginStatus(int(id), "账号下线")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println(task.ID)
|
||||||
|
}
|
||||||
@@ -17,4 +17,5 @@ func (*Twitter) TwitterRouterInit(app *gin.Engine) {
|
|||||||
twitter.GET("/logout", twitterApi.Logout) // 退出登录
|
twitter.GET("/logout", twitterApi.Logout) // 退出登录
|
||||||
twitter.POST("/register1", twitterApi.Register1)
|
twitter.POST("/register1", twitterApi.Register1)
|
||||||
twitter.GET("/test", twitterApi.Test)
|
twitter.GET("/test", twitterApi.Test)
|
||||||
|
twitter.GET("/export", twitterApi.Export) // 导出接口
|
||||||
}
|
}
|
||||||
|
|||||||
83
services/twitter_account_export_service.go
Normal file
83
services/twitter_account_export_service.go
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go-account-register/models"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/xuri/excelize/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 导出 Twitter 账号数据到 Excel
|
||||||
|
func ExportTwitterAccounts() ([]string, error) {
|
||||||
|
accountService := InitTwitterAccountService()
|
||||||
|
accounts := accountService.GetAll(&models.TwitterAccount{
|
||||||
|
Type: "get",
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分类
|
||||||
|
countryMap := map[string][]models.TwitterAccount{
|
||||||
|
"United States": {},
|
||||||
|
"Singapore": {},
|
||||||
|
"Japan": {},
|
||||||
|
"Taiwan": {},
|
||||||
|
"Other": {},
|
||||||
|
}
|
||||||
|
for _, acc := range accounts {
|
||||||
|
addr := acc.RegisterAddress
|
||||||
|
if addr == "United States" || addr == "Singapore" || addr == "Japan" || addr == "Taiwan" {
|
||||||
|
countryMap[addr] = append(countryMap[addr], acc)
|
||||||
|
} else {
|
||||||
|
countryMap["Other"] = append(countryMap["Other"], acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var files []string
|
||||||
|
for k, v := range countryMap {
|
||||||
|
if len(v) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
file := excelize.NewFile()
|
||||||
|
titles := []string{"编号", "用户id", "用户名", "邮箱", "密码", "邮箱密码", "生日", "Token", "二步验证码", "Cookies", "类型", "状态", "登录状态", "代理", "浏览器ID", "浏览器地址", "注册时间", "注册地区", "注册IP", "更新时间", "创建时间"}
|
||||||
|
for i, t := range titles {
|
||||||
|
cell, _ := excelize.CoordinatesToCellName(i+1, 1)
|
||||||
|
file.SetCellValue("Sheet1", cell, t)
|
||||||
|
}
|
||||||
|
for row, acc := range v {
|
||||||
|
vals := []interface{}{
|
||||||
|
acc.ID,
|
||||||
|
acc.Uid,
|
||||||
|
acc.Name,
|
||||||
|
acc.Email,
|
||||||
|
acc.Password,
|
||||||
|
acc.EmailPassword,
|
||||||
|
acc.Birthday,
|
||||||
|
acc.Token,
|
||||||
|
acc.Fa2,
|
||||||
|
acc.Cookies,
|
||||||
|
acc.Type,
|
||||||
|
acc.Status,
|
||||||
|
acc.LoginStatus,
|
||||||
|
acc.Proxy,
|
||||||
|
acc.BrowserId,
|
||||||
|
acc.BrowserUrl,
|
||||||
|
acc.RegisterDate,
|
||||||
|
acc.RegisterAddress,
|
||||||
|
acc.RegisterIp,
|
||||||
|
acc.UpdateTime,
|
||||||
|
acc.CreateTime,
|
||||||
|
}
|
||||||
|
for col, val := range vals {
|
||||||
|
cell, _ := excelize.CoordinatesToCellName(col+1, row+2)
|
||||||
|
file.SetCellValue("Sheet1", cell, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filename := "twitter_accounts_" + k + ".xlsx"
|
||||||
|
if err := file.SaveAs(filename); err != nil {
|
||||||
|
log.Println("保存文件失败:", filename, err)
|
||||||
|
} else {
|
||||||
|
files = append(files, filename)
|
||||||
|
log.Println("已导出:", filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files, nil
|
||||||
|
}
|
||||||
@@ -17,6 +17,12 @@ func InitTwitterAccountService() *TwitterAccountService {
|
|||||||
return &TwitterAccountService{db: db}
|
return &TwitterAccountService{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TwitterAccountService) GetAll(params *models.TwitterAccount) []models.TwitterAccount {
|
||||||
|
var accounts []models.TwitterAccount
|
||||||
|
t.db.Model(&models.TwitterAccount{}).Where(params).Find(&accounts)
|
||||||
|
return accounts
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TwitterAccountService) Create(params *models.TwitterAccount) int64 {
|
func (t *TwitterAccountService) Create(params *models.TwitterAccount) int64 {
|
||||||
params.CreateTime = time.Now().Unix()
|
params.CreateTime = time.Now().Unix()
|
||||||
params.UpdateTime = time.Now().Unix()
|
params.UpdateTime = time.Now().Unix()
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ func (*TwitterService) Login(id int) *libs.ErrorInfo {
|
|||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
getAccountInfo(page, int64(id))
|
getAccountInfo(page, int64(id))
|
||||||
|
getRegisterInfo(page, int64(id), user.Password)
|
||||||
return libs.ErrorCode["LoginSuccessful"]
|
return libs.ErrorCode["LoginSuccessful"]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +171,53 @@ func getAccountInfo(page *rod.Page, id int64) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRegisterInfo(page *rod.Page, id int64, password string) {
|
||||||
|
// 进入账号信息页面
|
||||||
|
page.MustNavigate("https://x.com/settings/your_twitter_data/account").MustWaitLoad()
|
||||||
|
page.MustWaitNavigation()
|
||||||
|
page.MustWaitLoad() // DOM 加载完成
|
||||||
|
page.MustWaitIdle() // 基本静止(减少早期误判)
|
||||||
|
page.MustActivate() // 前置
|
||||||
|
// 判断当前是否需要输入密码
|
||||||
|
inpurPassword, err := page.Timeout(5 * time.Second).Element(`input[name="current_password"]`)
|
||||||
|
if err == nil {
|
||||||
|
if is, err1 := inpurPassword.Visible(); err1 == nil && is {
|
||||||
|
inpurPassword.MustInput(password)
|
||||||
|
}
|
||||||
|
ConfirmButton := page.Timeout(5 * time.Second).MustElement(`button.css-175oi2r.r-sdzlij.r-1phboty.r-rs99b7.r-lrvibr.r-ddtstp.r-1xpp3t0.r-2yi16.r-1qi8awa.r-3pj75a.r-1loqt21.r-o7ynqc.r-6416eg.r-1ny4l3l`)
|
||||||
|
ConfirmButton.MustClick()
|
||||||
|
}
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
// 获取创建时间
|
||||||
|
dateElement := page.Timeout(10 * time.Second).MustElement(`#react-root > div > div > div.css-175oi2r.r-1f2l425.r-13qz1uu.r-417010.r-18u37iz > main > div > div > div > section:nth-child(2) > div.css-175oi2r.r-qocrb3.r-14lw9ot.r-1h0z5md.r-1jx8gzb.r-f8sm7e.r-13qz1uu.r-1ye8kvj > div > div:nth-child(6) > div:nth-child(2)`)
|
||||||
|
createdAt, _ := dateElement.Text()
|
||||||
|
// 获取注册IP
|
||||||
|
ipElement := page.Timeout(10 * time.Second).MustElement(`#react-root > div > div > div.css-175oi2r.r-1f2l425.r-13qz1uu.r-417010.r-18u37iz > main > div > div > div > section:nth-child(2) > div.css-175oi2r.r-qocrb3.r-14lw9ot.r-1h0z5md.r-1jx8gzb.r-f8sm7e.r-13qz1uu.r-1ye8kvj > div > div:nth-child(6) > div:nth-child(3)`)
|
||||||
|
ipAddr, _ := ipElement.Text()
|
||||||
|
|
||||||
|
// 分离IP地址和地区
|
||||||
|
var ip, region string
|
||||||
|
// ipAddr 格式: "68.132.165.85 (United States)"
|
||||||
|
if strings.Contains(ipAddr, "(") {
|
||||||
|
parts := strings.Split(ipAddr, " (")
|
||||||
|
ip = strings.TrimSpace(parts[0])
|
||||||
|
if len(parts) > 1 {
|
||||||
|
region = strings.TrimRight(parts[1], ")")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ip = ipAddr
|
||||||
|
}
|
||||||
|
log.Println("注册IP:", ip)
|
||||||
|
log.Println("注册地区:", region)
|
||||||
|
log.Println("创建时间:", createdAt)
|
||||||
|
userService := InitTwitterAccountService()
|
||||||
|
userService.Update(id, &models.TwitterAccount{
|
||||||
|
RegisterIp: ip,
|
||||||
|
RegisterDate: createdAt,
|
||||||
|
RegisterAddress: region,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 退出登录
|
// 退出登录
|
||||||
func (*TwitterService) Logout(id int) {
|
func (*TwitterService) Logout(id int) {
|
||||||
Browser.CancelBrowser(id)
|
Browser.CancelBrowser(id)
|
||||||
@@ -709,3 +757,12 @@ func (*TwitterService) LoopViewPost(id int) *libs.ErrorInfo {
|
|||||||
}
|
}
|
||||||
return libs.ErrorCode["ViewSuccessful"]
|
return libs.ErrorCode["ViewSuccessful"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出 Twitter 账号数据到 Excel
|
||||||
|
func (s *TwitterService) ExportAccounts() (code int, msg string, files []string) {
|
||||||
|
result, err := ExportTwitterAccounts()
|
||||||
|
if err != nil {
|
||||||
|
return 500, "导出失败", nil
|
||||||
|
}
|
||||||
|
return 200, "导出成功", result
|
||||||
|
}
|
||||||
|
|||||||
@@ -170,9 +170,9 @@ func (s *Scheduler) processQueue() {
|
|||||||
func (s *Scheduler) executeTask(task *paramsTypes.Task) {
|
func (s *Scheduler) executeTask(task *paramsTypes.Task) {
|
||||||
// 根据类型判断任务
|
// 根据类型判断任务
|
||||||
switch task.Type {
|
switch task.Type {
|
||||||
// case 6:
|
case 2:
|
||||||
// var taskNurturingClashPlugin plugin.TaskNurturingClashPlugin
|
var taskGetPlugin plugin.TaskGetPlugin
|
||||||
// go taskNurturingClashPlugin.Run(task)
|
go taskGetPlugin.Run(task)
|
||||||
case 1:
|
case 1:
|
||||||
var taskViewPostPlugin plugin.TaskViewPostPlugin
|
var taskViewPostPlugin plugin.TaskViewPostPlugin
|
||||||
go taskViewPostPlugin.Run(task)
|
go taskViewPostPlugin.Run(task)
|
||||||
|
|||||||
Reference in New Issue
Block a user