提交 5d08f579 authored 作者: lihuihui's avatar lihuihui

开发课程,教案,其他内容

上级 b4673484
......@@ -134,6 +134,7 @@
"useDisplayMedia": true,
"useDocumentVisibility": true,
"useDraggable": true,
"useDropZone": true,
"useElementBounding": true,
"useElementByPoint": true,
"useElementHover": true,
......
......@@ -135,6 +135,7 @@ declare global {
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
const useDraggable: typeof import('@vueuse/core')['useDraggable']
const useDropZone: typeof import('@vueuse/core')['useDropZone']
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
const useElementHover: typeof import('@vueuse/core')['useElementHover']
......
......@@ -2,10 +2,8 @@ import { getCategoryList } from '@/api/base'
export function useGetCategoryList() {
const list = ref([])
onMounted(() => {
getCategoryList({ type: 'tree' }).then((res: any) => {
list.value = res.data
})
getCategoryList({ type: 'tree' }).then((res: any) => {
list.value = res.data
})
return { list }
}
\ No newline at end of file
......@@ -3,12 +3,9 @@ import { getProjectList } from '@/api/base'
export function useProjectList(id?: string) {
const list = ref([])
const members = ref([])
// onMounted(() => {
getProjectList({ organization_id: id || '' }).then((res: any) => {
list.value = res.data.departments
console.log(res.data, 'res.data')
members.value = res.data.members
})
// })
return { list, members }
}
\ No newline at end of file
......@@ -14,25 +14,29 @@ export function getCourseList(params: {
// 创建
export function createCourse(data: {
url: string
name: string
source: string
classification: string
knowledge_points: string
knowledge_points?: string
url: string
type: string
size: string
}) {
return httpRequest.post('/api/resource/v1/resource/courseware/create', data)
}
// 更新课件
export function updateCourse(data: {
id: string
url: string
id: string,
name: string
source: string
classification: string
knowledge_points: string
knowledge_points?: string
url: string
type: string
size: string
}) {
return httpRequest.post('/v1/resource/courseware/update', data)
return httpRequest.post('/api/resource/v1/resource/courseware/update', data)
}
// 获取课件详情
export function getCourseDetails(params: { id: string }) {
......
<script setup lang="ts">
import { setDepartment, setPlatform, setStatus, setBelong } from '../api'
import { useProjectList } from '@/composables/useGetProjectList'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useMapStore } from '@/stores/map'
const store = useMapStore()
console.log(store)
const router = useRouter()
const route = useRoute()
const props = defineProps(['data'])
const path = router.currentRoute.value.path
console.log(path, 'path')
const path = route.path
// 详情id
const id = router.currentRoute.value.query.id as string
const id = route.query.id as string
// 设置部门共享
const handleDepartment = () => {
ElMessageBox.confirm(
......
......@@ -63,7 +63,7 @@ const props = defineProps({
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon8.png" class="icons" />
<div class="text-box">
<div class="name">知识点</div>
<div class="textarea-box">
<div class="textarea-box" style="min-width:500px;">
{{ props.data?.knowledge_points || '暂无' }}
</div>
</div>
......
<script setup lang="ts">
import { getCourseList } from '../api'
import CardListItem from '@/components/base/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
import { Expand } from '@element-plus/icons-vue'
import { useMapStore } from '@/stores/map'
import { useGetCategoryList } from '@/composables/useGetCategoryList'
import { useProjectList } from '@/composables/useGetProjectList'
const store = useMapStore()
const appList = ref()
// 列表切换
const isCard = ref(true)
// 资源出处 tab触发
const tabValue = ref('1')
const tabChange = () => {
appList.value.refetch()
}
const store = useMapStore()
// 筛选项目列表
let { list: projectList } = useProjectList()
......@@ -28,27 +19,31 @@ const defaultProps = {
value: 'id'
}
const appList = ref()
// 列表切换
const isCard = ref(true)
// 资源出处 tab触发
const tabValue = ref('1')
const tabChange = () => {
appList.value.refetch()
}
const listOptions = $computed(() => {
return {
remote: {
httpRequest: getCourseList,
params: { tab: tabValue, title: '', status: '', authorized: '', classification: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
}
params: { tab: tabValue, status: '', authorized: '' }
},
filters: [
{
type: 'select',
prop: 'audit_status',
label: '状态',
options: store.mapList?.filter((item: any) => item.key === 'system_status')[0]?.values
options: store.getMapValuesByKey('system_status')
},
{ type: 'select', prop: 'authorized', label: '项目', options: projectList.value, labelKey: 'name', valueKey: 'id' },
{ prop: 'classification', label: '类别', slots: 'filter-type' },
{ prop: 'search', slots: 'filter-search' }
// { type: 'input', prop: 'category_id', prefixIcon: 'Search' }
{ prop: 'classification', label: '类别', slots: 'filter-type' }
],
columns: [
{ label: '课件标题', prop: 'name' },
......@@ -82,9 +77,6 @@ const listOptions = $computed(() => {
</div>
<AppList v-bind="listOptions" ref="appList">
<template #header-aside></template>
<template #filter-search="{ params }">
<el-input v-model="params.search" placeholder="搜索" :prefix-icon="Search" />
</template>
<template #filter-type="{ params }">
<el-tree-select :props="defaultProps" v-model="params.classification" :data="selectTree" />
</template>
......
<script setup lang="ts">
import { createCourse, updateCourse, getCourseDetails } from '../api'
import AppUpload from '@/components/base/AppUpload.vue'
import type { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import UploadAuth from '@/components/base/UploadAuth.vue'
import type { FormInstance, FormRules } from 'element-plus'
import { createCourse, getCourseDetails, updateCourse } from '../api'
import { useGetCategoryList } from '@/composables/useGetCategoryList'
import Operation from '../components/Operation.vue'
// 路由
const router = useRouter()
const ruleFormRef = ref<FormInstance>()
// 判断编辑还是新建
const route = useRoute()
// form表单
const form = reactive({
source: '2',
url: 'http://123.pdf',
name: '',
classification: '',
knowledge_points: ''
})
const rules = reactive<FormRules>({
url: [{ required: true, message: '请选择课件文件', trigger: 'change' }],
name: [{ required: true, message: '请输入课件名称', trigger: 'blur' }],
classification: [{ required: true, message: '请选择课件分类', trigger: 'change' }]
const id = route.query.id as string
// is 编辑 新建
const isUpdate = $computed(() => {
return !!route.query.id
})
// 协议
const protocol = ref(false)
// 上传视频过程返回值
const videoUpload = reactive({ code: -1, msg: '', progress: 0, fileName: '' })
// 上传视频回调
const uploadProgress = (res: any) => {
videoUpload.progress = res
}
const upload = (res: any) => {
const { code, msg, name } = res
videoUpload.code = code
videoUpload.msg = msg
videoUpload.fileName = name
videoUpload.progress = 0
// 编辑数据回显
if (isUpdate) {
getCourseDetails({ id: id }).then((res: any) => {
form = res.data
form.file = [
{
name: res.data.name,
url: res.data.url
}
]
})
}
// 下拉选择tree 视频分类
......@@ -47,122 +38,93 @@ const defaultProps = {
value: 'id'
}
const handleConfirm = async (formEl: FormInstance | undefined) => {
// form表单
let form: any = $ref({
file: [],
name: '',
source: '2',
classification: '',
knowledge_points: '',
url: '',
type: '',
size: ''
})
// 表单验证
const rules = {
name: [{ required: true, message: '请输入标题', trigger: 'blur' }],
classification: [{ required: true, message: '请选择分类', trigger: 'change' }],
file: [{ required: true, message: '' }]
}
// 新建编辑表单提交
const ruleFormRef = ref<FormInstance>()
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
await formEl.validate((valid) => {
if (valid) {
if (!protocol.value) {
ElMessage('请勾选用户协议')
return
}
const id = router.currentRoute.value.query.id as string
if (id !== '' && id) {
const params = Object.assign({ id: id }, form)
updateCourse(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '更新成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/courseware'
})
}, 1000)
}
})
const { url, type, size } = form.file[0]
form.url = url
form.type = type
form.size = size
const params = Object.assign({}, form)
delete params.file
if (isUpdate) {
params.id = id
updateResources(params)
} else {
createCourse(form).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '创建成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/courseware'
})
}, 1000)
}
})
createResources(params)
}
} else {
ElMessage('请完善信息')
console.log('error submit!', fields)
}
})
}
const statusData = reactive<{
department_public: string
platform_public: string
status: string
organ_id_name: string
organ_id: string
created_operator_name: string
belong_operator_name: string
created_time: string
updated_time: string
}>({
department_public: '0',
platform_public: '0',
status: '0',
organ_id_name: '',
organ_id: '',
created_operator_name: '',
belong_operator_name: '',
created_time: '',
updated_time: ''
})
const id = router.currentRoute.value.query.id as string
if (id !== '' && id) {
getCourseDetails({ id: id }).then(res => {
const key = ['name', 'classification', 'knowledge_points', 'cover', 'source_id']
key.forEach(item => {
form[item] = res.data[item]
})
const {
department_public,
platform_public,
status,
organ_id_name,
organ_id,
created_operator_name,
belong_operator_name,
created_time,
updated_time
} = res.data
statusData.department_public = department_public
statusData.platform_public = platform_public
statusData.status = status
statusData.organ_id_name = organ_id_name
statusData.organ_id = organ_id
statusData.created_operator_name = created_operator_name
statusData.belong_operator_name = belong_operator_name
statusData.created_time = created_time
statusData.updated_time = updated_time
// 更新
const updateResources = (params: any) => {
updateCourse(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '更新成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/courseware'
})
}, 1000)
}
})
}
// 新建
const createResources = (params: any) => {
createCourse(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '创建成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/courseware'
})
}, 1000)
}
})
}
// 协议
const protocol = ref(false)
</script>
<template>
<AppCard :title="id ? '编辑课件资源' : '新建课件资源'">
<div class="tool-btn-box" v-if="$route.query.id">
<div class="btn-item">部门共享</div>
<div class="btn-item">平台共享</div>
<div class="btn-item">资源下线</div>
<div class="btn-item">更改负责人</div>
</div>
<AppCard :title="isUpdate ? '编辑课件资源' : '新建课件资源'">
<Operation :data="form"></Operation>
<el-form ref="ruleFormRef" :model="form" :rules="rules" style="width: 70%">
<el-form-item label="课件文件:" prop="url">
<el-form-item label="课件文件:" prop="file">
<div>
<div class="upload-video">
<div class="upload-btn">
本地文件
<UploadAuth @progress="uploadProgress" @upload="upload"></UploadAuth>
</div>
<div class="demo-progress" v-if="videoUpload.code === 1">
<el-progress :percentage="videoUpload.progress" status="success" />
</div>
<div class="error video-info" v-if="videoUpload.code === 2">
<div class="name">上传失败</div>
</div>
<div class="video-info" v-if="videoUpload.code === 0">
<div class="name">{{ videoUpload.fileName }}</div>
<div class="view">查阅</div>
<div class="upload-box">
<AppUpload :limit="1" v-model="form.file"></AppUpload>
<div class="upload-btn">本地文件</div>
</div>
</div>
<div class="tips">课件支持格式包含:doc docx xls xlsx pdf ppt pptx,大小不超过50M</div>
......@@ -180,7 +142,7 @@ if (id !== '' && id) {
placeholder="请选择课件分类"
/>
</el-form-item>
<el-form-item label="&nbsp;&nbsp;&nbsp;知识点:" prop="knowledge_points">
<el-form-item label="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;知识点:">
<el-input v-model="form.knowledge_points" :rows="2" type="textarea" />
</el-form-item>
</el-form>
......@@ -190,12 +152,20 @@ if (id !== '' && id) {
</el-checkbox>
</div>
<div class="btn-box">
<div class="confirm" @click="handleConfirm(ruleFormRef)">保存</div>
<div class="confirm" @click="submitForm(ruleFormRef)">保存</div>
<div class="cancel">取消</div>
</div>
</AppCard>
</template>
<style lang="scss" scoped>
<style lang="scss">
.upload-box {
position: relative;
.app-upload-btn {
position: relative;
z-index: 99;
opacity: 0.0001 !important;
}
}
.tips {
font-size: 12px;
line-height: 100%;
......@@ -330,7 +300,9 @@ if (id !== '' && id) {
display: flex;
align-items: center;
.upload-btn {
position: relative;
position: absolute;
top: 0;
left: 0;
width: 94px;
line-height: 36px;
background: rgba(250, 223, 230, 0.39);
......
<script setup lang="ts">
import TopInfo from '../components/TopInfo.vue'
import CenterInfo from '../components/CenterInfo.vue'
import BottomInfo from '../components/BottomInfo.vue'
import ViewTop from '../components/ViewTop.vue'
import ViewCenter from '../components/ViewCenter.vue'
import ViewBottom from '../components/ViewBottom.vue'
import Operation from '../components/Operation.vue'
import { getCourseDetails } from '../api'
const router = useRouter()
const route = useRoute()
const id = route.query.id as string
const listOptions = {
columns: [
......@@ -25,27 +26,20 @@ const listOptions = {
{ img: 5, cursor_name: '宏观经济学.pptx', type_name: '5', zhang: '5', jie: '吉林师范大学', update: '王重阳' }
]
}
const id = router.currentRoute.value.query.id as string
// 获取详情
let courseDetails: any = ref({})
getCourseDetails({ id: id }).then(res => {
courseDetails.value = res.data
console.log(courseDetails, '1111111aaaaaaaaa')
})
</script>
<template>
<AppCard title="课件资源信息">
<!-- <div class="btn-box">
<div class="btn-item">部门共享</div>
<div class="btn-item">平台共享</div>
<div class="btn-item">资源下线</div>
<div class="btn-item">更改负责人</div>
</div> -->
<Operation :data="courseDetails" style="margin-bottom: 20px"></Operation>
<TopInfo v-if="Object.keys(courseDetails).length" :data="courseDetails"></TopInfo>
<CenterInfo v-if="Object.keys(courseDetails).length" :data="courseDetails"></CenterInfo>
<BottomInfo></BottomInfo>
<Operation :data="courseDetails"></Operation>
<ViewTop v-if="Object.keys(courseDetails).length" :data="courseDetails"></ViewTop>
<ViewCenter v-if="Object.keys(courseDetails).length" :data="courseDetails"></ViewCenter>
<ViewBottom></ViewBottom>
</AppCard>
<AppCard title="课件资源关联使用课程">
<AppList v-bind="listOptions" ref="appList" stripe>
......
<script setup lang="ts">
import { setDepartment, setPlatform, setStatus, setBelong } from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useMapStore } from '@/stores/map'
import { useProjectList } from '@/composables/useGetProjectList'
const store = useMapStore()
console.log(store)
const router = useRouter()
const route = useRoute()
const props = defineProps(['data'])
const path = router.currentRoute.value.path
console.log(path, 'path')
const path = route.path
// 详情id
const id = router.currentRoute.value.query.id as string
const id = route.query.id as string
// 设置部门共享
const handleDepartment = () => {
ElMessageBox.confirm(
......
<script setup lang="ts">
const props = defineProps({
data: {
type: Object,
require: true
}
})
</script>
<template>
<div class="center-video-box">
<div class="file-box">
<embed width="812" height="433" src="https://vocational-store.oss-cn-beijing.aliyuncs.com/files/20210604/7b1bfdec10354da769461199acf55176.pdf">
</div>
<!-- <video width="812" height="433" controls>
<div class="center-video-box">
<div class="file-box">
<embed width="812" height="433" :src="props.data?.url" />
</div>
<!-- <video width="812" height="433" controls>
<source src="https://video.shipin520.com/videos/17/36/71/b_KSyZ5ujXfz7R1567173671.mp4" type="video/mp4">
</video> -->
<div class="right-statistics">
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon1.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">使用项目/学校</div>
<div class="right-statistics">
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon1.png" />
<div class="content">
<div class="unit">{{ props.data?.project_count }}<span></span></div>
<div class="tag">使用项目/学校</div>
</div>
</div>
</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon2.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">使用课程</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon2.png" />
<div class="content">
<div class="unit">{{ props.data?.course_count }}<span></span></div>
<div class="tag">使用课程</div>
</div>
</div>
</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon3.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">累计学习人次</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon3.png" />
<div class="content">
<div class="unit">{{ props.data?.learn_count }}<span></span></div>
<div class="tag">累计学习人次</div>
</div>
</div>
</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon4.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">累计学习时长</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon4.png" />
<div class="content">
<div class="unit">{{ props.data?.learn_time_count }}<span></span></div>
<div class="tag">累计学习时长</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.center-video-box{
.center-video-box {
padding: 20px 0;
display: flex;
.right-statistics{
.right-statistics {
flex: 1;
padding-top: 15px;
.stat-item{
.stat-item {
width: 210px;
height: 85px;
background: #B41E47;
background: #b41e47;
border-radius: 6px;
display: flex;
align-items: center;
margin: 0 auto 20px;
&:nth-child(even){
background: #BF9D6B;
&:nth-child(even) {
background: #bf9d6b;
}
img{
img {
width: 52px;
height: 52px;
display: block;
margin-left: 18px;
}
.content{
.content {
margin-left: 18px;
.unit{
.unit {
font-size: 26px;
line-height: 100%;
color: #FFFFFF;
span{
color: #ffffff;
span {
font-size: 12px;
line-height: 100%;
}
}
.tag{
.tag {
font-size: 14px;
line-height: 100%;
color: #FFFFFF;
color: #ffffff;
margin-top: 10px;
}
}
......
<script setup lang="ts">
import { Files } from '@element-plus/icons-vue'
const props = defineProps({
data: {
type: Object,
require: true
}
})
</script>
<template>
......@@ -12,53 +18,53 @@ import { Files } from '@element-plus/icons-vue'
</div>
<div class="info-items">
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon1.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon1.png" class="icons" />
<div class="text-box">
<div class="name">状态</div>
<div class="value active">有效</div>
<div class="value active">{{ props.data?.status_name }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon12.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon12.png" class="icons" />
<div class="text-box">
<div class="name">创建者</div>
<div class="value">张三丰</div>
<div class="value">{{ props.data?.created_operator_name }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon3.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon3.png" class="icons" />
<div class="text-box">
<div class="name">创建时间</div>
<div class="value">2021-08-09 12:32:21</div>
<div class="value">{{ props.data?.created_time }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon4.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon4.png" class="icons" />
<div class="text-box">
<div class="name">更新时间</div>
<div class="value">2021-08-09 12:32:21</div>
<div class="value">{{ props.data?.updated_time }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon5.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon5.png" class="icons" />
<div class="text-box">
<div class="name">课件名称</div>
<div class="value">基金产品(中)(初级)</div>
<div class="name">教案名称</div>
<div class="value">{{ props.data?.name }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon6.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon6.png" class="icons" />
<div class="text-box">
<div class="name">课件分类</div>
<div class="value">金融产品数字化营销-黄老师</div>
<div class="name">教案分类</div>
<div class="value">{{ props.data?.classification_name || '暂无' }}</div>
</div>
</div>
<div class="i-items" style="align-items: flex-start;">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon8.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon8.png" class="icons" />
<div class="text-box">
<div class="name">知识点</div>
<div class="textarea-box">
某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某
<div class="textarea-box" style="min-width:500px;">
{{ props.data?.knowledge_points || '暂无' }}
</div>
</div>
</div>
......@@ -66,19 +72,19 @@ import { Files } from '@element-plus/icons-vue'
</div>
</template>
<style lang="scss" scoped>
.video-info{
background: #F7F7F7;
.video-info {
background: #f7f7f7;
margin-top: 20px;
padding: 20px;
display: flex;
.video-img{
.video-img {
// width: 211px;
padding: 0 30px;
.item-info-icon{
.item-info-icon {
font-size: 100px;
color: #aa1941;
}
.name{
.name {
font-size: 16px;
line-height: 100%;
color: #666666;
......@@ -86,40 +92,40 @@ import { Files } from '@element-plus/icons-vue'
text-align: center;
}
}
.info-items{
.info-items {
display: flex;
flex-wrap: wrap;
padding-left: 12px;
.i-items{
.i-items {
display: flex;
align-items: center;
height: fit-content;
margin-right: 80px;
margin-bottom: 30px;
.textarea-box{
.textarea-box {
padding: 18px 18px 51px;
background: #FFFFFF;
background: #ffffff;
border-radius: 4px;
font-size: 16px;
line-height: 24px;
color: #505050;
margin-top: 14px;
}
.text-box{
.text-box {
margin-left: 16px;
.name{
.name {
font-size: 14px;
line-height: 100%;
color: #999999;
}
.value{
.value {
font-size: 16px;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-top: 8px;
&.active{
color: #1AB226;
&.active {
color: #1ab226;
}
}
}
......
<script setup lang="ts">
import { getLessonList } from '../api'
import CardListItem from '@/components/base/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
import { Expand } from '@element-plus/icons-vue'
import { useMapStore } from '@/stores/map'
import { useGetCategoryList } from '@/composables/useGetCategoryList'
import { useProjectList } from '@/composables/useGetProjectList'
const store = useMapStore()
const appList = ref()
const isCard = ref(true)
// 资源出处 tab触发
const tabValue = ref('1')
const tabChange = () => {
appList.value.refetch()
}
// 筛选项目列表
let { list: projectList } = useProjectList()
// 下拉选择tree 视频分类
......@@ -26,15 +22,17 @@ const defaultProps = {
value: 'id'
}
// 资源出处 tab触发
const tabValue = ref('1')
const tabChange = () => {
appList.value.refetch()
}
const listOptions = $computed(() => {
return {
remote: {
httpRequest: getLessonList,
params: { tab: tabValue, status: '', authorized: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
}
params: { tab: tabValue, status: '', authorized: '' }
},
filters: [
{
......@@ -44,9 +42,7 @@ const listOptions = $computed(() => {
options: store.getMapValuesByKey('system_status')
},
{ type: 'select', prop: 'authorized', label: '项目', options: projectList.value, labelKey: 'name', valueKey: 'id' },
{ prop: 'classification', label: '类别', slots: 'filter-type' },
{ prop: 'search', slots: 'filter-search' }
// { type: 'input', prop: 'category_id', prefixIcon: 'Search' }
{ prop: 'classification', label: '类别', slots: 'filter-type' }
],
columns: [
{ label: '教案标题', prop: 'name' },
......@@ -81,9 +77,6 @@ const listOptions = $computed(() => {
</div>
<AppList v-bind="listOptions" ref="appList">
<template #header-aside></template>
<template #filter-search="{ params }">
<el-input v-model="params.search" placeholder="搜索" :prefix-icon="Search" />
</template>
<template #filter-type="{ params }">
<el-tree-select :props="defaultProps" v-model="params.classification" :data="selectTree" />
</template>
......
......@@ -8,8 +8,27 @@ import Operation from '../components/Operation.vue'
// 路由
const router = useRouter()
const route = useRoute()
const id = router.currentRoute.value.query.id as string
const id = route.query.id as string
// is 编辑 新建
const isUpdate = $computed(() => {
return !!route.query.id
})
// 编辑数据回显
if (isUpdate) {
getLessonDetails({ id: id }).then((res: any) => {
form = res.data
form.file = [
{
name: res.data.name,
url: res.data.url
}
]
})
}
// 下拉选择tree 视频分类
let { list: selectTree } = useGetCategoryList()
......@@ -20,7 +39,7 @@ const defaultProps = {
}
// form表单
const form: any = reactive({
let form: any = $ref({
file: [],
name: '',
source: '2',
......@@ -40,115 +59,65 @@ const rules = {
const ruleFormRef = ref<FormInstance>()
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
console.log(valid, 'valid', fields)
await formEl.validate((valid) => {
if (valid) {
if (!protocol.value) {
ElMessage('请勾选用户协议')
return
}
const id = router.currentRoute.value.query.id as string
const formFile = form.file[0]
form.url = formFile.url
form.type = formFile.type
form.size = formFile.size
const { url, type, size } = form.file[0]
form.url = url
form.type = type
form.size = size
const params = Object.assign({}, form)
delete params.file
if (id !== '' && id) {
if (isUpdate) {
params.id = id
console.log(params, 'paramsparams')
updateLessonPlan(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '更新成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/lessonplan'
})
}, 1000)
}
})
updateResources(params)
} else {
createLessonPlan(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '创建成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/lessonplan'
})
}, 1000)
}
})
createResources(params)
}
} else {
ElMessage('请完善信息')
console.log('error submit!', fields)
}
})
}
// 协议
const protocol = ref(false)
// 判断编辑还是新建
const statusData = reactive<{
department_public: string
platform_public: string
status: string
organ_id_name: string
organ_id: string
created_operator_name: string
belong_operator_name: string
created_time: string
updated_time: string
}>({
department_public: '0',
platform_public: '0',
status: '0',
organ_id_name: '',
organ_id: '',
created_operator_name: '',
belong_operator_name: '',
created_time: '',
updated_time: ''
})
if (id !== '' && id) {
getLessonDetails({ id: id }).then(res => {
const key = ['name', 'classification', 'knowledge_points', 'url', 'size', 'type']
key.forEach(item => {
form[item] = res.data[item]
})
form.file = [
{
name: res.data.name,
url: res.data.url
}
]
const {
department_public,
platform_public,
status,
organ_id_name,
organ_id,
created_operator_name,
belong_operator_name,
created_time,
updated_time
} = res.data
statusData.department_public = department_public
statusData.platform_public = platform_public
statusData.status = status
statusData.organ_id_name = organ_id_name
statusData.organ_id = organ_id
statusData.created_operator_name = created_operator_name
statusData.belong_operator_name = belong_operator_name
statusData.created_time = created_time
statusData.updated_time = updated_time
// 更新
const updateResources = (params: any) => {
updateLessonPlan(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '更新成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/lessonplan'
})
}, 1000)
}
})
}
// 新建
const createResources = (params: any) => {
createLessonPlan(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '创建成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/lessonplan'
})
}, 1000)
}
})
}
// 协议
const protocol = ref(false)
</script>
<template>
<AppCard title="新建教案资源">
<Operation :data="statusData" style="margin-bottom: 20px"></Operation>
<AppCard :title="isUpdate ? '编辑教案资源' : '新建教案资源'">
<Operation :data="form"></Operation>
<el-form ref="ruleFormRef" :model="form" :rules="rules" style="width: 70%">
<el-form-item label="教案文件:" prop="file">
<div>
......
<script setup lang="ts">
import TopInfo from '../components/TopInfo.vue'
import CenterInfo from '../components/CenterInfo.vue'
import BottomInfo from '../components/BottomInfo.vue'
import ViewTop from '../components/ViewTop.vue'
import ViewCenter from '../components/ViewCenter.vue'
import ViewBottom from '../components/ViewBottom.vue'
import Operation from '../components/Operation.vue'
import { getLessonDetails } from '../api'
const router = useRouter()
const route = useRoute()
const listOptions = {
columns: [
......@@ -24,7 +25,7 @@ const listOptions = {
{ img: 5, cursor_name: '宏观经济学.pptx', type_name: '5', zhang: '5', jie: '吉林师范大学', update: '王重阳' }
]
}
const id = router.currentRoute.value.query.id as string
const id = route.query.id as string
// 获取详情
let lessonDetails: any = ref({})
getLessonDetails({ id: id }).then((res: any) => {
......@@ -34,17 +35,10 @@ getLessonDetails({ id: id }).then((res: any) => {
<template>
<AppCard title="课件资源信息">
<!-- <div class="btn-box">
<div class="btn-item">部门共享</div>
<div class="btn-item">平台共享</div>
<div class="btn-item">资源下线</div>
<div class="btn-item">更改负责人</div>
</div> -->
<Operation :data="lessonDetails" style="margin-bottom: 20px"></Operation>
<TopInfo :data="lessonDetails"></TopInfo>
<CenterInfo v-if="Object.keys(lessonDetails).length" :data="lessonDetails"></CenterInfo>
<BottomInfo></BottomInfo>
<Operation :data="lessonDetails"></Operation>
<ViewTop :data="lessonDetails"></ViewTop>
<ViewCenter v-if="Object.keys(lessonDetails).length" :data="lessonDetails"></ViewCenter>
<ViewBottom></ViewBottom>
</AppCard>
<AppCard title="课件资源关联使用课程">
<AppList v-bind="listOptions" ref="appList" stripe>
......
......@@ -11,6 +11,34 @@ export function getOtherList(params?: {
}) {
return httpRequest.get('/api/resource/v1/resource/other-information/list', { params })
}
// 创建教案
export function createOther(data: {
name: string
source: string
classification: string
knowledge_points?: string
url: string
type: string
size: string
}) {
return httpRequest.post('/api/resource/v1/resource/other-information/create', data)
}
// 更新教案
export function updateOther(data: {
id: string,
name: string
source: string
classification: string
knowledge_points?: string
url: string
type: string
size: string
}) {
return httpRequest.post('/api/resource/v1/resource/other-information/update', data)
}
// 获取其他资料详情
export function getOtherDetails(params: { id: string }) {
return httpRequest.get('/api/resource/v1/resource/other-information/view', { params })
......
<script setup lang="ts">
const props = defineProps({
data: {
type: Object,
require: true
}
})
</script>
<template>
<div class="center-video-box">
<div class="file-box">
<embed width="812" height="433" src="https://vocational-store.oss-cn-beijing.aliyuncs.com/files/20210604/7b1bfdec10354da769461199acf55176.pdf">
</div>
<!-- <video width="812" height="433" controls>
<div class="center-video-box">
<div class="file-box">
<embed width="812" height="433" :src="props.data?.url" />
</div>
<!-- <video width="812" height="433" controls>
<source src="https://video.shipin520.com/videos/17/36/71/b_KSyZ5ujXfz7R1567173671.mp4" type="video/mp4">
</video> -->
<div class="right-statistics">
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon1.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">使用项目/学校</div>
<div class="right-statistics">
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon1.png" />
<div class="content">
<div class="unit">{{ props.data?.project_count }}<span></span></div>
<div class="tag">使用项目/学校</div>
</div>
</div>
</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon2.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">使用课程</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon2.png" />
<div class="content">
<div class="unit">{{ props.data?.course_count }}<span></span></div>
<div class="tag">使用课程</div>
</div>
</div>
</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon3.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">累计学习人次</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon3.png" />
<div class="content">
<div class="unit">{{ props.data?.learn_count }}<span></span></div>
<div class="tag">累计学习人次</div>
</div>
</div>
</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon4.png">
<div class="content">
<div class="unit">758<span></span></div>
<div class="tag">累计学习时长</div>
<div class="stat-item">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/view-vicon4.png" />
<div class="content">
<div class="unit">{{ props.data?.learn_time_count }}<span></span></div>
<div class="tag">累计学习时长</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.center-video-box{
.center-video-box {
padding: 20px 0;
display: flex;
.right-statistics{
.right-statistics {
flex: 1;
padding-top: 15px;
.stat-item{
.stat-item {
width: 210px;
height: 85px;
background: #B41E47;
background: #b41e47;
border-radius: 6px;
display: flex;
align-items: center;
margin: 0 auto 20px;
&:nth-child(even){
background: #BF9D6B;
&:nth-child(even) {
background: #bf9d6b;
}
img{
img {
width: 52px;
height: 52px;
display: block;
margin-left: 18px;
}
.content{
.content {
margin-left: 18px;
.unit{
.unit {
font-size: 26px;
line-height: 100%;
color: #FFFFFF;
span{
color: #ffffff;
span {
font-size: 12px;
line-height: 100%;
}
}
.tag{
.tag {
font-size: 14px;
line-height: 100%;
color: #FFFFFF;
color: #ffffff;
margin-top: 10px;
}
}
......
<script setup lang="ts">
import { Files } from '@element-plus/icons-vue'
const props = defineProps({
data: {
type: Object,
require: true
}
})
</script>
<template>
......@@ -12,53 +18,53 @@ import { Files } from '@element-plus/icons-vue'
</div>
<div class="info-items">
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon1.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon1.png" class="icons" />
<div class="text-box">
<div class="name">状态</div>
<div class="value active">有效</div>
<div class="value active">{{ props.data?.status_name }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon12.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon12.png" class="icons" />
<div class="text-box">
<div class="name">创建者</div>
<div class="value">张三丰</div>
<div class="value">{{ props.data?.created_operator_name }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon3.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon3.png" class="icons" />
<div class="text-box">
<div class="name">创建时间</div>
<div class="value">2021-08-09 12:32:21</div>
<div class="value">{{ props.data?.created_time }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon4.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon4.png" class="icons" />
<div class="text-box">
<div class="name">更新时间</div>
<div class="value">2021-08-09 12:32:21</div>
<div class="value">{{ props.data?.updated_time }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon5.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon5.png" class="icons" />
<div class="text-box">
<div class="name">课件名称</div>
<div class="value">基金产品(中)(初级)</div>
<div class="name">其他名称</div>
<div class="value">{{ props.data?.name }}</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon6.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon6.png" class="icons" />
<div class="text-box">
<div class="name">课件分类</div>
<div class="value">金融产品数字化营销-黄老师</div>
<div class="name">其他分类</div>
<div class="value">{{ props.data?.classification_name || '暂无' }}</div>
</div>
</div>
<div class="i-items" style="align-items: flex-start;">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon8.png" class="icons">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon8.png" class="icons" />
<div class="text-box">
<div class="name">知识点</div>
<div class="textarea-box">
某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某
<div class="textarea-box" style="min-width:500px;">
{{ props.data?.knowledge_points || '暂无' }}
</div>
</div>
</div>
......@@ -66,19 +72,19 @@ import { Files } from '@element-plus/icons-vue'
</div>
</template>
<style lang="scss" scoped>
.video-info{
background: #F7F7F7;
.video-info {
background: #f7f7f7;
margin-top: 20px;
padding: 20px;
display: flex;
.video-img{
.video-img {
// width: 211px;
padding: 0 30px;
.item-info-icon{
.item-info-icon {
font-size: 100px;
color: #aa1941;
}
.name{
.name {
font-size: 16px;
line-height: 100%;
color: #666666;
......@@ -86,40 +92,40 @@ import { Files } from '@element-plus/icons-vue'
text-align: center;
}
}
.info-items{
.info-items {
display: flex;
flex-wrap: wrap;
padding-left: 12px;
.i-items{
.i-items {
display: flex;
align-items: center;
height: fit-content;
margin-right: 80px;
margin-bottom: 30px;
.textarea-box{
.textarea-box {
padding: 18px 18px 51px;
background: #FFFFFF;
background: #ffffff;
border-radius: 4px;
font-size: 16px;
line-height: 24px;
color: #505050;
margin-top: 14px;
}
.text-box{
.text-box {
margin-left: 16px;
.name{
.name {
font-size: 14px;
line-height: 100%;
color: #999999;
}
.value{
.value {
font-size: 16px;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-top: 8px;
&.active{
color: #1AB226;
&.active {
color: #1ab226;
}
}
}
......
<script setup lang="ts">
import { getOtherList } from '../api'
import CardListItem from '@/components/base/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
import { Expand } from '@element-plus/icons-vue'
import { useMapStore } from '@/stores/map'
import { useProjectList } from '@/composables/useGetProjectList'
// 下拉选择tree 视频分类
import { useGetCategoryList } from '@/composables/useGetCategoryList'
const store = useMapStore()
const appList = ref()
......@@ -33,23 +34,24 @@ const listOptions = $computed(() => {
return {
remote: {
httpRequest: getOtherList,
params: { tab: tabValue, title: '', status: '', authorized: '', classification: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
}
params: { tab: tabValue, status: '', authorized: '' }
},
filters: [
{
type: 'select',
prop: 'audit_status',
label: '状态',
options: store.mapList?.filter((item: any) => item.key === 'system_status')[0]?.values
options: store.getMapValuesByKey('system_status')
},
{ type: 'select', prop: 'authorized', label: '项目', options: projectList.value, labelKey: 'name', valueKey: 'id' },
{ prop: 'classification', label: '类别', slots: 'filter-type' },
{ prop: 'search', slots: 'filter-search' }
// { type: 'input', prop: 'category_id', prefixIcon: 'Search' }
{
type: 'select',
prop: 'authorized',
label: '项目',
options: projectList.value,
labelKey: 'name',
valueKey: 'id'
},
{ prop: 'classification', label: '类别', slots: 'filter-type' }
],
columns: [
{ label: '课件标题', prop: 'name' },
......@@ -77,24 +79,21 @@ const listOptions = $computed(() => {
<el-icon class="video-head-icon" @click="isCard = !isCard"><Expand /></el-icon>
</div>
<div class="video-tool-btn">
<router-link to="/resource/courseware/update">
<router-link to="/resource/other/update">
<el-button type="primary" round>新建课件资源</el-button>
</router-link>
</div>
<AppList v-bind="listOptions" ref="appList">
<template #header-aside></template>
<template #filter-search="{ params }">
<el-input v-model="params.search" placeholder="搜索" :prefix-icon="Search" />
</template>
<template #filter-type="{ params }">
<el-tree-select :props="defaultProps" v-model="params.classification" :data="selectTree" />
</template>
<template #table-operate="{ row }">
<el-space>
<router-link :to="`/resource/courseware/update/?id=${row.id}`">
<router-link :to="`/resource/other/update/?id=${row.id}`">
<el-button plain>编辑</el-button>
</router-link>
<router-link :to="`/resource/courseware/view/?id=${row.id}`">
<router-link :to="`/resource/other/view/?id=${row.id}`">
<el-button type="primary" plain>查看</el-button>
</router-link>
</el-space>
......
<script setup lang="ts">
import UploadAuth from '@/components/base/UploadAuth.vue'
import AppUpload from '@/components/base/AppUpload.vue'
import type { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import { createOther, getOtherDetails, updateOther } from '../api'
import { useGetCategoryList } from '@/composables/useGetCategoryList'
import Operation from '../components/Operation.vue'
// form表单
const form = reactive({ videoFile: '', videoName: '', videoType: '', zsd: '', aliyun_video_id: '', weight: '' })
const rules = {}
const data = [
{
value: '1',
label: 'Level one 1',
children: [
{
value: '1-1',
label: 'Level two 1-1',
children: [
{
value: '1-1-1',
label: 'Level three 1-1-1',
},
],
},
],
},
{
value: '2',
label: 'Level one 2',
children: [
{
value: '2-1',
label: 'Level two 2-1',
children: [
{
value: '2-1-1',
label: 'Level three 2-1-1',
},
],
},
{
value: '2-2',
label: 'Level two 2-2',
children: [
{
value: '2-2-1',
label: 'Level three 2-2-1',
},
],
},
],
},
{
value: '3',
label: 'Level one 3',
children: [
{
value: '3-1',
label: 'Level two 3-1',
children: [
{
value: '3-1-1',
label: 'Level three 3-1-1',
},
],
},
{
value: '3-2',
label: 'Level two 3-2',
children: [
{
value: '3-2-1',
label: 'Level three 3-2-1',
},
],
},
],
},
]
// 协议
const protocol = ref(false)
// 上传视频过程返回值
const videoUpload = reactive({ code: -1, msg: '', progress: 0, fileName: '' })
// 上传视频回调
const uploadProgress = (res: any) => {
videoUpload.progress = res
}
const upload = (res: any) => {
const { code, msg, name } = res
videoUpload.code = code
videoUpload.msg = msg
videoUpload.fileName = name
videoUpload.progress = 0
}
// 路由
const router = useRouter()
const route = useRoute()
const id = route.query.id as string
// is 编辑 新建
const isUpdate = $computed(() => {
return !!route.query.id
})
// 编辑数据回显
if (isUpdate) {
getOtherDetails({ id: id }).then((res: any) => {
form = res.data
form.file = [
{
name: res.data.name,
url: res.data.url
}
]
})
}
// 下拉选择tree 视频分类
let { list: selectTree } = useGetCategoryList()
const defaultProps = {
children: 'children',
label: 'category_name',
value: 'id'
}
// form表单
let form: any = $ref({
file: [],
name: '',
source: '2',
classification: '',
knowledge_points: '',
url: '',
type: '',
size: ''
})
// 表单验证
const rules = {
name: [{ required: true, message: '请输入标题', trigger: 'blur' }],
classification: [{ required: true, message: '请选择分类', trigger: 'change' }],
file: [{ required: true, message: '' }]
}
// 新建编辑表单提交
const ruleFormRef = ref<FormInstance>()
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
if (valid) {
if (!protocol.value) {
ElMessage('请勾选用户协议')
return
}
const { url, type, size } = form.file[0]
form.url = url
form.type = type
form.size = size
const params = Object.assign({}, form)
delete params.file
if (isUpdate) {
params.id = id
updateResources(params)
} else {
createResources(params)
}
} else {
ElMessage('请完善信息')
}
})
}
// 更新
const updateResources = (params: any) => {
updateOther(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '更新成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/other'
})
}, 1000)
}
})
}
// 新建
const createResources = (params: any) => {
createOther(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '创建成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/other'
})
}, 1000)
}
})
}
// 协议
const protocol = ref(false)
</script>
<template>
<AppCard title="新建其他资源">
<div class="tool-btn-box" v-if="$route.query.id">
<div class="btn-item">部门共享</div>
<div class="btn-item">平台共享</div>
<div class="btn-item">资源下线</div>
<div class="btn-item">更改负责人</div>
</div>
<el-form ref="formRef" :model="form" :rules="rules" style="width: 70%">
<el-form-item label="资料文件:" prop="course_name">
<AppCard :title="isUpdate ? '编辑其他资源' : '新建其他资源'">
<Operation :data="form"></Operation>
<el-form ref="ruleFormRef" :model="form" :rules="rules" style="width: 70%">
<el-form-item label="其他文件:" prop="file">
<div>
<div class="upload-video">
<div class="upload-btn">
本地文件
<UploadAuth @progress="uploadProgress" @upload="upload"></UploadAuth>
</div>
<div class="demo-progress" v-if="videoUpload.code === 1">
<el-progress :percentage="videoUpload.progress" status="success" />
</div>
<div class="error video-info" v-if="videoUpload.code === 2">
<div class="name">上传失败</div>
</div>
<div class="video-info" v-if="videoUpload.code === 0">
<div class="name">{{ videoUpload.fileName }}</div>
<div class="view">查阅</div>
<div class="upload-box">
<AppUpload :limit="1" v-model="form.file"></AppUpload>
<div class="upload-btn">本地文件</div>
</div>
</div>
<div class="tips">文件支持格式包含:doc docx xls xlsx pdf ppt pptx mp3 mp4 png jpeg jpg,大小不超过200M</div>
</div>
</el-form-item>
<el-form-item label="资料名称:" prop="course_name">
<el-input v-model="form.videoName" />
<el-form-item label="其他名称:" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="资料分类:" prop="course_name">
<el-tree-select style="width:100%" v-model="form.videoType" :data="data" />
<el-form-item label="其他分类:" prop="classification">
<el-tree-select :props="defaultProps" style="width: 100%" v-model="form.classification" :data="selectTree" />
</el-form-item>
<el-form-item label="&nbsp;&nbsp;&nbsp;知识点:" prop="course_name">
<el-input
v-model="form.zsd"
:rows="2"
type="textarea"
/>
<el-form-item label="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;知识点:">
<el-input v-model="form.knowledge_points" :rows="2" type="textarea" />
</el-form-item>
</el-form>
<div class="protocol-box">
......@@ -141,65 +146,73 @@
</el-checkbox>
</div>
<div class="btn-box">
<div class="confirm">保存</div>
<div class="confirm" @click="submitForm(ruleFormRef)">保存</div>
<div class="cancel">取消</div>
</div>
</AppCard>
</template>
<style lang="scss" scoped>
.tips{
<style lang="scss">
.upload-box {
position: relative;
.app-upload-btn {
position: relative;
z-index: 99;
opacity: 0.0001 !important;
}
}
.tips {
font-size: 12px;
line-height: 100%;
color: #999999;
margin-top: 8px;
}
.tool-btn-box{
.tool-btn-box {
display: flex;
justify-content: right;
.btn-item{
.btn-item {
width: 127px;
line-height: 36px;
background: #AA1941;
background: #aa1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
color: #ffffff;
text-align: center;
}
}
.demo-progress{
.demo-progress {
width: 350px;
}
.video-cover{
.video-cover {
display: flex;
.img-box{
.img-box {
width: 208px;
height: 130px;
border-radius: 4px;
background: #F7F7F7;
background: #f7f7f7;
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
img{
img {
width: 100%;
height: 100%;
display: block;
}
}
.video-cover_right{
.video-cover_right {
margin-left: 20px;
.list{
.item{
.list {
.item {
display: flex;
align-items: center;
margin-top: 12px;
img{
img {
width: 9px;
display: block;
margin-right: 5px;
}
.text{
.text {
font-size: 12px;
color: #999999;
line-height: 100%;
......@@ -208,58 +221,58 @@
}
}
}
.swiper-box{
.swiper-box {
min-width: 660px;
margin-top: 20px;
padding: 0 40px;
position: relative;
.arrow{
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 30px;
color: #D5D5D5;
color: #d5d5d5;
cursor: pointer;
&.left{
&.left {
left: 0;
}
&.right{
&.right {
right: 10px;
}
}
.cover-list{
.cover-list {
display: flex;
flex-wrap: wrap;
.cover-list_item{
.cover-list_item {
display: block;
width: 155px;
height: 96px;
margin: 0 10px 10px 0;
border-radius: 4px;
border-radius: 4px;
cursor: pointer;
}
}
}
:deep(.el-carousel__indicators--horizontal){
:deep(.el-carousel__indicators--horizontal) {
display: none;
}
.protocol-box{
.protocol-box {
font-size: 14px;
line-height: 24px;
padding-left: 90px;
padding-top: 20px;
color: #666666;
span{
color: #AA1941;
span {
color: #aa1941;
}
}
.btn-box{
.btn-box {
display: flex;
margin-top: 20px;
margin-left: 90px;
.confirm{
.confirm {
width: 94px;
background: #AA1941;
background: #aa1941;
border-radius: 20px;
text-align: center;
line-height: 36px;
......@@ -267,42 +280,44 @@
margin-right: 26px;
cursor: pointer;
}
.cancel{
.cancel {
width: 94px;
line-height: 36px;
border: 1px solid #AA1941;
border: 1px solid #aa1941;
border-radius: 20px;
text-align: center;
color: #AA1941;
color: #aa1941;
cursor: pointer;
}
}
.upload-video{
.upload-video {
display: flex;
align-items: center;
.upload-btn{
position: relative;
.upload-btn {
position: absolute;
top: 0;
left: 0;
width: 94px;
line-height: 36px;
background: rgba(250, 223, 230, 0.39);
border: 1px solid #AA1941;
border: 1px solid #aa1941;
border-radius: 20px;
font-size: 14px;
color: #AA1941;
color: #aa1941;
margin-right: 30px;
text-align: center;
}
.video-info{
.video-info {
display: flex;
.name{
.name {
color: #333333;
font-size: 16px;
line-height: 100%;
}
.view{
.view {
font-size: 16px;
line-height: 100%;
color: #399EE8;
color: #399ee8;
margin-left: 20px;
cursor: pointer;
}
......
<script setup lang="ts">
import TopInfo from '../components/TopInfo.vue'
import CenterInfo from '../components/CenterInfo.vue'
import BottomInfo from '../components/BottomInfo.vue'
import ViewTop from '../components/ViewTop.vue'
import ViewCenter from '../components/ViewCenter.vue'
import ViewBottom from '../components/ViewBottom.vue'
import Operation from '../components/Operation.vue'
import { getOtherDetails } from '../api'
const router = useRouter()
const route = useRoute()
const id = route.query.id as string
const listOptions = {
columns: [
......@@ -24,7 +27,7 @@ const listOptions = {
{ img: 5, cursor_name: '宏观经济学.pptx', type_name: '5', zhang: '5', jie: '吉林师范大学', update: '王重阳' }
]
}
const id = router.currentRoute.value.query.id as string
// 获取详情
let otherDetails: any = ref({})
getOtherDetails({ id: id }).then((res: any) => {
......@@ -34,17 +37,10 @@ getOtherDetails({ id: id }).then((res: any) => {
<template>
<AppCard title="课件资源信息">
<!-- <div class="btn-box">
<div class="btn-item">部门共享</div>
<div class="btn-item">平台共享</div>
<div class="btn-item">资源下线</div>
<div class="btn-item">更改负责人</div>
</div> -->
<Operation :data="otherDetails" style="margin-bottom: 20px"></Operation>
<TopInfo :data="otherDetails"></TopInfo>
<CenterInfo v-if="Object.keys(otherDetails).length" :data="otherDetails"></CenterInfo>
<BottomInfo></BottomInfo>
<ViewTop :data="otherDetails"></ViewTop>
<ViewCenter v-if="Object.keys(otherDetails).length" :data="otherDetails"></ViewCenter>
<ViewBottom></ViewBottom>
</AppCard>
<AppCard title="课件资源关联使用课程">
<AppList v-bind="listOptions" ref="appList" stripe>
......
<script setup lang="ts">
import { setDepartment, setPlatform, setStatus, setBelong } from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useMapStore } from '@/stores/map'
import { useProjectList } from '@/composables/useGetProjectList'
const store = useMapStore()
console.log(store)
const router = useRouter()
const route = useRoute()
const props = defineProps(['data'])
const path = router.currentRoute.value.path
console.log(path, 'path')
const path = route.path
// 详情id
const id = router.currentRoute.value.query.id as string
const id = route.query.id as string
// 设置部门共享
const handleDepartment = () => {
ElMessageBox.confirm(
......
<script setup lang="ts">
import { getCreateAuth, updateAuth } from '@/api/base'
/**
* upload 上传状态 {code: -1(待上传)0(成功) 1(开始上传) 2(上传失败), msg: '上传信息'}
* progress 上传进度
**/
interface IUpload {
code: number,
name?: string,
msg?: string,
progress?: number,
videoId?: string
}
let uploadData = $ref<IUpload>({ code: -1 })
const emit = defineEmits(['upload'])
const form:any = reactive({
timeout: '',
partSize: '',
parallel: '',
retryCount: '',
retryDuration: '',
region: 'cn-shanghai',
userId: '1303984639806000',
file: null,
authProgress: 0,
uploader: null,
statusText: ''
})
const fileChange = (e:any) => {
form.file = e.target.files[0]
var userData = '{"Vod":{}}'
if (form.uploader) {
form.uploader.stopUpload()
form.authProgress = 0
form.statusText = ""
}
form.uploader = createUploader()
form.uploader.addFile(form.file, null, null, null, userData)
form.uploader.startUpload()
}
const createUploader:any = () => {
const w = window as any
const uploader = new w.AliyunUpload.Vod({
timeout: form.timeout || 60000,
partSize: form.partSize || 1048576,
parallel: form.parallel || 5,
retryCount: form.retryCount || 3,
retryDuration: form.retryDuration || 2,
region: form.region,
userId: form.userId,
// 开始上传
onUploadstarted: function (uploadInfo:any) {
const fileData = JSON.parse(window.localStorage.fileData || '{}')
// 判断有没有上传过
const isFile = !!fileData.sourceId
if (!isFile) {
// 没上传过请求凭证上传
getCreateAuth({ title: uploadInfo.file.name, file_name: uploadInfo.file.name }).then((data: any) => {
window.localStorage.fileData = JSON.stringify({
uploadAuth: data.data.upload_auth,
uploadAddress: data.data.upload_address,
videoId: data.data.source_id,
fileName: uploadInfo.file.name,
fileSize: uploadInfo.file.size
})
uploader.setUploadAuthAndAddress(uploadInfo, data.data.upload_auth, data.data.upload_address, data.data.source_id)
})
} else {
// 上传过判断一下上次上传的文件和本次上传的文件一不一样,一样的话继续上传
if (fileData.fileName === uploadInfo.file.name && fileData.fileSize === uploadInfo.file.size) {
uploader.setUploadAuthAndAddress(uploadInfo, fileData.uploadAuth, fileData.uploadAddress, fileData.videoId)
} else {
getCreateAuth({ title: uploadInfo.file.name, file_name: uploadInfo.file.name }).then((data: any) => {
uploader.setUploadAuthAndAddress(uploadInfo, data.data.upload_auth, data.data.upload_address, data.data.source_id)
})
}
}
uploadData = {
code: 1,
name: uploadInfo.file.name,
msg: '开始上传'
}
},
// 文件上传成功
onUploadSucceed: function (uploadInfo:any) {
const fileData = window.localStorage.fileData ? JSON.parse(window.localStorage.fileData) : {}
uploadData = {
code: 0,
name: uploadInfo.file.name,
videoId: fileData.videoId,
msg: '上传成功'
}
emit('upload', fileData.videoId)
},
// 文件上传失败
// code:any, message:any
onUploadFailed: function (uploadInfo:any) {
uploadData = {
code: 2,
name: uploadInfo.file.name,
msg: '文件上传失败'
}
},
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress: function (uploadInfo:any, totalSize:any, progress:any) {
let progressPercent = Math.ceil(progress * 100)
form.authProgress = progressPercent
uploadData.progress = progressPercent
},
// 上传凭证超时
onUploadTokenExpired: function (uploadInfo:any) {
const fileData = JSON.parse(window.localStorage.fileData || '{}')
updateAuth({ source_id: fileData.videoId }).then(({ data }) => {
let uploadAuth = data.UploadAuth
window.localStorage.fileData = JSON.stringify({
uploadAuth: data.data.upload_auth,
uploadAddress: data.data.upload_address,
videoId: data.data.source_id,
fileName: uploadInfo.file.name,
fileSize: uploadInfo.file.size
})
uploader.resumeUploadWithAuth(uploadAuth)
})
}
// 全部文件上传结束
// onUploadEnd: function (uploadInfo: any) {
// console.log(uploadInfo, '上传完成')
// // console.log("onUploadEnd: uploaded all the files")
// }
})
return uploader
}
</script>
<template>
<div>
<div class="upload-video">
<div class="upload-btn">
本地文件
<input type="file" id="fileUpload" @change="fileChange($event)">
</div>
<div class="demo-progress" v-if="uploadData.code === 1">
<el-progress :percentage="uploadData.progress" status="success" />
</div>
<div class="error video-info" v-if="uploadData.code === 2">
<div class="name">上传失败</div>
</div>
<div class="video-info" v-if="uploadData.code === 0">
<div class="name">{{ uploadData.name }}</div>
</div>
</div>
<div class="tips">
推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。
</div>
</div>
</template>
<style lang="scss">
.demo-progress {
width: 350px;
}
#fileUpload{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.00001;
}
.tips {
font-size: 12px;
line-height: 100%;
color: #999999;
margin-top: 8px;
}
.upload-video {
display: flex;
align-items: center;
.upload-btn {
position: relative;
width: 94px;
line-height: 36px;
background: rgba(250, 223, 230, 0.39);
border: 1px solid #aa1941;
border-radius: 20px;
font-size: 14px;
color: #aa1941;
margin-right: 30px;
text-align: center;
}
.video-info {
display: flex;
.name {
color: #333333;
font-size: 16px;
line-height: 100%;
}
.view {
font-size: 16px;
line-height: 100%;
color: #399ee8;
margin-left: 20px;
cursor: pointer;
}
}
}
</style>
\ No newline at end of file
<script setup lang="ts">
const props = defineProps(['data'])
console.log(props, 'porps')
</script>
<template>
......
<script setup lang="ts">
import TopInfo from '../components/TopInfo.vue'
import Upload from '../components/Upload.vue'
import ViewTop from '../components/ViewTop.vue'
import UploadImg from '../components/UploadImg.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getVideoPpt, createPpt, updatePpt, deletePpt } from '../api'
......@@ -106,7 +106,6 @@ const deleteUploadList = (index: number, url: string) => {
// 修改时间码
const uploadTimeCode = (ppt_id: string, name: string, url: string) => {
console.log(id)
ElMessageBox.prompt('请输入时间码', '提示', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
......@@ -149,7 +148,7 @@ const deleteCourseware = (ppt_id: string) => {
<template>
<el-dialog v-model="dialogFormVisible">
<Upload v-model="covers"></Upload>
<UploadImg v-model="covers"></UploadImg>
<AppList v-bind="uploadList">
<template #table-cover="{ row }">
<img :src="row.url" style="width:100px;display: block;">
......@@ -171,7 +170,7 @@ const deleteCourseware = (ppt_id: string) => {
</template>
</el-dialog>
<AppCard title="编辑视频资源">
<TopInfo :data="videoDetails"></TopInfo>
<ViewTop :data="videoDetails"></ViewTop>
</AppCard>
<AppCard>
<el-button @click="dialogFormVisible = true" type="primary">关联课件</el-button>
......
<script setup lang="ts">
import { getVideoList } from '../api'
import CardListItem from '../components/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
import { Expand } from '@element-plus/icons-vue'
import { useGetCategoryList } from '@/composables/useGetCategoryList'
import { useProjectList } from '@/composables/useGetProjectList'
import { useMapStore } from '@/stores/map'
const store = useMapStore()
// 筛选项目列表
let { list: projectList } = useProjectList()
// 筛选下拉选择tree 视频分类
let { list: selectTree } = useGetCategoryList()
const defaultProps = {
children: 'children',
label: 'category_name',
value: 'id'
}
// 资源出处 tab触发
const tabValue = ref('1')
......@@ -23,21 +33,14 @@ const listOptions = $computed(() => {
return {
remote: {
httpRequest: getVideoList,
params: { tab: tabValue, title: '', status: '', authorized: '', classification: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
}
params: { tab: tabValue, status: '', authorized: '' }
},
filters: [
{
type: 'select',
prop: 'status',
label: '状态',
options: [
{ label: '有效', value: '1' },
{ label: '失效', value: '0' }
]
options: store.getMapValuesByKey('system_status')
},
{
type: 'select',
......@@ -47,8 +50,7 @@ const listOptions = $computed(() => {
labelKey: 'name',
valueKey: 'id'
},
{ prop: 'classification', label: '类别', slots: 'filter-type' },
{ prop: 'title', slots: 'filter-search' }
{ prop: 'classification', label: '类别', slots: 'filter-type' }
],
columns: [
{ label: '视频标题', prop: 'name', align: 'center' },
......@@ -64,14 +66,6 @@ const listOptions = $computed(() => {
]
}
})
// 下拉选择tree 视频分类
let { list: selectTree } = useGetCategoryList()
const defaultProps = {
children: 'children',
label: 'category_name',
value: 'id'
}
</script>
<template>
......@@ -97,9 +91,6 @@ const defaultProps = {
<template #filter-type="{ params }">
<el-tree-select :props="defaultProps" v-model="params.classification" :data="selectTree" />
</template>
<template #filter-search="{ params }">
<el-input v-model="params.title" placeholder="搜索" :prefix-icon="Search" />
</template>
<template #table-operate="{ row }">
<el-space>
<router-link :to="`/resource/video/update?id=${row.id}`">
......
......@@ -2,14 +2,29 @@
import { PictureFilled, ArrowLeftBold, ArrowRightBold } from '@element-plus/icons-vue'
import type { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import Upload from '../components/Upload.vue'
import UploadImg from '../components/UploadImg.vue'
import Operation from '../components/Operation.vue'
import UploadAuth from '@/components/base/UploadAuth.vue'
import UploadVideo from '../components/UploadVideo.vue'
import { getCoverList, createVideo, getVideoDetails, updateVideo } from '../api'
import { useGetCategoryList } from '@/composables/useGetCategoryList'
// 路由
const router = useRouter()
const route = useRoute()
const id = route.query.id as string
// is 编辑 新建
const isUpdate = $computed(() => {
return !!route.query.id
})
// 编辑数据回显
if (isUpdate) {
getVideoDetails({ id: id }).then((res: any) => {
form.data = res.data
})
}
// 下拉选择tree 视频分类
let { list: selectTree } = useGetCategoryList()
......@@ -45,12 +60,13 @@ const swiperChange = (type?: string) => {
type === 'prev' ? swiper.value.prev() : swiper.value.next()
}
const swiperItemHandle = (url: string) => {
form.cover = url
console.log(url)
form.data.cover = url
}
// form表单 提交
const form = reactive({ name: '', source: '2', classification: '', knowledge_points: '', cover: '', source_id: '' })
// form表单
let form = reactive({
data: { name: '', source: '2', classification: '', knowledge_points: '', cover: '', source_id: '' }
})
// 表单验证
const rules = {
name: [{ required: true, message: '请输入标题', trigger: 'blur' }],
......@@ -60,159 +76,92 @@ const rules = {
const ruleFormRef = ref<FormInstance>()
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
await formEl.validate(valid => {
if (valid) {
if (!protocol.value) {
ElMessage('请勾选用户协议')
return
}
const id = router.currentRoute.value.query.id as string
if (id !== '' && id) {
const params = Object.assign({ id: id }, form)
updateVideo(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '更新成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/video'
})
}, 1000)
}
})
if (isUpdate) {
updateResources()
} else {
createVideo(form).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '创建成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/video'
})
}, 1000)
}
})
createResources()
}
} else {
ElMessage('请完善信息')
console.log('error submit!', fields)
}
})
}
// 协议勾选
const protocol = ref(false)
// 上传视频过程返回值
const videoUpload = reactive({ code: -1, msg: '', progress: 0, fileName: '' })
// 上传视频回调
const uploadProgress = (res: any) => {
videoUpload.progress = res
}
const upload = (res: any) => {
const { code, msg, name, videoId } = res
videoUpload.code = code
videoUpload.msg = msg
videoUpload.fileName = name
videoUpload.progress = 0
form.source_id = videoId
// 更新
const updateResources = () => {
const params = Object.assign({ id: id }, form.data)
updateVideo(params).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '更新成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/video'
})
}, 1000)
}
})
}
// 判断编辑还是新建
const id = router.currentRoute.value.query.id as string
const statusData = reactive<{
department_public: string
platform_public: string
status: string
organ_id_name: string
organ_id: string
created_operator_name: string
belong_operator_name: string
created_time: string
updated_time: string
}>({
department_public: '0',
platform_public: '0',
status: '0',
organ_id_name: '',
organ_id: '',
created_operator_name: '',
belong_operator_name: '',
created_time: '',
updated_time: ''
})
if (id !== '' && id) {
getVideoDetails({ id: id }).then(res => {
const key = ['name', 'classification', 'knowledge_points', 'cover', 'source_id']
key.forEach(item => {
form[item] = res.data[item]
})
const {
department_public,
platform_public,
status,
organ_id_name,
organ_id,
created_operator_name,
belong_operator_name,
created_time,
updated_time
} = res.data
statusData.department_public = department_public
statusData.platform_public = platform_public
statusData.status = status
statusData.organ_id_name = organ_id_name
statusData.organ_id = organ_id
statusData.created_operator_name = created_operator_name
statusData.belong_operator_name = belong_operator_name
statusData.created_time = created_time
statusData.updated_time = updated_time
// 新建
const createResources = () => {
createVideo(form.data).then((res: any) => {
if (res.code === 0) {
ElMessage({ message: '创建成功', type: 'success' })
setTimeout(() => {
router.push({
path: '/resource/video'
})
}, 1000)
}
})
}
// 协议勾选
const protocol = ref(false)
// 上传视频成功
const uploadVideo = (id: string) => {
form.data.source_id = id
}
</script>
<template>
<AppCard title="新建视频资源">
<Operation :data="statusData" style="margin-bottom: 20px"></Operation>
<el-form ref="ruleFormRef" :model="form" :rules="rules" style="width: 70%">
<el-form-item label="视频文件:" prop="source_id" v-if="id == '' || id == undefined">
<div>
<div class="upload-video">
<div class="upload-btn">
本地文件
<UploadAuth @progress="uploadProgress" @upload="upload"></UploadAuth>
</div>
<div class="demo-progress" v-if="videoUpload.code === 1">
<el-progress :percentage="videoUpload.progress" status="success" />
</div>
<div class="error video-info" v-if="videoUpload.code === 2">
<div class="name">上传失败</div>
</div>
<div class="video-info" v-if="videoUpload.code === 0">
<div class="name">{{ videoUpload.fileName }}</div>
<!-- <div class="view">查阅</div> -->
</div>
</div>
<div class="tips">
推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。
</div>
</div>
<Operation :data="form.data"></Operation>
<el-form ref="ruleFormRef" :model="form.data" :rules="rules" style="width: 70%">
<el-form-item label="视频文件:" prop="source_id" v-if="!isUpdate">
<UploadVideo @upload="uploadVideo"></UploadVideo>
</el-form-item>
<el-form-item label="视频名称:" prop="name">
<el-input v-model="form.name" />
<el-input v-model="form.data.name" />
</el-form-item>
<el-form-item label="视频分类:" prop="classification">
<el-tree-select :props="defaultProps" style="width: 100%" v-model="form.classification" :data="selectTree" />
<el-tree-select
:props="defaultProps"
style="width: 100%"
v-model="form.data.classification"
:data="selectTree"
/>
</el-form-item>
<el-form-item label="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;知识点:">
<el-input v-model="form.knowledge_points" :rows="2" type="textarea" />
<el-input v-model="form.data.knowledge_points" :rows="2" type="textarea" />
</el-form-item>
<el-form-item label="&nbsp;&nbsp;视频封面:">
<div class="video-cover">
<div class="img-box">
<el-icon :size="50" color="#ccc" v-if="form.cover == ''">
<el-icon :size="50" color="#ccc" v-if="form.data.cover == ''">
<PictureFilled></PictureFilled>
</el-icon>
<img :src="form.cover" v-else />
<img :src="form.data.cover" v-else />
</div>
<div class="video-cover_right">
<Upload v-model="form.cover"></Upload>
<UploadImg v-model="form.data.cover"></UploadImg>
<div class="list">
<div class="item">
<img
......@@ -276,12 +225,6 @@ if (id !== '' && id) {
</AppCard>
</template>
<style lang="scss" scoped>
.tips {
font-size: 12px;
line-height: 100%;
color: #999999;
margin-top: 8px;
}
.tool-btn-box {
display: flex;
justify-content: right;
......@@ -406,35 +349,4 @@ if (id !== '' && id) {
cursor: pointer;
}
}
.upload-video {
display: flex;
align-items: center;
.upload-btn {
position: relative;
width: 94px;
line-height: 36px;
background: rgba(250, 223, 230, 0.39);
border: 1px solid #aa1941;
border-radius: 20px;
font-size: 14px;
color: #aa1941;
margin-right: 30px;
text-align: center;
}
.video-info {
display: flex;
.name {
color: #333333;
font-size: 16px;
line-height: 100%;
}
.view {
font-size: 16px;
line-height: 100%;
color: #399ee8;
margin-left: 20px;
cursor: pointer;
}
}
}
</style>
<!-- <script setup lang="ts">
import { ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus'
import { createVideo, updateVideo, getVideo } from '../api'
const props = defineProps<{ id?: string }>()
const router = useRouter()
const formRef = ref<FormInstance>()
const form = reactive({ course_name: '', type: '', cover_page: '', aliyun_video_id: '', weight: '' })
const rules = {
course_name: [{ required: true, message: '请输入标题', trigger: 'blur' }],
type: [{ required: true, message: '请选择类型', trigger: 'change' }],
cover_page: [{ required: true, message: '请上传视频封面图片', trigger: 'change' }],
aliyun_video_id: [{ required: true, message: '请输入阿里云播放视频ID', trigger: 'blur' }]
}
const typeList = [
{ label: '入学指南', value: '1' },
{ label: '学习地图', value: '2' },
{ label: '考试攻略', value: '3' }
]
// 提交
const onSubmit = () => {
if (!formRef.value) return
formRef.value.validate().then(() => {
props.id ? update() : create()
})
}
// 取消
const onCancel = () => {
router.replace('/video')
}
// 创建
const create = () => {
createVideo(form).then(() => {
ElMessage({ message: '创建成功', type: 'success' })
router.push('/video')
})
}
// 修改
const update = () => {
const params = { ...form, id: props.id as string }
updateVideo(params).then(() => {
ElMessage({ message: '修改成功', type: 'success' })
router.push('/video')
})
}
onMounted(() => {
props.id &&
getVideo({ id: props.id }).then(res => {
Object.assign(form, res.data)
})
})
</script>
<template>
<AppCard>
<el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
<el-form-item label="标题" prop="course_name">
<el-input v-model="form.course_name" />
</el-form-item>
<el-form-item label="类型" prop="type">
<el-select v-model="form.type">
<el-option v-for="item in typeList" :label="item.label" :value="item.value" :key="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="权重" prop="weight">
<el-input type="number" v-model="form.weight" controls-position="right" />
</el-form-item>
<el-form-item label="视频封面" prop="cover_page">
<AppUpload v-model="form.cover_page"></AppUpload>
</el-form-item>
<el-form-item label="阿里云播放视频ID" prop="aliyun_video_id">
<el-input v-model="form.aliyun_video_id" />
</el-form-item>
<el-form-item>
<el-button type="primary" auto-insert-space @click="onSubmit">保存</el-button>
<el-button auto-insert-space @click="onCancel">取消</el-button>
</el-form-item>
</el-form>
</AppCard>
</template> -->
<script setup lang="ts">
import TopInfo from '../components/TopInfo.vue'
import CenterInfo from '../components/CenterInfo.vue'
import BottomInfo from '../components/BottomInfo.vue'
import ViewTop from '../components/ViewTop.vue'
import ViewCenter from '../components/ViewCenter.vue'
import ViewBottom from '../components/ViewBottom.vue'
import Operation from '../components/Operation.vue'
// api
import { getVideoDetails } from '../api'
// 路由
const router = useRouter()
const route = useRoute()
const id = route.query.id as string
const listOptions = {
columns: [
......@@ -28,9 +28,8 @@ const listOptions = {
]
}
const id = router.currentRoute.value.query.id as string
// 获取详情
let videoDetails:any = ref({})
let videoDetails: any = ref({})
getVideoDetails({ id: id }).then(res => {
videoDetails.value = res.data
})
......@@ -38,30 +37,17 @@ getVideoDetails({ id: id }).then(res => {
<template>
<AppCard title="视频资源信息">
<Operation :data="videoDetails" style="margin-bottom: 20px;"></Operation>
<!-- <div class="btn-box">
<div class="btn-item">编辑视频信息</div>
<div class="btn-item">编辑视频课件</div>
<div class="btn-item">部门共享</div>
<div class="btn-item">平台共享</div>
<div class="btn-item">资源下线</div>
<div class="btn-item">更改负责人</div>
</div> -->
<TopInfo :data="videoDetails"></TopInfo>
<CenterInfo v-if="Object.keys(videoDetails).length" :data="videoDetails"></CenterInfo>
<BottomInfo></BottomInfo>
<Operation :data="videoDetails"></Operation>
<ViewTop :data="videoDetails"></ViewTop>
<ViewCenter v-if="Object.keys(videoDetails).length" :data="videoDetails"></ViewCenter>
<ViewBottom></ViewBottom>
</AppCard>
<AppCard title="视频资源信息">
<AppList v-bind="listOptions" ref="appList" stripe>
<template #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<el-button
style="color: #399EE8;"
type="primary"
link
>查看</el-button
>
<el-button style="color: #399ee8" type="primary" link>查看</el-button>
</router-link>
</el-space>
</template>
......@@ -69,17 +55,17 @@ getVideoDetails({ id: id }).then(res => {
</AppCard>
</template>
<style lang="scss" scoped>
.btn-box{
.btn-box {
display: flex;
justify-content: right;
.btn-item{
.btn-item {
width: 127px;
line-height: 36px;
background: #AA1941;
background: #aa1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
color: #ffffff;
text-align: center;
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论