package services import ( "baliance.com/gooxml/document" "baliance.com/gooxml/measurement" "baliance.com/gooxml/schema/soo/wml" "bufio" "errors" "eta/eta_api/models" "eta/eta_api/models/speech_recognition" "eta/eta_api/services/alarm_msg" "eta/eta_api/utils" "fmt" "github.com/jung-kurt/gofpdf" "os" "strconv" "sync" "time" ) const ( SpeechRecognitionExportTypeTxt = 1 SpeechRecognitionExportTypeDocx = 2 SpeechRecognitionExportTypePdf = 3 SpeechMenuCheckRemoveTypePass = 0 // 目录删除校验-可删除 SpeechMenuCheckRemoveTypeRefused = 1 // 目录删除校验-不可删除 SpeechMenuCheckRemoveTypeWarning = 2 // 目录删除校验-警告 ) // GetSpeechRecognitionMenuTreeRecursive 递归获取标签目录树 func GetSpeechRecognitionMenuTreeRecursive(list []*speech_recognition.SpeechRecognitionMenu, parentId int) []*speech_recognition.SpeechRecognitionMenuItem { res := make([]*speech_recognition.SpeechRecognitionMenuItem, 0) for _, v := range list { if v.ParentId == parentId { t := new(speech_recognition.SpeechRecognitionMenuItem) t.UniqueCode = v.UniqueCode t.MenuId = v.SpeechRecognitionMenuId t.MenuName = v.MenuName t.ParentId = v.ParentId t.Level = v.Level t.Sort = v.Sort t.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime) t.Children = GetSpeechRecognitionMenuTreeRecursive(list, v.SpeechRecognitionMenuId) res = append(res, t) } } return res } // GetSpeechRecognitionTagMenuTreeRecursive 递归获取标签目录树 func GetSpeechRecognitionTagMenuTreeRecursive(list []*speech_recognition.SpeechRecognitionTagMenu, parentId int) []*speech_recognition.SpeechRecognitionTagMenuItem { res := make([]*speech_recognition.SpeechRecognitionTagMenuItem, 0) for _, v := range list { if v.ParentId == parentId { t := new(speech_recognition.SpeechRecognitionTagMenuItem) t.UniqueCode = v.UniqueCode t.MenuId = v.SpeechRecognitionTagMenuId t.MenuName = v.MenuName t.ParentId = v.ParentId t.Level = v.Level t.Sort = v.Sort t.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime) t.Children = GetSpeechRecognitionTagMenuTreeRecursive(list, v.SpeechRecognitionTagMenuId) res = append(res, t) } } return res } // BatchConvertSpeech 批量转写语音 func BatchConvertSpeech(speeches []*speech_recognition.SpeechRecognition) { var err error defer func() { if err != nil { tips := fmt.Sprintf("批量转写语音失败, ErrMsg: %s", err.Error()) utils.FileLog.Info(tips) go alarm_msg.SendAlarmMsg(tips, 1) } }() conf, e := models.GetBusinessConf() if e != nil { err = fmt.Errorf("获取配置失败, Err: %s", e.Error()) return } if conf[models.BusinessConfTencentApiSecretId] == "" || conf[models.BusinessConfTencentApiSecretKey] == "" || conf[models.BusinessConfTencentApiRecTaskCallbackUrl] == "" { err = fmt.Errorf("API配置有误, SecretId: %s, SecretKey: %s, Callback: %s", conf[models.BusinessConfTencentApiSecretId], conf[models.BusinessConfTencentApiSecretKey], conf[models.BusinessConfTencentApiRecTaskCallbackUrl]) return } // 限制接口请求频率 apiLimit := make(chan struct{}, 20) var wg sync.WaitGroup for _, v := range speeches { wg.Add(1) go func(speech *speech_recognition.SpeechRecognition) { defer func() { wg.Done() <-apiLimit }() apiLimit <- struct{}{} // 发起请求 var errMsg string var r TencentRecTaskReq r.FileUrl = speech.ResourceUrl r.SecretId = conf[models.BusinessConfTencentApiSecretId] r.SecretKey = conf[models.BusinessConfTencentApiSecretKey] r.CallbackUrl = conf[models.BusinessConfTencentApiRecTaskCallbackUrl] taskId, e := TencentCreateRecTask(r) if e != nil { errMsg = "创建语音识别任务失败" utils.FileLog.Info("TencentCreateRecTask创建语音识别任务失败, ErrMsg: %s", e.Error()) } if errMsg == "" { apiLog := new(speech_recognition.SpeechRecognitionApiLog) apiLog.SpeechRecognitionId = speech.SpeechRecognitionId apiLog.RequestId = strconv.Itoa(taskId) apiLog.RequestCode = -1 apiLog.CreateTime = time.Now().Local() apiLog.ModifyTime = time.Now().Local() if e = apiLog.Create(); e != nil { errMsg = "生成API请求失败" utils.FileLog.Info("CreateApiLog生成API请求记录失败, ErrMsg: %s", e.Error()) return } } // 有报错则更新对应语音识别状态 if errMsg == "" { return } speech.State = speech_recognition.SpeechRecognitionStateFail speech.ConvertRemark = errMsg speech.ModifyTime = time.Now().Local() updateCols := []string{speech_recognition.SpeechRecognitionCols.State, speech_recognition.SpeechRecognitionCols.ConvertRemark, speech_recognition.SpeechRecognitionCols.ModifyTime} if e = speech.Update(updateCols); e != nil { utils.FileLog.Info("UpdateSpeech更新语音识别状态失败, ErrMsg: %s", e.Error()) return } }(v) } wg.Wait() return } // SpeechRecognitionContentExport 导出语音识别内容 func SpeechRecognitionContentExport(exportType int, exportTimestamp bool, fileName string, contents []*speech_recognition.SpeechRecognitionContent) (result string, err error) { defer func() { if err != nil { fmt.Println(err) } }() if len(contents) == 0 { return } // 整理内容 exportText := "" exportArr := make([]string, 0) exportPdfArr := make([]string, 0) for _, v := range contents { if v.Content == "" { continue } sec := "" secPdf := "" if exportTimestamp { // 毫秒转时间格式 sec = fmt.Sprintf("%s\n%s\n\n", utils.MillisecondsToHHMMSS(v.StartMs), v.Content) secPdf = fmt.Sprintf("%s %s", utils.MillisecondsToHHMMSS(v.StartMs), v.Content) } else { sec = fmt.Sprintf("%s\n\n", v.Content) secPdf = v.Content } exportText += sec exportArr = append(exportArr, sec) exportPdfArr = append(exportPdfArr, secPdf) } // 导出doc if exportType == SpeechRecognitionExportTypeDocx { doc := document.New() for _, v := range exportArr { p := doc.AddParagraph() prop := p.Properties() prop.Spacing().SetLineSpacing(measurement.Distance(1.5*15*measurement.Point), wml.ST_LineSpacingRuleAuto) prop.SetAlignment(wml.ST_JcLeft) run := p.AddRun() runProp := run.Properties() runProp.SetSize(measurement.Distance(15 * measurement.Point)) runProp.SetFontFamily("宋体") run.AddText(v) run.AddBreak() } filePath := fmt.Sprintf("%s.docx", fileName) if e := doc.SaveToFile(filePath); e != nil { err = fmt.Errorf("生成docx失败, Err: %s", e.Error()) return } result = filePath return } // 导出pdf if exportType == SpeechRecognitionExportTypePdf { pdf := gofpdf.New("P", "mm", "A4", "") pdf.AddPage() pdf.AddUTF8Font("SimHei", "", "static/SimHei.ttf") // 此处字体文件只能用本地的 pdf.SetFont("SimHei", "", 14) // 计算可用内容区域宽度 w, _ := pdf.GetPageSize() marginLeft := 10.0 marginRight := 10.0 availableWidth := w - marginLeft - marginRight for _, v := range exportPdfArr { pdf.MultiCell(availableWidth, 10, v, "", "L", false) pdf.MultiCell(availableWidth, 5, "", "", "L", false) // 单纯的换行 } filePath := fmt.Sprintf("%s.pdf", fileName) if e := pdf.OutputFileAndClose(filePath); e != nil { err = fmt.Errorf("生成pdf失败, Err: %s", e.Error()) return } result = filePath return } // 默认导出txt filePath := fmt.Sprintf("%s.txt", fileName) file, e := os.Create(filePath) if e != nil { err = fmt.Errorf("生成txt文件失败, err: %s", e.Error()) return } defer file.Close() // 写入txt writer := bufio.NewWriter(file) _, e = writer.WriteString(exportText) if e != nil { err = fmt.Errorf("写入txt文件失败, err: %s", e.Error()) return } if e = writer.Flush(); e != nil { err = fmt.Errorf("刷新txt缓存失败, err: %s", e.Error()) return } result = filePath return } // ------------------ 移动目录/语音识别(有空的话后面可以优化一下,以后这种菜单混合移动的情况不会少,CV起来怪麻烦的) ------------------ // // MoveSpeechMenu 移动语音识别目录/识别文件 func MoveSpeechMenu(req speech_recognition.SpeechRecognitionMenuMoveReq) (err error, errMsg string) { menuId := req.MenuId parentMenuId := req.ParentMenuId prevMenuId := req.PrevMenuId nextMenuId := req.NextMenuId speechId := req.SpeechId prevSpeechId := req.PrevSpeechId nextSpeechId := req.NextSpeechId //首先确定移动的对象是目录还是语音识别 //判断上一个节点是目录还是语音识别 //判断下一个节点是目录还是语音识别 //同时更新目录目录下的目录sort和语音识别sort //更新当前移动的目录或者语音识别sort menuOb := new(speech_recognition.SpeechRecognitionMenu) speechOb := new(speech_recognition.SpeechRecognition) var parentSpeechMenu *speech_recognition.SpeechRecognitionMenu if parentMenuId > 0 { t, e := menuOb.GetItemById(parentMenuId) if e != nil { errMsg = "移动失败" err = errors.New("获取上级目录信息失败,Err:" + err.Error()) return } parentSpeechMenu = t } //如果有传入 上一个兄弟节点目录id var ( speechMenu *speech_recognition.SpeechRecognitionMenu prevMenu *speech_recognition.SpeechRecognitionMenu nextMenu *speech_recognition.SpeechRecognitionMenu speechItem *speech_recognition.SpeechRecognition prevSpeech *speech_recognition.SpeechRecognition nextSpeech *speech_recognition.SpeechRecognition prevSort int nextSort int ) // 移动对象为目录 if speechId == 0 { speechMenu, err = menuOb.GetItemById(menuId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前目录不存在" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } errMsg = "移动失败" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } if parentMenuId > 0 && parentSpeechMenu.Level == 3 { errMsg = "最高只支持添加3级目录" err = errors.New(errMsg) return } // 如果是移动目录, 那么校验一下父级目录下是否有重名目录 { cond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s <> ?`, speech_recognition.SpeechRecognitionMenuCols.MenuName, speech_recognition.SpeechRecognitionMenuCols.ParentId, speech_recognition.SpeechRecognitionMenuCols.SpeechRecognitionMenuId) pars := make([]interface{}, 0) pars = append(pars, speechMenu.MenuName, parentMenuId, menuId) exists, e := menuOb.GetItemByCondition(cond, pars, "") if e != nil && e.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = fmt.Errorf("获取父级目录下的同名目录失败, Err: %s", e.Error()) return } if exists != nil { errMsg = "移动失败,目录名称已存在" return } } } else { speechItem, err = speechOb.GetItemById(speechId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前语音识别不存在" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } errMsg = "移动失败" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } if parentMenuId == 0 { errMsg = "移动失败,语音识别必须挂在目录下" err = errors.New(errMsg) return } } if prevMenuId > 0 { prevMenu, err = menuOb.GetItemById(prevMenuId) if err != nil { errMsg = "移动失败" err = errors.New("获取上一个兄弟节点目录信息失败,Err:" + err.Error()) return } prevSort = prevMenu.Sort } else if prevSpeechId > 0 { prevSpeech, err = speechOb.GetItemById(prevSpeechId) if err != nil { errMsg = "移动失败" err = errors.New("获取上一个兄弟节点信息失败,Err:" + err.Error()) return } prevSort = prevSpeech.Sort } // 下一个兄弟节点 if nextMenuId > 0 { nextMenu, err = menuOb.GetItemById(nextMenuId) if err != nil { errMsg = "移动失败" err = errors.New("获取下一个兄弟节点目录信息失败,Err:" + err.Error()) return } nextSort = nextMenu.Sort } else if nextSpeechId > 0 { nextSpeech, err = speechOb.GetItemById(nextSpeechId) if err != nil { errMsg = "移动失败" err = errors.New("获取下一个兄弟节点目录信息失败,Err:" + err.Error()) return } nextSort = nextSpeech.Sort } err, errMsg = moveSpeechMenu(parentSpeechMenu, speechMenu, prevMenu, nextMenu, speechItem, prevSpeech, nextSpeech, parentMenuId, prevSort, nextSort) return } func moveSpeechMenu(parentSpeechMenu, speechMenu, prevMenu, nextMenu *speech_recognition.SpeechRecognitionMenu, speechItem, prevSpeech, nextSpeech *speech_recognition.SpeechRecognition, parentMenuId int, prevSort, nextSort int) (err error, errMsg string) { updateCol := make([]string, 0) menuOb := new(speech_recognition.SpeechRecognitionMenu) speechOb := new(speech_recognition.SpeechRecognition) // 移动对象为目录, 判断目录是否存在 if speechMenu != nil { oldParentId := speechMenu.ParentId oldLevel := speechMenu.Level var menuIds []int if oldParentId != parentMenuId { //更新子目录对应的level childList, e, m := GetChildSpeechMenuByMenuId(speechMenu.SpeechRecognitionMenuId) if e != nil { errMsg = "移动失败" err = errors.New("查询子目录失败,Err:" + e.Error() + m) return } if len(childList) > 0 { for _, v := range childList { if v.SpeechRecognitionMenuId == speechMenu.SpeechRecognitionMenuId { continue } menuIds = append(menuIds, v.SpeechRecognitionMenuId) } } } //判断上级id是否一致,如果不一致的话,那么需要移动该目录层级 if speechMenu.ParentId != parentMenuId && parentMenuId != 0 { if speechMenu.Level != parentSpeechMenu.Level+1 { //禁止层级调整 errMsg = "移动失败" err = errors.New("不支持目录层级变更") return } speechMenu.ParentId = parentSpeechMenu.SpeechRecognitionMenuId speechMenu.RootId = parentSpeechMenu.RootId speechMenu.Level = parentSpeechMenu.Level + 1 speechMenu.ModifyTime = time.Now() updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime") } else if speechMenu.ParentId != parentMenuId && parentMenuId == 0 { errMsg = "移动失败" err = errors.New("不支持目录层级变更") return } if prevSort > 0 { //如果是移动在两个兄弟节点之间 if nextSort > 0 { //下一个兄弟节点 //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1 if prevSort == nextSort || prevSort == speechMenu.Sort { //变更兄弟节点的排序 updateSortStr := `sort + 2` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionMenuId, prevMenu.Sort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更语音识别 if prevSpeech != nil { //变更兄弟节点的排序 _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, prevSpeech.SpeechRecognitionId, updateSortStr) } else { _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } else { //如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了 if nextSort-prevSort == 1 { //变更兄弟节点的排序 updateSortStr := `sort + 1` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionMenuId, prevSort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更语音识别 if prevSpeech != nil { //变更兄弟节点的排序 _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, prevSpeech.SpeechRecognitionId, updateSortStr) } else { _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } } } speechMenu.Sort = prevSort + 1 speechMenu.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else if prevMenu == nil && nextMenu == nil && prevSpeech == nil && nextSpeech == nil && parentMenuId > 0 { //处理只拖动到目录里,默认放到目录底部的情况 var maxSort int maxSort, err = GetSpeechMenuMaxSort(parentMenuId) if err != nil { errMsg = "移动失败" err = errors.New("查询组内排序信息失败,Err:" + err.Error()) return } speechMenu.Sort = maxSort + 1 //那就是排在组内最后一位 speechMenu.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else { // 拖动到父级目录的第一位 firstMenu, tmpErr := menuOb.GetFirstByParentId(parentMenuId) if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tmpErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstMenu != nil && firstMenu.Sort == 0 { updateSortStr := ` sort + 1 ` _ = menuOb.UpdateSortByParentId(parentMenuId, firstMenu.SpeechRecognitionMenuId-1, 0, updateSortStr) //该目录下的所有语音识别也需要+1 _ = speechOb.UpdateSortByMenuId(parentMenuId, 0, 0, updateSortStr) } else { //如果该目录下存在语音识别,且第一个语音识别的排序等于0,那么需要调整排序 firstSpeech, tErr := speechOb.GetFirstByMenuId(parentMenuId) if tErr != nil && tErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstSpeech != nil && firstSpeech.Sort == 0 { updateSortStr := ` sort + 1 ` _ = speechOb.UpdateSortByMenuId(parentMenuId, 0, firstSpeech.SpeechRecognitionId-1, updateSortStr) _ = menuOb.UpdateSortByParentId(parentMenuId, 0, 0, updateSortStr) } } speechMenu.Sort = 0 //那就是排在第一位 speechMenu.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } //更新 if len(updateCol) > 0 { err = speechMenu.Update(updateCol) if err != nil { errMsg = "移动失败" err = errors.New("修改失败,Err:" + err.Error()) return } //更新对应目录的root_id和层级 if oldParentId != parentMenuId { if len(menuIds) > 0 { levelStep := speechMenu.Level - oldLevel err = menuOb.UpdateChildByParentMenuId(menuIds, speechMenu.RootId, levelStep) if err != nil { errMsg = "移动失败" err = errors.New("更新子目录失败,Err:" + err.Error()) return } } } } } else { if speechItem == nil { errMsg = "当前语音识别不存在" err = errors.New(errMsg) return } //如果改变了目录,那么移动该语音识别数据 if speechItem.MenuId != parentMenuId { speechItem.MenuId = parentMenuId speechItem.ModifyTime = time.Now() updateCol = append(updateCol, speech_recognition.SpeechRecognitionCols.MenuId, speech_recognition.SpeechRecognitionCols.ModifyTime) } if prevSort > 0 { //如果是移动在两个兄弟节点之间 if nextSort > 0 { //下一个兄弟节点 //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1 if prevSort == nextSort || prevSort == speechItem.Sort { //变更兄弟节点的排序 updateSortStr := `sort + 2` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionMenuId, prevMenu.Sort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更语音识别 if prevSpeech != nil { //变更兄弟节点的排序 _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, prevSpeech.SpeechRecognitionId, updateSortStr) } else { _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } else { //如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了 if nextSort-prevSort == 1 { //变更兄弟节点的排序 updateSortStr := `sort + 1` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionMenuId, prevSort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更语音识别 if prevSpeech != nil { //变更兄弟节点的排序 _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, prevSpeech.SpeechRecognitionId, updateSortStr) } else { _ = speechOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } } } speechItem.Sort = prevSort + 1 speechItem.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else if prevMenu == nil && nextMenu == nil && prevSpeech == nil && nextSpeech == nil && parentMenuId > 0 { //处理只拖动到目录里,默认放到目录底部的情况 var maxSort int maxSort, err = GetSpeechMenuMaxSort(parentMenuId) if err != nil { errMsg = "移动失败" err = errors.New("查询组内排序信息失败,Err:" + err.Error()) return } speechItem.Sort = maxSort + 1 //那就是排在组内最后一位 speechItem.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else { // 拖动到父级目录的第一位 firstMenu, tmpErr := menuOb.GetFirstByParentId(parentMenuId) if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tmpErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstMenu != nil && firstMenu.Sort == 0 { updateSortStr := ` sort + 1 ` _ = menuOb.UpdateSortByParentId(parentMenuId, firstMenu.SpeechRecognitionMenuId-1, 0, updateSortStr) //该目录下的所有语音识别也需要+1 _ = speechOb.UpdateSortByMenuId(parentMenuId, 0, 0, updateSortStr) } else { //如果该目录下存在语音识别,且第一个语音识别的排序等于0,那么需要调整排序 firstSpeech, tErr := speechOb.GetFirstByMenuId(parentMenuId) if tErr != nil && tErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstSpeech != nil && firstSpeech.Sort == 0 { updateSortStr := ` sort + 1 ` _ = speechOb.UpdateSortByMenuId(parentMenuId, 0, firstSpeech.SpeechRecognitionId-1, updateSortStr) _ = menuOb.UpdateSortByParentId(parentMenuId, 0, 0, updateSortStr) } } speechItem.Sort = 0 //那就是排在第一位 speechItem.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } //更新 if len(updateCol) > 0 { err = speechItem.Update(updateCol) if err != nil { errMsg = "移动失败" err = errors.New("修改失败,Err:" + err.Error()) return } } } return } func GetChildSpeechMenuByMenuId(menuId int) (targetList []*speech_recognition.SpeechRecognitionMenu, err error, errMsg string) { menuOb := new(speech_recognition.SpeechRecognitionMenu) //判断是否是挂在顶级目录下 speechMenu, err := menuOb.GetItemById(menuId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前目录不存在" err = errors.New(errMsg) return } errMsg = "获取失败" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } cond := fmt.Sprintf(" AND %s = ?", speech_recognition.SpeechRecognitionMenuCols.RootId) pars := make([]interface{}, 0) pars = append(pars, speechMenu.RootId) order := fmt.Sprintf("%s ASC, %s ASC, %s ASC", speech_recognition.SpeechRecognitionMenuCols.Level, speech_recognition.SpeechRecognitionMenuCols.Sort, speech_recognition.SpeechRecognitionMenuCols.SpeechRecognitionMenuId) tmpList, err := speechMenu.GetItemsByCondition(cond, pars, []string{}, order) if err != nil && err.Error() != utils.ErrNoRow() { errMsg = "获取失败" err = errors.New("获取数据失败,Err:" + err.Error()) return } idMap := make(map[int]struct{}) if len(tmpList) > 0 { for _, v := range tmpList { if v.SpeechRecognitionMenuId == speechMenu.SpeechRecognitionMenuId { idMap[v.SpeechRecognitionMenuId] = struct{}{} } } for _, v := range tmpList { if _, ok := idMap[v.ParentId]; ok { idMap[v.SpeechRecognitionMenuId] = struct{}{} } } for _, v := range tmpList { if _, ok := idMap[v.SpeechRecognitionMenuId]; ok { targetList = append(targetList, v) } } } return } // GetSpeechMenuMaxSort 获取同级下最大的排序 func GetSpeechMenuMaxSort(parentId int) (maxSort int, err error) { menuOb := new(speech_recognition.SpeechRecognitionMenu) speechOb := new(speech_recognition.SpeechRecognition) //获取该层级下最大的排序数 menuMax, err := menuOb.GetMaxSortByParentId(parentId) if err != nil { return } maxSort = menuMax speechMax, err := speechOb.GetMaxSortByMenuId(parentId) if err != nil { return } if maxSort < speechMax { maxSort = speechMax } return } // ------------------ 移动目录/语音识别 ------------------ // // ------------------ 移动标签目录/标签 ------------------ // // MoveSpeechTagMenu 移动标签目录/标签 func MoveSpeechTagMenu(req speech_recognition.SpeechRecognitionTagMenuMoveReq) (err error, errMsg string) { menuId := req.MenuId parentMenuId := req.ParentMenuId prevMenuId := req.PrevMenuId nextMenuId := req.NextMenuId tagId := req.TagId prevTagId := req.PrevTagId nextTagId := req.NextTagId //首先确定移动的对象是目录还是标签 //判断上一个节点是目录还是标签 //判断下一个节点是目录还是标签 //同时更新目录目录下的目录sort和标签sort //更新当前移动的目录或者标签sort menuOb := new(speech_recognition.SpeechRecognitionTagMenu) tagOb := new(speech_recognition.SpeechRecognitionTag) var parentTagMenu *speech_recognition.SpeechRecognitionTagMenu if parentMenuId > 0 { t, e := menuOb.GetItemById(parentMenuId) if e != nil { errMsg = "移动失败" err = errors.New("获取上级目录信息失败,Err:" + err.Error()) return } parentTagMenu = t } //如果有传入 上一个兄弟节点目录id var ( tagMenu *speech_recognition.SpeechRecognitionTagMenu prevMenu *speech_recognition.SpeechRecognitionTagMenu nextMenu *speech_recognition.SpeechRecognitionTagMenu tagItem *speech_recognition.SpeechRecognitionTag prevTag *speech_recognition.SpeechRecognitionTag nextTag *speech_recognition.SpeechRecognitionTag prevSort int nextSort int ) // 移动对象为目录 if tagId == 0 { tagMenu, err = menuOb.GetItemById(menuId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前目录不存在" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } errMsg = "移动失败" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } if parentMenuId > 0 && parentTagMenu.Level == 3 { errMsg = "最高只支持添加3级目录" err = errors.New(errMsg) return } // 如果是移动目录, 那么校验一下父级目录下是否有重名目录 { cond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s <> ?`, speech_recognition.SpeechRecognitionTagMenuCols.MenuName, speech_recognition.SpeechRecognitionTagMenuCols.ParentId, speech_recognition.SpeechRecognitionTagMenuCols.SpeechRecognitionTagMenuId) pars := make([]interface{}, 0) pars = append(pars, tagMenu.MenuName, parentMenuId, menuId) exists, e := menuOb.GetItemByCondition(cond, pars, "") if e != nil && e.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = fmt.Errorf("获取父级目录下的同名目录失败, Err: %s", e.Error()) return } if exists != nil { errMsg = "移动失败,目录名称已存在" return } } } else { tagItem, err = tagOb.GetItemById(tagId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前标签不存在" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } errMsg = "移动失败" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } if parentMenuId == 0 { errMsg = "移动失败,标签必须挂在目录下" err = errors.New(errMsg) return } } if prevMenuId > 0 { prevMenu, err = menuOb.GetItemById(prevMenuId) if err != nil { errMsg = "移动失败" err = errors.New("获取上一个兄弟节点目录信息失败,Err:" + err.Error()) return } prevSort = prevMenu.Sort } else if prevTagId > 0 { prevTag, err = tagOb.GetItemById(prevTagId) if err != nil { errMsg = "移动失败" err = errors.New("获取上一个兄弟节点信息失败,Err:" + err.Error()) return } prevSort = prevTag.Sort } // 下一个兄弟节点 if nextMenuId > 0 { nextMenu, err = menuOb.GetItemById(nextMenuId) if err != nil { errMsg = "移动失败" err = errors.New("获取下一个兄弟节点目录信息失败,Err:" + err.Error()) return } nextSort = nextMenu.Sort } else if nextTagId > 0 { nextTag, err = tagOb.GetItemById(nextTagId) if err != nil { errMsg = "移动失败" err = errors.New("获取下一个兄弟节点目录信息失败,Err:" + err.Error()) return } nextSort = nextTag.Sort } err, errMsg = moveSpeechTagMenu(parentTagMenu, tagMenu, prevMenu, nextMenu, tagItem, prevTag, nextTag, parentMenuId, prevSort, nextSort) return } func moveSpeechTagMenu(parentTagMenu, tagMenu, prevMenu, nextMenu *speech_recognition.SpeechRecognitionTagMenu, tagItem, prevTag, nextTag *speech_recognition.SpeechRecognitionTag, parentMenuId int, prevSort, nextSort int) (err error, errMsg string) { updateCol := make([]string, 0) menuOb := new(speech_recognition.SpeechRecognitionTagMenu) tagOb := new(speech_recognition.SpeechRecognitionTag) // 移动对象为目录, 判断目录是否存在 if tagMenu != nil { oldParentId := tagMenu.ParentId oldLevel := tagMenu.Level var menuIds []int if oldParentId != parentMenuId { //更新子目录对应的level childList, e, m := GetChildSpeechTagMenuByMenuId(tagMenu.SpeechRecognitionTagMenuId) if e != nil { errMsg = "移动失败" err = errors.New("查询子目录失败,Err:" + e.Error() + m) return } if len(childList) > 0 { for _, v := range childList { if v.SpeechRecognitionTagMenuId == tagMenu.SpeechRecognitionTagMenuId { continue } menuIds = append(menuIds, v.SpeechRecognitionTagMenuId) } } } //判断上级id是否一致,如果不一致的话,那么需要移动该目录层级 if tagMenu.ParentId != parentMenuId && parentMenuId != 0 { if tagMenu.Level != parentTagMenu.Level+1 { //禁止层级调整 errMsg = "移动失败" err = errors.New("不支持目录层级变更") return } tagMenu.ParentId = parentTagMenu.SpeechRecognitionTagMenuId tagMenu.RootId = parentTagMenu.RootId tagMenu.Level = parentTagMenu.Level + 1 tagMenu.ModifyTime = time.Now() updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime") } else if tagMenu.ParentId != parentMenuId && parentMenuId == 0 { errMsg = "移动失败" err = errors.New("不支持目录层级变更") return } if prevSort > 0 { //如果是移动在两个兄弟节点之间 if nextSort > 0 { //下一个兄弟节点 //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1 if prevSort == nextSort || prevSort == tagMenu.Sort { //变更兄弟节点的排序 updateSortStr := `sort + 2` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionTagMenuId, prevMenu.Sort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更标签 if prevTag != nil { //变更兄弟节点的排序 _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, prevTag.SpeechRecognitionTagId, updateSortStr) } else { _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } else { //如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了 if nextSort-prevSort == 1 { //变更兄弟节点的排序 updateSortStr := `sort + 1` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionTagMenuId, prevSort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更标签 if prevTag != nil { //变更兄弟节点的排序 _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, prevTag.SpeechRecognitionTagId, updateSortStr) } else { _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } } } tagMenu.Sort = prevSort + 1 tagMenu.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else if prevMenu == nil && nextMenu == nil && prevTag == nil && nextTag == nil && parentMenuId > 0 { //处理只拖动到目录里,默认放到目录底部的情况 var maxSort int maxSort, err = GetSpeechTagMenuMaxSort(parentMenuId) if err != nil { errMsg = "移动失败" err = errors.New("查询组内排序信息失败,Err:" + err.Error()) return } tagMenu.Sort = maxSort + 1 //那就是排在组内最后一位 tagMenu.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else { // 拖动到父级目录的第一位 firstTagMenu, tmpErr := menuOb.GetFirstByParentId(parentMenuId) if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tmpErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstTagMenu != nil && firstTagMenu.Sort == 0 { updateSortStr := ` sort + 1 ` _ = menuOb.UpdateSortByParentId(parentMenuId, firstTagMenu.SpeechRecognitionTagMenuId-1, 0, updateSortStr) //该目录下的所有标签也需要+1 _ = tagOb.UpdateSortByMenuId(parentMenuId, 0, 0, updateSortStr) } else { //如果该目录下存在标签,且第一个标签的排序等于0,那么需要调整排序 firstTag, tErr := tagOb.GetFirstByMenuId(parentMenuId) if tErr != nil && tErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstTag != nil && firstTag.Sort == 0 { updateSortStr := ` sort + 1 ` _ = tagOb.UpdateSortByMenuId(parentMenuId, 0, firstTag.SpeechRecognitionTagId-1, updateSortStr) _ = menuOb.UpdateSortByParentId(parentMenuId, 0, 0, updateSortStr) } } tagMenu.Sort = 0 //那就是排在第一位 tagMenu.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } //更新 if len(updateCol) > 0 { err = tagMenu.Update(updateCol) if err != nil { errMsg = "移动失败" err = errors.New("修改失败,Err:" + err.Error()) return } //更新对应目录的root_id和层级 if oldParentId != parentMenuId { if len(menuIds) > 0 { levelStep := tagMenu.Level - oldLevel err = menuOb.UpdateChildByParentMenuId(menuIds, tagMenu.RootId, levelStep) if err != nil { errMsg = "移动失败" err = errors.New("更新子目录失败,Err:" + err.Error()) return } } } } } else { if tagItem == nil { errMsg = "当前标签不存在" err = errors.New(errMsg) return } //如果改变了目录,那么移动该标签数据 if tagItem.MenuId != parentMenuId { tagItem.MenuId = parentMenuId tagItem.ModifyTime = time.Now() updateCol = append(updateCol, speech_recognition.SpeechRecognitionTagCols.MenuId, speech_recognition.SpeechRecognitionTagCols.ModifyTime) } if prevSort > 0 { //如果是移动在两个兄弟节点之间 if nextSort > 0 { //下一个兄弟节点 //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1 if prevSort == nextSort || prevSort == tagItem.Sort { //变更兄弟节点的排序 updateSortStr := `sort + 2` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionTagMenuId, prevMenu.Sort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更标签 if prevTag != nil { //变更兄弟节点的排序 _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, prevTag.SpeechRecognitionTagId, updateSortStr) } else { _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } else { //如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了 if nextSort-prevSort == 1 { //变更兄弟节点的排序 updateSortStr := `sort + 1` //变更目录 if prevMenu != nil { _ = menuOb.UpdateSortByParentId(parentMenuId, prevMenu.SpeechRecognitionTagMenuId, prevSort, updateSortStr) } else { _ = menuOb.UpdateSortByParentId(parentMenuId, 0, prevSort, updateSortStr) } //变更标签 if prevTag != nil { //变更兄弟节点的排序 _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, prevTag.SpeechRecognitionTagId, updateSortStr) } else { _ = tagOb.UpdateSortByMenuId(parentMenuId, prevSort, 0, updateSortStr) } } } } tagItem.Sort = prevSort + 1 tagItem.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else if prevMenu == nil && nextMenu == nil && prevTag == nil && nextTag == nil && parentMenuId > 0 { //处理只拖动到目录里,默认放到目录底部的情况 var maxSort int maxSort, err = GetSpeechTagMenuMaxSort(parentMenuId) if err != nil { errMsg = "移动失败" err = errors.New("查询组内排序信息失败,Err:" + err.Error()) return } tagItem.Sort = maxSort + 1 //那就是排在组内最后一位 tagItem.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else { // 拖动到父级目录的第一位 firstTagMenu, tmpErr := menuOb.GetFirstByParentId(parentMenuId) if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tmpErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstTagMenu != nil && firstTagMenu.Sort == 0 { updateSortStr := ` sort + 1 ` _ = menuOb.UpdateSortByParentId(parentMenuId, firstTagMenu.SpeechRecognitionTagMenuId-1, 0, updateSortStr) //该目录下的所有标签也需要+1 _ = tagOb.UpdateSortByMenuId(parentMenuId, 0, 0, updateSortStr) } else { //如果该目录下存在标签,且第一个标签的排序等于0,那么需要调整排序 firstTag, tErr := tagOb.GetFirstByMenuId(parentMenuId) if tErr != nil && tErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级目录下的排序第一条的目录信息失败,Err:" + tErr.Error()) return } //如果该目录下存在其他目录,且第一个其他目录的排序等于0,那么需要调整排序 if firstTag != nil && firstTag.Sort == 0 { updateSortStr := ` sort + 1 ` _ = tagOb.UpdateSortByMenuId(parentMenuId, 0, firstTag.SpeechRecognitionTagId-1, updateSortStr) _ = menuOb.UpdateSortByParentId(parentMenuId, 0, 0, updateSortStr) } } tagItem.Sort = 0 //那就是排在第一位 tagItem.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } //更新 if len(updateCol) > 0 { err = tagItem.Update(updateCol) if err != nil { errMsg = "移动失败" err = errors.New("修改失败,Err:" + err.Error()) return } } } return } func GetChildSpeechTagMenuByMenuId(menuId int) (targetList []*speech_recognition.SpeechRecognitionTagMenu, err error, errMsg string) { menuOb := new(speech_recognition.SpeechRecognitionTagMenu) //判断是否是挂在顶级目录下 tagMenu, err := menuOb.GetItemById(menuId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前目录不存在" err = errors.New(errMsg) return } errMsg = "获取失败" err = errors.New("获取目录信息失败,Err:" + err.Error()) return } cond := fmt.Sprintf(" AND %s = ?", speech_recognition.SpeechRecognitionTagMenuCols.RootId) pars := make([]interface{}, 0) pars = append(pars, tagMenu.RootId) order := fmt.Sprintf("%s ASC, %s ASC, %s ASC", speech_recognition.SpeechRecognitionTagMenuCols.Level, speech_recognition.SpeechRecognitionTagMenuCols.Sort, speech_recognition.SpeechRecognitionTagMenuCols.SpeechRecognitionTagMenuId) tmpList, err := tagMenu.GetItemsByCondition(cond, pars, []string{}, order) if err != nil && err.Error() != utils.ErrNoRow() { errMsg = "获取失败" err = errors.New("获取数据失败,Err:" + err.Error()) return } idMap := make(map[int]struct{}) if len(tmpList) > 0 { for _, v := range tmpList { if v.SpeechRecognitionTagMenuId == tagMenu.SpeechRecognitionTagMenuId { idMap[v.SpeechRecognitionTagMenuId] = struct{}{} } } for _, v := range tmpList { if _, ok := idMap[v.ParentId]; ok { idMap[v.SpeechRecognitionTagMenuId] = struct{}{} } } for _, v := range tmpList { if _, ok := idMap[v.SpeechRecognitionTagMenuId]; ok { targetList = append(targetList, v) } } } return } // GetSpeechTagMenuMaxSort 获取同级下最大的排序 func GetSpeechTagMenuMaxSort(parentId int) (maxSort int, err error) { menuOb := new(speech_recognition.SpeechRecognitionTagMenu) tagOb := new(speech_recognition.SpeechRecognitionTag) //获取该层级下最大的排序数 menuMax, err := menuOb.GetMaxSortByParentId(parentId) if err != nil { return } maxSort = menuMax speechMax, err := tagOb.GetMaxSortByMenuId(parentId) if err != nil { return } if maxSort < speechMax { maxSort = speechMax } return } // ------------------ 移动标签目录/标签 ------------------ // // GetSpeechRecognitionMenuChildrenRecursive 递归获取目录的子目录集 func GetSpeechRecognitionMenuChildrenRecursive(list []*speech_recognition.SpeechRecognitionMenu, parentId int) []int { childIds := make([]int, 0) for _, v := range list { if v.ParentId == parentId { childIds = append(childIds, v.SpeechRecognitionMenuId) ids := GetSpeechRecognitionMenuChildrenRecursive(list, v.SpeechRecognitionMenuId) if len(ids) > 0 { childIds = append(childIds, ids...) } } } return childIds } // GetSpeechRecognitionTagMenuChildrenRecursive 递归获取标签目录的子目录集 func GetSpeechRecognitionTagMenuChildrenRecursive(list []*speech_recognition.SpeechRecognitionTagMenu, parentId int) []int { childIds := make([]int, 0) for _, v := range list { if v.ParentId == parentId { childIds = append(childIds, v.SpeechRecognitionTagMenuId) ids := GetSpeechRecognitionTagMenuChildrenRecursive(list, v.SpeechRecognitionTagMenuId) if len(ids) > 0 { childIds = append(childIds, ids...) } } } return childIds } // CheckSpeechRecognitionMenuRemove 校验是否可删除目录 func CheckSpeechRecognitionMenuRemove(menuId int) (result *speech_recognition.SpeechRecognitionMenuRemoveCheckResp, menuIds []int, err error) { menuOb := new(speech_recognition.SpeechRecognitionMenu) result = new(speech_recognition.SpeechRecognitionMenuRemoveCheckResp) // 递归获取目录的子目录集合 menus, e := menuOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "") if e != nil { err = fmt.Errorf("获取语音识别目录列表失败, err: %s", e.Error()) return } childIds := GetSpeechRecognitionMenuChildrenRecursive(menus, menuId) menuIds = make([]int, 0) menuIds = append(menuIds, menuId) if len(childIds) > 0 { menuIds = append(menuIds, childIds...) } // 校验目录下(包含子目录)是否有内容 speechOb := new(speech_recognition.SpeechRecognition) cond := fmt.Sprintf(` AND %s IN (%s)`, speech_recognition.SpeechRecognitionCols.MenuId, utils.GetOrmInReplace(len(menuIds))) pars := make([]interface{}, 0) pars = append(pars, menuIds) count, e := speechOb.GetCountByCondition(cond, pars) if e != nil { err = fmt.Errorf("获取目录下的语音识别数失败, err: %s", e.Error()) return } if count > 0 { result.CheckResult = SpeechMenuCheckRemoveTypeRefused result.Tips = "该分类关联转写文件,删除失败!" return } // 如果无语音识别, 但存在子目录, 则返回第二种提示 if len(childIds) > 0 { result.CheckResult = SpeechMenuCheckRemoveTypeWarning result.Tips = "该分类包含内容为空的子分类" return } // 通过校验 result.Tips = "校验通过,可以删除" return } // CheckSpeechRecognitionTagMenuRemove 校验是否可删除标签目录 func CheckSpeechRecognitionTagMenuRemove(menuId int) (result *speech_recognition.SpeechRecognitionMenuRemoveCheckResp, menuIds []int, err error) { menuOb := new(speech_recognition.SpeechRecognitionTagMenu) result = new(speech_recognition.SpeechRecognitionMenuRemoveCheckResp) // 递归获取目录的子目录集合 menus, e := menuOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "") if e != nil { err = fmt.Errorf("获取标签目录列表失败, err: %s", e.Error()) return } childIds := GetSpeechRecognitionTagMenuChildrenRecursive(menus, menuId) menuIds = make([]int, 0) menuIds = append(menuIds, menuId) if len(childIds) > 0 { menuIds = append(menuIds, childIds...) } // 校验目录下(包含子目录)是否有内容 tagOb := new(speech_recognition.SpeechRecognitionTag) cond := fmt.Sprintf(` AND %s IN (%s)`, speech_recognition.SpeechRecognitionTagCols.MenuId, utils.GetOrmInReplace(len(menuIds))) pars := make([]interface{}, 0) pars = append(pars, menuIds) count, e := tagOb.GetCountByCondition(cond, pars) if e != nil { err = fmt.Errorf("获取目录下的标签数失败, err: %s", e.Error()) return } if count > 0 { result.CheckResult = SpeechMenuCheckRemoveTypeRefused result.Tips = "该分类关联标签,删除失败!" return } // 如果无内容, 但存在子目录, 则返回第二种提示 if len(childIds) > 0 { result.CheckResult = SpeechMenuCheckRemoveTypeWarning result.Tips = "该分类包含内容为空的子分类" return } // 通过校验 result.Tips = "校验通过,可以删除" return } // GetSpeechRecognitionMenuPathRecursive 根据子目录递归获取目录树 func GetSpeechRecognitionMenuPathRecursive(list []*speech_recognition.SpeechRecognitionMenu, menuId int) []*speech_recognition.SpeechRecognitionMenuItem { res := make([]*speech_recognition.SpeechRecognitionMenuItem, 0) for _, v := range list { if v.SpeechRecognitionMenuId == menuId { t := new(speech_recognition.SpeechRecognitionMenuItem) t.UniqueCode = v.UniqueCode t.MenuId = v.SpeechRecognitionMenuId t.MenuName = v.MenuName t.ParentId = v.ParentId t.Level = v.Level t.Sort = v.Sort t.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime) if v.ParentId > 0 { res = GetSpeechRecognitionMenuPathRecursive(list, v.ParentId) } res = append(res, t) } } return res }