提交 1bb22bb8 authored 作者: 王鹏飞's avatar 王鹏飞

feat: 实验大赛规则增加成绩规则

上级 bb6e583b
<script setup lang="ts"> <script setup lang="ts">
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { getCompetitionRule, saveCompetitionRule } from '../api' import { getCompetitionRule, saveCompetitionRule } from '../api'
interface Props { interface Props {
...@@ -9,6 +10,18 @@ const props = defineProps<Props>() ...@@ -9,6 +10,18 @@ const props = defineProps<Props>()
const dialogVisible = ref(false) const dialogVisible = ref(false)
const gradeRuleList = [
{ label: '商品品类管理', value: 1 },
{ label: '商品属性管理', value: 2 },
{ label: '商品管理', value: 3 },
{ label: '直播话术管理', value: 4 },
{ label: '直播演练', value: 5 },
{ label: '直播总结汇报', value: 6 },
]
const defaultConfig = {
min_submit_time: '',
rules: [] as any[],
}
const formRef = ref() const formRef = ref()
const form = reactive({ const form = reactive({
name: '', name: '',
...@@ -16,6 +29,7 @@ const form = reactive({ ...@@ -16,6 +29,7 @@ const form = reactive({
end_time: '', end_time: '',
questions: '1', questions: '1',
competition: '1', competition: '1',
config: { ...defaultConfig },
}) })
const rules = ref({ const rules = ref({
...@@ -33,11 +47,23 @@ const options = ref([ ...@@ -33,11 +47,23 @@ const options = ref([
const competitionOptions = ref([ const competitionOptions = ref([
{ label: '网络主播赛项', value: '1' }, { label: '网络主播赛项', value: '1' },
{ label: '全媒体运营赛项', value: '2' }, { label: '全媒体运营赛项', value: '2' },
{ label: '互联网营销师(直播销售)', value: '3' },
]) ])
async function fetchInfo() { async function fetchInfo() {
const res = await getCompetitionRule({ experiment_id: props.id }) const res = await getCompetitionRule({ experiment_id: props.id })
Object.assign(form, res.data.detail) const detail = res.data.detail
if (!detail) return
let config = { ...defaultConfig }
try {
if (detail.config) {
config = JSON.parse(detail.config)
config = { ...defaultConfig, ...config }
}
} catch (error) {
console.log(error)
}
Object.assign(form, detail, { config })
} }
watch( watch(
...@@ -50,17 +76,93 @@ watch( ...@@ -50,17 +76,93 @@ watch(
// 提交 // 提交
async function handleSubmit() { async function handleSubmit() {
// 验证成绩规则
for (let i = 0; i < form.config.rules.length; i++) {
const item = form.config.rules[i]
if (!item.name || !item.type) {
ElMessage.error(`实操成绩第${i + 1}行规则配置错误,请检查后重试`)
return
}
if (!item.percent) {
ElMessage.error(`${item.name}分数不能为0!`)
return
}
}
if (form.config.rules.length > 0 && total.value !== 100) {
ElMessage.error('成绩规则项分数之和必须为100!')
return
}
await formRef.value?.validate() await formRef.value?.validate()
await saveCompetitionRule({ ...form, experiment_id: props.id }) const params = { ...form, experiment_id: props.id, config: JSON.stringify(form.config) }
await saveCompetitionRule(params)
ElMessage.success('保存成功') ElMessage.success('保存成功')
dialogVisible.value = false dialogVisible.value = false
} }
// 合计
const total = computed(() => {
return form.config.rules.reduce((result: number, item: any) => {
return result + (item.percent || 0)
}, 0)
})
// 添加
function handleAdd() {
form.config.rules.push({ name: '', type: undefined, percent: undefined, rule_mode: 1 })
}
// 删除
function handleRemove(index: number) {
form.config.rules.splice(index, 1)
}
// 当前评分方法
function currentRuleNames(value: number) {
const typeList = form.config.rules.map((item: any) => item.type)
const tempList = gradeRuleList.filter((item) => {
return item.value === value || !typeList.includes(item.value)
})
return tempList
}
function handleTypeChange(row: any) {
row.rule_mode = 1
if (row.type === 5) return
row.name = gradeRuleList.find((item: any) => item.value === row.type)?.label
}
// 占比改变
function handlePercentChange(row: any, index: number) {
const otherTotal = form.config.rules.reduce((result: number, item: any, i: number) => {
if (index !== i) {
result += item.percent || 0
}
return result
}, 0)
// 最大可输入占比
nextTick(() => {
row.percent = Math.min(100 - otherTotal, row.percent)
})
}
const currentRole = ref()
const currentRoleDialogVisible = ref(false)
function handleEdit(row: any) {
currentRole.value = row
currentRoleDialogVisible.value = true
}
// 最短交卷时间禁用日期:必须大于开始时间且小于结束时间
function disabledMinSubmitDate(time: Date) {
const startTime = form.start_time ? new Date(form.start_time).getTime() : 0
const endTime = form.end_time ? new Date(form.end_time).getTime() : Infinity
return time.getTime() < startTime || time.getTime() > endTime
}
</script> </script>
<template> <template>
<el-button type="primary" @click="dialogVisible = true">编辑大赛规则</el-button> <el-button type="primary" @click="dialogVisible = true">编辑大赛规则</el-button>
<el-dialog title="编辑大赛规则" :close-on-click-modal="false" width="500px" v-model="dialogVisible" append-to-body> <el-dialog title="编辑大赛规则" :close-on-click-modal="false" width="800px" v-model="dialogVisible" append-to-body>
<el-form ref="formRef" :model="form" :rules="rules" label-position="right" label-width="80px"> <el-form ref="formRef" :model="form" :rules="rules" label-position="right" label-width="100px">
<el-form-item label="大赛名称" prop="name"> <el-form-item label="大赛名称" prop="name">
<el-input v-model="form.name" placeholder="请输入大赛名称" /> <el-input v-model="form.name" placeholder="请输入大赛名称" />
</el-form-item> </el-form-item>
...@@ -89,11 +191,68 @@ async function handleSubmit() { ...@@ -89,11 +191,68 @@ async function handleSubmit() {
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%" /> style="width: 100%" />
</el-form-item> </el-form-item>
<el-form-item label="最短交卷时间" prop="config.min_submit_time">
<el-date-picker
v-model="form.config.min_submit_time"
type="datetime"
placeholder="请选择最短交卷时间"
value-format="YYYY-MM-DD HH:mm:ss"
:disabled-date="disabledMinSubmitDate"
style="width: 100%" />
</el-form-item>
<el-form-item label="试题" prop="questions"> <el-form-item label="试题" prop="questions">
<el-select v-model="form.questions" style="width: 100%" placeholder="请选择" filterable> <el-select v-model="form.questions" style="width: 100%" placeholder="请选择" filterable>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-divider />
<el-form-item label-width="0">
<el-row justify="space-between" style="width: 100%">
<p>成绩规则:</p>
<el-button type="primary" :icon="Plus" @click="handleAdd"></el-button>
</el-row>
<el-table :data="form.config.rules">
<el-table-column prop="name" width="170">
<template #default="{ row }">
<el-select v-model="row.type" style="width: 100%" @change="handleTypeChange(row)">
<el-option v-for="item in currentRuleNames(row.type)" :key="item.value" v-bind="item"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="percent" align="center" width="200">
<template #default="{ row, $index }">
<el-input-number v-model="row.percent" :min="0" :max="100" @change="handlePercentChange(row, $index)" />
</template>
</el-table-column>
<el-table-column prop="rule_mode" width="200">
<template #default="{ row }">
<el-radio-group v-model="row.rule_mode" size="small">
<el-radio :label="1">人工评分</el-radio>
<el-radio :label="2" :disabled="[4, 5, 6].includes(row.type)">自动评分</el-radio>
</el-radio-group>
</template>
</el-table-column>
<el-table-column align="center">
<template #default="{ $index, row }">
<div class="btn-box">
<el-button
style="padding: 0"
text
type="primary"
@click="handleEdit(row)"
:disabled="[4, 5, 6].includes(row.type) || row.rule_mode === 1"
>编辑</el-button
>
<el-button style="padding: 0" text type="primary" @click="handleRemove($index)">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="total" v-if="form.config.rules.length">
<p>合计:{{ total }}分</p>
</div>
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-row justify="center"> <el-row justify="center">
...@@ -102,4 +261,33 @@ async function handleSubmit() { ...@@ -102,4 +261,33 @@ async function handleSubmit() {
</el-row> </el-row>
</template> </template>
</el-dialog> </el-dialog>
<el-drawer
title="编辑大赛评分规则提示词"
:close-on-click-modal="false"
v-model="currentRoleDialogVisible"
append-to-body>
<el-input v-model="currentRole.content" type="textarea" placeholder="请输入提示词" :rows="20" />
<template #footer>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="currentRoleDialogVisible = false">确定</el-button>
</el-row>
</template>
</el-drawer>
</template> </template>
<style lang="scss" scoped>
.total {
width: 100%;
padding: 10px 0;
box-sizing: border-box;
text-align: right;
p {
display: inline-block;
min-width: 120px;
text-align: center;
color: #016fa0;
background-color: #ededed;
padding: 5px 10px;
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论