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

chore: update

上级 959017fb
......@@ -193,6 +193,7 @@
"usePointer": true,
"usePointerSwipe": true,
"usePreferredColorScheme": true,
"usePreferredContrast": true,
"usePreferredDark": true,
"usePreferredLanguages": true,
"usePreferredReducedMotion": true,
......
......@@ -194,6 +194,7 @@ declare global {
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
......
<script setup lang="ts">
import { Close } from '@element-plus/icons-vue'
interface FileItem {
name: string
url: string
upload_time?: string
}
interface Props {
modelValue: boolean
index: number
items: FileItem[]
}
withDefaults(defineProps<Props>(), {
modelValue: false,
index: 0
})
</script>
<template>
<div class="image-viewer" v-if="modelValue">
<div class="image-viewer__close" @click="$emit('update:modelValue', false)">
<el-icon><Close /></el-icon>
</div>
<el-carousel :autoplay="false" :initial-index="index" arrow="always" height="100vh">
<el-carousel-item v-for="item in items" :key="item.url">
<div class="image-viewer__pic"><img :src="item.url" /></div>
</el-carousel-item>
</el-carousel>
</div>
</template>
<style lang="scss">
.image-viewer {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10000;
background-color: rgba(0, 0, 0, 0.5);
}
.image-viewer__close {
position: absolute;
right: 40px;
top: 40px;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
opacity: 0.8;
cursor: pointer;
box-sizing: border-box;
user-select: none;
width: 44px;
height: 44px;
font-size: 24px;
color: #fff;
background-color: var(--el-text-color-regular);
border-color: #fff;
}
.image-viewer__pic {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
img {
max-width: 100%;
max-height: 100%;
}
}
</style>
......@@ -2,13 +2,23 @@
interface Props {
data: any
}
defineProps<Props>()
const props = defineProps<Props>()
const genFileClassNames = $computed(() => {
const extName = props.data.url?.split('.').pop() || ''
return {
'icon-file__word': extName.includes('doc'),
'icon-file__excel': extName.includes('xls'),
'icon-file__ppt': extName.includes('ppt'),
'icon-file__pdf': extName.includes('pdf')
}
})
</script>
<template>
<div class="list-item">
<div class="list-item-hd">
<div class="icon-file"></div>
<div class="icon-file" :class="genFileClassNames"></div>
<div class="button-group">
<div class="button icon-view" v-permission="'v1-teacher-book-view'">
<router-link :to="`/admin/lab/book/${data.id}`" target="_blank"></router-link>
......@@ -74,6 +84,22 @@ defineProps<Props>()
background: url(@/assets/images/icon_word.png) no-repeat;
background-size: contain;
}
.icon-file__word {
background: url(@/assets/images/icon_word.png) no-repeat;
background-size: contain;
}
.icon-file__excel {
background: url(@/assets/images/icon_excel.png) no-repeat;
background-size: contain;
}
.icon-file__ppt {
background: url(@/assets/images/icon_ppt.png) no-repeat;
background-size: contain;
}
.icon-file__pdf {
background: url(@/assets/images/icon_pdf.png) no-repeat;
background-size: contain;
}
.icon-edit {
width: 16px;
height: 16px;
......
<script setup lang="ts">
import type { ExperimentRecord } from '../types'
import ImageViewer from '@/components/ImageViewer.vue'
import { uploadExperimentPicture } from '../api'
interface Props {
experiment_id?: string
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
}>()
const detail = $ref<ExperimentRecord>(inject('detail'))
const isEmpty = $computed(() => {
return !props.experiment_id || !detail
})
const canRemove = $computed(() => {
return !(detail?.status !== 0)
})
let imageViewerVisible = $ref<boolean>(false)
let imageViewerIndex = $ref<number>(0)
// 查看
function handlePreview(index: number) {
imageViewerVisible = true
imageViewerIndex = index
}
// 删除
function handleRemove(index: number) {
if (!props.experiment_id) return
const pictures = detail.pictures.filter((item, i) => i !== index)
uploadExperimentPicture({ experiment_id: props.experiment_id, pictures: JSON.stringify(pictures) }).then(() => {
emit('update')
})
}
</script>
<template>
......@@ -21,17 +46,18 @@ const isEmpty = $computed(() => {
</div>
<h3>实验过程</h3>
<ul class="picture-list">
<li v-for="item in detail.pictures" :key="item.url">
<li v-for="(item, index) in detail.pictures" :key="item.url">
<img :src="item.url" />
<p>截图时间:{{ item.upload_time }}</p>
<div class="cover">
<div class="cover-inner">
<el-button type="primary" plain round>查看</el-button>
<el-button type="primary" plain round>删除</el-button>
<el-button type="primary" plain round @click="handlePreview(index)">查看</el-button>
<el-button type="primary" plain round @click="handleRemove(index)" v-if="canRemove">删除</el-button>
</div>
</div>
</li>
</ul>
<ImageViewer v-model="imageViewerVisible" :index="imageViewerIndex" :items="detail.pictures"></ImageViewer>
</template>
</template>
......
......@@ -128,7 +128,7 @@ function handleSubmit() {
<Discuss :experiment_id="form.experiment_id"></Discuss>
</el-tab-pane>
<el-tab-pane label="过程与结果" lazy>
<Result :experiment_id="form.experiment_id"></Result>
<Result :experiment_id="form.experiment_id" @update="fetchInfo"></Result>
</el-tab-pane>
</el-tabs>
</div>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论