add service
This commit is contained in:
parent
0a94f55363
commit
76fbd6ea7b
|
@ -0,0 +1,115 @@
|
|||
package apis
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/go-playground/locales/en"
|
||||
"github.com/go-playground/locales/zh"
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
zht "github.com/go-playground/validator/v10/translations/zh"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type errorCode int
|
||||
|
||||
const (
|
||||
Success errorCode = 200
|
||||
Failed errorCode = 500
|
||||
ParamError errorCode = 400
|
||||
NotFound errorCode = 404
|
||||
UnAuthorized errorCode = 401
|
||||
)
|
||||
|
||||
var codeMsg = map[errorCode]string{
|
||||
Success: "正常",
|
||||
Failed: "系统异常",
|
||||
ParamError: "参数错误",
|
||||
NotFound: "记录不存在",
|
||||
UnAuthorized: "未授权",
|
||||
}
|
||||
|
||||
type Api struct {
|
||||
Page int
|
||||
PageSize int
|
||||
}
|
||||
|
||||
type Pagination struct {
|
||||
List interface{} `json:"list"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
}
|
||||
|
||||
var BaseApi = &Api{}
|
||||
|
||||
var trans ut.Translator
|
||||
|
||||
// 注册validator中文翻译
|
||||
func init() {
|
||||
uni := ut.New(en.New(), zh.New())
|
||||
trans, _ = uni.GetTranslator("zh")
|
||||
validate := binding.Validator.Engine().(*validator.Validate)
|
||||
_ = zht.RegisterDefaultTranslations(validate, trans)
|
||||
}
|
||||
|
||||
func translate(err error) string {
|
||||
errors, ok := err.(validator.ValidationErrors)
|
||||
if !ok {
|
||||
return err.Error()
|
||||
}
|
||||
result := make([]string, 0)
|
||||
for _, err := range errors {
|
||||
errMsg := err.Translate(trans)
|
||||
if errMsg == "" {
|
||||
continue
|
||||
}
|
||||
result = append(result, errMsg)
|
||||
}
|
||||
return strings.Join(result, ",")
|
||||
}
|
||||
|
||||
func (r *Api) ParsePage(ctx *gin.Context) {
|
||||
page, err := strconv.Atoi(ctx.Query("page"))
|
||||
if err != nil || page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
pageSize, err := strconv.Atoi(ctx.Query("page_size"))
|
||||
if err != nil || pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
if pageSize > 1000 {
|
||||
pageSize = 1000
|
||||
}
|
||||
r.Page = page
|
||||
r.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (*Api) Index(ctx *gin.Context) {
|
||||
ctx.String(http.StatusOK, "Gen Web")
|
||||
}
|
||||
|
||||
func (*Api) Success(ctx *gin.Context, msg string, data interface{}) {
|
||||
ctx.JSON(http.StatusOK, gin.H{
|
||||
"code": Success,
|
||||
"msg": msg,
|
||||
"data": data,
|
||||
"trace_id": ctx.GetString("trace_id"),
|
||||
})
|
||||
}
|
||||
|
||||
func (*Api) Failed(ctx *gin.Context, code errorCode, msg string) {
|
||||
errMsg := codeMsg[code] + ": " + msg
|
||||
ctx.AbortWithStatusJSON(http.StatusOK, gin.H{
|
||||
"code": code,
|
||||
"msg": errMsg,
|
||||
"data": nil,
|
||||
"trace_id": ctx.GetString("trace_id"),
|
||||
})
|
||||
if code != Success {
|
||||
ctx.Set("error_code", int(code))
|
||||
ctx.Set("error_msg", msg)
|
||||
}
|
||||
}
|
|
@ -2,12 +2,24 @@ package apis
|
|||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
json "github.com/json-iterator/go"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/common"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/model"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/service"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type datasetApi struct {
|
||||
*Api
|
||||
*service.DatasetService
|
||||
}
|
||||
|
||||
var DatasetApi = datasetApi{
|
||||
Api: BaseApi,
|
||||
DatasetService: service.NewDatasetService(),
|
||||
}
|
||||
|
||||
func GetDatasetPublic(ctx *gin.Context) {
|
||||
var param model.DatasetParam
|
||||
if err := ctx.BindJSON(¶m); err != nil {
|
||||
|
@ -16,13 +28,17 @@ func GetDatasetPublic(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
if token == "" {
|
||||
model.Response(ctx, 401, "access_token为必填字段", nil)
|
||||
return
|
||||
}
|
||||
|
||||
reqUrl := common.OPENIPREFIX + common.DATASETPUBLIC
|
||||
|
||||
var resp model.Dataset
|
||||
|
||||
req := common.GetRestyRequest(common.TIMEOUT)
|
||||
_, err := req.
|
||||
res, err := req.
|
||||
SetQueryParam(common.ACCESSTOKEN, token).
|
||||
SetQueryParam("type", strconv.Itoa(param.Type)).
|
||||
SetQueryParam("q", param.Q).
|
||||
|
@ -37,6 +53,12 @@ func GetDatasetPublic(ctx *gin.Context) {
|
|||
model.Response(ctx, 500, common.INVOKEERROR, err)
|
||||
return
|
||||
}
|
||||
if res != nil {
|
||||
if res.StatusCode() == 401 {
|
||||
model.Response(ctx, 401, "access_token值无效请检查", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if resp.Code != 0 {
|
||||
model.Response(ctx, 500, common.INVOKEERROR, err)
|
||||
|
@ -86,7 +108,8 @@ func ExportDataset(ctx *gin.Context) {
|
|||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
|
||||
func CreateDataset(ctx *gin.Context) {
|
||||
func (r datasetApi) CreateDataset(ctx *gin.Context) {
|
||||
var respErr model.RespErr
|
||||
var param model.CreateDatasetParam
|
||||
if err := ctx.BindJSON(¶m); err != nil {
|
||||
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, err)
|
||||
|
@ -100,7 +123,7 @@ func CreateDataset(ctx *gin.Context) {
|
|||
var resp model.CreateDataset
|
||||
|
||||
req := common.GetRestyRequest(common.TIMEOUT)
|
||||
_, err := req.
|
||||
res, err := req.
|
||||
SetQueryParam(common.ACCESSTOKEN, token).
|
||||
SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
|
@ -110,7 +133,7 @@ func CreateDataset(ctx *gin.Context) {
|
|||
"task": param.Task,
|
||||
"description": param.Description,
|
||||
}).
|
||||
SetResult(&resp).
|
||||
SetResult(&resp).SetError(&respErr).
|
||||
Post(reqUrl)
|
||||
|
||||
if err != nil {
|
||||
|
@ -118,10 +141,64 @@ func CreateDataset(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
if res != nil {
|
||||
if res.StatusCode() != 200 {
|
||||
errStr := json.Get(res.Body(), "message").ToString()
|
||||
model.Response(ctx, 500, errStr, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if resp.Code != 0 {
|
||||
model.Response(ctx, 500, resp.Message, nil)
|
||||
return
|
||||
}
|
||||
|
||||
//返回创建数据集的id
|
||||
ld := model.DatasetParam{
|
||||
UserName: param.UserName,
|
||||
RepoName: param.RepoName,
|
||||
Type: -1,
|
||||
}
|
||||
datasets, err := r.DatasetService.ListDatasets(token, &ld)
|
||||
if err != nil {
|
||||
model.Response(ctx, 500, common.INVOKEERROR, err)
|
||||
}
|
||||
resp.DatasetId = datasets.Data[0].Id
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
|
||||
func (r datasetApi) ListDatasets(ctx *gin.Context) {
|
||||
var param model.DatasetParam
|
||||
if err := ctx.ShouldBind(¶m); err != nil {
|
||||
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, translate(err))
|
||||
return
|
||||
}
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
if resp, err := r.DatasetService.ListDatasets(token, ¶m); err != nil {
|
||||
r.Failed(ctx, Failed, err.Error())
|
||||
} else {
|
||||
r.Success(ctx, "success", resp.Data)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r datasetApi) UploadFileDatasets(ctx *gin.Context) {
|
||||
// 绑定表单参数到结构体
|
||||
var param model.DatasetUploadFileParam
|
||||
if err := ctx.ShouldBind(¶m); err != nil {
|
||||
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, translate(err))
|
||||
return
|
||||
}
|
||||
// 获取上传的文件
|
||||
fileHeader, err := ctx.FormFile("file")
|
||||
if err != nil {
|
||||
model.Response(ctx, 500, common.INVOKEERROR, err)
|
||||
return
|
||||
}
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
if resp, err := r.DatasetService.UploadFile(param, token, fileHeader); err != nil {
|
||||
model.Response(ctx, 500, err.Error(), resp)
|
||||
} else {
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@ package apis
|
|||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
json "github.com/json-iterator/go"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/common"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/model"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/service"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -12,6 +14,16 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
type modelApi struct {
|
||||
*Api
|
||||
*service.ModelService
|
||||
}
|
||||
|
||||
var ModelApi = modelApi{
|
||||
Api: BaseApi,
|
||||
ModelService: service.NewModelService(),
|
||||
}
|
||||
|
||||
func CreateModel(ctx *gin.Context) {
|
||||
var param model.CreateModelParam
|
||||
if err := ctx.BindJSON(¶m); err != nil {
|
||||
|
@ -149,7 +161,7 @@ func CreateLocalModel(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req := common.GetRestyRequest(common.TIMEOUT)
|
||||
_, err := req.
|
||||
res, err := req.
|
||||
SetQueryParam(common.ACCESSTOKEN, token).
|
||||
SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
|
@ -170,6 +182,13 @@ func CreateLocalModel(ctx *gin.Context) {
|
|||
model.Response(ctx, 500, common.INVOKEERROR, err)
|
||||
return
|
||||
}
|
||||
if res != nil {
|
||||
if res.StatusCode() != 200 {
|
||||
errStr := json.Get(res.Body(), "message").ToString()
|
||||
model.Response(ctx, 500, errStr, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if resp.Code != "0" {
|
||||
model.Response(ctx, 500, resp.Msg, nil)
|
||||
|
@ -332,3 +351,56 @@ func CompleteMultipart(ctx *gin.Context) {
|
|||
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
|
||||
func (r modelApi) UploadFile2Model(ctx *gin.Context) {
|
||||
// 设置最大请求体大小(100 个文件 * 512 MiB = 51.2 GiB)
|
||||
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 100<<20*512)
|
||||
|
||||
// 解析 multipart form
|
||||
form, err := ctx.MultipartForm()
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": "文件上传失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// 获取所有文件
|
||||
files := form.File["files"]
|
||||
|
||||
// 检查文件数量
|
||||
if len(files) > 100 {
|
||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": "单次最多上传 100 个文件"})
|
||||
return
|
||||
}
|
||||
|
||||
// 检查文件名长度和文件大小
|
||||
for _, file := range files {
|
||||
// 检查文件名长度
|
||||
if len(file.Filename) > 128 {
|
||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": "文件名不能超过 128 个字符"})
|
||||
return
|
||||
}
|
||||
|
||||
// 检查单个文件大小(512 MiB)
|
||||
if file.Size > 512<<20 {
|
||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": "单个文件不能超过 512 MiB"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定表单参数到结构体
|
||||
var param model.ModelUploadFileParam
|
||||
if err := ctx.ShouldBind(¶m); err != nil {
|
||||
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, translate(err))
|
||||
return
|
||||
}
|
||||
|
||||
// 获取 token
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
|
||||
// 调用服务层处理文件上传
|
||||
if resp, err := r.ModelService.UploadFile(param, token, files); err != nil {
|
||||
model.Response(ctx, http.StatusInternalServerError, err.Error(), resp)
|
||||
} else {
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
}
|
||||
|
|
64
apis/repo.go
64
apis/repo.go
|
@ -4,9 +4,20 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/common"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/model"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/service"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type repoApi struct {
|
||||
*Api
|
||||
*service.RepoService
|
||||
}
|
||||
|
||||
var RepoApi = repoApi{
|
||||
Api: BaseApi,
|
||||
RepoService: service.NewRepoService(),
|
||||
}
|
||||
|
||||
func GetRepos(ctx *gin.Context) {
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
|
||||
|
@ -55,3 +66,56 @@ func CreateRepo(ctx *gin.Context) {
|
|||
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
|
||||
// UploadFile2Repo 上传
|
||||
func (r repoApi) UploadFile2Repo(ctx *gin.Context) {
|
||||
var param model.RepoUploadFileParam
|
||||
if err := ctx.BindJSON(¶m); err != nil {
|
||||
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, translate(err))
|
||||
return
|
||||
}
|
||||
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
// 调用服务层处理文件上传
|
||||
if resp, err := r.RepoService.UploadFile(token, param); err != nil {
|
||||
model.Response(ctx, http.StatusInternalServerError, err.Error(), resp)
|
||||
} else {
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateFile2Repo 更新项目文件内容
|
||||
func (r repoApi) UpdateFile2Repo(ctx *gin.Context) {
|
||||
var param model.RepoUpdateFileParam
|
||||
if err := ctx.BindJSON(¶m); err != nil {
|
||||
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, translate(err))
|
||||
return
|
||||
}
|
||||
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
if resp, err := r.RepoService.UpdateFile(token, param); err != nil {
|
||||
model.Response(ctx, http.StatusInternalServerError, err.Error(), resp)
|
||||
} else {
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
}
|
||||
|
||||
// QueryRepoFilesContent 查询文件详情
|
||||
func (r repoApi) QueryRepoFilesContent(ctx *gin.Context) {
|
||||
var param model.QueryFilesContentParam
|
||||
if err := ctx.ShouldBind(¶m); err != nil {
|
||||
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, translate(err))
|
||||
return
|
||||
}
|
||||
token := ctx.Query(common.ACCESSTOKEN)
|
||||
if token == "" {
|
||||
model.Response(ctx, 401, "access_token为必填字段", nil)
|
||||
return
|
||||
}
|
||||
if resp, err := r.RepoService.QueryFilesContent(token, ¶m); err != nil {
|
||||
model.Response(ctx, 500, err.Error(), nil)
|
||||
} else {
|
||||
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
3
app.go
3
app.go
|
@ -1,10 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/initialize"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/router"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//初始化公共配置
|
||||
initialize.InitConfig()
|
||||
rt, _ := router.Create(nil)
|
||||
_ = rt.Run(":2024")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/model"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
NoRedirectClient *resty.Client
|
||||
RestyClient *resty.Client
|
||||
HttpClient *http.Client
|
||||
)
|
||||
var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
|
||||
var DefaultTimeout = time.Second * 300
|
||||
|
||||
func InitClient() {
|
||||
NoRedirectClient = resty.New().SetRedirectPolicy(
|
||||
resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}),
|
||||
).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
||||
NoRedirectClient.SetHeader("user-agent", UserAgent)
|
||||
|
||||
RestyClient = NewRestyClient()
|
||||
HttpClient = NewHttpClient()
|
||||
}
|
||||
|
||||
func NewRestyClient() *resty.Client {
|
||||
client := resty.New().
|
||||
SetHeader("user-agent", UserAgent).
|
||||
SetRetryCount(3).
|
||||
SetRetryResetReaders(true).
|
||||
SetTimeout(DefaultTimeout).
|
||||
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
||||
return client
|
||||
}
|
||||
|
||||
func NewHttpClient() *http.Client {
|
||||
return &http.Client{
|
||||
Timeout: time.Hour * 48,
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func Request(url string, method string, callback ReqCallback) ([]byte, error) {
|
||||
respErr := &model.RespErr{}
|
||||
req := RestyClient.R().
|
||||
SetHeaders(map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}).
|
||||
SetError(&respErr)
|
||||
|
||||
if callback != nil {
|
||||
callback(req)
|
||||
}
|
||||
|
||||
res, err := req.Execute(method, OPENIPREFIX+url)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if respErr.Message != "" {
|
||||
return nil, errors.New(respErr.Message)
|
||||
}
|
||||
|
||||
if res.StatusCode() != http.StatusOK && res.StatusCode() != http.StatusCreated {
|
||||
return nil, errors.New(fmt.Sprintf("msg: %s, status: %d", res.String(), res.StatusCode()))
|
||||
}
|
||||
|
||||
return res.Body(), nil
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package common
|
||||
|
||||
const (
|
||||
MaxChunkSize int64 = 1024 * 1024 * 64 //64MB
|
||||
|
||||
QUESTION_MARK = "?"
|
||||
TIMEOUT = 10
|
||||
OPENIPREFIX = "https://openi.pcl.ac.cn"
|
||||
|
@ -10,6 +12,7 @@ const (
|
|||
|
||||
// repo
|
||||
REPO = "/api/v1/user/repos"
|
||||
RepoFile = "/api/v1/repos/{username}/{reponame}/contents/{filepath}" //上传文件到项目中、修改项目中的文件内容
|
||||
|
||||
// image
|
||||
IMAGERECOMMENDED = "/api/v1/images/recommend"
|
||||
|
@ -22,7 +25,14 @@ const (
|
|||
DATASETPUBLIC = "/api/v1/datasets/{username}/{reponame}/public_datasets" //查询公开数据集
|
||||
DATASETFAVORITE = "/api/v1/datasets/{username}/{reponame}/my_favorite" //查询我收藏的数据集
|
||||
DATASETEXISTEXPORT = "/api/v1/datasets/{username}/{reponame}/model/export_exist_dataset" //将用户选择的文件从训练任务结果中导出到数据集中 POST请求
|
||||
DATASETCREATE = "/api/v1/datasets/{username}/{reponame}/create"
|
||||
DATASETCREATE = "/api/v1/datasets/{username}/{reponame}/create" //
|
||||
BaseDatasetsUrl = "/api/v1/datasets/{username}/{reponame}" //数据集列表 //数据集基本接口
|
||||
|
||||
// datasets upload
|
||||
GetChunksUrl = "/api/v1/attachments/get_chunks" //获取当前需要上传文件的chunk信息
|
||||
NewMultipartUrl = "/api/v1/attachments/new_multipart" //获取文件上传的需要的信息
|
||||
GetMultipartUrl = "/api/v1/attachments/get_multipart_url" //获取文件上传的地址
|
||||
CompleteMultipartUrl = "/api/v1/attachments/complete_multipart" //完成上传接口 //上传文件到数据集
|
||||
|
||||
// task
|
||||
TASKCREATIONREQUIRED = "/api/v1/{username}/{reponame}/ai_task/creation/required" // 查询创建任务所需资源接口
|
||||
|
@ -39,6 +49,9 @@ const (
|
|||
MODELCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_new_model" //模型新增接口
|
||||
MODELGETBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byId" //根据模型ID查询模型信息接口
|
||||
MODELDOWNLOADBYID = "/api/v1/repos/{username}/{reponame}/modelmanage/downloadall"
|
||||
QUERYMODELBYNAME = "/api/v1/repos/{username}/{reponame}/modelmanage/query_model_byName" //根据模型名称查询模型
|
||||
PageModel = "/api/v1/repos/{username}/{reponame}/modelmanage/show_model_api" //分页查询模型
|
||||
UploadFileToModel = "" //上传文件到模型记录中
|
||||
|
||||
// model local create
|
||||
MODELLOCALCREATE = "/api/v1/repos/{username}/{reponame}/modelmanage/create_local_model" //创建一条本地模型记录
|
||||
|
@ -55,6 +68,6 @@ const (
|
|||
// error
|
||||
const (
|
||||
INVOKEERROR = "failed to invoke"
|
||||
INVALIDPARAMS = "invalid request params"
|
||||
INVALIDPARAMS = "invalid Request params"
|
||||
NOTFOUND = "not found"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package common
|
||||
|
||||
import "github.com/go-resty/resty/v2"
|
||||
|
||||
type Json map[string]interface{}
|
||||
|
||||
type TokenResp struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
type ReqCallback func(req *resty.Request)
|
|
@ -1,7 +1,12 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -10,3 +15,19 @@ func GetRestyRequest(timeoutSeconds int64) *resty.Request {
|
|||
request := client.R()
|
||||
return request
|
||||
}
|
||||
|
||||
func GetFileMd5(file multipart.File) (string, error) {
|
||||
hash := md5.New()
|
||||
if _, err := io.Copy(hash, file); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 计算MD5并转换为16进制字符串
|
||||
md5Bytes := hash.Sum(nil)
|
||||
md5Str := hex.EncodeToString(md5Bytes)
|
||||
return md5Str, nil
|
||||
}
|
||||
|
||||
func Bool2String(b bool) string {
|
||||
return strconv.FormatBool(b)
|
||||
}
|
||||
|
|
7
go.mod
7
go.mod
|
@ -3,19 +3,20 @@ module gitlink.org.cn/JointCloud/pcm-openi
|
|||
go 1.22.0
|
||||
|
||||
require (
|
||||
code.gitea.io/gitea/modules/structs v0.0.0-20190610152049-835b53fc259c
|
||||
github.com/gin-gonic/gin v1.9.0
|
||||
github.com/go-playground/locales v0.14.1
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/go-resty/resty/v2 v2.10.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.8.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/goccy/go-json v0.10.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
code.gitea.io/gitea/modules/structs v0.0.0-20190610152049-835b53fc259c h1:WwxK+8qmKYgU2pfcbCeRSqKwEPeHnW/sfmNc6pjLZC8=
|
||||
code.gitea.io/gitea/modules/structs v0.0.0-20190610152049-835b53fc259c/go.mod h1:e/Ukqo229PbsSEymXfLWmNz4g04hwnFml5lW6U+0Azs=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
|
||||
github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
|
||||
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/go-resty/resty/v2 v2.10.0 h1:Qla4W/+TMmv0fOeeRqzEpXPLfTUnR5HZ1+lGs+CkiCo=
|
||||
github.com/go-resty/resty/v2 v2.10.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
|
||||
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
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.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
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/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
|
||||
github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
|
@ -0,0 +1,9 @@
|
|||
package initialize
|
||||
|
||||
import (
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/common"
|
||||
)
|
||||
|
||||
func InitConfig() {
|
||||
common.InitClient()
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package model
|
||||
|
||||
type DatasetParam struct {
|
||||
UserName string `json:"username"`
|
||||
RepoName string `json:"reponame"`
|
||||
Type int `json:"type"` //type=0 GPU环境可用数据集;type=1 NPU环境可用数据集。
|
||||
Q string `json:"q,omitempty"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
UserName string `json:"username" form:"username"`
|
||||
RepoName string `json:"reponame" form:"reponame"`
|
||||
Type int `json:"type" form:"type"` //type=0 GPU环境可用数据集;type=1 NPU环境可用数据集。
|
||||
Q string `json:"q,omitempty" form:"q"`
|
||||
Page int `json:"page" form:"page"`
|
||||
PageSize int `json:"pageSize" form:"pageSize"`
|
||||
}
|
||||
|
||||
type Dataset struct {
|
||||
|
@ -81,4 +81,73 @@ type CreateDatasetParam struct {
|
|||
type CreateDataset struct {
|
||||
Code int `json:"Code"`
|
||||
Message string `json:"Message"`
|
||||
DatasetId int `json:"DatasetId"`
|
||||
}
|
||||
|
||||
type DatasetUploadFileParam struct {
|
||||
UserName string `json:"username" form:"username" binding:"required"`
|
||||
RepoName string `json:"repoName" form:"repoName" binding:"required"`
|
||||
DatasetId string `json:"datasetId" form:"datasetId" binding:"required"`
|
||||
CustomName string `json:"customName" form:"customName" binding:"required"` //自定义名称
|
||||
}
|
||||
|
||||
type GetChunksResp struct {
|
||||
AttachID string `json:"attachID"`
|
||||
Chunks string `json:"chunks"`
|
||||
DatasetID string `json:"datasetID"`
|
||||
DatasetName string `json:"datasetName"`
|
||||
ModelName string `json:"modelName"`
|
||||
Modeluuid string `json:"modeluuid"`
|
||||
FileName string `json:"fileName"`
|
||||
UploadID string `json:"uploadID"`
|
||||
Uploaded string `json:"uploaded"`
|
||||
Uuid string `json:"uuid"`
|
||||
}
|
||||
|
||||
type NewMultipartResp struct {
|
||||
ResultCode string `json:"result_code"`
|
||||
UploadID string `json:"uploadID"`
|
||||
Uuid string `json:"uuid"`
|
||||
}
|
||||
type GetMultipartUrlResp struct {
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
type CompleteMultipartResp struct {
|
||||
Msg string `json:"msg"`
|
||||
ResultCode string `json:"result_code"`
|
||||
}
|
||||
|
||||
type ListDatasetsResp struct {
|
||||
Code int `json:"code"`
|
||||
Data []struct {
|
||||
Id int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Status int `json:"status"`
|
||||
Category string `json:"category"`
|
||||
Description string `json:"description"`
|
||||
DownloadTimes int `json:"downloadTimes"`
|
||||
UseCount int `json:"useCount"`
|
||||
NumStars int `json:"numStars"`
|
||||
Recommend bool `json:"recommend"`
|
||||
License string `json:"license"`
|
||||
Task string `json:"task"`
|
||||
ReleaseId int `json:"releaseId"`
|
||||
UserId int `json:"userId"`
|
||||
RepoId int `json:"repoId"`
|
||||
Repo struct {
|
||||
OwnerName string `json:"ownerName"`
|
||||
Name string `json:"name"`
|
||||
} `json:"repo"`
|
||||
CreatedUnix int `json:"createdUnix"`
|
||||
UpdatedUnix int `json:"updatedUnix"`
|
||||
Attachments interface{} `json:"attachments"`
|
||||
} `json:"data"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type Err struct {
|
||||
DocumentationUrl string `json:"documentation_url"`
|
||||
Errors interface{} `json:"errors"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
|
|
@ -22,3 +22,8 @@ type Error struct {
|
|||
// example: you need to provide a valid access token or user credentials to access this api
|
||||
ErrorDescription string `json:"errorDescription"`
|
||||
}
|
||||
|
||||
type RespErr struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@ type GetByIdModelParam struct {
|
|||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type QueryModelParam struct {
|
||||
UserName string `json:"username"`
|
||||
RepoName string `json:"reponame"`
|
||||
}
|
||||
|
||||
type DownloadByIdParam struct {
|
||||
UserName string `json:"username"`
|
||||
RepoName string `json:"reponame"`
|
||||
|
@ -85,6 +90,7 @@ type CreateLocalModelParam struct {
|
|||
IsPrivate bool `json:"isPrivate,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Type int `json:"type"`
|
||||
License string `json:"license"`
|
||||
}
|
||||
|
||||
type CreateLocalModel struct {
|
||||
|
@ -159,3 +165,59 @@ type CompleteMultipartParam struct {
|
|||
type CompleteMultipart struct {
|
||||
Code string `json:"result_code"`
|
||||
}
|
||||
|
||||
type ListModelResp struct {
|
||||
Count int `json:"count"`
|
||||
Data []struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ModelType int `json:"modelType"`
|
||||
Version string `json:"version"`
|
||||
VersionCount int `json:"versionCount"`
|
||||
New int `json:"new"`
|
||||
Type int `json:"type"`
|
||||
Size int `json:"size"`
|
||||
Description string `json:"description"`
|
||||
Label string `json:"label"`
|
||||
Path string `json:"path"`
|
||||
DownloadCount int `json:"downloadCount"`
|
||||
Engine int `json:"engine"`
|
||||
ComputeResource string `json:"computeResource"`
|
||||
Status int `json:"status"`
|
||||
StatusDesc string `json:"statusDesc"`
|
||||
Accuracy string `json:"accuracy"`
|
||||
AttachmentId string `json:"attachmentId"`
|
||||
RepoId int `json:"repoId"`
|
||||
CodeBranch string `json:"codeBranch"`
|
||||
CodeCommitID string `json:"codeCommitID"`
|
||||
Recommend int `json:"recommend"`
|
||||
UserId int `json:"userId"`
|
||||
IsPrivate bool `json:"isPrivate"`
|
||||
UserName string `json:"userName"`
|
||||
UserRelAvatarLink string `json:"userRelAvatarLink"`
|
||||
TrainTaskInfo string `json:"trainTaskInfo"`
|
||||
CreatedUnix int `json:"createdUnix"`
|
||||
UpdatedUnix int `json:"updatedUnix"`
|
||||
IsCanOper bool `json:"isCanOper"`
|
||||
IsCanDelete bool `json:"isCanDelete"`
|
||||
IsCanDownload bool `json:"isCanDownload"`
|
||||
IsCollected bool `json:"isCollected"`
|
||||
RepoName string `json:"repoName"`
|
||||
RepoDisplayName string `json:"repoDisplayName"`
|
||||
RepoOwnerName string `json:"repoOwnerName"`
|
||||
DatasetInfo interface{} `json:"datasetInfo"`
|
||||
ReferenceCount int `json:"referenceCount"`
|
||||
CollectedCount int `json:"collectedCount"`
|
||||
ModelFileList interface{} `json:"modelFileList"`
|
||||
OnlineInfo interface{} `json:"onlineInfo"`
|
||||
UsedCloudbrain interface{} `json:"usedCloudbrain"`
|
||||
HasOnlineUrl int `json:"hasOnlineUrl"`
|
||||
License string `json:"license"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
type ModelUploadFileParam struct {
|
||||
UserName string `json:"username" form:"username" binding:"required"`
|
||||
RepoName string `json:"repoName" form:"repoName" binding:"required"`
|
||||
ModelUuid string `json:"modelUuid" form:"modelUuid" binding:"required"`
|
||||
}
|
||||
|
|
|
@ -140,3 +140,55 @@ type RepoCreateParam struct {
|
|||
Private bool `json:"private"`
|
||||
Readme string `json:"readme"`
|
||||
}
|
||||
|
||||
type RepoUploadFileParam struct {
|
||||
UserName string `json:"username" form:"username" binding:"required"`
|
||||
RepoName string `json:"repoName" form:"repoName" binding:"required"`
|
||||
FileContents []*FileContent `json:"fileContents" form:"filePath" binding:"required"`
|
||||
}
|
||||
|
||||
type FileContent struct {
|
||||
FilePath string `json:"filePath" form:"filePath" binding:"required"`
|
||||
Content string `json:"content" form:"content" binding:"required"`
|
||||
FileSha string `json:"fileSha" form:"content"`
|
||||
}
|
||||
|
||||
type RepoUpdateFileParam struct {
|
||||
UserName string `json:"username" form:"username" binding:"required"`
|
||||
RepoName string `json:"repoName" form:"repoName" binding:"required"`
|
||||
FileContents []*FileContent `json:"fileContents" form:"filePath" binding:"required"`
|
||||
}
|
||||
|
||||
type FileContentErr struct {
|
||||
Message string `json:"message"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
type QueryFilesContentParam struct {
|
||||
UserName string `json:"username" form:"username" binding:"required"`
|
||||
RepoName string `json:"repoName" form:"repoName" binding:"required"`
|
||||
FilePath string `json:"filePath" form:"filePath"`
|
||||
}
|
||||
|
||||
type FileContentResp struct {
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Sha string `json:"sha"`
|
||||
Type string `json:"type"`
|
||||
Size int `json:"size"`
|
||||
Encoding string `json:"encoding"`
|
||||
Content string `json:"content"`
|
||||
Target interface{} `json:"target"`
|
||||
Url string `json:"url"`
|
||||
HtmlUrl string `json:"html_url"`
|
||||
GitUrl string `json:"git_url"`
|
||||
DownloadUrl string `json:"download_url"`
|
||||
SubmoduleGitUrl interface{} `json:"submodule_git_url"`
|
||||
Links struct {
|
||||
Self string `json:"self"`
|
||||
Git string `json:"git"`
|
||||
Html string `json:"html"`
|
||||
} `json:"_links"`
|
||||
Language string `json:"language"`
|
||||
FileType string `json:"fileType"`
|
||||
}
|
||||
|
|
|
@ -30,19 +30,26 @@ func Create(conf *config.Configuration) (*gin.Engine, error) {
|
|||
user.GET("", apis.GetUserInfo)
|
||||
|
||||
//repo
|
||||
repoApi := apis.RepoApi
|
||||
repo := v1.Group("user")
|
||||
repo.GET("/repos", apis.GetRepos)
|
||||
repo.POST("/repos", apis.CreateRepo)
|
||||
repo.POST("/repos/uploadFile", repoApi.UploadFile2Repo) //上传文件到项目中
|
||||
repo.PUT("/repos/updateFile", repoApi.UpdateFile2Repo) //修改项目文件
|
||||
repo.GET("/repos/queryFileContent", repoApi.QueryRepoFilesContent) //查询项目文件内容
|
||||
|
||||
//image
|
||||
image := v1.Group("image")
|
||||
image.GET("/recommend", apis.GetImageRecommended)
|
||||
|
||||
//datasets
|
||||
datasetsApi := apis.DatasetApi
|
||||
datasets := v1.Group("datasets")
|
||||
datasets.POST("/create", apis.CreateDataset)
|
||||
datasets.POST("/create", datasetsApi.CreateDataset)
|
||||
datasets.GET("/public", apis.GetDatasetPublic)
|
||||
datasets.POST("/export", apis.ExportDataset) //将用户选择的文件从训练任务结果中导出到数据集中
|
||||
datasets.POST("/uploadFile", datasetsApi.UploadFileDatasets) //上传文件到数据集中
|
||||
datasets.GET("/listDatasets", datasetsApi.ListDatasets) //查询数据集列表
|
||||
|
||||
//tasks
|
||||
task := v1.Group("task")
|
||||
|
@ -57,10 +64,12 @@ func Create(conf *config.Configuration) (*gin.Engine, error) {
|
|||
task.GET("/downloadAll", apis.DownloadAllById)
|
||||
|
||||
//model
|
||||
modelApi := apis.ModelApi
|
||||
model := v1.Group("model")
|
||||
model.POST("/create", apis.CreateModel)
|
||||
model.GET("/getById", apis.GetModelById)
|
||||
model.GET("/download", apis.DownloadById)
|
||||
model.POST("/uploadFile", modelApi.UploadFile2Model)
|
||||
|
||||
// model local create
|
||||
model.POST("/localCreate", apis.CreateLocalModel)
|
||||
|
|
|
@ -0,0 +1,267 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
json "github.com/json-iterator/go"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/common"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/model"
|
||||
"io"
|
||||
"math"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type DatasetService struct {
|
||||
}
|
||||
|
||||
func NewDatasetService() *DatasetService {
|
||||
return &DatasetService{}
|
||||
}
|
||||
|
||||
func (r DatasetService) ListDatasets(token string, param *model.DatasetParam) (resp *model.ListDatasetsResp, err error) {
|
||||
respErr := &model.RespErr{}
|
||||
_, err = common.Request(common.BaseDatasetsUrl, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
SetQueryParams(map[string]string{
|
||||
common.ACCESSTOKEN: token,
|
||||
"type": strconv.Itoa(param.Type),
|
||||
"q": param.Q,
|
||||
"page": strconv.Itoa(param.Page),
|
||||
"pageSize": strconv.Itoa(param.PageSize),
|
||||
}).SetError(&respErr).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListDatasetCurrentDatasets 查询当前项目的数据集接口
|
||||
func (r DatasetService) ListDatasetCurrentDatasets(token string, param *model.DatasetParam) (resp *model.Dataset, err error) {
|
||||
respErr := &model.RespErr{}
|
||||
_, err = common.Request(common.DATASETCURRENT, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
SetQueryParams(map[string]string{
|
||||
common.ACCESSTOKEN: token,
|
||||
"type": strconv.Itoa(param.Type),
|
||||
"q": param.Q,
|
||||
"page": strconv.Itoa(param.Page),
|
||||
"pageSize": strconv.Itoa(param.PageSize),
|
||||
}).SetError(&respErr).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r DatasetService) getChunks(token, md5, fileName, dataType, datasetId, size string) (resp *model.GetChunksResp, err error) {
|
||||
_, err = common.Request(common.GetChunksUrl, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetQueryParams(map[string]string{
|
||||
"md5": md5,
|
||||
"file_name": fileName,
|
||||
"type": dataType,
|
||||
"dataset_id": datasetId,
|
||||
"size": size,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// newMultipart 开启一个本地数据集文件上传
|
||||
func (r DatasetService) newMultipart(token, totalChunkCounts, md5, fileName, dataType, datasetId, size string) (resp *model.NewMultipartResp, err error) {
|
||||
res, err := common.Request(common.NewMultipartUrl, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetQueryParams(map[string]string{
|
||||
"totalChunkCounts": totalChunkCounts,
|
||||
"type": dataType,
|
||||
"size": size,
|
||||
"md5": md5,
|
||||
"file_name": fileName,
|
||||
"dataset_id": datasetId,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.UploadID == "" || resp.Uuid == "" {
|
||||
msg := json.Get(res, "msg").ToString()
|
||||
return nil, fmt.Errorf(msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// getMultipartUrl 获取数据集分片传输url
|
||||
func (r DatasetService) getMultipartUrl(token, uuid, uploadID, fileName, dataType, datasetId, size, chunkNumber string) (resp *model.GetMultipartUrlResp, err error) {
|
||||
res, err := common.Request(common.GetMultipartUrl, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetQueryParams(map[string]string{
|
||||
"uuid": uuid,
|
||||
"uploadID": uploadID,
|
||||
"type": dataType,
|
||||
"size": size,
|
||||
"chunkNumber": chunkNumber,
|
||||
"file_name": fileName,
|
||||
"dataset_id": datasetId,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Url == "" {
|
||||
msg := json.Get(res, "msg").ToString()
|
||||
return nil, fmt.Errorf(msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// upLoadChunk 上传chunk
|
||||
func (r DatasetService) upLoadChunk(token, url, fileName string, reader io.Reader) (err error) {
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(http.MethodPut, url, reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "")
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
// 读取响应体
|
||||
_, err = io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return errors.New(res.Status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// completeMultipart 完成数据集文件上传
|
||||
func (r DatasetService) completeMultipart(token, uuid, uploadID, fileName, size, datasetId, dataType, customName string) (resp *model.CompleteMultipartResp, err error) {
|
||||
_, err = common.Request(common.CompleteMultipartUrl, http.MethodPost, func(req *resty.Request) {
|
||||
req.SetQueryParams(map[string]string{
|
||||
"uuid": uuid,
|
||||
"uploadID": uploadID,
|
||||
"file_name": fileName,
|
||||
"size": size,
|
||||
"dataset_id": datasetId,
|
||||
"type": dataType,
|
||||
"description": customName,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.ResultCode == "-1" {
|
||||
return nil, fmt.Errorf(resp.Msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r DatasetService) UploadFile(param model.DatasetUploadFileParam, token string, fileHeader *multipart.FileHeader) (respId string, err error) {
|
||||
datasetId := param.DatasetId
|
||||
// step.1 优先计算所需信息
|
||||
dataType := "1"
|
||||
uuid := ""
|
||||
uploadID := ""
|
||||
chunkNumber := 1
|
||||
fileName := fileHeader.Filename
|
||||
fileSize := fileHeader.Size
|
||||
totalChunkCounts := int(math.Ceil(float64(fileSize) / float64(common.MaxChunkSize)))
|
||||
|
||||
fileSizeStr := strconv.FormatInt(fileSize, 10)
|
||||
// 打开上传的文件
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("文件打开失败: %s", err.Error()))
|
||||
}
|
||||
defer file.Close() // 确保关闭文件
|
||||
md5hash, err := common.GetFileMd5(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Get already uploaded chunks
|
||||
chunks, err := r.getChunks(token, md5hash, fileName, dataType, datasetId, fileSizeStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if chunks.Uploaded == "1" {
|
||||
return "", errors.New(fmt.Sprintf("该文件已上传在数据集: %s", chunks.DatasetName))
|
||||
}
|
||||
if chunks.UploadID != "" && chunks.Uuid != "" {
|
||||
uuid = chunks.Uuid
|
||||
uploadID = chunks.UploadID
|
||||
} else {
|
||||
// Start a new multipart upload
|
||||
newMultipart, err := r.newMultipart(token, strconv.Itoa(totalChunkCounts), md5hash, fileName, dataType, datasetId, fileSizeStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uuid = newMultipart.Uuid
|
||||
uploadID = newMultipart.UploadID
|
||||
}
|
||||
|
||||
// Upload each chunk
|
||||
for chunkNumber <= totalChunkCounts {
|
||||
// Get multipart URL for the current chunk
|
||||
multipartUrl, err := r.getMultipartUrl(token, uuid, uploadID, fileName, dataType, datasetId, fileSizeStr, strconv.Itoa(chunkNumber))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a reader for the current chunk
|
||||
chunkReader := io.NewSectionReader(file, int64(chunkNumber-1)*common.MaxChunkSize, common.MaxChunkSize)
|
||||
|
||||
// Retry mechanism for uploading the current chunk
|
||||
for attempt := 1; attempt <= 3; attempt++ {
|
||||
err = r.upLoadChunk(token, multipartUrl.Url, fileName, chunkReader)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if attempt == 3 {
|
||||
return "", errors.New(fmt.Sprintf("error uploading chunk %d after 3 attempts: %s", chunkNumber, err.Error()))
|
||||
}
|
||||
}
|
||||
chunkNumber++
|
||||
}
|
||||
|
||||
// Complete the multipart upload
|
||||
_, err = r.completeMultipart(token, uuid, uploadID, fileName, fileSizeStr, datasetId, dataType, param.CustomName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ld := model.DatasetParam{
|
||||
UserName: param.UserName,
|
||||
RepoName: param.RepoName,
|
||||
Type: -1,
|
||||
}
|
||||
datasets, err := r.ListDatasetCurrentDatasets(token, &ld)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, datum := range datasets.Data {
|
||||
for _, attachment := range datum.Attachments {
|
||||
//数据集里面文件名称可重复,使用用户自定义名称做唯一区分
|
||||
if attachment.Description == param.CustomName {
|
||||
respId = attachment.Uuid
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
json "github.com/json-iterator/go"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/common"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/model"
|
||||
"io"
|
||||
"math"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type ModelService struct {
|
||||
}
|
||||
|
||||
func NewModelService() *ModelService {
|
||||
return &ModelService{}
|
||||
}
|
||||
|
||||
func (r ModelService) CreateLocalModel(token string, param model.CreateLocalModelParam) (resp model.CreateLocalModel, err error) {
|
||||
respErr := &model.RespErr{}
|
||||
_, err = common.Request(common.MODELLOCALCREATE, http.MethodPost, func(req *resty.Request) {
|
||||
req.SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
SetFormData(map[string]string{
|
||||
"name": param.Name,
|
||||
"version": param.Version,
|
||||
"engine": strconv.Itoa(param.Engine),
|
||||
"label": param.Label,
|
||||
"isPrivate": strconv.FormatBool(param.IsPrivate),
|
||||
"description": param.Description,
|
||||
"type": strconv.Itoa(param.Type),
|
||||
"license": param.License,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetError(respErr).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ListModel 分页查询模型
|
||||
func (r ModelService) ListModel(token string, param *model.QueryModelParam) (resp *model.ListModelResp, err error) {
|
||||
respErr := &model.RespErr{}
|
||||
_, err = common.Request(common.PageModel, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
SetQueryParam(common.ACCESSTOKEN, token).
|
||||
SetResult(&respErr).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// getChunks 获取模型该文件已经上传的分片
|
||||
func (r ModelService) getChunks(token, md5, fileName, dataType, modelUuid, size string) (resp *model.GetChunksResp, err error) {
|
||||
_, err = common.Request(common.MODELLOCALGETUPLOADEDCHUNKS, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetQueryParams(map[string]string{
|
||||
"md5": md5,
|
||||
"file_name": fileName,
|
||||
"type": dataType,
|
||||
"modeluuid": modelUuid,
|
||||
"size": size,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// newMultipart 开启一个本地模型文件上传
|
||||
func (r ModelService) newMultipart(token, totalChunkCounts, md5, fileName, dataType, modelUuid, size string) (resp *model.NewMultipartResp, err error) {
|
||||
res, err := common.Request(common.MODELLOCALNEWMULTIPART, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetQueryParams(map[string]string{
|
||||
"totalChunkCounts": totalChunkCounts,
|
||||
"type": dataType,
|
||||
"size": size,
|
||||
"md5": md5,
|
||||
"file_name": fileName,
|
||||
"modeluuid": modelUuid,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.UploadID == "" || resp.Uuid == "" {
|
||||
msg := json.Get(res, "msg").ToString()
|
||||
return nil, fmt.Errorf(msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// getMultipartUrl 获取模型分片传输url
|
||||
func (r ModelService) getMultipartUrl(token, uuid, uploadID, fileName, dataType, modelUuid, size, chunkNumber string) (resp *model.GetMultipartUrlResp, err error) {
|
||||
res, err := common.Request(common.MODELLOCALGETMULTIPARTURL, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetQueryParams(map[string]string{
|
||||
"uuid": uuid,
|
||||
"uploadID": uploadID,
|
||||
"type": dataType,
|
||||
"size": size,
|
||||
"chunkNumber": chunkNumber,
|
||||
"file_name": fileName,
|
||||
"modeluuid": modelUuid,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Url == "" {
|
||||
msg := json.Get(res, "msg").ToString()
|
||||
return nil, fmt.Errorf(msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// upLoadChunk 上传chunk
|
||||
func (r ModelService) upLoadChunk(token string, reqUrl, fileName string, reader io.Reader) (err error) {
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(http.MethodPut, reqUrl, reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "")
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
// 读取响应体
|
||||
_, err = io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return errors.New(res.Status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// completeMultipart 完成模型文件上传
|
||||
func (r ModelService) completeMultipart(token string, uuid, uploadID, fileName, size, modelUuid, dataType string) (resp *model.CompleteMultipartResp, err error) {
|
||||
_, err = common.Request(common.MODELLOCALCOMPLETEMULTIPART, http.MethodPost, func(req *resty.Request) {
|
||||
req.SetFormData(map[string]string{
|
||||
"uuid": uuid,
|
||||
"uploadID": uploadID,
|
||||
"type": dataType,
|
||||
"modeluuid": modelUuid,
|
||||
"file_name": fileName,
|
||||
"size": size,
|
||||
common.ACCESSTOKEN: token,
|
||||
}).SetResult(&resp)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.ResultCode == "-1" {
|
||||
return nil, fmt.Errorf(resp.Msg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r ModelService) UploadFile(param model.ModelUploadFileParam, token string, fileHeaders []*multipart.FileHeader) (respId string, err error) {
|
||||
modelUuid := param.ModelUuid
|
||||
for _, fileHeader := range fileHeaders {
|
||||
// step.1 优先计算所需信息
|
||||
dataType := "1"
|
||||
uuid := ""
|
||||
uploadID := ""
|
||||
chunkNumber := 1
|
||||
fileName := fileHeader.Filename
|
||||
fileSize := fileHeader.Size
|
||||
totalChunkCounts := int(math.Ceil(float64(fileSize) / float64(common.MaxChunkSize)))
|
||||
|
||||
fileSizeStr := strconv.FormatInt(fileSize, 10)
|
||||
// 打开上传的文件
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("文件打开失败: %s", err.Error()))
|
||||
}
|
||||
defer file.Close() // 确保关闭文件
|
||||
md5hash, err := common.GetFileMd5(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Get already uploaded chunks
|
||||
chunks, err := r.getChunks(token, md5hash, fileName, dataType, modelUuid, fileSizeStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if chunks.Uploaded == "1" {
|
||||
return "", errors.New(fmt.Sprintf("该文件已上传在模型: %s", chunks.ModelName))
|
||||
}
|
||||
if chunks.UploadID != "" && chunks.Uuid != "" {
|
||||
uuid = chunks.Uuid
|
||||
uploadID = chunks.UploadID
|
||||
} else {
|
||||
// Start a new multipart upload
|
||||
newMultipart, err := r.newMultipart(token, strconv.Itoa(totalChunkCounts), md5hash, fileName, dataType, modelUuid, fileSizeStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uuid = newMultipart.Uuid
|
||||
uploadID = newMultipart.UploadID
|
||||
}
|
||||
|
||||
// Upload each chunk
|
||||
for chunkNumber <= totalChunkCounts {
|
||||
// Get multipart URL for the current chunk
|
||||
multipartUrl, err := r.getMultipartUrl(token, uuid, uploadID, fileName, dataType, modelUuid, fileSizeStr, strconv.Itoa(chunkNumber))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a reader for the current chunk
|
||||
chunkReader := io.NewSectionReader(file, int64(chunkNumber-1)*common.MaxChunkSize, common.MaxChunkSize)
|
||||
|
||||
// Retry mechanism for uploading the current chunk
|
||||
for attempt := 1; attempt <= 3; attempt++ {
|
||||
err = r.upLoadChunk(token, multipartUrl.Url, fileName, chunkReader)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if attempt == 3 {
|
||||
return "", errors.New(fmt.Sprintf("error uploading chunk %d after 3 attempts: %s", chunkNumber, err.Error()))
|
||||
}
|
||||
}
|
||||
chunkNumber++
|
||||
}
|
||||
|
||||
// Complete the multipart upload
|
||||
_, err = r.completeMultipart(token, uuid, uploadID, fileName, fileSizeStr, modelUuid, dataType)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/common"
|
||||
"gitlink.org.cn/JointCloud/pcm-openi/model"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type RepoService struct {
|
||||
}
|
||||
|
||||
func NewRepoService() *RepoService {
|
||||
return &RepoService{}
|
||||
}
|
||||
|
||||
func (r RepoService) UploadFile(token string, param model.RepoUploadFileParam) (resp *structs.FileResponse, err error) {
|
||||
for _, content := range param.FileContents {
|
||||
respErr := &model.FileContentErr{}
|
||||
body := structs.CreateFileOptions{}
|
||||
//Base64编码后的文件内容
|
||||
body.Content = content.Content
|
||||
_, err = common.Request(common.RepoFile, http.MethodPost, func(req *resty.Request) {
|
||||
req.SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
SetPathParam("filepath", content.FilePath).
|
||||
SetQueryParam(common.ACCESSTOKEN, token).
|
||||
SetBody(&body).SetResult(&resp).SetError(&respErr)
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r RepoService) UpdateFile(token string, param model.RepoUpdateFileParam) (resp *structs.FileResponse, err error) {
|
||||
for _, content := range param.FileContents {
|
||||
respErr := &model.FileContentErr{}
|
||||
resp := &structs.FileResponse{}
|
||||
body := structs.UpdateFileOptions{}
|
||||
//Base64编码后的文件内容
|
||||
body.Content = content.Content
|
||||
body.SHA = content.FileSha
|
||||
_, err = common.Request(common.RepoFile, http.MethodPut, func(req *resty.Request) {
|
||||
req.SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
SetPathParam("filepath", content.FilePath).
|
||||
SetQueryParam(common.ACCESSTOKEN, token).
|
||||
SetBody(&body).SetResult(&resp).SetError(&respErr)
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r RepoService) QueryFilesContent(token string, param *model.QueryFilesContentParam) (resp interface{}, err error) {
|
||||
var respErr interface{}
|
||||
_, err = common.Request(common.RepoFile, http.MethodGet, func(req *resty.Request) {
|
||||
req.SetPathParam("username", param.UserName).
|
||||
SetPathParam("reponame", param.RepoName).
|
||||
SetPathParam("filepath", param.FilePath).
|
||||
SetQueryParam(common.ACCESSTOKEN, token).
|
||||
SetResult(&resp).SetError(&respErr)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue