This commit is contained in:
GYJ 2025-03-18 14:34:50 +08:00
commit f85fff80be
17 changed files with 544 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,21 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AliAccessStaticViaInstance" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAbstractClassShouldStartWithAbstractNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidApacheBeanUtilsCopy" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidCallStaticSimpleDateFormat" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidComplexCondition" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidNewDateGetTime" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidPatternCompileInMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaAvoidUseTimer" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaClassMustHaveAuthor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaLockShouldWithTryFinally" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaMethodTooLong" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaPackageNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaSneakyThrowsWithoutExceptionType" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaTestClassShouldEndWithTestNaming" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaTransactionMustHaveRollback" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlibabaUseRightCaseForDateFormat" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/video_data_copy.iml" filepath="$PROJECT_DIR$/video_data_copy.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

63
data/orders.go Normal file
View File

@ -0,0 +1,63 @@
package data
type (
Orders struct {
OrdersId int64 `json:"orders_id" gorm:"primary_key;column:orders_id"`
OrdersNo string `json:"orders_no" gorm:"column:orders_no"`
TradeNo string `json:"trade_no" gorm:"column:trade_no"`
UserId int64 `json:"user_id" gorm:"column:user_id"`
CourseId int64 `json:"course_id" gorm:"column:course_id"`
PayMoney float64 `json:"pay_money" gorm:"column:pay_money"`
PayWay int `json:"pay_way" gorm:"column:pay_way"`
Status int `json:"status" gorm:"column:status"`
CreateTime string `json:"create_time" gorm:"column:create_time"`
RefundContent string `json:"refund_content" gorm:"column:refund_content"`
OrdersType int `json:"orders_type" gorm:"column:orders_type"`
VipNameType int `json:"vip_name_type" gorm:"column:vip_name_type"`
CourseDetailsId int64 `json:"course_details_id" gorm:"column:course_details_id"`
CourseDetailsIds string `json:"course_details_ids" gorm:"column:course_details_ids"`
QdMoney float64 `json:"qd_money" gorm:"column:qd_money"`
SysUserId int64 `json:"sys_user_id" gorm:"column:sys_user_id"`
OneMoney float64 `json:"one_money" gorm:"column:one_money"`
OneUserId int64 `json:"one_user_id" gorm:"column:one_user_id"`
TwoMoney float64 `json:"two_money" gorm:"column:two_money"`
TwoUserId int64 `json:"two_user_id" gorm:"column:two_user_id"`
PayTime string `json:"pay_time" gorm:"column:pay_time"`
PayDiamond float64 `json:"pay_diamond" gorm:"column:pay_diamond"`
Diamond int32 `json:"diamond" gorm:"column:diamond"`
}
OrdersCopy1 struct {
OrdersId int64 `json:"orders_id" gorm:"primary_key;column:orders_id"`
OrdersNo string `json:"orders_no" gorm:"column:orders_no"`
TradeNo string `json:"trade_no" gorm:"column:trade_no"`
UserId int64 `json:"user_id" gorm:"column:user_id"`
CourseId int64 `json:"course_id" gorm:"column:course_id"`
PayMoney float64 `json:"pay_money" gorm:"column:pay_money"`
PayWay int `json:"pay_way" gorm:"column:pay_way"`
Status int `json:"status" gorm:"column:status"`
CreateTime string `json:"create_time" gorm:"column:create_time"`
RefundContent string `json:"refund_content" gorm:"column:refund_content"`
OrdersType int `json:"orders_type" gorm:"column:orders_type"`
VipNameType int `json:"vip_name_type" gorm:"column:vip_name_type"`
CourseDetailsId int64 `json:"course_details_id" gorm:"column:course_details_id"`
CourseDetailsIds string `json:"course_details_ids" gorm:"column:course_details_ids"`
QdMoney float64 `json:"qd_money" gorm:"column:qd_money"`
SysUserId int64 `json:"sys_user_id" gorm:"column:sys_user_id"`
OneMoney float64 `json:"one_money" gorm:"column:one_money"`
OneUserId int64 `json:"one_user_id" gorm:"column:one_user_id"`
TwoMoney float64 `json:"two_money" gorm:"column:two_money"`
TwoUserId int64 `json:"two_user_id" gorm:"column:two_user_id"`
PayTime string `json:"pay_time" gorm:"column:pay_time"`
PayDiamond float64 `json:"pay_diamond" gorm:"column:pay_diamond"`
Diamond int32 `json:"diamond" gorm:"column:diamond"`
}
)
func (o *Orders) TableName() string {
return "orders"
}
func (o *OrdersCopy1) TableName() string {
return "orders_copy1"
}

45
data/pau_details.go Normal file
View File

@ -0,0 +1,45 @@
package data
type (
PayDetails struct {
Id int64 `json:"id" gorm:"primary_key;column:id"`
Classify int `json:"classify" gorm:"column:classify"`
TradeNo string `json:"trade_no" gorm:"column:trade_no"`
Money float64 `json:"money" gorm:"column:money"`
UserId int64 `json:"user_id" gorm:"column:user_id"`
CreateTime string `json:"create_time" gorm:"column:create_time"`
PayTime string `json:"pay_time" gorm:"column:pay_time"`
Type int `json:"type" gorm:"column:type"`
Remark string `json:"remark" gorm:"column:remark"`
OrderId string `json:"order_id" gorm:"column:order_id"`
ProductId string `json:"product_id" gorm:"column:product_id"`
PayDiamond float64 `json:"pay_diamond" gorm:"column:pay_diamond"`
Diamond int `json:"diamond" gorm:"column:diamond"`
ThirdOrderNo string `json:"third_order_no" gorm:"column:third_order_no"`
}
PayDetailsCopy1 struct {
Id int64 `json:"id" gorm:"primary_key;column:id"`
Classify int `json:"classify" gorm:"column:classify"`
TradeNo string `json:"trade_no" gorm:"column:trade_no"`
Money float64 `json:"money" gorm:"column:money"`
UserId int64 `json:"user_id" gorm:"column:user_id"`
CreateTime string `json:"create_time" gorm:"column:create_time"`
PayTime string `json:"pay_time" gorm:"column:pay_time"`
Type int `json:"type" gorm:"column:type"`
Remark string `json:"remark" gorm:"column:remark"`
OrderId string `json:"order_id" gorm:"column:order_id"`
ProductId string `json:"product_id" gorm:"column:product_id"`
PayDiamond float64 `json:"pay_diamond" gorm:"column:pay_diamond"`
Diamond int `json:"diamond" gorm:"column:diamond"`
ThirdOrderNo string `json:"third_order_no" gorm:"column:third_order_no"`
}
)
func (PayDetails) TableName() string {
return "pay_details"
}
func (PayDetailsCopy1) TableName() string {
return "pay_details_copy1"
}

View File

@ -0,0 +1,45 @@
package data
type (
UserMoneyDetails struct {
Id int64 `json:"id" gorm:"column:id;primary_key"`
UserId int64 `json:"user_id" gorm:"column:user_id"`
SysUserId int64 `json:"sys_user_id" gorm:"column:sys_user_id"`
ByUserId int64 `json:"by_user_id" gorm:"column:by_user_id"`
Title string `json:"title" gorm:"column:title"`
Classify int `json:"classify" gorm:"column:classify"`
Type int `json:"type" gorm:"column:type"`
State int `json:"state" gorm:"column:state"`
Money float64 `json:"money" gorm:"column:money"`
Content string `json:"content" gorm:"column:content"`
MoneyType int `json:"money_type" gorm:"column:money_type"`
CreateTime string `json:"create_time" gorm:"column:create_time"`
SourceId int64 `json:"source_id" gorm:"column:source_id"`
AwardCount int `json:"award_count" gorm:"column:award_count"`
}
UserMoneyDetailsCopy1 struct {
Id int64 `json:"id" gorm:"column:id;primary_key"`
UserId int64 `json:"user_id" gorm:"column:user_id"`
SysUserId int64 `json:"sys_user_id" gorm:"column:sys_user_id"`
ByUserId int64 `json:"by_user_id" gorm:"column:by_user_id"`
Title string `json:"title" gorm:"column:title"`
Classify int `json:"classify" gorm:"column:classify"`
Type int `json:"type" gorm:"column:type"`
State int `json:"state" gorm:"column:state"`
Money float64 `json:"money" gorm:"column:money"`
Content string `json:"content" gorm:"column:content"`
MoneyType int `json:"money_type" gorm:"column:money_type"`
CreateTime string `json:"create_time" gorm:"column:create_time"`
SourceId int64 `json:"source_id" gorm:"column:source_id"`
AwardCount int `json:"award_count" gorm:"column:award_count"`
}
)
func (UserMoneyDetails) TableName() string {
return "user_money_details"
}
func (UserMoneyDetailsCopy1) TableName() string {
return "user_money_details_copy1"
}

125
db/copy_data.go Normal file
View File

@ -0,0 +1,125 @@
package db
import (
"fmt"
"github.com/jinzhu/copier"
"gorm.io/gorm"
"time"
"video_data_copy/data"
)
func copyOrders(db *gorm.DB, timeNow time.Time) {
order := &data.Orders{}
db.Model(order).Where("create_time < ?", timeNow.Format("2006-01-02 15:04:05")).Order("create_time asc").First(order)
parse, err := time.Parse("2006-01-02T15:04:05Z07:00", order.CreateTime)
if err != nil {
fmt.Println("parse order create_time error:", err)
}
format := parse.Format("2006-01-02 15:04:05")
fmt.Println("copy orders from:", format)
db.Debug().Where("create_time >= ?", format).Delete(&data.OrdersCopy1{})
_execOrders(db, timeNow.Format("2006-01-02 15:04:05"), 0)
}
func _execOrders(db *gorm.DB, timeNow string, index int) {
var orders []*data.Orders
db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&orders)
fmt.Printf("index: %d, timeNow: %s ,orders count: %d\n", index, timeNow, len(orders))
if len(orders) == 0 {
return
}
var copyList []*data.OrdersCopy1
for _, order := range orders {
copyOrder := &data.OrdersCopy1{}
CopyStruct(order, copyOrder)
copyList = append(copyList, copyOrder)
}
db.Create(&copyList)
_execOrders(db, timeNow, index+1)
}
func copyPayDetails(db *gorm.DB, timeNow time.Time) {
detail := &data.PayDetails{}
db.Model(detail).Where("create_time < ?", timeNow.Format("2006-01-02 15:04:05")).Order("create_time asc").First(detail)
parse, err := time.Parse("2006-01-02T15:04:05Z07:00", detail.CreateTime)
if err != nil {
fmt.Println("parse pay_details create_time error:", err)
}
format := parse.Format("2006-01-02 15:04:05")
fmt.Println("copy pay_details from:", format)
db.Debug().Where("create_time >= ?", format).Delete(&data.PayDetailsCopy1{})
_execPayDetails(db, timeNow.Format("2006-01-02 15:04:05"), 0)
}
func _execPayDetails(db *gorm.DB, timeNow string, index int) {
var details []*data.PayDetails
db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&details)
fmt.Printf("index: %d, timeNow: %s ,pay_details count: %d\n", index, timeNow, len(details))
if len(details) == 0 {
return
}
var copyList []*data.PayDetailsCopy1
for _, detail := range details {
detailCopy := &data.PayDetailsCopy1{}
CopyStruct(detail, detailCopy)
copyList = append(copyList, detailCopy)
}
db.Create(&copyList)
_execPayDetails(db, timeNow, index+1)
}
func copyUserMoneyDetails(db *gorm.DB, timeNow time.Time) {
detail := &data.UserMoneyDetails{}
db.Model(detail).Where("create_time < ?", timeNow.Format("2006-01-02 15:04:05")).Order("create_time asc").First(detail)
parse, err := time.Parse("2006-01-02T15:04:05Z07:00", detail.CreateTime)
if err != nil {
fmt.Println("parse pay_details create_time error:", err)
}
format := parse.Format("2006-01-02 15:04:05")
fmt.Println("copy pay_details from:", format)
db.Debug().Where("create_time >= ?", format).Delete(&data.UserMoneyDetailsCopy1{})
_execUserMoneyDetails(db, timeNow.Format("2006-01-02 15:04:05"), 0)
}
func _execUserMoneyDetails(db *gorm.DB, timeNow string, index int) {
var details []*data.UserMoneyDetails
db.Debug().Where("create_time < ?", timeNow).Limit(1000).Offset(index * 1000).Find(&details)
fmt.Printf("index: %d, timeNow: %s ,pay_details count: %d\n", index, timeNow, len(details))
if len(details) == 0 {
return
}
var copyList []*data.UserMoneyDetailsCopy1
for _, detail := range details {
detailCopy := &data.UserMoneyDetailsCopy1{}
CopyStruct(detail, detailCopy)
copyList = append(copyList, detailCopy)
}
db.Create(&copyList)
_execUserMoneyDetails(db, timeNow, index+1)
}
// CopyStruct 使用反射复制结构体
func CopyStruct(src, dst interface{}) {
_ = copier.Copy(dst, src)
}

17
db/db_config.go Normal file
View File

@ -0,0 +1,17 @@
package db
type (
ConnectInfo struct {
Host string `yaml:"host" json:"host"`
Name string `yaml:"name" json:"name"`
Password string `yaml:"password" json:"password"`
Port string `yaml:"port" json:"port"`
Dbs []string `yaml:"dbs" json:"dbs"`
}
Config struct {
Env string `yaml:"env" json:"env"`
Dev *ConnectInfo `yaml:"dev" json:"dev"`
Prod *ConnectInfo `yaml:"prod" json:"prod"`
}
)

95
db/db_manager.go Normal file
View File

@ -0,0 +1,95 @@
package db
import (
"fmt"
"gopkg.in/yaml.v3"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"os"
"time"
)
var (
config *Config
dbList []*gorm.DB
)
func ConnectDB() {
_loadConfig()
_goConnectDB()
}
func CopyData() {
if len(dbList) == 0 {
panic("dbList is nil")
}
timeNow := time.Now().Add(-30 * 24 * time.Hour)
for _, db := range dbList {
copyOrders(db, timeNow)
copyPayDetails(db, timeNow)
copyUserMoneyDetails(db, timeNow)
}
}
func DisconnectDB() {
for _, db := range dbList {
s, err := db.DB()
if err != nil {
continue
}
_ = s.Close()
}
}
func _loadConfig() {
// 读取YAML文件内容
yamlFile, err := os.ReadFile("db_config.yml")
if err != nil {
panic(err)
}
c := &Config{}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
panic(err)
}
config = c
}
func _goConnectDB() {
if config == nil {
panic("config is nil")
}
if config.Env != "dev" && config.Env != "prod" {
panic("config.Env is not valid")
}
configInfo := config.Dev
if config.Env == "prod" {
configInfo = config.Prod
}
for _, dbInfo := range configInfo.Dbs {
connectUrl := _getDbConnectUrl(configInfo, dbInfo)
db, err := gorm.Open(mysql.Open(connectUrl))
if err != nil {
panic(err)
}
dbList = append(dbList, db)
}
fmt.Println("Connect to DB success")
}
func _getDbConnectUrl(configInfo *ConnectInfo, dbName string) string {
return configInfo.Name +
":" +
configInfo.Password +
"@tcp(" + configInfo.Host + ":" + configInfo.Port + ")/" +
dbName +
"?charset=utf8mb4&parseTime=True&loc=Local"
}

25
db_config.yml Normal file
View File

@ -0,0 +1,25 @@
env: dev
dev:
host: rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com
name: video_user
password: VideoUser@1
port: 3306
dbs:
- duanju-0
- duanju-1
- duanju-2
- duanju-3
- duanju-4
prod:
host: rm-gc7xx913734hv5w5qxo.mysql.cn-chengdu.rds.aliyuncs.com
name: video_user
password: VideoUser@1
port: 3306
dbs:
- duanju-0
- duanju-1
- duanju-2
- duanju-3
- duanju-4

16
go.mod Normal file
View File

@ -0,0 +1,16 @@
module video_data_copy
go 1.23.4
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/go-sql-driver/mysql v1.9.0 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
golang.org/x/text v0.23.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.5.7 // indirect
gorm.io/gorm v1.25.12 // indirect
)

23
go.sum Normal file
View File

@ -0,0 +1,23 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.9.0 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo=
github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw=
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

32
main.go Normal file
View File

@ -0,0 +1,32 @@
package main
import (
"fmt"
"github.com/robfig/cron/v3"
"time"
"video_data_copy/db"
)
func main() {
c := cron.New()
_, err := c.AddFunc("0 4 * * *", func() {
fmt.Println("定时任务开始执行")
_startCopyData()
})
if err != nil {
fmt.Printf("添加定时任务出错: %v\n", err)
return
}
fmt.Println("定时任务启动成功")
c.Start()
select {}
}
func _startCopyData() {
db.ConnectDB()
db.CopyData()
time.Sleep(10 * time.Second)
db.DisconnectDB()
}

9
video_data_copy.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

BIN
video_data_copy_linux_amd64 Executable file

Binary file not shown.