yinbangzhong
2024-06-18 500985cf7556808ee42e2e9e3066bb4648a8e534
watch preloads file to autoload
5个文件已修改
313 ■■■■■ 已修改文件
controllers/audio.go 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/process.go 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/audio.go
@@ -7,6 +7,7 @@
    "gorm.io/gorm"
    "io"
    "mime/multipart"
    "net/url"
    "os"
    "path"
    "path/filepath"
@@ -28,14 +29,16 @@
// Upload
// @Tags      音频
// @Summary   上传音频
// @Accept     multipart/form-data
// @Produce   application/json
// @Param files formData []file false "多文件上传"
// @Param file formData []file false "多文件上传"
// @Success   200 {object} util.Response "成功"
// @Router    /api-sa/v1/audio/upload [post]
func (slf AudioCtl) Upload(c *gin.Context) {
    var headers []*multipart.FileHeader
    if len(c.Request.MultipartForm.File["file"]) > 1 {
        headers = c.Request.MultipartForm.File["file"]
    files, _ := c.MultipartForm()
    if len(files.File["file"]) > 1 {
        headers = files.File["file"]
    } else {
        util.ResponseFormat(c, code.RequestParamError, "文件需要一一对应")
        return
@@ -89,7 +92,7 @@
            //解析 交路号:123_公里标:321
            fileds := string(bts)
            arr = strings.Split(fileds, "_")
            if len(arr) > 1 {
            if len(arr) != 2 {
                util.ResponseFormat(c, code.RequestParamError, "文件内容格式不对")
                return
            } else {
@@ -291,8 +294,9 @@
    }
    if params.Filetype == 2 {
        filepath = audio.TxtFilePath
        //设置Content-Type为txt文件类型
        c.Header("Content-Type", "text/plain")
        //设置Content-Type为txt文件类型,避免中文乱码
        c.Header("Content-Type", "text/plain; charset=utf-8")
        c.Header("Content-Transfer-Encoding", "binary")
    }
    if filepath == "" {
        util.ResponseFormat(c, code.InternalError, "查询失败")
@@ -312,7 +316,7 @@
        return
    }
    c.Header("Content-Disposition", "inline; filename="+audio.Name) // 在浏览器中直接打开
    c.Header("Content-Disposition", "inline; filename="+url.PathEscape(audio.Name)) // 在浏览器中直接打开
    c.Header("Content-Length", fmt.Sprint(fileInfo.Size()))
    if _, err := io.Copy(c.Writer, file); err != nil {
docs/docs.go
@@ -117,6 +117,11 @@
                "parameters": [
                    {
                        "type": "integer",
                        "name": "fileType",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "name": "id",
                        "in": "query",
                        "required": true
@@ -196,6 +201,11 @@
                ],
                "summary": "音频详情,含解析结果",
                "parameters": [
                    {
                        "type": "integer",
                        "name": "fileType",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "name": "id",
@@ -457,6 +467,9 @@
        },
        "/api-sa/v1/audio/upload": {
            "post": {
                "consumes": [
                    "multipart/form-data"
                ],
                "produces": [
                    "application/json"
                ],
@@ -472,7 +485,7 @@
                        },
                        "collectionFormat": "csv",
                        "description": "多文件上传",
                        "name": "files",
                        "name": "file",
                        "in": "formData"
                    }
                ],
@@ -697,7 +710,7 @@
                    "type": "integer"
                },
                "station": {
                    "description": "车站",
                    "description": "公里标",
                    "type": "string"
                },
                "trainNumber": {
@@ -822,6 +835,9 @@
                "id"
            ],
            "properties": {
                "fileType": {
                    "type": "integer"
                },
                "id": {
                    "type": "integer"
                }
docs/swagger.json
@@ -106,6 +106,11 @@
                "parameters": [
                    {
                        "type": "integer",
                        "name": "fileType",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "name": "id",
                        "in": "query",
                        "required": true
@@ -185,6 +190,11 @@
                ],
                "summary": "音频详情,含解析结果",
                "parameters": [
                    {
                        "type": "integer",
                        "name": "fileType",
                        "in": "query"
                    },
                    {
                        "type": "integer",
                        "name": "id",
@@ -446,6 +456,9 @@
        },
        "/api-sa/v1/audio/upload": {
            "post": {
                "consumes": [
                    "multipart/form-data"
                ],
                "produces": [
                    "application/json"
                ],
@@ -461,7 +474,7 @@
                        },
                        "collectionFormat": "csv",
                        "description": "多文件上传",
                        "name": "files",
                        "name": "file",
                        "in": "formData"
                    }
                ],
@@ -686,7 +699,7 @@
                    "type": "integer"
                },
                "station": {
                    "description": "车站",
                    "description": "公里标",
                    "type": "string"
                },
                "trainNumber": {
@@ -811,6 +824,9 @@
                "id"
            ],
            "properties": {
                "fileType": {
                    "type": "integer"
                },
                "id": {
                    "type": "integer"
                }
docs/swagger.yaml
@@ -89,7 +89,7 @@
        description: 音频大小
        type: integer
      station:
        description: 车站
        description: 公里标
        type: string
      trainNumber:
        description: 车次
@@ -170,6 +170,8 @@
    type: object
  request.ProcessAudio:
    properties:
      fileType:
        type: integer
      id:
        type: integer
    required:
@@ -268,6 +270,9 @@
    get:
      parameters:
      - in: query
        name: fileType
        type: integer
      - in: query
        name: id
        required: true
        type: integer
@@ -313,6 +318,9 @@
  /api-sa/v1/audio/info:
    get:
      parameters:
      - in: query
        name: fileType
        type: integer
      - in: query
        name: id
        required: true
@@ -483,13 +491,15 @@
      - 音频
  /api-sa/v1/audio/upload:
    post:
      consumes:
      - multipart/form-data
      parameters:
      - collectionFormat: csv
        description: 多文件上传
        in: formData
        items:
          type: file
        name: files
        name: file
        type: array
      produces:
      - application/json
service/process.go
@@ -165,6 +165,10 @@
    if mkdirErr != nil {
        logx.Errorf("function os.MkdirAll() err:%v", mkdirErr)
    }
    mkdirErr1 := os.MkdirAll(conf.LocalConf.StorePath, os.ModePerm)
    if mkdirErr1 != nil {
        logx.Errorf("function os.MkdirAll() err:%v", mkdirErr1)
    }
    //文件夹下新增音频文件时触发
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
@@ -175,6 +179,111 @@
    if err != nil {
        log.Fatal(err)
    }
    audoF := func(eventName, fileName string, audio *models.Audio) bool {
        time.Sleep(time.Second * 1)
        //设置文件访问权限
        err = os.Chmod(eventName, 0777)
        if err != nil {
            logx.Errorf(fmt.Sprintf("%s:%s", eventName, "设置文件权限失败"))
        }
        //校验文件命名
        arr := strings.Split(fileName, "_")
        if len(arr) != 6 {
            logx.Errorf(fmt.Sprintf("%s:%s", fileName, "文件名称错误"))
            return false
        }
        timeStr := arr[4] + strings.Split(arr[5], ".")[0]
        t, err := time.ParseInLocation("20060102150405", timeStr, time.Local)
        if err != nil {
            logx.Errorf(fmt.Sprintf("%s:%s", fileName, "时间格式不对"))
        }
        //查重
        _, err = models.NewAudioSearch().SetName(fileName).First()
        if err != gorm.ErrRecordNotFound {
            logx.Errorf(fmt.Sprintf("%s:%s", fileName, "重复上传"))
            return false
        }
        //将文件移动到uploads文件夹下
        //判断storePath中末尾是否带
        var src string
        if strings.HasSuffix(conf.LocalConf.StorePath, "/") {
            src = conf.LocalConf.StorePath + fileName
        } else {
            src = conf.LocalConf.StorePath + "/" + fileName
        }
        err = os.Rename(eventName, src)
        if err != nil {
            logx.Errorf(fmt.Sprintf("%s:%s", fileName, "移动文件失败"))
            return false
        }
        // 读取文件大小
        fileInfo, err := os.Stat(src)
        if err != nil {
            logx.Errorf(fmt.Sprintf("%s:%s", fileName, "获取文件大小失败"))
            return false
        }
        size := fileInfo.Size()
        fmt.Println("fileName:", fileName, "size:", size, "src1", src)
        audio.Name = fileName
        audio.Size = size
        audio.FilePath = src
        audio.AudioStatus = constvar.AudioStatusUploadOk
        audio.LocomotiveNumber = arr[0]
        audio.TrainNumber = arr[1]
        audio.DriverNumber = arr[2]
        audio.Station = arr[3]
        audio.OccurrenceAt = t
        audio.IsFollowed = 0
        return true
    }
    txtF := func(filePath string, audio *models.Audio) bool {
        fileName := filepath.Base(filePath)
        //读取filepath文件内容到bts
        bts, err := os.ReadFile(filePath)
        if err != nil {
            logx.Errorf(fmt.Sprintf("%s:%s", filePath, "读取txt文件失败"))
            return false
        }
        //解析 交路号:123_公里标:321
        fileds := string(bts)
        arr := strings.Split(fileds, "_")
        if len(arr) != 2 {
            logx.Errorf(fmt.Sprintf("%s:%s", filePath, "读取txt文件内容格式不对"))
            return false
        } else {
            RouteNumber := strings.Split(arr[0], ":")
            KilometerMarker := strings.Split(arr[1], ":")
            if len(RouteNumber) > 1 && len(KilometerMarker) > 1 {
                audio.RouteNumber = RouteNumber[1]
                audio.KilometerMarker = KilometerMarker[1]
            } else {
                logx.Errorf(fmt.Sprintf("%s:%s", filePath, "文件内容格式不对"))
                return false
            }
        }
        var src string
        if strings.HasSuffix(conf.LocalConf.StorePath, "/") {
            src = conf.LocalConf.StorePath + fileName
        } else {
            src = conf.LocalConf.StorePath + "/" + fileName
        }
        err = os.Rename(filePath, src)
        if err != nil {
            logx.Errorf(fmt.Sprintf("%s:%s", fileName, "移动文件失败"))
            return false
        }
        audio.TxtFilePath = src
        return true
    }
    //成对变量
    pair := make(map[string]string)
FOR:
    for {
        select {
@@ -186,98 +295,56 @@
                continue
            }
            if event.Op&fsnotify.Create == fsnotify.Create {
                // 判断文件类型是否为.mp3或.wav
                if filepath.Ext(event.Name) == ".mp3" || filepath.Ext(event.Name) == ".wav" {
                    time.Sleep(time.Second * 1)
                    //设置文件访问权限
                    err = os.Chmod(event.Name, 0777)
                    if err != nil {
                        logx.Errorf(fmt.Sprintf("%s:%s", event.Name, "设置文件权限失败"))
                // 文件名
                fileName := filepath.Base(event.Name)
                //获取不带扩展名的文件名
                name := strings.TrimSuffix(fileName, filepath.Ext(fileName))
                //判断文件在pair中
                if _, ok := pair[name]; !ok {
                    pair[name] = event.Name
                } else {
                    audio := &models.Audio{}
                    isOk := true
                    // 判断文件类型是否为.mp3或.wav
                    if filepath.Ext(event.Name) == ".mp3" || filepath.Ext(event.Name) == ".wav" {
                        isOk = audoF(event.Name, fileName, audio) && txtF(pair[name], audio)
                    }
                    // 文件名
                    fileName := filepath.Base(event.Name)
                    //校验文件命名
                    arr := strings.Split(fileName, "_")
                    if len(arr) != 6 {
                        logx.Errorf(fmt.Sprintf("%s:%s", fileName, "文件名称错误"))
                    if filepath.Ext(event.Name) == ".txt" {
                        isOk = audoF(pair[name], filepath.Base(pair[name]), audio) && txtF(event.Name, audio)
                    }
                    if !isOk {
                        delete(pair, name)
                        continue
                    }
                    timeStr := arr[4] + strings.Split(arr[5], ".")[0]
                    t, err := time.ParseInLocation("20060102150405", timeStr, time.Local)
                    if err != nil {
                        logx.Errorf(fmt.Sprintf("%s:%s", fileName, "时间格式不对"))
                    }
                    //查重
                    _, err = models.NewAudioSearch().SetName(fileName).First()
                    if err != gorm.ErrRecordNotFound {
                        logx.Errorf(fmt.Sprintf("%s:%s", fileName, "重复上传"))
                        continue
                    }
                    //将文件移动到uploads文件夹下
                    //判断storePath中末尾是否带
                    var src string
                    if strings.HasSuffix(conf.LocalConf.StorePath, "/") {
                        src = conf.LocalConf.StorePath + fileName
                    } else {
                        src = conf.LocalConf.StorePath + "/" + fileName
                    }
                    err = os.Rename(event.Name, src)
                    if err != nil {
                        logx.Errorf(fmt.Sprintf("%s:%s", fileName, "移动文件失败"))
                        continue
                    }
                    // 读取文件大小
                    fileInfo, err := os.Stat(src)
                    if err != nil {
                        logx.Errorf(fmt.Sprintf("%s:%s", fileName, "获取文件大小失败"))
                        continue
                    }
                    size := fileInfo.Size()
                    fmt.Println("fileName:", fileName, "size:", size, "src1", src)
                    audio := &models.Audio{
                        Name:             fileName,
                        Size:             size,
                        FilePath:         src,
                        AudioStatus:      constvar.AudioStatusUploadOk,
                        LocomotiveNumber: arr[0],
                        TrainNumber:      arr[1],
                        DriverNumber:     arr[2],
                        Station:          arr[3],
                        OccurrenceAt:     t,
                        IsFollowed:       0,
                    }
                    if err = models.NewAudioSearch().Create(audio); err != nil {
                        logx.Errorf(fmt.Sprintf("%s:%s", fileName, "数据库create失败"))
                        continue
                    }
                    go func() {
                        var trainInfoNames = []string{arr[0], arr[1], arr[3]} //
                        var (
                            info   *models.TrainInfo
                            err    error
                            parent models.TrainInfo
                        )
                        for i := 0; i < 3; i++ {
                            name := trainInfoNames[i]
                            class := constvar.Class(i + 1)
                            info, err = models.NewTrainInfoSearch().SetName(name).SetClass(class).First()
                            if err == gorm.ErrRecordNotFound {
                                info = &models.TrainInfo{
                                    Name:     name,
                                    Class:    class,
                                    ParentID: parent.ID,
                                }
                                _ = models.NewTrainInfoSearch().Create(info)
                            }
                            parent = *info
                    if len(audio.Name) > 0 {
                        if err = models.NewAudioSearch().Create(audio); err != nil {
                            logx.Errorf(fmt.Sprintf("%s:%s", fileName, "数据库create失败"))
                            continue
                        }
                        go func() {
                            var trainInfoNames = []string{audio.LocomotiveNumber, audio.TrainNumber, audio.Station} //
                            var (
                                info   *models.TrainInfo
                                err    error
                                parent models.TrainInfo
                            )
                            for i := 0; i < 3; i++ {
                                name := trainInfoNames[i]
                                class := constvar.Class(i + 1)
                                info, err = models.NewTrainInfoSearch().SetName(name).SetClass(class).First()
                                if err == gorm.ErrRecordNotFound {
                                    info = &models.TrainInfo{
                                        Name:     name,
                                        Class:    class,
                                        ParentID: parent.ID,
                                    }
                                    _ = models.NewTrainInfoSearch().Create(info)
                                }
                                parent = *info
                            }
                    }()
                        }()
                    }
                }
            }
        case err, ok := <-watcher.Errors: