diff --git a/casdoor/user_adapter.go b/casdoor/user_adapter.go index 09b7957..741d14d 100644 --- a/casdoor/user_adapter.go +++ b/casdoor/user_adapter.go @@ -78,3 +78,51 @@ func QueryUsers(ids []string) map[string]*auth.User { } return users } + +func GetUserById(id string) *auth.User { + owner := CasdoorOrganization + + if adapter == nil { + panic("casdoor adapter is nil") + } + + if owner == "" || id == "" { + return nil + } + + user := auth.User{Owner: owner, Id: id} + existed, err := adapter.Engine.Get(&user) + if err != nil { + panic(err) + } + + if existed { + return &user + } else { + return nil + } +} + +func GetUserByName(name string) *auth.User { + owner := CasdoorOrganization + + if adapter == nil { + panic("casdoor adapter is nil") + } + + if owner == "" || name == "" { + return nil + } + + user := auth.User{Owner: owner, Name: name} + existed, err := adapter.Engine.Get(&user) + if err != nil { + panic(err) + } + + if existed { + return &user + } else { + return nil + } +} diff --git a/controllers/assignment.go b/controllers/assignment.go index 14aefc4..564e78b 100644 --- a/controllers/assignment.go +++ b/controllers/assignment.go @@ -114,3 +114,60 @@ func (c *ApiController) ChangeAssignment() { c.ResponseOk(true) } + +// MakeOneTpAssignment +// @Title MakeOneTpAssignment +// @Description 分配试卷流程处理员 +// @Param json body object.MakeOneTpAssignmentRequest true "assignment information" +// @Success 200 {object} response.Default +// @Failure 400 "invalid token(body)" +// @router /api/review/proj/tpassign [post] +func (c *ApiController) MakeOneTpAssignment() { + if c.RequireSignedIn() { + return + } + + var newAssign object.MakeOneTpAssignmentRequest + err := json.Unmarshal(c.Ctx.Input.RequestBody, &newAssign) + if err != nil { + c.ResponseError(err.Error()) + return + } + user := c.GetSessionUser() + + newAssign.Operator = user.Id + resp, err := object.MakeOneTpAssignment(&newAssign) + if err != nil { + c.ResponseError(err.Error()) + return + } + + c.ResponseOk(resp) +} + +// GetTpAssignment +// @Title GetTpAssignment +// @Description 分配试卷流程处理员 +// @Param tid path string true "uuid of testpaper" +// @Success 200 {object} response.Default +// @Failure 400 "invalid token(body)" +// @router /api/review/proj/tpassign/:tid [get] +func (c *ApiController) GetTpAssignment() { + if c.RequireSignedIn() { + return + } + + tid := c.GetString(":tid") + if tid == "" { + c.ResponseError("invalid id") + return + } + + resp, err := object.GetTestpaperAssignment(tid) + if err != nil { + c.ResponseError(err.Error()) + return + } + + c.ResponseOk(resp) +} diff --git a/controllers/file.go b/controllers/file.go index 34cea03..e3de035 100644 --- a/controllers/file.go +++ b/controllers/file.go @@ -6,7 +6,6 @@ import ( "io" "log" "mime/multipart" - "net/url" "path" "strings" @@ -46,7 +45,6 @@ func (c *ApiController) UploadFile() { defer file.Close() fileName := fileHeader.Filename - fileName = url.QueryEscape(fileName) fileBytes := getFileBytes(&file) fileDescription := c.GetString("description") @@ -63,13 +61,13 @@ func (c *ApiController) UploadFile() { Description: fileDescription, Tags: fileTags, } - fileUrl, objectKey := object.UploadFileToStorage(&uploadRequest, fileBytes) + fileUrl, _ := object.UploadFileToStorage(&uploadRequest, fileBytes) if fileUrl == "" { c.ResponseError("upload file error") return } - c.ResponseOk(fileUrl, objectKey) + c.ResponseOk(fileUrl, fileName) } // GetFileInfo diff --git a/controllers/question.go b/controllers/question.go index 8eb3d6f..ff21384 100644 --- a/controllers/question.go +++ b/controllers/question.go @@ -6,6 +6,21 @@ import ( "github.com/open-ct/openitem/object" ) +type CreateNewQuestionRequest struct { + Body object.Task `json:"body"` + Answer object.Task `json:"answer"` + Solution object.Task `json:"solution"` + + SourceProject string `json:"source_project"` // 项目来源 + Author string `json:"author"` + Info object.QuestionInfo `json:"info"` + BasicProps object.QuestionBasicProps `json:"basic_props"` + SpecProps object.QuestionSpecProps `json:"spec_props"` + ExtraProps object.QuestionExtraProps `json:"extra_props"` + AdvancedProps object.QuestionAdvancedProps `json:"advanced_props"` + ApplyRecord object.QuestionApplyRecord `json:"apply_record"` +} + // CreateNewQuestion // @Title CreateNewQuestion // @Description 创建新的题目(临时题目) @@ -18,13 +33,32 @@ func (c *ApiController) CreateNewQuestion() { return } - var request object.TempQuestion + var request CreateNewQuestionRequest + // var request object.TempQuestion err := json.Unmarshal(c.Ctx.Input.RequestBody, &request) + + tempQuestion := object.TempQuestion{ + SourceProject: request.SourceProject, + Author: request.Author, + Info: object.QuestionInfo{ + Title: request.Info.Title, + Type: request.Info.Type, + Body: request.Body.Text, + Answer: request.Answer.Text, + Solution: request.Solution.Text, + }, + BasicProps: request.BasicProps, + SpecProps: request.SpecProps, + ExtraProps: request.ExtraProps, + AdvancedProps: request.AdvancedProps, + ApplyRecord: request.ApplyRecord, + } + if err != nil { c.ResponseError(err.Error()) return } - resp, err := object.CreateNewTempQuestion(&request) + resp, err := object.CreateNewTempQuestion(&tempQuestion) if err != nil { c.ResponseError(err.Error()) return @@ -241,3 +275,29 @@ func (c *ApiController) GetProjectFinalQuestions() { c.ResponseOk(resp) } + +// SearchFinalQuestion +// @Title SearchFinalQuestion +// @Description 根据字符串模糊匹配题目题干 +// @Param bodyString path string true "题干描述字符串" +// @Success 200 {[]object.FinalQuestion} +// @Failure 400 "invalid qid" +// @router /api/qbank/question/search/:bodyString [get] +func (c *ApiController) SearchFinalQuestion() { + if c.RequireSignedIn() { + return + } + + bodyString := c.GetString(":bodyString") + if bodyString == "" { + c.ResponseError("null string") + return + } + resp, err := object.SearchQuestion(bodyString) + if err != nil { + c.ResponseError(err.Error()) + return + } + + c.ResponseOk(resp) +} diff --git a/controllers/step.go b/controllers/step.go index ebb8830..a75d82b 100644 --- a/controllers/step.go +++ b/controllers/step.go @@ -172,6 +172,32 @@ func (c *ApiController) SetStepStatus() { c.ResponseOk(true) } +// NextStep +// @Title NextStep +// @Description 进入下一流程 +// @Param json body object.NextStepRequest true "项目信息" +// @Success 200 true +// @Failure 400 "invalid json body" +// @router /api/review/proj/step/nextstep [post] +func (c *ApiController) NextStep() { + if c.RequireSignedIn() { + return + } + + var req object.NextStepRequest + err := json.Unmarshal(c.Ctx.Input.RequestBody, &req) + if err != nil { + c.ResponseError(err.Error()) + return + } + err = object.NextStep(&req) + if err != nil { + c.ResponseError(err.Error()) + return + } + c.ResponseOk(true) +} + // SetStepTimePoint // @Title SetStepTimePoint // @Description 为step设置时间点 diff --git a/controllers/submit.go b/controllers/submit.go index 28a842c..6aafd45 100644 --- a/controllers/submit.go +++ b/controllers/submit.go @@ -222,3 +222,56 @@ func (c *ApiController) DeleteSubmit() { c.ResponseOk(true) } + +// UpdateSubmitFile +// @Title UpdateSubmitFile +// @Description 更新submit中的文件 +// @Param json body object.UpdateFileRequest "submit id 和 修改后的文件url" +// @Success 200 true +// @Failure 400 "invalid submit id" +// @router /api/review/proj/submit/updatefile [put] +func (c *ApiController) UpdateSubmitFile() { + if c.RequireSignedIn() { + return + } + + var req *object.UpdateFileRequest + err := json.Unmarshal(c.Ctx.Input.RequestBody, &req) + if err != nil { + c.ResponseError(err.Error()) + return + } + err = object.UpdateSubmitFile(req) + if err != nil { + c.ResponseError(err.Error()) + return + } + + c.ResponseOk(true) +} + +// GetProjectSubmit +// @Title GetProjectSubmit +// @Description 获取项目所有submit +// @Param pid path string true "项目id" +// @Success 200 true +// @Failure 400 "invalid submit id" +// @router /api/review/proj/submit/getall/:pid [get] +func (c *ApiController) GetProjectSubmit() { + if c.RequireSignedIn() { + return + } + + pid := c.GetString(":pid") + if pid == "" { + c.ResponseError("invalid id") + return + } + resp, err := object.GetProjectSubmit(pid) + if err != nil { + c.ResponseError(err.Error()) + return + } + + c.ResponseOk(resp) +} diff --git a/controllers/testpaper.go b/controllers/testpaper.go index cadb806..eca3078 100644 --- a/controllers/testpaper.go +++ b/controllers/testpaper.go @@ -274,3 +274,30 @@ func (c *ApiController) DeleteTempTestpaper() { c.ResponseOk("ok") } + +// GetTempTestPaperDetail +// @Title GetProjectFinalTestpaper +// @Description 根据id获取tempTestPaper +// @Param uid path string true "tempTestpaper id" +// @Success 200 {[]object.FinalTestpaper} +// @Failure 400 "invalid qid" +// @router /api/qbank/testpaper/:tid [get] +func (c *ApiController) GetTempTestPaperDetail() { + if c.RequireSignedIn() { + return + } + + tid := c.GetString(":tid") + if tid == "" { + c.ResponseError("invalid id") + return + } + + resp, err := object.GetTempTestPaperDetail(tid) + if err != nil { + c.ResponseError(err.Error()) + return + } + + c.ResponseOk(resp) +} diff --git a/controllers/user.go b/controllers/user.go index 6068cf6..c1e0c7d 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -2,7 +2,32 @@ package controllers import "github.com/open-ct/openitem/casdoor" +// GetUsers +// @Title GetUsers +// @Description 获取组织中的所有人员 +// @Success 200 {object} []*auth.User +// @router /api/get-users [get] func (c *ApiController) GetUsers() { + if c.RequireSignedIn() { + return + } + c.Data["json"] = casdoor.GetUsers() c.ServeJSON() } + +// GetUserByName +// @Title GetUserByName +// @Description 根据用户名获取用户信息 +// @Success 200 {object} auth.User +// @router /api/get-user/:name [get] +func (c *ApiController) GetUserByName() { + if c.RequireSignedIn() { + return + } + + name := c.GetString(":name") + + c.Data["json"] = casdoor.GetUserByName(name) + c.ServeJSON() +} diff --git a/go.mod b/go.mod index b601351..37ea9fb 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,13 @@ require ( github.com/astaxie/beego v1.12.3 github.com/casdoor/casdoor-go-sdk v0.3.3 github.com/go-sql-driver/mysql v1.6.0 + github.com/google/go-cmp v0.5.6 // indirect github.com/google/uuid v1.0.0 + github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect + golang.org/x/tools v0.1.11 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect xorm.io/builder v0.3.12 xorm.io/core v0.7.3 xorm.io/xorm v1.2.5 diff --git a/go.sum b/go.sum index d5d4091..5c9f08b 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,7 @@ github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:sr github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -189,8 +190,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -289,9 +291,6 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= -github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -314,8 +313,9 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -335,8 +335,9 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -486,6 +487,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= @@ -524,8 +526,9 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -555,8 +558,9 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -592,8 +596,9 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -610,6 +615,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -657,8 +663,12 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 h1:h+EGohizhe9XlX18rfpa8k8RAc5XyaeamM+0VHRd4lc= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -667,8 +677,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -721,8 +732,9 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 h1:M8tBwCtWD/cZV9DZpFYRUgaymAYAr+aIUTWzDaM3uPs= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY= +golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -826,7 +838,6 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= -gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -837,12 +848,11 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE= -gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/object/adapter.go b/object/adapter.go index 1ee48c3..d7b5af5 100644 --- a/object/adapter.go +++ b/object/adapter.go @@ -139,4 +139,9 @@ func (a *Adapter) createTable() { if err != nil { panic(err) } + + err = a.engine.Sync2(new(TpAssignment)) + if err != nil { + panic(err) + } } diff --git a/object/assignment.go b/object/assignment.go index da9b1ed..e52f6ba 100644 --- a/object/assignment.go +++ b/object/assignment.go @@ -10,12 +10,12 @@ import ( type Assignment struct { Uuid string `xorm:"varchar(100) notnull pk" json:"uuid"` - UserId string `json:"user_id" bson:"user_id"` - ProjectId string `json:"project_id" bson:"project_id"` - Role int `json:"role" bson:"role"` - Operator string `json:"operator" bson:"operator"` - IsConfirmed bool `json:"is_confirmed" bson:"is_confirmed"` - Status int `json:"status" bson:"status"` + UserId string `json:"user_id"` + ProjectId string `json:"project_id"` + Role int `json:"role"` + Operator string `json:"operator"` + IsConfirmed bool `json:"is_confirmed"` + Status int `json:"status"` CreateAt time.Time `xorm:"created" json:"create_at"` UpdatedAt time.Time `xorm:"updated" json:"updated_at"` diff --git a/object/file.go b/object/file.go index 639c9b2..29e2026 100644 --- a/object/file.go +++ b/object/file.go @@ -35,7 +35,7 @@ func AddFile(fileItem *FileItem) error { func UploadFileToStorage(req *FileItem, fileBytes []byte) (string, string) { tag := "file" parent := "UploadFile" - fullFilePath := fmt.Sprintf("openitem/file/%s/%s/%s", req.Owner, "uploadfile", req.Name) + fullFilePath := fmt.Sprintf(req.Name) fileUrl, objectKey, err := auth.UploadResource(req.Owner, tag, parent, fullFilePath, fileBytes) if err != nil { panic(err) diff --git a/object/project.go b/object/project.go index 93f8ae1..d1b4fcb 100644 --- a/object/project.go +++ b/object/project.go @@ -48,7 +48,7 @@ type ProjectMaterials struct { Files []string `json:"files" bson:"files"` } -// ProjectTimeTable: describe the time line of a project +// ProjectTimeTable describe the timeline of a project type ProjectTimeTable struct { TimePoints []ProjectTimePoint `json:"time_points" bson:"time_points"` } @@ -210,7 +210,7 @@ func CreateTemplateProject(req *Project) (string, error) { _, err = adapter.engine.Insert(&assign) if err != nil { - log.Printf("[Mongo] Create project's assignment error: %s\n", err.Error()) + log.Printf("Create project's assignment error: %s\n", err.Error()) // delete project adapter.engine.ID(core.PK{newProject.Owner, newProject.Name}).Delete(&Project{}) return "", err @@ -226,13 +226,18 @@ func CreateTemplateProject(req *Project) (string, error) { "组建团队", "测试框架与论证报告", "6人访谈", "30人测试", "试题外审", "300人测试", "定稿审查", } for i := 0; i < 7; i++ { + statusString := "未开始" + if i == 0 { + statusString = "未通过" + } + step := Step{ Uuid: util.GenUuidV4(), Name: stepName[i], ProjectId: fmt.Sprintf("%s/%s", newProject.Owner, newProject.Name), - Index: i, - Status: 0, + StepIndex: i, + Status: statusString, Creator: req.Owner, } @@ -330,7 +335,7 @@ func GetProjectDetailedInfo(pid string) (map[string]interface{}, error) { // get steps & all references var projectSteps []Step - err = adapter.engine.Where(builder.Eq{"project_id": pid}).Asc("index").Find(&projectSteps) + err = adapter.engine.Where(builder.Eq{"project_id": pid}).Asc("step_index").Find(&projectSteps) if err != nil { return nil, err } @@ -361,6 +366,9 @@ func GetProjectDetailedInfo(pid string) (map[string]interface{}, error) { } projectInfo["materials"] = projectMaterials + nowStep, _ := getProjectStep(pid) + projectInfo["now_step"] = nowStep + return projectInfo, nil } diff --git a/object/question.go b/object/question.go index 74a2df5..a76fa8b 100644 --- a/object/question.go +++ b/object/question.go @@ -9,66 +9,94 @@ import ( ) type QuestionInfo struct { - Title string `json:"title" bson:"title"` - Type string `json:"type" bson:"type"` - Body string `json:"body" bson:"body"` - Answer string `json:"answer" bson:"answer"` - Solution string `json:"solution" bson:"solution"` + Title string `json:"title"` + Type string `json:"type"` + Body string `json:"body"` + Answer string `json:"answer"` + Solution string `json:"solution"` } type QuestionBasicProps struct { - Encode string `json:"encode" bson:"encode"` - Subject string `json:"subject" bson:"subject"` - DetailsDimension string `json:"details_dimension" bson:"details_dimension"` - SubDetailsDimension string `json:"sub_details_dimension" bson:"sub_details_dimension"` - AbilityDimension string `json:"ability_dimension" bson:"ability_dimension"` - SubAbilityDimension string `json:"sub_ability_dimension" bson:"sub_ability_dimension"` - Description string `json:"description" bson:"description"` - SubjectRequirements string `json:"subject_requirements" bson:"subject_requirements"` - Details string `json:"details" bson:"details"` - Keywords []string `json:"keywords" bson:"keywords"` + Encode string `json:"encode"` + Subject string `json:"subject"` + DetailsDimension string `json:"details_dimension"` + SubDetailsDimension string `json:"sub_details_dimension"` + AbilityDimension string `json:"ability_dimension"` + SubAbilityDimension string `json:"sub_ability_dimension"` + Description string `json:"description"` + SubjectRequirements string `json:"subject_requirements"` + Details string `json:"details"` + Keywords []string `json:"keywords"` } type QuestionSpecProps struct { - Topic string `json:"topic" bson:"topic"` - ArticleType string `json:"article_type" bson:"article_type"` - Length string `json:"length" bson:"length"` + Topic string `json:"topic"` + ArticleType string `json:"article_type"` + Length string `json:"length"` } type QuestionExtraProps struct { - IsScene bool `json:"is_scene" bson:"is_scene"` - IsQuestionGroup bool `json:"is_question_group" bson:"is_question_group"` - ReadingMaterialTopic string `json:"reading_material_topic" bson:"reading_material_topic"` - MaterialLength int `json:"material_length" bson:"material_length"` + IsScene bool `json:"is_scene"` + IsQuestionGroup bool `json:"is_question_group"` + ReadingMaterialTopic string `json:"reading_material_topic"` + MaterialLength int `json:"material_length"` } type QuestionAdvancedProps struct { - CttLevel float64 `json:"ctt_level" bson:"ctt_level"` - CttDiff_1 float64 `json:"ctt_diff_1" bson:"ctt_diff_1"` - CttDiff_2 float64 `json:"ctt_diff_2" bson:"ctt_diff_2"` - IrtLevel float64 `json:"irt_level" bson:"irt_level"` + CttLevel float64 `json:"ctt_level"` + CttDiff_1 float64 `json:"ctt_diff_1"` + CttDiff_2 float64 `json:"ctt_diff_2"` + IrtLevel float64 `json:"irt_level"` } type QuestionComment struct { - TimePoint time.Time `json:"time_point" bson:"time_point"` - Comment string `json:"comment" bson:"comment"` - Author string `json:"author" bson:"author"` + TimePoint time.Time `json:"time_point"` + Comment string `json:"comment"` + Author string `json:"author"` } type QuestionApplyRecord struct { - GradeFits string `json:"grade_fits" bson:"grade_fits"` - TestYear string `json:"test_year" bson:"test_year"` - TestRegion []string `json:"test_region" bson:"test_region"` - ParticipantCount int `json:"participant_count" bson:"participant_count"` - TestCount int `json:"test_count" bson:"test_count"` + GradeFits string `json:"grade_fits"` + TestYear string `json:"test_year"` + TestRegion []string `json:"test_region"` + ParticipantCount int `json:"participant_count"` + TestCount int `json:"test_count"` +} + +type Task struct { + Owner string `xorm:"varchar(100) notnull pk" json:"owner"` + Name string `xorm:"varchar(100) notnull pk" json:"name"` + CreatedTime string `xorm:"varchar(100)" json:"createdTime"` + + Preface string `xorm:"mediumtext" json:"preface"` + Text string `xorm:"mediumtext" json:"text"` + Type string `xorm:"varchar(100)" json:"type"` + Canvas string `xorm:"mediumtext" json:"canvas"` + Basic string `xorm:"mediumtext" json:"basic"` + Video string `xorm:"mediumtext" json:"video"` + Slides string `xorm:"mediumtext" json:"slides"` + Sketch string `xorm:"mediumtext" json:"sketch"` + Frame string `xorm:"mediumtext" json:"frame"` + Three string `xorm:"mediumtext" json:"three"` + Game string `xorm:"mediumtext" json:"game"` + Deck string `xorm:"mediumtext" json:"deck"` + Extras []string `xorm:"varchar(1000)" json:"extras"` + + Options []string `xorm:"varchar(100)" json:"options"` + Answer []string `xorm:"varchar(100)" json:"answer"` + + SourceProject string `json:"source_project"` // 项目来源 } type TempQuestion struct { Uuid string `xorm:"varchar(100) notnull pk" json:"uuid"` - IsRoot bool `json:"is_root"` // 临时题目是否是根 - Base string `json:"base"` // 若不是root, 需要设置上级题目, 进行版本管理 + IsRoot bool `json:"is_root"` // 临时题目是否是根 + Base string `json:"base"` // 若不是root, 需要设置上级题目, 进行版本管理 + Next string `json:"next"` SourceProject string `json:"source_project"` // 项目来源 Author string `json:"author"` + IsNew bool `json:"is_new"` + FinalBase string `json:"final_base"` Info QuestionInfo `xorm:"mediumtext json" json:"info"` BasicProps QuestionBasicProps `xorm:"mediumtext json" json:"basic_props"` SpecProps QuestionSpecProps `xorm:"mediumtext json" json:"spec_props"` @@ -76,6 +104,7 @@ type TempQuestion struct { AdvancedProps QuestionAdvancedProps `xorm:"mediumtext json" json:"advanced_props"` ApplyRecord QuestionApplyRecord `xorm:"mediumtext json" json:"apply_record"` CommentRecord []QuestionComment `xorm:"mediumtext" json:"comment_record"` + ChangeLog string `json:"change_log"` CreateAt time.Time `xorm:"created" json:"create_at"` UpdatedAt time.Time `xorm:"updated" json:"updated_at"` @@ -147,12 +176,16 @@ func CreateNewTempQuestion(request *TempQuestion) (string, error) { IsRoot: true, SourceProject: request.SourceProject, Author: request.Author, + Next: "null", + IsNew: true, + FinalBase: "", Info: request.Info, BasicProps: request.BasicProps, SpecProps: request.SpecProps, ExtraProps: request.ExtraProps, AdvancedProps: request.AdvancedProps, ApplyRecord: request.ApplyRecord, + ChangeLog: request.ChangeLog, CommentRecord: nil, } newTempQuestion.Base = newTempQuestion.Uuid @@ -182,14 +215,18 @@ func UpdateQuestion(request *TempQuestion) (string, error) { Uuid: util.GenUuidV4(), IsRoot: false, Base: request.Base, + Next: "null", SourceProject: oldQuestion.SourceProject, - Author: request.Author, + Author: oldQuestion.Author, + IsNew: oldQuestion.IsNew, + FinalBase: oldQuestion.FinalBase, Info: request.Info, BasicProps: request.BasicProps, SpecProps: request.SpecProps, ExtraProps: request.ExtraProps, AdvancedProps: request.AdvancedProps, ApplyRecord: request.ApplyRecord, + ChangeLog: request.ChangeLog, CommentRecord: nil, } @@ -200,10 +237,35 @@ func UpdateQuestion(request *TempQuestion) (string, error) { } updatedId := newTempQuestion.Uuid + + _, err = adapter.engine.ID(request.Base).Cols("next").Update(&TempQuestion{Next: updatedId}) + if err != nil { + return "", err + } + log.Printf("temp-question updated: %s\n", updatedId) return updatedId, nil } +func UpdateFinalQuestion(request *TempQuestion) error { + newFinalQuestion := FinalQuestion{ + FinalVersion: request.Uuid, + Info: request.Info, + BasicProps: request.BasicProps, + SpecProps: request.SpecProps, + ExtraProps: request.ExtraProps, + AdvancedProps: request.AdvancedProps, + ApplyRecord: request.ApplyRecord, + } + + _, err := adapter.engine.ID(request.FinalBase).Update(&newFinalQuestion) + if err != nil { + return err + } + + return nil +} + func TraceQuestionVersion(qid string) ([]TempQuestion, error) { var endPointQuestion TempQuestion @@ -293,7 +355,7 @@ func FinishTempQuestion(qid string) (string, error) { func GetUserTempQuestions(uid string) ([]TempQuestion, error) { var questions []TempQuestion - err := adapter.engine.Where(builder.Eq{"author": uid}).Find(&questions) + err := adapter.engine.Where(builder.Eq{"author": uid, "next": "null"}).Find(&questions) if err != nil { log.Printf("find user's temp-question error: %s\n", err.Error()) return nil, err @@ -315,7 +377,7 @@ func GetUserFinalQuestions(uid string) ([]FinalQuestion, error) { func GetProjectTempQuestions(pid string) ([]TempQuestion, error) { var questions []TempQuestion - err := adapter.engine.Where(builder.Eq{"source_project": pid}).Find(&questions) + err := adapter.engine.Where(builder.Eq{"source_project": pid, "next": "null"}).Find(&questions) if err != nil { log.Printf("find project's temp-question error: %s\n", err.Error()) return nil, err @@ -349,3 +411,15 @@ func QueryTempQuestions(idList []string) map[string]TempQuestion { } return questionsMap } + +func SearchQuestion(bodyString string) ([]FinalQuestion, error) { + var questions []FinalQuestion + + err := adapter.engine.Where("info like ?", "%\\\"body\\\":\\\"%"+bodyString+"%\\\"%").Find(&questions) + if err != nil { + log.Printf("search final-question error: %s\n", err.Error()) + return nil, err + } + + return questions, nil +} diff --git a/object/step.go b/object/step.go index c64e420..5d34e92 100644 --- a/object/step.go +++ b/object/step.go @@ -1,6 +1,7 @@ package object import ( + "errors" "log" "time" @@ -12,23 +13,23 @@ type Step struct { Uuid string `xorm:"varchar(100) notnull pk" json:"uuid"` Name string `json:"name"` ProjectId string `json:"project_id"` - Index int `json:"index"` + StepIndex int `json:"step_index"` Description string `json:"description"` Requirement string `json:"requirement"` - Status int `json:"status"` + Status string `json:"status"` Deadline int64 `json:"deadline"` Timetable []ProjectTimePoint `xorm:"mediumtext" json:"timetable"` Creator string `json:"creator"` - Attachments []string `xorm:"mediumtext" json:"attachments"` // uuid of files + Attachments []FileRecord `xorm:"mediumtext" json:"attachments"` // uuid of files CreateAt time.Time `xorm:"created" json:"create_at"` UpdatedAt time.Time `xorm:"updated" json:"updated_at"` } type AddStepAttachment struct { - StepId string `json:"step_id"` - FilesIds []string `json:"files_ids"` - Uploader string `json:"uploader"` + StepId string `json:"step_id"` + FilesIds []FileRecord `json:"files_ids"` + Uploader string `json:"uploader"` } type SetStepTimePointRequest struct { @@ -61,6 +62,10 @@ type StepDataStatistic struct { ToCorrect float64 `json:"to_correct"` } +type NextStepRequest struct { + Pid string `json:"pid"` +} + func AddStep(step *Step) error { _, err := adapter.engine.Insert(step) if err != nil { @@ -75,11 +80,11 @@ func CreateOneStep(req *Step) (string, error) { Uuid: util.GenUuidV4(), Name: req.Name, ProjectId: req.ProjectId, - Index: req.Index, + StepIndex: req.StepIndex, Description: req.Description, Requirement: req.Requirement, Deadline: req.Deadline, - Status: 0, + Status: "未开始", Creator: req.Creator, } @@ -277,3 +282,59 @@ func DeleteStep(stepId string) error { } return nil } + +func NextStep(req *NextStepRequest) error { + var step Step + _, err := adapter.engine.Where(builder.Eq{"project_id": req.Pid}.And(builder.Eq{"status": "未通过"})).Get(&step) + if err != nil { + return err + } + + var tempTestpapers []TempTestpaper + adapter.engine.Where(builder.Eq{"source_project": req.Pid}).Find(&tempTestpapers) + + flag := true + + for _, v := range tempTestpapers { + var submit Submit + get, err := adapter.engine.Where(builder.Eq{"testpaper_id": v.Uuid}).Get(&submit) + if err != nil { + return err + } + if !get || submit.Status != "审核通过" { + flag = false + break + } + } + + if flag { + index := step.StepIndex + + if index == 6 { + // 最后一个步骤 + adapter.engine.Where(builder.Eq{"project_id": req.Pid}.And(builder.Eq{"step_index": index})).Update(&Step{Status: "已通过"}) + } else { + adapter.engine.Where(builder.Eq{"project_id": req.Pid}.And(builder.Eq{"step_index": index})).Cols("status").Update(&Step{Status: "已通过"}) + adapter.engine.Where(builder.Eq{"project_id": req.Pid}.And(builder.Eq{"step_index": index + 1})).Cols("status").Update(&Step{Status: "未通过"}) + } + + return nil + } else { + return errors.New("试卷审核未全部通过") + } +} + +func getProjectStep(pid string) (string, error) { + var step Step + + _, err := adapter.engine.Where(builder.Eq{"project_id": pid, "status": "未通过"}).Get(&step) + if err != nil { + return "", err + } + + stepName := []string{ + "组建团队", "测试框架与论证报告", "6人访谈", "30人测试", "试题外审", "300人测试", "定稿审查", + } + + return stepName[step.StepIndex], nil +} diff --git a/object/submit.go b/object/submit.go index 085cdac..ca01e8b 100644 --- a/object/submit.go +++ b/object/submit.go @@ -16,12 +16,14 @@ type Submit struct { Name string `xorm:"varchar(100) notnull pk" json:"name"` CreatedTime string `xorm:"varchar(100)" json:"created_time"` - StepId string `json:"step_id"` - Title string `json:"title"` - Description string `json:"description"` - Submitter string `json:"submitter"` - Contents []Content `xorm:"mediumtext" json:"contents"` - Status int `json:"status"` + StepId string `json:"step_id"` + TestpaperId string `json:"testpaper_id"` + Title string `json:"title"` + Description string `json:"description"` + Submitter string `json:"submitter"` + Contents []Content `xorm:"mediumtext" json:"contents"` + Status string `json:"status"` + File []FileRecord `json:"file"` CreateAt time.Time `xorm:"created" json:"create_at"` UpdatedAt time.Time `xorm:"updated" json:"updated_at"` @@ -57,7 +59,17 @@ type WithdrawContentInSubmit struct { type SetSubmitStatusRequest struct { SubmitId string `json:"submit_id"` - NewStatus int `json:"new_status"` + NewStatus string `json:"new_status"` +} + +type UpdateFileRequest struct { + SubmitId string `json:"submit_id"` + NewFileUrl []FileRecord `json:"new_file_url"` +} + +type FileRecord struct { + FileName string `json:"file_name"` + FileUrl string `json:"file_url"` } func getSubmit(owner string, name string) *Submit { @@ -124,9 +136,12 @@ func MakeOneSubmit(req *Submit) (*Submit, error) { CreatedTime: time.Now().Format("2006-01-02 15:04:05"), StepId: req.StepId, + TestpaperId: req.TestpaperId, Title: req.Title, Description: req.Description, Submitter: req.Submitter, + Status: fmt.Sprintf("%s", "未审核"), + File: req.File, } err := AddSubmit(&newSubmit) @@ -141,6 +156,16 @@ func MakeOneSubmit(req *Submit) (*Submit, error) { return &newSubmit, nil } +func UpdateSubmitFile(req *UpdateFileRequest) error { + owner, name := util.GetOwnerAndNameFromId(req.SubmitId) + _, err := adapter.engine.ID(core.PK{owner, name}).Cols("file").Update(&Submit{File: req.NewFileUrl}) + if err != nil { + return err + } + + return nil +} + func AppendContent(req *AppendContentInSubmit) (*[]Content, error) { var submit Submit @@ -201,7 +226,7 @@ func SetSubmitStatus(req *SetSubmitStatusRequest) error { _, err := adapter.engine.ID(core.PK{owner, name}).Cols("status").Update(&Submit{Status: req.NewStatus}) if err != nil { - log.Printf("delete content error: %s\n" + err.Error()) + log.Printf("set submit status error: %s\n" + err.Error()) return err } return nil @@ -218,3 +243,25 @@ func DeleteSubmit(submitId string) error { return nil } + +func GetProjectSubmit(pid string) ([]Submit, error) { + var steps []Step + + err := adapter.engine.Where(builder.Eq{"project_id": pid}).Find(&steps) + if err != nil { + return nil, err + } + + var submits []Submit + + for _, step := range steps { + var tempSubmits []Submit + err := adapter.engine.Where(builder.Eq{"step_id": step.Uuid}).Find(&tempSubmits) + if err != nil { + return nil, err + } + submits = append(submits, tempSubmits...) + } + + return submits, nil +} diff --git a/object/testpaper.go b/object/testpaper.go index fe760f0..b5033bf 100644 --- a/object/testpaper.go +++ b/object/testpaper.go @@ -2,6 +2,7 @@ package object import ( "log" + "sort" "time" "github.com/open-ct/openitem/util" @@ -9,23 +10,40 @@ import ( ) type QuestionItem struct { - QuestionId string `json:"question_id"` - Score int `json:"score"` - Comment string `json:"comment"` + SmallQuestionNumber int `json:"small_question_number"` + QuestionId string `json:"question_id"` + Score int `json:"score"` + Comment string `json:"comment"` +} + +type QuestionItemV1 struct { + SmallQuestionNumber int `json:"small_question_number"` + Question TempQuestion `json:"question"` + Score int `json:"score"` + Comment string `json:"comment"` } type TestpaperPart struct { - Title string `json:"title"` - Description string `json:"description"` - QuestionList []QuestionItem `xorm:"mediumtext" json:"question_list"` - Score int `json:"score"` + BigQuestionNumber int `json:"big_question_number"` + Title string `json:"title"` + Description string `json:"description"` + QuestionList []QuestionItem `xorm:"mediumtext" json:"question_list"` + Score int `json:"score"` +} + +type TestpaperPartV1 struct { + BigQuestionNumber int `json:"big_question_number"` + Title string `json:"title"` + Description string `json:"description"` + QuestionList []QuestionItemV1 `xorm:"mediumtext" json:"question_list"` + Score int `json:"score"` } type TestpaperProps struct { - GradeRange []string `xorm:"mediumtext notnull pk" json:"grade_range"` - Subjects []string `xorm:"mediumtext notnull pk" json:"subjects"` - Difficulty string `xorm:"notnull pk" json:"difficulty"` - TimeLimit string `xorm:"notnull pk" json:"time_limit"` + GradeRange []string `xorm:"mediumtext" json:"grade_range"` + Subjects []string `xorm:"mediumtext" json:"subjects"` + Difficulty string `json:"difficulty"` + TimeLimit string `json:"time_limit"` } type TestpaperComment struct { @@ -69,6 +87,18 @@ type AddTestpaperCommentRequest struct { Author string `json:"author"` } +type TempTestpaperResponse struct { + Uuid string `xorm:"varchar(100) notnull pk" json:"uuid"` + IsRoot bool `json:"is_root"` + Base string `json:"base"` + SourceProject string `json:"source_project"` + Author string `json:"author"` + Title string `json:"title"` + Info []TestpaperPartV1 `xorm:"mediumtext" json:"info"` + Props TestpaperProps `xorm:"mediumtext json" json:"props"` + CommentRecord []TestpaperComment `xorm:"mediumtext" json:"comment_record"` +} + func AddTempTestpaper(tempTestpaper *TempTestpaper) error { _, err := adapter.engine.Insert(tempTestpaper) if err != nil { @@ -292,3 +322,71 @@ func DeleteFinalTestpaper(tid string) error { } return nil } + +func GetTempTestPaperDetail(tid string) (*TempTestpaperResponse, error) { + var tempTestpaper TempTestpaper + + _, err := adapter.engine.ID(tid).Get(&tempTestpaper) + if err != nil { + log.Printf("[get temptestpaper] get temptestpaper error: %s\n", err.Error()) + return nil, err + } + + var infoV1 []TestpaperPartV1 + + for _, part := range tempTestpaper.Info { + testpaperPart := TestpaperPartV1{ + BigQuestionNumber: part.BigQuestionNumber, + Title: part.Title, + Description: part.Description, + QuestionList: []QuestionItemV1{}, + Score: part.Score, + } + + for _, question := range part.QuestionList { + var tempQuestion TempQuestion + _, err := adapter.engine.ID(question.QuestionId).Get(&tempQuestion) + if err != nil { + return nil, err + } + testpaperPart.QuestionList = append(testpaperPart.QuestionList, QuestionItemV1{ + SmallQuestionNumber: question.SmallQuestionNumber, + Question: tempQuestion, + Score: question.Score, + Comment: question.Comment, + }) + } + + questionList := &testpaperPart.QuestionList + + sort.Slice(*questionList, func(i, j int) bool { + if (*questionList)[i].SmallQuestionNumber < (*questionList)[j].SmallQuestionNumber { + return true + } + return false + }) + + infoV1 = append(infoV1, testpaperPart) + } + + sort.Slice(infoV1, func(i, j int) bool { + if infoV1[i].BigQuestionNumber < infoV1[j].BigQuestionNumber { + return true + } + return false + }) + + res := &TempTestpaperResponse{ + Uuid: tempTestpaper.Uuid, + IsRoot: tempTestpaper.IsRoot, + Base: tempTestpaper.Base, + SourceProject: tempTestpaper.SourceProject, + Author: tempTestpaper.Author, + Title: tempTestpaper.Title, + Info: infoV1, + Props: tempTestpaper.Props, + CommentRecord: tempTestpaper.CommentRecord, + } + + return res, nil +} diff --git a/object/tpassignment.go b/object/tpassignment.go new file mode 100644 index 0000000..266e0e4 --- /dev/null +++ b/object/tpassignment.go @@ -0,0 +1,68 @@ +package object + +import ( + "log" + "time" + + "github.com/casdoor/casdoor-go-sdk/auth" + "github.com/open-ct/openitem/casdoor" + "github.com/open-ct/openitem/util" + "xorm.io/builder" +) + +type TpAssignment struct { + Uuid string `xorm:"varchar(100) notnull pk" json:"uuid"` + UserId string `json:"user_id"` + ProjectId string `json:"project_id"` + TestpaperId string `json:"testpaper_id"` + Role string `json:"role"` + Operator string `json:"operator"` + + CreateAt time.Time `xorm:"created" json:"create_at"` + UpdatedAt time.Time `xorm:"updated" json:"updated_at"` +} + +type MakeOneTpAssignmentRequest struct { + Operator string `json:"operator"` + ProjectId string `json:"project_id"` + TestpaperId string `json:"testpaper_id"` + UserId string `json:"user_id"` + Role string `json:"role"` +} + +func MakeOneTpAssignment(req *MakeOneTpAssignmentRequest) (string, error) { + newAssign := TpAssignment{ + Uuid: util.GenUuidV4(), + UserId: req.UserId, + ProjectId: req.ProjectId, + TestpaperId: req.TestpaperId, + Role: req.Role, + Operator: req.Operator, + } + _, err := adapter.engine.Insert(&newAssign) + if err != nil { + log.Printf("[TpAssignment] %s\n", err.Error()) + return "", err + } + log.Printf("Created new tpassignment: %s", newAssign.Uuid) + return newAssign.Uuid, nil +} + +func GetTestpaperAssignment(tid string) (map[string]auth.User, error) { + var tpassignments []TpAssignment + + err := adapter.engine.Where(builder.Eq{"testpaper_id": tid}).Find(&tpassignments) + if err != nil { + return nil, err + } + + umap := make(map[string]auth.User) + + for _, assign := range tpassignments { + user := casdoor.GetUserById(assign.UserId) + + umap[assign.Role] = *user + } + + return umap, nil +} diff --git a/routers/router.go b/routers/router.go index a9bcc00..823854c 100644 --- a/routers/router.go +++ b/routers/router.go @@ -24,6 +24,7 @@ func initAPI() { beego.Router("/api/get-account", &controllers.ApiController{}, "GET:GetAccount") beego.Router("/api/get-users", &controllers.ApiController{}, "GET:GetUsers") + beego.Router("/api/get-user", &controllers.ApiController{}, "GET:GetUserByName") beego.Router("/api/get-global-datasets", &controllers.ApiController{}, "GET:GetGlobalDatasets") beego.Router("/api/get-datasets", &controllers.ApiController{}, "GET:GetDatasets") @@ -57,6 +58,7 @@ func initAPI() { beego.Router("/api/review/proj/step/timepoint", &controllers.ApiController{}, "DELETE:DeleteStepTimePoint") beego.Router("/api/review/proj/step/stat", &controllers.ApiController{}, "GET:GetStepStatisticData") beego.Router("/api/review/proj/step", &controllers.ApiController{}, "DELETE:DeleteStep") + beego.Router("/api/review/proj/next", &controllers.ApiController{}, "POST:NextStep") // submit beego.Router("/api/review/proj/submit", &controllers.ApiController{}, "GET:GetOneSubmit") @@ -67,6 +69,8 @@ func initAPI() { beego.Router("/api/review/proj/submit/content", &controllers.ApiController{}, "DELETE:WithdrawContentInStep") beego.Router("/api/review/proj/submit", &controllers.ApiController{}, "PUT:SetSubmitStatus") beego.Router("/api/review/proj/submit", &controllers.ApiController{}, "DELETE:DeleteSubmit") + beego.Router("/api/review/proj/submit/updatefile", &controllers.ApiController{}, "PUT:UpdateSubmitFile") + beego.Router("/api/review/proj/submit/getall", &controllers.ApiController{}, "GET:GetProjectSubmit") // assignment beego.Router("/api/review/proj/user", &controllers.ApiController{}, "GET:GetUserAssignments") @@ -74,6 +78,8 @@ func initAPI() { beego.Router("/api/review/proj/assign", &controllers.ApiController{}, "GET:GetProjectAssignments") beego.Router("/api/review/proj/assign", &controllers.ApiController{}, "DELETE:DeleteAssignment") beego.Router("/api/review/proj/assign", &controllers.ApiController{}, "PATCH:ChangeAssignment") + beego.Router("/api/review/proj/tpassign", &controllers.ApiController{}, "POST:MakeOneTpAssignment") + beego.Router("/api/review/proj/tpassign", &controllers.ApiController{}, "GET:GetTpAssignment") // file beego.Router("/api/review/file", &controllers.ApiController{}, "POST:UploadFile") @@ -97,10 +103,12 @@ func initAPI() { beego.Router("/api/qbank/question/user_f", &controllers.ApiController{}, "GET:GetUserFinalQuestions") beego.Router("/api/qbank/question/proj_t", &controllers.ApiController{}, "GET:GetProjectTempQuestions") beego.Router("/api/qbank/question/proj_f", &controllers.ApiController{}, "GET:GetProjectFinalQuestions") + beego.Router("/api/qbank/question/search", &controllers.ApiController{}, "GET:SearchFinalQuestion") // testpaper beego.Router("/api/qbank/testpaper", &controllers.ApiController{}, "POST:CreateNewTestpaper") beego.Router("/api/qbank/testpaper", &controllers.ApiController{}, "PUT:UpdateTestpaper") + beego.Router("/api/qbank/testpaper", &controllers.ApiController{}, "GET:GetTempTestPaperDetail") beego.Router("/api/qbank/testpaper/temp", &controllers.ApiController{}, "DELETE:DeleteTempTestpaper") beego.Router("/api/qbank/testpaper/comment", &controllers.ApiController{}, "POST:AddTestpaperComment") beego.Router("/api/qbank/testpaper/trace", &controllers.ApiController{}, "GET:TraceTestpaperVersion")