package controller import ( "fmt" "github.com/gin-gonic/gin" "knowledge/api/dao" "knowledge/api/model" "knowledge/api/responses" "knowledge/global" "regexp" "strings" "sync" "sync/atomic" "time" ) type Migrate struct{} var ( concurrency = 50 // 最大并发协程的数量 running int32 // 当前运行的协程数量 wg sync.WaitGroup limiter = make(chan struct{}, concurrency) // 通道作为限流器 ) // Migrate 迁移数据 func (r *Migrate) Migrate(c *gin.Context) { // 获取全部数据 Testpaper12Dao := dao.Testpaper12Dao{} maps := make(map[string]interface{}) //maps["id"] = 51134 maps["is_migrate"] = 0 Testpaper12s, err := Testpaper12Dao.GetTestpaper12List(maps) if err != nil { panic("数据迁移失败! " + err.Error()) } if len(Testpaper12s) <= 0 { fmt.Println("已全部处理结束") } for i, v := range Testpaper12s { wg.Add(1) go doWork(i, v) } wg.Wait() responses.Ok(c) } func doWork(i int, v *model.Testpaper12) { defer wg.Done() // goroutine结束就登记-1 limiter <- struct{}{} // 获取一个令牌 atomic.AddInt32(&running, 1) time.Sleep(100 * time.Millisecond) // 模拟工作 <-limiter // 释放一个令牌 atomic.AddInt32(&running, -1) questionDao := dao.QuestionDao{} // 开始事务 tx := global.Db.Begin() // 处理题目名称 if v.Name == "" { tx.Rollback() return } // 题目名称去除前面标点符号 re := regexp.MustCompile(`^\d+\.`) questionName := re.ReplaceAllString(v.Name, "") re = regexp.MustCompile(`^\d+、`) questionName = re.ReplaceAllString(questionName, "") re = regexp.MustCompile(`^\(\d+分\)\d+\.`) questionName = re.ReplaceAllString(questionName, "") // 处理答案 【答案】D if v.Answer == "" { tx.Rollback() return } re = regexp.MustCompile(`[A-Z]+$`) questionAnswer := re.FindString(v.Answer) if questionAnswer == "" { // 未匹配到 tx.Rollback() return } if questionAnswer == "" { tx.Rollback() return } // 处理解析 questionAnalysis := "" if v.Explain != "" { questionAnalysis = strings.Replace(v.Explain, "【解析】", "", 1) questionAnalysis = strings.Replace(questionAnalysis, "【答案解析】", "", 1) } // 添加题库表 question := &model.Question{ QuestionName: questionName, QuestionType: 1, // 题目类型 QuestionSource: 1, // 题目来源(1:本题库 2:外部数据) QuestionAnswer: questionAnswer, QuestionAnalysis: questionAnalysis, FirstLabelId: nil, SecondLabelId: nil, } question, err := questionDao.AddQuestion(tx, question) if err != nil { tx.Rollback() return } // 处理选项 questionOptions := strings.Split(v.Item, "★") if len(questionOptions) > 0 { questionOptionDao := dao.QuestionOptionDao{} s := false for _, option := range questionOptions { questionOption := &model.QuestionOption{ QuestionId: question.QuestionId, OptionValue: option, } questionOption, err := questionOptionDao.AddQuestionOption(tx, questionOption) if err != nil { tx.Rollback() s = true break } } if s { tx.Rollback() return } } // 修改为已迁移 testpaper12Data := make(map[string]interface{}) testpaper12Data["is_migrate"] = 1 Testpaper12Dao := dao.Testpaper12Dao{} err = Testpaper12Dao.EditTestpaper12ById(tx, int64(v.Id), testpaper12Data) if err != nil { tx.Rollback() fmt.Println(err) } tx.Commit() }