提交 f00e730f authored 作者: lihuihui's avatar lihuihui

On master: 暂存

{
"globals": {
"$": true,
"$$": true,
"$computed": true,
"$customRef": true,
"$ref": true,
"$shallowRef": true,
"$toRef": true,
"EffectScope": true,
"asyncComputed": true,
"autoResetRef": true,
"computed": true,
"computedAsync": true,
"computedEager": true,
"computedInject": true,
"computedWithControl": true,
"controlledComputed": true,
"controlledRef": true,
"createApp": true,
"createEventHook": true,
"createGlobalState": true,
"createInjectionState": true,
"createReactiveFn": true,
"createSharedComposable": true,
"createUnrefFn": true,
"customRef": true,
"debouncedRef": true,
"debouncedWatch": true,
"defineAsyncComponent": true,
"defineComponent": true,
"eagerComputed": true,
"effectScope": true,
"extendRef": true,
"getCurrentInstance": true,
"getCurrentScope": true,
"h": true,
"ignorableWatch": true,
"inject": true,
"isDefined": true,
"isReadonly": true,
"isRef": true,
"logicAnd": true,
"logicNot": true,
"logicOr": true,
"makeDestructurable": true,
"markRaw": true,
"nextTick": true,
"onActivated": true,
"onBeforeMount": true,
"onBeforeUnmount": true,
"onBeforeUpdate": true,
"onClickOutside": true,
"onDeactivated": true,
"onErrorCaptured": true,
"onKeyStroke": true,
"onLongPress": true,
"onMounted": true,
"onRenderTracked": true,
"onRenderTriggered": true,
"onScopeDispose": true,
"onServerPrefetch": true,
"onStartTyping": true,
"onUnmounted": true,
"onUpdated": true,
"pausableWatch": true,
"provide": true,
"reactify": true,
"reactifyObject": true,
"reactive": true,
"reactiveComputed": true,
"reactiveOmit": true,
"reactivePick": true,
"readonly": true,
"ref": true,
"refAutoReset": true,
"refDebounced": true,
"refDefault": true,
"refThrottled": true,
"refWithControl": true,
"resolveComponent": true,
"shallowReactive": true,
"shallowReadonly": true,
"shallowRef": true,
"syncRef": true,
"syncRefs": true,
"templateRef": true,
"throttledRef": true,
"throttledWatch": true,
"toRaw": true,
"toReactive": true,
"toRef": true,
"toRefs": true,
"triggerRef": true,
"tryOnBeforeMount": true,
"tryOnBeforeUnmount": true,
"tryOnMounted": true,
"tryOnScopeDispose": true,
"tryOnUnmounted": true,
"unref": true,
"unrefElement": true,
"until": true,
"useActiveElement": true,
"useAsyncQueue": true,
"useAsyncState": true,
"useAttrs": true,
"useBase64": true,
"useBattery": true,
"useBreakpoints": true,
"useBroadcastChannel": true,
"useBrowserLocation": true,
"useCached": true,
"useClamp": true,
"useClipboard": true,
"useColorMode": true,
"useConfirmDialog": true,
"useCounter": true,
"useCssModule": true,
"useCssVar": true,
"useCssVars": true,
"useCurrentElement": true,
"useCycleList": true,
"useDark": true,
"useDateFormat": true,
"useDebounce": true,
"useDebounceFn": true,
"useDebouncedRefHistory": true,
"useDeviceMotion": true,
"useDeviceOrientation": true,
"useDevicePixelRatio": true,
"useDevicesList": true,
"useDisplayMedia": true,
"useDocumentVisibility": true,
"useDraggable": true,
"useElementBounding": true,
"useElementByPoint": true,
"useElementHover": true,
"useElementSize": true,
"useElementVisibility": true,
"useEventBus": true,
"useEventListener": true,
"useEventSource": true,
"useEyeDropper": true,
"useFavicon": true,
"useFetch": true,
"useFileSystemAccess": true,
"useFocus": true,
"useFocusWithin": true,
"useFps": true,
"useFullscreen": true,
"useGamepad": true,
"useGeolocation": true,
"useIdle": true,
"useInfiniteScroll": true,
"useIntersectionObserver": true,
"useInterval": true,
"useIntervalFn": true,
"useKeyModifier": true,
"useLastChanged": true,
"useLocalStorage": true,
"useMagicKeys": true,
"useManualRefHistory": true,
"useMediaControls": true,
"useMediaQuery": true,
"useMemoize": true,
"useMemory": true,
"useMounted": true,
"useMouse": true,
"useMouseInElement": true,
"useMousePressed": true,
"useMutationObserver": true,
"useNavigatorLanguage": true,
"useNetwork": true,
"useNow": true,
"useOffsetPagination": true,
"useOnline": true,
"usePageLeave": true,
"useParallax": true,
"usePermission": true,
"usePointer": true,
"usePointerSwipe": true,
"usePreferredColorScheme": true,
"usePreferredDark": true,
"usePreferredLanguages": true,
"useRafFn": true,
"useRefHistory": true,
"useResizeObserver": true,
"useRoute": true,
"useRouter": true,
"useScreenOrientation": true,
"useScreenSafeArea": true,
"useScriptTag": true,
"useScroll": true,
"useScrollLock": true,
"useSessionStorage": true,
"useShare": true,
"useSlots": true,
"useSpeechRecognition": true,
"useSpeechSynthesis": true,
"useStorage": true,
"useStorageAsync": true,
"useStyleTag": true,
"useSwipe": true,
"useTemplateRefsList": true,
"useTextSelection": true,
"useThrottle": true,
"useThrottleFn": true,
"useThrottledRefHistory": true,
"useTimeAgo": true,
"useTimeout": true,
"useTimeoutFn": true,
"useTimeoutPoll": true,
"useTimestamp": true,
"useTitle": true,
"useToggle": true,
"useTransition": true,
"useUrlSearchParams": true,
"useUserMedia": true,
"useVModel": true,
"useVModels": true,
"useVibrate": true,
"useVirtualList": true,
"useWakeLock": true,
"useWebNotification": true,
"useWebSocket": true,
"useWebWorker": true,
"useWebWorkerFn": true,
"useWindowFocus": true,
"useWindowScroll": true,
"useWindowSize": true,
"watch": true,
"watchAtMost": true,
"watchDebounced": true,
"watchEffect": true,
"watchIgnorable": true,
"watchOnce": true,
"watchPausable": true,
"watchThrottled": true,
"watchWithFilter": true,
"whenever": true
}
}
\ No newline at end of file
差异被折叠。
......@@ -6,6 +6,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>统一资源管理平台</title>
<script src="https://webapp-pub.ezijing.com/plugins/tinymce@6/tinymce.min.js"></script>
<script src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/lib/aliyun-upload-sdk/lib/es6-promise.min.js"></script>
<script src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/lib/aliyun-upload-sdk/lib/aliyun-oss-sdk-6.17.1.min.js"></script>
<script src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.3.min.js"></script>
</head>
<body>
<div id="app"></div>
......
......@@ -34,3 +34,18 @@ export function uploadFile(data: Record<string, any>) {
export function deleteComment(data: { id: string }) {
return httpRequest.post('/api/psp/backend/comment/delete', data)
}
// 上传视频
export function getCreateAuth(data: { title: string, file_name: string }) {
return httpRequest.post('/api/resource/v1/resource/video/create-auth', data)
}
// 刷新上传视频的地址凭证
export function updateAuth(data: { source_id: string }) {
return httpRequest.post('/api/resource/v1/resource/video/create-auth', data)
}
// 获取公共字典列表
export function getMapList() {
return httpRequest.get('/api/resource/v1/util/get-data-dictionary-list')
}
......@@ -93,7 +93,7 @@ const handlePreview: UploadProps['onPreview'] = uploadFile => {
<template v-if="showFileList">
<template v-if="$attrs['list-type'] === 'picture-card'">
<el-icon><Plus /></el-icon>
</template>
</template>
<template v-else>
<el-button type="primary">点击上传</el-button>
</template>
......
<script setup lang="ts">
import { Files } from '@element-plus/icons-vue'
</script>
<template>
<div class="card-item">
<div class="card-item-top">
<!-- <div class="title">基金产品(中)(初级)</div> -->
<!-- <img src="http://iph.href.lu/265x170" /> -->
<div class="title">基金产品(中)(初级)</div>
<div class="item-info">
<div class="info">文件大小:1MB</div>
<div class="info">文件大小:1MB</div>
<div class="info">学习人次:165人次</div>
</div>
<el-icon class="item-info-icon">
<Files />
</el-icon>
<div class="tool-pop-btn">
<div class="edit-btn">编辑</div>
<div class="view-btn">查看</div>
</div>
</div>
<div class="card-item-bottom">
<div class="item-t">
<div class="text">张三丰/紫荆教育</div>
<div class="tag green">失效</div>
</div>
<div class="item-b">
<div class="time">2022-03-21 12:34:21</div>
<div class="tag">新建</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.card-item {
width: 265px;
border-radius: 6px;
overflow: hidden;
margin-right: 20px;
margin-bottom: 20px;
// box-shadow: #666666;
box-shadow: 0 0 10px 0 rgb(0 0 0 / 10%);
background: #fff;
.card-item-top {
background: rgba(204,204,204, .5);
height: 170px;
position: relative;
display: flex;
align-items: center;
&:hover {
.tool-pop-btn {
opacity: 1;
}
}
.item-info{
padding-left: 20px;
.info{
width: 150px;
font-size: 14px;
line-height: 100%;
color: #666666;
margin-bottom: 10px;
}
}
.item-info-icon{
font-size: 50px;
color: #aa1941;
}
img {
width: 100%;
height: 100%;
display: block;
}
.title {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
line-height: 37px;
background: rgba(0, 0, 0, .6);
font-size: 18px;
color: #ffffff;
padding-left: 16px;
box-sizing: border-box;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
.tool-pop-btn {
transition: all .5s;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
opacity: 0;
.edit-btn{
width: 113px;
line-height: 32px;
border: 1px solid #D3D3D3;
border-radius: 18px;
text-align: center;
font-size: 14px;
color: #FFFFFF;
margin: 52px auto 12px;
cursor: pointer;
}
.view-btn{
width: 113px;
line-height: 32px;
background: #AA1941;
border-radius: 18px;
text-align: center;
font-size: 14px;
color: #FFFFFF;
margin: 0 auto;
cursor: pointer;
}
}
}
}
.card-item-bottom{
background: #fff;
padding: 20px 16px 30px;
.item-t{
display: flex;
align-items: center;
justify-content: space-between;
.text{
width: 150px;
font-size: 16px;
line-height: 100%;
color: #666666;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
.tag{
width: 48px;
line-height: 22px;
background: #AA1941;
border-radius: 11px;
font-size: 14px;
color: #fff;
text-align: center;
&.green{
background: #1AB226;
}
}
}
.item-b{
margin-top: 18px;
display: flex;
align-items: center;
justify-content: space-between;
.time{
font-size: 14px;
line-height: 100%;
color: #999999;
}
.tag{
font-size: 16px;
line-height: 100%;
color: #999999;
}
}
}
</style>
\ No newline at end of file
<script setup lang="ts">
import { getCreateAuth, updateAuth } from '@/api/base'
/**
* upload 上传状态 {code: 0(成功) 1(开始上传) 2(上传失败), msg: '上传信息'}
* progress 上传进度
**/
const emit = defineEmits(['upload', 'progress'])
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)
})
}
}
const res = {
code: 1,
name: uploadInfo.file.name,
msg: '开始上传'
}
emit('upload', res)
},
// 文件上传成功
onUploadSucceed: function (uploadInfo:any) {
// console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
const fileData = window.localStorage.fileData ? JSON.parse(window.localStorage.fileData) : {}
const res = {
code: 0,
name: uploadInfo.file.name,
videoId: fileData.videoId,
msg: '上传成功'
}
emit('upload', res)
},
// 文件上传失败
onUploadFailed: function (uploadInfo:any, code:any, message:any) {
console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message)
const res = {
code: 2,
name: uploadInfo.file.name,
msg: '文件上传失败'
}
emit('upload', res)
},
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress: function (uploadInfo:any, totalSize:any, progress:any) {
let progressPercent = Math.ceil(progress * 100)
form.authProgress = progressPercent
emit('progress', form.authProgress)
},
// 上传凭证超时
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>
<input type="file" id="fileUpload" @change="fileChange($event)">
</template>
<style lang="scss" scoped>
#fileUpload{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.00001;
}
</style>
\ No newline at end of file
import httpRequest from '@/utils/axios'
// 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params })
}
// 创建视频
export function createVideo(data: { course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/create', data)
}
// 更新视频
export function updateVideo(data: { id: string; course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/update', data)
}
// 获取视频详情
export function getVideo(params: { id: string }) {
return httpRequest.get('/api/psp/backend/video/view', { params })
}
<script setup lang="ts">
import * as echarts from "echarts"
const echartsRef = ref()
onMounted(() => {
const myEcharts = echarts.init(echartsRef.value)
const option = {
grid: {
bottom: 30,
left: 30,
right: 30
},
xAxis: {
data: ['2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21'],
axisTick: {
show: false
}
},
color: ['#BF9D6B'],
yAxis: {},
series: [
{
type: 'bar',
barWidth: '18',
data: [5, 20, 36, 10, 10, 20]
}
],
}
//设置配置
myEcharts.setOption(option)
})
const listOptions = {
columns: [
{ label: '访问时间', prop: 'name', align: 'center' },
{ label: '姓名', prop: 'bumen', align: 'center' },
{ label: '所在项目', prop: 'update', align: 'center' },
{ label: '访问时长', prop: 'time', align: 'center' }
],
data: [
{ time: '111', id: 1, name: '宏观经济学.pptx', type: '1', index: '1', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 2, name: '宏观经济学.pptx', type: '2', index: '2', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 3, name: '宏观经济学.pptx', type: '3', index: '3', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 4, name: '宏观经济学.pptx', type: '4', index: '4', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
]
}
</script>
<template>
<div class="data-box">
<div class="echart">
<div class="name">访问量/关联量一周走势图</div>
<div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div>
</div>
<div class="label-box">
<div class="name">最近访问</div>
<AppList v-bind="listOptions" ref="appList" stripe></AppList>
</div>
</div>
<!-- <div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div> -->
</template>
<style lang="scss" scoped>
.data-box{
display: flex;
.echart{
flex: 1;
height: 369px;
box-sizing: border-box;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-right: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
.label-box{
box-sizing: border-box;
flex: 1;
height: 369px;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-left: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
}
</style>
<script setup lang="ts">
</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>
<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>
</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>
</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>
</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>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.center-video-box{
padding: 20px 0;
display: flex;
.right-statistics{
flex: 1;
padding-top: 15px;
.stat-item{
width: 210px;
height: 85px;
background: #B41E47;
border-radius: 6px;
display: flex;
align-items: center;
margin: 0 auto 20px;
&:nth-child(even){
background: #BF9D6B;
}
img{
width: 52px;
height: 52px;
display: block;
margin-left: 18px;
}
.content{
margin-left: 18px;
.unit{
font-size: 26px;
line-height: 100%;
color: #FFFFFF;
span{
font-size: 12px;
line-height: 100%;
}
}
.tag{
font-size: 14px;
line-height: 100%;
color: #FFFFFF;
margin-top: 10px;
}
}
}
}
}
</style>
<script setup lang="ts">
import { Files } from '@element-plus/icons-vue'
</script>
<template>
<div class="video-info">
<div class="video-img">
<el-icon class="item-info-icon">
<Files />
</el-icon>
<!-- <img src="https://iph.href.lu/211x146"> -->
</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">
<div class="text-box">
<div class="name">状态</div>
<div class="value active">有效</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">
<div class="text-box">
<div class="name">创建者</div>
<div class="value">张三丰</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">
<div class="text-box">
<div class="name">创建时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">更新时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">课件名称</div>
<div class="value">基金产品(中)(初级)</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">
<div class="text-box">
<div class="name">课件分类</div>
<div class="value">金融产品数字化营销-黄老师</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">
<div class="text-box">
<div class="name">知识点</div>
<div class="textarea-box">
某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.video-info{
background: #F7F7F7;
margin-top: 20px;
padding: 20px;
display: flex;
.video-img{
// width: 211px;
padding: 0 30px;
.item-info-icon{
font-size: 100px;
color: #aa1941;
}
.name{
font-size: 16px;
line-height: 100%;
color: #666666;
margin-top: 12px;
text-align: center;
}
}
.info-items{
display: flex;
flex-wrap: wrap;
padding-left: 12px;
.i-items{
display: flex;
align-items: center;
height: fit-content;
margin-right: 80px;
margin-bottom: 30px;
.textarea-box{
padding: 18px 18px 51px;
background: #FFFFFF;
border-radius: 4px;
font-size: 16px;
line-height: 24px;
color: #505050;
margin-top: 14px;
}
.text-box{
margin-left: 16px;
.name{
font-size: 14px;
line-height: 100%;
color: #999999;
}
.value{
font-size: 16px;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-top: 8px;
&.active{
color: #1AB226;
}
}
}
}
}
}
</style>
import type { RouteRecordRaw } from 'vue-router'
import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/resource/courseware',
component: AppLayout,
children: [
{ path: '', component: () => import('./views/List.vue') },
{ path: 'update', component: () => import('./views/Update.vue') },
{ path: 'view', component: () => import('./views/View.vue') }
// { path: 'update/:id', component: () => import('./views/Update.vue'), props: true }
]
}
]
<script setup lang="ts">
// import { getVideoList } from '../api'
import CardListItem from '@/components/base/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
const appList = ref()
const isCard = ref(true)
const listOptions = {
remote: {
// httpRequest: getVideoList,
params: { type: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
}
},
filters: [
{ type: 'select', prop: 'type', label: '状态' },
{ type: 'select', prop: 'project_id', label: '项目' },
{ type: 'select', prop: 'category_id', label: '类别' },
{ prop: 'search', slots: 'filter-search' }
// { type: 'input', prop: 'category_id', prefixIcon: 'Search' }
],
columns: [
{ label: '视频标题', prop: 'title' },
{ label: '视频分类', prop: 'type' },
{ label: '知识点', prop: 'zsd' },
{ label: '封面', slots: 'table-cover', width: 100 },
{ label: '资源状态', prop: 'state' },
{ label: '审核状态', prop: 'state2' },
{ label: '更新人', prop: 'update' },
{ label: '更新人部门', prop: 'updatebm' },
{ label: '更新日期', prop: 'update_time' },
{ label: '操作', slots: 'table-operate', align: 'right' }
],
data: [
{ id: 1, title: '视频标题', type: '视频分类' },
{ id: 2, title: '视频标题', type: '视频分类' }
]
}
</script>
<template>
<AppCard>
<!-- <el-switch v-model="isCard"></el-switch> -->
<div class="video-head">
<el-tabs>
<el-tab-pane label="我的资源"></el-tab-pane>
<el-tab-pane label="部门资源"></el-tab-pane>
<el-tab-pane label="公开资源"></el-tab-pane>
</el-tabs>
<el-icon class="video-head-icon" @click="isCard = !isCard"><Expand /></el-icon>
</div>
<div class="video-tool-btn">
<router-link to="/resource/courseware/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 #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<el-button plain>编辑</el-button>
</router-link>
<router-link :to="`/video/view/${row.id}`">
<el-button type="primary" plain>查看</el-button>
</router-link>
</el-space>
</template>
<!-- 卡片 -->
<template #body="{ data }" v-if="isCard">
<div class="card-list">
<CardListItem v-for="(item, index) in data" :data="item" :key="index"></CardListItem>
</div>
<!-- <div class="resource-video-item" v-for="item in data" :key="item.id">{{ item.title }}</div> -->
</template>
</AppList>
</AppCard>
</template>
<style lang="scss">
.card-list{
background: #FAFAFA;
padding: 20px;
display: flex;
}
.video-head {
position: relative;
.video-head-icon {
position: absolute;
top: 0;
right: 0;
font-size: 30px;
color: #666;
cursor: pointer;
}
}
.video-tool-btn {
padding: 10px 0 30px 0;
}
</style>
<script setup lang="ts">
import UploadAuth from '@/components/base/UploadAuth.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
}
</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">
<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">课件支持格式包含:doc docx xls xlsx pdf ppt pptx,大小不超过50M</div>
</div>
</el-form-item>
<el-form-item label="课件名称:" prop="course_name">
<el-input v-model="form.videoName" />
</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>
<el-form-item label="&nbsp;&nbsp;&nbsp;知识点:" prop="course_name">
<el-input
v-model="form.zsd"
:rows="2"
type="textarea"
/>
</el-form-item>
</el-form>
<div class="protocol-box">
<el-checkbox v-model="protocol" size="large">
我已阅读并同意<span>《紫荆教育用户入驻及网络教学资源协议》</span>
</el-checkbox>
</div>
<div class="btn-box">
<div class="confirm">保存</div>
<div class="cancel">取消</div>
</div>
</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;
.btn-item{
width: 127px;
line-height: 36px;
background: #AA1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
text-align: center;
}
}
.demo-progress{
width: 350px;
}
.video-cover{
display: flex;
.img-box{
width: 208px;
height: 130px;
border-radius: 4px;
background: #F7F7F7;
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
img{
width: 100%;
height: 100%;
display: block;
}
}
.video-cover_right{
margin-left: 20px;
.list{
.item{
display: flex;
align-items: center;
margin-top: 12px;
img{
width: 9px;
display: block;
margin-right: 5px;
}
.text{
font-size: 12px;
color: #999999;
line-height: 100%;
}
}
}
}
}
.swiper-box{
min-width: 660px;
margin-top: 20px;
padding: 0 40px;
position: relative;
.arrow{
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 30px;
color: #D5D5D5;
cursor: pointer;
&.left{
left: 0;
}
&.right{
right: 10px;
}
}
.cover-list{
display: flex;
flex-wrap: wrap;
.cover-list_item{
display: block;
width: 155px;
height: 96px;
margin: 0 10px 10px 0;
border-radius: 4px;
cursor: pointer;
}
}
}
:deep(.el-carousel__indicators--horizontal){
display: none;
}
.protocol-box{
font-size: 14px;
line-height: 24px;
padding-left: 90px;
padding-top: 20px;
color: #666666;
span{
color: #AA1941;
}
}
.btn-box{
display: flex;
margin-top: 20px;
margin-left: 90px;
.confirm{
width: 94px;
background: #AA1941;
border-radius: 20px;
text-align: center;
line-height: 36px;
color: #fff;
margin-right: 26px;
cursor: pointer;
}
.cancel{
width: 94px;
line-height: 36px;
border: 1px solid #AA1941;
border-radius: 20px;
text-align: center;
color: #AA1941;
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 TopInfo from '../components/view/TopInfo.vue'
import CenterInfo from '../components/view/CenterInfo.vue'
import BottomInfo from '../components/view/BottomInfo.vue'
const listOptions = {
columns: [
{ label: '课程图片', prop: 'img', align: 'center' },
{ label: '课程名称', prop: 'cursor_name', align: 'center' },
{ label: '分类名称', prop: 'type_name', align: 'center' },
{ label: '所在章', slots: 'zhang', align: 'center' },
{ label: '所在小结', prop: 'jie', align: 'center' },
{ label: '创建日期', prop: 'update', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: [
{ img: 1, cursor_name: '宏观经济学.pptx', type_name: '1', zhang: '1', jie: '吉林师范大学', update: '王重阳' },
{ img: 2, cursor_name: '宏观经济学.pptx', type_name: '2', zhang: '2', jie: '吉林师范大学', update: '王重阳' },
{ img: 3, cursor_name: '宏观经济学.pptx', type_name: '3', zhang: '3', jie: '吉林师范大学', update: '王重阳' },
{ img: 4, cursor_name: '宏观经济学.pptx', type_name: '4', zhang: '4', jie: '吉林师范大学', update: '王重阳' },
{ img: 5, cursor_name: '宏观经济学.pptx', type_name: '5', zhang: '5', jie: '吉林师范大学', update: '王重阳' }
]
}
</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>
<TopInfo></TopInfo>
<CenterInfo></CenterInfo>
<BottomInfo></BottomInfo>
</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
>
</router-link>
</el-space>
</template>
</AppList>
</AppCard>
</template>
<style lang="scss" scoped>
.btn-box{
display: flex;
justify-content: right;
.btn-item{
width: 127px;
line-height: 36px;
background: #AA1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
text-align: center;
}
}
</style>
import httpRequest from '@/utils/axios'
// 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params })
// 获取资源统计信息
export function getUtilData() {
return httpRequest.get('/api/resource/v1/util/index')
}
<script setup lang="ts"></script>
<script setup lang="ts">
const prop = defineProps(['data'])
const listOptions = {
columns: [
{ label: '排名', slots: 'table-ranking', align: 'center' },
{ label: '关联使用', slots: 'table-relation', align: 'center' },
{ label: '资源名称', prop: 'name', align: 'center' },
{ label: '资源类型', slots: 'table-type', align: 'center' },
{ label: '所在部门', prop: 'project_id_name', align: 'center' },
{ label: '更新人', prop: 'created_operator_name', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: prop.data
}
</script>
<template>
<div></div>
<AppList v-bind="listOptions" ref="appList" border stripe>
<template #table-ranking="{ row }">
<div :class="`table-ranking active${row.index}`">{{ row.index <= 3 ? '' : row.index }}</div>
</template>
<template #table-relation="{ row }">
<div :class="`table-relation active${row.index}`">{{ row.relation }}<span></span></div>
</template>
<template #table-type="{ row }">
<div :class="`table-type active${row.index}`">{{ row.resource_type }}</div>
</template>
<template #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<el-button
style="color: #399EE8;"
type="primary"
link
>查阅</el-button
>
</router-link>
</el-space>
</template>
</AppList>
</template>
<style lang="scss"></style>
\ No newline at end of file
<style lang="scss">
.table-ranking{
font-size: 14px;
color: #666666;
margin: 0 auto;
&.active1{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking1.png);
}
&.active2{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking2.png);
}
&.active3{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking3.png);
}
}
.table-type{
width: 84px;
line-height: 28px;
border-radius: 14px;
text-align: center;
font-size: 14px;
margin: 0 auto;
&.active1{
background: #FAEDF1;
color: #AA1941;
}
&.active2{
background: #F5EBDA;
color: #BA8B45;
}
&.active3{
background:#E9EAF8;
color: #5B61B5;
}
&.active4{
background: #DFEFF2;
color:#47A7B9;
}
&.active5{
background: #FAEEE2;
color: #CE893F;
}
}
.table-relation{
font-size: 14px;
span{
color: #666666;
}
&.active1{
color: #AA1941;
}
&.active2{
color: #BA8B45;
}
&.active3{
color: #5B61B5;
}
&.active4{
color:#47A7B9;
}
&.active5{
color: #CE893F;
}
}
</style>
\ No newline at end of file
<script setup lang="ts"></script>
<script setup lang="ts">
const prop = defineProps(['data'])
const listOptions = {
columns: [
{ label: '排名', slots: 'table-ranking', align: 'center' },
{ label: '资源名称', prop: 'name', align: 'center' },
{ label: '资源类型', slots: 'table-type', align: 'center' },
{ label: '所在部门', prop: 'project_id_name', align: 'center' },
{ label: '更新人', prop: 'created_operator_name', align: 'center' },
{ label: '更新时间', prop: 'updated_time', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: prop.data
}
</script>
<template>
<div></div>
<AppList v-bind="listOptions" ref="appList" border stripe>
<template #table-ranking="{ row }">
<div :class="`table-ranking active${row.index}`">{{ row.index <= 3 ? '' : row.index }}</div>
</template>
<template #table-type="{ row }">
<div :class="`table-type active${row.index}`">{{ row.resource_type }}</div>
</template>
<template #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<el-button
style="color: #399EE8;"
type="primary"
link
>查阅</el-button
>
</router-link>
</el-space>
</template>
</AppList>
</template>
<style lang="scss"></style>
\ No newline at end of file
<style lang="scss">
.table-ranking{
font-size: 14px;
color: #666666;
margin: 0 auto;
&.active1{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking1.png);
}
&.active2{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking2.png);
}
&.active3{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking3.png);
}
}
.table-type{
width: 84px;
line-height: 28px;
border-radius: 14px;
text-align: center;
font-size: 14px;
margin: 0 auto;
&.active1{
background: #FAEDF1;
color: #AA1941;
}
&.active2{
background: #F5EBDA;
color: #BA8B45;
}
&.active3{
background:#E9EAF8;
color: #5B61B5;
}
&.active4{
background: #DFEFF2;
color:#47A7B9;
}
&.active5{
background: #FAEEE2;
color: #CE893F;
}
}
</style>
\ No newline at end of file
<script setup lang="ts"></script>
<script setup lang="ts">
const prop = defineProps(['data'])
const listOptions = {
columns: [
{ label: '排名', slots: 'table-ranking', align: 'center' },
{ label: '资源名称', prop: 'name', align: 'center' },
{ label: '资源类型', slots: 'table-type', align: 'center' },
{ label: '所在部门', prop: 'project_id_name', align: 'center' },
{ label: '更新人', prop: 'created_operator_name', align: 'center' },
{ label: '更新时间', prop: 'updated_time', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: prop.data
}
</script>
<template>
<div></div>
<AppList v-bind="listOptions" ref="appList" border stripe>
<template #table-ranking="{ row }">
<div :class="`table-ranking active${row.index}`">{{ row.index <= 3 ? '' : row.index }}</div>
</template>
<template #table-type="{ row }">
<div :class="`table-type active${row.index}`">{{ row.resource_type }}</div>
</template>
<template #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<el-button
style="color: #399EE8;"
type="primary"
link
>查阅</el-button
>
</router-link>
</el-space>
</template>
</AppList>
</template>
<style lang="scss"></style>
\ No newline at end of file
<style lang="scss">
.table-ranking{
font-size: 14px;
color: #666666;
margin: 0 auto;
&.active1{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking1.png);
}
&.active2{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking2.png);
}
&.active3{
width: 20px;
height: 26px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-ranking3.png);
}
}
.table-type{
width: 84px;
line-height: 28px;
border-radius: 14px;
text-align: center;
font-size: 14px;
margin: 0 auto;
&.active1{
background: #FAEDF1;
color: #AA1941;
}
&.active2{
background: #F5EBDA;
color: #BA8B45;
}
&.active3{
background:#E9EAF8;
color: #5B61B5;
}
&.active4{
background: #DFEFF2;
color:#47A7B9;
}
&.active5{
background: #FAEEE2;
color: #CE893F;
}
}
</style>
\ No newline at end of file
<script setup lang="ts"></script>
<script setup lang="ts">
const prop = defineProps(['data'])
</script>
<template>
<div class="statistics-list">
<div class="item"></div>
<div class="item" v-for="(item, index) in prop.data" :key="index">
<div class="icon"></div>
<div class="num">{{ item.number }}<span>{{ item.unit }}</span></div>
<div class="text">{{ item.text }}</div>
</div>
</div>
</template>
<style lang="scss">
.statistics-list{
display: flex;
flex-wrap: wrap;
margin-top: -20px;
.item{
width: 110px;
padding-top: 15px;
min-width: 110px;
height: 140px;
border: 1px solid #E5E5E5;
border-radius: 6px;
box-sizing: border-box;
margin-right: 20px;
margin-top: 20px;
.icon{
width: 40px;
height: 40px;
background-size: 100% 100%;
margin: 0 auto;
&:nth-child(1){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon1.png);
}
&:nth-child(2){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon2.png);
}
&:nth-child(3){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon3.png);
}
&:nth-child(4){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon4.png);
}
&:nth-child(5){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon5.png);
}
&:nth-child(6){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon6.png);
}
&:nth-child(7){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon7.png);
}
&:nth-child(8){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon8.png);
}
&:nth-child(9){
background-image: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/home-icon9.png);
}
}
.num{
font-size: 26px;
line-height: 100%;
color: #BF9D6B;
text-align: center;
padding: 10px;
span{
font-size: 12px;
}
}
.text{
font-size: 14px;
line-height: 100%;
color: #8E8E8E;
text-align: center;
}
}
}
</style>
\ No newline at end of file
......@@ -3,18 +3,64 @@ import Statistics from '../components/Statistics.vue'
import Newest from '../components/Newest.vue'
import Hottest from '../components/Hottest.vue'
import RecentLearning from '../components/RecentLearning.vue'
import { getUtilData } from '../api'
let flag = $ref(false)
const data = reactive<{statistics: object[], latest: object[], hot: object[], learn: object[] }>({
statistics: [],
latest: [],
hot: [],
learn: []
})
// 所有数据
getUtilData().then(res => {
flag = true
let { latest = [], hot = [], learn = [] }: { latest: object[], hot: object[], learn: object[] } = res.data
if (learn === null) learn = []
// 统计资源数据整合
const statisticsData = [
{ key: 'video_count', unit: '个', number: 0, text: '视频资源' },
{ key: 'courseware_count', unit: '个', number: 0, text: '课件资源' },
{ key: 'other_information_count', unit: '个', number: 0, text: '其他资料' },
{ key: 'question_count', unit: '个', number: 0, text: '题库资源' },
{ key: 'paper_count', unit: '套', number: 0, text: '试卷资源' },
{ key: 'memory_size', unit: 'GB', number: 0, text: '资源总体量' },
{ key: 'length', unit: '小时', number: 0, text: '资源总时长' },
{ key: 'learn_times', unit: '万人次', number: 0, text: '总学习人次' },
{ key: 'learn_time_length', unit: '小时', number: 0, text: '总学习时长' }
]
data.statistics = statisticsData.map(item => {
item.number = res.data[item.key] || 0
return item
})
// 最近数据
data.latest = latest.map((item: any, index: number) => {
item.index = index + 1
return item
})
// 最热资源
data.hot = hot.map((item: any, index: number) => {
item.index = index + 1
return item
})
data.learn = learn.map((item: any, index: number) => {
item.index = index + 1
return item
})
})
</script>
<template>
<AppCard title="资源统计">
<Statistics></Statistics>
</AppCard>
<AppCard title="最新资源">
<Newest></Newest>
</AppCard>
<AppCard title="最热资源">
<Hottest></Hottest>
</AppCard>
<AppCard title="最近学习">
<RecentLearning></RecentLearning>
</AppCard>
<div v-if="flag">
<AppCard title="资源统计">
<Statistics :data="data.statistics"></Statistics>
</AppCard>
<AppCard title="最新资源">
<Newest :data="data.latest"></Newest>
</AppCard>
<AppCard :data="data.hot" title="最热资源">
<Hottest></Hottest>
</AppCard>
<AppCard title="最近学习">
<RecentLearning :data="data.learn"></RecentLearning>
</AppCard>
</div>
</template>
import httpRequest from '@/utils/axios'
// 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params })
}
// 创建视频
export function createVideo(data: { course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/create', data)
}
// 更新视频
export function updateVideo(data: { id: string; course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/update', data)
}
// 获取视频详情
export function getVideo(params: { id: string }) {
return httpRequest.get('/api/psp/backend/video/view', { params })
}
<script setup lang="ts">
import * as echarts from "echarts"
const echartsRef = ref()
onMounted(() => {
const myEcharts = echarts.init(echartsRef.value)
const option = {
grid: {
bottom: 30,
left: 30,
right: 30
},
xAxis: {
data: ['2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21'],
axisTick: {
show: false
}
},
color: ['#BF9D6B'],
yAxis: {},
series: [
{
type: 'bar',
barWidth: '18',
data: [5, 20, 36, 10, 10, 20]
}
],
}
//设置配置
myEcharts.setOption(option)
})
const listOptions = {
columns: [
{ label: '访问时间', prop: 'name', align: 'center' },
{ label: '姓名', prop: 'bumen', align: 'center' },
{ label: '所在项目', prop: 'update', align: 'center' },
{ label: '访问时长', prop: 'time', align: 'center' }
],
data: [
{ time: '111', id: 1, name: '宏观经济学.pptx', type: '1', index: '1', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 2, name: '宏观经济学.pptx', type: '2', index: '2', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 3, name: '宏观经济学.pptx', type: '3', index: '3', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 4, name: '宏观经济学.pptx', type: '4', index: '4', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
]
}
</script>
<template>
<div class="data-box">
<div class="echart">
<div class="name">访问量/关联量一周走势图</div>
<div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div>
</div>
<div class="label-box">
<div class="name">最近访问</div>
<AppList v-bind="listOptions" ref="appList" stripe></AppList>
</div>
</div>
<!-- <div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div> -->
</template>
<style lang="scss" scoped>
.data-box{
display: flex;
.echart{
flex: 1;
height: 369px;
box-sizing: border-box;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-right: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
.label-box{
box-sizing: border-box;
flex: 1;
height: 369px;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-left: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
}
</style>
<script setup lang="ts">
</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>
<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>
</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>
</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>
</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>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.center-video-box{
padding: 20px 0;
display: flex;
.right-statistics{
flex: 1;
padding-top: 15px;
.stat-item{
width: 210px;
height: 85px;
background: #B41E47;
border-radius: 6px;
display: flex;
align-items: center;
margin: 0 auto 20px;
&:nth-child(even){
background: #BF9D6B;
}
img{
width: 52px;
height: 52px;
display: block;
margin-left: 18px;
}
.content{
margin-left: 18px;
.unit{
font-size: 26px;
line-height: 100%;
color: #FFFFFF;
span{
font-size: 12px;
line-height: 100%;
}
}
.tag{
font-size: 14px;
line-height: 100%;
color: #FFFFFF;
margin-top: 10px;
}
}
}
}
}
</style>
<script setup lang="ts">
import { Files } from '@element-plus/icons-vue'
</script>
<template>
<div class="video-info">
<div class="video-img">
<el-icon class="item-info-icon">
<Files />
</el-icon>
<!-- <img src="https://iph.href.lu/211x146"> -->
</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">
<div class="text-box">
<div class="name">状态</div>
<div class="value active">有效</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">
<div class="text-box">
<div class="name">创建者</div>
<div class="value">张三丰</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">
<div class="text-box">
<div class="name">创建时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">更新时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">课件名称</div>
<div class="value">基金产品(中)(初级)</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">
<div class="text-box">
<div class="name">课件分类</div>
<div class="value">金融产品数字化营销-黄老师</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">
<div class="text-box">
<div class="name">知识点</div>
<div class="textarea-box">
某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.video-info{
background: #F7F7F7;
margin-top: 20px;
padding: 20px;
display: flex;
.video-img{
// width: 211px;
padding: 0 30px;
.item-info-icon{
font-size: 100px;
color: #aa1941;
}
.name{
font-size: 16px;
line-height: 100%;
color: #666666;
margin-top: 12px;
text-align: center;
}
}
.info-items{
display: flex;
flex-wrap: wrap;
padding-left: 12px;
.i-items{
display: flex;
align-items: center;
height: fit-content;
margin-right: 80px;
margin-bottom: 30px;
.textarea-box{
padding: 18px 18px 51px;
background: #FFFFFF;
border-radius: 4px;
font-size: 16px;
line-height: 24px;
color: #505050;
margin-top: 14px;
}
.text-box{
margin-left: 16px;
.name{
font-size: 14px;
line-height: 100%;
color: #999999;
}
.value{
font-size: 16px;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-top: 8px;
&.active{
color: #1AB226;
}
}
}
}
}
}
</style>
import type { RouteRecordRaw } from 'vue-router'
import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/resource/lessonplan',
component: AppLayout,
children: [
{ path: '', component: () => import('./views/List.vue') },
{ path: 'update', component: () => import('./views/Update.vue') },
{ path: 'view', component: () => import('./views/View.vue') }
// { path: 'update/:id', component: () => import('./views/Update.vue'), props: true }
]
}
]
<script setup lang="ts">
// import { getVideoList } from '../api'
import CardListItem from '@/components/base/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
const appList = ref()
const isCard = ref(true)
const listOptions = {
remote: {
// httpRequest: getVideoList,
params: { type: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
}
},
filters: [
{ type: 'select', prop: 'type', label: '状态' },
{ type: 'select', prop: 'project_id', label: '项目' },
{ type: 'select', prop: 'category_id', label: '类别' },
{ prop: 'search', slots: 'filter-search' }
// { type: 'input', prop: 'category_id', prefixIcon: 'Search' }
],
columns: [
{ label: '视频标题', prop: 'title' },
{ label: '视频分类', prop: 'type' },
{ label: '知识点', prop: 'zsd' },
{ label: '封面', slots: 'table-cover', width: 100 },
{ label: '资源状态', prop: 'state' },
{ label: '审核状态', prop: 'state2' },
{ label: '更新人', prop: 'update' },
{ label: '更新人部门', prop: 'updatebm' },
{ label: '更新日期', prop: 'update_time' },
{ label: '操作', slots: 'table-operate', align: 'right' }
],
data: [
{ id: 1, title: '视频标题', type: '视频分类' },
{ id: 2, title: '视频标题', type: '视频分类' }
]
}
</script>
<template>
<AppCard>
<!-- <el-switch v-model="isCard"></el-switch> -->
<div class="video-head">
<el-tabs>
<el-tab-pane label="我的资源"></el-tab-pane>
<el-tab-pane label="部门资源"></el-tab-pane>
<el-tab-pane label="公开资源"></el-tab-pane>
</el-tabs>
<el-icon class="video-head-icon" @click="isCard = !isCard"><Expand /></el-icon>
</div>
<div class="video-tool-btn">
<router-link to="/resource/lessonplan/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 #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<el-button plain>编辑</el-button>
</router-link>
<router-link :to="`/video/view/${row.id}`">
<el-button type="primary" plain>查看</el-button>
</router-link>
</el-space>
</template>
<!-- 卡片 -->
<template #body="{ data }" v-if="isCard">
<div class="card-list">
<CardListItem v-for="(item, index) in data" :data="item" :key="index"></CardListItem>
</div>
<!-- <div class="resource-video-item" v-for="item in data" :key="item.id">{{ item.title }}</div> -->
</template>
</AppList>
</AppCard>
</template>
<style lang="scss">
.card-list{
background: #FAFAFA;
padding: 20px;
display: flex;
}
.video-head {
position: relative;
.video-head-icon {
position: absolute;
top: 0;
right: 0;
font-size: 30px;
color: #666;
cursor: pointer;
}
}
.video-tool-btn {
padding: 10px 0 30px 0;
}
</style>
<script setup lang="ts">
import UploadAuth from '@/components/base/UploadAuth.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
}
</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">
<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">课件支持格式包含:doc docx pdf ppt pptx,大小不超过50M</div>
</div>
</el-form-item>
<el-form-item label="教案名称:" prop="course_name">
<el-input v-model="form.videoName" />
</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>
<el-form-item label="&nbsp;&nbsp;&nbsp;知识点:" prop="course_name">
<el-input
v-model="form.zsd"
:rows="2"
type="textarea"
/>
</el-form-item>
</el-form>
<div class="protocol-box">
<el-checkbox v-model="protocol" size="large">
我已阅读并同意<span>《紫荆教育用户入驻及网络教学资源协议》</span>
</el-checkbox>
</div>
<div class="btn-box">
<div class="confirm">保存</div>
<div class="cancel">取消</div>
</div>
</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;
.btn-item{
width: 127px;
line-height: 36px;
background: #AA1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
text-align: center;
}
}
.demo-progress{
width: 350px;
}
.video-cover{
display: flex;
.img-box{
width: 208px;
height: 130px;
border-radius: 4px;
background: #F7F7F7;
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
img{
width: 100%;
height: 100%;
display: block;
}
}
.video-cover_right{
margin-left: 20px;
.list{
.item{
display: flex;
align-items: center;
margin-top: 12px;
img{
width: 9px;
display: block;
margin-right: 5px;
}
.text{
font-size: 12px;
color: #999999;
line-height: 100%;
}
}
}
}
}
.swiper-box{
min-width: 660px;
margin-top: 20px;
padding: 0 40px;
position: relative;
.arrow{
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 30px;
color: #D5D5D5;
cursor: pointer;
&.left{
left: 0;
}
&.right{
right: 10px;
}
}
.cover-list{
display: flex;
flex-wrap: wrap;
.cover-list_item{
display: block;
width: 155px;
height: 96px;
margin: 0 10px 10px 0;
border-radius: 4px;
cursor: pointer;
}
}
}
:deep(.el-carousel__indicators--horizontal){
display: none;
}
.protocol-box{
font-size: 14px;
line-height: 24px;
padding-left: 90px;
padding-top: 20px;
color: #666666;
span{
color: #AA1941;
}
}
.btn-box{
display: flex;
margin-top: 20px;
margin-left: 90px;
.confirm{
width: 94px;
background: #AA1941;
border-radius: 20px;
text-align: center;
line-height: 36px;
color: #fff;
margin-right: 26px;
cursor: pointer;
}
.cancel{
width: 94px;
line-height: 36px;
border: 1px solid #AA1941;
border-radius: 20px;
text-align: center;
color: #AA1941;
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 TopInfo from '../components/view/TopInfo.vue'
import CenterInfo from '../components/view/CenterInfo.vue'
import BottomInfo from '../components/view/BottomInfo.vue'
const listOptions = {
columns: [
{ label: '课程图片', prop: 'img', align: 'center' },
{ label: '课程名称', prop: 'cursor_name', align: 'center' },
{ label: '分类名称', prop: 'type_name', align: 'center' },
{ label: '所在章', slots: 'zhang', align: 'center' },
{ label: '所在小结', prop: 'jie', align: 'center' },
{ label: '创建日期', prop: 'update', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: [
{ img: 1, cursor_name: '宏观经济学.pptx', type_name: '1', zhang: '1', jie: '吉林师范大学', update: '王重阳' },
{ img: 2, cursor_name: '宏观经济学.pptx', type_name: '2', zhang: '2', jie: '吉林师范大学', update: '王重阳' },
{ img: 3, cursor_name: '宏观经济学.pptx', type_name: '3', zhang: '3', jie: '吉林师范大学', update: '王重阳' },
{ img: 4, cursor_name: '宏观经济学.pptx', type_name: '4', zhang: '4', jie: '吉林师范大学', update: '王重阳' },
{ img: 5, cursor_name: '宏观经济学.pptx', type_name: '5', zhang: '5', jie: '吉林师范大学', update: '王重阳' }
]
}
</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>
<TopInfo></TopInfo>
<CenterInfo></CenterInfo>
<BottomInfo></BottomInfo>
</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
>
</router-link>
</el-space>
</template>
</AppList>
</AppCard>
</template>
<style lang="scss" scoped>
.btn-box{
display: flex;
justify-content: right;
.btn-item{
width: 127px;
line-height: 36px;
background: #AA1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
text-align: center;
}
}
</style>
import httpRequest from '@/utils/axios'
// 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params })
}
// 创建视频
export function createVideo(data: { course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/create', data)
}
// 更新视频
export function updateVideo(data: { id: string; course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/update', data)
}
// 获取视频详情
export function getVideo(params: { id: string }) {
return httpRequest.get('/api/psp/backend/video/view', { params })
}
<script setup lang="ts">
import * as echarts from "echarts"
const echartsRef = ref()
onMounted(() => {
const myEcharts = echarts.init(echartsRef.value)
const option = {
grid: {
bottom: 30,
left: 30,
right: 30
},
xAxis: {
data: ['2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21'],
axisTick: {
show: false
}
},
color: ['#BF9D6B'],
yAxis: {},
series: [
{
type: 'bar',
barWidth: '18',
data: [5, 20, 36, 10, 10, 20]
}
],
}
//设置配置
myEcharts.setOption(option)
})
const listOptions = {
columns: [
{ label: '访问时间', prop: 'name', align: 'center' },
{ label: '姓名', prop: 'bumen', align: 'center' },
{ label: '所在项目', prop: 'update', align: 'center' },
{ label: '访问时长', prop: 'time', align: 'center' }
],
data: [
{ time: '111', id: 1, name: '宏观经济学.pptx', type: '1', index: '1', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 2, name: '宏观经济学.pptx', type: '2', index: '2', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 3, name: '宏观经济学.pptx', type: '3', index: '3', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 4, name: '宏观经济学.pptx', type: '4', index: '4', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
]
}
</script>
<template>
<div class="data-box">
<div class="echart">
<div class="name">访问量/关联量一周走势图</div>
<div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div>
</div>
<div class="label-box">
<div class="name">最近访问</div>
<AppList v-bind="listOptions" ref="appList" stripe></AppList>
</div>
</div>
<!-- <div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div> -->
</template>
<style lang="scss" scoped>
.data-box{
display: flex;
.echart{
flex: 1;
height: 369px;
box-sizing: border-box;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-right: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
.label-box{
box-sizing: border-box;
flex: 1;
height: 369px;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-left: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
}
</style>
<script setup lang="ts">
</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>
<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>
</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>
</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>
</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>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.center-video-box{
padding: 20px 0;
display: flex;
.right-statistics{
flex: 1;
padding-top: 15px;
.stat-item{
width: 210px;
height: 85px;
background: #B41E47;
border-radius: 6px;
display: flex;
align-items: center;
margin: 0 auto 20px;
&:nth-child(even){
background: #BF9D6B;
}
img{
width: 52px;
height: 52px;
display: block;
margin-left: 18px;
}
.content{
margin-left: 18px;
.unit{
font-size: 26px;
line-height: 100%;
color: #FFFFFF;
span{
font-size: 12px;
line-height: 100%;
}
}
.tag{
font-size: 14px;
line-height: 100%;
color: #FFFFFF;
margin-top: 10px;
}
}
}
}
}
</style>
<script setup lang="ts">
import { Files } from '@element-plus/icons-vue'
</script>
<template>
<div class="video-info">
<div class="video-img">
<el-icon class="item-info-icon">
<Files />
</el-icon>
<!-- <img src="https://iph.href.lu/211x146"> -->
</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">
<div class="text-box">
<div class="name">状态</div>
<div class="value active">有效</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">
<div class="text-box">
<div class="name">创建者</div>
<div class="value">张三丰</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">
<div class="text-box">
<div class="name">创建时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">更新时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">课件名称</div>
<div class="value">基金产品(中)(初级)</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">
<div class="text-box">
<div class="name">课件分类</div>
<div class="value">金融产品数字化营销-黄老师</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">
<div class="text-box">
<div class="name">知识点</div>
<div class="textarea-box">
某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.video-info{
background: #F7F7F7;
margin-top: 20px;
padding: 20px;
display: flex;
.video-img{
// width: 211px;
padding: 0 30px;
.item-info-icon{
font-size: 100px;
color: #aa1941;
}
.name{
font-size: 16px;
line-height: 100%;
color: #666666;
margin-top: 12px;
text-align: center;
}
}
.info-items{
display: flex;
flex-wrap: wrap;
padding-left: 12px;
.i-items{
display: flex;
align-items: center;
height: fit-content;
margin-right: 80px;
margin-bottom: 30px;
.textarea-box{
padding: 18px 18px 51px;
background: #FFFFFF;
border-radius: 4px;
font-size: 16px;
line-height: 24px;
color: #505050;
margin-top: 14px;
}
.text-box{
margin-left: 16px;
.name{
font-size: 14px;
line-height: 100%;
color: #999999;
}
.value{
font-size: 16px;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-top: 8px;
&.active{
color: #1AB226;
}
}
}
}
}
}
</style>
import type { RouteRecordRaw } from 'vue-router'
import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/resource/other',
component: AppLayout,
children: [
{ path: '', component: () => import('./views/List.vue') },
{ path: 'update', component: () => import('./views/Update.vue') },
{ path: 'view', component: () => import('./views/View.vue') }
// { path: 'update/:id', component: () => import('./views/Update.vue'), props: true }
]
}
]
<script setup lang="ts">
// import { getVideoList } from '../api'
import CardListItem from '@/components/base/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
const appList = ref()
const isCard = ref(true)
const listOptions = {
remote: {
// httpRequest: getVideoList,
params: { type: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
}
},
filters: [
{ type: 'select', prop: 'type', label: '状态' },
{ type: 'select', prop: 'project_id', label: '项目' },
{ type: 'select', prop: 'category_id', label: '类别' },
{ prop: 'search', slots: 'filter-search' }
// { type: 'input', prop: 'category_id', prefixIcon: 'Search' }
],
columns: [
{ label: '视频标题', prop: 'title' },
{ label: '视频分类', prop: 'type' },
{ label: '知识点', prop: 'zsd' },
{ label: '封面', slots: 'table-cover', width: 100 },
{ label: '资源状态', prop: 'state' },
{ label: '审核状态', prop: 'state2' },
{ label: '更新人', prop: 'update' },
{ label: '更新人部门', prop: 'updatebm' },
{ label: '更新日期', prop: 'update_time' },
{ label: '操作', slots: 'table-operate', align: 'right' }
],
data: [
{ id: 1, title: '视频标题', type: '视频分类' },
{ id: 2, title: '视频标题', type: '视频分类' }
]
}
</script>
<template>
<AppCard>
<!-- <el-switch v-model="isCard"></el-switch> -->
<div class="video-head">
<el-tabs>
<el-tab-pane label="我的资源"></el-tab-pane>
<el-tab-pane label="部门资源"></el-tab-pane>
<el-tab-pane label="公开资源"></el-tab-pane>
</el-tabs>
<el-icon class="video-head-icon" @click="isCard = !isCard"><Expand /></el-icon>
</div>
<div class="video-tool-btn">
<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 #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<el-button plain>编辑</el-button>
</router-link>
<router-link :to="`/video/view/${row.id}`">
<el-button type="primary" plain>查看</el-button>
</router-link>
</el-space>
</template>
<!-- 卡片 -->
<template #body="{ data }" v-if="isCard">
<div class="card-list">
<CardListItem v-for="(item, index) in data" :data="item" :key="index"></CardListItem>
</div>
<!-- <div class="resource-video-item" v-for="item in data" :key="item.id">{{ item.title }}</div> -->
</template>
</AppList>
</AppCard>
</template>
<style lang="scss">
.card-list{
background: #FAFAFA;
padding: 20px;
display: flex;
}
.video-head {
position: relative;
.video-head-icon {
position: absolute;
top: 0;
right: 0;
font-size: 30px;
color: #666;
cursor: pointer;
}
}
.video-tool-btn {
padding: 10px 0 30px 0;
}
</style>
<script setup lang="ts">
import UploadAuth from '@/components/base/UploadAuth.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
}
</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">
<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">文件支持格式包含: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>
<el-form-item label="资料分类:" prop="course_name">
<el-tree-select style="width:100%" v-model="form.videoType" :data="data" />
</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>
</el-form>
<div class="protocol-box">
<el-checkbox v-model="protocol" size="large">
我已阅读并同意<span>《紫荆教育用户入驻及网络教学资源协议》</span>
</el-checkbox>
</div>
<div class="btn-box">
<div class="confirm">保存</div>
<div class="cancel">取消</div>
</div>
</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;
.btn-item{
width: 127px;
line-height: 36px;
background: #AA1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
text-align: center;
}
}
.demo-progress{
width: 350px;
}
.video-cover{
display: flex;
.img-box{
width: 208px;
height: 130px;
border-radius: 4px;
background: #F7F7F7;
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
img{
width: 100%;
height: 100%;
display: block;
}
}
.video-cover_right{
margin-left: 20px;
.list{
.item{
display: flex;
align-items: center;
margin-top: 12px;
img{
width: 9px;
display: block;
margin-right: 5px;
}
.text{
font-size: 12px;
color: #999999;
line-height: 100%;
}
}
}
}
}
.swiper-box{
min-width: 660px;
margin-top: 20px;
padding: 0 40px;
position: relative;
.arrow{
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 30px;
color: #D5D5D5;
cursor: pointer;
&.left{
left: 0;
}
&.right{
right: 10px;
}
}
.cover-list{
display: flex;
flex-wrap: wrap;
.cover-list_item{
display: block;
width: 155px;
height: 96px;
margin: 0 10px 10px 0;
border-radius: 4px;
cursor: pointer;
}
}
}
:deep(.el-carousel__indicators--horizontal){
display: none;
}
.protocol-box{
font-size: 14px;
line-height: 24px;
padding-left: 90px;
padding-top: 20px;
color: #666666;
span{
color: #AA1941;
}
}
.btn-box{
display: flex;
margin-top: 20px;
margin-left: 90px;
.confirm{
width: 94px;
background: #AA1941;
border-radius: 20px;
text-align: center;
line-height: 36px;
color: #fff;
margin-right: 26px;
cursor: pointer;
}
.cancel{
width: 94px;
line-height: 36px;
border: 1px solid #AA1941;
border-radius: 20px;
text-align: center;
color: #AA1941;
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 TopInfo from '../components/view/TopInfo.vue'
import CenterInfo from '../components/view/CenterInfo.vue'
import BottomInfo from '../components/view/BottomInfo.vue'
const listOptions = {
columns: [
{ label: '课程图片', prop: 'img', align: 'center' },
{ label: '课程名称', prop: 'cursor_name', align: 'center' },
{ label: '分类名称', prop: 'type_name', align: 'center' },
{ label: '所在章', slots: 'zhang', align: 'center' },
{ label: '所在小结', prop: 'jie', align: 'center' },
{ label: '创建日期', prop: 'update', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: [
{ img: 1, cursor_name: '宏观经济学.pptx', type_name: '1', zhang: '1', jie: '吉林师范大学', update: '王重阳' },
{ img: 2, cursor_name: '宏观经济学.pptx', type_name: '2', zhang: '2', jie: '吉林师范大学', update: '王重阳' },
{ img: 3, cursor_name: '宏观经济学.pptx', type_name: '3', zhang: '3', jie: '吉林师范大学', update: '王重阳' },
{ img: 4, cursor_name: '宏观经济学.pptx', type_name: '4', zhang: '4', jie: '吉林师范大学', update: '王重阳' },
{ img: 5, cursor_name: '宏观经济学.pptx', type_name: '5', zhang: '5', jie: '吉林师范大学', update: '王重阳' }
]
}
</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>
<TopInfo></TopInfo>
<CenterInfo></CenterInfo>
<BottomInfo></BottomInfo>
</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
>
</router-link>
</el-space>
</template>
</AppList>
</AppCard>
</template>
<style lang="scss" scoped>
.btn-box{
display: flex;
justify-content: right;
.btn-item{
width: 127px;
line-height: 36px;
background: #AA1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
text-align: center;
}
}
</style>
......@@ -2,12 +2,22 @@ import httpRequest from '@/utils/axios'
// 获取视频列表
export function getVideoList(params?: { type?: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/backend/video/index', { params })
return httpRequest.get('/api/resource/v1/resource/video/list', { params })
}
// 创建视频
export function createVideo(data: { course_name: string; cover_page: string; type: string; weight?: string }) {
return httpRequest.post('/api/psp/backend/video/create', data)
export function createVideo(data: { name: string; source: string; classification: string; knowledge_points: string; cover: string; source_id: string }) {
return httpRequest.post('/api/resource/v1/resource/video/create', data)
}
// 获取分类列表
export function getCategoryList(params: { type: string; category_name?: string }) {
return httpRequest.get('/api/resource/v1/backend/category/list', { params })
}
// 获取封面列表
export function getCoverList() {
return httpRequest.get('/api/resource/v1/util/get-cover-list')
}
// 更新视频
......
<script setup lang="ts">
// const props = defineProps<{ data: object }>()
const props:any = defineProps<{ data: object }>()
</script>
<template>
<!-- <div>{{ props.data }}</div> -->
<div class="card-item">
<div class="card-item-top">
<div class="title">基金产品(中)(初级)</div>
<img src="http://iph.href.lu/265x170" />
<div class="title">{{ props.data.name }}</div>
<!-- <img :src="props.data.cover" /> -->
<div class="cover-img" :style="`background-image:url(${props.data.cover})`"></div>
<div class="tool-pop-btn">
<div class="edit-btn">编辑</div>
<div class="view-btn">查看</div>
<router-link to="/resource/video/update">
<div class="edit-btn">编辑</div>
</router-link>
<router-link to="/resource/video/view">
<div class="view-btn">查看</div>
</router-link>
</div>
</div>
<div class="card-item-bottom">
<div class="item-t">
<div class="text">张三丰/紫荆教育</div>
<div class="tag green">失效</div>
<div class="text">{{ props.data.created_operator_name }}/{{ props.data.organ_id_name }}</div>
<div :class="props.data.status == 1 ? 'tag green' : 'tag'">{{ props.data.status_name }}</div>
</div>
<div class="item-b">
<div class="time">2022-03-21 12:34:21</div>
<div class="tag">新建</div>
<div class="time">{{ props.data.updated_time }}</div>
<!-- <div class="tag">新建</div> -->
</div>
</div>
</div>
......@@ -39,10 +44,10 @@
opacity: 1;
}
}
img {
.cover-img {
width: 100%;
height: 100%;
display: block;
background-size: cover;
}
.title {
position: absolute;
......
<script lang="ts" setup>
import { ElMessage } from 'element-plus'
// import { Plus } from '@element-plus/icons-vue'
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/'
})
const emit = defineEmits(['update:modelValue'])
const uploadData = ref()
const fileList = ref<UploadUserFile[]>([])
watch(
() => props.modelValue,
value => {
fileList.value = Array.isArray(value) ? [...value] : []
}
)
const showFileList = computed(() => {
return Array.isArray(props.modelValue)
})
// 上传之前
const handleBeforeUpload = async (file: any) => {
const fileName = file.name
const key = props.prefix + md5(fileName + new Date().getTime()) + fileName.substr(fileName.lastIndexOf('.'))
const response: Record<string, any> = await getSignature()
uploadData.value = {
key,
OSSAccessKeyId: response.accessid,
policy: response.policy,
signature: response.signature,
success_action_status: '200',
url: `${response.host}/${key}`
}
file.url = `${response.host}/${key}`
}
// 上传成功
const handleSuccess = (response: any, file: any, files: any) => {
if (!files.every((item: any) => item.status === 'success')) return
if (showFileList.value) {
emit(
'update:modelValue',
files.map((item: any) => {
return { name: item.name, url: item.url || item.raw.url }
})
)
} else {
emit('update:modelValue', file.raw.url)
}
}
// 上传限制
const handleExceed: UploadProps['onExceed'] = () => {
ElMessage.warning('文件超出个数限制')
}
// 删除
const handleRemove: UploadProps['onRemove'] = (file, files) => {
emit(
'update:modelValue',
files.map((item: any) => {
return { name: item.name, url: item.url || item.raw.url }
})
)
}
// 预览
const handlePreview: UploadProps['onPreview'] = uploadFile => {
console.log(uploadFile)
}
</script>
<template>
<el-upload
action="https://webapp-pub.oss-cn-beijing.aliyuncs.com"
:data="uploadData"
:show-file-list="showFileList"
:before-upload="handleBeforeUpload"
:on-exceed="handleExceed"
:on-remove="handleRemove"
:on-preview="handlePreview"
:on-success="handleSuccess"
:file-list="fileList"
class="uploader"
>
<el-button type="primary">选择本地图片</el-button>
</el-upload>
</template>
<style lang="scss">
.uploader {
flex: 1;
}
.avatar-uploader {
width: 178px;
height: 178px;
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
.el-image {
width: 100%;
height: 100%;
}
}
.avatar-uploader:hover {
border-color: var(--el-color-primary);
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 100%;
height: 100%;
text-align: center;
}
</style>
<script setup lang="ts">
import * as echarts from "echarts"
const echartsRef = ref()
onMounted(() => {
const myEcharts = echarts.init(echartsRef.value)
const option = {
grid: {
bottom: 30,
left: 30,
right: 30
},
xAxis: {
data: ['2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21', '2022-02-21'],
axisTick: {
show: false
}
},
color: ['#BF9D6B'],
yAxis: {},
series: [
{
type: 'bar',
barWidth: '18',
data: [5, 20, 36, 10, 10, 20]
}
],
}
//设置配置
myEcharts.setOption(option)
})
const listOptions = {
columns: [
{ label: '访问时间', prop: 'name', align: 'center' },
{ label: '姓名', prop: 'bumen', align: 'center' },
{ label: '所在项目', prop: 'update', align: 'center' },
{ label: '访问时长', prop: 'time', align: 'center' }
],
data: [
{ time: '111', id: 1, name: '宏观经济学.pptx', type: '1', index: '1', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 2, name: '宏观经济学.pptx', type: '2', index: '2', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 3, name: '宏观经济学.pptx', type: '3', index: '3', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
{ time: '111', id: 4, name: '宏观经济学.pptx', type: '4', index: '4', bumen: '吉林师范大学', update: '王重阳', relation: '22' },
]
}
</script>
<template>
<div class="data-box">
<div class="echart">
<div class="name">访问量/关联量一周走势图</div>
<div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div>
</div>
<div class="label-box">
<div class="name">最近访问</div>
<AppList v-bind="listOptions" ref="appList" stripe></AppList>
</div>
</div>
<!-- <div
class="echarts"
ref="echartsRef"
:style="{
width: '600px',
height: '300px'
}"
></div> -->
</template>
<style lang="scss" scoped>
.data-box{
display: flex;
.echart{
flex: 1;
height: 369px;
box-sizing: border-box;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-right: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
.label-box{
box-sizing: border-box;
flex: 1;
height: 369px;
border: 1px solid #E0E0E0;
border-radius: 10px;
margin-left: 10px;
padding: 20px;
.name{
font-size: 16px;
line-height: 100%;
color: #333333;
}
}
}
</style>
<script setup lang="ts">
</script>
<template>
<div class="center-video-box">
<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>
</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>
</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>
</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>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.center-video-box{
padding: 20px 0;
display: flex;
.right-statistics{
flex: 1;
padding-top: 15px;
.stat-item{
width: 210px;
height: 85px;
background: #B41E47;
border-radius: 6px;
display: flex;
align-items: center;
margin: 0 auto 20px;
&:nth-child(even){
background: #BF9D6B;
}
img{
width: 52px;
height: 52px;
display: block;
margin-left: 18px;
}
.content{
margin-left: 18px;
.unit{
font-size: 26px;
line-height: 100%;
color: #FFFFFF;
span{
font-size: 12px;
line-height: 100%;
}
}
.tag{
font-size: 14px;
line-height: 100%;
color: #FFFFFF;
margin-top: 10px;
}
}
}
}
}
</style>
<script setup lang="ts">
</script>
<template>
<div class="video-info">
<div class="video-img">
<img src="https://iph.href.lu/211x146">
<div class="name">视频封面</div>
</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">
<div class="text-box">
<div class="name">状态</div>
<div class="value active">有效</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">
<div class="text-box">
<div class="name">创建者</div>
<div class="value">张三丰</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">
<div class="text-box">
<div class="name">创建时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">更新时间</div>
<div class="value">2021-08-09 12:32:21</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">
<div class="text-box">
<div class="name">视频名称</div>
<div class="value">基金产品(中)(初级)</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">
<div class="text-box">
<div class="name">资源来源</div>
<div class="value">金融产品数字化营销-黄老师</div>
</div>
</div>
<div class="i-items">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/center_resource/video-view-icon7.png" class="icons">
<div class="text-box">
<div class="name">视频分类</div>
<div class="value">金融产品数字化营销-黄老师</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">
<div class="text-box">
<div class="name">知识点</div>
<div class="textarea-box">
某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某某
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.video-info{
background: #F7F7F7;
margin-top: 20px;
padding: 20px;
display: flex;
.video-img{
width: 211px;
img{
width: 211px;
display: block;
}
.name{
font-size: 16px;
line-height: 100%;
color: #666666;
margin-top: 12px;
text-align: center;
}
}
.info-items{
display: flex;
flex-wrap: wrap;
padding-left: 12px;
.i-items{
display: flex;
align-items: center;
height: fit-content;
margin-right: 80px;
margin-bottom: 30px;
.textarea-box{
padding: 18px 18px 51px;
background: #FFFFFF;
border-radius: 4px;
font-size: 16px;
line-height: 24px;
color: #505050;
margin-top: 14px;
}
.text-box{
margin-left: 16px;
.name{
font-size: 14px;
line-height: 100%;
color: #999999;
}
.value{
font-size: 16px;
font-weight: bold;
line-height: 100%;
color: #333333;
margin-top: 8px;
&.active{
color: #1AB226;
}
}
}
}
}
}
</style>
......@@ -7,8 +7,10 @@ export const routes: Array<RouteRecordRaw> = [
component: AppLayout,
children: [
{ path: '', component: () => import('./views/List.vue') },
{ path: 'create', component: () => import('./views/Update.vue') },
{ path: 'update/:id', component: () => import('./views/Update.vue'), props: true }
{ path: 'update', component: () => import('./views/Update.vue') },
{ path: 'view', component: () => import('./views/View.vue') },
{ path: 'edit-courseware', component: () => import('./views/EditCourseware.vue') }
// { path: 'update/:id', component: () => import('./views/Update.vue'), props: true }
]
}
]
<script setup lang="ts">
import TopInfo from '../components/view/TopInfo.vue'
const listOptions = {
columns: [
{ label: '课程图片', prop: 'img', align: 'center' },
{ label: '文件名', prop: 'file_name', align: 'center' },
{ label: '时码', slots: 'table-operate', align: 'center' }
],
data: [
{ img: 1, cursor_name: '宏观经济学.pptx', type_name: '1', zhang: '1', jie: '吉林师范大学', update: '王重阳' },
{ img: 2, cursor_name: '宏观经济学.pptx', type_name: '2', zhang: '2', jie: '吉林师范大学', update: '王重阳' },
{ img: 3, cursor_name: '宏观经济学.pptx', type_name: '3', zhang: '3', jie: '吉林师范大学', update: '王重阳' },
{ img: 4, cursor_name: '宏观经济学.pptx', type_name: '4', zhang: '4', jie: '吉林师范大学', update: '王重阳' },
{ img: 5, cursor_name: '宏观经济学.pptx', type_name: '5', zhang: '5', jie: '吉林师范大学', update: '王重阳' }
]
}
</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 class="btn-item">资源下线</div>
<div class="btn-item">更改负责人</div>
</div> -->
<TopInfo></TopInfo>
</AppCard>
<AppCard>
<el-button type="primary">关联课件</el-button>
<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
>
</router-link>
</el-space>
</template>
</AppList>
</AppCard>
</template>
<style lang="scss" scoped>
.btn-box{
display: flex;
justify-content: right;
.btn-item{
width: 127px;
line-height: 36px;
background: #AA1941;
border-radius: 20px;
margin-right: 10px;
font-size: 14px;
color: #FFFFFF;
text-align: center;
}
}
</style>
<script setup lang="ts">
// import { getVideoList } from '../api'
import { getVideoList } from '../api'
import CardListItem from '../components/CardListItem.vue'
import { Expand, Search } from '@element-plus/icons-vue'
......@@ -9,8 +9,8 @@ const isCard = ref(true)
const listOptions = {
remote: {
// httpRequest: getVideoList,
params: { type: '' },
httpRequest: getVideoList,
params: { title: '' },
beforeRequest(params: any) {
// params.type = 选项卡类型
return params
......@@ -20,20 +20,20 @@ const listOptions = {
{ type: 'select', prop: 'type', label: '状态' },
{ type: 'select', prop: 'project_id', label: '项目' },
{ type: 'select', prop: 'category_id', label: '类别' },
{ prop: 'search', slots: 'filter-search' }
{ prop: 'title', slots: 'filter-search' }
// { type: 'input', prop: 'category_id', prefixIcon: 'Search' }
],
columns: [
{ label: '视频标题', prop: 'title' },
{ label: '视频分类', prop: 'type' },
{ label: '知识点', prop: 'zsd' },
{ label: '封面', slots: 'table-cover', width: 100 },
{ label: '资源状态', prop: 'state' },
{ label: '审核状态', prop: 'state2' },
{ label: '更新人', prop: 'update' },
{ label: '更新人部门', prop: 'updatebm' },
{ label: '更新日期', prop: 'update_time' },
{ label: '操作', slots: 'table-operate', align: 'right' }
{ label: '视频标题', prop: 'name', align: 'center' },
{ label: '视频分类', prop: 'classification_name', align: 'center' },
{ label: '知识点', prop: 'knowledge_points', align: 'center' },
{ label: '封面', slots: 'table-cover', width: 150, align: 'center' },
{ label: '资源状态', prop: 'status_name', align: 'center' },
{ label: '审核状态', prop: 'audit_status_name', align: 'center' },
{ label: '更新人', prop: 'updated_operator_name', align: 'center' },
{ label: '更新人部门', prop: 'organ_id_name', align: 'center' },
{ label: '更新日期', prop: 'updated_time', align: 'center' },
{ label: '操作', slots: 'table-operate', align: 'center' }
],
data: [
{ id: 1, title: '视频标题', type: '视频分类' },
......@@ -44,31 +44,33 @@ const listOptions = {
<template>
<AppCard>
<!-- <el-switch v-model="isCard"></el-switch> -->
<div class="video-head">
<el-tabs>
<el-tab-pane label="个人资源"></el-tab-pane>
<el-tab-pane label="我的资源"></el-tab-pane>
<el-tab-pane label="部门资源"></el-tab-pane>
<el-tab-pane label="公开资源"></el-tab-pane>
</el-tabs>
<el-icon class="video-head-icon" @click="isCard = !isCard"><Expand /></el-icon>
</div>
<div class="video-tool-btn">
<router-link to="/resource/video/create">
<router-link to="/resource/video/update">
<el-button type="primary" round>新建视频资源</el-button>
</router-link>
</div>
<AppList v-bind="listOptions" ref="appList">
<template #header-aside></template>
<template #table-cover="{ row }">
<img :src="row.cover" style="width:150px;display: block;">
</template>
<template #filter-search="{ params }">
<el-input v-model="params.search" placeholder="搜索" :prefix-icon="Search" />
<el-input v-model="params.title" placeholder="搜索" :prefix-icon="Search" />
</template>
<template #table-operate="{ row }">
<el-space>
<router-link :to="`/video/update/${row.id}`">
<router-link :to="`/resource/video/update/${row.id}`">
<el-button plain>编辑</el-button>
</router-link>
<router-link :to="`/video/view/${row.id}`">
<router-link :to="`/resource/video/view/${row.id}`">
<el-button type="primary" plain>查看</el-button>
</router-link>
</el-space>
......@@ -76,7 +78,7 @@ const listOptions = {
<!-- 卡片 -->
<template #body="{ data }" v-if="isCard">
<div class="card-list">
<div class="card-list" v-if="data.length">
<CardListItem v-for="(item, index) in data" :data="item" :key="index"></CardListItem>
</div>
<!-- <div class="resource-video-item" v-for="item in data" :key="item.id">{{ item.title }}</div> -->
......
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论