新功能开发

This commit is contained in:
Soohyeonl 2022-10-13 13:02:01 +08:00
parent 0aafb73ab0
commit 2691de0a42
20 changed files with 779 additions and 100 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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设置时间点

View File

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

View File

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

View File

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

6
go.mod
View File

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

42
go.sum
View File

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

View File

@ -139,4 +139,9 @@ func (a *Adapter) createTable() {
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(TpAssignment))
if err != nil {
panic(err)
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

68
object/tpassignment.go Normal file
View File

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

View File

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