| @@ -1,18 +1,26 @@ | |||||
| package ai | package ai | ||||
| import ( | import ( | ||||
| "github.com/zeromicro/go-zero/rest/httpx" | |||||
| "encoding/json" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/logic/ai" | "gitlink.org.cn/JointCloud/pcm-coordinator/internal/logic/ai" | ||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | ||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types" | |||||
| dataset "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types/ai" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result" | "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result" | ||||
| "io" | |||||
| "net/http" | "net/http" | ||||
| ) | ) | ||||
| func CreateDataSetHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | func CreateDataSetHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||||
| return func(w http.ResponseWriter, r *http.Request) { | return func(w http.ResponseWriter, r *http.Request) { | ||||
| var req types.CreateDataSetReq | |||||
| if err := httpx.Parse(r, &req); err != nil { | |||||
| var req dataset.CreateDatasetReq | |||||
| body, err := io.ReadAll(r.Body) | |||||
| if err != nil { | |||||
| result.ParamErrorResult(r, w, err) | |||||
| return | |||||
| } | |||||
| if err = json.Unmarshal(body, &req); err != nil { | |||||
| result.ParamErrorResult(r, w, err) | result.ParamErrorResult(r, w, err) | ||||
| return | return | ||||
| } | } | ||||
| @@ -0,0 +1,32 @@ | |||||
| package ai | |||||
| import ( | |||||
| "encoding/json" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/logic/ai" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | |||||
| Model "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types/ai" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result" | |||||
| "io" | |||||
| "net/http" | |||||
| ) | |||||
| func CreateModelHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | |||||
| return func(w http.ResponseWriter, r *http.Request) { | |||||
| var req Model.CreateModelReq | |||||
| body, err := io.ReadAll(r.Body) | |||||
| if err != nil { | |||||
| result.ParamErrorResult(r, w, err) | |||||
| return | |||||
| } | |||||
| if err = json.Unmarshal(body, &req); err != nil { | |||||
| result.ParamErrorResult(r, w, err) | |||||
| return | |||||
| } | |||||
| l := ai.NewCreateModelLogic(r.Context(), svcCtx) | |||||
| resp, err := l.CreateModel(&req) | |||||
| result.HttpResult(r, w, resp, err) | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,32 @@ | |||||
| package ai | |||||
| import ( | |||||
| "encoding/json" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/logic/ai" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | |||||
| Model "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types/ai" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/repository/result" | |||||
| "io" | |||||
| "net/http" | |||||
| ) | |||||
| func TaskResultSyncHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | |||||
| return func(w http.ResponseWriter, r *http.Request) { | |||||
| var req Model.ResultSyncReq | |||||
| body, err := io.ReadAll(r.Body) | |||||
| if err != nil { | |||||
| result.ParamErrorResult(r, w, err) | |||||
| return | |||||
| } | |||||
| if err = json.Unmarshal(body, &req); err != nil { | |||||
| result.ParamErrorResult(r, w, err) | |||||
| return | |||||
| } | |||||
| l := ai.NewTaskResultSyncLogic(r.Context(), svcCtx) | |||||
| resp, err := l.TaskResultSync(&req) | |||||
| result.HttpResult(r, w, resp, err) | |||||
| } | |||||
| } | |||||
| @@ -218,9 +218,22 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | |||||
| { | { | ||||
| // 创建数据集 | // 创建数据集 | ||||
| Method: http.MethodPost, | Method: http.MethodPost, | ||||
| Path: "/ai/createDataSet/:projectId", | |||||
| Path: "/ai/createDataSet", | |||||
| Handler: ai.CreateDataSetHandler(serverCtx), | Handler: ai.CreateDataSetHandler(serverCtx), | ||||
| }, | }, | ||||
| { | |||||
| // 创建模型 | |||||
| Method: http.MethodPost, | |||||
| Path: "/ai/createModel", | |||||
| Handler: ai.CreateModelHandler(serverCtx), | |||||
| }, | |||||
| { | |||||
| // 创建模型 | |||||
| Method: http.MethodPost, | |||||
| Path: "/ai/task/sync", | |||||
| Handler: ai.TaskResultSyncHandler(serverCtx), | |||||
| }, | |||||
| { | { | ||||
| // 创建notebook | // 创建notebook | ||||
| Method: http.MethodPost, | Method: http.MethodPost, | ||||
| @@ -16,15 +16,12 @@ package ai | |||||
| import ( | import ( | ||||
| "context" | "context" | ||||
| "github.com/jinzhu/copier" | |||||
| "github.com/go-resty/resty/v2" | |||||
| "github.com/pkg/errors" | "github.com/pkg/errors" | ||||
| "github.com/zeromicro/go-zero/core/logx" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | ||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types" | "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types" | ||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/helper/xerr" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils" | |||||
| "gitlink.org.cn/JointCloud/pcm-modelarts/modelarts" | |||||
| "github.com/zeromicro/go-zero/core/logx" | |||||
| dataset "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types/ai" | |||||
| ) | ) | ||||
| type CreateDataSetLogic struct { | type CreateDataSetLogic struct { | ||||
| @@ -41,18 +38,22 @@ func NewCreateDataSetLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Cre | |||||
| } | } | ||||
| } | } | ||||
| func (l *CreateDataSetLogic) CreateDataSet(req *types.CreateDataSetReq) (resp *types.CreateDataSetResp, err error) { | |||||
| // todo: add your logic here and delete this line | |||||
| func (l *CreateDataSetLogic) CreateDataSet(req *dataset.CreateDatasetReq) (resp *dataset.CreateDatasetResp, err error) { | |||||
| modelartsReq := &modelarts.CreateDataSetReq{} | |||||
| err = copier.CopyWithOption(modelartsReq, req, copier.Option{Converters: utils.Converters}) | |||||
| CreateDataSetResp, err := l.svcCtx.ModelArtsRpc.CreateDataSet(l.ctx, modelartsReq) | |||||
| if err != nil { | |||||
| return nil, errors.Wrapf(xerr.NewErrMsg("Failed to get db DataSet list"), "Failed to get db DataSet list err : %v ,req:%+v", err, req) | |||||
| cluster := &types.GetClusterByIdResp{} | |||||
| tx := l.svcCtx.DbEngin.Raw("select * from t_cluster where id = ?", req.ClusterId).Scan(&cluster.ClusterInfo) | |||||
| if tx.Error != nil { | |||||
| logx.Errorf(tx.Error.Error()) | |||||
| return nil, errors.New("cluster create failed") | |||||
| } | } | ||||
| resp = &types.CreateDataSetResp{} | |||||
| err = copier.CopyWithOption(&resp, &CreateDataSetResp, copier.Option{Converters: utils.Converters}) | |||||
| return resp, nil | |||||
| httpClient := resty.New().R() | |||||
| createDatasetResp := &dataset.CreateDatasetResp{} | |||||
| _, err = httpClient.SetHeader("Content-Type", "application/json"). | |||||
| SetQueryParams(map[string]string{"pfId": cluster.ClusterInfo.Id}). | |||||
| SetBody(req). | |||||
| SetResult(&createDatasetResp). | |||||
| Post(cluster.ClusterInfo.Server + "/ai/dataset/create") | |||||
| return createDatasetResp, err | |||||
| } | } | ||||
| @@ -0,0 +1,59 @@ | |||||
| /* | |||||
| Copyright (c) [2023] [pcm] | |||||
| [pcm-coordinator] is licensed under Mulan PSL v2. | |||||
| You can use this software according to the terms and conditions of the Mulan PSL v2. | |||||
| You may obtain a copy of Mulan PSL v2 at: | |||||
| http://license.coscl.org.cn/MulanPSL2 | |||||
| THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | |||||
| EITHER EXPaRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | |||||
| MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | |||||
| See the Mulan PSL v2 for more details. | |||||
| */ | |||||
| package ai | |||||
| import ( | |||||
| "context" | |||||
| "github.com/go-resty/resty/v2" | |||||
| "github.com/pkg/errors" | |||||
| "github.com/zeromicro/go-zero/core/logx" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types" | |||||
| model "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types/ai" | |||||
| ) | |||||
| type CreateModelLogic struct { | |||||
| logx.Logger | |||||
| ctx context.Context | |||||
| svcCtx *svc.ServiceContext | |||||
| } | |||||
| func NewCreateModelLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateModelLogic { | |||||
| return &CreateModelLogic{ | |||||
| Logger: logx.WithContext(ctx), | |||||
| ctx: ctx, | |||||
| svcCtx: svcCtx, | |||||
| } | |||||
| } | |||||
| func (l *CreateModelLogic) CreateModel(req *model.CreateModelReq) (resp *model.CreateModelResp, err error) { | |||||
| cluster := &types.GetClusterByIdResp{} | |||||
| tx := l.svcCtx.DbEngin.Raw("select * from t_cluster where id = ?", req.ClusterId).Scan(&cluster.ClusterInfo) | |||||
| if tx.Error != nil { | |||||
| logx.Errorf(tx.Error.Error()) | |||||
| return nil, errors.New("cluster create failed") | |||||
| } | |||||
| httpClient := resty.New().R() | |||||
| createModelResp := &model.CreateModelResp{} | |||||
| _, err = httpClient.SetHeader("Content-Type", "application/json"). | |||||
| SetQueryParams(map[string]string{"pfId": cluster.ClusterInfo.Id}). | |||||
| SetBody(req). | |||||
| SetResult(&createModelResp). | |||||
| Post(cluster.ClusterInfo.Server + "/ai/model/create") | |||||
| return createModelResp, err | |||||
| } | |||||
| @@ -0,0 +1,59 @@ | |||||
| /* | |||||
| Copyright (c) [2023] [pcm] | |||||
| [pcm-coordinator] is licensed under Mulan PSL v2. | |||||
| You can use this software according to the terms and conditions of the Mulan PSL v2. | |||||
| You may obtain a copy of Mulan PSL v2 at: | |||||
| http://license.coscl.org.cn/MulanPSL2 | |||||
| THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | |||||
| EITHER EXPaRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | |||||
| MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | |||||
| See the Mulan PSL v2 for more details. | |||||
| */ | |||||
| package ai | |||||
| import ( | |||||
| "context" | |||||
| "github.com/go-resty/resty/v2" | |||||
| "github.com/pkg/errors" | |||||
| "github.com/zeromicro/go-zero/core/logx" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc" | |||||
| "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types" | |||||
| sync "gitlink.org.cn/JointCloud/pcm-coordinator/internal/types/ai" | |||||
| ) | |||||
| type TaskResultSyncLogic struct { | |||||
| logx.Logger | |||||
| ctx context.Context | |||||
| svcCtx *svc.ServiceContext | |||||
| } | |||||
| func NewTaskResultSyncLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TaskResultSyncLogic { | |||||
| return &TaskResultSyncLogic{ | |||||
| Logger: logx.WithContext(ctx), | |||||
| ctx: ctx, | |||||
| svcCtx: svcCtx, | |||||
| } | |||||
| } | |||||
| func (l *TaskResultSyncLogic) TaskResultSync(req *sync.ResultSyncReq) (resp *sync.ResultSyncResp, err error) { | |||||
| cluster := &types.GetClusterByIdResp{} | |||||
| tx := l.svcCtx.DbEngin.Raw("select * from t_cluster where id = ?", req.ClusterId).Scan(&cluster.ClusterInfo) | |||||
| if tx.Error != nil { | |||||
| logx.Errorf(tx.Error.Error()) | |||||
| return nil, errors.New("cluster create failed") | |||||
| } | |||||
| httpClient := resty.New().R() | |||||
| createModelResp := &sync.ResultSyncResp{} | |||||
| _, err = httpClient.SetHeader("Content-Type", "application/json"). | |||||
| SetQueryParams(map[string]string{"pfId": cluster.ClusterInfo.Id}). | |||||
| SetBody(req). | |||||
| SetResult(&createModelResp). | |||||
| Post(cluster.ClusterInfo.Server + "/ai/task/sync") | |||||
| return createModelResp, err | |||||
| } | |||||
| @@ -1,30 +1,20 @@ | |||||
| package algorithm | |||||
| package ai | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| "fmt" | "fmt" | ||||
| ) | ) | ||||
| type CreateParameter interface { | |||||
| type CreateAlgorithmParameter interface { | |||||
| AlgorithmCreateParam() | AlgorithmCreateParam() | ||||
| } | } | ||||
| type Source struct { | |||||
| Jcs JcsBase `json:"jcs,omitempty"` | |||||
| } | |||||
| type JcsBase struct { | |||||
| UserID int `json:"userID" binding:"required"` | |||||
| PackageId int `json:"packageId" binding:"required"` | |||||
| BucketID int `json:"bucketID" binding:"required"` | |||||
| } | |||||
| type CreateAlgorithmReq struct { | type CreateAlgorithmReq struct { | ||||
| Name string `json:"name" binding:"required"` | |||||
| ClusterId string `json:"clusterId"` | |||||
| Desc string `json:"desc"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param CreateParameter `json:"param,omitempty"` | |||||
| Name string `json:"name" binding:"required"` | |||||
| ClusterId string `json:"clusterId"` | |||||
| Desc string `json:"desc"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param CreateAlgorithmParameter `json:"param,omitempty"` | |||||
| } | } | ||||
| type CreateAlgorithmResp struct { | type CreateAlgorithmResp struct { | ||||
| @@ -33,18 +23,18 @@ type CreateAlgorithmResp struct { | |||||
| ErrorMsg string `json:"errorMsg,omitempty" copier:"ErrorMsg"` | ErrorMsg string `json:"errorMsg,omitempty" copier:"ErrorMsg"` | ||||
| } | } | ||||
| type OpenI struct { | |||||
| type OpenIAlgorithm struct { | |||||
| BootFile string `json:"bootFile,omitempty"` | BootFile string `json:"bootFile,omitempty"` | ||||
| DefaultBranch string `json:"defaultBranch,omitempty"` | DefaultBranch string `json:"defaultBranch,omitempty"` | ||||
| } | } | ||||
| func (o *OpenI) AlgorithmCreateParam() { | |||||
| func (o *OpenIAlgorithm) AlgorithmCreateParam() { | |||||
| } | } | ||||
| type Octopus struct { | |||||
| type OctopusAlgorithm struct { | |||||
| } | } | ||||
| func (o *Octopus) AlgorithmCreateParam() { | |||||
| func (o *OctopusAlgorithm) AlgorithmCreateParam() { | |||||
| } | } | ||||
| func (cp *CreateAlgorithmReq) UnmarshalJSON(data []byte) error { | func (cp *CreateAlgorithmReq) UnmarshalJSON(data []byte) error { | ||||
| @@ -70,7 +60,7 @@ func (cp *CreateAlgorithmReq) UnmarshalJSON(data []byte) error { | |||||
| // 解析 param 字段的原始数据为具体类型 | // 解析 param 字段的原始数据为具体类型 | ||||
| if temp.Param != nil { | if temp.Param != nil { | ||||
| // 尝试解析为 OpenI 类型 | // 尝试解析为 OpenI 类型 | ||||
| var openi OpenI | |||||
| var openi OpenIAlgorithm | |||||
| if err := json.Unmarshal(temp.Param, &openi); err != nil { | if err := json.Unmarshal(temp.Param, &openi); err != nil { | ||||
| // 打印详细错误(如字段不匹配、类型错误等) | // 打印详细错误(如字段不匹配、类型错误等) | ||||
| fmt.Printf("解析 OpenI 失败: %v\n", err) // 关键调试日志 | fmt.Printf("解析 OpenI 失败: %v\n", err) // 关键调试日志 | ||||
| @@ -80,7 +70,7 @@ func (cp *CreateAlgorithmReq) UnmarshalJSON(data []byte) error { | |||||
| } | } | ||||
| // 新增:尝试解析为 Octopus 类型 | // 新增:尝试解析为 Octopus 类型 | ||||
| var octopus Octopus | |||||
| var octopus OctopusAlgorithm | |||||
| if err := json.Unmarshal(temp.Param, &octopus); err == nil { | if err := json.Unmarshal(temp.Param, &octopus); err == nil { | ||||
| cp.Param = &octopus | cp.Param = &octopus | ||||
| return nil | return nil | ||||
| @@ -0,0 +1,11 @@ | |||||
| package ai | |||||
| type Source struct { | |||||
| Jcs JcsBase `json:"jcs,omitempty"` | |||||
| } | |||||
| type JcsBase struct { | |||||
| UserID int `json:"userID" binding:"required"` | |||||
| PackageId int `json:"packageId" binding:"required"` | |||||
| BucketID int `json:"bucketID" binding:"required"` | |||||
| } | |||||
| @@ -0,0 +1,82 @@ | |||||
| package ai | |||||
| import ( | |||||
| "encoding/json" | |||||
| "fmt" | |||||
| ) | |||||
| type CreateDatasetParameter interface { | |||||
| DatasetCreateParam() | |||||
| } | |||||
| type CreateDatasetReq struct { | |||||
| Name string `json:"name" binding:"required"` | |||||
| ClusterId string `json:"clusterId"` | |||||
| Desc string `json:"desc"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param CreateDatasetParameter `json:"param,omitempty"` | |||||
| } | |||||
| type CreateDatasetResp struct { | |||||
| Code int32 `json:"code,omitempty" copier:"Code"` | |||||
| Msg string `json:"msg,omitempty" copier:"Msg"` | |||||
| ErrorMsg string `json:"errorMsg,omitempty" copier:"ErrorMsg"` | |||||
| } | |||||
| type OpenIDataset struct { | |||||
| Repo string `json:"repo,omitempty"` | |||||
| } | |||||
| func (o *OpenIDataset) DatasetCreateParam() { | |||||
| } | |||||
| type OctopusDataset struct { | |||||
| } | |||||
| func (o *OctopusDataset) DatasetCreateParam() { | |||||
| } | |||||
| func (cp *CreateDatasetReq) UnmarshalJSON(data []byte) error { | |||||
| // 临时结构体:用于捕获原始 JSON 中的 param 字段数据 | |||||
| type TempCreateParam struct { | |||||
| Name string `json:"name"` | |||||
| ClusterId string `json:"clusterId"` | |||||
| Desc string `json:"desc"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param json.RawMessage `json:"param,omitempty"` // 捕获原始 JSON 数据 | |||||
| } | |||||
| var temp TempCreateParam | |||||
| if err := json.Unmarshal(data, &temp); err != nil { | |||||
| return err | |||||
| } | |||||
| // 将临时结构体的字段赋值给原结构体(除 Param 外) | |||||
| cp.Name = temp.Name | |||||
| cp.ClusterId = temp.ClusterId | |||||
| cp.Desc = temp.Desc | |||||
| cp.Src = temp.Src | |||||
| // 解析 param 字段的原始数据为具体类型 | |||||
| if temp.Param != nil { | |||||
| // 尝试解析为 OpenI 类型 | |||||
| var openi OpenIDataset | |||||
| if err := json.Unmarshal(temp.Param, &openi); err != nil { | |||||
| // 打印详细错误(如字段不匹配、类型错误等) | |||||
| fmt.Printf("解析 OpenI 失败: %v\n", err) // 关键调试日志 | |||||
| } else { | |||||
| cp.Param = &openi | |||||
| return nil | |||||
| } | |||||
| // 新增:尝试解析为 Octopus 类型 | |||||
| var octopus OctopusDataset | |||||
| if err := json.Unmarshal(temp.Param, &octopus); err == nil { | |||||
| cp.Param = &octopus | |||||
| return nil | |||||
| } | |||||
| return fmt.Errorf("unsupported param type in CreateParam") | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -0,0 +1,82 @@ | |||||
| package ai | |||||
| import ( | |||||
| "encoding/json" | |||||
| "fmt" | |||||
| ) | |||||
| type CreateModelParameter interface { | |||||
| ModelCreateParam() | |||||
| } | |||||
| type CreateModelReq struct { | |||||
| Name string `json:"name" binding:"required"` | |||||
| ClusterId string `json:"clusterId"` | |||||
| Desc string `json:"desc"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param CreateModelParameter `json:"param,omitempty"` | |||||
| } | |||||
| type CreateModelResp struct { | |||||
| Code int32 `json:"code,omitempty" copier:"Code"` | |||||
| Msg string `json:"msg,omitempty" copier:"Msg"` | |||||
| ErrorMsg string `json:"errorMsg,omitempty" copier:"ErrorMsg"` | |||||
| } | |||||
| type OpenIModel struct { | |||||
| RepoName string `json:"repoName,omitempty"` | |||||
| } | |||||
| func (o *OpenIModel) ModelCreateParam() { | |||||
| } | |||||
| type OctopusModel struct { | |||||
| } | |||||
| func (o *OctopusModel) ModelCreateParam() { | |||||
| } | |||||
| func (cp *CreateModelReq) UnmarshalJSON(data []byte) error { | |||||
| // 临时结构体:用于捕获原始 JSON 中的 param 字段数据 | |||||
| type TempCreateParam struct { | |||||
| Name string `json:"name"` | |||||
| ClusterId string `json:"clusterId"` | |||||
| Desc string `json:"desc"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param json.RawMessage `json:"param,omitempty"` // 捕获原始 JSON 数据 | |||||
| } | |||||
| var temp TempCreateParam | |||||
| if err := json.Unmarshal(data, &temp); err != nil { | |||||
| return err | |||||
| } | |||||
| // 将临时结构体的字段赋值给原结构体(除 Param 外) | |||||
| cp.Name = temp.Name | |||||
| cp.ClusterId = temp.ClusterId | |||||
| cp.Desc = temp.Desc | |||||
| cp.Src = temp.Src | |||||
| // 解析 param 字段的原始数据为具体类型 | |||||
| if temp.Param != nil { | |||||
| // 尝试解析为 OpenI 类型 | |||||
| var openi OpenIModel | |||||
| if err := json.Unmarshal(temp.Param, &openi); err != nil { | |||||
| // 打印详细错误(如字段不匹配、类型错误等) | |||||
| fmt.Printf("解析 OpenI 失败: %v\n", err) // 关键调试日志 | |||||
| } else { | |||||
| cp.Param = &openi | |||||
| return nil | |||||
| } | |||||
| // 新增:尝试解析为 Octopus 类型 | |||||
| var octopus OctopusModel | |||||
| if err := json.Unmarshal(temp.Param, &octopus); err == nil { | |||||
| cp.Param = &octopus | |||||
| return nil | |||||
| } | |||||
| return fmt.Errorf("unsupported param type in CreateParam") | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -0,0 +1,81 @@ | |||||
| package ai | |||||
| import ( | |||||
| "encoding/json" | |||||
| "fmt" | |||||
| ) | |||||
| type ResultSyncParameter interface { | |||||
| ResultSyncParam() | |||||
| } | |||||
| type ResultSyncReq struct { | |||||
| ClusterId string `json:"clusterId"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param ResultSyncParameter `json:"param,omitempty"` | |||||
| } | |||||
| type ResultSyncResp struct { | |||||
| Code int32 `json:"code,omitempty" copier:"Code"` | |||||
| Msg string `json:"msg,omitempty" copier:"Msg"` | |||||
| ErrorMsg string `json:"errorMsg,omitempty" copier:"ErrorMsg"` | |||||
| } | |||||
| type OpenISync struct { | |||||
| Id string `json:"id,omitempty"` | |||||
| RepoName string `json:"repoName,omitempty"` | |||||
| ParentDir string `json:"parentDir,omitempty"` | |||||
| BootFile string `json:"bootFile,omitempty"` | |||||
| DefaultBranch string `json:"defaultBranch,omitempty"` | |||||
| } | |||||
| func (o *OpenISync) ResultSyncParam() { | |||||
| } | |||||
| type OctopusSync struct { | |||||
| } | |||||
| func (o *OctopusSync) ResultSyncParam() { | |||||
| } | |||||
| func (cp *ResultSyncReq) UnmarshalJSON(data []byte) error { | |||||
| // 临时结构体:用于捕获原始 JSON 中的 param 字段数据 | |||||
| type TempCreateParam struct { | |||||
| ClusterId string `json:"clusterId"` | |||||
| Src Source `json:"src,omitempty"` | |||||
| Param json.RawMessage `json:"param,omitempty"` // 捕获原始 JSON 数据 | |||||
| } | |||||
| var temp TempCreateParam | |||||
| if err := json.Unmarshal(data, &temp); err != nil { | |||||
| return err | |||||
| } | |||||
| // 将临时结构体的字段赋值给原结构体(除 Param 外) | |||||
| cp.ClusterId = temp.ClusterId | |||||
| cp.Src = temp.Src | |||||
| // 解析 param 字段的原始数据为具体类型 | |||||
| if temp.Param != nil { | |||||
| // 尝试解析为 OpenI 类型 | |||||
| var openi OpenISync | |||||
| if err := json.Unmarshal(temp.Param, &openi); err != nil { | |||||
| // 打印详细错误(如字段不匹配、类型错误等) | |||||
| fmt.Printf("解析 OpenI 失败: %v\n", err) // 关键调试日志 | |||||
| } else { | |||||
| cp.Param = &openi | |||||
| return nil | |||||
| } | |||||
| // 新增:尝试解析为 Octopus 类型 | |||||
| var octopus OctopusSync | |||||
| if err := json.Unmarshal(temp.Param, &octopus); err == nil { | |||||
| cp.Param = &octopus | |||||
| return nil | |||||
| } | |||||
| return fmt.Errorf("unsupported param type in CreateParam") | |||||
| } | |||||
| return nil | |||||
| } | |||||