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

chore: update

上级 24a06d04
...@@ -49,7 +49,6 @@ function handleUpdate(row: BookItem) { ...@@ -49,7 +49,6 @@ function handleUpdate(row: BookItem) {
} }
function onUpdateSuccess() { function onUpdateSuccess() {
dialogVisible = false
appList?.refetch() appList?.refetch()
} }
</script> </script>
......
...@@ -17,3 +17,13 @@ export function getDiscussList(params?: { ...@@ -17,3 +17,13 @@ export function getDiscussList(params?: {
export function getFilterList() { export function getFilterList() {
return httpRequest.get('/api/lab/v1/teacher/discussion/search-list') return httpRequest.get('/api/lab/v1/teacher/discussion/search-list')
} }
// 获取讨论交流详情
export function getDiscuss(params: { id: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/lab/v1/teacher/discussion/view', { params })
}
// 获取讨论交流详情
export function submitDiscussComment(data: { id: string; content: string }) {
return httpRequest.post('/api/lab/v1/teacher/discussion/comment', data)
}
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { DiscussListItem, DiscussInfo, DiscussCommentItem } from '../types'
import { Loading } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { useInfiniteScroll } from '@vueuse/core'
import DiscussItem from './DiscussItem.vue'
import { getDiscuss, submitDiscussComment } from '../api'
interface Props {
data: DiscussListItem
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const params = reactive({ id: props.data.id, page: 1, 'per-page': 10 })
let hasMore = $ref(false)
let isLoading = $ref(false)
const detail = reactive<{ info?: DiscussInfo; list: DiscussCommentItem[] }>({ info: undefined, list: [] })
function fetchInfo(isForce = false) {
if (!props.data.id) return
if (isForce) {
params.page = 1
}
isLoading = true
getDiscuss(params)
.then(res => {
detail.info = res.data.info
detail.list = isForce ? res.data.list : [...detail.list, ...res.data.list]
hasMore = !!res.data.list.length
})
.finally(() => {
isLoading = false
})
}
watch(
() => props.data.id,
() => {
fetchInfo(true)
},
{ immediate: true }
)
// 滚动加载
const scrollRef = ref<HTMLElement>()
useInfiniteScroll(
scrollRef,
() => {
if (!hasMore || isLoading) return
params.page++
fetchInfo()
},
{ distance: 10 }
)
const formRef = $ref<FormInstance>()
const form = reactive<{ content: string }>({ content: '' })
const rules = ref<FormRules>({
content: [{ required: true, message: '请输入回复内容' }]
})
// 提交
function handleSubmit() {
formRef?.validate().then(() => {
const params = { ...form, id: props.data.id }
submitDiscussComment(params).then(() => {
ElMessage({ message: '回复成功', type: 'success' })
emit('update')
fetchInfo(true)
formRef?.resetFields()
})
})
}
</script>
<template>
<el-dialog title="实验话题讨论" :close-on-click-modal="false" @update:modelValue="$emit('update:modelValue')">
<div class="discuss-scroll" ref="scrollRef">
<DiscussItem :info="detail.info" :list="detail.list" v-if="detail.info"></DiscussItem>
<div class="tips" v-if="isLoading">
<el-icon class="is-loading">
<Loading />
</el-icon>
加载中...
</div>
<div class="tips" v-if="!hasMore">没有更多了</div>
</div>
<el-form ref="formRef" :rules="rules" :model="form" style="margin-top: 40px">
<el-form-item prop="content">
<el-input type="textarea" v-model="form.content" :autosize="{ minRows: 4, maxRows: 6 }" />
</el-form-item>
<el-row justify="end">
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
<el-button type="primary" round auto-insert-space @click="handleSubmit">保存回复</el-button>
</el-row>
</el-form>
</el-dialog>
</template>
<style lang="scss" scoped>
.discuss-scroll {
max-height: 400px;
overflow-y: auto;
}
.tips {
padding: 40px;
color: #555;
text-align: center;
}
.el-icon.is-loading {
animation: rotating 2s linear infinite;
}
</style>
<script setup lang="ts">
import type { DiscussInfo, DiscussCommentItem } from '../types'
import { ChatLineRound } from '@element-plus/icons-vue'
interface Props {
info: DiscussInfo
list: DiscussCommentItem[]
}
defineProps<Props>()
defineEmits<{
(e: 'update'): void
}>()
</script>
<template>
<div class="discuss-item">
<div class="discuss-box">
<div class="discuss-box-user">
<img :src="info.created_operator_avatar" />
<p>{{ info.student_id_name }}</p>
</div>
<div class="discuss-box-main">
<div class="discuss-box-header">
<p class="discuss-box-time">{{ info.created_time }}</p>
<div class="tools">
<el-icon><ChatLineRound></ChatLineRound></el-icon>{{ info.replies_num }}
</div>
</div>
<h3>{{ info.title }}</h3>
<div class="discuss-box-content" v-html="info.content"></div>
</div>
</div>
<div class="discuss-box discuss-comment" v-for="item in list" :key="item.id">
<div class="discuss-box-user">
<img :src="item.sso_id_avatar" />
<p>{{ item.sso_id_name }}</p>
</div>
<div class="discuss-box-main">
<p class="discuss-box-time">{{ item.created_time }}</p>
<div class="discuss-box-content" v-html="item.content"></div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.discuss-box {
display: flex;
margin: 10px 0;
padding: 10px;
font-size: 12px;
color: var(--main-color);
border-radius: 10px;
border: 1px solid var(--main-color);
&.discuss-comment {
margin-left: 40px;
color: #016fa0;
border: 1px solid #016fa0;
}
}
.discuss-box-user {
img {
width: 50px;
height: 50px;
border-radius: 50%;
overflow: hidden;
object-fit: cover;
}
p {
text-align: center;
}
}
.discuss-box-main {
flex: 1;
padding-left: 10px;
h3 {
font-size: 14px;
font-weight: 500;
}
}
.discuss-box-content {
padding: 5px 0;
color: #555;
}
.discuss-box-header {
display: flex;
align-items: center;
justify-content: space-between;
.tools {
display: flex;
align-items: center;
.el-icon {
font-size: 16px;
margin-left: 10px;
margin-right: 5px;
color: #333333;
}
}
}
</style>
export interface DiscussListItem {
class_id: string
class_id_name: string
course_id: string
course_id_name: string
created_time: string
experiment_id: string
experiment_id_name: string
id: string
is_reply: string
is_reply_name: string
replies_num: number
sno_number: string
specialty_id: string
specialty_id_name: string
student_id: string
student_name: string
title: string
}
export interface DiscussInfo {
content: string
created_operator: string
created_operator_avatar: string
created_time: string
delete_time: string
experiment_id: string
id: string
is_reply: string
replies_num: number
status: string
student_id: string
student_id_name: string
title: string
updated_operator: string
updated_time: string
}
export interface DiscussCommentItem {
content: string
created_time: string
discussion_id: string
id: string
role: string
sso_id: string
sso_id_avatar: string
sso_id_name: string
}
<script setup lang="ts"> <script setup lang="ts">
import type { DiscussListItem } from '../types'
import AppList from '@/components/base/AppList.vue'
import { getDiscussList } from '../api' import { getDiscussList } from '../api'
import { useFilterList } from '../composables/useFilterList' import { useFilterList } from '../composables/useFilterList'
const DiscussDialog = defineAsyncComponent(() => import('../components/DiscussDialog.vue'))
const { courses, experiments, specialties, classes } = useFilterList() const { courses, experiments, specialties, classes } = useFilterList()
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置 // 列表配置
const listOptions = $computed(() => { const listOptions = $computed(() => {
return { return {
...@@ -65,25 +71,42 @@ const listOptions = $computed(() => { ...@@ -65,25 +71,42 @@ const listOptions = $computed(() => {
] ]
} }
}) })
let dialogVisible = $ref(false)
const rowData = ref<DiscussListItem>()
// 评论
function handleComment(row: DiscussListItem) {
rowData.value = row
dialogVisible = true
}
function onUpdateSuccess() {
appList?.refetch()
}
</script> </script>
<template> <template>
<AppCard title="实验讨论交流"> <AppCard title="实验讨论交流">
<AppList v-bind="listOptions"> <AppList v-bind="listOptions" ref="appList">
<template #table-replies-num="{ row }"> <template #table-replies-num="{ row }">
<span :class="{ 'is-info': !!row.replies_num }">{{ row.replies_num }}</span> <span :class="{ 'is-info': !!row.replies_num }">{{ row.replies_num }}</span>
</template> </template>
<template #table-reply="{ row }"> <template #table-reply="{ row }">
<span :class="{ 'is-success': row.is_reply === '1' }">{{ row.is_reply_name }}</span> <span :class="{ 'is-success': row.is_reply === '1' }">{{ row.is_reply_name }}</span>
</template> </template>
<template #table-x> <template #table-x="{ row }">
<el-button text type="primary">评论</el-button> <el-button text type="primary" @click="handleComment(row)">评论</el-button>
</template> </template>
</AppList> </AppList>
</AppCard> </AppCard>
<DiscussDialog
v-model="dialogVisible"
:data="rowData"
@update="onUpdateSuccess"
v-if="dialogVisible && rowData"
></DiscussDialog>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
.is-success { .is-success {
color: #63a103; color: #63a103;
} }
......
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
// 获取实验成绩列表 // 获取实验记录列表
export function getExperimentRecordList(params?: { export function getExperimentRecordList(params?: {
course_id?: string course_id?: string
experiment_id?: string experiment_id?: string
...@@ -17,3 +17,26 @@ export function getExperimentRecordList(params?: { ...@@ -17,3 +17,26 @@ export function getExperimentRecordList(params?: {
export function getFilterList() { export function getFilterList() {
return httpRequest.get('/api/lab/v1/teacher/record/search-list') return httpRequest.get('/api/lab/v1/teacher/record/search-list')
} }
// 获取实验记录详情
export function getExperimentRecord(params: { experiment_id: string; student_id: string }) {
return httpRequest.get('/api/lab/v1/teacher/record/view', { params })
}
// 实验记录评分
export function checkExperimentRecord(data: {
experiment_id: string
student_id: string
operate: number
result: number
file: number
}) {
return httpRequest.post('/api/lab/v1/teacher/record/check', data)
}
// 批量导入实验记录评分
export function uploadCheckExperimentRecord(data: { file: File }) {
return httpRequest.post('/api/lab/v1/teacher/record/check', data, {
headers: { 'Content-Type': 'multipart/form-data' }
})
}
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { RecordItem, FileItem } from '../types'
import { Document } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getExperimentRecord, checkExperimentRecord } from '../api'
interface Props {
data: RecordItem
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
let detail = $ref<RecordItem>()
function fetchInfo() {
getExperimentRecord({ experiment_id: props.data.experiment_id, student_id: props.data.student_id }).then(res => {
detail = res.data
})
}
watchEffect(() => {
fetchInfo()
})
// 实验报告文件
const file = $computed<FileItem>(() => {
try {
return detail?.file ? JSON.parse(detail.file) : null
} catch (error) {
console.log(error)
}
return null
})
// 实验过程截图
const pictures = $computed<FileItem[]>(() => {
try {
return detail?.pictures ? JSON.parse(detail.pictures) : []
} catch (error) {
console.log(error)
}
return []
})
const formRef = $ref<FormInstance>()
const form = reactive<{ operate?: number; result?: number; file?: number }>({
operate: undefined,
result: undefined,
file: undefined
})
const score = $computed<number>(() => {
const result = ((form.operate || 0) + (form.result || 0) + (form.file || 0)) / 3
return parseFloat(result.toFixed(2))
})
const rules = ref<FormRules>({
operate: [{ required: true, message: '请输入0~100数字' }],
result: [{ required: true, message: '请输入0~100数字' }],
file: [{ required: true, message: '请输入0~100数字' }]
})
// 提交
function handleSubmit() {
formRef?.validate().then(() => {
ElMessageBox.confirm('成绩评分不能修改,确认要保存该成绩吗?', '提示').then(() => {
const params: any = { ...form, experiment_id: props.data.experiment_id, student_id: props.data.student_id }
checkExperimentRecord(params).then(() => {
ElMessage({ message: '保存成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
})
})
})
}
</script>
<template>
<el-dialog title="学生实验评分" :close-on-click-modal="false" @update:modelValue="$emit('update:modelValue')">
<el-form :rules="rules" label-width="120px" label-suffix=":" v-if="detail">
<el-form-item label="实验名称">{{ detail.experiment_name }}</el-form-item>
<el-form-item label="实验课程名称">{{ detail.course_name }}</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="学生姓名">{{ detail.student_name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学生学号">{{ detail.sno_number }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="所属专业">{{ detail.specialty_name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属班级">{{ detail.class_name }}</el-form-item>
</el-col>
</el-row>
<el-form-item label="实验报告文件">
<p v-if="file">
<a :href="file.url" target="_blank">
<el-icon><Document /></el-icon>{{ file.name }}
</a>
</p>
</el-form-item>
<el-form-item label="实验过程截图">
<ul class="picture-list">
<li v-for="item in pictures" :key="item.url">
<p class="t1">
<a :href="item.url" target="_blank">{{ item.name }}</a>
</p>
<p class="t2">截图时间:{{ item.upload_time }}</p>
</li>
</ul>
</el-form-item>
<el-form-item label="实验成绩">
<el-form
ref="formRef"
:model="form"
:rules="rules"
hide-required-asterisk
inline
label-position="top"
style="padding: 5px 0 20px"
>
<el-form-item label="实验操作" prop="operate">
<el-input-number :min="0" :max="100" :controls="false" step-strictly v-model="form.operate" />
</el-form-item>
<el-form-item label="实验结果" prop="result">
<el-input-number :min="0" :max="100" :controls="false" step-strictly v-model="form.result" />
</el-form-item>
<el-form-item label="实验报告" prop="file">
<el-input-number :min="0" :max="100" :controls="false" step-strictly v-model="form.file" />
</el-form-item>
<el-form-item label="综合实验成绩">
<el-input-number :min="0" :max="100" :controls="false" disabled v-model="score" />
</el-form-item>
</el-form>
</el-form-item>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="handleSubmit">保存</el-button>
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
</el-row>
</el-form>
</el-dialog>
</template>
<style lang="scss" scoped>
.picture-list {
width: 100%;
li {
display: flex;
justify-content: space-between;
}
a {
color: blue;
}
.t1 {
flex: 1;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.t2 {
flex: 1;
}
}
</style>
...@@ -3,7 +3,7 @@ import AppLayout from '@/components/layout/Index.vue' ...@@ -3,7 +3,7 @@ import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [ export const routes: Array<RouteRecordRaw> = [
{ {
path: '/admin/lab/score', path: '/admin/lab/record',
component: AppLayout, component: AppLayout,
children: [{ path: '', component: () => import('./views/Index.vue') }] children: [{ path: '', component: () => import('./views/Index.vue') }]
} }
......
export interface RecordItem {
check_time: string
checker_id?: string
class_id: string
class_name: string
commit_time: string
course_name?: string
experiment_id: string
experiment_name: string
file?: string
pictures?: string
score: string
score_details?: string
sno_number: string
specialty_id: string
specialty_name: string
status: 0 | 1 | 2
status_name: string
student_id: string
student_name: string
}
export interface FileItem {
name: string
url: string
upload_time: string
}
<script setup lang="ts"> <script setup lang="ts">
import type { RecordItem } from '../types'
import { Upload, Promotion } from '@element-plus/icons-vue' import { Upload, Promotion } from '@element-plus/icons-vue'
import { getExperimentRecordList } from '../api' import AppList from '@/components/base/AppList.vue'
import { getExperimentRecordList, uploadCheckExperimentRecord } from '../api'
import { useFilterList } from '../composables/useFilterList' import { useFilterList } from '../composables/useFilterList'
import { useFileDialog } from '@vueuse/core'
const ScoreDialog = defineAsyncComponent(() => import('../components/ScoreDialog.vue'))
const { courses, experiments, specialties, classes } = useFilterList() const { courses, experiments, specialties, classes } = useFilterList()
const LAB_URL = import.meta.env.VITE_LAB_URL const LAB_URL = import.meta.env.VITE_LAB_URL
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置 // 列表配置
const listOptions = $computed(() => { const listOptions = $computed(() => {
return { return {
...@@ -68,14 +74,41 @@ const listOptions = $computed(() => { ...@@ -68,14 +74,41 @@ const listOptions = $computed(() => {
] ]
} }
}) })
// 批量导入
const { files, open } = useFileDialog()
function handleImport() {
open({
accept: '.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel',
multiple: false
})
}
watchEffect(() => {
if (!files.value?.length) return
const [file] = files.value
uploadCheckExperimentRecord({ file }).then(() => {
appList?.refetch()
})
})
let dialogVisible = $ref(false)
const rowData = ref<RecordItem>()
// 评分
function handleScore(row: RecordItem) {
rowData.value = row
dialogVisible = true
}
function onUpdateSuccess() {
appList?.refetch()
}
</script> </script>
<template> <template>
<AppCard title="实验成绩管理"> <AppCard title="实验成绩管理">
<AppList v-bind="listOptions"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-row justify="space-between"> <el-row justify="space-between">
<el-button type="primary" round :icon="Upload">批量导入</el-button> <el-button type="primary" round :icon="Upload" @click="handleImport">批量导入</el-button>
<a :href="LAB_URL" target="_blank"> <a :href="LAB_URL" target="_blank">
<el-button type="primary" round :icon="Promotion">进入实验室</el-button> <el-button type="primary" round :icon="Promotion">进入实验室</el-button>
</a> </a>
...@@ -88,13 +121,19 @@ const listOptions = $computed(() => { ...@@ -88,13 +121,19 @@ const listOptions = $computed(() => {
<span :class="{ 'is-info': row.score !== '--' }">{{ row.score }}</span> <span :class="{ 'is-info': row.score !== '--' }">{{ row.score }}</span>
</template> </template>
<template #table-x="{ row }"> <template #table-x="{ row }">
<el-button text type="primary" v-if="row.status === 1">打分</el-button> <el-button text type="primary" v-if="row.status === 1" @click="handleScore(row)">打分</el-button>
</template> </template>
</AppList> </AppList>
</AppCard> </AppCard>
<ScoreDialog
v-model="dialogVisible"
:data="rowData"
@update="onUpdateSuccess"
v-if="dialogVisible && rowData"
></ScoreDialog>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
.is-success { .is-success {
color: #63a103; color: #63a103;
} }
......
...@@ -49,7 +49,6 @@ function handleUpdate(row: VideoItem) { ...@@ -49,7 +49,6 @@ function handleUpdate(row: VideoItem) {
} }
function onUpdateSuccess() { function onUpdateSuccess() {
dialogVisible = false
appList?.refetch() appList?.refetch()
} }
</script> </script>
......
...@@ -36,11 +36,12 @@ onMounted(() => { ...@@ -36,11 +36,12 @@ onMounted(() => {
<el-descriptions-item label="创建人:">{{ detail.created_operator_name }}</el-descriptions-item> <el-descriptions-item label="创建人:">{{ detail.created_operator_name }}</el-descriptions-item>
<el-descriptions-item label="创建时间:">{{ detail.created_time }}</el-descriptions-item> <el-descriptions-item label="创建时间:">{{ detail.created_time }}</el-descriptions-item>
</el-descriptions> </el-descriptions>
<div style="height: 600px" v-if="playUrl">
<AppVideoPlayer <AppVideoPlayer
:options="{ sources: [{ src: playUrl, type: 'application/x-mpegURL' }] }" :options="{ sources: [{ src: playUrl, type: 'application/x-mpegURL' }] }"
style="width: 100%; height: 600px" style="width: 100%; height: 100%"
v-if="playUrl"
></AppVideoPlayer> ></AppVideoPlayer>
</div>
</template> </template>
</AppCard> </AppCard>
</template> </template>
...@@ -52,7 +52,6 @@ function handleUpdate(row: ExperimentItem) { ...@@ -52,7 +52,6 @@ function handleUpdate(row: ExperimentItem) {
} }
function onUpdateSuccess() { function onUpdateSuccess() {
dialogVisible = false
appList?.refetch() appList?.refetch()
} }
</script> </script>
......
...@@ -10,23 +10,32 @@ interface Props { ...@@ -10,23 +10,32 @@ interface Props {
experiment_id?: string experiment_id?: string
} }
const props = defineProps<Props>() const props = defineProps<Props>()
const params = reactive({ tag: 1, page: 0, 'per-page': 10 }) const params = reactive({ tag: 1, page: 1, 'per-page': 10 })
let list = $ref<ExperimentDiscussType[]>([]) let list = $ref<ExperimentDiscussType[]>([])
let hasMore = $ref(false) let hasMore = $ref(false)
let isLoading = $ref(false) let isLoading = $ref(false)
function fetchInfo() { function fetchInfo(isForce = false) {
if (!props.experiment_id) return if (!props.experiment_id) return
if (isForce) {
params.page = 1
}
isLoading = true isLoading = true
getExperimentDiscussList({ ...params, experiment_id: props.experiment_id }) getExperimentDiscussList({ ...params, experiment_id: props.experiment_id })
.then(res => { .then(res => {
list = params.page ? [...list, ...res.data.list] : res.data.list list = isForce ? res.data.list : [...list, ...res.data.list]
hasMore = !!res.data.list.length hasMore = !!res.data.list.length
}) })
.finally(() => { .finally(() => {
isLoading = false isLoading = false
}) })
} }
watch(() => props.experiment_id, handleRefetch, { immediate: true }) watch(
() => props.experiment_id,
() => {
fetchInfo(true)
},
{ immediate: true }
)
const isEmpty = $computed(() => { const isEmpty = $computed(() => {
return !props.experiment_id || !list.length return !props.experiment_id || !list.length
...@@ -34,18 +43,12 @@ const isEmpty = $computed(() => { ...@@ -34,18 +43,12 @@ const isEmpty = $computed(() => {
const dialogVisible = $ref(false) const dialogVisible = $ref(false)
// 刷新
function handleRefetch() {
params.page = 0
fetchInfo()
}
// 滚动加载 // 滚动加载
const scrollRef = ref<HTMLElement>() const scrollRef = ref<HTMLElement>()
useInfiniteScroll( useInfiniteScroll(
scrollRef, scrollRef,
() => { () => {
if (!hasMore) return if (!hasMore || isLoading) return
params.page++ params.page++
fetchInfo() fetchInfo()
}, },
...@@ -55,7 +58,7 @@ useInfiniteScroll( ...@@ -55,7 +58,7 @@ useInfiniteScroll(
<template> <template>
<div class="discuss"> <div class="discuss">
<el-radio-group v-model="params.tag" @change="handleRefetch"> <el-radio-group v-model="params.tag" @change="fetchInfo(true)">
<el-radio :label="1">我发起的</el-radio> <el-radio :label="1">我发起的</el-radio>
<el-radio :label="2">我回复的</el-radio> <el-radio :label="2">我回复的</el-radio>
<el-radio :label="3">我的小组</el-radio> <el-radio :label="3">我的小组</el-radio>
...@@ -67,7 +70,7 @@ useInfiniteScroll( ...@@ -67,7 +70,7 @@ useInfiniteScroll(
<el-empty description="暂无数据" v-if="isEmpty" /> <el-empty description="暂无数据" v-if="isEmpty" />
<template v-else> <template v-else>
<div class="discuss-scroll" ref="scrollRef"> <div class="discuss-scroll" ref="scrollRef">
<DiscussItem v-for="item in list" :key="item.id" :data="item" @update="handleRefetch"></DiscussItem> <DiscussItem v-for="item in list" :key="item.id" :data="item" @update="fetchInfo(true)"></DiscussItem>
<div class="tips" v-if="isLoading"> <div class="tips" v-if="isLoading">
<el-icon class="is-loading"> <el-icon class="is-loading">
<Loading /> <Loading />
...@@ -82,7 +85,7 @@ useInfiniteScroll( ...@@ -82,7 +85,7 @@ useInfiniteScroll(
<DiscussAddDialog <DiscussAddDialog
v-model="dialogVisible" v-model="dialogVisible"
:experiment_id="experiment_id" :experiment_id="experiment_id"
@update="handleRefetch" @update="fetchInfo(true)"
v-if="dialogVisible && experiment_id" v-if="dialogVisible && experiment_id"
></DiscussAddDialog> ></DiscussAddDialog>
</template> </template>
......
import type { IMenuItem } from '@/types' import type { IMenuItem } from '@/types'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { Notebook, Tickets, VideoCamera, ChatSquare, Finished, ScaleToOriginal } from '@element-plus/icons-vue' import { Notebook, VideoCamera, ChatSquare, Finished, ScaleToOriginal } from '@element-plus/icons-vue'
interface State { interface State {
studentMenus: IMenuItem[] studentMenus: IMenuItem[]
...@@ -42,7 +42,7 @@ const adminMenus: IMenuItem[] = [ ...@@ -42,7 +42,7 @@ const adminMenus: IMenuItem[] = [
{ {
icon: markRaw(Finished), icon: markRaw(Finished),
name: '实验成绩管理', name: '实验成绩管理',
path: '/admin/lab/score' path: '/admin/lab/record'
} }
] ]
}, },
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论