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