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

feat: 添加删除功能,支持删除实验指导书、案例原文和操作视频

上级 00476186
...@@ -27,3 +27,8 @@ export function createBook(data: BookCreateItem) { ...@@ -27,3 +27,8 @@ export function createBook(data: BookCreateItem) {
export function updateBook(data: BookCreateItem) { export function updateBook(data: BookCreateItem) {
return httpRequest.post('/api/lab/v1/teacher/book/update', data) return httpRequest.post('/api/lab/v1/teacher/book/update', data)
} }
// 删除指导书
export function deleteBook(data: { id: string }) {
return httpRequest.post('/api/lab/v1/teacher/book/delete', data)
}
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import type { BookItem, BookCreateItem } from '../types' import type { BookFormData, BookItem, BookCreateItem } from '../types'
import { ElMessageBox, ElMessage } from 'element-plus' import { ElMessageBox, ElMessage } from 'element-plus'
import AppUpload from '@/components/base/AppUpload.vue' import AppUpload from '@/components/base/AppUpload.vue'
import { createBook, updateBook } from '../api' import { createBook, updateBook } from '../api'
import { useGetCourseList } from '../composables/useGetCourseList'
import { useGetExperimentList } from '../composables/useGetExperimentList' import { useGetExperimentList } from '../composables/useGetExperimentList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -19,32 +18,29 @@ const emit = defineEmits<{ ...@@ -19,32 +18,29 @@ const emit = defineEmits<{
(e: 'update:modelValue', visible: boolean): void (e: 'update:modelValue', visible: boolean): void
}>() }>()
// 课程列表
const { courses } = useGetCourseList()
// 数据状态 // 数据状态
const status = useMapStore().getMapValuesByKey('system_status') const status = useMapStore().getMapValuesByKey('system_status')
// 实验列表 // 实验列表
const { experiments, updateExperiments } = useGetExperimentList() const { experiments, updateExperiments } = useGetExperimentList()
const formRef = $ref<FormInstance>() const formRef = $ref<FormInstance>()
const form = reactive<BookCreateItem>({ const form = reactive<BookFormData>({
name: '', name: '',
course_id: '',
experiment_id: '', experiment_id: '',
status: '1', status: '1',
url: '', url: '',
type: '', type: '',
size: '', size: '',
files: [], files: [],
protocol: false protocol: true
}) })
watchEffect(() => { watchEffect(() => {
if (!props.data) return if (!props.data) return
form.files = [{ name: props.data.name, url: props.data.url, type: props.data.type }] form.files = [{ name: props.data.name, url: props.data.url, type: props.data.type }]
Object.assign(form, { protocol: true }, props.data) Object.assign(form, { protocol: true }, props.data)
}) })
watchEffect(() => { onMounted(() => {
updateExperiments(form.course_id) updateExperiments()
}) })
const checkProtocol = (rule: any, value: any, callback: any) => { const checkProtocol = (rule: any, value: any, callback: any) => {
if (!value) { if (!value) {
...@@ -56,7 +52,6 @@ const checkProtocol = (rule: any, value: any, callback: any) => { ...@@ -56,7 +52,6 @@ const checkProtocol = (rule: any, value: any, callback: any) => {
const rules = ref<FormRules>({ const rules = ref<FormRules>({
files: [{ type: 'array', required: true, message: '请上传实验指导书' }], files: [{ type: 'array', required: true, message: '请上传实验指导书' }],
name: [{ required: true, message: '请输入实验指导书名称', trigger: 'blur' }], name: [{ required: true, message: '请输入实验指导书名称', trigger: 'blur' }],
course_id: [{ required: true, message: '请选择关联实验课程', trigger: 'change' }],
experiment_id: [{ required: true, message: '请选择关联实验', trigger: 'change' }], experiment_id: [{ required: true, message: '请选择关联实验', trigger: 'change' }],
protocol: [{ validator: checkProtocol, message: '请阅读并同意', trigger: 'change' }] protocol: [{ validator: checkProtocol, message: '请阅读并同意', trigger: 'change' }]
}) })
...@@ -121,11 +116,6 @@ function handleUpdate(params: BookCreateItem) { ...@@ -121,11 +116,6 @@ function handleUpdate(params: BookCreateItem) {
<el-input v-model="form.name"></el-input> <el-input v-model="form.name"></el-input>
<p class="form-tips">实验指导书名称自动取值于文件名称,可以进行二次修改。</p> <p class="form-tips">实验指导书名称自动取值于文件名称,可以进行二次修改。</p>
</el-form-item> </el-form-item>
<el-form-item label="关联实验课程" prop="course_id">
<el-select v-model="form.course_id" filterable style="width: 100%" @change="form.experiment_id = ''">
<el-option v-for="item in courses" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="关联实验" prop="experiment_id"> <el-form-item label="关联实验" prop="experiment_id">
<el-select v-model="form.experiment_id" filterable style="width: 100%"> <el-select v-model="form.experiment_id" filterable style="width: 100%">
<el-option v-for="item in experiments" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in experiments" :key="item.id" :label="item.name" :value="item.id"></el-option>
......
...@@ -24,12 +24,14 @@ export interface BookItem { ...@@ -24,12 +24,14 @@ export interface BookItem {
export interface BookCreateItem { export interface BookCreateItem {
id?: string id?: string
experiment_id: string experiment_id: string
course_id: string
status: string status: string
name: string name: string
type: string type: string
url: string url: string
size: string size: string
}
export interface BookFormData extends BookCreateItem {
protocol: boolean protocol: boolean
files: FileItem[] files: FileItem[]
} }
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
import type { BookItem } from '../types' import type { BookItem } from '../types'
import { CirclePlus } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import { useLocalStorage } from '@vueuse/core' import { useLocalStorage } from '@vueuse/core'
import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import ListItem from '../components/ListItem.vue' import ListItem from '../components/ListItem.vue'
import { getBookList } from '../api' import { deleteBook, getBookList } from '../api'
import { useGetExperimentList } from '../composables/useGetExperimentList' import { useGetExperimentList } from '../composables/useGetExperimentList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -63,7 +64,7 @@ const listOptions = $computed(() => { ...@@ -63,7 +64,7 @@ const listOptions = $computed(() => {
{ label: '创建人', prop: 'created_operator_name', width: 120 }, { label: '创建人', prop: 'created_operator_name', width: 120 },
{ label: '创建时间', prop: 'created_time', width: 180 }, { label: '创建时间', prop: 'created_time', width: 180 },
{ label: '更新时间', prop: 'updated_time', width: 180 }, { label: '更新时间', prop: 'updated_time', width: 180 },
{ label: '操作', slots: 'table-x', width: 160 }, { label: '操作', slots: 'table-x', width: 260 },
], ],
} }
}) })
...@@ -81,6 +82,14 @@ function handleUpdate(row: BookItem) { ...@@ -81,6 +82,14 @@ function handleUpdate(row: BookItem) {
dialogVisible = true dialogVisible = true
} }
async function handleDelete(row: BookItem) {
ElMessageBox.confirm(`确定要删除实验指导书“${row.name}”吗?`, '提示').then(async () => {
await deleteBook({ id: row.id })
ElMessage.success('删除成功')
appList?.refetch()
})
}
function onUpdateSuccess() { function onUpdateSuccess() {
appList?.refetch() appList?.refetch()
} }
...@@ -118,7 +127,12 @@ function onUpdateSuccess() { ...@@ -118,7 +127,12 @@ function onUpdateSuccess() {
</template> </template>
<template #body="{ data }" v-if="viewMode === 'card'"> <template #body="{ data }" v-if="viewMode === 'card'">
<div class="list-card" v-if="data.length"> <div class="list-card" v-if="data.length">
<ListItem v-for="item in data" :data="item" :key="item.id" @clickEdit="handleUpdate(item)"></ListItem> <ListItem
v-for="item in data"
:data="item"
:key="item.id"
@clickEdit="handleUpdate(item)"
@clickDelete="handleDelete(item)"></ListItem>
</div> </div>
<el-empty description="暂无数据" v-else /> <el-empty description="暂无数据" v-else />
</template> </template>
...@@ -129,6 +143,7 @@ function onUpdateSuccess() { ...@@ -129,6 +143,7 @@ function onUpdateSuccess() {
<el-button type="primary" round @click="handleUpdate(row)" v-permission="'v1-teacher-book-update'" <el-button type="primary" round @click="handleUpdate(row)" v-permission="'v1-teacher-book-update'"
>编辑</el-button >编辑</el-button
> >
<el-button type="danger" round @click="handleDelete(row)" v-permission="'v1-teacher-book-delete'">删除</el-button>
</template> </template>
<template #table-status="{ row }: { row: BookItem }"> <template #table-status="{ row }: { row: BookItem }">
<span :class="isActiveStatus(row.status) ? 'status-active' : 'status-inactive'">{{ row.status_name }}</span> <span :class="isActiveStatus(row.status) ? 'status-active' : 'status-inactive'">{{ row.status_name }}</span>
......
...@@ -27,3 +27,8 @@ export function createCase(data: CaseCreateItem) { ...@@ -27,3 +27,8 @@ export function createCase(data: CaseCreateItem) {
export function updateCase(data: CaseCreateItem) { export function updateCase(data: CaseCreateItem) {
return httpRequest.post('/api/lab/v1/teacher/experiment-cases/update', data) return httpRequest.post('/api/lab/v1/teacher/experiment-cases/update', data)
} }
// 删除案例原文
export function deleteCase(data: { id: string }) {
return httpRequest.post('/api/lab/v1/teacher/experiment-cases/delete', data)
}
...@@ -5,7 +5,6 @@ import { ElMessageBox, ElMessage } from 'element-plus' ...@@ -5,7 +5,6 @@ import { ElMessageBox, ElMessage } from 'element-plus'
import AppUpload from '@/components/base/AppUpload.vue' import AppUpload from '@/components/base/AppUpload.vue'
import { createCase, updateCase } from '../api' import { createCase, updateCase } from '../api'
import { useGetCourseList } from '../composables/useGetCourseList'
import { useGetExperimentList } from '../composables/useGetExperimentList' import { useGetExperimentList } from '../composables/useGetExperimentList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -19,8 +18,6 @@ const emit = defineEmits<{ ...@@ -19,8 +18,6 @@ const emit = defineEmits<{
(e: 'update:modelValue', visible: boolean): void (e: 'update:modelValue', visible: boolean): void
}>() }>()
// 课程列表
const { courses } = useGetCourseList()
// 数据状态 // 数据状态
const status = useMapStore().getMapValuesByKey('system_status') const status = useMapStore().getMapValuesByKey('system_status')
// 实验列表 // 实验列表
...@@ -29,22 +26,21 @@ const { experiments, updateExperiments } = useGetExperimentList() ...@@ -29,22 +26,21 @@ const { experiments, updateExperiments } = useGetExperimentList()
const formRef = $ref<FormInstance>() const formRef = $ref<FormInstance>()
const form = reactive<CaseFormData>({ const form = reactive<CaseFormData>({
name: '', name: '',
course_id: '',
experiment_id: '', experiment_id: '',
status: '1', status: '1',
url: '', url: '',
type: '', type: '',
size: '', size: '',
files: [], files: [],
protocol: false protocol: true
}) })
watchEffect(() => { watchEffect(() => {
if (!props.data) return if (!props.data) return
form.files = [{ name: props.data.name, url: props.data.url, type: props.data.type }] form.files = [{ name: props.data.name, url: props.data.url, type: props.data.type }]
Object.assign(form, { protocol: true, course_id: props.data.course.id }, props.data) Object.assign(form, { protocol: true }, props.data)
}) })
watchEffect(() => { onMounted(() => {
updateExperiments(form.course_id) updateExperiments()
}) })
const checkProtocol = (rule: any, value: any, callback: any) => { const checkProtocol = (rule: any, value: any, callback: any) => {
if (!value) { if (!value) {
...@@ -56,7 +52,6 @@ const checkProtocol = (rule: any, value: any, callback: any) => { ...@@ -56,7 +52,6 @@ const checkProtocol = (rule: any, value: any, callback: any) => {
const rules = ref<FormRules>({ const rules = ref<FormRules>({
files: [{ type: 'array', required: true, message: '请上传案例原文' }], files: [{ type: 'array', required: true, message: '请上传案例原文' }],
name: [{ required: true, message: '请输入案例原文名称', trigger: 'blur' }], name: [{ required: true, message: '请输入案例原文名称', trigger: 'blur' }],
course_id: [{ required: true, message: '请选择关联实验课程', trigger: 'change' }],
experiment_id: [{ required: true, message: '请选择关联实验', trigger: 'change' }], experiment_id: [{ required: true, message: '请选择关联实验', trigger: 'change' }],
protocol: [{ validator: checkProtocol, message: '请阅读并同意', trigger: 'change' }] protocol: [{ validator: checkProtocol, message: '请阅读并同意', trigger: 'change' }]
}) })
...@@ -66,13 +61,6 @@ const isUpdate = $computed(() => { ...@@ -66,13 +61,6 @@ const isUpdate = $computed(() => {
const title = $computed(() => { const title = $computed(() => {
return isUpdate ? '编辑案例原文' : '新增案例原文' return isUpdate ? '编辑案例原文' : '新增案例原文'
}) })
// 实验列表
const experimentList = $computed(() => {
if (!props.data) return experiments.value
return isUpdate && props.data.course.id === form.course_id
? [{ id: props.data.experiment_id, name: props.data.experiment.name }, ...experiments.value]
: experiments.value
})
function handleBeforeUpload() { function handleBeforeUpload() {
if (form.files.length) { if (form.files.length) {
...@@ -128,14 +116,9 @@ function handleUpdate(params: CaseUpdateItem) { ...@@ -128,14 +116,9 @@ function handleUpdate(params: CaseUpdateItem) {
<el-input v-model="form.name"></el-input> <el-input v-model="form.name"></el-input>
<p class="form-tips">案例原文名称自动取值于文件名称,可以进行二次修改。</p> <p class="form-tips">案例原文名称自动取值于文件名称,可以进行二次修改。</p>
</el-form-item> </el-form-item>
<el-form-item label="关联实验课程" prop="course_id">
<el-select v-model="form.course_id" filterable style="width: 100%" @change="form.experiment_id = ''">
<el-option v-for="item in courses" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="关联实验" prop="experiment_id"> <el-form-item label="关联实验" prop="experiment_id">
<el-select v-model="form.experiment_id" filterable style="width: 100%"> <el-select v-model="form.experiment_id" filterable style="width: 100%">
<el-option v-for="item in experimentList" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in experiments" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="有效状态" prop="status"> <el-form-item label="有效状态" prop="status">
......
...@@ -33,7 +33,6 @@ export interface CaseOperator { ...@@ -33,7 +33,6 @@ export interface CaseOperator {
export interface CaseFormData { export interface CaseFormData {
id?: string id?: string
experiment_id: string experiment_id: string
course_id: string
status: string status: string
name: string name: string
type: string type: string
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
import type { CaseItem } from '../types' import type { CaseItem } from '../types'
import { CirclePlus } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import { useLocalStorage } from '@vueuse/core' import { useLocalStorage } from '@vueuse/core'
import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import ListItem from '../components/ListItem.vue' import ListItem from '../components/ListItem.vue'
import { getCaseList } from '../api' import { deleteCase, getCaseList } from '../api'
import { useGetExperimentList } from '../composables/useGetExperimentList' import { useGetExperimentList } from '../composables/useGetExperimentList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -95,7 +96,7 @@ const listOptions = $computed(() => { ...@@ -95,7 +96,7 @@ const listOptions = $computed(() => {
{ label: '创建人', prop: 'created_operator_name', width: 120 }, { label: '创建人', prop: 'created_operator_name', width: 120 },
{ label: '创建时间', prop: 'created_time', width: 180 }, { label: '创建时间', prop: 'created_time', width: 180 },
{ label: '更新时间', prop: 'updated_time', width: 180 }, { label: '更新时间', prop: 'updated_time', width: 180 },
{ label: '操作', slots: 'table-x', width: 160 }, { label: '操作', slots: 'table-x', width: 260 },
], ],
} }
}) })
...@@ -113,6 +114,14 @@ function handleUpdate(row: CaseItem) { ...@@ -113,6 +114,14 @@ function handleUpdate(row: CaseItem) {
dialogVisible = true dialogVisible = true
} }
async function handleDelete(row: CaseItem) {
ElMessageBox.confirm(`确定要删除案例原文“${row.name}”吗?`, '提示').then(async () => {
await deleteCase({ id: row.id })
ElMessage.success('删除成功')
appList?.refetch()
})
}
function onUpdateSuccess() { function onUpdateSuccess() {
appList?.refetch() appList?.refetch()
} }
...@@ -150,7 +159,12 @@ function onUpdateSuccess() { ...@@ -150,7 +159,12 @@ function onUpdateSuccess() {
</template> </template>
<template #body="{ data }: { data: CaseListRow[] }" v-if="viewMode === 'card'"> <template #body="{ data }: { data: CaseListRow[] }" v-if="viewMode === 'card'">
<div class="list-card" v-if="viewMode === 'card' && data.length"> <div class="list-card" v-if="viewMode === 'card' && data.length">
<ListItem v-for="item in data" :data="item" :key="item.id" @clickEdit="handleUpdate(item)"></ListItem> <ListItem
v-for="item in data"
:data="item"
:key="item.id"
@clickEdit="handleUpdate(item)"
@clickDelete="handleDelete(item)"></ListItem>
</div> </div>
<el-empty description="暂无数据" v-else /> <el-empty description="暂无数据" v-else />
</template> </template>
...@@ -161,6 +175,9 @@ function onUpdateSuccess() { ...@@ -161,6 +175,9 @@ function onUpdateSuccess() {
<el-button type="primary" round @click="handleUpdate(row)" v-permission="'teacher-experiment-cases-update'" <el-button type="primary" round @click="handleUpdate(row)" v-permission="'teacher-experiment-cases-update'"
>编辑</el-button >编辑</el-button
> >
<el-button type="danger" round @click="handleDelete(row)" v-permission="'teacher-experiment-cases-delete'"
>删除</el-button
>
</template> </template>
<template #table-status="{ row }: { row: CaseListRow }"> <template #table-status="{ row }: { row: CaseListRow }">
<span :class="isActiveStatus(row.status) ? 'status-active' : 'status-inactive'">{{ row.status_name }}</span> <span :class="isActiveStatus(row.status) ? 'status-active' : 'status-inactive'">{{ row.status_name }}</span>
......
...@@ -27,3 +27,8 @@ export function createVideo(data: VideoCreateItem) { ...@@ -27,3 +27,8 @@ export function createVideo(data: VideoCreateItem) {
export function updateVideo(data: VideoCreateItem) { export function updateVideo(data: VideoCreateItem) {
return httpRequest.post('/api/lab/v1/teacher/video/update', data) return httpRequest.post('/api/lab/v1/teacher/video/update', data)
} }
// 删除操作视频
export function deleteVideo(data: { id: string }) {
return httpRequest.post('/api/lab/v1/teacher/video/delete', data)
}
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import type { VideoItem, VideoCreateItem } from '../types' import type { VideoFormData, VideoItem, VideoCreateItem } from '../types'
import { ElMessageBox, ElMessage } from 'element-plus' import { ElMessageBox, ElMessage } from 'element-plus'
import UploadVideo from '@/components/UploadVideo.vue' import UploadVideo from '@/components/UploadVideo.vue'
import { createVideo, updateVideo } from '../api' import { createVideo, updateVideo } from '../api'
import { useGetCourseList } from '../composables/useGetCourseList'
import { useGetExperimentList } from '../composables/useGetExperimentList' import { useGetExperimentList } from '../composables/useGetExperimentList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -19,28 +18,25 @@ const emit = defineEmits<{ ...@@ -19,28 +18,25 @@ const emit = defineEmits<{
(e: 'update:modelValue', visible: boolean): void (e: 'update:modelValue', visible: boolean): void
}>() }>()
// 课程列表
const { courses } = useGetCourseList()
// 数据状态 // 数据状态
const status = useMapStore().getMapValuesByKey('system_status') const status = useMapStore().getMapValuesByKey('system_status')
// 实验列表 // 实验列表
const { experiments, updateExperiments } = useGetExperimentList() const { experiments, updateExperiments } = useGetExperimentList()
const formRef = $ref<FormInstance>() const formRef = $ref<FormInstance>()
const form = reactive<VideoCreateItem>({ const form = reactive<VideoFormData>({
name: '', name: '',
course_id: '',
experiment_id: '', experiment_id: '',
status: '1', status: '1',
source_id: '', source_id: '',
protocol: false protocol: true
}) })
watchEffect(() => { watchEffect(() => {
if (!props.data) return if (!props.data) return
Object.assign(form, { protocol: true }, props.data) Object.assign(form, { protocol: true }, props.data)
}) })
watchEffect(() => { onMounted(() => {
updateExperiments(form.course_id) updateExperiments()
}) })
const checkProtocol = (rule: any, value: any, callback: any) => { const checkProtocol = (rule: any, value: any, callback: any) => {
if (!value) { if (!value) {
...@@ -52,7 +48,6 @@ const checkProtocol = (rule: any, value: any, callback: any) => { ...@@ -52,7 +48,6 @@ const checkProtocol = (rule: any, value: any, callback: any) => {
const rules = ref<FormRules>({ const rules = ref<FormRules>({
source_id: [{ required: true, message: '请上传实验操作视频' }], source_id: [{ required: true, message: '请上传实验操作视频' }],
name: [{ required: true, message: '请输入实验操作视频名称', trigger: 'blur' }], name: [{ required: true, message: '请输入实验操作视频名称', trigger: 'blur' }],
course_id: [{ required: true, message: '请选择关联实验课程', trigger: 'change' }],
experiment_id: [{ required: true, message: '请选择关联实验', trigger: 'change' }], experiment_id: [{ required: true, message: '请选择关联实验', trigger: 'change' }],
protocol: [{ validator: checkProtocol, message: '请阅读并同意', trigger: 'change' }] protocol: [{ validator: checkProtocol, message: '请阅读并同意', trigger: 'change' }]
}) })
...@@ -110,11 +105,6 @@ function handleUpdate(params: VideoCreateItem) { ...@@ -110,11 +105,6 @@ function handleUpdate(params: VideoCreateItem) {
<el-input v-model="form.name"></el-input> <el-input v-model="form.name"></el-input>
<p class="form-tips">操作视频名称自动取值于文件名称,可以进行二次修改。</p> <p class="form-tips">操作视频名称自动取值于文件名称,可以进行二次修改。</p>
</el-form-item> </el-form-item>
<el-form-item label="关联实验课程" prop="course_id">
<el-select v-model="form.course_id" filterable style="width: 100%" @change="form.experiment_id = ''">
<el-option v-for="item in courses" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="关联实验" prop="experiment_id"> <el-form-item label="关联实验" prop="experiment_id">
<el-select v-model="form.experiment_id" filterable style="width: 100%"> <el-select v-model="form.experiment_id" filterable style="width: 100%">
<el-option v-for="item in experiments" :key="item.id" :label="item.name" :value="item.id"></el-option> <el-option v-for="item in experiments" :key="item.id" :label="item.name" :value="item.id"></el-option>
......
...@@ -24,9 +24,11 @@ export interface VideoItem { ...@@ -24,9 +24,11 @@ export interface VideoItem {
export interface VideoCreateItem { export interface VideoCreateItem {
id?: string id?: string
experiment_id: string experiment_id: string
course_id: string
status: string status: string
name: string name: string
source_id: string source_id: string
}
export interface VideoFormData extends VideoCreateItem {
protocol: boolean protocol: boolean
} }
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
import type { VideoItem } from '../types' import type { VideoItem } from '../types'
import { CirclePlus } from '@element-plus/icons-vue' import { CirclePlus } from '@element-plus/icons-vue'
import { useLocalStorage } from '@vueuse/core' import { useLocalStorage } from '@vueuse/core'
import { ElMessage, ElMessageBox } from 'element-plus'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import ListItem from '../components/ListItem.vue' import ListItem from '../components/ListItem.vue'
import { getVideoList } from '../api' import { deleteVideo, getVideoList } from '../api'
import { useGetExperimentList } from '../composables/useGetExperimentList' import { useGetExperimentList } from '../composables/useGetExperimentList'
import { useMapStore } from '@/stores/map' import { useMapStore } from '@/stores/map'
...@@ -63,7 +64,7 @@ const listOptions = $computed(() => { ...@@ -63,7 +64,7 @@ const listOptions = $computed(() => {
{ label: '创建人', prop: 'created_operator_name', width: 120 }, { label: '创建人', prop: 'created_operator_name', width: 120 },
{ label: '创建时间', prop: 'created_time', width: 180 }, { label: '创建时间', prop: 'created_time', width: 180 },
{ label: '更新时间', prop: 'updated_time', width: 180 }, { label: '更新时间', prop: 'updated_time', width: 180 },
{ label: '操作', slots: 'table-x', width: 160 }, { label: '操作', slots: 'table-x', width: 260 },
], ],
} }
}) })
...@@ -81,6 +82,14 @@ function handleUpdate(row: VideoItem) { ...@@ -81,6 +82,14 @@ function handleUpdate(row: VideoItem) {
dialogVisible = true dialogVisible = true
} }
async function handleDelete(row: VideoItem) {
ElMessageBox.confirm(`确定要删除实验操作视频“${row.name}”吗?`, '提示').then(async () => {
await deleteVideo({ id: row.id })
ElMessage.success('删除成功')
appList?.refetch()
})
}
function onUpdateSuccess() { function onUpdateSuccess() {
appList?.refetch() appList?.refetch()
} }
...@@ -118,7 +127,12 @@ function onUpdateSuccess() { ...@@ -118,7 +127,12 @@ function onUpdateSuccess() {
</template> </template>
<template #body="{ data }" v-if="viewMode === 'card'"> <template #body="{ data }" v-if="viewMode === 'card'">
<div class="list-card" v-if="data.length"> <div class="list-card" v-if="data.length">
<ListItem v-for="item in data" :data="item" :key="item.id" @clickEdit="handleUpdate(item)"></ListItem> <ListItem
v-for="item in data"
:data="item"
:key="item.id"
@clickEdit="handleUpdate(item)"
@clickDelete="handleDelete(item)"></ListItem>
</div> </div>
<el-empty description="暂无数据" v-else /> <el-empty description="暂无数据" v-else />
</template> </template>
...@@ -129,6 +143,9 @@ function onUpdateSuccess() { ...@@ -129,6 +143,9 @@ function onUpdateSuccess() {
<el-button type="primary" round @click="handleUpdate(row)" v-permission="'v1-teacher-video-update'" <el-button type="primary" round @click="handleUpdate(row)" v-permission="'v1-teacher-video-update'"
>编辑</el-button >编辑</el-button
> >
<el-button type="danger" round @click="handleDelete(row)" v-permission="'v1-teacher-video-delete'"
>删除</el-button
>
</template> </template>
<template #table-status="{ row }: { row: VideoItem }"> <template #table-status="{ row }: { row: VideoItem }">
<span :class="isActiveStatus(row.status) ? 'status-active' : 'status-inactive'">{{ row.status_name }}</span> <span :class="isActiveStatus(row.status) ? 'status-active' : 'status-inactive'">{{ row.status_name }}</span>
......
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论