├── .gitignore
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── proj-review
├── .idea
│ ├── .gitignore
│ ├── modules.xml
│ ├── proj-review.iml
│ └── vcs.xml
├── auth
│ ├── access.go
│ └── jwt.go
├── conf
│ ├── app.conf
│ ├── file.conf
│ ├── log.conf
│ └── mongo.conf
├── constant
│ ├── code.go
│ ├── message.go
│ └── msg.go
├── controllers
│ ├── assignment.go
│ ├── default.go
│ ├── file.go
│ ├── project.go
│ └── user.go
├── database
│ └── mongo.go
├── go.mod
├── go.sum
├── log
│ └── log.go
├── main.go
├── models
│ ├── assignment.go
│ ├── file.go
│ ├── project.go
│ ├── reference.go
│ ├── step.go
│ ├── task.go
│ └── user.go
├── request
│ ├── assignment.go
│ ├── default.go
│ ├── file.go
│ ├── project.go
│ └── user.go
├── response
│ ├── assignment.go
│ ├── default.go
│ ├── file.go
│ ├── project.go
│ └── user.go
├── routers
│ ├── access.go
│ ├── auth.go
│ ├── default.go
│ ├── file.go
│ ├── project.go
│ └── user.go
├── static
│ └── js
│ │ └── reload.min.js
├── tests
│ ├── api-test.http
│ ├── default_test.go
│ ├── file-api-test.http
│ ├── proj-api-test.http
│ └── user-api-test.http
├── utils
│ ├── gendoc.go
│ ├── hash.go
│ ├── mkdir.go
│ └── uuid.go
└── views
│ ├── api.html
│ ├── api.md
│ └── index.tpl
├── review
├── .idea
│ ├── httpRequests
│ │ ├── 2021-08-19T170925.200.json
│ │ ├── 2021-08-19T170954.200.json
│ │ ├── 2021-08-19T171040.200.json
│ │ ├── 2021-08-19T171401.200.json
│ │ ├── 2021-08-19T171454.200.json
│ │ ├── 2021-08-19T171716.200.json
│ │ ├── 2021-08-19T171810.404.html
│ │ ├── 2021-08-19T171820.400.json
│ │ ├── 2021-08-19T171855.200.json
│ │ ├── 2021-08-19T171944.200.json
│ │ ├── 2021-08-19T171957.200.json
│ │ ├── 2021-08-19T172053.200.json
│ │ ├── 2021-08-19T172234.200.json
│ │ ├── 2021-08-19T172324.200.json
│ │ ├── 2021-08-19T172352.200.json
│ │ ├── 2021-08-19T172607.200.html
│ │ ├── 2021-08-19T172629.200.html
│ │ ├── 2021-08-19T172636.200.html
│ │ ├── 2021-08-19T172647.200.json
│ │ ├── 2021-08-19T172709.200.json
│ │ ├── 2021-08-19T172827.200.json
│ │ ├── 2021-08-19T173234.200.json
│ │ ├── 2021-08-19T173351.200.json
│ │ ├── 2021-08-19T173453.200.json
│ │ ├── 2021-08-19T173531.200.json
│ │ ├── 2021-08-19T173650.200.json
│ │ ├── 2021-08-19T173745.200.json
│ │ ├── 2021-08-20T173424.200.json
│ │ ├── 2021-08-20T173441.200.json
│ │ ├── 2021-08-20T173509.200.json
│ │ ├── 2021-08-20T173526.200.json
│ │ ├── 2021-08-20T173545.200.json
│ │ ├── 2021-08-20T173556.200.json
│ │ ├── 2021-08-20T173717.200.json
│ │ ├── 2021-08-20T185844.200.json
│ │ ├── 2021-08-20T185859.200.json
│ │ ├── 2021-08-23T111250.200.json
│ │ ├── 2021-08-24T085435.200.json
│ │ ├── 2021-08-24T085452.200.json
│ │ ├── 2021-08-24T085502.200.json
│ │ ├── 2021-08-24T085511.200.json
│ │ ├── 2021-08-24T085520.200.json
│ │ ├── 2021-08-24T085529.200.json
│ │ ├── 2021-08-24T085550.200.json
│ │ ├── 2021-08-24T085559.200.json
│ │ ├── 2021-08-24T085607.200.json
│ │ ├── 2021-08-24T085622.200.json
│ │ ├── 2021-08-24T092901.200.json
│ │ ├── 2021-08-24T175026.200.json
│ │ ├── http-client.cookies
│ │ └── http-requests-log.http
│ ├── modules.xml
│ ├── review.iml
│ ├── vcs.xml
│ └── workspace.xml
├── access
│ ├── check.go
│ ├── cros.go
│ ├── filter.go
│ └── jwt.go
├── conf
│ ├── app.conf
│ ├── file.conf
│ ├── log.conf
│ ├── mail.conf
│ └── mongo.conf
├── controllers
│ ├── assignment.go
│ ├── audit.go
│ ├── default.go
│ ├── file.go
│ ├── noticer.go
│ ├── project.go
│ ├── query.go
│ ├── step.go
│ ├── submit.go
│ └── user.go
├── database
│ └── mongo.go
├── go.mod
├── go.sum
├── logger
│ └── log.go
├── main.go
├── models
│ ├── assignment.go
│ ├── audit.go
│ ├── file.go
│ ├── project.go
│ ├── step.go
│ ├── submit.go
│ ├── user.go
│ └── versionItem.go
├── noticer
│ ├── mail.go
│ └── message.go
├── query
│ └── query.go
├── request
│ ├── file.go
│ ├── project.go
│ └── user.go
├── response
│ ├── code.go
│ ├── default.go
│ └── listquery.go
├── routers
│ ├── commentsRouter_controllers.go
│ └── router.go
├── swagger.zip
├── swagger
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── index.html
│ ├── oauth2-redirect.html
│ ├── swagger-ui-bundle.js
│ ├── swagger-ui-bundle.js.map
│ ├── swagger-ui-standalone-preset.js
│ ├── swagger-ui-standalone-preset.js.map
│ ├── swagger-ui.css
│ ├── swagger-ui.css.map
│ ├── swagger-ui.js
│ ├── swagger-ui.js.map
│ ├── swagger.json
│ └── swagger.yml
├── tests
│ ├── default_test.go
│ ├── file-test.http
│ └── user-test.http
└── utils
│ ├── crypto.go
│ ├── json.go
│ ├── mkdir.go
│ └── uuid.go
├── warehouse
├── .idea
│ ├── .gitignore
│ ├── modules.xml
│ ├── vcs.xml
│ └── warehouse.iml
├── conf
│ ├── app.conf
│ ├── log.conf
│ └── mongo.conf
├── controllers
│ ├── default.go
│ ├── query.go
│ ├── question.go
│ ├── testpaper.go
│ └── user.go
├── database
│ └── mongo.go
├── go.mod
├── go.sum
├── logger
│ └── logger.go
├── main.go
├── models
│ ├── actions.go
│ ├── query.go
│ ├── question.go
│ ├── request.go
│ ├── testpaper.go
│ └── user.go
├── routers
│ ├── commentsRouter_controllers.go
│ └── router.go
├── swagger.zip
├── swagger
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── index.html
│ ├── oauth2-redirect.html
│ ├── swagger-ui-bundle.js
│ ├── swagger-ui-bundle.js.map
│ ├── swagger-ui-standalone-preset.js
│ ├── swagger-ui-standalone-preset.js.map
│ ├── swagger-ui.css
│ ├── swagger-ui.css.map
│ ├── swagger-ui.js
│ ├── swagger-ui.js.map
│ ├── swagger.json
│ └── swagger.yml
├── tests
│ └── default_test.go
└── utils
│ └── uuid.go
└── web
├── .gitignore
├── README.md
├── build
├── asset-manifest.json
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── robots.txt
└── static
│ ├── css
│ ├── 2.e4902758.chunk.css
│ ├── 2.e4902758.chunk.css.map
│ ├── main.28dd778d.chunk.css
│ └── main.28dd778d.chunk.css.map
│ ├── js
│ ├── 2.75a36cd2.chunk.js
│ ├── 2.75a36cd2.chunk.js.LICENSE.txt
│ ├── 2.75a36cd2.chunk.js.map
│ ├── main.f8299ca7.chunk.js
│ ├── main.f8299ca7.chunk.js.map
│ ├── runtime-main.3b3646ce.js
│ └── runtime-main.3b3646ce.js.map
│ └── media
│ ├── Rockets.bcd94bd9.png
│ ├── login_background.d1cc80fb.png
│ └── proposition-paper-icon.2d177c41.png
├── config-overrides.js
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App.jsx
├── App.less
├── asset
│ └── images
│ │ ├── Cloud.png
│ │ ├── Crying_face.png
│ │ ├── Flu_expression.png
│ │ ├── Rockets.png
│ │ ├── Unhapply.png
│ │ ├── login_background.png
│ │ ├── openct_logo_1082x328.png
│ │ └── proposition-paper-icon.png
├── components
│ ├── BuildTeam
│ │ ├── index.jsx
│ │ └── index.less
│ ├── CalendarButton
│ │ ├── index.jsx
│ │ └── index.less
│ ├── ChangeTags
│ │ ├── index.jsx
│ │ └── index.less
│ ├── ChoiceQuestionEditer
│ │ ├── index.jsx
│ │ └── index.less
│ ├── CompletionStatus
│ │ ├── index.jsx
│ │ └── index.less
│ ├── DataTable
│ │ ├── index.jsx
│ │ └── index.less
│ ├── DifficultyBox
│ │ ├── index.jsx
│ │ └── index.less
│ ├── HistoryQuestion
│ │ ├── index.jsx
│ │ └── index.less
│ ├── MaterialWarehouse
│ │ ├── index.jsx
│ │ └── index.less
│ ├── ModifyRecordModal
│ │ ├── index.jsx
│ │ └── index.less
│ ├── ModulaCard
│ │ ├── index.jsx
│ │ └── index.less
│ ├── Step
│ │ ├── index.jsx
│ │ └── index.less
│ ├── TaskRequirements
│ │ ├── index.jsx
│ │ └── index.less
│ ├── UpLoadModal
│ │ ├── index.jsx
│ │ └── index.less
│ └── UpLoadQuestionModal
│ │ ├── index.jsx
│ │ └── index.less
├── conf
│ └── index.js
├── index.js
├── index.less
├── logo.svg
├── setupProxy.js
├── store
│ ├── action.js
│ ├── constants.js
│ ├── index.js
│ └── reducer.js
├── utils
│ ├── cookies.js
│ ├── request.js
│ └── storage.js
└── views
│ ├── Home
│ ├── index.jsx
│ └── index.less
│ ├── Login
│ ├── index.jsx
│ └── index.less
│ ├── PendingTasks
│ ├── index.jsx
│ └── index.less
│ ├── ProjectManagement
│ ├── index.jsx
│ └── index.less
│ ├── PropositionPaper
│ ├── index.jsx
│ └── views
│ │ ├── CreatePaper
│ │ ├── index.jsx
│ │ └── index.less
│ │ ├── Home
│ │ ├── home.jsx
│ │ └── index.less
│ │ └── UploadQuestions
│ │ ├── index.jsx
│ │ └── index.less
│ └── errors
│ ├── 402.jsx
│ ├── 404.jsx
│ └── index.less
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
17 | # Goalng mod packs:
18 | vendor
19 |
20 | # ignore the log file
21 | *.log
22 |
23 | # compile temp file
24 | *.tmp
25 |
26 | # temp upload file & exec file
27 | proj-review/static/files/*
28 | proj-review/proj-review
29 | review/static/files/*
30 |
31 |
32 | /node_modules
33 | package-lock.json
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenItem
2 | Online proposition and question bank system.
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "cz-conventional-changelog": "^3.3.0"
4 | },
5 | "config": {
6 | "commitizen": {
7 | "path": "./node_modules/cz-conventional-changelog"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/proj-review/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/proj-review/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/proj-review/.idea/proj-review.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/proj-review/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/proj-review/auth/access.go:
--------------------------------------------------------------------------------
1 | package auth
2 |
--------------------------------------------------------------------------------
/proj-review/conf/app.conf:
--------------------------------------------------------------------------------
1 | ; Basic config
2 | appname = PQBS_review_module
3 | httpaddr = localhost
4 | httpport = 9001
5 | runmode = dev
6 | copyrequestbody = true
7 |
8 | # iclude "mysql.conf"
9 | include "mongo.conf"
10 | include "file.conf"
11 | include "log.conf"
--------------------------------------------------------------------------------
/proj-review/conf/file.conf:
--------------------------------------------------------------------------------
1 | ; 用于配置文件上传 & 下载
2 | filerootpath = "static/files/"
3 | maxmemory = 1<<22
4 |
--------------------------------------------------------------------------------
/proj-review/conf/log.conf:
--------------------------------------------------------------------------------
1 | ; review module log
2 |
3 | logpath = log/
4 | logfile = pqbs-review.log
5 | loglevel = full
--------------------------------------------------------------------------------
/proj-review/conf/mongo.conf:
--------------------------------------------------------------------------------
1 | ; mongo database config
2 | mongoaddr = localhost
3 | mongoport = 27017
4 | mongodb = openct_pqbs
5 | mongouser = openct
6 | mongopwd = 123456
7 |
8 | ; collections name define
9 | [mongo-collections]
10 | ; review
11 | users = "users"
12 | assignments = "assignments"
13 | projects = "projects"
14 | steps = "steps"
15 | tasks = "tasks"
16 | fileRecords = "file_records"
17 | references = "references"
18 |
19 | ; warehouse
20 | tempQuestions = "temp_questions"
21 | finalQuestions = "final_questions"
22 | tempTestPapers = "temp_test_papers"
23 | finalTestPapers = "final_test_papers"
--------------------------------------------------------------------------------
/proj-review/constant/code.go:
--------------------------------------------------------------------------------
1 | package constant
2 |
3 | var (
4 | SUCCESS = 1000
5 | FAIL = 2000
6 | )
7 |
--------------------------------------------------------------------------------
/proj-review/constant/msg.go:
--------------------------------------------------------------------------------
1 | package constant
2 |
3 | var Message = make(map[int]string)
4 |
5 | func init() {
6 | message := make(map[int]string)
7 | message[SUCCESS] = "ok"
8 | message[FAIL] = "发生未知错误"
9 |
10 | Message = message
11 | }
12 |
--------------------------------------------------------------------------------
/proj-review/controllers/assignment.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import beego "github.com/beego/beego/v2/server/web"
4 |
5 | type AssignmentController struct {
6 | beego.Controller
7 | }
8 |
--------------------------------------------------------------------------------
/proj-review/controllers/default.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | beego "github.com/beego/beego/v2/server/web"
7 | "proj-review/auth"
8 | "proj-review/log"
9 | )
10 |
11 | // Test controller, no used.
12 | type MainController struct {
13 | beego.Controller
14 | }
15 |
16 | func (c *MainController) Get() {
17 | c.Data["Website"] = "beego.me"
18 | c.Data["Email"] = "astaxie@gmail.com"
19 | c.TplName = "index.tpl"
20 | }
21 |
22 | func (c *MainController) List() {
23 | c.TplName = "api.html"
24 | }
25 |
26 | func (c *MainController) Demo() {
27 | c.Ctx.Output.Download("tests/api-test.http", "api.http")
28 | }
29 |
30 | // universal functions in controller
31 |
32 | // unmarshalBody parse the response body (json type)
33 | func unmarshalBody(body []byte, obj interface{}) error {
34 | // marshal json body
35 | if err := json.Unmarshal(body, obj); err != nil {
36 | log.Logger.Warn("[JSON] " + err.Error())
37 | return err
38 | }
39 | return nil
40 | }
41 |
42 | // parseUserToken get user id from token string
43 | func parseUserToken(token string) (string, error) {
44 | //
45 | fmt.Println("recv token: ", token)
46 | //
47 | tokenData, err := auth.ParseToken(token)
48 | if err != nil {
49 | return "", err
50 | }
51 | //
52 | fmt.Println("recv user: ", tokenData.UserID)
53 | fmt.Println("recv token time from ", tokenData.IssuedAt, " to ", tokenData.ExpiresAt)
54 | //
55 | return tokenData.UserID, nil
56 | }
57 |
58 | func checkHttpBodyEmpty(body []byte) bool {
59 | if len(body) == 0 {
60 | return false
61 | }
62 | return true
63 | }
64 |
--------------------------------------------------------------------------------
/proj-review/go.mod:
--------------------------------------------------------------------------------
1 | module proj-review
2 |
3 | go 1.16
4 |
5 | require github.com/beego/beego/v2 v2.0.1
6 |
7 | require (
8 | github.com/dgrijalva/jwt-go v3.2.0+incompatible
9 | github.com/google/uuid v1.3.0
10 | github.com/microcosm-cc/bluemonday v1.0.15
11 | github.com/qiniu/qmgo v0.9.4
12 | github.com/russross/blackfriday v1.6.0
13 | github.com/smartystreets/goconvey v1.6.4
14 | go.mongodb.org/mongo-driver v1.7.1
15 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
16 | )
17 |
--------------------------------------------------------------------------------
/proj-review/log/log.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "fmt"
5 | "github.com/beego/beego/v2/core/logs"
6 | beego "github.com/beego/beego/v2/server/web"
7 | )
8 |
9 | var Logger *logs.BeeLogger
10 |
11 | func init() {
12 | // 设置日志生成器
13 | log := logs.NewLogger()
14 | // 读取配置
15 | logPath, err := beego.AppConfig.String("logpath")
16 | if err != nil {
17 | fmt.Println("load log path config error.")
18 | }
19 | logFile, err := beego.AppConfig.String("logfile")
20 | if err != nil {
21 | fmt.Println("load log filename config error.")
22 | }
23 | // 配置日志输出 todo: more options need to be config by .conf
24 | logConfig := fmt.Sprintf(
25 | `{"filename":"%s","level":7,"daily":true,"maxdays":10,"color":true}`,
26 | logPath+logFile,
27 | )
28 | log.SetLogger(
29 | logs.AdapterFile,
30 | logConfig,
31 | )
32 | log.SetLogger(logs.AdapterConsole)
33 | log.EnableFuncCallDepth(true)
34 | log.SetLevel(logs.LevelDebug)
35 |
36 | Logger = log
37 | }
38 |
--------------------------------------------------------------------------------
/proj-review/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | beego "github.com/beego/beego/v2/server/web"
5 | _ "proj-review/database"
6 | _ "proj-review/routers"
7 | )
8 |
9 | func main() {
10 | beego.Run()
11 | }
12 |
--------------------------------------------------------------------------------
/proj-review/models/reference.go:
--------------------------------------------------------------------------------
1 | package models
2 |
--------------------------------------------------------------------------------
/proj-review/models/step.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "github.com/qiniu/qmgo/field"
5 | )
6 |
7 | type Step struct {
8 | field.DefaultField `bson:",inline"`
9 | Uuid string `json:"uuid" bson:"uuid"`
10 | Belong string `json:"belong" bson:"belong"`
11 | Name string `json:"name" bson:"name"`
12 | Status int `json:"status" bson:"status"`
13 | Tasks string `json:"tasks" bson:"tasks"`
14 | Description string `json:"description" bson:"description"`
15 | }
16 |
--------------------------------------------------------------------------------
/proj-review/models/task.go:
--------------------------------------------------------------------------------
1 | package models
2 |
--------------------------------------------------------------------------------
/proj-review/request/assignment.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | type MakeAssignment struct {
4 | UserId string `json:"user_id"`
5 | ProjectId string `json:"project_id"`
6 | Role int `json:"role"`
7 | Operator string `json:"operator"`
8 | }
9 |
10 | type ChangeAssignment struct {
11 | AssignmentId string `json:"assignment_id"`
12 | NewRole int `json:"new_role"`
13 | Operator string `json:"operator"`
14 | }
15 |
--------------------------------------------------------------------------------
/proj-review/request/default.go:
--------------------------------------------------------------------------------
1 | package request
2 |
--------------------------------------------------------------------------------
/proj-review/request/file.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | /*
4 | Define some request structures for file operations.
5 | */
6 |
7 | // UploadFile define the upload file request format
8 | type UploadFile struct {
9 | UserId string `json:"user_id"`
10 | FileName string `json:"file_name"`
11 | Type string `json:"type"`
12 | Description string `json:"description"`
13 | Tags []string `json:"tags"`
14 | }
15 |
16 | // SearchFile define the search request format, todo
17 | type SearchFile struct {
18 | FileName string `json:"file_name"`
19 | Type string `json:"type"`
20 | Tags []string `json:"tags"`
21 | }
22 |
23 | // GetFileInfo: just using http-get with url params
24 | // DownloadFile: just using http-get with url params
25 |
--------------------------------------------------------------------------------
/proj-review/request/project.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | type CreateProject struct {
4 | Name string `json:"name"`
5 | Description string `json:"description"`
6 | Requirement string `json:"requirement"`
7 | Target string `json:"target"`
8 | GradeRange []string `json:"grade_range"`
9 | Subjects []string `json:"subjects"`
10 | Summary string `json:"summary"`
11 | Creator string `json:"creator"`
12 | }
13 |
14 | type SearchProject struct {
15 | Name string `json:"name"`
16 | GradeRange []string `json:"grade_range"`
17 | Subjects []string `json:"subjects"`
18 | }
19 |
20 | type GetUserProjects struct {
21 | UserId string `json:"user_id"`
22 | }
23 |
--------------------------------------------------------------------------------
/proj-review/request/user.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | // CheckDuplicate
4 | type CheckDuplicate struct {
5 | Phone string `json:"phone"`
6 | Email string `json:"email"`
7 | }
8 |
9 | //UserLogin define the user login struct
10 | type UserLogin struct {
11 | Phone string `json:"phone"`
12 | Email string `json:"email"`
13 | Password string `json:"password"`
14 | }
15 |
16 | // UserRegister defines create user request format
17 | type UserRegister struct {
18 | Name string `json:"name"`
19 | Password string `json:"password"`
20 | Email string `json:"email"`
21 | Phone string `json:"phone"`
22 | Gender bool `json:"gender"`
23 | Degree string `json:"degree"`
24 | Position string `json:"position"`
25 | Employer string `json:"employer"`
26 | Major string `json:"major"`
27 | }
28 |
29 | // UserUpdatePassword define the update password req format 请求更新密码
30 | type UserUpdatePassword struct {
31 | ID string `json:"id"`
32 | OldPassword string `json:"old_password"`
33 | NewPassword string `json:"new_password"`
34 | }
35 |
36 | // UserUpdateInfo define the user info updating request format
37 | type UserUpdateInfo struct {
38 | ID string `json:"id"`
39 | Name string `json:"name"`
40 | Email string `json:"email"`
41 | Phone string `json:"phone"`
42 | Gender bool `json:"gender"`
43 | Degree string `json:"degree"`
44 | Position string `json:"position"`
45 | Employer string `json:"employer"`
46 | Major string `json:"major"`
47 | }
48 |
49 | // GetUserInfo: just using http-get with url params
50 | // UserLogout: just using http-get with url params
51 |
52 | // UserSearch define search users struct
53 | type UserSearch struct {
54 | Phone string `json:"phone"`
55 | Email string `json:"email"`
56 | Name string `json:"name"`
57 | Degree string `json:"degree"`
58 | Position string `json:"position"`
59 | Employer string `json:"employer"`
60 | Major string `json:"major"`
61 | }
62 |
--------------------------------------------------------------------------------
/proj-review/response/assignment.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | import "time"
4 |
5 | type AssignmentDefault struct {
6 | AssignmentId string `json:"assignment_id"`
7 | Description string `json:"description"`
8 | }
9 |
10 | type GetAssignments struct {
11 | Count int `json:"count"`
12 | Assignments []AssignmentItem `json:"assignments"`
13 | Description string `json:"description"`
14 | }
15 |
16 | type AssignmentItem struct {
17 | Uuid string `json:"uuid"`
18 | UserId string `json:"user_id"`
19 | UserName string `json:"user_name"`
20 | ProjectId string `json:"project_id"`
21 | ProjectName string `json:"project_name"`
22 | Role int `json:"role"`
23 | IsConfirmed bool `json:"is_confirmed"`
24 | Status int `json:"status"`
25 | CreatedAt time.Time `json:"created_at"`
26 | }
27 |
--------------------------------------------------------------------------------
/proj-review/response/default.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | // Default define the default response format
4 | type Default struct {
5 | Code int `json:"code"`
6 | Message string `json:"message"`
7 | Data interface{} `json:"data"`
8 | }
9 |
10 | // GenResponse function to generate default response struct.
11 | func GenResponse(code int, msg string, data interface{}) Default {
12 | return Default{
13 | Code: code,
14 | Message: msg,
15 | Data: data,
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/proj-review/response/file.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | // FileDefault
4 | type FileDefault struct {
5 | FileID string `json:"file_id"`
6 | FileName string `json:"file_name"`
7 | FileType string `json:"file_type"`
8 | FilePath string `json:"file_path"`
9 | Description string `json:"description"`
10 | }
11 |
12 | // FindFile
13 | type FindFile struct {
14 | FileID string `json:"file_id"`
15 | FileName string `json:"file_name"`
16 | FileType string `json:"file_type"`
17 | FileTags []string `json:"file_tags"`
18 | FilePath string `json:"file_path"`
19 | FileDescription string `json:"file_description"`
20 | FileOwner string `json:"file_owner"`
21 | Description string `json:"description"`
22 | }
23 |
24 | // SearchFiles
25 | type SearchFiles struct {
26 | SearchCount int `json:"search_count"`
27 | Results []FileItem `json:"results"`
28 | Description string `json:"description"`
29 | }
30 |
31 | type FileItem struct {
32 | FileID string `json:"file_id"`
33 | FileName string `json:"file_name"`
34 | FileType string `json:"file_type"`
35 | FileTags []string `json:"file_tags"`
36 | FilePath string `json:"file_path"`
37 | FileOwner string `json:"file_owner"`
38 | FileDescription string `json:"file_description"`
39 | }
40 |
--------------------------------------------------------------------------------
/proj-review/response/project.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | import "time"
4 |
5 | type ProjectDefault struct {
6 | ProjectID string `json:"project_id"`
7 | ProjectName string `json:"project_name"`
8 | Description string `json:"description"`
9 | }
10 |
11 | type ProjectInfo struct {
12 | ProjectId string `json:"project_id"`
13 | ProjectName string `json:"project_name"`
14 | ProjectDescription string `json:"project_description"`
15 | Requirement string `json:"requirement"`
16 | Target string `json:"target"`
17 | GradeRange []string `json:"grade_range"`
18 | Subjects []string `json:"subjects"`
19 | Summary string `json:"summary"`
20 | Creator string `json:"creator"`
21 | Status int `json:"status"`
22 | Group interface{} `json:"group"`
23 | Timetable interface{} `json:"timetable"`
24 | Steps interface{} `json:"steps"`
25 | Description string `json:"description"`
26 | CreateAt time.Time `json:"create_at"`
27 | UpdatedAt time.Time `json:"updated_at"`
28 | }
29 |
--------------------------------------------------------------------------------
/proj-review/response/user.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | // UserDefault
4 | /*
5 | This response used in:
6 | */
7 | type UserDefault struct {
8 | UserID string `json:"user_id"`
9 | Name string `json:"name"`
10 | Description string `json:"description"`
11 | }
12 |
13 | // UserInfo
14 | type UserInfo struct {
15 | UserID string `json:"user_id"`
16 | Name string `json:"name"`
17 | Email string `json:"email"`
18 | Phone string `json:"phone"`
19 | Gender bool `json:"gender"`
20 | Degree string `json:"degree"`
21 | Position string `json:"position"`
22 | Employer string `json:"employer"`
23 | Major string `json:"major"`
24 | Description string `json:"description"`
25 | }
26 |
27 | // UserList
28 | type UserList struct {
29 | UserList []UserInfo `json:"user_list"`
30 | Count int `json:"count"`
31 | Description string `json:"description"`
32 | }
33 |
34 | // LoginResponse defines login result response
35 | type LoginResponse struct {
36 | UserID string `json:"user_id"`
37 | UserInfo UserInfo `json:"user_info"`
38 | Token string `json:"token"`
39 | Description string `json:"description"`
40 | }
41 |
42 | // CheckDuplicate
43 | type CheckDuplicate struct {
44 | Result bool `json:"result"`
45 | Description string `json:"description"`
46 | }
47 |
--------------------------------------------------------------------------------
/proj-review/routers/access.go:
--------------------------------------------------------------------------------
1 | package routers
2 |
--------------------------------------------------------------------------------
/proj-review/routers/auth.go:
--------------------------------------------------------------------------------
1 | package routers
2 |
3 | /*
4 | provide some apis (routers) for auth module
5 | */
6 |
--------------------------------------------------------------------------------
/proj-review/routers/default.go:
--------------------------------------------------------------------------------
1 | package routers
2 |
3 | import (
4 | beego "github.com/beego/beego/v2/server/web"
5 | "proj-review/controllers"
6 | )
7 |
8 | func init() {
9 | beego.Router("/", &controllers.MainController{})
10 | // 开发测试使用
11 | beego.Router("/api/list", &controllers.MainController{}, "get:List")
12 | beego.Router("/api/demo", &controllers.MainController{}, "get:Demo")
13 | }
14 |
--------------------------------------------------------------------------------
/proj-review/routers/file.go:
--------------------------------------------------------------------------------
1 | package routers
2 |
3 | import (
4 | beego "github.com/beego/beego/v2/server/web"
5 | "proj-review/controllers"
6 | )
7 |
8 | func init() {
9 | beego.Router("/file/getInfo", &controllers.FileController{}, "get:GetFileInfo")
10 | beego.Router("/file/download", &controllers.FileController{}, "get:DownloadFile")
11 | beego.Router("/file/upload", &controllers.FileController{}, "post:UploadFile")
12 | beego.Router("/file/search", &controllers.FileController{}, "post:SearchFile")
13 | beego.Router("/file/delete", &controllers.FileController{}, "get:DeleteFile")
14 | }
15 |
--------------------------------------------------------------------------------
/proj-review/routers/project.go:
--------------------------------------------------------------------------------
1 | package routers
2 |
3 | import (
4 | beego "github.com/beego/beego/v2/server/web"
5 | "proj-review/controllers"
6 | )
7 |
8 | func init() {
9 | // projects
10 | beego.Router("/proj/createEmpty", &controllers.ProjectController{}, "post:CreateNewProject")
11 | beego.Router("/proj/getInfo", &controllers.ProjectController{}, "get:GetProjectInfo")
12 | // assignments
13 | beego.Router("/proj/userAssign", &controllers.ProjectController{}, "get:GetUserAssignments")
14 | beego.Router("/proj/projectAssign", &controllers.ProjectController{}, "get:GetProjectAssignments")
15 | beego.Router("/proj/makeAssign", &controllers.ProjectController{}, "post:MakeNewAssignment")
16 | beego.Router("/proj/changeAssign", &controllers.ProjectController{}, "post:ChangeAssignment")
17 | beego.Router("/proj/removeAssign", &controllers.ProjectController{}, "get:RemoveAssignment")
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/proj-review/routers/user.go:
--------------------------------------------------------------------------------
1 | package routers
2 |
3 | import (
4 | beego "github.com/beego/beego/v2/server/web"
5 | "proj-review/controllers"
6 | )
7 |
8 | func init() {
9 | // 用户登录 & 注册路由
10 | beego.Router("/user/checkInfo", &controllers.UserController{}, "post:CheckDuplicate")
11 | beego.Router("/user/register", &controllers.UserController{}, "post:UserRegister")
12 | beego.Router("/user/login", &controllers.UserController{}, "post:UserLogin")
13 | // todo: 用户退出登陆操作
14 | beego.Router("/user/logout", &controllers.UserController{}, "get:UserLogout")
15 | beego.Router("/user/delete", &controllers.UserController{}, "get:DeleteUser")
16 | // todp: search user
17 | beego.Router("/user/search", &controllers.UserController{}, "post:SearchUser")
18 | beego.Router("/user/getInfo", &controllers.UserController{}, "get:GetUserInfo")
19 | beego.Router("/user/updateInfo", &controllers.UserController{}, "post:UpdateUserInfo")
20 | beego.Router("/user/updatePwd", &controllers.UserController{}, "post:UpdateUserPassword")
21 | }
22 |
--------------------------------------------------------------------------------
/proj-review/static/js/reload.min.js:
--------------------------------------------------------------------------------
1 | function b(a){var c=new WebSocket(a);c.onclose=function(){setTimeout(function(){b(a)},2E3)};c.onmessage=function(){location.reload()}}try{if(window.WebSocket)try{b("ws://localhost:12450/reload")}catch(a){console.error(a)}else console.log("Your browser does not support WebSockets.")}catch(a){console.error("Exception during connecting to Reload:",a)};
2 |
--------------------------------------------------------------------------------
/proj-review/tests/default_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "path/filepath"
7 | _ "proj-review/routers"
8 | "runtime"
9 | "testing"
10 |
11 | beego "github.com/beego/beego/v2/server/web"
12 | . "github.com/smartystreets/goconvey/convey"
13 | )
14 |
15 | func init() {
16 | _, file, _, _ := runtime.Caller(0)
17 | apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
18 | beego.TestBeegoInit(apppath)
19 | }
20 |
21 | // TestBeego is a sample to run an endpoint test
22 | func TestBeego(t *testing.T) {
23 | r, _ := http.NewRequest("GET", "/", nil)
24 | w := httptest.NewRecorder()
25 | beego.BeeApp.Handlers.ServeHTTP(w, r)
26 |
27 | beego.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String())
28 |
29 | Convey("Subject: Test Station Endpoint\n", t, func() {
30 | Convey("Status Code Should Be 200", func() {
31 | So(w.Code, ShouldEqual, 200)
32 | })
33 | Convey("The Result Should Not Be Empty", func() {
34 | So(w.Body.Len(), ShouldBeGreaterThan, 0)
35 | })
36 | })
37 | }
38 |
--------------------------------------------------------------------------------
/proj-review/tests/file-api-test.http:
--------------------------------------------------------------------------------
1 | POST http://localhost:9001/file/search
2 | Content-Type: application/json
3 |
4 | {
5 | "file_name": "雷达图.png",
6 | "type": ".png"
7 | }
8 |
9 | ###
10 | GET http://localhost:9001/file/delete?file_id=9094ce1c-e402-4e07-a363-a3383a471010
11 | Accept: application/json
12 |
13 |
14 | ###
15 | GET http://localhost:9001/file/getInfo?file_id=9094ce1c-e402-4e07-a363-a3383a471010
16 | Accept: application/json
17 |
18 | ###
19 | GET http://localhost:9001/file/download?file_id=9094ce1c-e402-4e07-a363-a3383a471010
20 | Accept: application/json
21 |
22 | ### xx
23 | POST http://localhost:9001/file/upload
24 | Content-Type: multipart/form-data; boundary=WebAppBoundary
25 |
26 | --WebAppBoundary
27 | Content-Disposition: form-data; name="field-name"; filename="file.txt"
28 |
29 | < ./relative/path/to/local_file.txt
30 | --WebAppBoundary--
--------------------------------------------------------------------------------
/proj-review/tests/proj-api-test.http:
--------------------------------------------------------------------------------
1 | POST http://localhost:9001/proj/changeAssign
2 | Content-Type: application/json
3 | Token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYzk5M2FhM2MtYWRlOS00ZDk5LWE1NmItNmE1YjQ3MmQ5ZGJhIiwiZXhwIjoxNjI5NzE2MDUxLCJpYXQiOjE2MjkxMTEyNTEsImlzcyI6InJvYm90LTFAcHFicy5jb20ifQ.D1jdCkOv56qn_BQaDym_Omg2LkHj7s6PjjTYpKstRS4
4 |
5 | {
6 | "assignment_id": "a33cbbc9-5497-48df-9d95-f3f25f270af9",
7 | "new_role": 1
8 | }
9 |
10 | ###
11 | POST http://localhost:9001/proj/makeAssign
12 | Content-Type: application/json
13 | Token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYzk5M2FhM2MtYWRlOS00ZDk5LWE1NmItNmE1YjQ3MmQ5ZGJhIiwiZXhwIjoxNjI5NzE2MDUxLCJpYXQiOjE2MjkxMTEyNTEsImlzcyI6InJvYm90LTFAcHFicy5jb20ifQ.D1jdCkOv56qn_BQaDym_Omg2LkHj7s6PjjTYpKstRS4
14 |
15 | {
16 | "user_id": "1c00da28-0c1c-42a2-bff2-b00ed5d8ac52",
17 | "project_id": "17dc1bf8-7b4d-42e8-8b53-4971aa65cf0d",
18 | "role": 1
19 | }
20 |
21 | ###
22 | GET http://localhost:9001/proj/removeAssign?assignment_id=b16d1aa9-8572-4152-871d-2a5b06c0e2f0
23 | Accept: application/json
24 |
25 | ###
26 |
27 | GET http://localhost:9001/proj/projectAssign?proj_id=12ef6101-e47f-41fe-814f-b13a922ece8d
28 | Accept: application/json
29 |
30 | ###
31 | GET http://localhost:9001/proj/userAssign?user_id=1c00da28-0c1c-42a2-bff2-b00ed5d8ac52
32 | Accept: application/json
33 |
34 | ###
35 |
36 | GET http://localhost:9001/proj/getInfo?proj_id=12ef6101-e47f-41fe-814f-b13a922ece8d
37 | Accept: application/json
38 |
39 | ###
40 | POST http://localhost:9001/proj/createEmpty
41 | Content-Type: application/json
42 | Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYzk5M2FhM2MtYWRlOS00ZDk5LWE1NmItNmE1YjQ3MmQ5ZGJhIiwiZXhwIjoxNjI5MzY0OTI0LCJpYXQiOjE2Mjg3NjAxMjQsImlzcyI6InJvYm90LTFAcHFicy5jb20ifQ.5ifVw1DyoXsxQL092qdMoShFMcvkC3qjM2ZBThiQi7s
43 |
44 | {
45 | "name": "test-project-3",
46 | "Description": "this is a no.3 test-project, which is an empty project.",
47 | "requirement": "nothing... just testing.",
48 | "target": "test create project api.",
49 | "grade_range": ["10", "12", "15"],
50 | "subjects": ["go", "html"],
51 | "summary": "speed up..."
52 | }
53 |
54 | ###
55 |
--------------------------------------------------------------------------------
/proj-review/tests/user-api-test.http:
--------------------------------------------------------------------------------
1 | POST http://localhost:9001/user/checkInfo
2 | Content-Type: application/json
3 |
4 | {
5 | "phone": "13000000011",
6 | "email": "robot-5@pqbs.com"
7 | }
8 |
9 | ###
10 | POST http://localhost:9001/user/updateInfo
11 | Content-Type: application/json
12 |
13 | {
14 | "id": "c993aa3c-ade9-4d99-a56b-6a5b472d9dba",
15 | "name": "robot-01",
16 | "email": "robot-1@pqbs.com",
17 | "phone": "13000000001",
18 | "gender": false,
19 | "degree": "robot",
20 | "position": "robot-man",
21 | "employer": "developer",
22 | "major": "test"
23 | }
24 |
25 | ###
26 | GET http://localhost:9001/user/delete?user_id=c2dbc93b-f1c0-43b8-b4fc-6ecea7f52591
27 | Accept: application/json
28 |
29 | ###
30 | GET http://localhost:9001/user/getInfo?user_id=c993aa3c-ade9-4d99-a56b-6a5b472d9dba
31 | Accept: application/json
32 |
33 | ###
34 | POST http://localhost:9001/user/updatePwd
35 | Content-Type: application/json
36 |
37 | {
38 | "id": "c993aa3c-ade9-4d99-a56b-6a5b472d9dba",
39 | "old_password": "123456",
40 | "new_password": "abcdef"
41 | }
42 |
43 |
44 | ###
45 | POST http://localhost:9001/user/login
46 | Content-Type: application/json
47 |
48 | {
49 | "email": "robot-1@pqbs.com",
50 | "password": "abcdef"
51 | }
52 |
53 | ###
54 | POST http://localhost:9001/user/register
55 | Content-Type: application/json
56 |
57 | {
58 | "name": "robot-2",
59 | "password": "123456",
60 | "email": "robot-2@pqbs.com",
61 | "phone": "13000000002",
62 | "gender": false,
63 | "degree": "robot",
64 | "position": "robot-man",
65 | "employer": "developer",
66 | "major": "test"
67 | }
68 |
69 |
70 | ###
71 | POST http://localhost:9001/user/search
72 | Content-Type: application/json
73 |
74 | {
75 | "name": "robot-3",
76 | "employer": "developer",
77 | "major": "test"
78 | }
--------------------------------------------------------------------------------
/proj-review/utils/gendoc.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "github.com/microcosm-cc/bluemonday"
5 | "github.com/russross/blackfriday"
6 | "io/ioutil"
7 | "os"
8 | "proj-review/log"
9 | )
10 |
11 | func readAll(filePth string) ([]byte, error) {
12 | f, err := os.Open(filePth)
13 | if err != nil {
14 | return nil, err
15 | }
16 | return ioutil.ReadAll(f)
17 | }
18 |
19 | func markdownToHTML(md string) string {
20 | myHTMLFlags := 0 |
21 | blackfriday.HTML_USE_XHTML |
22 | blackfriday.HTML_USE_SMARTYPANTS |
23 | blackfriday.HTML_SMARTYPANTS_FRACTIONS |
24 | blackfriday.HTML_SMARTYPANTS_DASHES |
25 | blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
26 |
27 | myExtensions := 0 |
28 | blackfriday.EXTENSION_NO_INTRA_EMPHASIS |
29 | blackfriday.EXTENSION_TABLES |
30 | blackfriday.EXTENSION_FENCED_CODE |
31 | blackfriday.EXTENSION_AUTOLINK |
32 | blackfriday.EXTENSION_STRIKETHROUGH |
33 | blackfriday.EXTENSION_SPACE_HEADERS |
34 | blackfriday.EXTENSION_HEADER_IDS |
35 | blackfriday.EXTENSION_BACKSLASH_LINE_BREAK |
36 | blackfriday.EXTENSION_DEFINITION_LISTS |
37 | blackfriday.EXTENSION_HARD_LINE_BREAK
38 |
39 | renderer := blackfriday.HtmlRenderer(myHTMLFlags, "", "")
40 | bytes := blackfriday.MarkdownOptions([]byte(md), renderer, blackfriday.Options{
41 | Extensions: myExtensions,
42 | })
43 | theHTML := string(bytes)
44 | return bluemonday.UGCPolicy().Sanitize(theHTML)
45 | }
46 |
47 | func GenApiDoc() {
48 | path := "views/api.md"
49 | res, err := readAll(path)
50 | if err != nil {
51 | log.Logger.Warn("Build API docs error: " + err.Error())
52 | return
53 | }
54 |
55 | result := markdownToHTML(string(res))
56 | // 写入到文件
57 | dstFile, err := os.Create("views/api.html")
58 | if err != nil {
59 | log.Logger.Warn("Build API docs error: " + err.Error())
60 | return
61 | }
62 | defer dstFile.Close()
63 | dstFile.WriteString(result + "\n")
64 | }
65 |
--------------------------------------------------------------------------------
/proj-review/utils/hash.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "crypto/sha256"
5 | "encoding/base64"
6 | )
7 |
8 | func GenSha256(str string) string {
9 | h := sha256.New()
10 | h.Write([]byte(str))
11 | return ConvertToBase64(h.Sum(nil))
12 | }
13 |
14 | func ConvertToBase64(str []byte) string {
15 | enc := base64.StdEncoding.EncodeToString(str)
16 | return enc
17 | }
18 |
--------------------------------------------------------------------------------
/proj-review/utils/mkdir.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "path/filepath"
7 | "time"
8 | )
9 |
10 | // CreateDateDir 根据当前日期来创建文件夹
11 | func CreateDateDir(Path string) string {
12 | t := time.Now()
13 | folderDate := fmt.Sprintf("%d-%d-%d", t.Year(), t.Month(), t.Day())
14 | folderPath := filepath.Join(Path, folderDate)
15 | if _, err := os.Stat(folderPath); os.IsNotExist(err) {
16 | // 必须分成两步:先创建文件夹、再修改权限
17 | os.MkdirAll(folderPath, os.ModePerm) //0777
18 | os.Chmod(folderPath, os.ModePerm)
19 | }
20 | return folderPath
21 | }
22 |
23 | // IsDirExists 判断所给路径文件/文件夹是否存在
24 | func IsDirExists(path string) bool {
25 | _, err := os.Stat(path) //os.Stat获取文件信息
26 | if err != nil {
27 | if os.IsExist(err) {
28 | return true
29 | }
30 | return false
31 | }
32 | return true
33 | }
34 |
35 | // IsDir 判断所给路径是否为文件夹
36 | func IsDir(path string) bool {
37 | s, err := os.Stat(path)
38 | if err != nil {
39 | return false
40 | }
41 | return s.IsDir()
42 | }
43 |
44 | // IsFile 判断所给路径是否为文件
45 | func IsFile(path string) bool {
46 | return !IsDir(path)
47 | }
48 |
--------------------------------------------------------------------------------
/proj-review/utils/uuid.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import "github.com/google/uuid"
4 |
5 | /*
6 | 用于生成uuid使用, 这里使用V1(基于timestamp)和V4版本(基于随机数)
7 | */
8 |
9 | // GenUuidV1 generate the uuid version 1 (timestamp)
10 | func GenUuidV1() (string, error) {
11 | res, err := uuid.NewUUID()
12 | if err != nil {
13 | return "", err
14 | }
15 | return res.String(), nil
16 | }
17 |
18 | // GenUuidV4 generate the uuid version 4 (random number)
19 | func GenUuidV4() string {
20 | res := uuid.New()
21 | return res.String()
22 | }
23 |
--------------------------------------------------------------------------------
/proj-review/views/api.md:
--------------------------------------------------------------------------------
1 |
2 | # User
3 | - [x] [2021-8-15] /user/checkInfo:检查是否重复注册邮箱 & 手机号码;
4 | - [x] [2021-8-15] /user/register:用户注册;
5 | - [x] [2021-8-15] /user/login: 用户登录;
6 | - [x] [2021-8-15] /user/getInfo:根据id获取用户信息;
7 | - [x] [2021-8-15] /user/updateInfo:更新用户信息;
8 | - [x] [2021-8-15] /user/updatePwd:用户更新密码;
9 | - [ ] [2021-8-15] /user/resetPwd:重置密码;
10 | - [ ] [2021-] /user/logout:退出登录;
11 | - [x] [2021-8-15] /user/delete:删除用户;
12 | - [x] [2021-8-15] /user/search:搜索用户;
13 |
14 | # File
15 | - [x] [2021-8-15] /file/upload:上传文件
16 | - [x] [2021-8-15] /file/download:使用id下载文件
17 | - [x] [2021-8-15] /file/getInfo:获取文件记录信息;
18 | - [x] [2021-8-15] /file/delete:删除文件记录(不在磁盘上删除)
19 | - [x] [2021-8-15] /file/search:文件搜索;
20 |
21 | # Project
22 | - [x] [2021-8-15] /proj/createEmpty:创建空项目(创建项目管理员关联);
23 | - [ ] [2021-] /proj/createTemplate:创建模板项目(7个标准流程)
24 | - [ ] [2021-] /proj/set:设置项目信息;
25 | - [x] [2021-8-16] /proj/makeAssign:创建项目人员分配角色;
26 | - [ ] [2021-] /proj/makeGroupAssigns:批量进行人员分配;
27 | - [x] [2021-8-16] /proj/changeAssign:更改项目人员分配角色;
28 | - [ ] [2021-] /proj/removeAssign:移除某个分配记录;
29 | - [x] [2021-8-15] /proj/userAssign:获取某个用户参与的项目角色;
30 | - [x] [2021-8-15] /proj/projectAssign:获取某个项目的人员分配信息
31 | - [ ] [2021-] /proj/changeState:更改项目进度;
32 | - [ ] [2021-] /proj/dataStat:项目数据统计;
33 | - [ ] [2021-] /step/create:创建流程;
34 | - [ ] [2021-] /step/changeState:更改流程进度;
35 | - [ ] [2021-] /step/set:设置流程的信息;
36 | - [ ] [2021-] /task/create:创建任务;
37 | - [ ] [2021-] /task/changeState:更改任务进度
38 | - [ ] [2021-] /task/set:设置任务信息;
39 | - [ ] [2021-] /task/delete:删除任务
40 | - [ ] [2021-] /task/newRef:创建任务下的材料引用;
41 | - [ ] [2021-] /task/reviewRef:管理员审核任务材料;
42 |
43 | # Questions
44 | - [ ] [2021-] /question/new
45 | - [ ] [2021-] /question/import
46 | - [ ] [2021-] /question/getInfo
47 | - [ ] [2021-] /question/update
48 | - [ ] [2021-] /question/review
49 | - [ ] [2021-] /question/trace
50 | - [ ] [2021-] /question/compare
51 | - [ ] [2021-] /question/finish
52 | - [ ] [2021-] /question/search
53 |
54 | # Exam Paper
55 | - [ ] [2021-] /exam/new
56 | - [ ] [2021-] /exam/update
57 | - [ ] [2021-] /exam/review
58 | - [ ] [2021-] /exam/getInfo
59 | - [ ] [2021-] /exam/trace
60 | - [ ] [2021-] /exam/compare
61 | - [ ] [2021-] /exam/finish
62 | - [ ] [2021-] /exam/getFinal
63 | - [ ] [2021-] /exam/search
64 |
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T170925.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2001,
3 | "message": "",
4 | "data": [
5 | null
6 | ]
7 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T170954.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2001,
3 | "message": "",
4 | "data": [
5 | null
6 | ]
7 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171040.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2001,
3 | "message": "",
4 | "data": [
5 | null
6 | ]
7 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171401.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTY5MjQxLCJpYXQiOjE2MjkzNjQ0NDEsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.F8A5BbxUHo86frL7YKqPkK0lT9rHVuKfqtWxPAkUefE",
4 | "data": [
5 | {
6 | "name": "",
7 | "age": 0,
8 | "locaion": "",
9 | "email": "robot1@openct.com",
10 | "phone": "",
11 | "gender": false,
12 | "degree": "",
13 | "position": "",
14 | "employer": "",
15 | "major": ""
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171454.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTY5Mjk0LCJpYXQiOjE2MjkzNjQ0OTQsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0._0bGgd_Icp7FkW3K1hCWpBkeuAjHiI3Ce1BXwPG-Lvk",
4 | "data": [
5 | {
6 | "name": "robot1",
7 | "age": 0,
8 | "locaion": "china",
9 | "email": "robot1@openct.com",
10 | "phone": "10000000001",
11 | "gender": true,
12 | "degree": "本科",
13 | "position": "developer",
14 | "employer": "openct-community",
15 | "major": "program"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171716.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTY5NDM1LCJpYXQiOjE2MjkzNjQ2MzUsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.qbkcF-aEjNp6Nvr-3WHiK8B-aKHc_RG9Av_xTn2PGEM",
4 | "data": [
5 | {
6 | "Id": "611e1e4dfe69b544cb451d3e",
7 | "CreateAt": "2021-08-19T09:03:09.604Z",
8 | "UpdateAt": "2021-08-19T09:03:09.604Z",
9 | "uuid": "e59bdc40-e551-4236-9cf0-73e2df6a78cf",
10 | "profile": {
11 | "name": "robot1",
12 | "age": 0,
13 | "locaion": "china",
14 | "email": "robot1@openct.com",
15 | "phone": "10000000001",
16 | "gender": true,
17 | "degree": "本科",
18 | "position": "developer",
19 | "employer": "openct-community",
20 | "major": "program"
21 | },
22 | "password": "",
23 | "salt": ""
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171810.404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Not Found
6 |
81 |
82 |
83 |
84 |
85 |
86 |
Not Found
87 |
88 |
89 |
The page you have requested has flown the coop.
Perhaps you are here because:
90 |
The page has moved
The page no longer exists
You were looking for your puppy and got lost
You
91 | like 404 pages
92 |
93 |
Go Home
94 |
95 |
Powered by beego 2.0.0
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171820.400.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": [
5 | "e59bdc40-e551-4236-9cf0-73e2df6a78cf"
6 | ]
7 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171855.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2103,
3 | "message": "",
4 | "data": [
5 | "e59bdc40-e551-4236-9cf0-73e2df6a78cf"
6 | ]
7 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171944.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2103,
3 | "message": "e59bdc40-e551-4236-9cf0-73e2df6a78cf",
4 | "data": [
5 | null
6 | ]
7 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T171957.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTY5NTk2LCJpYXQiOjE2MjkzNjQ3OTYsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.DJhEl6SPLLO7hva1Kd4VitW0bGZoC5P3Kuhiplz22sE",
4 | "data": [
5 | {
6 | "Id": "611e1e4dfe69b544cb451d3e",
7 | "CreateAt": "2021-08-19T09:03:09.604Z",
8 | "UpdateAt": "2021-08-19T09:03:09.604Z",
9 | "uuid": "e59bdc40-e551-4236-9cf0-73e2df6a78cf",
10 | "profile": {
11 | "name": "robot1",
12 | "age": 0,
13 | "locaion": "china",
14 | "email": "robot1@openct.com",
15 | "phone": "10000000001",
16 | "gender": true,
17 | "degree": "本科",
18 | "position": "developer",
19 | "employer": "openct-community",
20 | "major": "program"
21 | },
22 | "password": "",
23 | "salt": ""
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172053.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": [
5 | {
6 | "name": "robot1",
7 | "age": 0,
8 | "locaion": "china",
9 | "email": "robot1@openct.com",
10 | "phone": "10000000001",
11 | "gender": true,
12 | "degree": "本科",
13 | "position": "developer",
14 | "employer": "openct-community",
15 | "major": "program"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172234.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": {
5 | "name": "robot1",
6 | "age": 0,
7 | "locaion": "china",
8 | "email": "robot1@openct.com",
9 | "phone": "10000000001",
10 | "gender": true,
11 | "degree": "本科",
12 | "position": "developer",
13 | "employer": "openct-community",
14 | "major": "program"
15 | }
16 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172324.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTY5ODA0LCJpYXQiOjE2MjkzNjUwMDQsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.AVd_2XAiSmjGN9pCuXN-jSC33Ps6qyvjPyaa1M7bdYk",
4 | "data": {
5 | "Id": "611e1e4dfe69b544cb451d3e",
6 | "CreateAt": "2021-08-19T09:03:09.604Z",
7 | "UpdateAt": "2021-08-19T09:03:09.604Z",
8 | "uuid": "e59bdc40-e551-4236-9cf0-73e2df6a78cf",
9 | "profile": {
10 | "name": "robot1",
11 | "age": 0,
12 | "locaion": "china",
13 | "email": "robot1@openct.com",
14 | "phone": "10000000001",
15 | "gender": true,
16 | "degree": "本科",
17 | "position": "developer",
18 | "employer": "openct-community",
19 | "major": "program"
20 | },
21 | "password": "",
22 | "salt": ""
23 | }
24 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172352.200.json:
--------------------------------------------------------------------------------
1 | "logout success"
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172607.200.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | beego application error
6 |
50 |
52 |
53 |
54 |
57 |
58 |
59 |
60 | Request Method: |
61 | GET |
62 |
63 |
64 | Request URL: |
65 | /review/user/logout |
66 |
67 |
68 | RemoteAddr: |
69 | 127.0.0.1 |
70 |
71 |
72 |
73 |
Stack
74 |
C:/DevTools/golang/go_17/src/runtime/panic.go:1038
75 | C:/DevTools/golang/go_17/src/runtime/panic.go:90
76 | D:/OpenCT/OpenItem/review/controllers/user.go:156
77 | C:/DevTools/golang/go_17/src/reflect/value.go:543
78 | C:/DevTools/golang/go_17/src/reflect/value.go:339
79 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/router.go:883
80 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/filter.go:81
81 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/router.go:664
82 | C:/DevTools/golang/go_17/src/net/http/server.go:2878
83 | C:/DevTools/golang/go_17/src/net/http/server.go:1929
84 | C:/DevTools/golang/go_17/src/runtime/asm_amd64.s:1581
85 |
86 |
87 |
88 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172629.200.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | beego application error
6 |
50 |
52 |
53 |
54 |
57 |
58 |
59 |
60 | Request Method: |
61 | GET |
62 |
63 |
64 | Request URL: |
65 | /review/user/logout |
66 |
67 |
68 | RemoteAddr: |
69 | 127.0.0.1 |
70 |
71 |
72 |
73 |
Stack
74 |
C:/DevTools/golang/go_17/src/runtime/panic.go:1038
75 | C:/DevTools/golang/go_17/src/runtime/panic.go:90
76 | D:/OpenCT/OpenItem/review/controllers/user.go:156
77 | C:/DevTools/golang/go_17/src/reflect/value.go:543
78 | C:/DevTools/golang/go_17/src/reflect/value.go:339
79 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/router.go:883
80 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/filter.go:81
81 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/router.go:664
82 | C:/DevTools/golang/go_17/src/net/http/server.go:2878
83 | C:/DevTools/golang/go_17/src/net/http/server.go:1929
84 | C:/DevTools/golang/go_17/src/runtime/asm_amd64.s:1581
85 |
86 |
87 |
88 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172636.200.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | beego application error
6 |
50 |
52 |
53 |
54 |
57 |
58 |
59 |
60 | Request Method: |
61 | GET |
62 |
63 |
64 | Request URL: |
65 | /review/user/logout |
66 |
67 |
68 | RemoteAddr: |
69 | 127.0.0.1 |
70 |
71 |
72 |
73 |
Stack
74 |
C:/DevTools/golang/go_17/src/runtime/panic.go:1038
75 | C:/DevTools/golang/go_17/src/runtime/panic.go:90
76 | D:/OpenCT/OpenItem/review/controllers/user.go:156
77 | C:/DevTools/golang/go_17/src/reflect/value.go:543
78 | C:/DevTools/golang/go_17/src/reflect/value.go:339
79 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/router.go:883
80 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/filter.go:81
81 | C:/Users/kkoog/go/pkg/mod/github.com/beego/beego/v2@v2.0.1/server/web/router.go:664
82 | C:/DevTools/golang/go_17/src/net/http/server.go:2878
83 | C:/DevTools/golang/go_17/src/net/http/server.go:1929
84 | C:/DevTools/golang/go_17/src/runtime/asm_amd64.s:1581
85 |
86 |
87 |
88 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172647.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "e59bdc40-e551-4236-9cf0-73e2df6a78cf"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172709.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "40f98bd5-e074-4951-8a56-615ed9258ce4"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T172827.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": null
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T173234.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTcwMzU0LCJpYXQiOjE2MjkzNjU1NTQsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.cbIALnwYx2kp8uq92mLgxVtQCoAMOG9gfm5ooFGHDsA",
4 | "data": {
5 | "Id": "611e1e4dfe69b544cb451d3e",
6 | "CreateAt": "2021-08-19T09:03:09.604Z",
7 | "UpdateAt": "2021-08-19T09:03:09.604Z",
8 | "uuid": "e59bdc40-e551-4236-9cf0-73e2df6a78cf",
9 | "profile": {
10 | "name": "robot1",
11 | "age": 0,
12 | "locaion": "china",
13 | "email": "robot1@openct.com",
14 | "phone": "10000000001",
15 | "gender": true,
16 | "degree": "本科",
17 | "position": "developer",
18 | "employer": "openct-community",
19 | "major": "program"
20 | },
21 | "password": "",
22 | "salt": ""
23 | }
24 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T173351.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2001,
3 | "message": "",
4 | "data": "e59bdc40-e551-4236-9cf0-73e2df6a78cf"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T173453.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2001,
3 | "message": "",
4 | "data": "e59bdc40-e551-4236-9cf0-73e2df6a78cf"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T173531.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "e59bdc40-e551-4236-9cf0-73e2df6a78cf"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T173650.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2001,
3 | "message": "",
4 | "data": ""
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-19T173745.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "e59bdc40-e551-4236-9cf0-73e2df6a78cf"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T173424.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": null
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T173441.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": null
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T173509.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "38509279-4363-4fa4-b3b8-f7e8cf711690"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T173526.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2001,
3 | "message": "",
4 | "data": ""
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T173545.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "93515443-dbab-42b9-bc4c-d3aedb7fa1f2"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T173556.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "c41d2a26-d4c7-45a8-a570-2312857ed49f"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T173717.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": {
5 | "name": "robot0",
6 | "age": 0,
7 | "locaion": "china",
8 | "email": "robot0@openct.com",
9 | "phone": "10000000000",
10 | "gender": true,
11 | "degree": "本科",
12 | "position": "developer",
13 | "employer": "openct-community",
14 | "major": "program"
15 | }
16 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T185844.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 2103,
3 | "message": "93515443-dbab-42b9-bc4c-d3aedb7fa1f2",
4 | "data": null
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-20T185859.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiOTM1MTU0NDMtZGJhYi00MmI5LWJjNGMtZDNhZWRiN2ZhMWYyIiwiZXhwIjoxNjMwMDYxOTM5LCJpYXQiOjE2Mjk0NTcxMzksImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.c6icyTvtRUjuai-51S2PuzSj3VLDfyij-wqEV5oJnJA",
4 | "data": {
5 | "Id": "611f777182927262361ed420",
6 | "CreateAt": "2021-08-20T09:35:45.167Z",
7 | "UpdateAt": "2021-08-20T09:35:45.167Z",
8 | "uuid": "93515443-dbab-42b9-bc4c-d3aedb7fa1f2",
9 | "profile": {
10 | "name": "robot1",
11 | "age": 0,
12 | "locaion": "china",
13 | "email": "robot1@openct.com",
14 | "phone": "10000000001",
15 | "gender": true,
16 | "degree": "本科",
17 | "position": "developer",
18 | "employer": "openct-community",
19 | "major": "program"
20 | },
21 | "password": "",
22 | "salt": ""
23 | }
24 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-23T111250.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiOTM1MTU0NDMtZGJhYi00MmI5LWJjNGMtZDNhZWRiN2ZhMWYyIiwiZXhwIjoxNjMwMjkzMTcwLCJpYXQiOjE2Mjk2ODgzNzAsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.9XZHK6l8Z_ZqnzL1sWsr-jqKCCDTWC2AGgTO5OeRBgc",
4 | "data": {
5 | "Id": "611f777182927262361ed420",
6 | "CreateAt": "2021-08-20T09:35:45.167Z",
7 | "UpdateAt": "2021-08-20T09:35:45.167Z",
8 | "uuid": "93515443-dbab-42b9-bc4c-d3aedb7fa1f2",
9 | "profile": {
10 | "name": "robot1",
11 | "age": 0,
12 | "locaion": "china",
13 | "email": "robot1@openct.com",
14 | "phone": "10000000001",
15 | "gender": true,
16 | "degree": "本科",
17 | "position": "developer",
18 | "employer": "openct-community",
19 | "major": "program"
20 | },
21 | "password": "",
22 | "salt": ""
23 | }
24 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085435.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "88eded2e-2fab-461b-9a43-a93d21df66c9"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085452.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "c38121f9-4584-402d-8253-54d60e9e2f9b"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085502.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "4cc3a021-8a9d-4d46-bd00-ad202ce1b5d1"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085511.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "95e24377-9e90-4d93-895c-5fb336de0570"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085520.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "741a34fb-5dd6-477d-86bc-6be475b56ee3"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085529.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "31ac623c-a4f7-4b60-b18b-5d0c3d560820"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085550.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "3bb8d658-eb4c-4b59-a688-5ab93be3ac30"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085559.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "29f98f18-6b58-4d90-9ba8-a03820f60ab7"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085607.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "e34361e9-24ed-465d-9f77-7d294c0eb48a"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T085622.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "",
4 | "data": "f5f9b556-6482-432c-ae47-0039068309aa"
5 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T092901.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiODhlZGVkMmUtMmZhYi00NjFiLTlhNDMtYTkzZDIxZGY2NmM5IiwiZXhwIjoxNjMwMzczMzQwLCJpYXQiOjE2Mjk3Njg1NDAsImlzcyI6InRlc3RtYW4tMUBvcGVuY3QuY29tIn0.EVJPeN2-1TiVaZNVwId5R0poYw_rfC5C1yAXQ0iJL5g",
4 | "data": {
5 | "Id": "6124434be55b388e3bc3072d",
6 | "CreateAt": "2021-08-24T00:54:35.655Z",
7 | "UpdateAt": "2021-08-24T00:54:35.655Z",
8 | "uuid": "88eded2e-2fab-461b-9a43-a93d21df66c9",
9 | "profile": {
10 | "name": "test-man-1",
11 | "age": 0,
12 | "locaion": "china",
13 | "email": "testman-1@openct.com",
14 | "phone": "11000000001",
15 | "gender": true,
16 | "degree": "本科",
17 | "position": "test-man",
18 | "employer": "openct-community",
19 | "major": "program"
20 | },
21 | "password": "",
22 | "salt": ""
23 | }
24 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/2021-08-24T175026.200.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation_code": 1000,
3 | "message": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiNGNjM2EwMjEtOGE5ZC00ZDQ2LWJkMDAtYWQyMDJjZTFiNWQxIiwiZXhwIjoxNjMwNDAzNDI2LCJpYXQiOjE2Mjk3OTg2MjYsImlzcyI6InRlc3RtYW4tM0BvcGVuY3QuY29tIn0.DToDI-F47QQq_xgXMiWSJvSqE6PY3qcdYkgYhvBxBLk",
4 | "data": {
5 | "Id": "61244366e55b388e3bc3072f",
6 | "CreateAt": "2021-08-24T00:55:02.101Z",
7 | "UpdateAt": "2021-08-24T00:55:02.101Z",
8 | "uuid": "4cc3a021-8a9d-4d46-bd00-ad202ce1b5d1",
9 | "profile": {
10 | "name": "test-man-3",
11 | "age": 0,
12 | "locaion": "china",
13 | "email": "testman-3@openct.com",
14 | "phone": "11000000003",
15 | "gender": true,
16 | "degree": "本科",
17 | "position": "test-man",
18 | "employer": "openct-community",
19 | "major": "program"
20 | },
21 | "password": "",
22 | "salt": ""
23 | }
24 | }
--------------------------------------------------------------------------------
/review/.idea/httpRequests/http-client.cookies:
--------------------------------------------------------------------------------
1 | # domain path name value date
2 |
--------------------------------------------------------------------------------
/review/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/review/.idea/review.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/review/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/review/access/check.go:
--------------------------------------------------------------------------------
1 | package access
2 |
--------------------------------------------------------------------------------
/review/access/cros.go:
--------------------------------------------------------------------------------
1 | package access
2 |
--------------------------------------------------------------------------------
/review/access/filter.go:
--------------------------------------------------------------------------------
1 | package access
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "github.com/beego/beego/v2/server/web/context"
7 | "log"
8 | "review/logger"
9 | "review/utils"
10 | )
11 |
12 | type FilterResponse struct {
13 | Status string `json:"status"`
14 | Msg string `json:"msg"`
15 | Data interface{} `json:"data"`
16 | }
17 |
18 | func denyRequest(ctx *context.Context, message string) {
19 | w := ctx.ResponseWriter
20 | w.WriteHeader(403)
21 | // resp := &controllers.Response{Status: "error", Msg: "Unauthorized operation"}
22 | resp := &FilterResponse{Status: "error", Msg: message}
23 | _, err := w.Write([]byte(utils.StructToJson(resp)))
24 | if err != nil {
25 | logger.Recorder.Error("filter error:" + err.Error())
26 | }
27 | }
28 |
29 | func TokenFilter(ctx *context.Context) {
30 | method := ctx.Request.Method
31 | if method == "POST" {
32 | var requestBody map[string]interface{}
33 | json.Unmarshal(ctx.Input.RequestBody, &requestBody)
34 | logger.Recorder.Info(fmt.Sprintf("%s", requestBody))
35 | if requestBody["token"] == nil {
36 | log.Println("deny")
37 | denyRequest(ctx, "no token")
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/review/conf/app.conf:
--------------------------------------------------------------------------------
1 | ; Basic config
2 | appname = PQBS_review_module
3 | httpaddr = localhost
4 | httpport = 9001
5 | runmode = dev
6 | copyrequestbody = true
7 |
8 | # iclude "mysql.conf"
9 | include "mongo.conf"
10 | include "file.conf"
11 | include "log.conf"
12 | include "mail.conf"
--------------------------------------------------------------------------------
/review/conf/file.conf:
--------------------------------------------------------------------------------
1 | ; 用于配置文件上传 & 下载
2 | filerootpath = "static/files/"
3 | maxmemory = 1<<22
4 |
--------------------------------------------------------------------------------
/review/conf/log.conf:
--------------------------------------------------------------------------------
1 | ; review module log
2 |
3 | logpath = log/
4 | logfile = pqbs-review.log
5 | loglevel = full
--------------------------------------------------------------------------------
/review/conf/mail.conf:
--------------------------------------------------------------------------------
1 | adminmail = "develop_pqbs@163.com"
2 | mailpassword = "develop_pqbs"
--------------------------------------------------------------------------------
/review/conf/mongo.conf:
--------------------------------------------------------------------------------
1 | ; mongo database config
2 | mongoaddr = localhost
3 | mongoport = 27017
4 | mongodb = openct_pqbs
5 | mongouser = openct
6 | mongopwd = 123456
7 |
8 | ; collections name define
9 | [mongo-collections]
10 | ; review
11 | users = "users"
12 | assignments = "assignments"
13 | projects = "projects"
14 | steps = "steps"
15 | tasks = "tasks"
16 | fileRecords = "file_records"
17 | submits = "submits"
18 | audits = "audits"
19 | references = "references"
20 |
21 | ; warehouse
22 | tempQuestions = "temp_questions"
23 | finalQuestions = "final_questions"
24 | tempTestPapers = "temp_test_papers"
25 | finalTestPapers = "final_test_papers"
--------------------------------------------------------------------------------
/review/controllers/default.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "review/access"
7 | "review/logger"
8 | )
9 |
10 | // unmarshalBody parse the response body (json type)
11 | func unmarshalBody(body []byte, obj interface{}) error {
12 | // marshal json body
13 | if err := json.Unmarshal(body, obj); err != nil {
14 | logger.Recorder.Warn("[JSON] " + err.Error())
15 | return err
16 | }
17 | return nil
18 | }
19 |
20 | // parseUserToken get user id from token string
21 | func parseUserToken(token string) (string, error) {
22 | //
23 | fmt.Println("recv token: ", token)
24 | //
25 | tokenData, err := access.ParseToken(token)
26 | if err != nil {
27 | return "", err
28 | }
29 | //
30 | fmt.Println("recv user: ", tokenData.UserID)
31 | fmt.Println("recv token time from ", tokenData.IssuedAt, " to ", tokenData.ExpiresAt)
32 | //
33 | return tokenData.UserID, nil
34 | }
35 |
--------------------------------------------------------------------------------
/review/controllers/noticer.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | beego "github.com/beego/beego/v2/server/web"
5 | "net/http"
6 | "review/noticer"
7 | "review/response"
8 | )
9 |
10 | type NoticerController struct {
11 | beego.Controller
12 | }
13 |
14 | func (n *NoticerController) respondJson(httpCode int, opCode int, message string, data ...interface{}) {
15 | n.Ctx.Output.SetStatus(httpCode)
16 | var d interface{}
17 | if len(data) == 1 {
18 | d = data[0]
19 | } else {
20 | d = data
21 | }
22 | resp := response.GenResponse(opCode, message, d)
23 | n.Data["json"] = resp
24 | n.ServeJSON()
25 | }
26 |
27 | // @Title SendEmail
28 | // @Description 发送邮件
29 | // @Param json body noticer.EmailPackage true "邮件内容"
30 | // @Success 200 {object} response.Default
31 | // @Failure 400 "invalid email-structure json body(token)"
32 | // @router /email [post]
33 | func (n *NoticerController) SendEmail() {
34 | var emailInfo noticer.EmailPackage
35 | err := unmarshalBody(n.Ctx.Input.RequestBody, &emailInfo)
36 | if err != nil {
37 | n.respondJson(http.StatusBadRequest, response.FAIL, "parse body (email information) failed")
38 | return
39 | }
40 | err = noticer.SendEmail(&emailInfo)
41 | if err != nil {
42 | n.respondJson(http.StatusOK, response.FAIL, "send email failed: "+err.Error())
43 | return
44 | }
45 | n.respondJson(http.StatusOK, response.SUCCESS, "send successfully")
46 | return
47 | }
48 |
--------------------------------------------------------------------------------
/review/go.mod:
--------------------------------------------------------------------------------
1 | module review
2 |
3 | go 1.17
4 |
5 | require github.com/beego/beego/v2 v2.0.1
6 |
7 | require (
8 | github.com/astaxie/beego v1.12.3 // indirect
9 | github.com/dgrijalva/jwt-go v3.2.0+incompatible
10 | github.com/google/uuid v1.1.1
11 | github.com/qiniu/qmgo v1.0.0
12 | github.com/smartystreets/goconvey v1.6.4
13 | go.mongodb.org/mongo-driver v1.7.1
14 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
15 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
16 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
17 | )
18 |
--------------------------------------------------------------------------------
/review/logger/log.go:
--------------------------------------------------------------------------------
1 | package logger
2 |
3 | import (
4 | "fmt"
5 | "github.com/beego/beego/v2/core/logs"
6 | beego "github.com/beego/beego/v2/server/web"
7 | )
8 |
9 | var Recorder *logs.BeeLogger
10 |
11 | func init() {
12 | // 设置日志生成器
13 | log := logs.NewLogger()
14 | // 读取配置
15 | logPath, err := beego.AppConfig.String("logpath")
16 | if err != nil {
17 | fmt.Println("load log path config error.")
18 | }
19 | logFile, err := beego.AppConfig.String("logfile")
20 | if err != nil {
21 | fmt.Println("load log filename config error.")
22 | }
23 | // todo: more options in .conf
24 | logConfig := fmt.Sprintf(
25 | `{"filename":"%s","level":7,"daily":true,"maxdays":10,"color":true}`,
26 | logPath+logFile,
27 | )
28 | log.SetLogger(
29 | logs.AdapterFile,
30 | logConfig,
31 | )
32 | log.SetLogger(logs.AdapterConsole)
33 | log.EnableFuncCallDepth(true)
34 | log.SetLevel(logs.LevelDebug)
35 |
36 | Recorder = log
37 | }
38 |
--------------------------------------------------------------------------------
/review/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/beego/beego/v2/server/web/filter/cors"
5 | _ "review/routers"
6 |
7 | beego "github.com/beego/beego/v2/server/web"
8 | )
9 |
10 | func main() {
11 | if beego.BConfig.RunMode == "dev" {
12 | beego.BConfig.WebConfig.DirectoryIndex = true
13 | beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
14 | }
15 |
16 | // insert the filter for cross-domain
17 | beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
18 | //AllowAllOrigins: true,
19 | AllowMethods: []string{"*"},
20 | //AllowHeaders: []string{"*"},
21 | AllowHeaders: []string{"Origin", "Authorization", "Access-Control-Allow-Origin", "content-type", "token"},
22 | ExposeHeaders: []string{"Content-Length", "Access-Control-Allow-Origin"},
23 | AllowCredentials: true,
24 | AllowOrigins: []string{"http://49.232.73.36:8085", "http://localhost:*", "http://127.0.0.1:*"},
25 | }))
26 | beego.Run()
27 | }
28 |
--------------------------------------------------------------------------------
/review/models/audit.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "github.com/qiniu/qmgo/field"
7 | "github.com/qiniu/qmgo/options"
8 | "go.mongodb.org/mongo-driver/bson"
9 | "review/database"
10 | "review/logger"
11 | "review/request"
12 | "review/response"
13 | "review/utils"
14 | )
15 |
16 | type Audit struct {
17 | field.DefaultField `bson:",inline"`
18 | Uuid string `json:"uuid" bson:"uuid"`
19 | SubmitContent string `json:"submit_content" bson:"submit_content"`
20 | Result int `json:"result" bson:"result"`
21 | Comment string `json:"comment" bson:"comment"`
22 | Auditor string `json:"auditor" bson:"auditor"`
23 | }
24 |
25 | // result: 0-not pass 1-pass, 2-need correct
26 |
27 | func init() {
28 | // clean old indexes
29 | database.MgoAudits.DropAllIndexes(context.Background())
30 | err := database.MgoAudits.CreateIndexes(
31 | context.Background(),
32 | []options.IndexModel{
33 | {Key: []string{"uuid"}, Unique: true},
34 | {Key: []string{"uuid", "submit_content"}, Unique: true},
35 | },
36 | )
37 | if err != nil {
38 | logger.Recorder.Error("[Mongo Submits] " + err.Error())
39 | return
40 | }
41 | logger.Recorder.Info("[Mongo] Create the index in submits collection successfully")
42 | return
43 | }
44 |
45 | func GetOneAudit(auditId string) (*Audit, int) {
46 | var audit Audit
47 | err := database.MgoAudits.Find(context.Background(), bson.M{
48 | "uuid": auditId,
49 | }).One(&audit)
50 | if err != nil {
51 | logger.Recorder.Warn("find audit info err: " + err.Error())
52 | return nil, response.AuditGetInfoFail
53 | }
54 | return &audit, response.SUCCESS
55 | }
56 |
57 | func GetSubmitAudits(submitId string) (*[]Audit, int) {
58 | var submit Submit
59 | err := database.MgoSubmits.Find(context.Background(), bson.M{
60 | "uuid": submitId,
61 | }).One(&submit)
62 | if err != nil {
63 | logger.Recorder.Warn("address submit info err: " + err.Error())
64 | return nil, response.AuditGetInfoFail
65 | }
66 | var audits []Audit
67 | for _, content := range submit.Contents {
68 | var audit Audit
69 | err := database.MgoAudits.Find(context.Background(), bson.M{
70 | "submit_content": content.Uuid,
71 | }).One(&audit)
72 | if err != nil {
73 | continue
74 | } else {
75 | audits = append(audits, audit)
76 | }
77 | }
78 | return &audits, response.SUCCESS
79 | }
80 |
81 | func MakeOneAudit(req *request.MakeOneAudit) (*Audit, int) {
82 | newAudit := Audit{
83 | DefaultField: field.DefaultField{},
84 | Uuid: utils.GenUuidV4(),
85 | SubmitContent: req.SubmitContentId,
86 | Result: req.Result,
87 | Comment: req.Comment,
88 | Auditor: req.UserId,
89 | }
90 | insert, err := database.MgoAudits.InsertOne(context.Background(), &newAudit)
91 | if err != nil {
92 | logger.Recorder.Warn("[mongo create new audit failed] " + err.Error())
93 | return nil, response.AuditCreateFail
94 | }
95 | logger.Recorder.Info("[Mongo Insert] " + fmt.Sprintf("%s", insert.InsertedID))
96 | return &newAudit, response.SUCCESS
97 | }
98 |
99 | func CorrectAudit(req *request.UpdateAudit) (*Audit, int) {
100 | err := database.MgoAudits.UpdateOne(context.Background(), bson.M{
101 | "uuid": req.AuditId,
102 | }, bson.M{
103 | "$set": bson.M{
104 | "result": req.NewResult,
105 | "comment": req.NewComment,
106 | "auditor": req.NewAuditor,
107 | },
108 | })
109 | if err != nil {
110 | logger.Recorder.Warn("[mongo update new audit failed] " + err.Error())
111 | return nil, response.AuditCorrectFail
112 | }
113 | var newAudit Audit
114 | database.MgoAudits.Find(context.Background(), bson.M{"uuid": req.AuditId}).One(&newAudit)
115 | return &newAudit, response.SUCCESS
116 | }
117 |
118 | func DeleteAudit(auditId string) int {
119 | // delete in audit collection
120 | err := database.MgoAudits.Remove(context.Background(), bson.M{
121 | "uuid": auditId,
122 | })
123 | if err != nil {
124 | return response.AuditDeleteFail
125 | }
126 | return response.SUCCESS
127 | }
128 |
--------------------------------------------------------------------------------
/review/models/versionItem.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "github.com/qiniu/qmgo/field"
4 |
5 | // todo: Abstract the versioned object as a base struct.
6 | type VersionItem struct {
7 | field.DefaultField `bson:",inline"`
8 | Uuid string `bson:"uuid"`
9 | Creator string `bson:"creator"`
10 | Updater string `bson:"updater"`
11 | Base string `bson:"base"`
12 | }
13 |
--------------------------------------------------------------------------------
/review/noticer/mail.go:
--------------------------------------------------------------------------------
1 | package noticer
2 |
3 | import (
4 | "gopkg.in/gomail.v2"
5 | )
6 |
7 | type EmailPackage struct {
8 | Destination []string `json:"destination"`
9 | Subject string `json:"subject"`
10 | Body EmailBody `json:"body"`
11 | }
12 |
13 | type EmailBody struct {
14 | Sender string `json:"sender"`
15 | SendTime string `json:"send_time"`
16 | Message string `json:"message"`
17 | }
18 |
19 | func SendEmail(email *EmailPackage) error {
20 | // 设置邮箱主体
21 | mailConn := map[string]string{
22 | "user": "develop_pqbs@163.com",
23 | "pass": "HYZXNSQZRZTQMCUP",
24 | "host": "smtp.163.com",
25 | }
26 |
27 | m := gomail.NewMessage(
28 | //就选择utf-8格式保存
29 | gomail.SetEncoding(gomail.Base64),
30 | )
31 | m.SetHeader("From", m.FormatAddress(mailConn["user"], email.Body.Sender))
32 | m.SetHeader("To", email.Destination...)
33 | m.SetHeader("Subject", email.Subject)
34 | message := email.Body.Message + "\ntime: " + email.Body.SendTime
35 | m.SetBody("text/html", message)
36 |
37 | // 163 port: 25
38 | d := gomail.NewDialer(mailConn["host"], 25, mailConn["user"], mailConn["pass"]) // 设置邮件正文
39 | //d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
40 | err := d.DialAndSend(m)
41 | return err
42 | }
43 |
--------------------------------------------------------------------------------
/review/noticer/message.go:
--------------------------------------------------------------------------------
1 | package noticer
2 |
3 | import "github.com/qiniu/qmgo/field"
4 |
5 | // site message
6 |
7 | type SiteMessage struct {
8 | field.DefaultField `bson:",inline"`
9 | Uuid string `json:"uuid" bson:"uuid"`
10 | Sender string `json:"sender" bson:"sender"`
11 | Receivers []string `json:"receivers" bson:"receivers"`
12 | Message string `json:"message" bson:"message"`
13 | }
14 |
--------------------------------------------------------------------------------
/review/query/query.go:
--------------------------------------------------------------------------------
1 | package query
2 |
3 | import (
4 | "context"
5 | "go.mongodb.org/mongo-driver/bson"
6 | "review/database"
7 | "review/models"
8 | )
9 |
10 | // get user list
11 | func QueryUsers(ids []string) map[string]models.User {
12 | users := make(map[string]models.User)
13 | for _, id := range ids {
14 | var u models.User
15 | err := database.MgoUsers.Find(context.Background(), bson.M{
16 | "uuid": id,
17 | }).One(&u)
18 | if err != nil {
19 | continue
20 | }
21 | users[id] = u
22 | }
23 | return users
24 | }
25 |
26 | // get project list
27 | func QueryProjects(ids []string) map[string]models.Project {
28 | projs := make(map[string]models.Project)
29 | for _, id := range ids {
30 | var p models.Project
31 | err := database.MgoProjects.Find(context.Background(), bson.M{
32 | "uuid": id,
33 | }).One(&p)
34 | if err != nil {
35 | continue
36 | }
37 | projs[id] = p
38 | }
39 | return projs
40 | }
41 |
42 | // get assignment list
43 | func QueryAssignments(ids []string) map[string]models.Assignment {
44 | assigns := make(map[string]models.Assignment)
45 | for _, id := range ids {
46 | var a models.Assignment
47 | err := database.MgoAssignments.Find(context.Background(), bson.M{
48 | "uuid": id,
49 | }).One(&a)
50 | if err != nil {
51 | continue
52 | }
53 | assigns[id] = a
54 | }
55 | return assigns
56 | }
57 |
58 | // get file list
59 | func QueryFiles(ids []string) map[string]models.FileItem {
60 | files := make(map[string]models.FileItem)
61 | for _, id := range ids {
62 | var p models.FileItem
63 | err := database.MgoFileRecords.Find(context.Background(), bson.M{
64 | "uuid": id,
65 | }).One(&p)
66 | if err != nil {
67 | continue
68 | }
69 | files[id] = p
70 | }
71 | return files
72 | }
73 |
74 | // get step list
75 | func QuerySteps(ids []string) map[string]models.Step {
76 | steps := make(map[string]models.Step)
77 | for _, id := range ids {
78 | var p models.Step
79 | err := database.MgoSteps.Find(context.Background(), bson.M{
80 | "uuid": id,
81 | }).One(&p)
82 | if err != nil {
83 | continue
84 | }
85 | steps[id] = p
86 | }
87 | return steps
88 | }
89 |
90 | // get submit list
91 | func QuerySubmits(ids []string) map[string]models.Submit {
92 | submits := make(map[string]models.Submit)
93 | for _, id := range ids {
94 | var s models.Submit
95 | err := database.MgoSubmits.Find(context.Background(), bson.M{
96 | "uuid": id,
97 | }).One(&s)
98 | if err != nil {
99 | continue
100 | }
101 | submits[id] = s
102 | }
103 | return submits
104 | }
105 |
106 | // get audit list
107 | func QueryAudits(ids []string) map[string]models.Audit {
108 | audits := make(map[string]models.Audit)
109 | for _, id := range ids {
110 | var a models.Audit
111 | err := database.MgoAudits.Find(context.Background(), bson.M{
112 | "uuid": id,
113 | }).One(&a)
114 | if err != nil {
115 | continue
116 | }
117 | audits[id] = a
118 | }
119 | return audits
120 | }
121 |
--------------------------------------------------------------------------------
/review/request/file.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | /*
4 | Define some request structures for file operations.
5 | */
6 |
7 | // UploadFile define the upload file request format
8 | type UploadFile struct {
9 | UserId string `json:"user_id"`
10 | FileName string `json:"file_name"`
11 | Type string `json:"type"`
12 | SourceProject string `json:"source_project"`
13 | Description string `json:"description"`
14 | Tags []string `json:"tags"`
15 | }
16 |
17 | // UpdateFile: define the struct for update a file version
18 | type UpdateFile struct {
19 | UserId string `json:"user_id"`
20 | BaseFile string `json:"base_file" bson:"base_file"`
21 | FileName string `json:"file_name"`
22 | Type string `json:"type"`
23 | Description string `json:"description"`
24 | Tags []string `json:"tags"`
25 | }
26 |
27 | // SearchFile define the search request format, todo
28 | type SearchFile struct {
29 | FileName string `json:"file_name"`
30 | Type string `json:"type"`
31 | Tags []string `json:"tags"`
32 | }
33 |
34 | // GetFileInfo: just using http-get with url params
35 | // DownloadFile: just using http-get with url params
36 |
--------------------------------------------------------------------------------
/review/request/user.go:
--------------------------------------------------------------------------------
1 | package request
2 |
3 | //UserLogin define the user login struct
4 | type UserLogin struct {
5 | Phone string `json:"phone"`
6 | Email string `json:"email"`
7 | Password string `json:"password"`
8 | }
9 |
10 | // UserRegister defines create user request format
11 | type UserRegister struct {
12 | Name string `json:"name"`
13 | Password string `json:"password"`
14 | Location string `json:"location"`
15 | Email string `json:"email"`
16 | Phone string `json:"phone"`
17 | Gender bool `json:"gender"`
18 | Degree string `json:"degree"`
19 | Position string `json:"position"`
20 | Employer string `json:"employer"`
21 | Major string `json:"major"`
22 | }
23 |
24 | // UserUpdatePassword define the update password req format 请求更新密码
25 | type UserUpdatePassword struct {
26 | ID string `json:"id"`
27 | OldPassword string `json:"old_password"`
28 | NewPassword string `json:"new_password"`
29 | }
30 |
31 | // UserUpdateInfo define the user info updating request format
32 | type UserUpdateInfo struct {
33 | ID string `json:"id"`
34 | Name string `json:"name"`
35 | Email string `json:"email"`
36 | Phone string `json:"phone"`
37 | Gender bool `json:"gender"`
38 | Location string `json:"location"`
39 | Degree string `json:"degree"`
40 | Position string `json:"position"`
41 | Employer string `json:"employer"`
42 | Major string `json:"major"`
43 | }
44 |
45 | // UserSearch define search users struct
46 | type UserSearch struct {
47 | Phone string `json:"phone"`
48 | Email string `json:"email"`
49 | Name string `json:"name"`
50 | Degree string `json:"degree"`
51 | Position string `json:"position"`
52 | Employer string `json:"employer"`
53 | Major string `json:"major"`
54 | }
55 |
56 | // GetUserInfo: just using http-get with url params
57 | // UserLogout: just using http-get with url params
58 |
--------------------------------------------------------------------------------
/review/response/code.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | var (
4 | SUCCESS = 1000 // operation exec successfully
5 |
6 | FAIL = 2000 // operation exec failed with default error
7 |
8 | // Database operations (mongodb)
9 | DatabaseDefaultError = 2001
10 | DatabaseInsertError = 2002
11 | DatabaseUpdateError = 2003
12 | DatabaseDeleteError = 2004
13 | DatabaseNoRecord = 2005
14 | DatabaseUniqueKeyDuplicate = 2006
15 |
16 | // user operations
17 | UserRegisterFail = 2100
18 | UserRegisterPasswordError = 2101
19 | UserLoginFail = 2102
20 | UserAuthError = 2103
21 | UserNotExist = 2104
22 | UserGenerateTokenError = 2105
23 | UserUpdatePasswordError = 2106
24 |
25 | // file operations
26 | FileUploadFail = 2200
27 | FileGetFileFail = 2201
28 | FileDownloadFileFail = 2202
29 |
30 | // project operations
31 | ProjectCreateFail = 2301
32 | ProjectNotExist = 2302
33 | ProjectGetInfoFail = 2303
34 | ProjectUpdateFail = 2304
35 |
36 | // project-assignment operations
37 | AssignmentCreateFail = 2310
38 | AssignmentUserGetFail = 2311
39 | AssignmentProjectGetFail = 2312
40 | AssignmentChangeFail = 2313
41 | AssignmentDeleteFail = 2314
42 | AssignConfirmFail = 2315
43 |
44 | // project-step operations
45 | StepCreateFail = 2320
46 | StepAddAttachmentsFail = 2321
47 | StepUpdateInfoFail = 2322
48 | StepChangeStatusFail = 2323
49 | StepGetInfoFail = 2324
50 | StepSetTimePointFail = 2325
51 | StepDeleteTimePointFail = 2326
52 | StepDeleteFail = 2327
53 | StepGetStatisticFail = 2328
54 |
55 | // project-submit operations
56 | SubmitGetInfoFail = 2330
57 | SubmitCreateFail = 2331
58 | SubmitUpdateFail = 2332
59 | SubmitWithdrawFail = 2333
60 | SubmitDeleteFail = 2334
61 |
62 | // project-audit operations
63 | AuditGetInfoFail = 2340
64 | AuditCreateFail = 2341
65 | AuditCorrectFail = 2342
66 | AuditDeleteFail = 2343
67 | )
68 |
--------------------------------------------------------------------------------
/review/response/default.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | type Default struct {
4 | OperationCode int `json:"operation_code"`
5 | Message string `json:"message"`
6 | Data interface{} `json:"data"`
7 | }
8 |
9 | func GenResponse(opCode int, message string, data interface{}) Default {
10 | return Default{
11 | OperationCode: opCode,
12 | Message: message,
13 | Data: data,
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/review/response/listquery.go:
--------------------------------------------------------------------------------
1 | package response
2 |
--------------------------------------------------------------------------------
/review/routers/router.go:
--------------------------------------------------------------------------------
1 | // @APIVersion 1.0.0
2 | // @Title OpenCT PQBS - api document
3 | // @Description beego has a very cool tools to autogenerate documents for your API
4 | // @Contact kkoogqw@hotmail.com
5 | // @TermsOfServiceUrl http://
6 | // @License Apache 2.0
7 | // @LicenseUrl http://www.apache.org/licenses/LICENSE-2.0.html
8 | package routers
9 |
10 | import (
11 | "review/controllers"
12 |
13 | beego "github.com/beego/beego/v2/server/web"
14 | )
15 |
16 | func init() {
17 | ns := beego.NewNamespace("/review",
18 | beego.NSNamespace("/user",
19 | beego.NSInclude(
20 | &controllers.UserController{},
21 | ),
22 | ),
23 | beego.NSNamespace("/file",
24 | beego.NSInclude(
25 | &controllers.FileController{},
26 | ),
27 | ),
28 | beego.NSNamespace("/proj",
29 | beego.NSInclude(
30 | &controllers.ProjectController{},
31 | ),
32 | ),
33 | beego.NSNamespace("/query",
34 | beego.NSInclude(
35 | &controllers.QueryController{},
36 | ),
37 | ),
38 | beego.NSNamespace("/noticer",
39 | beego.NSInclude(
40 | &controllers.NoticerController{},
41 | ),
42 | ),
43 | )
44 | beego.AddNamespace(ns)
45 | }
46 |
--------------------------------------------------------------------------------
/review/swagger.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/review/swagger.zip
--------------------------------------------------------------------------------
/review/swagger/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/review/swagger/favicon-16x16.png
--------------------------------------------------------------------------------
/review/swagger/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/review/swagger/favicon-32x32.png
--------------------------------------------------------------------------------
/review/swagger/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Swagger UI
7 |
8 |
9 |
10 |
11 |
30 |
31 |
32 |
33 |
34 |
67 |
68 |
69 |
70 |
71 |
72 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/review/swagger/oauth2-redirect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
54 |
--------------------------------------------------------------------------------
/review/swagger/swagger-ui-bundle.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAyTA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA0oJA;AAgwFA;AAyrGA;AA0lFA;AA4nFA;AA+9CA;AA+gDA;AAwrCA;AA60EA;;;;;AA6oCA;AAsyJA;;;;;;;;;;;;;;AA64EA;AA4mIA;AAquJA;AA2qHA;AA2mGA;AAiiEA;AAq4DA;AAg3DA;AAoPA;;;;;;AAk7FA;AA07FA;;;;;AAi8CA;AAgsFA;AAs2CA;AAglCA;AAu9CA;AAy8EA;AAsiCA;AA+yFA;;;;;;;;;AAgkDA;AA2zIA;AAu7FA;AAmrFA;AAu0EA","sourceRoot":""}
--------------------------------------------------------------------------------
/review/swagger/swagger-ui-standalone-preset.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA8QA;AAmvGA;AAuxFA;;;;;;AAocA;AAkvFA;AAu+CA;AAo+CA;AAgrCA;AAuyEA","sourceRoot":""}
--------------------------------------------------------------------------------
/review/swagger/swagger-ui.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui.css","sources":[],"mappings":"","sourceRoot":""}
--------------------------------------------------------------------------------
/review/swagger/swagger-ui.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA0yCA;AAoyHA;AAmyHA;AAykGA;AA+9BA;AA6iCA;AAojCA;AAu5BA","sourceRoot":""}
--------------------------------------------------------------------------------
/review/tests/default_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "path/filepath"
7 | _ "review/routers"
8 | "runtime"
9 | "testing"
10 |
11 | "github.com/beego/beego/v2/core/logs"
12 | beego "github.com/beego/beego/v2/server/web"
13 | . "github.com/smartystreets/goconvey/convey"
14 | )
15 |
16 | func init() {
17 | _, file, _, _ := runtime.Caller(0)
18 | apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
19 | beego.TestBeegoInit(apppath)
20 | }
21 |
22 | // TestGet is a sample to run an endpoint test
23 | func TestGet(t *testing.T) {
24 | r, _ := http.NewRequest("GET", "/v1/object", nil)
25 | w := httptest.NewRecorder()
26 | beego.BeeApp.Handlers.ServeHTTP(w, r)
27 |
28 | logs.Info("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String())
29 |
30 | Convey("Subject: Test Station Endpoint\n", t, func() {
31 | Convey("Status Code Should Be 200", func() {
32 | So(w.Code, ShouldEqual, 200)
33 | })
34 | Convey("The Result Should Not Be Empty", func() {
35 | So(w.Body.Len(), ShouldBeGreaterThan, 0)
36 | })
37 | })
38 | }
39 |
--------------------------------------------------------------------------------
/review/tests/file-test.http:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/review/tests/file-test.http
--------------------------------------------------------------------------------
/review/tests/user-test.http:
--------------------------------------------------------------------------------
1 | PUT http://127.0.0.1:9001/review/user/
2 | Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTY5ODA0LCJpYXQiOjE2MjkzNjUwMDQsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.AVd_2XAiSmjGN9pCuXN-jSC33Ps6qyvjPyaa1M7bdYk
3 | Content-Type: application/json
4 |
5 | {
6 | "id": "e59bdc40-e551-4236-9cf0-73e2df6a78cf",
7 | "degree": "本科",
8 | "email": "robot1@openct.com",
9 | "employer": "openct-community",
10 | "gender": true,
11 | "location": "china",
12 | "major": "program",
13 | "name": "robot1",
14 | "phone": "10000000001",
15 | "position": "developer"
16 | }
17 |
18 | ###
19 | DELETE http://127.0.0.1:9001/review/user/75ea985b-c9c8-43da-94d0-d3b22f461838
20 | Accept: application/json
21 |
22 |
23 | ###
24 | GET http://127.0.0.1:9001/review/user/logout
25 | Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiZTU5YmRjNDAtZTU1MS00MjM2LTljZjAtNzNlMmRmNmE3OGNmIiwiZXhwIjoxNjI5OTY5ODA0LCJpYXQiOjE2MjkzNjUwMDQsImlzcyI6InJvYm90MUBvcGVuY3QuY29tIn0.AVd_2XAiSmjGN9pCuXN-jSC33Ps6qyvjPyaa1M7bdYk
26 | Accept: application/json
27 |
28 | ###
29 | GET http://127.0.0.1:9001/review/user/38509279-4363-4fa4-b3b8-f7e8cf711690
30 | Accept: application/json
31 |
32 | ###
33 | PUT http://127.0.0.1:9001/review/user/password
34 | Content-Type: application/json
35 |
36 | {
37 | "id": "e59bdc40-e551-4236-9cf0-73e2df6a78cf",
38 | "new_password": "abcdef",
39 | "old_password": "123456"
40 | }
41 |
42 | ###
43 | POST http://127.0.0.1:9001/review/user/login
44 | Content-Type: application/json
45 |
46 | {
47 | "email": "testman-3@openct.com",
48 | "password": "123456"
49 | }
50 |
51 | ###
52 | POST http://127.0.0.1:9001/review/user
53 | Content-Type: application/json
54 |
55 | {
56 | "degree": "本科",
57 | "email": "testman-0@openct.com",
58 | "employer": "openct-community",
59 | "gender": true,
60 | "location": "china",
61 | "major": "program",
62 | "name": "test-man-0",
63 | "password": "123456",
64 | "phone": "11000000000",
65 | "position": "test-man"
66 | }
67 |
68 | ###
69 |
--------------------------------------------------------------------------------
/review/utils/crypto.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "crypto/sha256"
5 | "encoding/base64"
6 | )
7 |
8 | func GenSha256(str string) string {
9 | h := sha256.New()
10 | h.Write([]byte(str))
11 | return ConvertToBase64(h.Sum(nil))
12 | }
13 |
14 | func ConvertToBase64(str []byte) string {
15 | enc := base64.StdEncoding.EncodeToString(str)
16 | return enc
17 | }
18 |
--------------------------------------------------------------------------------
/review/utils/json.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "encoding/json"
5 | "review/logger"
6 | )
7 |
8 | func StructToJson(v interface{}) string {
9 | //data, err := json.MarshalIndent(v, "", " ")
10 | data, err := json.Marshal(v)
11 | if err != nil {
12 | logger.Recorder.Error("convert struct to json error: " + err.Error())
13 | }
14 | return string(data)
15 | }
16 |
17 | func JsonToStruct(data string, v interface{}) error {
18 | return json.Unmarshal([]byte(data), v)
19 | }
20 |
--------------------------------------------------------------------------------
/review/utils/mkdir.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "path/filepath"
7 | "time"
8 | )
9 |
10 | // CreateDateDir 根据当前日期来创建文件夹
11 | func CreateDateDir(Path string) string {
12 | t := time.Now()
13 | folderDate := fmt.Sprintf("%d-%d-%d", t.Year(), t.Month(), t.Day())
14 | folderPath := filepath.Join(Path, folderDate)
15 | if _, err := os.Stat(folderPath); os.IsNotExist(err) {
16 | // 必须分成两步:先创建文件夹、再修改权限
17 | os.MkdirAll(folderPath, os.ModePerm) //0777
18 | os.Chmod(folderPath, os.ModePerm)
19 | }
20 | return folderPath
21 | }
22 |
23 | // IsDirExists 判断所给路径文件/文件夹是否存在
24 | func IsDirExists(path string) bool {
25 | _, err := os.Stat(path) //os.Stat获取文件信息
26 | if err != nil {
27 | if os.IsExist(err) {
28 | return true
29 | }
30 | return false
31 | }
32 | return true
33 | }
34 |
35 | // IsDir 判断所给路径是否为文件夹
36 | func IsDir(path string) bool {
37 | s, err := os.Stat(path)
38 | if err != nil {
39 | return false
40 | }
41 | return s.IsDir()
42 | }
43 |
44 | // IsFile 判断所给路径是否为文件
45 | func IsFile(path string) bool {
46 | return !IsDir(path)
47 | }
48 |
--------------------------------------------------------------------------------
/review/utils/uuid.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import "github.com/google/uuid"
4 |
5 | /*
6 | 用于生成uuid使用, 这里使用V1(基于timestamp)和V4版本(基于随机数)
7 | */
8 |
9 | // GenUuidV1 generate the uuid version 1 (timestamp)
10 | func GenUuidV1() (string, error) {
11 | res, err := uuid.NewUUID()
12 | if err != nil {
13 | return "", err
14 | }
15 | return res.String(), nil
16 | }
17 |
18 | // GenUuidV4 generate the uuid version 4 (random number)
19 | func GenUuidV4() string {
20 | res := uuid.New()
21 | return res.String()
22 | }
23 |
--------------------------------------------------------------------------------
/warehouse/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/warehouse/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/warehouse/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/warehouse/.idea/warehouse.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/warehouse/conf/app.conf:
--------------------------------------------------------------------------------
1 | appname = question-warehouse
2 | httpaddr = localhost
3 | httpport = 9002
4 | runmode = dev
5 | autorender = false
6 | copyrequestbody = true
7 | EnableDocs = true
8 |
9 | include "mongo.conf"
10 | include "log.conf"
--------------------------------------------------------------------------------
/warehouse/conf/log.conf:
--------------------------------------------------------------------------------
1 | ; review module log
2 | logpath = log/
3 | logfile = qbank.log
4 | loglevel = full
--------------------------------------------------------------------------------
/warehouse/conf/mongo.conf:
--------------------------------------------------------------------------------
1 | ; mongo database config
2 | mongoaddr = localhost
3 | mongoport = 27017
4 | mongodb = openct_pqbs
5 | mongouser = openct
6 | mongopwd = 123456
7 |
8 | ; collections name define
9 | [mongo-collections]
10 | ; collections name define
11 | tempQuestions = "temp_questions"
12 | finalQuestions = "final_questions"
13 | tempTestPapers = "temp_test_papers"
14 | finalTestPapers = "final_test_papers"
--------------------------------------------------------------------------------
/warehouse/controllers/default.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "encoding/json"
5 | "warehouse/logger"
6 | )
7 |
8 | func unmarshalBody(body []byte, obj interface{}) error {
9 | // marshal json body
10 | if err := json.Unmarshal(body, obj); err != nil {
11 | logger.Recorder.Warn("[JSON] " + err.Error())
12 | return err
13 | }
14 | return nil
15 | }
16 |
--------------------------------------------------------------------------------
/warehouse/controllers/user.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "encoding/json"
5 | "warehouse/models"
6 |
7 | beego "github.com/beego/beego/v2/server/web"
8 | )
9 |
10 | // Operations about Users
11 | type UserController struct {
12 | beego.Controller
13 | }
14 |
15 | // @Title CreateUser
16 | // @Description create users
17 | // @Param body body models.User true "body for user content"
18 | // @Success 200 {int} models.User.Id
19 | // @Failure 403 body is empty
20 | // @router / [post]
21 | func (u *UserController) Post() {
22 | var user models.User
23 | json.Unmarshal(u.Ctx.Input.RequestBody, &user)
24 | uid := models.AddUser(user)
25 | u.Data["json"] = map[string]string{"uid": uid}
26 | u.ServeJSON()
27 | }
28 |
29 | // @Title GetAll
30 | // @Description get all Users
31 | // @Success 200 {object} models.User
32 | // @router / [get]
33 | func (u *UserController) GetAll() {
34 | users := models.GetAllUsers()
35 | u.Data["json"] = users
36 | u.ServeJSON()
37 | }
38 |
39 | // @Title Get
40 | // @Description get user by uid
41 | // @Param uid path string true "The key for staticblock"
42 | // @Success 200 {object} models.User
43 | // @Failure 403 :uid is empty
44 | // @router /:uid [get]
45 | func (u *UserController) Get() {
46 | uid := u.GetString(":uid")
47 | if uid != "" {
48 | user, err := models.GetUser(uid)
49 | if err != nil {
50 | u.Data["json"] = err.Error()
51 | } else {
52 | u.Data["json"] = user
53 | }
54 | }
55 | u.ServeJSON()
56 | }
57 |
58 | // @Title Update
59 | // @Description update the user
60 | // @Param uid path string true "The uid you want to update"
61 | // @Param body body models.User true "body for user content"
62 | // @Success 200 {object} models.User
63 | // @Failure 403 :uid is not int
64 | // @router /:uid [put]
65 | func (u *UserController) Put() {
66 | uid := u.GetString(":uid")
67 | if uid != "" {
68 | var user models.User
69 | json.Unmarshal(u.Ctx.Input.RequestBody, &user)
70 | uu, err := models.UpdateUser(uid, &user)
71 | if err != nil {
72 | u.Data["json"] = err.Error()
73 | } else {
74 | u.Data["json"] = uu
75 | }
76 | }
77 | u.ServeJSON()
78 | }
79 |
80 | // @Title Delete
81 | // @Description delete the user
82 | // @Param uid path string true "The uid you want to delete"
83 | // @Success 200 {string} delete success!
84 | // @Failure 403 uid is empty
85 | // @router /:uid [delete]
86 | func (u *UserController) Delete() {
87 | uid := u.GetString(":uid")
88 | models.DeleteUser(uid)
89 | u.Data["json"] = "delete success!"
90 | u.ServeJSON()
91 | }
92 |
93 | // @Title Login
94 | // @Description Logs user into the system
95 | // @Param username query string true "The username for login"
96 | // @Param password query string true "The password for login"
97 | // @Success 200 {string} login success
98 | // @Failure 403 user not exist
99 | // @router /login [get]
100 | func (u *UserController) Login() {
101 | username := u.GetString("username")
102 | password := u.GetString("password")
103 | if models.Login(username, password) {
104 | u.Data["json"] = "login success"
105 | } else {
106 | u.Data["json"] = "user not exist"
107 | }
108 | u.ServeJSON()
109 | }
110 |
111 | // @Title logout
112 | // @Description Logs out current logged in user session
113 | // @Success 200 {string} logout success
114 | // @router /logout [get]
115 | func (u *UserController) Logout() {
116 | u.Data["json"] = "logout success"
117 | u.ServeJSON()
118 | }
119 |
--------------------------------------------------------------------------------
/warehouse/go.mod:
--------------------------------------------------------------------------------
1 | module warehouse
2 |
3 | go 1.15
4 |
5 | require github.com/beego/beego/v2 v2.0.1
6 |
7 | require (
8 | github.com/astaxie/beego v1.12.3 // indirect
9 | github.com/golang/protobuf v1.5.2 // indirect
10 | github.com/google/uuid v1.3.0
11 | github.com/mitchellh/mapstructure v1.4.1 // indirect
12 | github.com/qiniu/qmgo v1.0.3
13 | github.com/smartystreets/goconvey v1.6.4
14 | github.com/stretchr/testify v1.7.0 // indirect
15 | go.mongodb.org/mongo-driver v1.7.2
16 | golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect
17 | golang.org/x/text v0.3.7 // indirect
18 | golang.org/x/tools v0.1.2 // indirect
19 | gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
20 | gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
21 | gopkg.in/yaml.v2 v2.4.0 // indirect
22 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
23 | )
24 |
--------------------------------------------------------------------------------
/warehouse/logger/logger.go:
--------------------------------------------------------------------------------
1 | package logger
2 |
3 | import (
4 | "fmt"
5 | "github.com/beego/beego/v2/core/logs"
6 | beego "github.com/beego/beego/v2/server/web"
7 | )
8 |
9 | var Recorder *logs.BeeLogger
10 |
11 | func init() {
12 | // 设置日志生成器
13 | log := logs.NewLogger()
14 | // 读取配置
15 | logPath, err := beego.AppConfig.String("logpath")
16 | if err != nil {
17 | fmt.Println("load log path config error.")
18 | }
19 | logFile, err := beego.AppConfig.String("logfile")
20 | if err != nil {
21 | fmt.Println("load log filename config error.")
22 | }
23 | // todo: more options in .conf
24 | logConfig := fmt.Sprintf(
25 | `{"filename":"%s","level":7,"daily":true,"maxdays":10,"color":true}`,
26 | logPath+logFile,
27 | )
28 | log.SetLogger(
29 | logs.AdapterFile,
30 | logConfig,
31 | )
32 | log.SetLogger(logs.AdapterConsole)
33 | log.EnableFuncCallDepth(true)
34 | log.SetLevel(logs.LevelDebug)
35 |
36 | Recorder = log
37 | }
38 |
--------------------------------------------------------------------------------
/warehouse/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | beego "github.com/beego/beego/v2/server/web"
5 | "github.com/beego/beego/v2/server/web/filter/cors"
6 | _ "warehouse/logger"
7 | _ "warehouse/models"
8 | _ "warehouse/routers"
9 | )
10 |
11 | func main() {
12 | if beego.BConfig.RunMode == "dev" {
13 | beego.BConfig.WebConfig.DirectoryIndex = true
14 | beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
15 | }
16 |
17 | // insert the filter for cross-domain
18 | beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
19 | //AllowAllOrigins: true,
20 | AllowMethods: []string{"*"},
21 | //AllowHeaders: []string{"*"},
22 | AllowHeaders: []string{"Origin", "Authorization", "Access-Control-Allow-Origin", "content-type", "token"},
23 | ExposeHeaders: []string{"Content-Length", "Access-Control-Allow-Origin"},
24 | AllowCredentials: true,
25 | AllowOrigins: []string{"http://49.232.73.36:8085", "http://localhost:*", "http://127.0.0.1:*"},
26 | }))
27 | beego.Run()
28 | }
29 |
--------------------------------------------------------------------------------
/warehouse/models/query.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "context"
5 | "gopkg.in/mgo.v2/bson"
6 | "warehouse/database"
7 | "warehouse/logger"
8 | )
9 |
10 | // 进行批量查询的方法
11 | func QueryTempQuestions(idList []string) map[string]TempQuestion {
12 | questionsMap := make(map[string]TempQuestion)
13 | for _, id := range idList {
14 | var question TempQuestion
15 | err := database.MgoTempQuestions.Find(
16 | context.Background(),
17 | bson.M{
18 | "uuid": id,
19 | },
20 | ).One(&question)
21 | if err != nil {
22 | logger.Recorder.Error("get temp-question error: [" + id + "]" + err.Error())
23 | continue
24 | }
25 | questionsMap[id] = question
26 | }
27 | return questionsMap
28 | }
29 |
30 | func QueryFinalQuestions(idList []string) map[string]FinalQuestion {
31 | questionsMap := make(map[string]FinalQuestion)
32 | for _, id := range idList {
33 | var question FinalQuestion
34 | err := database.MgoFinalQuestions.Find(
35 | context.Background(),
36 | bson.M{
37 | "uuid": id,
38 | },
39 | ).One(&question)
40 | if err != nil {
41 | logger.Recorder.Error("get final-question error: [" + id + "]" + err.Error())
42 | continue
43 | }
44 | questionsMap[id] = question
45 | }
46 | return questionsMap
47 | }
48 |
49 | func QueryTempTestpaper(idList []string) map[string]TempTestpaper {
50 | testpaperMap := make(map[string]TempTestpaper)
51 | for _, id := range idList {
52 | var testPaper TempTestpaper
53 | err := database.MgoTempTestPaper.Find(
54 | context.Background(),
55 | bson.M{
56 | "uuid": id,
57 | },
58 | ).One(&testPaper)
59 | if err != nil {
60 | logger.Recorder.Error("get final-test-paper error: [" + id + "]" + err.Error())
61 | continue
62 | }
63 | testpaperMap[id] = testPaper
64 | }
65 | return testpaperMap
66 | }
67 |
68 | func QueryFinalTestpaper(idList []string) map[string]FinalTestpaper {
69 | testpaperMap := make(map[string]FinalTestpaper)
70 | for _, id := range idList {
71 | var testPaper FinalTestpaper
72 | err := database.MgoFinalTestPaper.Find(
73 | context.Background(),
74 | bson.M{
75 | "uuid": id,
76 | },
77 | ).One(&testPaper)
78 | if err != nil {
79 | logger.Recorder.Error("get final-test-paper error: [" + id + "]" + err.Error())
80 | continue
81 | }
82 | testpaperMap[id] = testPaper
83 | }
84 | return testpaperMap
85 | }
86 |
--------------------------------------------------------------------------------
/warehouse/models/request.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type QueryListRequest struct {
4 | IdList []string `json:"id_list"`
5 | }
6 |
7 | // Questions
8 | type NewQuestionRequest struct {
9 | SourceProject string `json:"source_project"`
10 | Author string `json:"author"`
11 | Info QuestionInfo `json:"info"`
12 | BasicProps QuestionBasicProps `json:"basic_props"`
13 | SpecProps QuestionSpecProps `json:"spec_props"`
14 | ExtraProps QuestionExtraProps `json:"extra_props"`
15 | AdvancedProps QuestionAdvancedProps `json:"advanced_props"`
16 | ApplyRecord QuestionApplyRecord `json:"apply_record"`
17 | }
18 |
19 | type UpdateQuestionRequest struct {
20 | BaseQuestion string `json:"base_question"`
21 | Author string `json:"author"`
22 | NewInfo QuestionInfo `json:"new_info"`
23 | NewBasicProps QuestionBasicProps `json:"new_basic_props"`
24 | NewSpecProps QuestionSpecProps `json:"new_spec_props"`
25 | NewExtraProps QuestionExtraProps `json:"new_extra_props"`
26 | NewAdvancedProps QuestionAdvancedProps `json:"new_advanced_props"`
27 | NewApplyRecord QuestionApplyRecord `json:"new_apply_record"`
28 | }
29 |
30 | type AddQuestionCommentRequest struct {
31 | QuestionId string `json:"question_id"`
32 | Comment string `json:"comment"`
33 | Author string `json:"'author'"`
34 | }
35 |
36 | // Testpaper
37 | type NewTestpaperRequest struct {
38 | SourceProject string `json:"source_project"`
39 | Author string `json:"author"`
40 | Title string `json:"title"`
41 | Info []TestpaperPart `json:"info"`
42 | Props TestpaperProps `json:"props"`
43 | }
44 |
45 | type UpdateTestpaperRequest struct {
46 | BaseTestpaper string `json:"base_testpaper"`
47 | Author string `json:"author"`
48 | NewTitle string `json:"new_title"`
49 | NewInfo []TestpaperPart `json:"new_info"`
50 | NewProps TestpaperProps `json:"new_props"`
51 | }
52 |
53 | type AddTestpaperCommentRequest struct {
54 | TestpaperId string `json:"testpaper_id"`
55 | Comment string `json:"comment"`
56 | Author string `json:"author"`
57 | }
58 |
--------------------------------------------------------------------------------
/warehouse/models/testpaper.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "github.com/qiniu/qmgo/field"
5 | "time"
6 | )
7 |
8 | type QuestionItem struct {
9 | QuestionId string `json:"question_id" bson:"question_id"`
10 | Score int `json:"score" bson:"score"`
11 | Comment string `json:"comment" bson:"comment"`
12 | }
13 |
14 | type TestpaperPart struct {
15 | Title string `json:"title" bson:"title"`
16 | Description string `json:"description" bson:"description"`
17 | QuestionList []QuestionItem `json:"question_list" bson:"question_list"`
18 | Score int `json:"score" bson:"score"`
19 | }
20 |
21 | type TestpaperProps struct {
22 | GradeRange []string `json:"grade_range" bson:"grade_range"`
23 | Subjects []string `json:"subjects" bson:"subjects"`
24 | Difficulty string `json:"difficulty" bson:"difficulty"`
25 | TimeLimit string `json:"time_limit" bson:"time_limit"`
26 | }
27 |
28 | type TestpaperComment struct {
29 | TimePoint time.Time `json:"time_point" bson:"time_point"`
30 | Comment string `json:"comment" bson:"comment"`
31 | Author string `json:"author" bson:"author"`
32 | }
33 |
34 | type TempTestpaper struct {
35 | field.DefaultField `bson:",inline"`
36 | Uuid string `json:"uuid" bson:"uuid"`
37 | IsRoot bool `json:"is_root" bson:"is_root"`
38 | Base string `json:"base" bson:"base"`
39 | SourceProject string `json:"source_project" bson:"source_project"`
40 | Author string `json:"author" bson:"author"`
41 | Title string `json:"title" bson:"title"`
42 | Info []TestpaperPart `json:"info" bson:"info"`
43 | Props TestpaperProps `json:"props" bson:"props"`
44 | CommentRecord []TestpaperComment `json:"comment_record" bson:"comment_record"`
45 | }
46 |
47 | type FinalTestpaper struct {
48 | field.DefaultField `bson:",inline"`
49 | Uuid string `json:"uuid" bson:"uuid"`
50 | SourceProject string `json:"source_project" bson:"source_project"`
51 | Author string `json:"author" bson:"author"`
52 | Title string `json:"title" bson:"title"`
53 | Info []TestpaperPart `json:"info" bson:"info"`
54 | Props TestpaperProps `json:"props" bson:"props"`
55 | }
56 |
--------------------------------------------------------------------------------
/warehouse/models/user.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "errors"
5 | "strconv"
6 | "time"
7 | )
8 |
9 | var (
10 | UserList map[string]*User
11 | )
12 |
13 | func init() {
14 | UserList = make(map[string]*User)
15 | u := User{"user_11111", "astaxie", "11111", Profile{"male", 20, "Singapore", "astaxie@gmail.com"}}
16 | UserList["user_11111"] = &u
17 | }
18 |
19 | type User struct {
20 | Id string
21 | Username string
22 | Password string
23 | Profile Profile
24 | }
25 |
26 | type Profile struct {
27 | Gender string
28 | Age int
29 | Address string
30 | Email string
31 | }
32 |
33 | func AddUser(u User) string {
34 | u.Id = "user_" + strconv.FormatInt(time.Now().UnixNano(), 10)
35 | UserList[u.Id] = &u
36 | return u.Id
37 | }
38 |
39 | func GetUser(uid string) (u *User, err error) {
40 | if u, ok := UserList[uid]; ok {
41 | return u, nil
42 | }
43 | return nil, errors.New("User not exists")
44 | }
45 |
46 | func GetAllUsers() map[string]*User {
47 | return UserList
48 | }
49 |
50 | func UpdateUser(uid string, uu *User) (a *User, err error) {
51 | if u, ok := UserList[uid]; ok {
52 | if uu.Username != "" {
53 | u.Username = uu.Username
54 | }
55 | if uu.Password != "" {
56 | u.Password = uu.Password
57 | }
58 | if uu.Profile.Age != 0 {
59 | u.Profile.Age = uu.Profile.Age
60 | }
61 | if uu.Profile.Address != "" {
62 | u.Profile.Address = uu.Profile.Address
63 | }
64 | if uu.Profile.Gender != "" {
65 | u.Profile.Gender = uu.Profile.Gender
66 | }
67 | if uu.Profile.Email != "" {
68 | u.Profile.Email = uu.Profile.Email
69 | }
70 | return u, nil
71 | }
72 | return nil, errors.New("User Not Exist")
73 | }
74 |
75 | func Login(username, password string) bool {
76 | for _, u := range UserList {
77 | if u.Username == username && u.Password == password {
78 | return true
79 | }
80 | }
81 | return false
82 | }
83 |
84 | func DeleteUser(uid string) {
85 | delete(UserList, uid)
86 | }
87 |
--------------------------------------------------------------------------------
/warehouse/routers/router.go:
--------------------------------------------------------------------------------
1 | // @APIVersion 1.0.0
2 | // @Title OpenCT Question-warehouse API
3 | // @Description beego has a very cool tools to autogenerate documents for your API
4 | // @Contact kkoogqw@hotmial.com
5 | // @TermsOfServiceUrl http://beego.me/
6 | // @License Apache 2.0
7 | // @LicenseUrl http://www.apache.org/licenses/LICENSE-2.0.html
8 | package routers
9 |
10 | import (
11 | "warehouse/controllers"
12 |
13 | beego "github.com/beego/beego/v2/server/web"
14 | )
15 |
16 | func init() {
17 | ns := beego.NewNamespace("/qbank",
18 | beego.NSNamespace("/question",
19 | beego.NSInclude(
20 | &controllers.QuestionController{},
21 | ),
22 | ),
23 | beego.NSNamespace("/testpaper",
24 | beego.NSInclude(
25 | &controllers.TestpaperController{},
26 | ),
27 | ),
28 | beego.NSNamespace("/query",
29 | beego.NSInclude(
30 | &controllers.QueryController{},
31 | ),
32 | ),
33 | )
34 | beego.AddNamespace(ns)
35 | }
36 |
--------------------------------------------------------------------------------
/warehouse/swagger.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/warehouse/swagger.zip
--------------------------------------------------------------------------------
/warehouse/swagger/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/warehouse/swagger/favicon-16x16.png
--------------------------------------------------------------------------------
/warehouse/swagger/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/warehouse/swagger/favicon-32x32.png
--------------------------------------------------------------------------------
/warehouse/swagger/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Swagger UI
7 |
8 |
9 |
10 |
11 |
30 |
31 |
32 |
33 |
34 |
67 |
68 |
69 |
70 |
71 |
72 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/warehouse/swagger/oauth2-redirect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
54 |
--------------------------------------------------------------------------------
/warehouse/swagger/swagger-ui-bundle.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AAyTA;;;;;;AAoIA;AAi7FA;AAmtCA;AAi0IA;AA0oJA;AAgwFA;AAyrGA;AA0lFA;AA4nFA;AA+9CA;AA+gDA;AAwrCA;AA60EA;;;;;AA6oCA;AAsyJA;;;;;;;;;;;;;;AA64EA;AA4mIA;AAquJA;AA2qHA;AA2mGA;AAiiEA;AAq4DA;AAg3DA;AAoPA;;;;;;AAk7FA;AA07FA;;;;;AAi8CA;AAgsFA;AAs2CA;AAglCA;AAu9CA;AAy8EA;AAsiCA;AA+yFA;;;;;;;;;AAgkDA;AA2zIA;AAu7FA;AAmrFA;AAu0EA","sourceRoot":""}
--------------------------------------------------------------------------------
/warehouse/swagger/swagger-ui-standalone-preset.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA8QA;AAmvGA;AAuxFA;;;;;;AAocA;AAkvFA;AAu+CA;AAo+CA;AAgrCA;AAuyEA","sourceRoot":""}
--------------------------------------------------------------------------------
/warehouse/swagger/swagger-ui.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui.css","sources":[],"mappings":"","sourceRoot":""}
--------------------------------------------------------------------------------
/warehouse/swagger/swagger-ui.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA0yCA;AAoyHA;AAmyHA;AAykGA;AA+9BA;AA6iCA;AAojCA;AAu5BA","sourceRoot":""}
--------------------------------------------------------------------------------
/warehouse/tests/default_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "net/http"
5 | "net/http/httptest"
6 | "path/filepath"
7 | "runtime"
8 | "testing"
9 | _ "warehouse/routers"
10 |
11 | "github.com/beego/beego/v2/core/logs"
12 | beego "github.com/beego/beego/v2/server/web"
13 | . "github.com/smartystreets/goconvey/convey"
14 | )
15 |
16 | func init() {
17 | _, file, _, _ := runtime.Caller(0)
18 | apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
19 | beego.TestBeegoInit(apppath)
20 | }
21 |
22 | // TestGet is a sample to run an endpoint test
23 | func TestGet(t *testing.T) {
24 | r, _ := http.NewRequest("GET", "/v1/object", nil)
25 | w := httptest.NewRecorder()
26 | beego.BeeApp.Handlers.ServeHTTP(w, r)
27 |
28 | logs.Info("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String())
29 |
30 | Convey("Subject: Test Station Endpoint\n", t, func() {
31 | Convey("Status Code Should Be 200", func() {
32 | So(w.Code, ShouldEqual, 200)
33 | })
34 | Convey("The Result Should Not Be Empty", func() {
35 | So(w.Body.Len(), ShouldBeGreaterThan, 0)
36 | })
37 | })
38 | }
39 |
--------------------------------------------------------------------------------
/warehouse/utils/uuid.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import "github.com/google/uuid"
4 |
5 | /*
6 | 用于生成uuid使用, 这里使用V1(基于timestamp)和V4版本(基于随机数)
7 | */
8 |
9 | // GenUuidV1 generate the uuid version 1 (timestamp)
10 | func GenUuidV1() (string, error) {
11 | res, err := uuid.NewUUID()
12 | if err != nil {
13 | return "", err
14 | }
15 | return res.String(), nil
16 | }
17 |
18 | // GenUuidV4 generate the uuid version 4 (random number)
19 | func GenUuidV4() string {
20 | res := uuid.New()
21 | return res.String()
22 | }
23 |
--------------------------------------------------------------------------------
/web/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 |
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/web/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `yarn start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `yarn test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `yarn build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `yarn eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `yarn build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/web/build/asset-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": {
3 | "main.css": "./static/css/main.28dd778d.chunk.css",
4 | "main.js": "./static/js/main.f8299ca7.chunk.js",
5 | "main.js.map": "./static/js/main.f8299ca7.chunk.js.map",
6 | "runtime-main.js": "./static/js/runtime-main.3b3646ce.js",
7 | "runtime-main.js.map": "./static/js/runtime-main.3b3646ce.js.map",
8 | "static/css/2.e4902758.chunk.css": "./static/css/2.e4902758.chunk.css",
9 | "static/js/2.75a36cd2.chunk.js": "./static/js/2.75a36cd2.chunk.js",
10 | "static/js/2.75a36cd2.chunk.js.map": "./static/js/2.75a36cd2.chunk.js.map",
11 | "index.html": "./index.html",
12 | "static/css/2.e4902758.chunk.css.map": "./static/css/2.e4902758.chunk.css.map",
13 | "static/css/main.28dd778d.chunk.css.map": "./static/css/main.28dd778d.chunk.css.map",
14 | "static/js/2.75a36cd2.chunk.js.LICENSE.txt": "./static/js/2.75a36cd2.chunk.js.LICENSE.txt",
15 | "static/media/Rockets.bcd94bd9.png": "./static/media/Rockets.bcd94bd9.png",
16 | "static/media/index.less": "./static/media/login_background.d1cc80fb.png",
17 | "static/media/proposition-paper-icon.2d177c41.png": "./static/media/proposition-paper-icon.2d177c41.png"
18 | },
19 | "entrypoints": [
20 | "static/js/runtime-main.3b3646ce.js",
21 | "static/css/2.e4902758.chunk.css",
22 | "static/js/2.75a36cd2.chunk.js",
23 | "static/css/main.28dd778d.chunk.css",
24 | "static/js/main.f8299ca7.chunk.js"
25 | ]
26 | }
--------------------------------------------------------------------------------
/web/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/build/favicon.ico
--------------------------------------------------------------------------------
/web/build/index.html:
--------------------------------------------------------------------------------
1 | React App
--------------------------------------------------------------------------------
/web/build/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/build/logo192.png
--------------------------------------------------------------------------------
/web/build/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/build/logo512.png
--------------------------------------------------------------------------------
/web/build/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/web/build/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/web/build/static/js/2.75a36cd2.chunk.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*
2 | object-assign
3 | (c) Sindre Sorhus
4 | @license MIT
5 | */
6 |
7 | /*!
8 | Copyright (c) 2018 Jed Watson.
9 | Licensed under the MIT License (MIT), see
10 | http://jedwatson.github.io/classnames
11 | */
12 |
13 | /*!@license
14 | * UAParser.js v0.7.28
15 | * Lightweight JavaScript-based User-Agent string parser
16 | * https://github.com/faisalman/ua-parser-js
17 | *
18 | * Copyright © 2012-2021 Faisal Salman
19 | * Licensed under MIT License
20 | */
21 |
22 | /** @license React v0.20.2
23 | * scheduler.production.min.js
24 | *
25 | * Copyright (c) Facebook, Inc. and its affiliates.
26 | *
27 | * This source code is licensed under the MIT license found in the
28 | * LICENSE file in the root directory of this source tree.
29 | */
30 |
31 | /** @license React v16.13.1
32 | * react-is.production.min.js
33 | *
34 | * Copyright (c) Facebook, Inc. and its affiliates.
35 | *
36 | * This source code is licensed under the MIT license found in the
37 | * LICENSE file in the root directory of this source tree.
38 | */
39 |
40 | /** @license React v17.0.2
41 | * react-dom-server.browser.production.min.js
42 | *
43 | * Copyright (c) Facebook, Inc. and its affiliates.
44 | *
45 | * This source code is licensed under the MIT license found in the
46 | * LICENSE file in the root directory of this source tree.
47 | */
48 |
49 | /** @license React v17.0.2
50 | * react-dom.production.min.js
51 | *
52 | * Copyright (c) Facebook, Inc. and its affiliates.
53 | *
54 | * This source code is licensed under the MIT license found in the
55 | * LICENSE file in the root directory of this source tree.
56 | */
57 |
58 | /** @license React v17.0.2
59 | * react-jsx-runtime.production.min.js
60 | *
61 | * Copyright (c) Facebook, Inc. and its affiliates.
62 | *
63 | * This source code is licensed under the MIT license found in the
64 | * LICENSE file in the root directory of this source tree.
65 | */
66 |
67 | /** @license React v17.0.2
68 | * react.production.min.js
69 | *
70 | * Copyright (c) Facebook, Inc. and its affiliates.
71 | *
72 | * This source code is licensed under the MIT license found in the
73 | * LICENSE file in the root directory of this source tree.
74 | */
75 |
76 | //! moment.js
77 |
--------------------------------------------------------------------------------
/web/build/static/js/runtime-main.3b3646ce.js:
--------------------------------------------------------------------------------
1 | !function(e){function t(t){for(var n,l,i=t[0],f=t[1],a=t[2],p=0,s=[];p0.2%",
43 | "not dead",
44 | "not op_mini all"
45 | ],
46 | "development": [
47 | "last 1 chrome version",
48 | "last 1 firefox version",
49 | "last 1 safari version"
50 | ]
51 | },
52 | "homepage": "."
53 | }
54 |
--------------------------------------------------------------------------------
/web/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/public/favicon.ico
--------------------------------------------------------------------------------
/web/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/web/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/public/logo192.png
--------------------------------------------------------------------------------
/web/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/public/logo512.png
--------------------------------------------------------------------------------
/web/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/web/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/web/src/App.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-07-31 16:42:56
4 | * @LastEditTime: 2021-08-14 04:24:11
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web-client\src\App.js
8 | */
9 | import './App.less';
10 | import React, { Component } from 'react'
11 | import {Switch,Route,Redirect,HashRouter as Router} from 'react-router-dom'
12 | import Login from './views/Login'
13 | import Home from './views/Home'
14 | import NotFound from './views/errors/404'
15 | import Forbid from './views/errors/402'
16 |
17 | export default class App extends Component {
18 | getRemSize = ()=>{
19 | let whdef = 100/1920
20 | let wW = window.innerWidth
21 | let rem = wW * whdef
22 | document.documentElement.style.fontSize = rem + 'px'
23 | }
24 |
25 | componentDidMount = ()=>{
26 | window.resize = ()=>{
27 | this.getRemSize()
28 | }
29 | this.getRemSize()
30 | }
31 |
32 | render() {
33 | return (
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | )
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/web/src/App.less:
--------------------------------------------------------------------------------
1 | ::-webkit-scrollbar {
2 | width: 0 !important;
3 | }
4 | ::-webkit-scrollbar {
5 | width: 0 !important;height: 0;
6 | }
7 |
--------------------------------------------------------------------------------
/web/src/asset/images/Cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/Cloud.png
--------------------------------------------------------------------------------
/web/src/asset/images/Crying_face.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/Crying_face.png
--------------------------------------------------------------------------------
/web/src/asset/images/Flu_expression.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/Flu_expression.png
--------------------------------------------------------------------------------
/web/src/asset/images/Rockets.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/Rockets.png
--------------------------------------------------------------------------------
/web/src/asset/images/Unhapply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/Unhapply.png
--------------------------------------------------------------------------------
/web/src/asset/images/login_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/login_background.png
--------------------------------------------------------------------------------
/web/src/asset/images/openct_logo_1082x328.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/openct_logo_1082x328.png
--------------------------------------------------------------------------------
/web/src/asset/images/proposition-paper-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/asset/images/proposition-paper-icon.png
--------------------------------------------------------------------------------
/web/src/components/BuildTeam/index.less:
--------------------------------------------------------------------------------
1 | [data-component=build-team-page]{
2 | width: 100%;
3 | min-height: 6rem;
4 | background-color: white;
5 | .member-list{
6 | width: 100%;
7 | box-sizing: border-box;
8 | padding: 0px .2rem;
9 | }
10 | }
--------------------------------------------------------------------------------
/web/src/components/CalendarButton/index.less:
--------------------------------------------------------------------------------
1 | [data-component=calendar-button-box]{
2 | position: relative;
3 | width: max-content;
4 | height: max-content;
5 | > .calendar-box{
6 | width: auto;
7 | max-height: 0;
8 | overflow: hidden;
9 | transition: all .2s;
10 | position: absolute;
11 | background-color: white;
12 | filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
13 | top: .34rem;
14 | left: 50%;
15 | transform: translateX(-50%);
16 | z-index: 600;
17 | .ant-picker-calendar-date-value,th{
18 | font-size: .14rem;
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/web/src/components/ChangeTags/index.less:
--------------------------------------------------------------------------------
1 | .site-tag-plus {
2 | background: #fff;
3 | border-style: dashed;
4 | }
5 |
6 | .edit-tag {
7 | user-select: none;
8 | }
9 |
10 | .tag-input {
11 | width: 78px;
12 | margin-right: 8px;
13 | vertical-align: top;
14 | }
--------------------------------------------------------------------------------
/web/src/components/ChoiceQuestionEditer/index.less:
--------------------------------------------------------------------------------
1 | [data-component=choice-question-editer]{
2 | width: 100%;
3 | height: auto;
4 | .question-params{
5 | > .title{
6 | width: 100%;
7 | height: .41rem;
8 | background-color: #EEEEEE;
9 | line-height: .41rem;
10 | box-sizing: border-box;
11 | padding-left: .1rem;
12 | > span{
13 | font-size: .14rem;
14 | color: #000000;
15 |
16 | }
17 | }
18 | > .param-item{
19 | width: 100%;
20 | height: .32rem;
21 | .label{
22 | box-sizing: border-box;
23 | padding-left: .1rem;
24 | line-height: .32rem;
25 | > span{
26 | font-size: .14rem;
27 | color: #000000;
28 | }
29 | }
30 | .value{
31 | > .ant-select{
32 | width: 100%;
33 | }
34 | > .tag-list{
35 | width: 100%;
36 | height: 100%;
37 | display: flex;
38 | align-items: center;
39 | }
40 | }
41 | }
42 | }
43 | .question-complete-box{
44 | width: 100%;
45 | margin-top: .77rem;
46 | margin-bottom: .5rem;
47 | }
48 | }
--------------------------------------------------------------------------------
/web/src/components/CompletionStatus/index.less:
--------------------------------------------------------------------------------
1 | [data-component=completion-status-box]{
2 | width: 100%;
3 | display: flex;
4 | justify-content: space-between;
5 | box-sizing: border-box;
6 | padding-left: 0.47rem;
7 | > .left-box{
8 | > .title{
9 | height: .24rem;
10 | line-height: .24rem;
11 | margin-bottom: .08rem;
12 | > span{
13 | font-size: .14rem;
14 | color: #8C8C8C;
15 | }
16 | }
17 | > .value-list{
18 | .ant-statistic-title{
19 | font-size: .14rem;
20 | color: rgba(0, 0, 0, 0.45);
21 | }
22 | .ant-statistic-content-value-int,.ant-statistic-content-suffix{
23 | font-size: .26rem;
24 | color: rgba(0, 0, 0, 0.85);
25 | }
26 | }
27 | }
28 | > .right-box{
29 | .statistic-item-title{
30 | font-size: .14rem;
31 | color: #000000D9;
32 | line-height: .22rem;
33 | box-sizing: border-box;
34 | padding-left: .14rem;
35 | position: relative;
36 | > .circle{
37 | width: .06rem;
38 | height: .06rem;
39 | position: absolute;
40 | left: 0;
41 | top: 50%;
42 | transform: translateY(-50%);
43 | border-radius: 50%;
44 | }
45 | }
46 | .ant-statistic-content-value-int,.ant-statistic-content-suffix{
47 | font-size: .26rem;
48 | color: rgba(0, 0, 0, 0.85);
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/web/src/components/DataTable/index.less:
--------------------------------------------------------------------------------
1 | [data-component=data-table-box]{
2 | width: 100%;
3 | height: calc(100% - .38rem);
4 | box-sizing: border-box;
5 | padding: 0rem .25rem 0rem .4rem;
6 | position: relative;
7 | .ant-table-thead,.ant-table-row{
8 | height: .58rem;
9 | }
10 | .ant-table-cell{
11 | font-size: .14rem;
12 | }
13 | > .footer{
14 | width: 100%;
15 | height: .40rem;
16 | display: flex;
17 | align-items: center;
18 | position: absolute;
19 | bottom: 0;
20 | left: 0;
21 | box-sizing: border-box;
22 | padding-left: .4rem;
23 | }
24 | }
--------------------------------------------------------------------------------
/web/src/components/DifficultyBox/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import './index.less'
3 |
4 |
5 | export default class index extends Component {
6 |
7 | state={
8 | value:1
9 | }
10 |
11 | render() {
12 | return (
13 |
14 |
15 | {
16 | [1,2,3,4,5].map(item=>(
17 |
{
18 | this.setState({
19 | value:item
20 | })
21 | this.props.onChange(item)
22 | }}>
23 |
{item}
24 |
25 |
26 | ))
27 | }
28 |
29 |
36 |
37 |
38 | )
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/web/src/components/DifficultyBox/index.less:
--------------------------------------------------------------------------------
1 | [data-component=difficulty-box]{
2 | width: 100%;
3 | height: 32px;
4 | display: flex;
5 | align-items: center;
6 | justify-content: center;
7 | position: relative;
8 | > .difficulty-process-box{
9 | width: 100%;
10 | height: .04rem;
11 | background-color: #F5F5F5;
12 | display: flex;
13 | align-items: center;
14 | justify-content: space-between;
15 | position: relative;
16 | > .value-item{
17 | width: .08rem;
18 | height: .08rem;
19 | border-radius: .08rem;
20 |
21 | position: relative;
22 | cursor: pointer;
23 | z-index: 10;
24 | transition: all .5s;
25 | > .value{
26 | width: .16rem;
27 | height: .16rem;
28 | text-align: center;
29 | position: absolute;
30 | bottom: -.16rem;
31 | left: -.04rem;
32 | }
33 | > .center-cir{
34 | width: .04rem;
35 | height: .04rem;
36 | background-color: white;
37 | border-radius: .04rem;
38 | position: absolute;
39 | left: .02rem;
40 | top: .02rem;
41 | }
42 | }
43 | > .difficulty-process-value{
44 | height: 100%;
45 | position: absolute;
46 | left: 0;
47 | top: 0;
48 | background-color: #91D5FF;
49 | z-index: 8;
50 | transition: all .5s;
51 | }
52 | > .selected-cir{
53 | width: .15rem;
54 | height: .15rem;
55 | position: absolute;
56 | top: -0.055rem;
57 | border-radius: .15rem;
58 | background-color: #91D5FF;
59 | z-index: 12;
60 | transform: translateX(-50%);
61 | display: flex;
62 | align-items: center;
63 | justify-content: center;
64 | transition: all .5s;
65 | > .circle-1{
66 | width: .11rem;
67 | height: .11rem;
68 | background-color: white;
69 | border-radius: .11rem;
70 | display: flex;
71 | align-items: center;
72 | justify-content: center;
73 | > .circle-2{
74 | width: .07rem;
75 | height: .07rem;
76 | border-radius: .07rem;
77 | background-color: #91D5FF;
78 | display: flex;
79 | align-items: center;
80 | justify-content: center;
81 | > .circle-3{
82 | width: .04rem;
83 | height: .04rem;
84 | border-radius: .04rem;
85 | background-color: white;
86 | }
87 | }
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/web/src/components/HistoryQuestion/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {Row,Col,Button} from 'antd'
3 | import './index.less'
4 |
5 | export default class index extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 | 题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目......题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目.题目题目题目题目题目题目题目题目.(最多5行过多省略)题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目......题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目题目.题目题目题目题目题目题目题目题目.(最多5行过多省略)
12 |
13 |
14 |
15 |
16 | 学科名称:
17 |
18 |
19 | 数学
20 |
21 |
22 |
23 |
24 | 能力纬度:
25 |
26 |
27 | 参数1;参数2;参数3
28 |
29 |
30 |
31 |
32 | 内容纬度
33 |
34 |
35 | 参数1;参数2;参数3
36 |
37 |
38 |
39 |
40 | 难度等级:
41 |
42 |
43 | 参数1
44 |
45 |
46 |
47 |
48 |
49 |
50 | 答案:xxxx
51 |
52 |
53 |
54 |
55 |
56 |
57 | )
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/web/src/components/HistoryQuestion/index.less:
--------------------------------------------------------------------------------
1 | [data-component=history-question-item]{
2 | width: 100%;
3 | box-sizing: border-box;
4 | padding: .14rem .1rem .16rem .24rem;
5 | background-color: #FFFEFE33;
6 | border: .01rem solid #2DB7F5;
7 | margin-top: .2rem;
8 | > .queston-content{
9 | width: 100%;
10 | > .question-title{
11 | width: 100%;
12 | box-sizing: border-box;
13 | padding-top: .11rem;
14 | overflow: hidden;
15 | text-overflow: ellipsis;
16 | display: -webkit-box;
17 | -webkit-line-clamp: 5;
18 | -webkit-box-orient: vertical;
19 | text-align: justify;
20 | line-height: .22rem;
21 | > span{
22 | font-size: .14rem;
23 | color: #00000059;
24 | }
25 | }
26 | > .question-params{
27 | width: 100%;
28 | > .params-item{
29 | width: 100%;
30 | > .title{
31 | line-height: .22rem;
32 | > span{
33 | font-size: .1rem;
34 | color: #1890FF;
35 | }
36 | }
37 | > .value{
38 | line-height: .22rem;
39 | overflow: hidden;
40 | text-overflow: ellipsis;
41 | white-space: nowrap;
42 | > span{
43 | font-size: .1rem;
44 | color: #1890FF;
45 | }
46 | }
47 | }
48 | }
49 | }
50 |
51 | > .question-footer{
52 | width: 100%;
53 | margin-top: .25rem;
54 | > .question-answer{
55 | display: flex;
56 | align-items: center;
57 | > span{
58 | font-size: .1rem;
59 | color: #1890FF;
60 | }
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/web/src/components/MaterialWarehouse/index.less:
--------------------------------------------------------------------------------
1 | [data-component=material-warehouse-box]{
2 | width: 100%;
3 | height: calc(100% - .38rem);
4 | box-sizing: border-box;
5 | padding:0rem .21rem 0rem .23rem;
6 | > .container{
7 | width: 100%;
8 | height: calc(100% - .4rem);
9 | .empty-state-box{
10 | width: 100%;
11 | height: 100%;
12 | display: flex;
13 | align-items: center;
14 | justify-content: center;
15 | > .ant-empty{
16 | margin: 0;
17 | }
18 | }
19 | .file-item{
20 | width: 1rem;
21 | height: 1rem;
22 | background-color: #F3F3F3;
23 | float: left;
24 | margin-right: .1rem;
25 | display: flex;
26 | align-content: center;
27 | justify-content: center;
28 | flex-wrap: wrap;
29 | cursor: pointer;
30 | > .icon{
31 | width: 100%;
32 | height: .5rem;
33 | display: flex;
34 | align-items: center;
35 | justify-content: center;
36 | font-size: .32rem;
37 | }
38 | > .name{
39 | text-align: center;
40 | overflow:hidden;
41 | white-space: nowrap;
42 | text-overflow: ellipsis;
43 | box-sizing: border-box;
44 | padding: 0px .08rem;
45 | > span{
46 | font-size: .08rem;
47 | }
48 | }
49 | }
50 | > .upload-download-box{
51 | float: left;
52 | margin-right: .1rem;
53 | .file-load-btn{
54 | width: 100%;
55 | height: 100%;
56 | display: flex;
57 | align-content: center;
58 | justify-content: center;
59 | flex-wrap: wrap;
60 | }
61 | > .ant-upload-picture-card-wrapper{
62 | width: 1rem;
63 | height: 1rem;
64 | > .ant-upload{
65 | width: 100%;
66 | height: 100%;
67 | margin: 0;
68 | }
69 | }
70 | }
71 | }
72 | > .footer{
73 | display: flex;
74 | align-items: flex-end;
75 | width: 100%;
76 | height: .4rem;
77 | }
78 | }
--------------------------------------------------------------------------------
/web/src/components/ModifyRecordModal/index.less:
--------------------------------------------------------------------------------
1 | [data-component=modify-record-box]{
2 | width: 100%;
3 | > .basic{
4 | width: 100%;
5 | height: 1.49rem;
6 | box-sizing: border-box;
7 | padding: .16rem .16rem 0px .16rem;
8 | border: 1px solid #F0F0F0;
9 | border-radius: .02rem;
10 | margin-bottom: .32rem;
11 | > .id{
12 | font-size: .16rem;
13 | line-height: .24rem;
14 | font-weight: 400;
15 | color: #000000;
16 | height: .24rem;
17 | }
18 | > .date{
19 | height: .22rem;
20 | line-height: .22rem;
21 | font-size: .14rem;
22 | color: rgba(0, 0, 0, 0.45);
23 | }
24 | }
25 | .ant-table-cell{
26 | font-size: .14rem;
27 | }
28 | .ant-table-thead,.ant-table-row{
29 | height: .56rem;
30 | }
31 | }
--------------------------------------------------------------------------------
/web/src/components/ModulaCard/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import './index.less'
3 |
4 | export default class index extends Component {
5 | render() {
6 | return (
7 |
8 |
9 |
10 |
{this.props.title}
11 |
12 | {this.props.right}
13 |
14 |
15 | {this.props.children}
16 |
17 | )
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/web/src/components/ModulaCard/index.less:
--------------------------------------------------------------------------------
1 | [data-component=modula-card-box]{
2 | width: 100%;
3 | height: 100%;
4 | background-color: #fff;
5 | box-sizing: border-box;
6 | padding: .16rem 0rem ;
7 | > .title{
8 | width: 100%;
9 | height: .22rem;
10 | box-sizing: border-box;
11 | padding: 0px .26rem;
12 | display: flex;
13 | align-items: center;
14 | margin-bottom: .16rem;
15 | position: relative;
16 | > .icon{
17 | display: block;
18 | width: .06rem;
19 | height: .18rem;
20 | background-color: #1890FF;
21 | margin-right: .16rem;
22 | }
23 | > span{
24 | font-size: .16rem;
25 | font-weight: 400;
26 | line-height: .22rem;
27 | }
28 | > .right{
29 | position: absolute;
30 | height: 100%;
31 | right: .14rem;
32 | top: 0;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/web/src/components/Step/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Row, Col } from 'antd'
3 | import TaskRequirements from '../TaskRequirements'
4 | import CompletionStatus from '../CompletionStatus'
5 | import MaterialWarehouse from '../MaterialWarehouse'
6 | import DataTable from '../DataTable'
7 | import './index.less'
8 |
9 | export default class index extends Component {
10 |
11 | render() {
12 | return (
13 |
14 |
15 |
16 |
17 |
22 |
23 |
24 |
28 |
29 |
30 |
36 |
37 |
38 |
39 |
40 |
46 |
47 |
48 |
49 |
50 | )
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/web/src/components/Step/index.less:
--------------------------------------------------------------------------------
1 | [data-component=step-page]{
2 | width: 100%;
3 | height: auto;
4 | .addition-box{
5 | width: 100%;
6 | height: 100%;
7 | background-color: white;
8 | }
9 | }
--------------------------------------------------------------------------------
/web/src/components/TaskRequirements/index.less:
--------------------------------------------------------------------------------
1 | [data-component=task-requirements-box]{
2 | width: 100%;
3 | height: calc(100% - .38rem);
4 | > .describe-box{
5 | width: 100%;
6 | height: .66rem;
7 | box-sizing: border-box;
8 | padding: 0rem 0rem 0rem .5rem;
9 | display: flex;
10 | align-items: center;
11 | justify-content: space-between;
12 | margin-bottom: .21rem;
13 | > .context{
14 | width: 5rem;
15 | height: 100%;
16 | > p{
17 | font-size: .14rem;
18 | line-height: .22rem;
19 | margin: 0;
20 | }
21 | }
22 | > .btn-box{
23 | height: 100%;
24 | }
25 | }
26 | > .choice-box{
27 | width: 100%;
28 | height: .32rem;
29 | box-sizing: border-box;
30 | padding: 0rem 0rem 0rem .5rem;
31 | display: flex;
32 | .ant-btn {
33 | border-color: #1890FF;
34 | color: #1890FF;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/web/src/components/UpLoadModal/index.less:
--------------------------------------------------------------------------------
1 | [data-component=up-load-modal-box]{
2 | width: 100%;
3 | .material__id{
4 | display: block;
5 | .ant-form-item-control{
6 | box-sizing: border-box;
7 | padding-left: 0.4008rem;
8 | max-width: 91.66666667%;
9 | .ant-form-item-control-input{
10 | width: 100%;
11 | max-width: 100%;
12 | .ant-input {
13 | background-color: #FFFFFF;
14 | }
15 | }
16 | .ant-form-item-extra{
17 | font-size: .14rem;
18 | line-height: .22rem;
19 | color: #00000073;
20 | }
21 | }
22 | }
23 | .upload-file-item{
24 | width: 100%;
25 | height: .22rem;
26 | line-height: .22rem;
27 | > .anticon{
28 | color: #00000073;
29 | font-size: .11rem;
30 | }
31 | > span{
32 | font-size: .14rem;
33 | color: #1890FF;
34 | cursor: pointer;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/web/src/components/UpLoadQuestionModal/index.less:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-ct/OpenItem-old/2b4e89b9ba8cd0acd9b8c7a1c33f15da03f03386/web/src/components/UpLoadQuestionModal/index.less
--------------------------------------------------------------------------------
/web/src/conf/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-08-12 00:18:40
4 | * @LastEditTime: 2021-08-12 23:20:33
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web\src\conf\index.js
8 | */
9 | module.exports = {
10 | baseURL:'http://49.232.73.36:8081',
11 | }
12 |
--------------------------------------------------------------------------------
/web/src/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-07-31 16:42:56
4 | * @LastEditTime: 2021-08-13 01:38:48
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web-client\src\index.js
8 | */
9 | import React from 'react';
10 | import ReactDOM from 'react-dom';
11 | import './index.less';
12 | import 'antd/dist/antd.less';
13 | import App from './App.jsx';
14 | import store from './store'
15 |
16 | ReactDOM.render( , document.getElementById('root') );
17 |
18 | store.subscribe(()=>{
19 | ReactDOM.render(,document.getElementById('root'))
20 | })
--------------------------------------------------------------------------------
/web/src/index.less:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
15 | html,body,#root,#App{
16 | width: 19.2rem;
17 | height: 100%;
18 | margin: 0;
19 | padding: 0;
20 | }
21 |
--------------------------------------------------------------------------------
/web/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/src/setupProxy.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-09-19 00:17:31
4 | * @LastEditTime: 2021-10-02 01:45:35
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web\src\setupProxy.js
8 | */
9 | const { createProxyMiddleware } = require('http-proxy-middleware');
10 |
11 | module.exports = function (app) {
12 | // /api 表示代理路径
13 | // target 表示目标服务器的地址
14 | // app.use(createProxyMiddleware('/user', {target: "http://49.232.73.36:8081/review"}));
15 | // app.use(createProxyMiddleware('/proj', {target: "http://49.232.73.36:8081/review"}));
16 | // app.use(createProxyMiddleware('/file', {target: "http://49.232.73.36:8081/review"}));
17 | // app.use(createProxyMiddleware('/query/assign', {target: "http://49.232.73.36:8081/review"}));
18 | // app.use(createProxyMiddleware('/query/audit', {target: "http://49.232.73.36:8081/review"}));
19 | // app.use(createProxyMiddleware('/query/file', {target: "http://49.232.73.36:8081/review"}));
20 | // app.use(createProxyMiddleware('/query/proj', {target: "http://49.232.73.36:8081/review"}));
21 | // app.use(createProxyMiddleware('/query/step', {target: "http://49.232.73.36:8081/review"}));
22 | // app.use(createProxyMiddleware('/query/submit', {target: "http://49.232.73.36:8081/review"}));
23 | // app.use(createProxyMiddleware('/query/user', {target: "http://49.232.73.36:8081/review"}));
24 | // app.use(createProxyMiddleware('/question', {target: "http://49.232.73.36:8082/qbank"}));
25 | // app.use(createProxyMiddleware('/testpaper', {target: "http://49.232.73.36:8082/qbank"}));
26 | // app.use(createProxyMiddleware('/query/f_question', {target: "http://49.232.73.36:8082/qbank"}));
27 | // app.use(createProxyMiddleware('/query/f_testpaper', {target: "http://49.232.73.36:8082/qbank"}));
28 | // app.use(createProxyMiddleware('/query/t_question', {target: "http://49.232.73.36:8082/qbank"}));
29 | // app.use(createProxyMiddleware('/query/t_testpaper', {target: "http://49.232.73.36:8082/qbank"}));
30 | }
--------------------------------------------------------------------------------
/web/src/store/action.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-08-13 01:12:25
4 | * @LastEditTime: 2021-09-17 13:47:42
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web\src\store\user\action.js
8 | */
9 |
10 | import { SET_USERINFO,SET_PROJECTBASEINFO } from './constants'
11 |
12 | export const setuserinfo = (data)=>({type:SET_USERINFO,data})
13 | export const setprojectbaseinfo = (data)=>({type:SET_PROJECTBASEINFO,data})
14 |
--------------------------------------------------------------------------------
/web/src/store/constants.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-08-13 01:12:11
4 | * @LastEditTime: 2021-09-17 13:50:51
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web\src\store\user\constants.js
8 | */
9 | const SET_TOKEN = "setToken"
10 | const CLEAR_TOKEN = "clearToken"
11 | const SET_USERINFO = "setuserinfo"
12 | const SET_PROJECTBASEINFO = "setprojectbaseinfo"
13 |
14 | module.exports = {
15 | SET_TOKEN,
16 | CLEAR_TOKEN,
17 | SET_USERINFO,
18 | SET_PROJECTBASEINFO
19 | }
--------------------------------------------------------------------------------
/web/src/store/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-08-13 01:12:32
4 | * @LastEditTime: 2021-08-13 01:23:29
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web\src\store\user\index.js
8 | */
9 | import { createStore } from 'redux';
10 | import reducer from './reducer';
11 |
12 | const store = createStore(reducer);
13 |
14 | export default store;
15 |
--------------------------------------------------------------------------------
/web/src/store/reducer.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-08-13 00:58:37
4 | * @LastEditTime: 2021-09-17 13:46:36
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web\src\store\user\reduce.js
8 | */
9 | import { SET_PROJECTBASEINFO, SET_USERINFO } from './constants'
10 | import { getCookie, setCookie } from '../utils/cookies'
11 | import { getStorage, setStorage } from '../utils/storage'
12 |
13 | const userState = {
14 | token:getCookie('token'),
15 | userInfo:getStorage('userInfo'),
16 | currentProjectBaseInfo:getStorage('projectBaseInfo')
17 | }
18 |
19 | export default function userReduce(state=userState,action){
20 | switch(action.type){
21 | case SET_USERINFO:
22 | setCookie('token',action.data.message)
23 | setStorage('userInfo',{...action.data.data.profile,Id:action.data.data.uuid})
24 | return {...state, userInfo:getStorage('userInfo'),token:getCookie('token')}
25 | case SET_PROJECTBASEINFO:
26 | setStorage('projectBaseInfo',action.data)
27 | return {...state, userInfo:getStorage('userInfo'),token:getCookie('token'),projectBaseInfo:getStorage('projectBaseInfo')}
28 | default:
29 | return state
30 | }
31 | }
--------------------------------------------------------------------------------
/web/src/utils/cookies.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-08-12 00:25:43
4 | * @LastEditTime: 2021-08-12 23:18:32
5 | * @LastEditors: Please set LastEditors
6 | * @Description: 操作Cookie
7 | * @FilePath: \OpenItem\web\src\utils\cookies.js
8 | */
9 |
10 |
11 |
12 |
13 |
14 |
15 | /**
16 | * @description: 存值
17 | * @param {*} name
18 | * @param {*} value
19 | * @return {*}
20 | */
21 | function setCookie(name,value){
22 | var d = new Date();
23 | d.setTime(d.getTime()+(60*60*1000)); //保存一个小时
24 | var expires = "expires="+d.toGMTString();
25 | document.cookie = name+"="+value+"; "+expires;
26 | }
27 |
28 |
29 | /**
30 | * @description: 获取指定Cookie的值
31 | * @param {*} name
32 | * @return {*}
33 | */
34 | function getCookie(name){
35 | name = name + "=";
36 | var ca = document.cookie.split(';');
37 | for(var i=0; i {
18 | if (checkCookie('token')) {
19 | //Authorization Bearer
20 | config.headers['Token'] = getCookie('token')
21 | }
22 | return config
23 | },
24 | error => {
25 | return Promise.reject(error)
26 | }
27 | )
28 |
29 | request.interceptors.response.use(
30 | response => {
31 | const code = response.data.operation_code
32 | if(code===1000||!code){
33 | // const res = {...response.data.data,token:response.data.message||''}
34 | if(!code){
35 | return response
36 | }else{
37 | const res = {...response.data}
38 | return res
39 | }
40 | }else if(code===2000){
41 | return Promise.reject(response.data)
42 | }else{
43 | return Promise.reject(response.data)
44 | }
45 | },
46 | error => {
47 | console.log(error)
48 | return Promise.reject(error.response.data||error.response)
49 | }
50 | )
51 |
52 | export default request
53 |
--------------------------------------------------------------------------------
/web/src/utils/storage.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: your name
3 | * @Date: 2021-08-14 00:09:49
4 | * @LastEditTime: 2021-08-25 00:24:32
5 | * @LastEditors: Please set LastEditors
6 | * @Description: In User Settings Edit
7 | * @FilePath: \OpenItem\web\src\utils\storage.js
8 | */
9 |
10 | function getStorage(name) {
11 | return localStorage.getItem(name)===null?null:JSON.parse(localStorage.getItem(name))
12 | }
13 |
14 | function setStorage(name,value) {
15 | localStorage.setItem(name,JSON.stringify(value))
16 | }
17 |
18 | function checkStorage(name) {
19 | return localStorage.getItem(name)!==null
20 | }
21 |
22 | function delStorage(name) {
23 | localStorage.removeItem(name)
24 | }
25 |
26 | module.exports = {
27 | getStorage,
28 | setStorage,
29 | checkStorage,
30 | delStorage
31 | }
--------------------------------------------------------------------------------
/web/src/views/Home/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Layout, Menu, Avatar, Button } from 'antd';
3 | import DocumentTitle from 'react-document-title'
4 | import {Switch, Route,Redirect} from 'react-router-dom'
5 | import { UserOutlined } from '@ant-design/icons';
6 | import PendingTasks from '../PendingTasks'
7 | import ProjectManagement from '../ProjectManagement'
8 | import PropositionPaper from '../PropositionPaper'
9 | import NotFound from '../errors/404'
10 | import Forbid from '../errors/402'
11 | import store from '../../store';
12 | import './index.less'
13 |
14 |
15 | const { Header , Content } = Layout;
16 |
17 | export default class index extends Component {
18 |
19 | state = {
20 | menuCurrentSelected:"pending-tasks"
21 | }
22 |
23 | funcChange = (e)=>{
24 | this.setState({
25 | menuCurrentSelected:e.key
26 | })
27 | this.props.history.push(`/home/${e.key}`)
28 | }
29 |
30 | render() {
31 | return (
32 |
33 |
34 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | )
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/web/src/views/Login/index.less:
--------------------------------------------------------------------------------
1 | [data-component=login-page]{
2 | width: 100%;
3 | height: 100%;
4 | position: relative;
5 | background-image: url(../../asset/images/login_background.png);
6 | background-size: cover;
7 | background-repeat: no-repeat;
8 | background-color: #EEF4FF;
9 | overflow: hidden;
10 | > .login-box{
11 | width: 6.4rem;
12 | height: 4.5rem;
13 | background: #FFFFFF;
14 | border-radius: .4rem;
15 | box-sizing: border-box;
16 | padding: .26rem .28rem .61rem .69rem;
17 | position: absolute;
18 | right: 1.69rem;
19 | top: 2.57rem;
20 | > .login-btn__box{
21 | width: 100%;
22 | height: .52rem
23 | }
24 | > .login-btn__change{
25 | margin-bottom: .06rem;
26 | > .ant-btn{
27 | float: right;
28 | background-color: #FFC000;
29 | border-color: #FFC000;
30 | }
31 | }
32 | > .login-btn__operation{
33 | display: flex;
34 | width: 4.43rem;
35 | > .space-box{
36 | flex: 0 0 29.16666667%;
37 | }
38 | }
39 | > .login-form{
40 | width: 100%;
41 | height: calc(100% - 1.76rem);
42 | display: flex;
43 | align-content: center;
44 | flex-wrap: wrap;
45 | > .ant-form{
46 | width: 4.43rem;
47 | > .ant-form-item{
48 | > .ant-form-item-label{
49 | box-sizing: border-box;
50 | margin-right: .31rem;
51 | > label{
52 | font-size: .24rem;
53 | font-weight: 600;
54 | &::before{
55 | display: none;
56 | }
57 | }
58 | }
59 | }
60 | }
61 | > .more-choice-box{
62 | width: 4.43rem;
63 | text-align: right;
64 | > a{
65 | color: #55BAFF;
66 | border-bottom: .01rem solid #55BAFF;
67 | padding-bottom: .01rem;
68 | font-size: .16rem;
69 | font-weight: 400;
70 | }
71 | }
72 | }
73 | > .state-box{
74 | width: 100%;
75 | height: .38rem;
76 | box-sizing: border-box;
77 | padding-left: .36rem;
78 | margin-bottom: .28rem;
79 | > .message{
80 | width: 100%;
81 | height: 100%;
82 | display: flex;
83 | align-items: center;
84 | svg{
85 | width: .2744rem;
86 | height: .2744rem;
87 | color: #FF8C00;
88 | margin-right: .15rem;
89 | }
90 | > .content{
91 | font-size: .16rem;
92 | color: #FF8C00;
93 | }
94 | }
95 | }
96 | }
97 | > .login-describe{
98 | width: 3.2rem;
99 | position: absolute;
100 | top: 3rem;
101 | left: 1.83rem;
102 | box-sizing: border-box;
103 | padding-top: .3rem;
104 | > h1{
105 | font-weight: bold;
106 | color: #1890FF;
107 | font-size: .38rem;
108 | }
109 | > .describe-item{
110 | word-wrap: break-word;
111 | color: #1890FF;
112 | font-size: .18rem;
113 | }
114 | }
115 | }
116 |
117 | .ant-spin-nested-loading,.ant-spin-container{
118 | height: 100%;
119 | }
120 |
121 |
--------------------------------------------------------------------------------
/web/src/views/PendingTasks/index.less:
--------------------------------------------------------------------------------
1 | [data-component=pending-tasks-page]{
2 | width: 100%;
3 | height: 100%;
4 | > .ant-layout-header{
5 | width: 100%;
6 | height: .64rem;
7 | background: #FFFFFF;
8 | display: flex;
9 | align-items: center;
10 | justify-content: space-between;
11 | box-sizing: border-box;
12 | padding: 0rem .08rem;
13 | line-height: .64rem;
14 | > .title{
15 | font-size: .16rem;
16 | color: #000000D9;
17 | }
18 | > .right-box{
19 | display: flex;
20 | align-items: center;
21 | height: .64rem;
22 | > .ant-dropdown-trigger,.ant-input-search{
23 | margin-right: .16rem;
24 | }
25 | > .ant-dropdown-trigger{
26 | font-size: .14rem;
27 | }
28 | }
29 | }
30 | > .ant-layout-content{
31 | background-color: #FFFFFF;
32 | .ant-table-header{
33 | > .table{
34 | height: .48rem;
35 | }
36 | .ant-table-cell::before{
37 | display: none;
38 | }
39 | }
40 | .ant-table-row{
41 | height: .48rem;
42 | > .ant-table-cell{
43 | height: .48rem;
44 | padding: 0;
45 | font-size: 14px;
46 | }
47 | }
48 | }
49 | > .ant-layout-footer{
50 | padding: 0rem .2rem 0rem 0rem;
51 | height: .5rem;
52 | background-color: #ffffff;
53 | display: flex;
54 | align-items: center;
55 | flex-direction: row-reverse;
56 | }
57 | }
--------------------------------------------------------------------------------
/web/src/views/ProjectManagement/index.less:
--------------------------------------------------------------------------------
1 | [data-component=project-management-page]{
2 | width: 100%;
3 | height: 100%;
4 | background-color: #EEEEEE;
5 | overflow-y: scroll;
6 | > .ant-page-header{
7 | background-color: #FFFFFF;
8 | padding: .16rem 0rem 0rem 0rem;
9 | > .ant-page-header-heading{
10 | box-sizing: border-box;
11 | padding: 0rem .24rem;
12 | }
13 | > .ant-page-header-content{
14 | padding-left: .564rem;
15 | }
16 | .ant-page-header-heading-title{
17 | font-size: .2rem;
18 | font-weight: 500;
19 | line-height: .28rem;
20 | color: #000000;
21 | }
22 | .ant-page-header-heading-sub-title{
23 | font-size: .14rem;
24 | line-height: .22rem;
25 | color: rgba(0, 0, 0, 0.85);
26 | }
27 | .ant-tabs-nav-list{
28 | padding-left: .564rem
29 | }
30 | .ant-descriptions{
31 | width: 6.62rem;
32 | }
33 | .ant-tabs-tab-btn{
34 | font-size: .14rem;
35 | }
36 | }
37 | > .container{
38 | width: 100%;
39 | }
40 | .ant-spin-nested-loading{
41 | height: auto;
42 | background-color: white;
43 | }
44 | .page-content-box{
45 | width: 100%;
46 | box-sizing: border-box;
47 | padding: .3rem;
48 | }
49 | }
--------------------------------------------------------------------------------
/web/src/views/PropositionPaper/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {Switch, Route,Redirect} from 'react-router-dom'
3 | import CreatePaper from './views/CreatePaper'
4 | import UploadQuestions from './views/UploadQuestions'
5 | import Home from './views/Home/home'
6 |
7 | export default class index extends Component {
8 | render() {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | )
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/web/src/views/errors/402.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import DocumentTitle from 'react-document-title'
3 | import Rockets from '../../asset/images/Rockets.png'
4 | import Cloude from '../../asset/images/Cloud.png'
5 | import Unhapply from '../../asset/images/Unhapply.png'
6 | import './index.less'
7 |
8 | export default class index extends Component {
9 | render() {
10 | return (
11 |
12 |
13 |

14 |

15 |

16 |
17 |
402
18 |
19 | 错误原因错误原因错误原因错误原因
20 | 错误原因错误原因错误原因错误原因
21 | 错误原因错误原因错误原因错误原因
22 |
23 |
24 |
25 |
26 | )
27 | }
28 | }
--------------------------------------------------------------------------------
/web/src/views/errors/404.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import DocumentTitle from 'react-document-title'
3 | import Rockets from '../../asset/images/Rockets.png'
4 | import CryingFace from '../../asset/images/Crying_face.png'
5 | import FluExpression from '../../asset/images/Flu_expression.png'
6 | import './index.less'
7 |
8 | export default class index extends Component {
9 | render() {
10 | return (
11 |
12 |
13 |

14 |

15 |

16 |
17 |
18 |
19 |
20 |
404
21 |
22 | 错误原因错误原因错误原因错误原因
23 | 错误原因错误原因错误原因错误原因
24 | 错误原因错误原因错误原因错误原因
25 |
26 |
27 |
28 |
29 | )
30 | }
31 | }
--------------------------------------------------------------------------------
/web/src/views/errors/index.less:
--------------------------------------------------------------------------------
1 | [data-component=error_page__404]{
2 | width: 100%;
3 | min-height: 10.8rem;
4 | position: relative;
5 | background-color: #FFFFFF;
6 | > .pattern{
7 | position: absolute;
8 | }
9 | > .pattern__1{
10 | width: 3.2032rem;
11 | height: 3.2042rem;
12 | top: 1.637rem;
13 | left: 4.34rem;
14 | }
15 | > .pattern__2{
16 | width: 1.8731rem;
17 | height: 1.8731rem;
18 | left: 3.0534rem;
19 | top: 4.3634rem;
20 | }
21 | > .pattern__3{
22 | width: 1.89rem;
23 | height: 1.89rem;
24 | left: 7.975rem;
25 | top: 3.4681rem;
26 | }
27 | > .pattern__4{
28 | width: 2.88rem;
29 | height: 2.88rem;
30 | left: 2.33rem;
31 | top: 3.47rem;
32 | }
33 | > .pattern__5{
34 | width: 1.0625rem;
35 | height: 1.0625rem;
36 | left: 7.23rem;
37 | top: 4.44rem;
38 | }
39 | > .line{
40 | background-color: #597EF7;
41 | }
42 | > .line__1{
43 | width: 2.41rem;
44 | height: .23rem;
45 | left: 6.2rem;
46 | top: 5.4rem;
47 | }
48 | > .line__2{
49 | width: 2.41rem;
50 | height: .06rem;
51 | left: 6.2rem;
52 | top: 5.7rem;
53 | }
54 | > .line__3{
55 | width: .88rem;
56 | height: .17rem;
57 | left: 4.66rem;
58 | top: 6.24rem;
59 | }
60 | > .line__4{
61 | width: .88rem;
62 | height: .23rem;
63 | left: 4.66rem;
64 | top: 6.45rem;
65 | }
66 | > .line__5{
67 | width: 1.0625rem;
68 | height: .06rem;
69 | left: 7.23rem;
70 | top: 5.6681rem;
71 | }
72 | > .title{
73 | font-size: 1.44rem;
74 | font-weight: 400;
75 | color:#597EF7;
76 | right: 5.74rem;
77 | top: 3.09rem;
78 | line-height: 1.6875rem;
79 | }
80 | > .describe{
81 | width: 3.84rem;
82 | font-size: .24rem;
83 | line-height: .2813rem;
84 | color: #E5E5E5;
85 | right: 4.33rem;
86 | top: 5.0rem;
87 | }
88 | }
--------------------------------------------------------------------------------