forked from Open-CT/OpenPBL
feat: record learning progress
This commit is contained in:
parent
c86b20cc04
commit
caabfd7f92
|
@ -5,6 +5,12 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
type ChaptersResponse struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Chapters []models.Outline `json:"chapters"`
|
||||
}
|
||||
|
||||
// GetProjectChapters
|
||||
// @Title
|
||||
// @Description
|
||||
|
@ -13,12 +19,32 @@ import (
|
|||
// @Failure 403 body is empty
|
||||
// @router /:id/chapters [get]
|
||||
func (p *ProjectController) GetProjectChapters() {
|
||||
user := p.GetSessionUser()
|
||||
if user == nil {
|
||||
p.Data["json"] = ChaptersResponse{
|
||||
Code: 401,
|
||||
Msg: "请先登录",
|
||||
}
|
||||
p.ServeJSON()
|
||||
return
|
||||
}
|
||||
uid := ""
|
||||
if user.Tag == "student" {
|
||||
uid = user.Username
|
||||
}
|
||||
pid := p.GetString(":id")
|
||||
outline, err := models.GetChaptersByPid(pid)
|
||||
outline, err := models.GetChaptersByPid(pid, uid)
|
||||
if err != nil {
|
||||
p.Data["json"] = map[string][]models.Outline{"chapters": nil}
|
||||
p.Data["json"] = ChaptersResponse{
|
||||
Code: 400,
|
||||
Msg: err.Error(),
|
||||
Chapters: make([]models.Outline, 0),
|
||||
}
|
||||
} else {
|
||||
p.Data["json"] = map[string][]models.Outline{"chapters": outline}
|
||||
p.Data["json"] = ChaptersResponse{
|
||||
Code: 200,
|
||||
Chapters: outline,
|
||||
}
|
||||
}
|
||||
p.ServeJSON()
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package controllers
|
|||
|
||||
import (
|
||||
"OpenPBL/models"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
@ -175,5 +176,29 @@ func (p *ProjectController) ExchangeChapterSection() {
|
|||
p.ServeJSON()
|
||||
}
|
||||
|
||||
|
||||
// UpdateSectionsMinute
|
||||
// @Title
|
||||
// @Description
|
||||
// @Param body body []models.Section true ""
|
||||
// @Success 200 {object}
|
||||
// @Failure 401
|
||||
// @router /:projectId/sections-minute [post]
|
||||
func (p *ProjectController) UpdateSectionsMinute() {
|
||||
sections := make([]models.Section, 0)
|
||||
err := json.Unmarshal([]byte(p.GetString("sections")), §ions)
|
||||
err = models.UpdateSectionsMinute(sections)
|
||||
if err != nil {
|
||||
p.Data["json"] = Response{
|
||||
Code: 400,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
} else {
|
||||
p.Data["json"] = Response{
|
||||
Code: 200,
|
||||
Msg: "更新成功",
|
||||
Data: true,
|
||||
}
|
||||
}
|
||||
p.ServeJSON()
|
||||
}
|
||||
|
||||
|
|
|
@ -157,16 +157,14 @@ func (u *StudentController) FinishedProject() {
|
|||
u.ServeJSON()
|
||||
}
|
||||
|
||||
var TimeFormatStr = "2006-01-02 15:04:05"
|
||||
|
||||
// CreateLearnSection
|
||||
// GetLearnSection
|
||||
// @Title
|
||||
// @Description
|
||||
// @Param body body models.LearnSection true ""
|
||||
// @Success 200 {object} Response
|
||||
// @Failure 400
|
||||
// @router /section/:sectionId [post]
|
||||
func (u *StudentController) CreateLearnSection() {
|
||||
// @router /section/:sectionId [get]
|
||||
func (u *StudentController) GetLearnSection() {
|
||||
var resp Response
|
||||
user := u.GetSessionUser()
|
||||
if user == nil {
|
||||
|
@ -189,11 +187,7 @@ func (u *StudentController) CreateLearnSection() {
|
|||
}
|
||||
uid := user.Username
|
||||
sid, err := u.GetInt64(":sectionId")
|
||||
l := models.LearnSection{
|
||||
StudentId: uid,
|
||||
SectionId: sid,
|
||||
}
|
||||
err = l.Create()
|
||||
l, err := models.GetLearnSection(sid, uid)
|
||||
if err != nil {
|
||||
u.Data["json"] = Response{
|
||||
Code: 400,
|
||||
|
@ -202,7 +196,7 @@ func (u *StudentController) CreateLearnSection() {
|
|||
} else {
|
||||
u.Data["json"] = Response{
|
||||
Code: 200,
|
||||
Msg: "",
|
||||
Data: l,
|
||||
}
|
||||
}
|
||||
u.ServeJSON()
|
||||
|
@ -238,10 +232,13 @@ func (u *StudentController) UpdateLearnSection() {
|
|||
}
|
||||
uid := user.Username
|
||||
sid, err := u.GetInt64(":sectionId")
|
||||
|
||||
m, err := u.GetInt("learnMinute")
|
||||
s, err := u.GetInt("learnSecond")
|
||||
l := models.LearnSection{
|
||||
StudentId: uid,
|
||||
SectionId: sid,
|
||||
LearnMinute: m,
|
||||
LearnSecond: s,
|
||||
}
|
||||
err = l.Update()
|
||||
if err != nil {
|
||||
|
@ -252,7 +249,6 @@ func (u *StudentController) UpdateLearnSection() {
|
|||
} else {
|
||||
u.Data["json"] = Response{
|
||||
Code: 200,
|
||||
Msg: "",
|
||||
}
|
||||
}
|
||||
u.ServeJSON()
|
||||
|
|
|
@ -239,29 +239,3 @@ func (p *ProjectController) ExchangeTask() {
|
|||
}
|
||||
p.ServeJSON()
|
||||
}
|
||||
|
||||
|
||||
// SaveTaskWeight
|
||||
// @Title
|
||||
// @Description
|
||||
// @Param cid path string true ""
|
||||
// @Success 200 {object} Response
|
||||
// @Failure 401
|
||||
// @router /:projectId/tasks/exchange [post]
|
||||
func (p *ProjectController) SaveTaskWeight() {
|
||||
tid1 := p.GetString(":taskId1")
|
||||
tid2 := p.GetString(":taskId2")
|
||||
err := models.ExchangeTasks(tid1, tid2)
|
||||
if err != nil {
|
||||
p.Data["json"] = Response{
|
||||
Code: 400,
|
||||
}
|
||||
} else {
|
||||
p.Data["json"] = Response{
|
||||
Code: 200,
|
||||
Data: true,
|
||||
}
|
||||
}
|
||||
p.ServeJSON()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package models
|
||||
|
||||
import "xorm.io/xorm"
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type Chapter struct {
|
||||
Id int64 `json:"id" xorm:"not null pk autoincr"`
|
||||
|
@ -10,8 +12,8 @@ type Chapter struct {
|
|||
}
|
||||
|
||||
type Outline struct {
|
||||
Chapter `xorm:"extends"`
|
||||
Sections []Section `json:"sections" xorm:"extends"`
|
||||
Chapter `xorm:"extends"`
|
||||
Sections []SectionMinute `json:"sections" xorm:"extends"`
|
||||
}
|
||||
|
||||
func (p *Chapter) GetEngine() *xorm.Session {
|
||||
|
@ -40,7 +42,7 @@ func ExchangeChapters(cid1 string, cid2 string) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func GetChaptersByPid(pid string) (outline []Outline, err error) {
|
||||
func GetChaptersByPid(pid string, uid string) (outline []Outline, err error) {
|
||||
var c []Chapter
|
||||
err = (&Chapter{}).GetEngine().
|
||||
Where("project_id = ?", pid).
|
||||
|
@ -48,11 +50,17 @@ func GetChaptersByPid(pid string) (outline []Outline, err error) {
|
|||
Find(&c)
|
||||
outline = make([]Outline, len(c))
|
||||
for i:=0; i< len(c); i++ {
|
||||
sections := make([]Section, 0)
|
||||
sections := make([]SectionMinute, 0)
|
||||
outline[i].Chapter = c[i]
|
||||
err = (&Section{}).GetEngine().
|
||||
Where("chapter_id = ?", c[i].Id).
|
||||
Find(§ions)
|
||||
if uid == "" {
|
||||
err = (&Section{}).GetEngine().
|
||||
Where("chapter_id = ?", c[i].Id).
|
||||
Find(§ions)
|
||||
} else {
|
||||
err = adapter.Engine.
|
||||
SQL("select * from (select * from section where chapter_id = ?) s LEFT JOIN learn_section ls on s.id = ls.section_id and ls.student_id = ?", c[i].Id, uid).
|
||||
Find(§ions)
|
||||
}
|
||||
outline[i].Sections = sections
|
||||
}
|
||||
return
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
|
@ -11,7 +12,12 @@ type Section struct {
|
|||
SectionNumber int `json:"sectionNumber" xorm:"index"`
|
||||
ChapterNumber int `json:"chapterNumber" xorm:"index"`
|
||||
|
||||
SectionMinute int `json:"sectionMinute"`
|
||||
SectionMinute int `json:"sectionMinute" xorm:"default 10"`
|
||||
}
|
||||
|
||||
type SectionMinute struct {
|
||||
Section `xorm:"extends"`
|
||||
LearnSection `xorm:"extends"`
|
||||
}
|
||||
|
||||
type SectionDetail struct {
|
||||
|
@ -43,6 +49,15 @@ func (p *Section) Update() (err error) {
|
|||
_, err = p.GetEngine().ID(p.Id).Update(p)
|
||||
return
|
||||
}
|
||||
|
||||
func UpdateSectionsMinute(sections []Section) (err error) {
|
||||
for i:=0; i< len(sections); i++ {
|
||||
fmt.Println(sections[i])
|
||||
err = (§ions[i]).Update()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Section) Delete() (err error) {
|
||||
_, err = p.GetEngine().
|
||||
Exec("update section set section_number = section_number - 1 where section_number > ", p.SectionNumber)
|
||||
|
|
|
@ -18,7 +18,8 @@ type LearnSection struct {
|
|||
StudentId string `json:"studentId" xorm:"not null index pk"`
|
||||
SectionId int64 `json:"sectionId" xorm:"not null index pk"`
|
||||
|
||||
LearnMinute int `json:"learnTime" xorm:"default 0"`
|
||||
LearnMinute int `json:"learnMinute" xorm:"default 0"`
|
||||
LearnSecond int `json:"learnSecond" xorm:"default 0"`
|
||||
}
|
||||
|
||||
func (l *LearnProject) GetEngine() *xorm.Session {
|
||||
|
@ -27,6 +28,7 @@ func (l *LearnProject) GetEngine() *xorm.Session {
|
|||
func (l *LearnSection) GetEngine() *xorm.Session {
|
||||
return adapter.Engine.Table(l)
|
||||
}
|
||||
|
||||
func (l *LearnProject) Create() (err error) {
|
||||
_, err = (&LearnProject{}).GetEngine().Insert(l)
|
||||
_, err = adapter.Engine.
|
||||
|
@ -78,6 +80,19 @@ func GetProjectStudents(pid string, from int, size int) (s []LearnProject, rows
|
|||
return
|
||||
}
|
||||
|
||||
func GetLearnSection(sectionId int64, studentId string) (l LearnSection, err error) {
|
||||
var b bool
|
||||
b, err = (&LearnSection{}).GetEngine().
|
||||
Where("section_id = ?", sectionId).
|
||||
Where("student_id = ?", studentId).
|
||||
Get(&l)
|
||||
if !b {
|
||||
l.SectionId = sectionId
|
||||
l.StudentId = studentId
|
||||
(&l).Create()
|
||||
}
|
||||
return
|
||||
}
|
||||
func (l *LearnSection) Create() (err error) {
|
||||
_, err = (&LearnSection{}).GetEngine().Insert(l)
|
||||
return
|
||||
|
|
|
@ -23,6 +23,13 @@ const SectionApi = {
|
|||
data: qs.stringify(section)
|
||||
})
|
||||
},
|
||||
updateSectionsMinute(pid, sections) {
|
||||
return request({
|
||||
url: `/project/${pid}/sections-minute`,
|
||||
method: 'post',
|
||||
data: qs.stringify(sections)
|
||||
})
|
||||
},
|
||||
deleteChapterSection(pid, s) {
|
||||
return request({
|
||||
url: `/project/${pid}/chapter/${s.chapterId}/section/${s.id}/delete`,
|
||||
|
|
|
@ -24,6 +24,19 @@ const StudentApi = {
|
|||
learning: false
|
||||
})
|
||||
})
|
||||
},
|
||||
getLearnSection(sid) {
|
||||
return request({
|
||||
url: `/student/section/${sid}`,
|
||||
method: 'get'
|
||||
})
|
||||
},
|
||||
updateLearnSection(sid, data) {
|
||||
return request({
|
||||
url: `/student/section/${sid}`,
|
||||
method: 'post',
|
||||
data: qs.stringify(data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,12 @@ import TaskApi from "../../../api/TaskApi";
|
|||
import FillSurvey from "./component/FillSurvey";
|
||||
import SubmitApi from "../../../api/SubmitApi";
|
||||
import util from "../component/Util"
|
||||
import StudentApi from "../../../api/StudentApi";
|
||||
|
||||
|
||||
function PreviewSection(obj) {
|
||||
let s = new URLSearchParams(obj.location.search)
|
||||
const backUrl = s.get('back')
|
||||
let url = new URLSearchParams(obj.location.search)
|
||||
const backUrl = url.get('back')
|
||||
|
||||
const sid = obj.match.params.sid
|
||||
const pid = obj.match.params.pid
|
||||
|
@ -22,10 +23,33 @@ function PreviewSection(obj) {
|
|||
const [tasks, setTasks] = useState([])
|
||||
const [learning, setLearning] = useState(false)
|
||||
|
||||
const [minute, setMinute] = useState(0)
|
||||
const [second, setSecond] = useState(0)
|
||||
const [timer, setTimer] = useState(null)
|
||||
let s = 0
|
||||
let m = 0
|
||||
|
||||
useEffect(()=>{
|
||||
getSectionDetail()
|
||||
getTasks()
|
||||
}, [])
|
||||
useEffect(()=>{
|
||||
window.onbeforeunload = leave
|
||||
}, [])
|
||||
const leave = () => {
|
||||
if (timer != null) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
let data = {
|
||||
learnMinute: m,
|
||||
learnSecond: s
|
||||
}
|
||||
StudentApi.updateLearnSection(sid, data)
|
||||
.then(res=>{
|
||||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
}
|
||||
|
||||
const getSectionDetail = () => {
|
||||
SectionApi.getSectionDetail(sid, pid)
|
||||
.then(res=>{
|
||||
|
@ -64,10 +88,38 @@ function PreviewSection(obj) {
|
|||
}
|
||||
setTasks(t)
|
||||
setLearning(res.data.learning)
|
||||
if (res.data.learning) {
|
||||
getTimer()
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
}
|
||||
const getTimer = () => {
|
||||
StudentApi.getLearnSection(sid)
|
||||
.then(res=>{
|
||||
if (res.data.code === 200) {
|
||||
setSecond(res.data.data.learnSecond)
|
||||
setMinute(res.data.data.learnMinute)
|
||||
s = res.data.data.learnSecond
|
||||
m = res.data.data.learnMinute
|
||||
}
|
||||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
|
||||
setTimeout(count, 1000)
|
||||
}
|
||||
const count = () => {
|
||||
if (s === 30) {
|
||||
s = 0
|
||||
m ++
|
||||
setMinute(m)
|
||||
} else {
|
||||
s++
|
||||
}
|
||||
setSecond(s)
|
||||
setTimeout(count, 1000)
|
||||
}
|
||||
const back = e => {
|
||||
if (backUrl === undefined || backUrl === null) {
|
||||
window.location.href = `/project/${pid}/section/${sid}/edit`
|
||||
|
@ -141,6 +193,9 @@ function PreviewSection(obj) {
|
|||
<div style={{ padding: '20px', margin: 'auto'}}>
|
||||
<Card>
|
||||
<h2 style={{ fontWeight: 'bold' }}>{section.sectionName}</h2>
|
||||
{learning ?
|
||||
<span style={{float: 'right'}}>{minute} : {second}</span>
|
||||
: null}
|
||||
</Card>
|
||||
<Card className="resource-card">
|
||||
<div dangerouslySetInnerHTML={{__html: section.resource.content}}/>
|
||||
|
|
|
@ -6,16 +6,22 @@ import 'echarts/lib/component/legend';
|
|||
import 'echarts/lib/component/markPoint';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import QueueAnim from 'rc-queue-anim';
|
||||
import {Button, Card, Col, Divider, InputNumber, Row, Table, message} from "antd";
|
||||
import {Button, Card, Col, Divider, InputNumber, Row, Table, message, Menu, Input} from "antd";
|
||||
|
||||
import TaskApi from "../../../../api/TaskApi";
|
||||
import ProjectApi from "../../../../api/ProjectApi";
|
||||
import ChapterApi from "../../../../api/ChapterApi";
|
||||
import SectionApi from "../../../../api/SectionApi";
|
||||
|
||||
|
||||
const {SubMenu} = Menu
|
||||
|
||||
function ProjectEvaluation(obj) {
|
||||
const pid = obj.project.id
|
||||
const published = obj.project.published
|
||||
const type = localStorage.getItem("type")
|
||||
|
||||
const [chapters, setChapters] = useState([])
|
||||
const [defaultOpenedKeys, setDefaultOpenedKeys] = useState([])
|
||||
const [data, setData] = useState([])
|
||||
const [tasks, setTasks] = useState([])
|
||||
|
||||
|
@ -23,8 +29,10 @@ function ProjectEvaluation(obj) {
|
|||
const [learnMinuteWeight, setLearnMinuteWeight] = useState(obj.project.learnMinuteWeight)
|
||||
|
||||
const [editWeight, setEditWeight] = useState(false)
|
||||
const [editMinute, setEditMinute] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
getChapters()
|
||||
getTasks()
|
||||
}, []);
|
||||
const getTasks = () => {
|
||||
|
@ -41,7 +49,26 @@ function ProjectEvaluation(obj) {
|
|||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
}
|
||||
|
||||
const getChapters = () => {
|
||||
ChapterApi.getProjectChapters(pid)
|
||||
.then((res) => {
|
||||
if (res.data.chapters === null) {
|
||||
setChapters([])
|
||||
setDefaultOpenedKeys(0)
|
||||
} else {
|
||||
setChapters(res.data.chapters)
|
||||
setOpenAllKeys(res.data.chapters.length)
|
||||
}
|
||||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
}
|
||||
const setOpenAllKeys = n => {
|
||||
let keys = []
|
||||
for (let i=0; i<n; i++) {
|
||||
keys.push(i.toString())
|
||||
}
|
||||
setDefaultOpenedKeys(keys)
|
||||
}
|
||||
const checkWeight = () => {
|
||||
let total = learnMinuteWeight
|
||||
for (let i=0; i<tasks.length; i++) {
|
||||
|
@ -57,12 +84,29 @@ function ProjectEvaluation(obj) {
|
|||
}
|
||||
return false
|
||||
}
|
||||
const edit = () => {
|
||||
const edit1 = () => {
|
||||
setEditMinute(true)
|
||||
}
|
||||
const edit2 = () => {
|
||||
setEditWeight(true)
|
||||
}
|
||||
const save = () => {
|
||||
const saveMinute = () => {
|
||||
let sections = []
|
||||
for (let i=0; i<chapters.length; i++) {
|
||||
sections = sections.concat(chapters[i].sections)
|
||||
}
|
||||
let data = JSON.stringify(sections)
|
||||
SectionApi.updateSectionsMinute(pid, {sections: data})
|
||||
.then(res=>{
|
||||
setEditMinute(false)
|
||||
if (res.data.code === 200) {
|
||||
getChapters()
|
||||
}
|
||||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
}
|
||||
const saveWeight = () => {
|
||||
if (checkWeight()) {
|
||||
setEditWeight(false)
|
||||
let data = {
|
||||
learnMinute: learnMinute,
|
||||
learnMinuteWeight: learnMinuteWeight,
|
||||
|
@ -70,20 +114,24 @@ function ProjectEvaluation(obj) {
|
|||
}
|
||||
ProjectApi.updateWeight(pid, data)
|
||||
.then(res=>{
|
||||
setEditWeight(false)
|
||||
if (res.data.code === 200) {
|
||||
getTasks()
|
||||
obj.loadProjectDetail()
|
||||
}
|
||||
})
|
||||
.catch(e=>{console.log(e)})
|
||||
|
||||
}
|
||||
}
|
||||
const cancel = () => {
|
||||
const cancel1 = () => {
|
||||
setEditMinute(false)
|
||||
}
|
||||
const cancel2 = () => {
|
||||
setEditWeight(false)
|
||||
}
|
||||
const changeLearnMinute = (v) => {
|
||||
setLearnMinute(v)
|
||||
const changeLearnMinute = (v, index, subIndex) => {
|
||||
chapters[index].sections[subIndex].sectionMinute = v
|
||||
setChapters([...chapters])
|
||||
}
|
||||
const changeLearnMinuteWeight = (v) => {
|
||||
setLearnMinuteWeight(v)
|
||||
|
@ -193,34 +241,76 @@ function ProjectEvaluation(obj) {
|
|||
<div style={{textAlign: 'left', marginBottom: '30px'}} key="1">
|
||||
<ReactEcharts option={getOptions()}/>
|
||||
|
||||
{!published ?
|
||||
<div style={{textAlign: 'right'}}>
|
||||
{editWeight ?
|
||||
<>
|
||||
<Button onClick={cancel} style={{marginRight: '20px'}}>取消</Button>
|
||||
<Button onClick={save} type="primary">保存</Button>
|
||||
</>
|
||||
:
|
||||
<Button onClick={edit}>编辑权重</Button>
|
||||
<div>
|
||||
<p style={{textAlign: 'center', fontWeight: 'bold', fontSize: '20px', marginTop: '20px'}}>
|
||||
章节学习时长</p>
|
||||
{!published ?
|
||||
<div style={{float: 'right'}}>
|
||||
{editMinute ?
|
||||
<>
|
||||
<Button onClick={cancel1} style={{marginRight: '20px'}}>取消</Button>
|
||||
<Button onClick={saveMinute} type="primary">保存</Button>
|
||||
</>
|
||||
:
|
||||
<Button onClick={edit1}>编辑时长</Button>
|
||||
}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
<Menu
|
||||
style={{width: '100%'}}
|
||||
defaultSelectedKeys={[]}
|
||||
openKeys={defaultOpenedKeys}
|
||||
mode="inline"
|
||||
>{chapters.map((item, index) => (
|
||||
<SubMenu style={{fontSize: '2.7vh'}} key={index.toString()} title={item.chapterName}>
|
||||
{(item.sections === null || item.sections === undefined) ? null :
|
||||
item.sections.map((subItem, subIndex) => (
|
||||
<Menu.Item key={index.toString() + subIndex.toString()} >
|
||||
{subItem.sectionName}
|
||||
{editMinute ?
|
||||
<div style={{float: 'right'}}>
|
||||
学习时长不少于
|
||||
<InputNumber value={subItem.sectionMinute} onChange={v=>changeLearnMinute(v, index, subIndex)} min={0}/>
|
||||
分钟
|
||||
</div>
|
||||
:
|
||||
<div style={{float: 'right'}}>
|
||||
学习时长不少于 {subItem.sectionMinute} 分钟
|
||||
</div>
|
||||
}
|
||||
</Menu.Item>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
<p style={{textAlign: 'center', fontWeight: 'bold', fontSize: '20px', marginTop: '20px'}}>权重占比</p>
|
||||
</SubMenu>
|
||||
))}
|
||||
</Menu>
|
||||
<div>
|
||||
<p style={{textAlign: 'center', fontWeight: 'bold', fontSize: '20px', marginTop: '20px'}}>
|
||||
权重占比
|
||||
</p>
|
||||
{!published ?
|
||||
<div style={{float: 'right'}}>
|
||||
{editWeight ?
|
||||
<>
|
||||
<Button onClick={cancel2} style={{marginRight: '20px'}}>取消</Button>
|
||||
<Button onClick={saveWeight} type="primary">保存</Button>
|
||||
</>
|
||||
:
|
||||
<Button onClick={edit2}>编辑权重</Button>
|
||||
}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
<Divider />
|
||||
<Row style={{padding: '15px'}} gutter={[10, 10]}>
|
||||
<Col span={8}>
|
||||
<span style={{fontWeight: 'bold'}}>章节学习时长</span></Col>
|
||||
<Col span={10}>
|
||||
<span>每小节学习时长不少于 </span>
|
||||
{editWeight ?
|
||||
<span><InputNumber value={learnMinute} onChange={changeLearnMinute} min={0}/></span>
|
||||
:
|
||||
<span>{obj.project.learnMinute}</span>
|
||||
}
|
||||
<span> 分钟</span>
|
||||
<span style={{fontWeight: 'bold'}}>学习时长</span></Col>
|
||||
<Col span={8}>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Col span={8}>
|
||||
<span>权重 </span>
|
||||
{editWeight ?
|
||||
<span><InputNumber value={learnMinuteWeight} onChange={changeLearnMinuteWeight} min={0}/></span>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, {useEffect, useState} from "react";
|
||||
import {Menu} from 'antd'
|
||||
import {Menu, Progress} from 'antd'
|
||||
import QueueAnim from 'rc-queue-anim';
|
||||
|
||||
import ChapterApi from "../../../../api/ChapterApi";
|
||||
|
@ -40,6 +40,24 @@ function ProjectOutline(obj) {
|
|||
item.sections.map((subItem, subIndex) => (
|
||||
<Menu.Item key={index.toString() + subIndex.toString()} onClick={e => gotoLearning(item, subItem)}>
|
||||
{subItem.sectionName}
|
||||
{obj.project.learning ?
|
||||
<>
|
||||
<span style={{float: 'right'}}>
|
||||
<Progress
|
||||
trailColor="lightgray"
|
||||
width={35}
|
||||
strokeWidth={10}
|
||||
type="circle"
|
||||
percent={((subItem.learnMinute+subItem.learnSecond/60)/subItem.sectionMinute*100).toFixed(1)}
|
||||
/>
|
||||
</span>
|
||||
<span style={{float: 'right', marginRight: '20px'}}>
|
||||
学习进度:
|
||||
{subItem.learnMinute} : {subItem.learnSecond} /
|
||||
{subItem.sectionMinute}
|
||||
</span>
|
||||
</>
|
||||
: null }
|
||||
</Menu.Item>
|
||||
))
|
||||
}
|
||||
|
|
|
@ -45,18 +45,18 @@ func init() {
|
|||
|
||||
beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"],
|
||||
beego.ControllerComments{
|
||||
Method: "UpdateProject",
|
||||
Method: "GetProjectDetail",
|
||||
Router: "/:id",
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
AllowHTTPMethods: []string{"get"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetProjectDetail",
|
||||
Method: "UpdateProject",
|
||||
Router: "/:id",
|
||||
AllowHTTPMethods: []string{"get"},
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
@ -214,6 +214,15 @@ func init() {
|
|||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"],
|
||||
beego.ControllerComments{
|
||||
Method: "UpdateSectionsMinute",
|
||||
Router: "/:projectId/sections-minute",
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"],
|
||||
beego.ControllerComments{
|
||||
Method: "GetProjectStudents",
|
||||
|
@ -340,15 +349,6 @@ func init() {
|
|||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"],
|
||||
beego.ControllerComments{
|
||||
Method: "SaveTaskWeight",
|
||||
Router: "/:projectId/tasks/exchange",
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
||||
beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:ProjectController"],
|
||||
beego.ControllerComments{
|
||||
Method: "ExchangeTask",
|
||||
|
@ -432,9 +432,9 @@ func init() {
|
|||
|
||||
beego.GlobalControllerRouter["OpenPBL/controllers:StudentController"] = append(beego.GlobalControllerRouter["OpenPBL/controllers:StudentController"],
|
||||
beego.ControllerComments{
|
||||
Method: "CreateLearnSection",
|
||||
Method: "GetLearnSection",
|
||||
Router: "/section/:sectionId",
|
||||
AllowHTTPMethods: []string{"post"},
|
||||
AllowHTTPMethods: []string{"get"},
|
||||
MethodParams: param.Make(),
|
||||
Filters: nil,
|
||||
Params: nil})
|
||||
|
|
Loading…
Reference in New Issue