add service

This commit is contained in:
jagger 2025-02-14 18:02:51 +08:00
parent 0a94f55363
commit 76fbd6ea7b
20 changed files with 1406 additions and 22 deletions

115
apis/base_api.go Normal file
View File

@ -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)
}
}

View File

@ -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(&param); 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(&param); 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(&param); err != nil {
model.Response(ctx, http.StatusBadRequest, common.INVALIDPARAMS, translate(err))
return
}
token := ctx.Query(common.ACCESSTOKEN)
if resp, err := r.DatasetService.ListDatasets(token, &param); 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(&param); 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)
}
}

View File

@ -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(&param); 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(&param); 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)
}
}

View File

@ -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(&param); 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(&param); 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(&param); 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, &param); err != nil {
model.Response(ctx, 500, err.Error(), nil)
} else {
model.Response(ctx, http.StatusOK, common.SUCCESS, resp)
}
return
}

3
app.go
View File

@ -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")
}

80
common/client.go Normal file
View File

@ -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
}

View File

@ -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"
)

12
common/types.go Normal file
View File

@ -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)

View File

@ -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
View File

@ -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

127
go.sum Normal file
View File

@ -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=

9
initialize/common.go Normal file
View File

@ -0,0 +1,9 @@
package initialize
import (
"gitlink.org.cn/JointCloud/pcm-openi/common"
)
func InitConfig() {
common.InitClient()
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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)

267
service/dataset.go Normal file
View File

@ -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
}

251
service/model.go Normal file
View File

@ -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
}

75
service/repo.go Normal file
View File

@ -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
}