| @@ -25,6 +25,7 @@ type AiModelManage struct { | |||||
| DownloadCount int `xorm:"NOT NULL DEFAULT 0"` | DownloadCount int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Engine int64 `xorm:"NOT NULL DEFAULT 0"` | Engine int64 `xorm:"NOT NULL DEFAULT 0"` | ||||
| Status int `xorm:"NOT NULL DEFAULT 0"` | Status int `xorm:"NOT NULL DEFAULT 0"` | ||||
| StatusDesc string `xorm:"varchar(500)"` | |||||
| Accuracy string `xorm:"varchar(1000)"` | Accuracy string `xorm:"varchar(1000)"` | ||||
| AttachmentId string `xorm:"NULL"` | AttachmentId string `xorm:"NULL"` | ||||
| RepoId int64 `xorm:"INDEX NULL"` | RepoId int64 `xorm:"INDEX NULL"` | ||||
| @@ -286,6 +287,23 @@ func ModifyModelDescription(id string, description string) error { | |||||
| return nil | return nil | ||||
| } | } | ||||
| func ModifyModelStatus(id string, modelSize int64, status int, modelPath string, statusDesc string) error { | |||||
| var sess *xorm.Session | |||||
| sess = x.ID(id) | |||||
| defer sess.Close() | |||||
| re, err := sess.Cols("size", "status", "path", "status_desc").Update(&AiModelManage{ | |||||
| Size: modelSize, | |||||
| Status: status, | |||||
| Path: modelPath, | |||||
| StatusDesc: statusDesc, | |||||
| }) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| log.Info("success to update ModelStatus from db.re=" + fmt.Sprint((re))) | |||||
| return nil | |||||
| } | |||||
| func ModifyModelNewProperty(id string, new int, versioncount int) error { | func ModifyModelNewProperty(id string, new int, versioncount int) error { | ||||
| var sess *xorm.Session | var sess *xorm.Session | ||||
| sess = x.ID(id) | sess = x.ID(id) | ||||
| @@ -356,6 +374,12 @@ func QueryModel(opts *AiModelQueryOptions) ([]*AiModelManage, int64, error) { | |||||
| ) | ) | ||||
| } | } | ||||
| if (opts.Status) >= 0 { | |||||
| cond = cond.And( | |||||
| builder.Eq{"ai_model_manage.status": opts.Status}, | |||||
| ) | |||||
| } | |||||
| count, err := sess.Where(cond).Count(new(AiModelManage)) | count, err := sess.Where(cond).Count(new(AiModelManage)) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, 0, fmt.Errorf("Count: %v", err) | return nil, 0, fmt.Errorf("Count: %v", err) | ||||
| @@ -178,6 +178,7 @@ func init() { | |||||
| new(UserLoginLog), | new(UserLoginLog), | ||||
| new(UserMetrics), | new(UserMetrics), | ||||
| new(UserAnalysisPara), | new(UserAnalysisPara), | ||||
| new(Invitation), | |||||
| ) | ) | ||||
| gonicNames := []string{"SSL", "UID"} | gonicNames := []string{"SSL", "UID"} | ||||
| @@ -106,7 +106,8 @@ type UserBusinessAnalysisAll struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysis struct { | type UserBusinessAnalysis struct { | ||||
| @@ -193,7 +194,8 @@ type UserBusinessAnalysis struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysisQueryOptions struct { | type UserBusinessAnalysisQueryOptions struct { | ||||
| @@ -354,6 +356,33 @@ func QueryRankList(key string, tableName string, limit int) ([]*UserBusinessAnal | |||||
| return userBusinessAnalysisAllList, int64(len(userBusinessAnalysisAllList)) | return userBusinessAnalysisAllList, int64(len(userBusinessAnalysisAllList)) | ||||
| } | } | ||||
| func QueryUserInvitationDataByTableName(start int, pageSize int, tableName string, queryObj interface{}, userName string, invitationNum int) ([]*UserBusinessAnalysisAll, int64) { | |||||
| statictisSess := xStatistic.NewSession() | |||||
| defer statictisSess.Close() | |||||
| var cond = builder.NewCond() | |||||
| if len(userName) > 0 { | |||||
| cond = cond.And( | |||||
| builder.Like{"lower(name)", strings.ToLower(userName)}, | |||||
| ) | |||||
| } | |||||
| cond = cond.And( | |||||
| builder.Gte{"invitation_user_num": invitationNum}, | |||||
| ) | |||||
| allCount, err := statictisSess.Where(cond).Count(queryObj) | |||||
| if err != nil { | |||||
| log.Info("query error." + err.Error()) | |||||
| return nil, 0 | |||||
| } | |||||
| log.Info("query return total:" + fmt.Sprint(allCount)) | |||||
| userBusinessAnalysisAllList := make([]*UserBusinessAnalysisAll, 0) | |||||
| if err := statictisSess.Table(tableName).Where(cond).OrderBy("invitation_user_num desc,id asc").Limit(pageSize, start). | |||||
| Find(&userBusinessAnalysisAllList); err != nil { | |||||
| return nil, 0 | |||||
| } | |||||
| return userBusinessAnalysisAllList, allCount | |||||
| } | |||||
| func QueryUserStaticDataByTableName(start int, pageSize int, tableName string, queryObj interface{}, userName string) ([]*UserBusinessAnalysisAll, int64) { | func QueryUserStaticDataByTableName(start int, pageSize int, tableName string, queryObj interface{}, userName string) ([]*UserBusinessAnalysisAll, int64) { | ||||
| statictisSess := xStatistic.NewSession() | statictisSess := xStatistic.NewSession() | ||||
| defer statictisSess.Close() | defer statictisSess.Close() | ||||
| @@ -363,6 +392,7 @@ func QueryUserStaticDataByTableName(start int, pageSize int, tableName string, q | |||||
| builder.Like{"lower(name)", strings.ToLower(userName)}, | builder.Like{"lower(name)", strings.ToLower(userName)}, | ||||
| ) | ) | ||||
| } | } | ||||
| allCount, err := statictisSess.Where(cond).Count(queryObj) | allCount, err := statictisSess.Where(cond).Count(queryObj) | ||||
| if err != nil { | if err != nil { | ||||
| log.Info("query error." + err.Error()) | log.Info("query error." + err.Error()) | ||||
| @@ -752,6 +782,8 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||||
| CollectImage, CollectedImage := queryImageStars(start_unix, end_unix) | CollectImage, CollectedImage := queryImageStars(start_unix, end_unix) | ||||
| RecommendImage := queryRecommedImage(start_unix, end_unix) | RecommendImage := queryRecommedImage(start_unix, end_unix) | ||||
| InvitationMap := queryUserInvitationCount(start_unix, end_unix) | |||||
| DataDate := currentTimeNow.Format("2006-01-02") + " 00:01" | DataDate := currentTimeNow.Format("2006-01-02") + " 00:01" | ||||
| cond := "type != 1 and is_active=true" | cond := "type != 1 and is_active=true" | ||||
| @@ -825,7 +857,7 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||||
| dateRecordAll.CollectImage = getMapValue(dateRecordAll.ID, CollectImage) | dateRecordAll.CollectImage = getMapValue(dateRecordAll.ID, CollectImage) | ||||
| dateRecordAll.CollectedImage = getMapValue(dateRecordAll.ID, CollectedImage) | dateRecordAll.CollectedImage = getMapValue(dateRecordAll.ID, CollectedImage) | ||||
| dateRecordAll.RecommendImage = getMapValue(dateRecordAll.ID, RecommendImage) | dateRecordAll.RecommendImage = getMapValue(dateRecordAll.ID, RecommendImage) | ||||
| dateRecordAll.InvitationUserNum = getMapValue(dateRecordAll.ID, InvitationMap) | |||||
| dateRecordAll.UserIndexPrimitive = getUserIndexFromAnalysisAll(dateRecordAll, ParaWeight) | dateRecordAll.UserIndexPrimitive = getUserIndexFromAnalysisAll(dateRecordAll, ParaWeight) | ||||
| userIndexMap[dateRecordAll.ID] = dateRecordAll.UserIndexPrimitive | userIndexMap[dateRecordAll.ID] = dateRecordAll.UserIndexPrimitive | ||||
| if maxUserIndex < dateRecordAll.UserIndexPrimitive { | if maxUserIndex < dateRecordAll.UserIndexPrimitive { | ||||
| @@ -888,7 +920,7 @@ func insertTable(dateRecords []UserBusinessAnalysisAll, tableName string, static | |||||
| insertBatchSql := "INSERT INTO public." + tableName + | insertBatchSql := "INSERT INTO public." + tableName + | ||||
| "(id, count_date, code_merge_count, commit_count, issue_count, comment_count, focus_repo_count, star_repo_count, watched_count, gitea_age_month, commit_code_size, commit_dataset_size, " + | "(id, count_date, code_merge_count, commit_count, issue_count, comment_count, focus_repo_count, star_repo_count, watched_count, gitea_age_month, commit_code_size, commit_dataset_size, " + | ||||
| "commit_model_count, solve_issue_count, encyclopedias_count, regist_date, create_repo_count, login_count, open_i_index, email, name, data_date,cloud_brain_task_num,gpu_debug_job,npu_debug_job,gpu_train_job,npu_train_job,npu_inference_job,gpu_bench_mark_job,cloud_brain_run_time,commit_dataset_num,user_index,user_location,focus_other_user,collect_dataset,collected_dataset,recommend_dataset,collect_image,collected_image,recommend_image,user_index_primitive,phone) " + | |||||
| "commit_model_count, solve_issue_count, encyclopedias_count, regist_date, create_repo_count, login_count, open_i_index, email, name, data_date,cloud_brain_task_num,gpu_debug_job,npu_debug_job,gpu_train_job,npu_train_job,npu_inference_job,gpu_bench_mark_job,cloud_brain_run_time,commit_dataset_num,user_index,user_location,focus_other_user,collect_dataset,collected_dataset,recommend_dataset,collect_image,collected_image,recommend_image,user_index_primitive,phone,invitation_user_num) " + | |||||
| "VALUES" | "VALUES" | ||||
| for i, record := range dateRecords { | for i, record := range dateRecords { | ||||
| @@ -897,7 +929,7 @@ func insertTable(dateRecords []UserBusinessAnalysisAll, tableName string, static | |||||
| ", " + fmt.Sprint(record.WatchedCount) + ", " + fmt.Sprint(record.GiteaAgeMonth) + ", " + fmt.Sprint(record.CommitCodeSize) + ", " + fmt.Sprint(record.CommitDatasetSize) + | ", " + fmt.Sprint(record.WatchedCount) + ", " + fmt.Sprint(record.GiteaAgeMonth) + ", " + fmt.Sprint(record.CommitCodeSize) + ", " + fmt.Sprint(record.CommitDatasetSize) + | ||||
| ", " + fmt.Sprint(record.CommitModelCount) + ", " + fmt.Sprint(record.SolveIssueCount) + ", " + fmt.Sprint(record.EncyclopediasCount) + ", " + fmt.Sprint(record.RegistDate) + | ", " + fmt.Sprint(record.CommitModelCount) + ", " + fmt.Sprint(record.SolveIssueCount) + ", " + fmt.Sprint(record.EncyclopediasCount) + ", " + fmt.Sprint(record.RegistDate) + | ||||
| ", " + fmt.Sprint(record.CreateRepoCount) + ", " + fmt.Sprint(record.LoginCount) + ", " + fmt.Sprint(record.OpenIIndex) + ", '" + record.Email + "', '" + record.Name + "', '" + record.DataDate + "'," + fmt.Sprint(record.CloudBrainTaskNum) + "," + fmt.Sprint(record.GpuDebugJob) + "," + fmt.Sprint(record.NpuDebugJob) + "," + fmt.Sprint(record.GpuTrainJob) + "," + fmt.Sprint(record.NpuTrainJob) + "," + fmt.Sprint(record.NpuInferenceJob) + "," + fmt.Sprint(record.GpuBenchMarkJob) + "," + fmt.Sprint(record.CloudBrainRunTime) + "," + fmt.Sprint(record.CommitDatasetNum) + "," + fmt.Sprint(record.UserIndex) + ",'" + record.UserLocation + "'," + | ", " + fmt.Sprint(record.CreateRepoCount) + ", " + fmt.Sprint(record.LoginCount) + ", " + fmt.Sprint(record.OpenIIndex) + ", '" + record.Email + "', '" + record.Name + "', '" + record.DataDate + "'," + fmt.Sprint(record.CloudBrainTaskNum) + "," + fmt.Sprint(record.GpuDebugJob) + "," + fmt.Sprint(record.NpuDebugJob) + "," + fmt.Sprint(record.GpuTrainJob) + "," + fmt.Sprint(record.NpuTrainJob) + "," + fmt.Sprint(record.NpuInferenceJob) + "," + fmt.Sprint(record.GpuBenchMarkJob) + "," + fmt.Sprint(record.CloudBrainRunTime) + "," + fmt.Sprint(record.CommitDatasetNum) + "," + fmt.Sprint(record.UserIndex) + ",'" + record.UserLocation + "'," + | ||||
| fmt.Sprint(record.FocusOtherUser) + "," + fmt.Sprint(record.CollectDataset) + "," + fmt.Sprint(record.CollectedDataset) + "," + fmt.Sprint(record.RecommendDataset) + "," + fmt.Sprint(record.CollectImage) + "," + fmt.Sprint(record.CollectedImage) + "," + fmt.Sprint(record.RecommendImage) + "," + fmt.Sprint(record.UserIndexPrimitive) + ",'" + record.Phone + "')" | |||||
| fmt.Sprint(record.FocusOtherUser) + "," + fmt.Sprint(record.CollectDataset) + "," + fmt.Sprint(record.CollectedDataset) + "," + fmt.Sprint(record.RecommendDataset) + "," + fmt.Sprint(record.CollectImage) + "," + fmt.Sprint(record.CollectedImage) + "," + fmt.Sprint(record.RecommendImage) + "," + fmt.Sprint(record.UserIndexPrimitive) + ",'" + record.Phone + "'" + "," + fmt.Sprint(record.InvitationUserNum) + ")" | |||||
| if i < (len(dateRecords) - 1) { | if i < (len(dateRecords) - 1) { | ||||
| insertBatchSql += "," | insertBatchSql += "," | ||||
| } | } | ||||
| @@ -2173,6 +2205,41 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s | |||||
| return resultMap, resultItemMap | return resultMap, resultItemMap | ||||
| } | } | ||||
| func queryUserInvitationCount(start_unix int64, end_unix int64) map[int64]int { | |||||
| statictisSess := xStatistic.NewSession() | |||||
| defer statictisSess.Close() | |||||
| resultMap := make(map[int64]int) | |||||
| cond := "created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix) | |||||
| count, err := statictisSess.Where(cond).Count(new(Invitation)) | |||||
| if err != nil { | |||||
| log.Info("query queryUserInvitationCount error. return.") | |||||
| return resultMap | |||||
| } | |||||
| var indexTotal int64 | |||||
| indexTotal = 0 | |||||
| for { | |||||
| statictisSess.Select("id,src_user_id,user_id").Table("invitation").Where(cond).OrderBy("id asc").Limit(PAGE_SIZE, int(indexTotal)) | |||||
| invitationList := make([]*Invitation, 0) | |||||
| statictisSess.Find(&invitationList) | |||||
| log.Info("query invitationList size=" + fmt.Sprint(len(invitationList))) | |||||
| for _, invitationRecord := range invitationList { | |||||
| if _, ok := resultMap[invitationRecord.SrcUserID]; !ok { | |||||
| resultMap[invitationRecord.SrcUserID] = 1 | |||||
| } else { | |||||
| resultMap[invitationRecord.SrcUserID] += 1 | |||||
| } | |||||
| } | |||||
| indexTotal += PAGE_SIZE | |||||
| if indexTotal >= count { | |||||
| break | |||||
| } | |||||
| } | |||||
| log.Info("invitationList size=" + fmt.Sprint(len(resultMap))) | |||||
| return resultMap | |||||
| } | |||||
| func setMapKey(key string, userId int64, value int, resultItemMap map[string]int) { | func setMapKey(key string, userId int64, value int, resultItemMap map[string]int) { | ||||
| newKey := fmt.Sprint(userId) + "_" + key | newKey := fmt.Sprint(userId) + "_" + key | ||||
| if _, ok := resultItemMap[newKey]; !ok { | if _, ok := resultItemMap[newKey]; !ok { | ||||
| @@ -66,7 +66,8 @@ type UserBusinessAnalysisCurrentYear struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysisLast30Day struct { | type UserBusinessAnalysisLast30Day struct { | ||||
| @@ -133,7 +134,8 @@ type UserBusinessAnalysisLast30Day struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysisLastMonth struct { | type UserBusinessAnalysisLastMonth struct { | ||||
| @@ -200,7 +202,8 @@ type UserBusinessAnalysisLastMonth struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysisCurrentMonth struct { | type UserBusinessAnalysisCurrentMonth struct { | ||||
| @@ -267,7 +270,8 @@ type UserBusinessAnalysisCurrentMonth struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysisCurrentWeek struct { | type UserBusinessAnalysisCurrentWeek struct { | ||||
| @@ -335,7 +339,8 @@ type UserBusinessAnalysisCurrentWeek struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysisYesterday struct { | type UserBusinessAnalysisYesterday struct { | ||||
| @@ -403,7 +408,8 @@ type UserBusinessAnalysisYesterday struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserBusinessAnalysisLastWeek struct { | type UserBusinessAnalysisLastWeek struct { | ||||
| @@ -471,7 +477,8 @@ type UserBusinessAnalysisLastWeek struct { | |||||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | ||||
| Phone string `xorm:"NULL"` | |||||
| Phone string `xorm:"NULL"` | |||||
| InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"` | |||||
| } | } | ||||
| type UserAnalysisPara struct { | type UserAnalysisPara struct { | ||||
| @@ -0,0 +1,102 @@ | |||||
| package models | |||||
| import ( | |||||
| "fmt" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| ) | |||||
| // Follow represents relations of user and his/her followers. | |||||
| type Invitation struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| SrcUserID int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| UserID int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| Phone string `xorm:"INDEX"` | |||||
| Avatar string `xorm:"-"` | |||||
| Name string `xorm:"-"` | |||||
| InvitationUserNum int `xorm:"-"` | |||||
| IsActive bool `xorm:"-"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| } | |||||
| func QueryInvitaionByPhone(phone string) []*Invitation { | |||||
| statictisSess := xStatistic.NewSession() | |||||
| defer statictisSess.Close() | |||||
| cond := "phone ='" + phone + "'" | |||||
| invitationList := make([]*Invitation, 0) | |||||
| if err := statictisSess.Table(new(Invitation)).Where(cond). | |||||
| Find(&invitationList); err != nil { | |||||
| return nil | |||||
| } else { | |||||
| return invitationList | |||||
| } | |||||
| } | |||||
| func GetAllUserName() map[int64]string { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| sess.Select("id,name").Table("user") | |||||
| userList := make([]*User, 0) | |||||
| reMap := make(map[int64]string) | |||||
| sess.Find(&userList) | |||||
| for _, user := range userList { | |||||
| reMap[user.ID] = user.Name | |||||
| } | |||||
| return reMap | |||||
| } | |||||
| func QueryInvitaionPage(start int, pageSize int) ([]*Invitation, int64) { | |||||
| statictisSess := xStatistic.NewSession() | |||||
| defer statictisSess.Close() | |||||
| //cond := "created_unix >=" + fmt.Sprint(startTime) + " and created_unix <=" + fmt.Sprint(endTime) | |||||
| allCount, err := statictisSess.Count(new(Invitation)) | |||||
| if err != nil { | |||||
| log.Info("query error." + err.Error()) | |||||
| return nil, 0 | |||||
| } | |||||
| invitationList := make([]*Invitation, 0) | |||||
| if err := statictisSess.Table(new(Invitation)).OrderBy("created_unix desc").Limit(pageSize, start). | |||||
| Find(&invitationList); err != nil { | |||||
| return nil, 0 | |||||
| } | |||||
| return invitationList, allCount | |||||
| } | |||||
| func QueryInvitaionByTime(startTime int64, endTime int64) []*Invitation { | |||||
| statictisSess := xStatistic.NewSession() | |||||
| defer statictisSess.Close() | |||||
| cond := "created_unix >=" + fmt.Sprint(startTime) + " and created_unix <=" + fmt.Sprint(endTime) | |||||
| invitationList := make([]*Invitation, 0) | |||||
| if err := statictisSess.Table(new(Invitation)).Where(cond).OrderBy("created_unix desc"). | |||||
| Find(&invitationList); err != nil { | |||||
| return nil | |||||
| } | |||||
| return invitationList | |||||
| } | |||||
| func InsertInvitaion(invitationUser *Invitation) error { | |||||
| statictisSess := xStatistic.NewSession() | |||||
| defer statictisSess.Close() | |||||
| _, err := statictisSess.Insert(invitationUser) | |||||
| return err | |||||
| } | |||||
| func QueryInvitaionBySrcUserId(srcUserId int64, start int, pageSize int) ([]*Invitation, int64) { | |||||
| statictisSess := xStatistic.NewSession() | |||||
| defer statictisSess.Close() | |||||
| cond := "src_user_id =" + fmt.Sprint(srcUserId) | |||||
| allCount, err := statictisSess.Where(cond).Count(new(Invitation)) | |||||
| if err != nil { | |||||
| log.Info("query error." + err.Error()) | |||||
| return nil, 0 | |||||
| } | |||||
| invitationList := make([]*Invitation, 0) | |||||
| if err := statictisSess.Table(new(Invitation)).Where(cond).OrderBy("created_unix desc").Limit(pageSize, start). | |||||
| Find(&invitationList); err != nil { | |||||
| return nil, 0 | |||||
| } | |||||
| return invitationList, allCount | |||||
| } | |||||
| @@ -372,7 +372,7 @@ func (f *U2FDeleteForm) Validate(ctx *macaron.Context, errs binding.Errors) bind | |||||
| type PhoneNumberForm struct { | type PhoneNumberForm struct { | ||||
| PhoneNumber string `binding:"Required;MaxSize(20)"` | PhoneNumber string `binding:"Required;MaxSize(20)"` | ||||
| Mode int `binding:"Required"` | |||||
| Mode int `binding:"Required"` | |||||
| SlideID string `binding:"Required;MaxSize(100)"` | SlideID string `binding:"Required;MaxSize(100)"` | ||||
| } | } | ||||
| @@ -1,14 +1,15 @@ | |||||
| package grampus | package grampus | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "crypto/tls" | "crypto/tls" | ||||
| "encoding/json" | "encoding/json" | ||||
| "fmt" | "fmt" | ||||
| "github.com/go-resty/resty/v2" | |||||
| "net/http" | "net/http" | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "github.com/go-resty/resty/v2" | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| @@ -236,7 +237,7 @@ func GetTrainJobLog(jobID string) (string, error) { | |||||
| return logContent, fmt.Errorf("json.Unmarshal failed(%s): %v", res.String(), err.Error()) | return logContent, fmt.Errorf("json.Unmarshal failed(%s): %v", res.String(), err.Error()) | ||||
| } | } | ||||
| log.Error("GetTrainJobLog failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) | log.Error("GetTrainJobLog failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) | ||||
| return logContent, fmt.Errorf("GetTrainJobLog failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) | |||||
| return logContent, fmt.Errorf("GetTrainJobLog failed(%d):%d(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) | |||||
| } | } | ||||
| logContent = res.String() | logContent = res.String() | ||||
| @@ -66,9 +66,10 @@ const ( | |||||
| ) | ) | ||||
| type C2NetSequenceInfo struct { | type C2NetSequenceInfo struct { | ||||
| ID int `json:"id"` | |||||
| Name string `json:"name"` | |||||
| Content string `json:"content"` | |||||
| ID int `json:"id"` | |||||
| Name string `json:"name"` | |||||
| Content string `json:"content"` | |||||
| ContentEN string `json:"content_en"` | |||||
| } | } | ||||
| type C2NetSqInfos struct { | type C2NetSqInfos struct { | ||||
| @@ -1475,7 +1476,7 @@ func NewContext() { | |||||
| FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | ||||
| TrainJobFLAVORINFOS = sec.Key("TrainJob_FLAVOR_INFOS").MustString("") | TrainJobFLAVORINFOS = sec.Key("TrainJob_FLAVOR_INFOS").MustString("") | ||||
| ModelArtsSpecialPools = sec.Key("SPECIAL_POOL").MustString("") | ModelArtsSpecialPools = sec.Key("SPECIAL_POOL").MustString("") | ||||
| ModelArtsMultiNode=sec.Key("MULTI_NODE").MustString("") | |||||
| ModelArtsMultiNode = sec.Key("MULTI_NODE").MustString("") | |||||
| sec = Cfg.Section("elk") | sec = Cfg.Section("elk") | ||||
| ElkUrl = sec.Key("ELKURL").MustString("") | ElkUrl = sec.Key("ELKURL").MustString("") | ||||
| @@ -1570,7 +1571,7 @@ func getGrampusConfig() { | |||||
| Grampus.UserName = sec.Key("USERNAME").MustString("") | Grampus.UserName = sec.Key("USERNAME").MustString("") | ||||
| Grampus.Password = sec.Key("PASSWORD").MustString("") | Grampus.Password = sec.Key("PASSWORD").MustString("") | ||||
| Grampus.SpecialPools = sec.Key("SPECIAL_POOL").MustString("") | Grampus.SpecialPools = sec.Key("SPECIAL_POOL").MustString("") | ||||
| Grampus.C2NetSequence = sec.Key("C2NET_SEQUENCE").MustString("{\"sequence\":[{\"id\":1,\"name\":\"cloudbrain_one\",\"content\":\"鹏城云脑一号\"},{\"id\":2,\"name\":\"cloudbrain_two\",\"content\":\"鹏城云脑二号\"},{\"id\":3,\"name\":\"beida\",\"content\":\"北大人工智能集群系统\"},{\"id\":4,\"name\":\"hefei\",\"content\":\"合肥类脑智能开放平台\"},{\"id\":5,\"name\":\"wuhan\",\"content\":\"武汉人工智能计算中心\"},{\"id\":6,\"name\":\"xian\",\"content\":\"西安未来人工智能计算中心\"},{\"id\":7,\"pclcci\":\"more\",\"content\":\"鹏城云计算所\"},{\"id\":8,\"name\":\"xuchang\",\"content\":\"中原人工智能计算中心\"},{\"id\":9,\"name\":\"chengdu\",\"content\":\"成都人工智能计算中心\"},{\"id\":10,\"name\":\"more\",\"content\":\"横琴先进智能计算中心\"},{\"id\":11,\"name\":\"more\",\"content\":\"国家超级计算济南中心\"}]}") | |||||
| Grampus.C2NetSequence = sec.Key("C2NET_SEQUENCE").MustString("{\"sequence\":[{\"id\":1,\"name\":\"cloudbrain_one\",\"content\":\"鹏城云脑一号\",\"content_en\":\"Pencheng Cloudbrain Ⅰ\"},{\"id\":2,\"name\":\"cloudbrain_two\",\"content\":\"鹏城云脑二号\",\"content_en\":\"Pencheng Cloudbrain Ⅱ\"},{\"id\":3,\"name\":\"beida\",\"content\":\"北大人工智能集群系统\",\"content_en\":\"Peking University AI Center\"},{\"id\":4,\"name\":\"hefei\",\"content\":\"合肥类脑智能开放平台\",\"content_en\":\"Hefei AI Center\"},{\"id\":5,\"name\":\"wuhan\",\"content\":\"武汉人工智能计算中心\",\"content_en\":\"Wuhan AI Center\"},{\"id\":6,\"name\":\"xian\",\"content\":\"西安未来人工智能计算中心\",\"content_en\":\"Xi'an AI Center\"},{\"id\":7,\"pclcci\":\"more\",\"content\":\"鹏城云计算所\",\"content_en\":\"Pengcheng Cloud Computing Institute\"},{\"id\":8,\"name\":\"xuchang\",\"content\":\"中原人工智能计算中心\",\"content_en\":\"Zhongyuan AI Center\"},{\"id\":9,\"name\":\"chengdu\",\"content\":\"成都人工智能计算中心\",\"content_en\":\"Chengdu AI Center\"},{\"id\":10,\"name\":\"more\",\"content\":\"横琴先进智能计算中心\",\"content_en\":\"Hengqin AI Center\"},{\"id\":11,\"name\":\"more\",\"content\":\"国家超级计算济南中心\",\"content_en\":\"HPC & AI Center\"}]}") | |||||
| if Grampus.C2NetSequence != "" { | if Grampus.C2NetSequence != "" { | ||||
| if err := json.Unmarshal([]byte(Grampus.C2NetSequence), &C2NetInfos); err != nil { | if err := json.Unmarshal([]byte(Grampus.C2NetSequence), &C2NetInfos); err != nil { | ||||
| log.Error("Unmarshal(C2NetSequence) failed:%v", err) | log.Error("Unmarshal(C2NetSequence) failed:%v", err) | ||||
| @@ -70,6 +70,10 @@ your_dashboard = Dashboard | |||||
| your_profile = Profile | your_profile = Profile | ||||
| your_starred = Starred | your_starred = Starred | ||||
| your_settings = Settings | your_settings = Settings | ||||
| invite_friends = Invite Friends | |||||
| your_friend=Your friend | |||||
| invite_you_to_join_the_OpenI_AI_Collaboration_Platform_and_enjoy_abundant_free_computing_resources=invite you to join the OpenI AI Collaboration Platform and enjoy abundant free computing resources! | |||||
| recommender=Recommender | |||||
| all = All | all = All | ||||
| sources = Sources | sources = Sources | ||||
| @@ -532,6 +536,10 @@ form.name_reserved = The username '%s' is reserved. | |||||
| form.name_pattern_not_allowed = The pattern '%s' is not allowed in a username. | form.name_pattern_not_allowed = The pattern '%s' is not allowed in a username. | ||||
| form.name_chars_not_allowed = User name '%s' contains invalid characters. | form.name_chars_not_allowed = User name '%s' contains invalid characters. | ||||
| static.invitationdetailsheetname=User Invitation Detail | |||||
| static.invitationNum=User Invitation Count | |||||
| static.invitationsheetname=User Invitation | |||||
| static.srcUserId=Recommended User ID | |||||
| static.sheetname=User Analysis | static.sheetname=User Analysis | ||||
| static.id=ID | static.id=ID | ||||
| static.name=User Name | static.name=User Name | ||||
| @@ -1293,6 +1301,7 @@ modelconvert.taskurlname=Model transformation task | |||||
| log_scroll_start=Scroll to top | log_scroll_start=Scroll to top | ||||
| log_scroll_end=Scroll to bottom | log_scroll_end=Scroll to bottom | ||||
| modelconvert.tasknameempty=Please enter a task name. | modelconvert.tasknameempty=Please enter a task name. | ||||
| modelconvert.modelfileempty=Please choose a model file. | |||||
| modelconvert.inputshapeerror=Format input error, please input such as: 1,1,32,32, corresponding to the input data format. | modelconvert.inputshapeerror=Format input error, please input such as: 1,1,32,32, corresponding to the input data format. | ||||
| modelconvert.manage.create_error1=A model transformation task with the same name already exists. | modelconvert.manage.create_error1=A model transformation task with the same name already exists. | ||||
| @@ -70,6 +70,10 @@ your_dashboard=个人中心 | |||||
| your_profile=个人信息 | your_profile=个人信息 | ||||
| your_starred=已点赞 | your_starred=已点赞 | ||||
| your_settings=设置 | your_settings=设置 | ||||
| invite_friends=邀请好友 | |||||
| your_friend=您的好友 | |||||
| invite_you_to_join_the_OpenI_AI_Collaboration_Platform_and_enjoy_abundant_free_computing_resources=邀请您加入启智社区AI协作平台,畅享充沛的免费算力资源! | |||||
| recommender=推荐人 | |||||
| all=所有 | all=所有 | ||||
| sources=自建 | sources=自建 | ||||
| @@ -537,7 +541,11 @@ form.name_reserved='%s' 用户名被保留。 | |||||
| form.name_pattern_not_allowed=用户名中不允许使用 "%s"。 | form.name_pattern_not_allowed=用户名中不允许使用 "%s"。 | ||||
| form.name_chars_not_allowed=用户名 '%s' 包含无效字符。 | form.name_chars_not_allowed=用户名 '%s' 包含无效字符。 | ||||
| static.invitationdetailsheetname=用户邀请详细数据 | |||||
| static.invitationNum=邀请用户数 | |||||
| static.sheetname=用户分析 | static.sheetname=用户分析 | ||||
| static.srcUserId=推荐用户ID | |||||
| static.invitationsheetname=用户邀请分析 | |||||
| static.id=ID | static.id=ID | ||||
| static.name=用户名 | static.name=用户名 | ||||
| static.codemergecount=PR数 | static.codemergecount=PR数 | ||||
| @@ -1309,6 +1317,7 @@ log_scroll_start=滚动到顶部 | |||||
| log_scroll_end=滚动到底部 | log_scroll_end=滚动到底部 | ||||
| modelconvert.tasknameempty=请输入任务名称。 | modelconvert.tasknameempty=请输入任务名称。 | ||||
| modelconvert.inputshapeerror=格式输入错误,请输入如:1,1,32,32,与输入数据格式对应。 | modelconvert.inputshapeerror=格式输入错误,请输入如:1,1,32,32,与输入数据格式对应。 | ||||
| modelconvert.modelfileempty=请选择模型文件。 | |||||
| modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。 | modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。 | ||||
| modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。 | modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。 | ||||
| @@ -572,6 +572,19 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/query_user_all", operationReq, repo_ext.QueryUserStaticAll) | m.Get("/query_user_all", operationReq, repo_ext.QueryUserStaticAll) | ||||
| m.Get("/query_user_activity", operationReq, repo_ext.QueryUserActivity) | m.Get("/query_user_activity", operationReq, repo_ext.QueryUserActivity) | ||||
| m.Get("/query_user_login", operationReq, repo_ext.QueryUserLoginInfo) | m.Get("/query_user_login", operationReq, repo_ext.QueryUserLoginInfo) | ||||
| m.Get("/query_invitation_current_month", operationReq, repo_ext.QueryInvitationCurrentMonth) | |||||
| m.Get("/query_invitation_current_week", operationReq, repo_ext.QueryInvitationCurrentWeek) | |||||
| m.Get("/query_invitation_last_week", operationReq, repo_ext.QueryInvitationLastWeek) | |||||
| m.Get("/query_invitation_current_year", operationReq, repo_ext.QueryInvitationCurrentYear) | |||||
| m.Get("/query_invitation_last30_day", operationReq, repo_ext.QueryInvitationLast30Day) | |||||
| m.Get("/query_invitation_last_month", operationReq, repo_ext.QueryInvitationLastMonth) | |||||
| m.Get("/query_invitation_yesterday", operationReq, repo_ext.QueryInvitationYesterday) | |||||
| m.Get("/query_invitation_all", operationReq, repo_ext.QueryInvitationAll) | |||||
| m.Get("/query_invitation_userdefine", operationReq, repo_ext.QueryUserDefineInvitationPage) | |||||
| m.Get("/download_invitation_detail", operationReq, repo_ext.DownloadInvitationDetail) | |||||
| //cloudbrain board | //cloudbrain board | ||||
| m.Group("/cloudbrainboard", func() { | m.Group("/cloudbrainboard", func() { | ||||
| m.Get("/downloadAll", repo.DownloadCloudBrainBoard) | m.Get("/downloadAll", repo.DownloadCloudBrainBoard) | ||||
| @@ -969,6 +982,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("", repo.GetModelArtsTrainJobVersion) | m.Get("", repo.GetModelArtsTrainJobVersion) | ||||
| m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.GrampusStopJob) | m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.GrampusStopJob) | ||||
| m.Get("/log", repo_ext.GrampusGetLog) | m.Get("/log", repo_ext.GrampusGetLog) | ||||
| m.Get("/download_log", cloudbrain.AdminOrJobCreaterRightForTrain, repo_ext.GrampusDownloadLog) | |||||
| }) | }) | ||||
| }) | }) | ||||
| }, reqRepoReader(models.UnitTypeCloudBrain)) | }, reqRepoReader(models.UnitTypeCloudBrain)) | ||||
| @@ -379,7 +379,11 @@ func CloudbrainDownloadLogFile(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| prefix := "/" + setting.CBCodePathPrefix + job.JobName + "/model" | |||||
| logDir := "/model" | |||||
| if job.JobType == string(models.JobTypeInference) { | |||||
| logDir = cloudbrain.ResultPath | |||||
| } | |||||
| prefix := "/" + setting.CBCodePathPrefix + job.JobName + logDir | |||||
| files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("query cloudbrain model failed: %v", err) | log.Error("query cloudbrain model failed: %v", err) | ||||
| @@ -106,6 +106,11 @@ func Dashboard(ctx *context.Context) { | |||||
| log.Info("set image info=" + pictureInfo[0]["url"]) | log.Info("set image info=" + pictureInfo[0]["url"]) | ||||
| ctx.Data["image_url"] = pictureInfo[0]["url"] | ctx.Data["image_url"] = pictureInfo[0]["url"] | ||||
| ctx.Data["image_link"] = pictureInfo[0]["image_link"] | ctx.Data["image_link"] = pictureInfo[0]["image_link"] | ||||
| if len(pictureInfo) > 1 { | |||||
| ctx.Data["invite_image_url"] = pictureInfo[1]["url"] | |||||
| ctx.Data["invite_image_link"] = pictureInfo[1]["image_link"] | |||||
| } | |||||
| } | } | ||||
| if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { | if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { | ||||
| ctx.Data["Title"] = ctx.Tr("auth.active_your_account") | ctx.Data["Title"] = ctx.Tr("auth.active_your_account") | ||||
| @@ -728,6 +733,16 @@ func getImageInfo(filename string) ([]map[string]string, error) { | |||||
| return imageInfo, nil | return imageInfo, nil | ||||
| } | } | ||||
| func GetMapInfo(ctx *context.Context) { | |||||
| filename := ctx.Query("filename") | |||||
| url := setting.RecommentRepoAddr + filename | |||||
| result, err := repository.RecommendContentFromPromote(url) | |||||
| if err != nil { | |||||
| log.Info("get file error:" + err.Error()) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, result) | |||||
| } | |||||
| func GetRankUser(index string) ([]map[string]interface{}, error) { | func GetRankUser(index string) ([]map[string]interface{}, error) { | ||||
| url := setting.RecommentRepoAddr + "user_rank_" + index | url := setting.RecommentRepoAddr + "user_rank_" + index | ||||
| result, err := repository.RecommendFromPromote(url) | result, err := repository.RecommendFromPromote(url) | ||||
| @@ -27,6 +27,9 @@ const ( | |||||
| MODEL_LATEST = 1 | MODEL_LATEST = 1 | ||||
| MODEL_NOT_LATEST = 0 | MODEL_NOT_LATEST = 0 | ||||
| MODEL_MAX_SIZE = 1024 * 1024 * 1024 | MODEL_MAX_SIZE = 1024 * 1024 * 1024 | ||||
| STATUS_COPY_MODEL = 1 | |||||
| STATUS_FINISHED = 0 | |||||
| STATUS_ERROR = 2 | |||||
| ) | ) | ||||
| func saveModelByParameters(jobId string, versionName string, name string, version string, label string, description string, engine int, ctx *context.Context) error { | func saveModelByParameters(jobId string, versionName string, name string, version string, label string, description string, engine int, ctx *context.Context) error { | ||||
| @@ -62,13 +65,9 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
| modelSelectedFile := ctx.Query("modelSelectedFile") | modelSelectedFile := ctx.Query("modelSelectedFile") | ||||
| //download model zip //train type | //download model zip //train type | ||||
| if aiTask.ComputeResource == models.NPUResource { | if aiTask.ComputeResource == models.NPUResource { | ||||
| modelPath, modelSize, err = downloadModelFromCloudBrainTwo(id, aiTask.JobName, "", aiTask.TrainUrl, modelSelectedFile) | |||||
| if err != nil { | |||||
| log.Info("download model from CloudBrainTwo faild." + err.Error()) | |||||
| return err | |||||
| } | |||||
| cloudType = models.TypeCloudBrainTwo | cloudType = models.TypeCloudBrainTwo | ||||
| } else if aiTask.ComputeResource == models.GPUResource { | } else if aiTask.ComputeResource == models.GPUResource { | ||||
| cloudType = models.TypeCloudBrainOne | |||||
| var ResourceSpecs *models.ResourceSpecs | var ResourceSpecs *models.ResourceSpecs | ||||
| json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | ||||
| for _, tmp := range ResourceSpecs.ResourceSpec { | for _, tmp := range ResourceSpecs.ResourceSpec { | ||||
| @@ -77,24 +76,8 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
| aiTask.FlavorName = flaverName | aiTask.FlavorName = flaverName | ||||
| } | } | ||||
| } | } | ||||
| modelPath, modelSize, err = downloadModelFromCloudBrainOne(id, aiTask.JobName, "", aiTask.TrainUrl, modelSelectedFile) | |||||
| if err != nil { | |||||
| log.Info("download model from CloudBrainOne faild." + err.Error()) | |||||
| return err | |||||
| } | |||||
| cloudType = models.TypeCloudBrainOne | |||||
| } | } | ||||
| // else if cloudType == models.TypeC2Net { | |||||
| // if aiTask.ComputeResource == models.NPUResource { | |||||
| // modelPath, modelSize, err = downloadModelFromCloudBrainTwo(id, aiTask.JobName, "", aiTask.TrainUrl, modelSelectedFile) | |||||
| // if err != nil { | |||||
| // log.Info("download model from CloudBrainTwo faild." + err.Error()) | |||||
| // return err | |||||
| // } | |||||
| // } else if aiTask.ComputeResource == models.GPUResource { | |||||
| // } | |||||
| // } | |||||
| accuracy := make(map[string]string) | accuracy := make(map[string]string) | ||||
| accuracy["F1"] = "" | accuracy["F1"] = "" | ||||
| accuracy["Recall"] = "" | accuracy["Recall"] = "" | ||||
| @@ -123,6 +106,7 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
| Engine: int64(engine), | Engine: int64(engine), | ||||
| TrainTaskInfo: string(aiTaskJson), | TrainTaskInfo: string(aiTaskJson), | ||||
| Accuracy: string(accuracyJson), | Accuracy: string(accuracyJson), | ||||
| Status: STATUS_COPY_MODEL, | |||||
| } | } | ||||
| err = models.SaveModelToDb(model) | err = models.SaveModelToDb(model) | ||||
| @@ -146,11 +130,44 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
| models.UpdateRepositoryUnits(ctx.Repo.Repository, units, deleteUnitTypes) | models.UpdateRepositoryUnits(ctx.Repo.Repository, units, deleteUnitTypes) | ||||
| go asyncToCopyModel(aiTask, id, modelSelectedFile) | |||||
| log.Info("save model end.") | log.Info("save model end.") | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, name, models.ActionCreateNewModelTask) | notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, name, models.ActionCreateNewModelTask) | ||||
| return nil | return nil | ||||
| } | } | ||||
| func asyncToCopyModel(aiTask *models.Cloudbrain, id string, modelSelectedFile string) { | |||||
| if aiTask.ComputeResource == models.NPUResource { | |||||
| modelPath, modelSize, err := downloadModelFromCloudBrainTwo(id, aiTask.JobName, "", aiTask.TrainUrl, modelSelectedFile) | |||||
| if err != nil { | |||||
| updateStatus(id, 0, STATUS_ERROR, modelPath, err.Error()) | |||||
| log.Info("download model from CloudBrainTwo faild." + err.Error()) | |||||
| } else { | |||||
| updateStatus(id, modelSize, STATUS_FINISHED, modelPath, "") | |||||
| } | |||||
| } else if aiTask.ComputeResource == models.GPUResource { | |||||
| modelPath, modelSize, err := downloadModelFromCloudBrainOne(id, aiTask.JobName, "", aiTask.TrainUrl, modelSelectedFile) | |||||
| if err != nil { | |||||
| updateStatus(id, 0, STATUS_ERROR, modelPath, err.Error()) | |||||
| log.Info("download model from CloudBrainOne faild." + err.Error()) | |||||
| } else { | |||||
| updateStatus(id, modelSize, STATUS_FINISHED, modelPath, "") | |||||
| } | |||||
| } | |||||
| } | |||||
| func updateStatus(id string, modelSize int64, status int, modelPath string, statusDesc string) { | |||||
| if len(statusDesc) > 400 { | |||||
| statusDesc = statusDesc[0:400] | |||||
| } | |||||
| err := models.ModifyModelStatus(id, modelSize, status, modelPath, statusDesc) | |||||
| if err != nil { | |||||
| log.Info("update status error." + err.Error()) | |||||
| } | |||||
| } | |||||
| func SaveNewNameModel(ctx *context.Context) { | func SaveNewNameModel(ctx *context.Context) { | ||||
| if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { | if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { | ||||
| ctx.Error(403, ctx.Tr("repo.model_noright")) | ctx.Error(403, ctx.Tr("repo.model_noright")) | ||||
| @@ -331,6 +348,7 @@ func QueryModelByParameters(repoId int64, page int) ([]*models.AiModelManage, in | |||||
| RepoID: repoId, | RepoID: repoId, | ||||
| Type: -1, | Type: -1, | ||||
| New: MODEL_LATEST, | New: MODEL_LATEST, | ||||
| Status: -1, | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -642,7 +660,6 @@ func queryUserName(intSlice []int64) map[int64]*models.User { | |||||
| result[user.ID] = user | result[user.ID] = user | ||||
| } | } | ||||
| } | } | ||||
| return result | return result | ||||
| } | } | ||||
| @@ -685,6 +702,7 @@ func SetModelCount(ctx *context.Context) { | |||||
| RepoID: repoId, | RepoID: repoId, | ||||
| Type: Type, | Type: Type, | ||||
| New: MODEL_LATEST, | New: MODEL_LATEST, | ||||
| Status: -1, | |||||
| }) | }) | ||||
| ctx.Data["MODEL_COUNT"] = count | ctx.Data["MODEL_COUNT"] = count | ||||
| } | } | ||||
| @@ -758,6 +776,7 @@ func ShowModelPageInfo(ctx *context.Context) { | |||||
| RepoID: repoId, | RepoID: repoId, | ||||
| Type: Type, | Type: Type, | ||||
| New: MODEL_LATEST, | New: MODEL_LATEST, | ||||
| Status: -1, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("Cloudbrain", err) | ctx.ServerError("Cloudbrain", err) | ||||
| @@ -835,6 +854,7 @@ func QueryModelListForPredict(ctx *context.Context) { | |||||
| RepoID: repoId, | RepoID: repoId, | ||||
| Type: ctx.QueryInt("type"), | Type: ctx.QueryInt("type"), | ||||
| New: -1, | New: -1, | ||||
| Status: 0, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("Cloudbrain", err) | ctx.ServerError("Cloudbrain", err) | ||||
| @@ -896,12 +916,17 @@ func QueryOneLevelModelFile(ctx *context.Context) { | |||||
| log.Info("TypeCloudBrainTwo list model file.") | log.Info("TypeCloudBrainTwo list model file.") | ||||
| prefix := model.Path[len(setting.Bucket)+1:] | prefix := model.Path[len(setting.Bucket)+1:] | ||||
| fileinfos, _ := storage.GetOneLevelAllObjectUnderDir(setting.Bucket, prefix, parentDir) | fileinfos, _ := storage.GetOneLevelAllObjectUnderDir(setting.Bucket, prefix, parentDir) | ||||
| if fileinfos == nil { | |||||
| fileinfos = make([]storage.FileInfo, 0) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, fileinfos) | ctx.JSON(http.StatusOK, fileinfos) | ||||
| } else if model.Type == models.TypeCloudBrainOne { | } else if model.Type == models.TypeCloudBrainOne { | ||||
| log.Info("TypeCloudBrainOne list model file.") | log.Info("TypeCloudBrainOne list model file.") | ||||
| prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:] | prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:] | ||||
| fileinfos, _ := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, parentDir) | fileinfos, _ := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, parentDir) | ||||
| if fileinfos == nil { | |||||
| fileinfos = make([]storage.FileInfo, 0) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, fileinfos) | ctx.JSON(http.StatusOK, fileinfos) | ||||
| } | } | ||||
| } | } | ||||
| @@ -914,7 +914,7 @@ func GrampusTrainJobShow(ctx *context.Context) { | |||||
| ctx.HTML(http.StatusOK, tplGrampusTrainJobShow) | ctx.HTML(http.StatusOK, tplGrampusTrainJobShow) | ||||
| } | } | ||||
| func GrampusGetLog(ctx *context.Context) { | |||||
| func GrampusDownloadLog(ctx *context.Context) { | |||||
| jobID := ctx.Params(":jobid") | jobID := ctx.Params(":jobid") | ||||
| job, err := models.GetCloudbrainByJobID(jobID) | job, err := models.GetCloudbrainByJobID(jobID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -926,13 +926,40 @@ func GrampusGetLog(ctx *context.Context) { | |||||
| content, err := grampus.GetTrainJobLog(job.JobID) | content, err := grampus.GetTrainJobLog(job.JobID) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetTrainJobLog failed: %v", err, ctx.Data["MsgID"]) | log.Error("GetTrainJobLog failed: %v", err, ctx.Data["MsgID"]) | ||||
| content = "" | |||||
| } | |||||
| fileName := job.JobName + "-log.txt" | |||||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+fileName) | |||||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||||
| var b []byte = []byte(content) | |||||
| ctx.Resp.Write(b) | |||||
| } | |||||
| func GrampusGetLog(ctx *context.Context) { | |||||
| jobID := ctx.Params(":jobid") | |||||
| job, err := models.GetCloudbrainByJobID(jobID) | |||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByJobID failed: %v", err, ctx.Data["MsgID"]) | |||||
| ctx.ServerError(err.Error(), err) | ctx.ServerError(err.Error(), err) | ||||
| return | return | ||||
| } | } | ||||
| content, err := grampus.GetTrainJobLog(job.JobID) | |||||
| if err != nil { | |||||
| log.Error("GetTrainJobLog failed: %v", err, ctx.Data["MsgID"]) | |||||
| ctx.ServerError(err.Error(), err) | |||||
| return | |||||
| } | |||||
| var canLogDownload bool | |||||
| if err != nil { | |||||
| canLogDownload = false | |||||
| } else { | |||||
| canLogDownload = true | |||||
| } | |||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "JobName": job.JobName, | |||||
| "Content": content, | |||||
| "JobName": job.JobName, | |||||
| "Content": content, | |||||
| "CanLogDownload": canLogDownload, | |||||
| }) | }) | ||||
| return | return | ||||
| @@ -1551,7 +1551,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| }) | }) | ||||
| } | } | ||||
| task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, PreVersionName) | task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, PreVersionName) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error()) | log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error()) | ||||
| @@ -2322,6 +2321,7 @@ func InferenceJobIndex(ctx *context.Context) { | |||||
| RepoID: repoId, | RepoID: repoId, | ||||
| Type: Type, | Type: Type, | ||||
| New: MODEL_LATEST, | New: MODEL_LATEST, | ||||
| Status: 0, | |||||
| }) | }) | ||||
| ctx.Data["MODEL_COUNT"] = model_count | ctx.Data["MODEL_COUNT"] = model_count | ||||
| @@ -2402,6 +2402,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
| RepoID: repoId, | RepoID: repoId, | ||||
| Type: Type, | Type: Type, | ||||
| New: MODEL_LATEST, | New: MODEL_LATEST, | ||||
| Status: 0, | |||||
| }) | }) | ||||
| ctx.Data["MODEL_COUNT"] = model_count | ctx.Data["MODEL_COUNT"] = model_count | ||||
| ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ||||
| @@ -0,0 +1,440 @@ | |||||
| package repo | |||||
| import ( | |||||
| "fmt" | |||||
| "net/http" | |||||
| "net/url" | |||||
| "sort" | |||||
| "time" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "github.com/360EntSecGroup-Skylar/excelize/v2" | |||||
| ) | |||||
| func QueryInvitationCurrentMonth(ctx *context.Context) { | |||||
| // userName := ctx.Query("userName") | |||||
| // currentTimeNow := time.Now() | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| //queryUserDataPage(ctx, "public.user_business_analysis_current_month", new(models.UserBusinessAnalysisCurrentMonth)) | |||||
| //_, count := models.QueryUserStaticDataByTableName(1, 1, "public.user_business_analysis_current_month", new(models.UserBusinessAnalysisCurrentMonth), userName, 1) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_current_month", new(models.UserBusinessAnalysisCurrentMonth)) | |||||
| } | |||||
| func getInvitationExcelHeader(ctx *context.Context) map[string]string { | |||||
| excelHeader := make([]string, 0) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.id")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.name")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.invitationNum")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.phone")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.registdate")) | |||||
| excelHeaderMap := make(map[string]string, 0) | |||||
| var i byte | |||||
| i = 0 | |||||
| for _, value := range excelHeader { | |||||
| excelColumn := getColumn(i) + fmt.Sprint(1) | |||||
| excelHeaderMap[excelColumn] = value | |||||
| i++ | |||||
| } | |||||
| return excelHeaderMap | |||||
| } | |||||
| func getInvitationDetailExcelHeader(ctx *context.Context) map[string]string { | |||||
| excelHeader := make([]string, 0) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.id")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.name")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.srcUserId")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.phone")) | |||||
| excelHeader = append(excelHeader, ctx.Tr("user.static.registdate")) | |||||
| excelHeaderMap := make(map[string]string, 0) | |||||
| var i byte | |||||
| i = 0 | |||||
| for _, value := range excelHeader { | |||||
| excelColumn := getColumn(i) + fmt.Sprint(1) | |||||
| excelHeaderMap[excelColumn] = value | |||||
| i++ | |||||
| } | |||||
| return excelHeaderMap | |||||
| } | |||||
| func writeInvitationExcel(row int, xlsx *excelize.File, sheetName string, userRecord *models.UserBusinessAnalysisAll) { | |||||
| rows := fmt.Sprint(row) | |||||
| var tmp byte | |||||
| tmp = 0 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.ID) | |||||
| tmp = tmp + 1 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name) | |||||
| tmp = tmp + 1 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.InvitationUserNum) | |||||
| tmp = tmp + 1 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone) | |||||
| tmp = tmp + 1 | |||||
| formatTime := userRecord.RegistDate.Format("2006-01-02 15:04:05") | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3]) | |||||
| } | |||||
| func writeInvitationDetailExcel(row int, xlsx *excelize.File, sheetName string, userRecord *models.Invitation) { | |||||
| rows := fmt.Sprint(row) | |||||
| var tmp byte | |||||
| tmp = 0 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.UserID) | |||||
| tmp = tmp + 1 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name) | |||||
| tmp = tmp + 1 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SrcUserID) | |||||
| tmp = tmp + 1 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone) | |||||
| tmp = tmp + 1 | |||||
| formatTime := userRecord.CreatedUnix.Format("2006-01-02 15:04:05") | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3]) | |||||
| } | |||||
| func DownloadInvitationDetail(ctx *context.Context) { | |||||
| xlsx := excelize.NewFile() | |||||
| sheetName := ctx.Tr("user.static.invitationdetailsheetname") | |||||
| index := xlsx.NewSheet(sheetName) | |||||
| xlsx.DeleteSheet("Sheet1") | |||||
| excelHeader := getInvitationDetailExcelHeader(ctx) | |||||
| for k, v := range excelHeader { | |||||
| //设置单元格的值 | |||||
| xlsx.SetCellValue(sheetName, k, v) | |||||
| } | |||||
| userNameMap := models.GetAllUserName() | |||||
| _, count := models.QueryInvitaionPage(1, 1) | |||||
| var indexTotal int64 | |||||
| indexTotal = 0 | |||||
| row := 1 | |||||
| for { | |||||
| re, _ := models.QueryInvitaionPage(int(indexTotal), PAGE_SIZE) | |||||
| log.Info("return count=" + fmt.Sprint(count)) | |||||
| for _, userRecord := range re { | |||||
| row++ | |||||
| userRecord.Name = userNameMap[userRecord.UserID] | |||||
| if userRecord.Name == "" { | |||||
| userRecord.Name = "已注销" | |||||
| } | |||||
| writeInvitationDetailExcel(row, xlsx, sheetName, userRecord) | |||||
| } | |||||
| indexTotal += PAGE_SIZE | |||||
| if indexTotal >= count { | |||||
| break | |||||
| } | |||||
| } | |||||
| //设置默认打开的表单 | |||||
| xlsx.SetActiveSheet(index) | |||||
| filename := sheetName + ".xlsx" | |||||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename)) | |||||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||||
| if _, err := xlsx.WriteTo(ctx.Resp); err != nil { | |||||
| log.Info("writer exel error." + err.Error()) | |||||
| } | |||||
| } | |||||
| func queryDataFromStaticTable(ctx *context.Context, tableName string, queryObj interface{}) { | |||||
| page, pageSize := getPageInfo(ctx) | |||||
| userName := ctx.Query("userName") | |||||
| IsReturnFile := ctx.QueryBool("IsReturnFile") | |||||
| if IsReturnFile { | |||||
| //writer exec file. | |||||
| xlsx := excelize.NewFile() | |||||
| sheetName := ctx.Tr("user.static.invitationsheetname") | |||||
| index := xlsx.NewSheet(sheetName) | |||||
| xlsx.DeleteSheet("Sheet1") | |||||
| excelHeader := getInvitationExcelHeader(ctx) | |||||
| for k, v := range excelHeader { | |||||
| //设置单元格的值 | |||||
| xlsx.SetCellValue(sheetName, k, v) | |||||
| } | |||||
| _, count := models.QueryUserInvitationDataByTableName(1, 1, tableName, queryObj, "", 1) | |||||
| var indexTotal int64 | |||||
| indexTotal = 0 | |||||
| row := 1 | |||||
| for { | |||||
| re, _ := models.QueryUserInvitationDataByTableName(int(indexTotal), PAGE_SIZE, tableName, queryObj, "", 1) | |||||
| log.Info("return count=" + fmt.Sprint(count)) | |||||
| for _, userRecord := range re { | |||||
| row++ | |||||
| writeInvitationExcel(row, xlsx, sheetName, userRecord) | |||||
| } | |||||
| indexTotal += PAGE_SIZE | |||||
| if indexTotal >= count { | |||||
| break | |||||
| } | |||||
| } | |||||
| //设置默认打开的表单 | |||||
| xlsx.SetActiveSheet(index) | |||||
| filename := sheetName + "_" + ctx.Tr("user.static."+tableName) + ".xlsx" | |||||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename)) | |||||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||||
| if _, err := xlsx.WriteTo(ctx.Resp); err != nil { | |||||
| log.Info("writer exel error." + err.Error()) | |||||
| } | |||||
| } else { | |||||
| resultRecord, count := models.QueryUserInvitationDataByTableName((page-1)*pageSize, pageSize, tableName, queryObj, userName, 1) | |||||
| result := make([]models.Invitation, 0) | |||||
| for _, record := range resultRecord { | |||||
| invi := models.Invitation{ | |||||
| SrcUserID: record.ID, | |||||
| Name: record.Name, | |||||
| InvitationUserNum: record.InvitationUserNum, | |||||
| Phone: record.Phone, | |||||
| CreatedUnix: record.RegistDate, | |||||
| } | |||||
| result = append(result, invi) | |||||
| } | |||||
| mapInterface := make(map[string]interface{}) | |||||
| mapInterface["data"] = result | |||||
| mapInterface["count"] = count | |||||
| ctx.JSON(http.StatusOK, mapInterface) | |||||
| } | |||||
| } | |||||
| func QueryInvitationCurrentWeek(ctx *context.Context) { | |||||
| // currentTimeNow := time.Now() | |||||
| // offset := int(time.Monday - currentTimeNow.Weekday()) | |||||
| // if offset > 0 { | |||||
| // offset = -6 | |||||
| // } | |||||
| // pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset) | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // queryData(ctx, pageStartTime.Unix(), pageEndTime.Unix()) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_current_week", new(models.UserBusinessAnalysisCurrentWeek)) | |||||
| } | |||||
| func QueryInvitationLastWeek(ctx *context.Context) { | |||||
| // currentTimeNow := time.Now() | |||||
| // offset := int(time.Monday - currentTimeNow.Weekday()) | |||||
| // if offset > 0 { | |||||
| // offset = -6 | |||||
| // } | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset) | |||||
| // pageStartTime := pageEndTime.AddDate(0, 0, -7) | |||||
| // queryData(ctx, pageStartTime.Unix(), pageEndTime.Unix()) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_last_week", new(models.UserBusinessAnalysisLastWeek)) | |||||
| } | |||||
| func QueryInvitationCurrentYear(ctx *context.Context) { | |||||
| // currentTimeNow := time.Now() | |||||
| // pageStartTime := time.Date(currentTimeNow.Year(), 1, 1, 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // queryData(ctx, pageStartTime.Unix(), pageEndTime.Unix()) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_current_year", new(models.UserBusinessAnalysisCurrentYear)) | |||||
| } | |||||
| func QueryInvitationLast30Day(ctx *context.Context) { | |||||
| // currentTimeNow := time.Now() | |||||
| // pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, -30) | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // queryData(ctx, pageStartTime.Unix(), pageEndTime.Unix()) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_last30_day", new(models.UserBusinessAnalysisLast30Day)) | |||||
| } | |||||
| func QueryInvitationLastMonth(ctx *context.Context) { | |||||
| // currentTimeNow := time.Now() | |||||
| // thisMonth := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // pageStartTime := thisMonth.AddDate(0, -1, 0) | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 23, 59, 59, 0, currentTimeNow.Location()).AddDate(0, 0, -1) | |||||
| // queryData(ctx, pageStartTime.Unix(), pageEndTime.Unix()) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_last_month", new(models.UserBusinessAnalysisLastMonth)) | |||||
| } | |||||
| func QueryInvitationYesterday(ctx *context.Context) { | |||||
| // currentTimeNow := time.Now().AddDate(0, 0, -1) | |||||
| // pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local) | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||||
| // queryData(ctx, pageStartTime.Unix(), pageEndTime.Unix()) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_yesterday", new(models.UserBusinessAnalysisYesterday)) | |||||
| } | |||||
| func QueryInvitationAll(ctx *context.Context) { | |||||
| // currentTimeNow := time.Now() | |||||
| // pageStartTime := time.Date(2022, 8, 5, 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) | |||||
| // queryData(ctx, pageStartTime.Unix(), pageEndTime.Unix()) | |||||
| queryDataFromStaticTable(ctx, "public.user_business_analysis_all", new(models.UserBusinessAnalysisAll)) | |||||
| } | |||||
| func QueryUserDefineInvitationPage(ctx *context.Context) { | |||||
| startDate := ctx.Query("startDate") | |||||
| endDate := ctx.Query("endDate") | |||||
| startTime, _ := time.ParseInLocation("2006-01-02", startDate, time.Local) | |||||
| //startTime = startTime.UTC() | |||||
| endTime, _ := time.ParseInLocation("2006-01-02", endDate, time.Local) | |||||
| queryData(ctx, startTime, endTime) | |||||
| } | |||||
| func queryData(ctx *context.Context, startTime time.Time, endTime time.Time) { | |||||
| page, pageSize := getPageInfo(ctx) | |||||
| IsReturnFile := ctx.QueryBool("IsReturnFile") | |||||
| dbResult := models.QueryInvitaionByTime(startTime.Unix(), endTime.Unix()) | |||||
| invitaionNumMap := make(map[int64]int, 0) | |||||
| allUserIds := make([]int64, 0) | |||||
| for _, record := range dbResult { | |||||
| if _, ok := invitaionNumMap[record.SrcUserID]; !ok { | |||||
| invitaionNumMap[record.SrcUserID] = 1 | |||||
| } else { | |||||
| invitaionNumMap[record.SrcUserID] = invitaionNumMap[record.SrcUserID] + 1 | |||||
| } | |||||
| } | |||||
| invitaionNumList := make([]models.Invitation, 0) | |||||
| for key, value := range invitaionNumMap { | |||||
| invi := models.Invitation{ | |||||
| SrcUserID: key, | |||||
| InvitationUserNum: value, | |||||
| } | |||||
| invitaionNumList = append(invitaionNumList, invi) | |||||
| allUserIds = append(allUserIds, key) | |||||
| } | |||||
| sort.Slice(invitaionNumList, func(i, j int) bool { | |||||
| return invitaionNumList[i].InvitationUserNum > invitaionNumList[j].InvitationUserNum | |||||
| }) | |||||
| if IsReturnFile { | |||||
| xlsx := excelize.NewFile() | |||||
| sheetName := ctx.Tr("user.static.invitationsheetname") | |||||
| index := xlsx.NewSheet(sheetName) | |||||
| xlsx.DeleteSheet("Sheet1") | |||||
| excelHeader := getInvitationExcelHeader(ctx) | |||||
| for k, v := range excelHeader { | |||||
| //设置单元格的值 | |||||
| xlsx.SetCellValue(sheetName, k, v) | |||||
| } | |||||
| end := 100 | |||||
| userMap := make(map[int64]*models.User, 0) | |||||
| log.Info("len(allUserIds)=" + fmt.Sprint(len(allUserIds))) | |||||
| for i := 0; i < len(allUserIds); i += 100 { | |||||
| if end >= len(allUserIds) { | |||||
| end = len(allUserIds) | |||||
| } | |||||
| log.Info("i=" + fmt.Sprint(i) + " end=" + fmt.Sprint(end)) | |||||
| if i == end { | |||||
| break | |||||
| } | |||||
| userList, err := models.GetUsersByIDs(allUserIds[i:end]) | |||||
| if err == nil { | |||||
| for _, tmp := range userList { | |||||
| userMap[tmp.ID] = tmp | |||||
| } | |||||
| } else { | |||||
| } | |||||
| end = end + 100 | |||||
| } | |||||
| row := 1 | |||||
| log.Info("len(userMap)=" + fmt.Sprint(len(userMap))) | |||||
| for _, userRecord := range invitaionNumList { | |||||
| row++ | |||||
| rows := fmt.Sprint(row) | |||||
| var tmp byte | |||||
| tmp = 0 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SrcUserID) | |||||
| tmp = tmp + 1 | |||||
| name := "已注销" | |||||
| if userMap[userRecord.SrcUserID] != nil { | |||||
| name = userMap[userRecord.SrcUserID].Name | |||||
| } | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, name) | |||||
| tmp = tmp + 1 | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.InvitationUserNum) | |||||
| tmp = tmp + 1 | |||||
| Phone := "" | |||||
| if userMap[userRecord.SrcUserID] != nil { | |||||
| Phone = userMap[userRecord.SrcUserID].PhoneNumber | |||||
| } | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, Phone) | |||||
| tmp = tmp + 1 | |||||
| formatTime := "" | |||||
| if userMap[userRecord.SrcUserID] != nil { | |||||
| formatTime = userMap[userRecord.SrcUserID].CreatedUnix.Format("2006-01-02 15:04:05") | |||||
| formatTime = formatTime[0 : len(formatTime)-3] | |||||
| } | |||||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime) | |||||
| } | |||||
| //设置默认打开的表单 | |||||
| xlsx.SetActiveSheet(index) | |||||
| filename := sheetName + "_" + getTimeFileName(startTime) + "_" + getTimeFileName(endTime) + ".xlsx" | |||||
| //filename := sheetName + "_" + ctx.Tr("user.static."+tableName) + ".xlsx" | |||||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename)) | |||||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||||
| if _, err := xlsx.WriteTo(ctx.Resp); err != nil { | |||||
| log.Info("writer exel error." + err.Error()) | |||||
| } | |||||
| } else { | |||||
| result := make([]*models.Invitation, 0) | |||||
| userIds := make([]int64, 0) | |||||
| end := len(invitaionNumList) - 1 | |||||
| for start := (page - 1) * pageSize; start <= end; start++ { | |||||
| invi := invitaionNumList[start] | |||||
| //todo name phone,createunix | |||||
| result = append(result, &invi) | |||||
| userIds = append(userIds, invi.SrcUserID) | |||||
| if len(result) == pageSize { | |||||
| break | |||||
| } | |||||
| } | |||||
| userList, err := models.GetUsersByIDs(userIds) | |||||
| if err == nil { | |||||
| for _, invi := range result { | |||||
| tmpUser := userList[0] | |||||
| for _, tmp := range userList { | |||||
| if tmp.ID == invi.SrcUserID { | |||||
| tmpUser = tmp | |||||
| break | |||||
| } | |||||
| } | |||||
| if invi.SrcUserID == tmpUser.ID { | |||||
| invi.Name = tmpUser.Name | |||||
| invi.Phone = tmpUser.PhoneNumber | |||||
| invi.CreatedUnix = tmpUser.CreatedUnix | |||||
| } else { | |||||
| invi.Name = "已注销" | |||||
| } | |||||
| } | |||||
| } else { | |||||
| log.Info("query user error." + err.Error()) | |||||
| } | |||||
| mapInterface := make(map[string]interface{}) | |||||
| mapInterface["data"] = result | |||||
| mapInterface["count"] = len(invitaionNumList) | |||||
| ctx.JSON(http.StatusOK, mapInterface) | |||||
| } | |||||
| } | |||||
| func getPageInfo(ctx *context.Context) (int, int) { | |||||
| page := ctx.QueryInt("page") | |||||
| if page <= 0 { | |||||
| page = 1 | |||||
| } | |||||
| pageSize := ctx.QueryInt("pageSize") | |||||
| if pageSize <= 0 { | |||||
| pageSize = setting.UI.IssuePagingNum | |||||
| } | |||||
| return page, pageSize | |||||
| } | |||||
| @@ -335,6 +335,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| go reward.AcceptStatusChangeAction() | go reward.AcceptStatusChangeAction() | ||||
| m.Get("/action/notification", routers.ActionNotification) | m.Get("/action/notification", routers.ActionNotification) | ||||
| m.Get("/recommend/home", routers.RecommendHomeInfo) | m.Get("/recommend/home", routers.RecommendHomeInfo) | ||||
| m.Get("/dashboard/invitation", routers.GetMapInfo) | |||||
| //m.Get("/recommend/org", routers.RecommendOrgFromPromote) | //m.Get("/recommend/org", routers.RecommendOrgFromPromote) | ||||
| //m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | //m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | ||||
| m.Get("/recommend/userrank/:index", routers.GetUserRankFromPromote) | m.Get("/recommend/userrank/:index", routers.GetUserRankFromPromote) | ||||
| @@ -509,6 +510,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/forgot_password", user.ForgotPasswd) | m.Get("/forgot_password", user.ForgotPasswd) | ||||
| m.Post("/forgot_password", user.ForgotPasswdPost) | m.Post("/forgot_password", user.ForgotPasswdPost) | ||||
| m.Post("/logout", user.SignOut) | m.Post("/logout", user.SignOut) | ||||
| m.Get("/invitation_code", reqSignIn, user.GetInvitaionCode) | |||||
| m.Get("/invitation_tpl", reqSignIn, user.InviationTpl) | |||||
| }) | }) | ||||
| // ***** END: User ***** | // ***** END: User ***** | ||||
| @@ -0,0 +1,107 @@ | |||||
| package user | |||||
| import ( | |||||
| "errors" | |||||
| "strconv" | |||||
| "strings" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/base" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "code.gitea.io/gitea/services/repository" | |||||
| ) | |||||
| const ( | |||||
| tplInvitation base.TplName = "user/settings/invite" | |||||
| ) | |||||
| func GetInvitaionCode(ctx *context.Context) { | |||||
| page := ctx.QueryInt("page") | |||||
| if page <= 0 { | |||||
| page = 1 | |||||
| } | |||||
| pageSize := ctx.QueryInt("pageSize") | |||||
| if pageSize <= 0 { | |||||
| pageSize = setting.UI.IssuePagingNum | |||||
| } | |||||
| url := setting.RecommentRepoAddr + "invitaion_page" | |||||
| result, err := repository.RecommendFromPromote(url) | |||||
| resultJsonMap := make(map[string]interface{}, 0) | |||||
| if err == nil { | |||||
| for _, strLine := range result { | |||||
| tmpIndex := strings.Index(strLine, "=") | |||||
| if tmpIndex != -1 { | |||||
| key := strLine[0:tmpIndex] | |||||
| value := strLine[tmpIndex+1:] | |||||
| resultJsonMap[key] = value | |||||
| } | |||||
| } | |||||
| } | |||||
| if ctx.IsSigned { | |||||
| resultJsonMap["invitation_code"] = getInvitaionCode(ctx) | |||||
| re, count := models.QueryInvitaionBySrcUserId(ctx.User.ID, (page-1)*pageSize, pageSize) | |||||
| for _, record := range re { | |||||
| tmpUser, err := models.GetUserByID(record.UserID) | |||||
| if err == nil { | |||||
| record.Avatar = strings.TrimRight(setting.AppSubURL, "/") + "/user/avatar/" + tmpUser.Name + "/" + strconv.Itoa(-1) | |||||
| record.IsActive = tmpUser.IsActive | |||||
| record.Name = tmpUser.Name | |||||
| } | |||||
| } | |||||
| resultJsonMap["invitation_users"] = re | |||||
| resultJsonMap["invitation_users_count"] = count | |||||
| } | |||||
| ctx.JSON(200, resultJsonMap) | |||||
| } | |||||
| func InviationTpl(ctx *context.Context) { | |||||
| ctx.HTML(200, tplInvitation) | |||||
| } | |||||
| func RegisteUserByInvitaionCode(invitationcode string, newUserId int64, newPhoneNumber string) error { | |||||
| user := parseInvitaionCode(invitationcode) | |||||
| if user == nil { | |||||
| return errors.New("The invitated user not existed.") | |||||
| } | |||||
| if newPhoneNumber != "" { | |||||
| re := models.QueryInvitaionByPhone(newPhoneNumber) | |||||
| if re != nil { | |||||
| if len(re) > 0 { | |||||
| log.Info("The phone has been invitated. so ingore it.") | |||||
| return errors.New("The phone has been invitated.") | |||||
| } | |||||
| } | |||||
| } else { | |||||
| log.Info("the phone number is null. user name=" + user.Name) | |||||
| } | |||||
| invitation := &models.Invitation{ | |||||
| SrcUserID: user.ID, | |||||
| UserID: newUserId, | |||||
| Phone: newPhoneNumber, | |||||
| } | |||||
| err := models.InsertInvitaion(invitation) | |||||
| if err != nil { | |||||
| log.Info("insert error," + err.Error()) | |||||
| } | |||||
| return err | |||||
| } | |||||
| func getInvitaionCode(ctx *context.Context) string { | |||||
| return ctx.User.Name | |||||
| } | |||||
| func parseInvitaionCode(invitationcode string) *models.User { | |||||
| user, err := models.GetUserByName(invitationcode) | |||||
| if err == nil { | |||||
| return user | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -8,11 +8,12 @@ package user | |||||
| import ( | import ( | ||||
| "errors" | "errors" | ||||
| "fmt" | "fmt" | ||||
| "github.com/gomodule/redigo/redis" | |||||
| "net/http" | "net/http" | ||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| "github.com/gomodule/redigo/redis" | |||||
| "code.gitea.io/gitea/modules/slideimage" | "code.gitea.io/gitea/modules/slideimage" | ||||
| phoneService "code.gitea.io/gitea/services/phone" | phoneService "code.gitea.io/gitea/services/phone" | ||||
| @@ -352,18 +353,17 @@ func SignInPostCommon(ctx *context.Context, form auth.SignInForm) { | |||||
| ctx.Redirect(setting.AppSubURL + "/user/two_factor") | ctx.Redirect(setting.AppSubURL + "/user/two_factor") | ||||
| } | } | ||||
| func SignInCloudBrainPost(ctx *context.Context, form auth.SignInForm) { | func SignInCloudBrainPost(ctx *context.Context, form auth.SignInForm) { | ||||
| ctx.Data["PageIsCloudBrainLogin"] = true | ctx.Data["PageIsCloudBrainLogin"] = true | ||||
| ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login/cloud_brain" | ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login/cloud_brain" | ||||
| SignInPostCommon(ctx,form) | |||||
| SignInPostCommon(ctx, form) | |||||
| } | } | ||||
| // SignInPost response for sign in request | // SignInPost response for sign in request | ||||
| func SignInPost(ctx *context.Context, form auth.SignInForm) { | func SignInPost(ctx *context.Context, form auth.SignInForm) { | ||||
| ctx.Data["PageIsLogin"] = true | ctx.Data["PageIsLogin"] = true | ||||
| ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login" | ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login" | ||||
| SignInPostCommon(ctx,form) | |||||
| SignInPostCommon(ctx, form) | |||||
| } | } | ||||
| // TwoFactor shows the user a two-factor authentication page. | // TwoFactor shows the user a two-factor authentication page. | ||||
| @@ -1264,9 +1264,9 @@ func SignUp(ctx *context.Context) { | |||||
| // SignUpPost response for sign up information submission | // SignUpPost response for sign up information submission | ||||
| func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterForm) { | func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterForm) { | ||||
| ctx.Data["Title"] = ctx.Tr("sign_up") | ctx.Data["Title"] = ctx.Tr("sign_up") | ||||
| invitationCode := ctx.Query("invitation_code") | |||||
| ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up" | ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up" | ||||
| ctx.Data["invitationCode"] = invitationCode | |||||
| ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | ||||
| ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL | ||||
| ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||
| @@ -1366,6 +1366,11 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | |||||
| } | } | ||||
| log.Trace("Account created: %s", u.Name, ctx.Data["MsgID"]) | log.Trace("Account created: %s", u.Name, ctx.Data["MsgID"]) | ||||
| log.Info("enter here, and form.InvitaionCode =" + invitationCode) | |||||
| if invitationCode != "" { | |||||
| RegisteUserByInvitaionCode(invitationCode, u.ID, u.PhoneNumber) | |||||
| } | |||||
| err := models.AddEmailAddress(&models.EmailAddress{ | err := models.AddEmailAddress(&models.EmailAddress{ | ||||
| UID: u.ID, | UID: u.ID, | ||||
| Email: form.Email, | Email: form.Email, | ||||
| @@ -1919,7 +1924,7 @@ func SendVerifyCode(ctx *context.Context, slideImage *slideimage.SlideImage, for | |||||
| return | return | ||||
| } | } | ||||
| if form.Mode==0 { //注册 | |||||
| if form.Mode == 0 { //注册 | |||||
| if has { | if has { | ||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.already_register"))) | ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.already_register"))) | ||||
| @@ -1935,32 +1940,31 @@ func SendVerifyCode(ctx *context.Context, slideImage *slideimage.SlideImage, for | |||||
| } else { | } else { | ||||
| //修改手机号 mode=2 绑定手机 | //修改手机号 mode=2 绑定手机 | ||||
| u, err := models.GetUserByPhoneNumber(phoneNumber) | |||||
| if err != nil && !models.IsErrUserNotExist(err) { | |||||
| log.Warn("sql err", err) | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.query_err"))) | |||||
| return | |||||
| } | |||||
| if u != nil { | |||||
| u, err := models.GetUserByPhoneNumber(phoneNumber) | |||||
| if err != nil && !models.IsErrUserNotExist(err) { | |||||
| log.Warn("sql err", err) | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.query_err"))) | |||||
| return | |||||
| } | |||||
| if u.ID == ctx.User.ID { //没有修改手机号 | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.not_modify"))) | |||||
| return | |||||
| } else { //修改的手机已经被别的用户注册 | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.already_register"))) | |||||
| return | |||||
| } | |||||
| if u != nil { | |||||
| if u.ID == ctx.User.ID { //没有修改手机号 | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.not_modify"))) | |||||
| return | |||||
| } else { //修改的手机已经被别的用户注册 | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.already_register"))) | |||||
| return | |||||
| } | } | ||||
| } | |||||
| } | |||||
| } | |||||
| redisConn := labelmsg.Get() | redisConn := labelmsg.Get() | ||||
| defer redisConn.Close() | defer redisConn.Close() | ||||
| sendTimes, err := phoneService.GetPhoneNumberSendTimes(redisConn, phoneNumber) | sendTimes, err := phoneService.GetPhoneNumberSendTimes(redisConn, phoneNumber) | ||||
| if err != nil && err!=redis.ErrNil { | |||||
| if err != nil && err != redis.ErrNil { | |||||
| log.Warn("redis err", err) | log.Warn("redis err", err) | ||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.query_err"))) | ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("phone.query_err"))) | ||||
| return | return | ||||
| @@ -148,6 +148,28 @@ func GetRecommendRepoFromPromote(filename string) ([]map[string]interface{}, err | |||||
| return resultRepo, nil | return resultRepo, nil | ||||
| } | } | ||||
| func RecommendContentFromPromote(url string) (string, error) { | |||||
| defer func() { | |||||
| if err := recover(); err != nil { | |||||
| log.Info("not error.", err) | |||||
| return | |||||
| } | |||||
| }() | |||||
| resp, err := http.Get(url) | |||||
| if err != nil || resp.StatusCode != 200 { | |||||
| log.Info("Get organizations url error=" + err.Error()) | |||||
| return "", err | |||||
| } | |||||
| bytes, err := ioutil.ReadAll(resp.Body) | |||||
| resp.Body.Close() | |||||
| if err != nil { | |||||
| log.Info("Get organizations url error=" + err.Error()) | |||||
| return "", err | |||||
| } | |||||
| allLineStr := string(bytes) | |||||
| return allLineStr, nil | |||||
| } | |||||
| func RecommendFromPromote(url string) ([]string, error) { | func RecommendFromPromote(url string) ([]string, error) { | ||||
| defer func() { | defer func() { | ||||
| if err := recover(); err != nil { | if err := recover(); err != nil { | ||||
| @@ -52,6 +52,12 @@ | |||||
| <script src="/rotation3D/rotation3D.js?v={{MD5 AppVer}}"></script> | <script src="/rotation3D/rotation3D.js?v={{MD5 AppVer}}"></script> | ||||
| <script> | <script> | ||||
| var jobTask={}; | var jobTask={}; | ||||
| var html =document.documentElement; | |||||
| var lang = html.attributes["lang"] | |||||
| var isZh = true; | |||||
| if(lang != null && lang.nodeValue =="en-US" ){ | |||||
| isZh=false; | |||||
| } | |||||
| function queryAiCenterInfo(){ | function queryAiCenterInfo(){ | ||||
| $.ajax({ | $.ajax({ | ||||
| type:"GET", | type:"GET", | ||||
| @@ -96,7 +102,11 @@ | |||||
| tmp["type"]="green"; | tmp["type"]="green"; | ||||
| } | } | ||||
| tmp["icon"]=""; | tmp["icon"]=""; | ||||
| tmp["content"]=json[i].content; | |||||
| if(isZh){ | |||||
| tmp["content"]=json[i].content; | |||||
| }else{ | |||||
| tmp["content"]=json[i].content_en; | |||||
| } | |||||
| serverItemList.push(tmp); | serverItemList.push(tmp); | ||||
| } | } | ||||
| } | } | ||||
| @@ -182,6 +182,10 @@ | |||||
| </i> | </i> | ||||
| {{.i18n.Tr "custom.Platform_Tutorial"}} | {{.i18n.Tr "custom.Platform_Tutorial"}} | ||||
| </a> | </a> | ||||
| <a class="item" href="{{AppSubUrl}}/user/invitation_tpl"> | |||||
| <i class="icon users"></i> | |||||
| {{.i18n.Tr "invite_friends"}} | |||||
| </a> | |||||
| {{if .IsAdmin}} | {{if .IsAdmin}} | ||||
| <div class="divider"></div> | <div class="divider"></div> | ||||
| @@ -179,6 +179,10 @@ | |||||
| </svg> | </svg> | ||||
| </i> | </i> | ||||
| {{.i18n.Tr "custom.Platform_Tutorial"}} | {{.i18n.Tr "custom.Platform_Tutorial"}} | ||||
| </a> | |||||
| <a class="item" href="{{AppSubUrl}}/user/invitation_tpl"> | |||||
| <i class="icon users"></i> | |||||
| {{.i18n.Tr "invite_friends"}} | |||||
| </a> | </a> | ||||
| {{if .IsAdmin}} | {{if .IsAdmin}} | ||||
| <div class="divider"></div> | <div class="divider"></div> | ||||
| @@ -162,6 +162,10 @@ | |||||
| </i> | </i> | ||||
| {{.i18n.Tr "custom.Platform_Tutorial"}} | {{.i18n.Tr "custom.Platform_Tutorial"}} | ||||
| </a> | </a> | ||||
| <a class="item" href="{{AppSubUrl}}/user/invitation_tpl"> | |||||
| <i class="icon users"></i> | |||||
| {{.i18n.Tr "invite_friends"}} | |||||
| </a> | |||||
| {{if .IsAdmin}} | {{if .IsAdmin}} | ||||
| <div class="divider"></div> | <div class="divider"></div> | ||||
| @@ -183,6 +183,10 @@ | |||||
| </i> | </i> | ||||
| {{.i18n.Tr "custom.Platform_Tutorial"}} | {{.i18n.Tr "custom.Platform_Tutorial"}} | ||||
| </a> | </a> | ||||
| <a class="item" href="{{AppSubUrl}}/user/invitation_tpl"> | |||||
| <i class="icon users"></i> | |||||
| {{.i18n.Tr "invite_friends"}} | |||||
| </a> | |||||
| {{if .IsAdmin}} | {{if .IsAdmin}} | ||||
| <div class="divider"></div> | <div class="divider"></div> | ||||
| @@ -533,8 +533,7 @@ | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <div | |||||
| style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||||
| <div style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||||
| <span> | <span> | ||||
| <a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | <a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | ||||
| class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | ||||
| @@ -499,7 +499,16 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui tab" data-tab="second{{$k}}"> | <div class="ui tab" data-tab="second{{$k}}"> | ||||
| <div style="position: relative;"> | |||||
| <div> | |||||
| <a id="{{.VersionName}}-log-down" | |||||
| class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}}' | |||||
| href="/api/v1/repos/{{$.RepoRelPath}}/grampus/train-job/{{.JobID}}/download_log"> | |||||
| <i class="ri-download-cloud-2-line"></i> | |||||
| <span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span> | |||||
| </a> | |||||
| </div> | |||||
| <div style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||||
| <span> | <span> | ||||
| <a title="{{$.i18n.Tr "repo.log_scroll_start"}}" style="position: absolute; right: -32px;cursor: pointer;" | <a title="{{$.i18n.Tr "repo.log_scroll_start"}}" style="position: absolute; right: -32px;cursor: pointer;" | ||||
| class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | ||||
| @@ -241,7 +241,7 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="unite min_title inline fields required"> | |||||
| <div class="unite min_title inline fields required" id="ModelFile_Div"> | |||||
| <div class="three wide field right aligned"> | <div class="three wide field right aligned"> | ||||
| <label for="choice_file">{{$.i18n.Tr "repo.model.manage.modelfile"}}</label> | <label for="choice_file">{{$.i18n.Tr "repo.model.manage.modelfile"}}</label> | ||||
| </div> | </div> | ||||
| @@ -382,7 +382,14 @@ | |||||
| data['DestFormat'] = $('#DestFormat').val(); | data['DestFormat'] = $('#DestFormat').val(); | ||||
| data['NetOutputFormat']= $('#NetOutputFormat').val(); | data['NetOutputFormat']= $('#NetOutputFormat').val(); | ||||
| data['ModelFile'] = $('#ModelFile').val(); | data['ModelFile'] = $('#ModelFile').val(); | ||||
| if(data['ModelFile']==""){ | |||||
| $('.ui.error.message').text("{{.i18n.Tr "repo.modelconvert.modelfileempty"}}") | |||||
| $('.ui.error.message').css('display','block') | |||||
| $("#ModelFile_Div").addClass("error") | |||||
| return false | |||||
| }else{ | |||||
| $("#ModelFile_Div").removeClass("error") | |||||
| } | |||||
| $.post(`${repolink}/modelmanage/create_model_convert`,data,(result) => { | $.post(`${repolink}/modelmanage/create_model_convert`,data,(result) => { | ||||
| console.log("result=" + result); | console.log("result=" + result); | ||||
| if(result.result_code ==0){ | if(result.result_code ==0){ | ||||
| @@ -46,9 +46,9 @@ | |||||
| <div class="repository release dataset-list view"> | <div class="repository release dataset-list view"> | ||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| <!-- 列表容器 --> | <!-- 列表容器 --> | ||||
| <div class="ui container {{if ne $.MODEL_COUNT 0}}active loader {{end}}" id="loadContainer"> | |||||
| <div class="ui container {{if ne $.MODEL_COUNT 0}}active loader {{end}}" id="loadContainer" > | |||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <div class="ui two column stackable grid"> | |||||
| <div class="ui two column stackable grid" style="display: none;"> | |||||
| <div class="column"> | <div class="column"> | ||||
| <div class="ui blue small menu compact selectcloudbrain"> | <div class="ui blue small menu compact selectcloudbrain"> | ||||
| <a class="active item" href="{{.RepoLink}}/modelmanage/show_model">{{$.i18n.Tr "repo.model.list"}}</a> | <a class="active item" href="{{.RepoLink}}/modelmanage/show_model">{{$.i18n.Tr "repo.model.list"}}</a> | ||||
| @@ -35,6 +35,9 @@ | |||||
| {{if .DisableRegistration}} | {{if .DisableRegistration}} | ||||
| <p>{{.i18n.Tr "auth.disable_register_prompt"}}</p> | <p>{{.i18n.Tr "auth.disable_register_prompt"}}</p> | ||||
| {{else}} | {{else}} | ||||
| <div class="field invitation_tips" style="font-weight:400;font-size:14px;color:rgba(250,140,22,1);{{if not .invitationCode}}display:none;{{end}}"> | |||||
| <span>{{.i18n.Tr "your_friend"}} <span class="__invitation_code__">{{.invitationCode}}</span> {{.i18n.Tr "invite_you_to_join_the_OpenI_AI_Collaboration_Platform_and_enjoy_abundant_free_computing_resources"}}</span> | |||||
| </div> | |||||
| <div class="field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}"> | <div class="field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}"> | ||||
| <input id="user_name" name="user_name" value="{{.user_name}}" placeholder="{{.i18n.Tr "username"}}" autofocus required> | <input id="user_name" name="user_name" value="{{.user_name}}" placeholder="{{.i18n.Tr "username"}}" autofocus required> | ||||
| </div> | </div> | ||||
| @@ -71,6 +74,16 @@ | |||||
| {{template "user/auth/phone_verify" .}} | {{template "user/auth/phone_verify" .}} | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| <div class="field"> | |||||
| <div style="display:flex;"> | |||||
| <div style="display:flex;align-items:center;"> | |||||
| <span>{{.i18n.Tr "recommender"}}</span> | |||||
| </div> | |||||
| <input style="flex:1;margin-left:12px;" id="invitation_code" name="invitation_code" value="{{.invitationCode}}" {{if .invitationCode}}readonly="true"{{end}} autocomplete="off" /> | |||||
| </div> | |||||
| </div> | |||||
| <div class="field"> | <div class="field"> | ||||
| <div class="ui checkbox"> | <div class="ui checkbox"> | ||||
| <input name="agree" type="checkbox" tabindex="0" class="hidden" {{if .agree}}checked{{end}}><label>{{.i18n.Tr "use_and_privacy_agree" "/home/term" "/home/privacy" | Safe}}</label> | <input name="agree" type="checkbox" tabindex="0" class="hidden" {{if .agree}}checked{{end}}><label>{{.i18n.Tr "use_and_privacy_agree" "/home/term" "/home/privacy" | Safe}}</label> | ||||
| @@ -94,3 +107,28 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <script> | |||||
| ; (function() { | |||||
| var getUrlParams = function() { | |||||
| var url = window.location.search; | |||||
| var index = url.indexOf('?'); | |||||
| var obj = {}; | |||||
| if (index !== -1) { | |||||
| var str = url.substr(1); | |||||
| var arr = str.split('&'); | |||||
| for (var i = 0, iLen = arr.length; i < iLen; i++) { | |||||
| var list = arr[i].split('='); | |||||
| obj[list[0]] = list[1]; | |||||
| } | |||||
| } | |||||
| return obj; | |||||
| }; | |||||
| var sharedUser = getUrlParams()['sharedUser']; | |||||
| if (sharedUser) { | |||||
| setTimeout(function() { | |||||
| $('.invitation_tips').show().find('.__invitation_code__').text(sharedUser); | |||||
| $('input#invitation_code').val(sharedUser).attr('readonly', true); | |||||
| }, 20); | |||||
| } | |||||
| })(); | |||||
| </script> | |||||
| @@ -18,6 +18,11 @@ | |||||
| v-cloak | v-cloak | ||||
| > | > | ||||
| <div> | <div> | ||||
| {{if .invite_image_url}} | |||||
| <div style="height:60px;"> | |||||
| <a href="{{.invite_image_link}}" target="_blank"><img src="{{.invite_image_url}}" style="width:100%;height:100%" /></a> | |||||
| </div> | |||||
| {{end}} | |||||
| <div v-if="!isOrganization" class="ui two item tabable menu"> | <div v-if="!isOrganization" class="ui two item tabable menu"> | ||||
| <a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.i18n.Tr "repository"}}</a> | <a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.i18n.Tr "repository"}}</a> | ||||
| <a :class="{item: true, active: tab === 'organizations'}" @click="changeTab('organizations')">{{.i18n.Tr "organization"}}</a> | <a :class="{item: true, active: tab === 'organizations'}" @click="changeTab('organizations')">{{.i18n.Tr "organization"}}</a> | ||||
| @@ -48,7 +48,40 @@ | |||||
| </li> | </li> | ||||
| {{end}} | {{end}} | ||||
| {{end}} | {{end}} | ||||
| <li>{{svg "octicon-clock" 16}} {{.i18n.Tr "user.join_on"}} {{.Owner.CreatedUnix.FormatShort}}</li> | |||||
| <li> | |||||
| {{svg "octicon-clock" 16}} {{.i18n.Tr "user.join_on"}} {{.Owner.CreatedUnix.FormatShort}} | |||||
| {{if and .IsSigned (eq .SignedUserName .Owner.Name)}} | |||||
| <div class=__ad_profile_c__ style="margin-top:6px;height:50px;display:none;"> | |||||
| <a class="__ad_profile__" href="" target="_blank"><img src="" style="width:100%;height:100%" /></a> | |||||
| </div> | |||||
| <script> | |||||
| ;(function(){ | |||||
| document.addEventListener("DOMContentLoaded", function() { | |||||
| $.ajax({ | |||||
| type: "GET", | |||||
| url: "/dashboard/invitation", | |||||
| dataType: "json", | |||||
| data: { filename: 'ad-profile.json' }, | |||||
| success: function (res) { | |||||
| try { | |||||
| var data = JSON.parse(res); | |||||
| $('.__ad_profile__').attr('href', data.url).find('img').attr('src', data.src); | |||||
| $('.__ad_profile_c__').show(); | |||||
| } catch (err) { | |||||
| console.log(err); | |||||
| } | |||||
| }, | |||||
| error: function (err) { | |||||
| console.log(err); | |||||
| } | |||||
| }); | |||||
| }); | |||||
| })(); | |||||
| </script> | |||||
| {{end}} | |||||
| </li> | |||||
| {{if and .Orgs .HasOrgsVisible}} | {{if and .Orgs .HasOrgsVisible}} | ||||
| <li style="border-bottom: none;padding-bottom: 0;"><div style="border-bottom: 1px solid #eaeaea;padding-top: 5px;padding-bottom:5px"> <b>{{.i18n.Tr "organization"}} </b></div></li> | <li style="border-bottom: none;padding-bottom: 0;"><div style="border-bottom: 1px solid #eaeaea;padding-top: 5px;padding-bottom:5px"> <b>{{.i18n.Tr "organization"}} </b></div></li> | ||||
| @@ -0,0 +1,7 @@ | |||||
| {{template "base/head" .}} | |||||
| <link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-user-invite.css?v={{MD5 AppVer}}" /> | |||||
| <div class="user settings invite"> | |||||
| <div id="__vue-root"></div> | |||||
| </div> | |||||
| <script src="{{StaticUrlPrefix}}/js/vp-user-invite.js?v={{MD5 AppVer}}"></script> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,140 @@ | |||||
| ; (function () { | |||||
| /*const adList = [ | |||||
| { | |||||
| "width": 144, | |||||
| "height": 108, | |||||
| "pos": { | |||||
| "left": 50, | |||||
| "bottom": 50 | |||||
| }, | |||||
| "src": "https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/imgs/invitation/pic-01.png", | |||||
| "url": "/user/invitation_tpl", | |||||
| "show": true | |||||
| }, | |||||
| { | |||||
| "width": 144, | |||||
| "height": 108, | |||||
| "pos": { | |||||
| "right": 50, | |||||
| "bottom": 50 | |||||
| }, | |||||
| "src": "https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/imgs/invitation/pic-01.png", | |||||
| "url": "/user/invitation_tpl", | |||||
| "show": false | |||||
| } | |||||
| ];*/ | |||||
| const exceptPages = [ | |||||
| // '/user/invitation_tpl' | |||||
| ]; | |||||
| function initAd() { | |||||
| $.ajax({ | |||||
| type: "GET", | |||||
| url: "/dashboard/invitation", | |||||
| dataType: "json", | |||||
| data: { filename: 'ad-pop-up.json' }, | |||||
| success: function (res) { | |||||
| try { | |||||
| var data = JSON.parse(res); | |||||
| createAd(data); | |||||
| } catch (err) { | |||||
| console.log(err); | |||||
| } | |||||
| }, | |||||
| error: function (err) { | |||||
| console.log(err); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function createAd(adList) { | |||||
| const adInfoStr = window.localStorage.getItem('ads') || '{}'; | |||||
| let adInfoObj = JSON.parse(adInfoStr); | |||||
| const today = new Date(); | |||||
| const timeTodayEnd = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1).getTime(); | |||||
| const now = Date.now(); | |||||
| const expTime = now + 4 * 60 * 60 * 1000; | |||||
| if (!adInfoObj.expires || adInfoObj.expires <= now) { | |||||
| adInfoObj = { | |||||
| expires: Math.min(timeTodayEnd, expTime), | |||||
| }; | |||||
| } | |||||
| for (var i = 0, iLen = adList.length; i < iLen; i++) { | |||||
| var adI = adList[i]; | |||||
| if (adI.show === false) continue; | |||||
| var showOr = adInfoObj[i] === false ? false : true; | |||||
| adInfoObj[i] = showOr; | |||||
| if (!showOr) continue; | |||||
| var adEl = $(`<div class="__ad_c__" _id="${i}" style="position:fixed;z-index:99999999; | |||||
| width:${adI.width}px;height:${adI.height}px; | |||||
| left:${adI.pos.left !== undefined ? adI.pos.left + 'px' : ''}; | |||||
| top:${adI.pos.top !== undefined ? adI.pos.top + 'px' : ''}; | |||||
| right:${adI.pos.right !== undefined ? adI.pos.right + 'px' : ''}; | |||||
| bottom:${adI.pos.bottom !== undefined ? adI.pos.bottom + 'px' : ''};"> | |||||
| <a style="" href="${adI.url}" target="_blank"> | |||||
| <img style="height:100%;width:100%;" src="${adI.src}" /> | |||||
| </a> | |||||
| <div class="__ad_close_c__" style="position:absolute;top:6px;right:6px;"> | |||||
| <i class="ri-close-circle-line __ad_close__" style="color:white;font-size:18px;cursor:pointer;"></i> | |||||
| </div> | |||||
| </div>`); | |||||
| adEl.data('data', adI); | |||||
| $('body').append(adEl); | |||||
| } | |||||
| window.localStorage.setItem('ads', JSON.stringify(adInfoObj)); | |||||
| } | |||||
| function initAdEvent() { | |||||
| $('body').on('click', '.__ad_c__ .__ad_close__', function () { | |||||
| var self = $(this); | |||||
| var adEl = self.closest('.__ad_c__'); | |||||
| var adId = adEl.attr('_id'); | |||||
| const adInfoStr = window.localStorage.getItem('ads') || '{}'; | |||||
| const adInfoObj = JSON.parse(adInfoStr); | |||||
| adInfoObj[adId] = false; | |||||
| window.localStorage.setItem('ads', JSON.stringify(adInfoObj)); | |||||
| adEl.remove(); | |||||
| }); | |||||
| var scrollTopOld = $(document).scrollTop(); | |||||
| var timeHandler = null; | |||||
| $(window).scroll(function (e) { | |||||
| var scrollTop = $(document).scrollTop(); | |||||
| var offSet = scrollTop - scrollTopOld; | |||||
| scrollTopOld = scrollTop; | |||||
| timeHandler && clearTimeout(timeHandler); | |||||
| $('.__ad_c__').each(function (_, item) { | |||||
| var self = $(item); | |||||
| var adData = self.data('data'); | |||||
| if (adData.pos.bottom !== undefined) { | |||||
| self.animate({ bottom: adData.pos.bottom + offSet + 'px' }, 0); | |||||
| } | |||||
| if (adData.pos.top !== undefined) { | |||||
| self.animate({ top: adData.pos.top - offSet + 'px' }, 0); | |||||
| } | |||||
| }) | |||||
| timeHandler = setTimeout(function () { | |||||
| $('.__ad_c__').each(function (_, item) { | |||||
| var self = $(item); | |||||
| var adData = self.data('data'); | |||||
| if (adData.pos.bottom !== undefined) { | |||||
| self.animate({ bottom: adData.pos.bottom + 'px' }, 0); | |||||
| } | |||||
| if (adData.pos.top !== undefined) { | |||||
| self.animate({ top: adData.pos.top + 'px' }, 0); | |||||
| } | |||||
| }) | |||||
| }, 20); | |||||
| }); | |||||
| } | |||||
| setTimeout(function () { | |||||
| if (!$('meta[name="_uid"]').length) { // 未登录,不显示 | |||||
| window.localStorage.removeItem('ads'); | |||||
| return; | |||||
| } | |||||
| var pathName = window.location.pathname; | |||||
| if (exceptPages.indexOf(pathName) > -1) return; // 排除页,不显示 | |||||
| initAd(); | |||||
| initAdEvent(); | |||||
| }, 0); | |||||
| })(); | |||||
| @@ -97,6 +97,10 @@ export const i18nVue = { | |||||
| model_delete: "删除", | model_delete: "删除", | ||||
| model_create_title: "导入新模型", | model_create_title: "导入新模型", | ||||
| model_create_version_title: "创建模型新版本", | model_create_version_title: "创建模型新版本", | ||||
| model_status:"状态", | |||||
| model_wait:"模型加载中", | |||||
| model_success:"模型加载成功", | |||||
| model_failed:"模型加载失败", | |||||
| }, | }, | ||||
| US: { | US: { | ||||
| computer_vision: "computer vision", | computer_vision: "computer vision", | ||||
| @@ -200,5 +204,9 @@ export const i18nVue = { | |||||
| model_delete: "Delete", | model_delete: "Delete", | ||||
| model_create_title: "Import new model", | model_create_title: "Import new model", | ||||
| model_create_version_title: "Create a new version of the model", | model_create_version_title: "Create a new version of the model", | ||||
| model_status: "Status", | |||||
| model_wait:"Loading", | |||||
| model_success:"Success", | |||||
| model_failed:"Failed", | |||||
| }, | }, | ||||
| }; | }; | ||||
| @@ -52,6 +52,7 @@ import router from "./router/index.js"; | |||||
| import { Message } from "element-ui"; | import { Message } from "element-ui"; | ||||
| import { i18nVue } from "./features/i18nVue.js"; | import { i18nVue } from "./features/i18nVue.js"; | ||||
| import './features/ad.js'; | |||||
| Vue.use(ElementUI); | Vue.use(ElementUI); | ||||
| Vue.prototype.$axios = axios; | Vue.prototype.$axios = axios; | ||||
| @@ -77,7 +77,7 @@ | |||||
| }); | }); | ||||
| function mouseMove(e) { | function mouseMove(e) { | ||||
| var _clientX = e.clientX; | |||||
| var _clientX = e.clientX !== undefined ? e.clientX : e.targetTouches[0].clientX; | |||||
| var offset = _clientX - clientX; | var offset = _clientX - clientX; | ||||
| var triggerEl = self.dom.find('.slide-trigger'); | var triggerEl = self.dom.find('.slide-trigger'); | ||||
| var triggerWidth = triggerEl.width(); | var triggerWidth = triggerEl.width(); | ||||
| @@ -99,6 +99,8 @@ | |||||
| function mouseUp(e) { | function mouseUp(e) { | ||||
| $(document).off('mousemove', mouseMove); | $(document).off('mousemove', mouseMove); | ||||
| $(document).off('mouseup', mouseUp); | $(document).off('mouseup', mouseUp); | ||||
| $(document).off('touchmove', mouseMove); | |||||
| $(document).off('touchend', mouseUp); | |||||
| self.isMoving = false; | self.isMoving = false; | ||||
| $.ajax({ | $.ajax({ | ||||
| url: '/verifySlideImage', | url: '/verifySlideImage', | ||||
| @@ -106,7 +108,7 @@ | |||||
| dataType: 'json', | dataType: 'json', | ||||
| data: { | data: { | ||||
| slide_id: self.imgID, | slide_id: self.imgID, | ||||
| x: parseInt(self.dom.find('.slide-image-small').position().left) | |||||
| x: parseInt(self.dom.find('.slide-image-small').position().left / self.dom.find('.slide-image-big').attr('scale')) | |||||
| }, | }, | ||||
| success: function (res) { | success: function (res) { | ||||
| if (res && res.Code === 0) { | if (res && res.Code === 0) { | ||||
| @@ -138,13 +140,18 @@ | |||||
| }); | }); | ||||
| } | } | ||||
| this.dom.find('.slide-trigger').on('mousedown', function (e) { | |||||
| function mouseDown(e) { | |||||
| if (self.verifySucess) return; | if (self.verifySucess) return; | ||||
| clientX = e.clientX; | |||||
| clientX = e.clientX !== undefined ? e.clientX : e.targetTouches[0].clientX; | |||||
| oLeft = $(this).position().left; | oLeft = $(this).position().left; | ||||
| $(document).on('mousemove', mouseMove); | $(document).on('mousemove', mouseMove); | ||||
| $(document).on('mouseup', mouseUp); | $(document).on('mouseup', mouseUp); | ||||
| }); | |||||
| $(document).on('touchmove', mouseMove); | |||||
| $(document).on('touchend', mouseUp); | |||||
| } | |||||
| this.dom.find('.slide-trigger').on('mousedown', mouseDown); | |||||
| this.dom.find('.slide-trigger').on('touchstart', mouseDown); | |||||
| this.dom.find('.verify-code-send-btn').on('click', function () { | this.dom.find('.verify-code-send-btn').on('click', function () { | ||||
| if (!self.canSendCode) return; | if (!self.canSendCode) return; | ||||
| @@ -199,6 +206,7 @@ | |||||
| self.dom.find('.slide-bar-wrap').css('display', 'flex'); | self.dom.find('.slide-bar-wrap').css('display', 'flex'); | ||||
| self.dom.find('.verify-code-c').css('display', 'flex'); | self.dom.find('.verify-code-c').css('display', 'flex'); | ||||
| self.dom.find('.modify-phone-number').hide(); | self.dom.find('.modify-phone-number').hide(); | ||||
| self.refreshImages(); | |||||
| }); | }); | ||||
| }; | }; | ||||
| @@ -210,6 +218,8 @@ | |||||
| this.imgID = ''; | this.imgID = ''; | ||||
| this.dom.find('.slide-bar').removeClass('sucess error').css('width', '30px'); | this.dom.find('.slide-bar').removeClass('sucess error').css('width', '30px'); | ||||
| this.dom.find('.slide-trigger').removeClass('sucess error').css('left', '0px'); | this.dom.find('.slide-trigger').removeClass('sucess error').css('left', '0px'); | ||||
| var scale = this.dom.find('.slide-bar-bg').width() / 391; | |||||
| this.dom.find('.slide-image-big').css('transform', `scale(${scale})`).attr('scale', scale); | |||||
| this.dom.find('.slide-trigger .icon').hide(); | this.dom.find('.slide-trigger .icon').hide(); | ||||
| this.dom.find('.slide-trigger .icon.arrow').show(); | this.dom.find('.slide-trigger .icon.arrow').show(); | ||||
| this.dom.find('.slide-txt').show(); | this.dom.find('.slide-txt').show(); | ||||
| @@ -174,10 +174,11 @@ | |||||
| width: 391px; | width: 391px; | ||||
| height: 196px; | height: 196px; | ||||
| top: 36px; | top: 36px; | ||||
| left: 0; | |||||
| left: 1px; | |||||
| border-radius: 2px; | border-radius: 2px; | ||||
| z-index: 100; | z-index: 100; | ||||
| display: none; | display: none; | ||||
| transform-origin: 0 0; | |||||
| } | } | ||||
| .__phone-verify-code .slide-bar-c .slide-image-small { | .__phone-verify-code .slide-bar-c .slide-image-small { | ||||
| @@ -0,0 +1,11 @@ | |||||
| import service from '../service'; | |||||
| // 邀请好友页面数据 | |||||
| export const getUserInvitationCode = (params) => { // page pageSize | |||||
| return service({ | |||||
| url: '/user/invitation_code', | |||||
| method: 'get', | |||||
| params: params, | |||||
| data: {}, | |||||
| }); | |||||
| } | |||||
| @@ -162,6 +162,20 @@ const en = { | |||||
| available: 'Available', | available: 'Available', | ||||
| notAvailable: 'Not Available', | notAvailable: 'Not Available', | ||||
| }, | }, | ||||
| user: { | |||||
| inviteFriends: 'Invite Friends', | |||||
| inviteFriendsTips: 'Copy QR code or invite registration link to share with friends', | |||||
| clickToViewTheEventDetails: 'Click to view the event details', | |||||
| copyRegistrationInvitationLink: 'Copy registration invitation link', | |||||
| registrationAdress: 'Registration Adress: ', | |||||
| recommender: 'Recommender: ', | |||||
| invitedFriends: 'Invited friends', | |||||
| registrationTime: 'Registration time', | |||||
| theSharedContentHasBeenCopiedToTheClipboard: 'The shared content has been copied to the clipboard', | |||||
| copyError: 'Copy error', | |||||
| Activated: 'Activated', | |||||
| notActive: 'Not active', | |||||
| }, | |||||
| } | } | ||||
| export default en; | export default en; | ||||
| @@ -162,6 +162,20 @@ const zh = { | |||||
| available: '可用', | available: '可用', | ||||
| notAvailable: '不可用', | notAvailable: '不可用', | ||||
| }, | }, | ||||
| user: { | |||||
| inviteFriends: '邀请好友', | |||||
| inviteFriendsTips: '复制二维码或者注册邀请链接分享给好友', | |||||
| clickToViewTheEventDetails: '点击查看活动详情', | |||||
| copyRegistrationInvitationLink: '复制注册邀请链接', | |||||
| registrationAdress: '注册地址:', | |||||
| recommender: '推荐人:', | |||||
| invitedFriends: '已邀请好友', | |||||
| registrationTime: '注册时间', | |||||
| theSharedContentHasBeenCopiedToTheClipboard: '分享内容已复制到剪切板', | |||||
| copyError: '复制错误', | |||||
| Activated: '已激活', | |||||
| notActive: '未激活', | |||||
| }, | |||||
| } | } | ||||
| export default zh; | export default zh; | ||||
| @@ -0,0 +1,319 @@ | |||||
| <template> | |||||
| <div class="ui container"> | |||||
| <div class="title"> | |||||
| <div class="title-1"><span>{{ $t('user.inviteFriends') }}</span></div> | |||||
| <div class="title-2"><span>{{ $t('user.inviteFriendsTips') }}</span></div> | |||||
| </div> | |||||
| <div class="content-1"> | |||||
| <div class="img-c"> | |||||
| <img class="img" :src="bannerImg" /> | |||||
| <div class="txt">{{ bannerTitle }}</div> | |||||
| </div> | |||||
| <div class="descr"> | |||||
| <span>{{ pageLinkDesc }}</span> | |||||
| <a :href="pageLink" target="_blank">{{ $t('user.clickToViewTheEventDetails') }}</a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="content-2"> | |||||
| <div class="txt-c"> | |||||
| <div class="txt-1"> | |||||
| <span>{{ pageOpeniDesc }}</span> | |||||
| </div> | |||||
| <div class="txt-2"><span>{{ $t('user.registrationAdress') }}</span><span>{{ invitationLink + invitationCode | |||||
| }}</span></div> | |||||
| <div class="txt-3"><span>{{ $t('user.recommender') }}</span><span>{{ invitationCode }}</span></div> | |||||
| <el-button class="__copy_link_btn__" type="primary">{{ $t('user.copyRegistrationInvitationLink') }}</el-button> | |||||
| </div> | |||||
| <div class="qr-code"> | |||||
| <div id="__qr-code__" style="width:120px;height:120px;"></div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="table-container"> | |||||
| <div> | |||||
| <el-table border :data="tableData" style="width:100%" v-loading="loading" stripe> | |||||
| <el-table-column prop="ID" :label="$t('user.invitedFriends')" align="left" header-align="center"> | |||||
| <template slot-scope="scope"> | |||||
| <div style="display:flex;align-items:center;padding-left:20px;"> | |||||
| <img :src="scope.row.avatarSrc" alt="" style="height:45px;width:45px;margin-right:10px;" /> | |||||
| <a :href="scope.row.userLink" style="font-weight:500;font-size:15px;">{{ scope.row.userName }}</a> | |||||
| </div> | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column prop="statusStr" :label="$t('status')" align="center" header-align="center"> | |||||
| <template slot-scope="scope"> | |||||
| <span :style="{ color: scope.row.statusColor }">{{ scope.row.statusStr }}</span> | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column prop="regTime" :label="$t('user.registrationTime')" align="center" header-align="center"> | |||||
| </el-table-column> | |||||
| <template slot="empty"> | |||||
| <span>{{ | |||||
| loading ? $t('loading') : $t('noData') | |||||
| }}</span> | |||||
| </template> | |||||
| </el-table> | |||||
| </div> | |||||
| <div class="__r_p_pagination"> | |||||
| <div style="margin-top: 2rem"> | |||||
| <div class="center"> | |||||
| <el-pagination background @current-change="currentChange" :current-page="pageInfo.curpage" | |||||
| :page-sizes="pageInfo.pageSizes" :page-size="pageInfo.pageSize" | |||||
| layout="total, sizes, prev, pager, next, jumper" :total="pageInfo.total"> | |||||
| </el-pagination> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <script> | |||||
| import Clipboard from 'clipboard'; | |||||
| import QRCode from 'qrcodejs2'; | |||||
| import { formatDate } from 'element-ui/lib/utils/date-util'; | |||||
| import { getUserInvitationCode } from '~/apis/modules/userinvite'; | |||||
| export default { | |||||
| data() { | |||||
| return { | |||||
| bannerImg: '', | |||||
| bannerTitle: '', | |||||
| pageLink: '', | |||||
| pageLinkDesc: '', | |||||
| invitationLink: window.origin + '/user/sign_up?sharedUser=', | |||||
| invitationCode: '', | |||||
| pageOpeniDesc: '', | |||||
| loading: false, | |||||
| tableData: [], | |||||
| pageInfo: { | |||||
| curpage: 1, | |||||
| pageSize: 10, | |||||
| pageSizes: [10], | |||||
| total: 0, | |||||
| }, | |||||
| }; | |||||
| }, | |||||
| components: {}, | |||||
| methods: { | |||||
| initCopy() { | |||||
| const clipboard = new Clipboard('.__copy_link_btn__', { | |||||
| text: () => { | |||||
| return `${this.pageOpeniDesc}\n${this.$t('user.registrationAdress')}${this.invitationLink + this.invitationCode}\n${this.$t('user.recommender')}${this.invitationCode}`; | |||||
| }, | |||||
| }); | |||||
| clipboard.on('success', (e) => { | |||||
| this.$message({ | |||||
| type: 'success', | |||||
| message: this.$t('user.theSharedContentHasBeenCopiedToTheClipboard') | |||||
| }); | |||||
| }); | |||||
| clipboard.on('error', (e) => { | |||||
| this.$message({ | |||||
| type: 'error', | |||||
| message: this.$t('user.copyError') | |||||
| }); | |||||
| }); | |||||
| }, | |||||
| transRowData(item) { | |||||
| return { | |||||
| userName: item.Name, | |||||
| avatarSrc: item.Avatar, | |||||
| userLink: window.origin + '/' + item.Name, | |||||
| statusStr: item.IsActive ? this.$t('user.Activated') : this.$t('user.notActive'), | |||||
| statusColor: item.IsActive ? 'rgb(82, 196, 26)' : 'rgb(245, 34, 45)', | |||||
| regTime: formatDate(new Date(item.CreatedUnix * 1000), 'yyyy-MM-dd HH:mm:ss'), | |||||
| } | |||||
| }, | |||||
| initData() { | |||||
| getUserInvitationCode({ page: this.pageInfo.curpage, pageSize: this.pageInfo.pageSize }).then(res => { | |||||
| res = res.data; | |||||
| if (res) { | |||||
| this.bannerImg = res.page_banner_img; | |||||
| this.bannerTitle = res.page_banner_title; | |||||
| this.pageLink = res.page_link; | |||||
| this.pageLinkDesc = res.page_link_desc; | |||||
| this.invitationCode = res.invitation_code; | |||||
| this.pageOpeniDesc = res.page_openi_desc; | |||||
| this.tableData = (res.invitation_users || []).map((item, index) => { | |||||
| return this.transRowData(item); | |||||
| }); | |||||
| this.pageInfo.total = res.invitation_users_count; | |||||
| const qrCode = new QRCode("__qr-code__", { | |||||
| text: this.invitationLink + this.invitationCode, | |||||
| width: 120, | |||||
| height: 120, | |||||
| colorDark: '#000000', | |||||
| colorLight: '#ffffff', | |||||
| correctLevel: QRCode.CorrectLevel.H | |||||
| }); | |||||
| } | |||||
| }).catch(err => { | |||||
| console.log(err); | |||||
| }); | |||||
| }, | |||||
| getTableData() { | |||||
| const params = { | |||||
| page: this.pageInfo.curpage, | |||||
| pageSize: this.pageInfo.pageSize, | |||||
| }; | |||||
| this.loading = true; | |||||
| getUserInvitationCode(params).then(res => { | |||||
| this.loading = false; | |||||
| res = res.data; | |||||
| const data = (res.invitation_users || []).map((item, index) => { | |||||
| return this.transRowData(item); | |||||
| }); | |||||
| this.tableData = data; | |||||
| this.pageInfo.total = res.invitation_users_count; | |||||
| }).catch(err => { | |||||
| console.log(err); | |||||
| this.loading = false; | |||||
| }); | |||||
| }, | |||||
| currentChange(val) { | |||||
| this.pageInfo.curpage = val; | |||||
| this.getTableData(); | |||||
| }, | |||||
| }, | |||||
| mounted() { | |||||
| this.initData(); | |||||
| this.initCopy(); | |||||
| }, | |||||
| beforeDestroy() { | |||||
| }, | |||||
| }; | |||||
| </script> | |||||
| <style scoped lang="less"> | |||||
| .title { | |||||
| margin-top: 15px; | |||||
| margin-bottom: 15px; | |||||
| .title-1 { | |||||
| font-weight: 500; | |||||
| font-size: 20px; | |||||
| color: rgba(16, 16, 16, 1); | |||||
| margin-bottom: 10px; | |||||
| } | |||||
| .title-2 { | |||||
| font-weight: 400; | |||||
| font-size: 14px; | |||||
| color: rgba(136, 136, 136, 1); | |||||
| } | |||||
| } | |||||
| .content-1 { | |||||
| margin-bottom: 32px; | |||||
| .img-c { | |||||
| height: 80px; | |||||
| position: relative; | |||||
| .img { | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| } | |||||
| .txt { | |||||
| position: absolute; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| left: 0; | |||||
| top: 0; | |||||
| line-height: 80px; | |||||
| padding-left: 25px; | |||||
| font-weight: 500; | |||||
| font-size: 24px; | |||||
| color: rgb(255, 255, 255); | |||||
| } | |||||
| } | |||||
| .descr { | |||||
| font-weight: 300; | |||||
| font-size: 16px; | |||||
| color: rgb(16, 16, 16); | |||||
| padding: 25px; | |||||
| border-left: 1px solid rgba(0, 0, 0, 0.1); | |||||
| border-right: 1px solid rgba(0, 0, 0, 0.1); | |||||
| border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |||||
| border-radius: 0px 0px 4px 4px; | |||||
| } | |||||
| } | |||||
| .content-2 { | |||||
| display: flex; | |||||
| background-color: rgb(228, 242, 255); | |||||
| border-color: rgb(228, 242, 255); | |||||
| border-width: 1px; | |||||
| border-style: solid; | |||||
| border-radius: 5px; | |||||
| padding: 25px; | |||||
| margin-bottom: 32px; | |||||
| .txt-c { | |||||
| flex: 1; | |||||
| font-weight: 300; | |||||
| font-size: 16px; | |||||
| color: rgb(16, 16, 16); | |||||
| span { | |||||
| line-height: 24px; | |||||
| } | |||||
| div { | |||||
| margin-bottom: 6px; | |||||
| } | |||||
| .txt-3 { | |||||
| margin-bottom: 15px; | |||||
| } | |||||
| } | |||||
| .__copy_link_btn__ { | |||||
| font-size: 14px; | |||||
| padding: 11px 15px; | |||||
| background: rgb(21, 114, 255); | |||||
| border-radius: 0; | |||||
| } | |||||
| .qr-code { | |||||
| width: 150px; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: end; | |||||
| } | |||||
| } | |||||
| .table-container { | |||||
| margin-bottom: 16px; | |||||
| /deep/ .el-table__header { | |||||
| th { | |||||
| background: rgb(245, 245, 246); | |||||
| font-size: 14px; | |||||
| color: rgb(36, 36, 36); | |||||
| font-weight: 400; | |||||
| } | |||||
| } | |||||
| /deep/ .el-table__body { | |||||
| td { | |||||
| font-size: 14px; | |||||
| } | |||||
| } | |||||
| .op-btn { | |||||
| cursor: pointer; | |||||
| font-size: 12px; | |||||
| color: rgb(25, 103, 252); | |||||
| margin: 0 5px; | |||||
| } | |||||
| } | |||||
| .center { | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| } | |||||
| </style> | |||||
| @@ -0,0 +1,17 @@ | |||||
| import Vue from 'vue'; | |||||
| import ElementUI from 'element-ui'; | |||||
| import 'element-ui/lib/theme-chalk/index.css'; | |||||
| import localeEn from 'element-ui/lib/locale/lang/en'; | |||||
| import localeZh from 'element-ui/lib/locale/lang/zh-CN'; | |||||
| import { i18n, lang } from '~/langs'; | |||||
| import App from './index.vue'; | |||||
| Vue.use(ElementUI, { | |||||
| locale: lang === 'zh-CN' ? localeZh : localeEn, | |||||
| size: 'small', | |||||
| }); | |||||
| new Vue({ | |||||
| i18n, | |||||
| render: (h) => h(App), | |||||
| }).$mount('#__vue-root'); | |||||