forked from Open-CT/openct-tasks
280 lines
7.1 KiB
Go
280 lines
7.1 KiB
Go
package object
|
|
|
|
import (
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/open-ct/openitem/util"
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
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"`
|
|
Description string `json:"description"`
|
|
Requirement string `json:"requirement"`
|
|
Status int `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
|
|
|
|
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"`
|
|
}
|
|
|
|
type SetStepTimePointRequest struct {
|
|
StepId string `json:"step_id"`
|
|
PointIndex int `json:"point_index"`
|
|
// index < 0 || index >= len -> create a new time point
|
|
Info TimePoint `json:"info"`
|
|
}
|
|
|
|
type TimePoint struct {
|
|
Title string `json:"title"`
|
|
StartTime time.Time `json:"start_time"`
|
|
EndTime time.Time `json:"end_time"`
|
|
Notice string `json:"notice"`
|
|
Comment string `json:"comment"`
|
|
}
|
|
|
|
type DeleteStepTimePointRequest struct {
|
|
StepId string `json:"step_id"`
|
|
PointIndex int `json:"point_index"`
|
|
}
|
|
|
|
type StepDataStatistic struct {
|
|
Total float64 `json:"total"`
|
|
PassRate float64 `json:"pass_rate"`
|
|
Pass float64 `json:"pass"`
|
|
Returned float64 `json:"returned"`
|
|
ToUpload float64 `json:"to_upload"`
|
|
ToAudit float64 `json:"to_audit"`
|
|
ToCorrect float64 `json:"to_correct"`
|
|
}
|
|
|
|
func AddStep(step *Step) error {
|
|
_, err := adapter.engine.Insert(step)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func CreateOneStep(req *Step) (string, error) {
|
|
newStep := Step{
|
|
Uuid: util.GenUuidV4(),
|
|
Name: req.Name,
|
|
ProjectId: req.ProjectId,
|
|
Index: req.Index,
|
|
Description: req.Description,
|
|
Requirement: req.Requirement,
|
|
Deadline: req.Deadline,
|
|
Status: 0,
|
|
Creator: req.Creator,
|
|
}
|
|
|
|
var newTimeTable []ProjectTimePoint
|
|
for _, timePoint := range req.Timetable {
|
|
point := ProjectTimePoint{
|
|
Title: timePoint.Title,
|
|
StartTime: timePoint.StartTime,
|
|
EndTime: timePoint.EndTime,
|
|
Notice: timePoint.Notice,
|
|
Comment: timePoint.Comment,
|
|
}
|
|
newTimeTable = append(newTimeTable, point)
|
|
}
|
|
newStep.Timetable = newTimeTable
|
|
|
|
err := AddStep(&newStep)
|
|
if err != nil {
|
|
log.Printf("[File upload (create new step failed)] %s\n", err.Error())
|
|
return "", err
|
|
}
|
|
|
|
insertedStepId := newStep.Uuid
|
|
|
|
log.Printf("[Insert] %s\n", insertedStepId)
|
|
return insertedStepId, nil
|
|
}
|
|
|
|
func GetStepInfo(sid string) (*Step, error) {
|
|
var step Step
|
|
|
|
_, err := adapter.engine.ID(sid).Get(&step)
|
|
if err != nil {
|
|
log.Printf("err: %s\n", err.Error())
|
|
return nil, err
|
|
}
|
|
return &step, nil
|
|
}
|
|
|
|
func GetAllStepsInProject(pid string) (*[]Step, error) {
|
|
var steps []Step
|
|
|
|
err := adapter.engine.Where(builder.Eq{"project_id": pid}).Find(&steps)
|
|
if err != nil {
|
|
log.Printf("err: %s\n", err.Error())
|
|
return nil, err
|
|
}
|
|
return &steps, nil
|
|
}
|
|
|
|
func UploadStepAttachments(req *AddStepAttachment) error {
|
|
var updateStep Step
|
|
|
|
updateStep.Attachments = req.FilesIds
|
|
|
|
_, err := adapter.engine.ID(req.StepId).Cols("attachments").Update(&updateStep)
|
|
if err != nil {
|
|
log.Printf("add attachments for step: %s\n", err.Error())
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func UpdateStepInfo(req *Step) error {
|
|
var oldStep Step
|
|
|
|
_, err := adapter.engine.ID(req.Uuid).Get(&oldStep)
|
|
if err != nil {
|
|
log.Printf("update step information: %s\n", err.Error())
|
|
return err
|
|
}
|
|
|
|
_, err = adapter.engine.ID(oldStep.Uuid).Update(req)
|
|
if err != nil {
|
|
log.Printf("update step information: %s\n", err.Error())
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func SetStepStatus(req *Step) error {
|
|
_, err := adapter.engine.ID(req.Uuid).Cols("status").Update(req)
|
|
if err != nil {
|
|
log.Printf("change step status: %s\n", err.Error())
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func SetStepTimePoint(req *SetStepTimePointRequest) (*[]ProjectTimePoint, error) {
|
|
// get step data:
|
|
var step Step
|
|
|
|
_, err := adapter.engine.ID(req.StepId).Get(&step)
|
|
if err != nil {
|
|
log.Printf("address the step error: %s\n", err.Error())
|
|
return nil, err
|
|
}
|
|
newTimeTable := step.Timetable
|
|
newTimePoint := ProjectTimePoint{
|
|
Title: req.Info.Title,
|
|
StartTime: req.Info.StartTime,
|
|
EndTime: req.Info.EndTime,
|
|
Notice: req.Info.Notice,
|
|
Comment: req.Info.Comment,
|
|
}
|
|
if req.PointIndex < 0 || req.PointIndex >= len(step.Timetable) {
|
|
newTimeTable = append(newTimeTable, newTimePoint)
|
|
|
|
_, err = adapter.engine.ID(req.StepId).Cols("timetable").Update(&Step{Timetable: newTimeTable})
|
|
if err != nil {
|
|
log.Printf("append step time point error: %s\n" + err.Error())
|
|
return nil, err
|
|
}
|
|
return &newTimeTable, nil
|
|
}
|
|
newTimeTable[req.PointIndex] = newTimePoint
|
|
|
|
_, err = adapter.engine.ID(req.StepId).Cols("timetable").Update(&Step{Timetable: newTimeTable})
|
|
if err != nil {
|
|
log.Printf("append step time point error: %s\n" + err.Error())
|
|
return nil, err
|
|
}
|
|
return &newTimeTable, nil
|
|
}
|
|
|
|
func DeleteStepTimePoint(req *DeleteStepTimePointRequest) error {
|
|
var step Step
|
|
|
|
_, err := adapter.engine.ID(req.StepId).Get(&step)
|
|
if err != nil {
|
|
log.Printf("address the step error: %s\n", err.Error())
|
|
return err
|
|
}
|
|
if req.PointIndex >= len(step.Timetable) || req.PointIndex < 0 {
|
|
return err
|
|
}
|
|
newTimeTable := step.Timetable
|
|
// delete array element
|
|
newTimeTable = append(newTimeTable[:req.PointIndex], newTimeTable[req.PointIndex+1:]...)
|
|
_, err = adapter.engine.ID(req.StepId).Cols("timetable").Update(&Step{Timetable: newTimeTable})
|
|
if err != nil {
|
|
log.Printf("delete time point error: %s\n", err.Error())
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func GetStepDataStatistic(stepId string) (*StepDataStatistic, error) {
|
|
var dataStatistic StepDataStatistic
|
|
var submits []Submit
|
|
|
|
err := adapter.engine.Where(builder.Eq{"step_id": stepId}).Find(&submits)
|
|
if err != nil {
|
|
log.Printf("find submits info err: " + err.Error())
|
|
return nil, err
|
|
}
|
|
dataStatistic.Total = float64(len(submits))
|
|
for _, submit := range submits {
|
|
contentCount := len(submit.Contents)
|
|
if contentCount == 0 {
|
|
dataStatistic.ToUpload += 1
|
|
continue
|
|
}
|
|
lastContentId := submit.Contents[contentCount-1].Uuid
|
|
var lastAudit Audit
|
|
_, err := adapter.engine.Where(builder.Eq{"submit_content": lastContentId}).Get(&lastAudit)
|
|
if err != nil {
|
|
dataStatistic.ToAudit += 1
|
|
continue
|
|
}
|
|
if lastAudit.Result == "not pass" {
|
|
dataStatistic.Returned += 1
|
|
}
|
|
if lastAudit.Result == "pass" {
|
|
dataStatistic.Pass += 1
|
|
}
|
|
if lastAudit.Result == "need correct" {
|
|
dataStatistic.ToCorrect += 1
|
|
}
|
|
}
|
|
if dataStatistic.Total == 0 {
|
|
dataStatistic.PassRate = 0
|
|
} else {
|
|
dataStatistic.PassRate = dataStatistic.Pass / dataStatistic.Total
|
|
}
|
|
return &dataStatistic, nil
|
|
}
|
|
|
|
func DeleteStep(stepId string) error {
|
|
_, err := adapter.engine.ID(stepId).Delete(&Step{})
|
|
if err != nil {
|
|
log.Printf("delete step error: %s\n" + err.Error())
|
|
return err
|
|
}
|
|
return nil
|
|
}
|