Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-learn
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-learn
Commits
5100075e
提交
5100075e
authored
7月 29, 2022
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
c6ef9ea4
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
243 行增加
和
82 行删除
+243
-82
AppEditor.vue
src/components/base/AppEditor.vue
+0
-0
AppUpload.vue
src/components/base/AppUpload.vue
+18
-11
CourseExamCard.vue
src/modules/course/components/CourseExamCard.vue
+9
-5
CourseExamQuestion.vue
src/modules/course/components/CourseExamQuestion.vue
+3
-1
CourseExamQuestionItem.vue
src/modules/course/components/CourseExamQuestionItem.vue
+20
-15
CourseExamQuestionNumbers.vue
src/modules/course/components/CourseExamQuestionNumbers.vue
+20
-29
CourseViewWork.vue
src/modules/course/components/CourseViewWork.vue
+3
-1
CourseExam.vue
src/modules/course/views/CourseExam.vue
+10
-4
api.ts
src/modules/settings/api.ts
+9
-0
Suggestions.vue
src/modules/settings/components/Suggestions.vue
+85
-6
SuggestionsForm.vue
src/modules/settings/components/SuggestionsForm.vue
+56
-0
SuggestionsItem.vue
src/modules/settings/components/SuggestionsItem.vue
+0
-10
types.ts
src/modules/settings/types.ts
+9
-0
types.ts
src/types.ts
+1
-0
没有找到文件。
src/components/
tinymce/Index
.vue
→
src/components/
base/AppEditor
.vue
浏览文件 @
5100075e
File moved
src/components/base/AppUpload.vue
浏览文件 @
5100075e
...
...
@@ -94,18 +94,20 @@ const handlePreview: UploadProps['onPreview'] = uploadFile => {
:file-list=
"fileList"
class=
"uploader"
>
<template
v-if=
"showFileList"
>
<template
v-if=
"$attrs['list-type'] === 'picture-card'"
>
<el-icon><Plus
/></el-icon>
<slot>
<template
v-if=
"showFileList"
>
<template
v-if=
"$attrs['list-type'] === 'picture-card'"
>
<el-icon><Plus
/></el-icon>
</
template
>
<
template
v-else
>
<el-button
type=
"primary"
round
>
点击上传
</el-button>
</
template
>
</template>
<
template
v-else
>
<el-button
type=
"primary"
round
>
点击上传
</el-button>
</
template
>
</template>
<div
class=
"avatar-uploader"
v-else
>
<el-image
:src=
"(modelValue as string)"
fit=
"contain"
v-if=
"modelValue"
/>
<el-icon
v-else
class=
"avatar-uploader-icon"
><Plus
/></el-icon>
</div>
<div
class=
"avatar-uploader"
v-else
>
<el-image
:src=
"(modelValue as string)"
fit=
"contain"
v-if=
"modelValue"
/>
<el-icon
v-else
class=
"avatar-uploader-icon"
><Plus
/></el-icon>
</div>
</slot>
<
template
#
tip
>
<div
class=
"el-upload__tip"
><slot
name=
"tip"
></slot></div>
</
template
>
...
...
@@ -140,4 +142,9 @@ const handlePreview: UploadProps['onPreview'] = uploadFile => {
height
:
100%
;
text-align
:
center
;
}
.suggestion-file
{
display
:
inline-block
;
margin-top
:
10px
;
color
:
blue
;
}
</
style
>
src/modules/course/components/CourseExamCard.vue
浏览文件 @
5100075e
...
...
@@ -66,10 +66,14 @@ function handleSubmit() {
paper_id
:
paperId
,
type
,
question
:
JSON
.
stringify
(
genSubmitQuestion
(
questionList
))
}).
then
(()
=>
{
ElMessage
.
success
(
'提交成功'
)
emit
(
'update'
)
})
.
then
(()
=>
{
ElMessage
.
success
(
'提交成功'
)
emit
(
'update'
)
})
.
catch
(()
=>
{
submitLoading
=
false
})
}
// 自动提交
function
handleAutoSubmit
()
{
...
...
@@ -112,7 +116,7 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
<div
class=
"course-exam-card-bd"
>
<div
class=
"course-exam-left"
>
<div
class=
"course-exam-scroll"
>
<CourseExamQuestion
:question=
"currentQuestion"
:index=
"questionIndex + 1"
>
<CourseExamQuestion
:question=
"currentQuestion"
:
status=
"status"
:
index=
"questionIndex + 1"
>
<template
#
index
>
{{
questionIndex
+
1
}}
/
{{
questionLength
}}
</
template
>
</CourseExamQuestion>
</div>
...
...
@@ -125,7 +129,7 @@ function genSubmitQuestion(questionList: PaperQuestionType[]) {
</div>
<div
class=
"course-exam-right"
>
<div
class=
"course-exam-scroll"
>
<CourseExamQuestionNumbers
:index=
"questionIndex"
:status=
"
1
"
/>
<CourseExamQuestionNumbers
:index=
"questionIndex"
:status=
"
status
"
/>
</div>
<div
class=
"course-exam-buttons"
>
<el-button
...
...
src/modules/course/components/CourseExamQuestion.vue
浏览文件 @
5100075e
...
...
@@ -6,6 +6,7 @@ import { questionType } from '@/utils/dictionary'
interface
Props
{
index
:
number
status
:
number
question
:
PaperQuestionType
}
const
props
=
defineProps
<
Props
>
()
...
...
@@ -28,11 +29,12 @@ const questionTypeText = computed(() => {
<CourseExamQuestionItem
v-for=
"(item, index) in question.children"
:question=
"item"
:status=
"status"
:index=
"index + 1"
:key=
"item.id"
/>
</
template
>
<CourseExamQuestionItem
:question=
"question"
:index=
"index"
v-else
/>
<CourseExamQuestionItem
:question=
"question"
:
status=
"status"
:
index=
"index"
v-else
/>
</div>
</div>
</template>
...
...
src/modules/course/components/CourseExamQuestionItem.vue
浏览文件 @
5100075e
...
...
@@ -2,6 +2,7 @@
import
type
{
PaperQuestionType
}
from
'@/types'
interface
Props
{
index
:
number
status
:
number
question
:
PaperQuestionType
}
const
{
question
}
=
defineProps
<
Props
>
()
...
...
@@ -17,18 +18,9 @@ const currentOptions = computed(() => {
// 英文字母 + 名称
item
.
abc
=
A_Z
[
index
]
item
.
abc_option
=
`
${
A_Z
[
index
]}
.
${
item
.
option
}
`
// 提交时的选中状态
// item.checked = this.question.user_answer.includes(item.id)
// 处理正确的选中状态
// const hasChecked = Object.prototype.hasOwnProperty.call(item, 'isRight')
// const rightAnswer = this.question.question_answer || []
// if (!hasChecked && rightAnswer) {
// item.isRight = Array.isArray(rightAnswer) ? rightAnswer.includes(item.id) : rightAnswer === item.id
// }
return
item
})
})
// 26个英文字母
const
A_Z
=
$computed
(()
=>
{
const
result
=
[]
...
...
@@ -37,11 +29,24 @@ const A_Z = $computed(() => {
}
return
result
})
// 试题类型
const
questionType
=
computed
(()
=>
{
return
question
.
child_question_type
||
question
.
question_type
})
// 正确答案
const
correctAnswerText
=
computed
(()
=>
{
return
question
.
question_options
.
filter
((
item
:
any
)
=>
item
.
checked
)
.
map
((
item
:
any
)
=>
item
.
abc
)
.
join
(
'、'
)
})
// 提交的答案
const
submitAnswerText
=
computed
(()
=>
{
return
question
.
question_options
.
filter
((
item
:
any
)
=>
item
.
user_checked
)
.
map
((
item
:
any
)
=>
item
.
abc
)
.
join
(
'、'
)
})
const
value
=
computed
({
get
()
{
return
question
.
user_answer
...
...
@@ -100,7 +105,7 @@ const checkboxValues = computed({
>
</el-input>
</
template
>
</div>
<
!-- <div class="question-item-ft" v-if="hasResult
">
<
div
class=
"question-item-ft"
v-if=
"status === 3
"
>
<h3
class=
"question-item-ft__title"
>
答案解析
</h3>
<
template
v-if=
"questionType !== 3"
>
<div
class=
"answer-item"
>
...
...
@@ -113,16 +118,16 @@ const checkboxValues = computed({
</div>
</
template
>
<
template
v-else
>
<div class="answer-item" v-if="question.
comment
">
<div
class=
"answer-item"
v-if=
"question.
reviews
"
>
<div
class=
"answer-item-label"
>
老师点评:
</div>
<div class="answer-item-content">{{ question.
comment
}}</div>
<div
class=
"answer-item-content"
>
{{
question
.
reviews
}}
</div>
</div>
</
template
>
<div
class=
"answer-item"
v-if=
"question.question_analysis"
>
<div
class=
"answer-item-label"
>
解析:
</div>
<div
class=
"answer-item-content"
v-html=
"question.question_analysis"
></div>
</div>
</div>
-->
</div>
</div>
</template>
...
...
src/modules/course/components/CourseExamQuestionNumbers.vue
浏览文件 @
5100075e
...
...
@@ -12,41 +12,32 @@ const questionList = $ref<PaperQuestionType[]>(inject('questionList'))
// 试题索引
let
questionIndex
=
$ref
<
number
>
(
inject
(
'questionIndex'
))
const
questionNumTips
:
any
=
{
1
:
[
{
class
:
'is-info'
,
name
:
'已答'
},
{
class
:
'is-default'
,
name
:
'未答'
},
{
class
:
'is-success'
,
name
:
'当前'
}
],
2
:
[
{
class
:
'is-success'
,
name
:
'答对'
},
{
class
:
'is-error'
,
name
:
'答错'
},
{
class
:
'is-info'
,
name
:
'未答'
}
]
}
const
questionNum
=
computed
(()
=>
{
return
questionNumTips
[
props
.
status
]
if
(
props
.
status
===
3
)
{
return
[
{
class
:
'is-success'
,
name
:
'答对'
},
{
class
:
'is-error'
,
name
:
'答错'
},
{
class
:
'is-info'
,
name
:
'未答'
}
]
}
else
{
return
[
{
class
:
'is-info'
,
name
:
'已答'
},
{
class
:
'is-default'
,
name
:
'未答'
},
{
class
:
'is-success'
,
name
:
'当前'
}
]
}
})
function
genClass
(
data
:
any
,
index
:
number
)
{
// answer(0:未做,1:正确,2:错误)
if
(
props
.
status
===
1
)
{
return
{
'is-info'
:
!!
data
.
user_answer
,
// 已做
'is-success'
:
index
===
questionIndex
// 当前
}
}
if
(
props
.
status
===
2
)
{
if
(
props
.
status
===
3
)
{
return
{
'is-success'
:
data
.
answer
===
1
,
// 答对
'is-error'
:
data
.
answer
===
2
,
// 答错
'is-info'
:
data
.
answer
===
0
// 未答
'is-success'
:
data
.
user_answer_status
,
// 答对
'is-error'
:
!
data
.
user_answer_status
,
// 答错
'is-info'
:
!
data
.
user_answer
// 未答
}
}
if
(
props
.
status
===
3
)
{
}
else
{
return
{
'is-success'
:
data
.
checked_flag
,
// 已批阅
'is-error'
:
!
data
.
checked_flag
,
// 未批阅
'is-info'
:
data
.
answer
===
0
// 未做
'is-info'
:
!!
data
.
user_answer
,
// 已做
'is-success'
:
index
===
questionIndex
// 当前
}
}
}
...
...
src/modules/course/components/CourseViewWork.vue
浏览文件 @
5100075e
...
...
@@ -3,6 +3,8 @@
import
AppUpload
from
'@/components/base/AppUpload.vue'
import
{
ElMessage
}
from
'element-plus'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
AppEditor
from
'@/components/base/AppEditor.vue'
import
{
getCourseWork
,
submitCourseWork
}
from
'../api'
const
{
query
}
=
useRoute
()
...
...
@@ -79,7 +81,7 @@ onMounted(() => {
<el-input
v-model=
"form.title"
/>
</el-form-item>
<el-form-item
label=
"作业正文"
prop=
"password"
>
<
el-input
type=
"textarea"
v-model=
"form.content
"
/>
<
AppEditor
v-model=
"form.content"
:disabled=
"disabled
"
/>
</el-form-item>
<el-form-item
label=
"上传附件"
prop=
"password_r"
>
<AppUpload
v-model=
"form.attachments"
:disabled=
"disabled"
></AppUpload>
...
...
src/modules/course/views/CourseExam.vue
浏览文件 @
5100075e
...
...
@@ -2,19 +2,25 @@
import
type
{
PaperQuestionType
}
from
'@/types'
import
CourseExamCard
from
'../components/CourseExamCard.vue'
import
{
getPaper
}
from
'../api'
const
route
=
useRoute
()
const
courseId
=
$ref
(
route
.
query
.
course_id
as
string
)
const
semesterId
=
$ref
(
route
.
query
.
semester_id
as
string
)
const
paperId
=
$ref
(
route
.
query
.
paper_id
as
string
)
const
type
=
$ref
(
parseInt
(
route
.
query
.
type
as
string
))
const
detail
=
reactive
({
status
:
1
})
const
questionList
=
ref
<
PaperQuestionType
[]
>
([])
provide
(
'questionList'
,
questionList
)
let
questionList
=
$ref
<
PaperQuestionType
[]
>
([])
provide
(
'questionList'
,
$$
(
questionList
))
let
loading
=
$ref
<
boolean
>
(
false
)
// 获取试卷详情
function
fetchInfo
()
{
loading
=
true
getPaper
({
course_id
:
courseId
,
semester_id
:
semesterId
,
paper_id
:
paperId
,
type
}).
then
(
res
=>
{
const
{
question
,
status
,
score_details
}
=
res
.
data
Object
.
assign
(
detail
,
res
.
data
)
questionList
.
value
=
res
.
data
.
question
questionList
=
status
===
3
?
score_details
:
question
loading
=
false
})
}
onMounted
(()
=>
{
...
...
@@ -23,5 +29,5 @@ onMounted(() => {
</
script
>
<
template
>
<CourseExamCard
:status=
"detail.status"
@
update=
"fetchInfo"
></CourseExamCard>
<CourseExamCard
:status=
"detail.status"
@
update=
"fetchInfo"
v-loading=
"loading"
></CourseExamCard>
</
template
>
src/modules/settings/api.ts
浏览文件 @
5100075e
...
...
@@ -7,3 +7,12 @@ export function updateUser(data: { real_name: string; avatar: string; gender: nu
export
function
updatePassword
(
data
:
{
old_password
:
string
;
password
:
string
;
password_r
:
string
})
{
return
httpRequest
.
post
(
'/api/usercenter/v2/frontend/user/change-pwd-by-cookie'
,
data
)
}
// 获取投诉建议列表
export
function
getSuggestionList
(
params
?:
{
page
?:
number
;
limit
?:
number
;
status
?:
string
})
{
return
httpRequest
.
get
(
'/api/saas/api/v1/suggestion/list'
,
{
params
})
}
// 提交投诉建议
export
function
submitSuggestion
(
data
:
{
title
:
string
;
content
:
string
;
files
?:
string
})
{
return
httpRequest
.
post
(
'/api/saas/api/v1/suggestion/complaint'
,
data
)
}
src/modules/settings/components/Suggestions.vue
浏览文件 @
5100075e
<
script
setup
lang=
"ts"
></
script
>
<
script
setup
lang=
"ts"
>
import
type
{
SuggestionType
}
from
'../types'
import
SuggestionsForm
from
'./SuggestionsForm.vue'
import
{
getSuggestionList
}
from
'../api'
const
dialogVisible
=
ref
<
boolean
>
(
false
)
const
dataset
=
reactive
<
{
total
:
number
;
list
:
SuggestionType
[]
}
>
({
total
:
0
,
list
:
[]
})
const
params
=
reactive
({
limit
:
100
,
status
:
''
})
function
fetchList
()
{
getSuggestionList
(
params
).
then
(
res
=>
{
const
{
total
=
0
,
data
=
[]
}
=
res
.
data
dataset
.
total
=
total
dataset
.
list
=
data
})
}
watchEffect
(()
=>
{
fetchList
()
})
function
handleUpdate
()
{
dialogVisible
.
value
=
false
fetchList
()
}
</
script
>
<
template
>
<el-tabs>
<el-tab-pane
label=
"全部"
>
</el-tab-pane>
<el-tab-pane
label=
"待处理"
lazy
></el-tab-pane>
<el-tab-pane
label=
"已处理"
lazy
></el-tab-pane>
<el-tabs
v-model=
"params.status"
>
<el-tab-pane
label=
"全部"
name=
""
>
</el-tab-pane>
<el-tab-pane
label=
"待处理"
name=
"1"
lazy
></el-tab-pane>
<el-tab-pane
label=
"已处理"
name=
"2"
lazy
></el-tab-pane>
</el-tabs>
<el-button
round
>
创建
</el-button>
<el-button
round
type=
"warning"
@
click=
"dialogVisible = true"
style=
"margin-bottom: 20px"
>
创建
</el-button>
<el-collapse
v-if=
"dataset.list.length"
>
<el-collapse-item
v-for=
"item in dataset.list"
:name=
"item.id"
:key=
"item.id"
>
<template
#
title
>
<el-button
type=
"primary"
size=
"small"
round
style=
"margin-right: 10px"
v-if=
"item.status === 1"
>
待处理
</el-button
>
<el-button
color=
"#E8E8E8"
size=
"small"
round
style=
"margin-right: 10px"
v-if=
"item.status === 2"
>
已处理
</el-button
>
<h2
class=
"suggestion-title"
>
{{
item
.
title
}}
</h2>
</
template
>
<div
class=
"suggestion-main"
>
<div
class=
"suggestion-content"
v-html=
"item.content"
></div>
<a
:href=
"item.files"
target=
"_blank"
class=
"suggestion-file"
v-if=
"item.files"
>
下载附件
</a>
<p
class=
"t1"
>
发布于:{{ item.created_time }}
</p>
<
template
v-if=
"item.status === 2"
>
<h2
class=
"suggestion-title"
>
问题回复
</h2>
<div
class=
"suggestion-content"
v-html=
"item.reply"
></div>
</
template
>
</div>
</el-collapse-item>
</el-collapse>
<SuggestionsForm
v-model=
"dialogVisible"
@
update=
"handleUpdate"
></SuggestionsForm>
</template>
<
style
lang=
"scss"
scoped
>
.suggestion-main
{
margin-left
:
70px
;
.t1
{
margin-top
:
10px
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
24px
;
color
:
#999999
;
}
.suggestion-title
{
margin-top
:
28px
;
}
}
.suggestion-title
{
font-size
:
16px
;
font-weight
:
500
;
line-height
:
27px
;
color
:
#333333
;
}
.suggestion-content
{
font-size
:
14px
;
font-weight
:
400
;
line-height
:
24px
;
color
:
#666666
;
:deep
(
img
)
{
max-width
:
100%
;
}
}
</
style
>
src/modules/settings/components/SuggestionsForm.vue
0 → 100644
浏览文件 @
5100075e
<
script
setup
lang=
"ts"
>
import
{
ElMessage
}
from
'element-plus'
import
AppUpload
from
'@/components/base/AppUpload.vue'
import
AppEditor
from
'@/components/base/AppEditor.vue'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
submitSuggestion
}
from
'../api'
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
}
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
title
:
''
,
content
:
''
,
files
:
''
})
const
rules
=
ref
<
FormRules
>
({
title
:
[{
required
:
true
,
message
:
'请输入问题描述'
,
trigger
:
'blur'
}],
content
:
[{
required
:
true
,
message
:
'请输入问题详情'
,
trigger
:
'blur'
}]
})
// 提交
function
handleSubmit
()
{
formRef
?.
validate
().
then
(
update
)
}
// 修改
const
update
=
()
=>
{
submitSuggestion
(
form
).
then
(()
=>
{
ElMessage
({
message
:
'提交成功'
,
type
:
'success'
})
emit
(
'update'
)
formRef
?.
resetFields
()
})
}
</
script
>
<
template
>
<el-dialog
title=
"投诉建议"
width=
"800px"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
hide-required-asterisk
label-position=
"top"
>
<el-form-item
label=
"问题描述"
prop=
"title"
>
<el-input
v-model=
"form.title"
/>
</el-form-item>
<el-form-item
label=
"问题详情"
prop=
"content"
>
<AppEditor
v-model=
"form.content"
/>
</el-form-item>
<el-form-item
label=
"上传附件"
prop=
"files"
>
<AppUpload
v-model=
"form.files"
>
<el-button
round
>
点击上传
</el-button>
<p>
{{
form
.
files
}}
</p>
</AppUpload>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
round
auto-insert-space
@
click=
"handleSubmit"
>
提交
</el-button>
</el-form-item>
</el-form>
</el-dialog>
</
template
>
src/modules/settings/components/SuggestionsItem.vue
deleted
100644 → 0
浏览文件 @
c6ef9ea4
<
script
setup
lang=
"ts"
></
script
>
<
template
>
<el-tabs>
<el-tab-pane
label=
"全部"
>
</el-tab-pane>
<el-tab-pane
label=
"待处理"
lazy
></el-tab-pane>
<el-tab-pane
label=
"已处理"
lazy
></el-tab-pane>
</el-tabs>
<el-button
round
>
创建
</el-button>
</
template
>
src/modules/settings/types.ts
0 → 100644
浏览文件 @
5100075e
export
interface
SuggestionType
{
content
:
string
created_time
:
string
files
:
string
id
:
string
reply
:
string
title
:
string
status
:
1
|
2
}
src/types.ts
浏览文件 @
5100075e
...
...
@@ -146,6 +146,7 @@ export interface PaperQuestionType {
score
:
number
children
?:
PaperQuestionType
[]
user_answer
:
string
reviews
?:
string
}
export
interface
PaperQuestionOptionType
{
checked_option
:
string
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论