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

chore: update

上级 e981353f
......@@ -5,10 +5,17 @@ import type { UploadProps, UploadUserFile } from 'element-plus'
import md5 from 'blueimp-md5'
import { getSignature } from '@/api/base'
const props = withDefaults(defineProps<{ modelValue: string | []; prefix?: string }>(), {
prefix: 'upload/admin/'
interface Props {
modelValue: string | { name: string; url: string }[]
prefix?: string
size?: number
}
const props = withDefaults(defineProps<Props>(), {
prefix: 'upload/saas-learn/'
})
const emit = defineEmits(['update:modelValue'])
const emit = defineEmits(['update:modelValue', 'success'])
const uploadData = ref()
......@@ -17,7 +24,7 @@ const fileList = ref<UploadUserFile[]>([])
watch(
() => props.modelValue,
value => {
fileList.value = Array.isArray(value) ? [...value] : []
fileList.value = Array.isArray(value) ? value.map(item => ({ ...item })) : []
}
)
......@@ -27,6 +34,10 @@ const showFileList = computed(() => {
// 上传之前
const handleBeforeUpload = async (file: any) => {
if (props.size && file.size > props.size) {
ElMessage.error(`文件大小不能超过${props.size / 1024 / 1024}M`)
return false
}
const fileName = file.name
const key = props.prefix + md5(fileName + new Date().getTime()) + fileName.substr(fileName.lastIndexOf('.'))
const response: Record<string, any> = await getSignature()
......@@ -48,18 +59,13 @@ const handleSuccess = (response: any, file: any, files: any) => {
emit(
'update:modelValue',
files.map((item: any) => {
console.log(item, 'items')
return {
name: item.name,
url: item.url || item.raw.url,
size: item.raw.size,
type: item.raw.type || item.raw.url
}
return { name: item.name, url: item.url || item.raw.url, size: item.raw.size, type: item.raw.type }
})
)
} else {
emit('update:modelValue', file.raw.url)
}
emit('success', file, files)
}
// 上传限制
......@@ -83,7 +89,7 @@ const handleRemove: UploadProps['onRemove'] = (file, files) => {
// 预览
const handlePreview: UploadProps['onPreview'] = uploadFile => {
console.log(uploadFile)
window.open(uploadFile.url)
}
</script>
......@@ -100,18 +106,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>
</template>
<template v-else>
<el-button round class="app-upload-btn">本地文件</el-button>
<slot>
<template v-if="showFileList">
<template v-if="$attrs['list-type'] === 'picture-card'">
<el-icon><Plus /></el-icon>
</template>
<template v-else>
<el-button round>本地文件</el-button>
</template>
</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>
......
......@@ -28,3 +28,5 @@ app.use(router)
app.use(ElementPlus, { locale: zhCn })
app.mount('#app')
document.domain = 'ezijing.com'
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import AppUpload from '../../../../../components/base/AppUpload.vue'
// import { ElMessage } from 'element-plus'
import AppUpload from '@/components/base/AppUpload.vue'
interface Props {
data?: any
......@@ -9,8 +9,9 @@ interface Props {
const props = defineProps<Props>()
const emit = defineEmits<{
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const title = $computed(() => {
......
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import AppUpload from '../../../../../components/base/AppUpload.vue'
// import { ElMessage } from 'element-plus'
interface Props {
data?: any
......@@ -9,8 +8,9 @@ interface Props {
const props = defineProps<Props>()
const emit = defineEmits<{
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const title = $computed(() => {
......
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
// import { ElMessage } from 'element-plus'
interface Props {
data?: any
......@@ -8,8 +8,9 @@ interface Props {
const props = defineProps<Props>()
const emit = defineEmits<{
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const title = $computed(() => {
......
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
// import { ElMessage } from 'element-plus'
interface Props {
data?: any
......@@ -8,14 +8,11 @@ interface Props {
const props = defineProps<Props>()
const emit = defineEmits<{
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const title = $computed(() => {
return '新增实验'
})
const formRef = $ref<FormInstance>()
const form = reactive({ title: '', status: 1 })
watchEffect(() => {
......
<script setup lang="ts"></script>
<template>
<div>book</div>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import DiscussAddDialog from './DiscussAddDialog.vue'
import DiscussCommentAddDialog from './DiscussCommentAddDialog.vue'
const dialogVisible = $ref(false)
const commentDialogVisible = $ref(false)
</script>
<template>
<el-radio-group>
<el-radio :label="1">我发起的</el-radio>
<el-radio :label="2">我回复的</el-radio>
<el-radio :label="3">我的小组</el-radio>
<el-radio :label="4">我的班级</el-radio>
</el-radio-group>
<el-row justify="end">
<el-button round type="primary" @click="dialogVisible = true">发表新话题</el-button>
</el-row>
<div>discuss</div>
<el-row justify="end">
<el-button round type="primary" @click="commentDialogVisible = true">我要评论</el-button>
</el-row>
<DiscussAddDialog v-model="dialogVisible"></DiscussAddDialog>
<DiscussCommentAddDialog v-model="commentDialogVisible"></DiscussCommentAddDialog>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
// import { ElMessage } from 'element-plus'
interface Props {
data?: any
}
const props = defineProps<Props>()
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const formRef = $ref<FormInstance>()
const form = reactive({ title: '', content: '' })
watchEffect(() => {
Object.assign(form, props.data)
})
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="发表新话题" :close-on-click-modal="false" width="600px">
<el-form ref="formRef" :model="form" :rules="rules">
<el-form-item label="话题标题" prop="title">
<el-input v-model="form.title"></el-input>
</el-form-item>
<el-form-item label="话题描述" prop="content">
<el-input type="textarea" v-model="form.content" />
</el-form-item>
<el-row justify="center">
<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>
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
// import { ElMessage } from 'element-plus'
interface Props {
data?: any
}
const props = defineProps<Props>()
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const formRef = $ref<FormInstance>()
const form = reactive({ content: '' })
watchEffect(() => {
Object.assign(form, props.data)
})
const rules = ref<FormRules>({
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="话题评论" :close-on-click-modal="false" width="600px">
<el-form ref="formRef" :model="form" :rules="rules">
<el-form-item prop="content">
<el-input type="textarea" v-model="form.content" />
</el-form-item>
<el-row justify="center">
<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>
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
// import { ElMessage } from 'element-plus'
interface Props {
data?: any
}
const props = defineProps<Props>()
defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const formRef = $ref<FormInstance>()
const form = reactive({ files: [] })
watchEffect(() => {
Object.assign(form, props.data)
})
const rules = ref<FormRules>({
files: [{ 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="上传实验报告" :close-on-click-modal="false" width="600px">
<el-form ref="formRef" :model="form" :rules="rules">
<el-form-item label="实验报告文件" prop="files">
<AppUpload v-model="form.files">
<template #tip>实验报告文件只能上传一个,支持格式包含:doc docx pdf ppt pptx,大小不超过50M</template>
</AppUpload>
</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>
<script setup lang="ts"></script>
<template>
<div>result</div>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts"></script>
<template>
<div>video</div>
</template>
<style lang="scss" scoped></style>
<script setup lang="ts">
import { HomeFilled, Select, UploadFilled, FullScreen } from '@element-plus/icons-vue'
import type { FormInstance, FormRules } from 'element-plus'
import ReportDialog from '../components/ReportDialog.vue'
const LAB_URL = import.meta.env.VITE_LAB_URL
const Book = defineAsyncComponent(() => import('../components/Book.vue'))
const Video = defineAsyncComponent(() => import('../components/Video.vue'))
const Discuss = defineAsyncComponent(() => import('../components/Discuss.vue'))
const Result = defineAsyncComponent(() => import('../components/Result.vue'))
// 左侧
const formRef = $ref<FormInstance>()
const form = reactive({ course_id: '', e_id: 1 })
const rules = ref<FormRules>({
course_id: [{ required: true, message: '请选择课程', trigger: 'change' }],
e_id: [{ required: true, message: '请选择实验', trigger: 'change' }]
})
// 右侧
const LAB_URL = import.meta.env.VITE_LAB_URL
let iframeKey = $ref(Date.now())
// 返回首页
function handleBackHome() {
iframeKey = Date.now()
}
const reportDialogVisible = $ref(false)
// 是否已经提交
const submitted = $ref(false)
const iframeRef = $ref<HTMLIFrameElement>()
let screenshotLoading = $ref(false)
let screenshotTimestamp = $ref(0)
// 截图
function handleCapture() {
const iframeWindow = iframeRef?.contentWindow
if (!iframeWindow) return
screenshotTimestamp = Date.now()
screenshotLoading = true
// 发送截图消息
iframeWindow?.postMessage({ action: 'screenshot', timestamp: screenshotTimestamp }, '*')
}
// 截图之后
function handleCaptureCallback(event: MessageEvent) {
const { data } = event
if (data.action === 'screenshot' && data.timestamp === screenshotTimestamp) {
console.log(data)
const img = new Image()
img.src = data.dataURL
document.body.appendChild(img)
screenshotLoading = false
}
}
onMounted(() => {
window.addEventListener('message', handleCaptureCallback, false)
})
onUnmounted(() => {
window.removeEventListener('message', handleCaptureCallback, false)
})
</script>
<template>
<section class="lab">
<div class="lab-left"></div>
<div class="lab-left">
<el-form
:model="form"
:rules="rules"
label-suffix=":"
hide-required-asterisk
ref="formRef"
style="--el-text-color-regular: #fff"
>
<el-form-item label="请选择课程" prop="course_id">
<el-select style="width: 100%"></el-select>
</el-form-item>
<el-form-item label="请选择实验" prop="e_id">
<el-select style="width: 100%"></el-select>
</el-form-item>
</el-form>
<el-tabs type="border-card">
<el-tab-pane label="实训指导" name="first">
<Book></Book>
</el-tab-pane>
<el-tab-pane label="操作视频" name="second">
<Video></Video>
</el-tab-pane>
<el-tab-pane label="讨论交流" name="third">
<Discuss></Discuss>
</el-tab-pane>
<el-tab-pane label="过程与结果" name="fourth">
<Result></Result>
</el-tab-pane>
</el-tabs>
</div>
<div class="lab-right">
<AppCard>
<el-row justify="space-between">
<el-button type="primary" :icon="HomeFilled" @click="handleBackHome">返回首页</el-button>
<el-button type="primary" :icon="HomeFilled" :disabled="submitted" @click="handleBackHome"
>返回首页</el-button
>
<div>
<el-button type="primary" :icon="Select">提交</el-button>
<el-button type="primary" :icon="UploadFilled">上传报告</el-button>
<el-button type="primary" :icon="FullScreen">截图</el-button>
<el-button type="primary" :icon="Select" :disabled="submitted">提交</el-button>
<el-button type="primary" :icon="UploadFilled" :disabled="submitted" @click="reportDialogVisible = true"
>上传报告</el-button
>
<el-button
type="primary"
:icon="FullScreen"
:disabled="submitted"
:loading="screenshotLoading"
@click="handleCapture"
>截图</el-button
>
</div>
</el-row>
</AppCard>
<AppCard>
<iframe :src="LAB_URL" :key="iframeKey" frameborder="0" style="width: 100%; height: 70vh"></iframe>
</AppCard>
<div class="lab-box">
<el-empty description="您已经提交该实验,不能再进行操作,切换其他实验再做操作吧。" v-if="submitted" />
<iframe :src="LAB_URL" :key="iframeKey" frameborder="0" class="iframe" ref="iframeRef" v-else></iframe>
</div>
</div>
</section>
<ReportDialog v-model="reportDialogVisible"></ReportDialog>
</template>
<style lang="scss" scoped>
......@@ -37,11 +129,26 @@ function handleBackHome() {
height: 100%;
}
.lab-left {
width: 400px;
background-color: #f5f5f5;
width: 500px;
padding: 20px;
color: #fff;
background-color: rgba(45, 48, 55, 1);
border-radius: 6px;
}
.lab-right {
margin-left: 20px;
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
}
.lab-box {
flex: 1;
width: 100%;
margin-top: 20px;
}
.iframe {
width: 100%;
height: 100%;
}
</style>
......@@ -26,7 +26,8 @@ export default defineConfig(({ mode }) => ({
cert: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.pem'))
},
proxy: {
'/api': 'https://resource-center.ezijing.com'
'/api': 'https://resource-center.ezijing.com',
'/lab': 'https://dev.ezijing.com'
}
},
resolve: {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论