|
|
|
@ -1,20 +1,22 @@
|
|
|
|
|
import React, { useState, useRef } from 'react';
|
|
|
|
|
import { useRequest } from 'umi';
|
|
|
|
|
import { PlusOutlined, TagsOutlined, UploadOutlined } from '@ant-design/icons';
|
|
|
|
|
import { Button, message, Input, Drawer, Modal, Col, Row, Space, Upload } from 'antd';
|
|
|
|
|
import { Button, message, Modal, Col, Row, Space, Upload } from 'antd';
|
|
|
|
|
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
|
|
|
|
|
import type { ProColumns, ActionType } from '@ant-design/pro-table';
|
|
|
|
|
import ProTable from '@ant-design/pro-table';
|
|
|
|
|
import { BetaSchemaForm, ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
|
|
|
|
|
import { BetaSchemaForm, ModalForm } from '@ant-design/pro-form';
|
|
|
|
|
import type { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
|
|
|
|
|
import ProDescriptions from '@ant-design/pro-descriptions';
|
|
|
|
|
import type { FormValueType } from './components/UpdateForm';
|
|
|
|
|
import UpdateForm from './components/UpdateForm';
|
|
|
|
|
|
|
|
|
|
import { queryTagList, saveCourse, removeCourse, queryCourseList } from './service';
|
|
|
|
|
import type { TableListItem, TableListPagination } from './data';
|
|
|
|
|
import Tags from './components/Tags';
|
|
|
|
|
import type { DataItem } from '@antv/data-set/lib/transform/tag-cloud';
|
|
|
|
|
import { VideoJS } from './components/VideoJS';
|
|
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
|
|
|
|
|
|
const uuid = uuidv4();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加课程
|
|
|
|
@ -25,7 +27,7 @@ const handleAdd = async (fields: TableListItem) => {
|
|
|
|
|
const hide = message.loading('正在添加');
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await saveCourse({ ...fields });
|
|
|
|
|
await saveCourse({ ...fields, attachment_filesize:0, attachment_json: `{"img":"", "url": "down/M3u8/${uuid?.substr(0,2)}/${uuid}.m3u8"}` });
|
|
|
|
|
hide();
|
|
|
|
|
message.success('添加成功');
|
|
|
|
|
return true;
|
|
|
|
@ -82,6 +84,7 @@ const handleRemove = async (selectedRows: TableListItem[]) => {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CourseList: React.FC = () => {
|
|
|
|
|
|
|
|
|
|
/** 新建窗口的弹窗 */
|
|
|
|
@ -96,6 +99,10 @@ const CourseList: React.FC = () => {
|
|
|
|
|
const [currentRow, setCurrentRow] = useState<TableListItem>();
|
|
|
|
|
const [selectedRowsState, setSelectedRows] = useState<TableListItem[]>([]);
|
|
|
|
|
|
|
|
|
|
const [uploadFileName, SetUploadFileName] = useState<string>();
|
|
|
|
|
const [uploadFileExt, SetUploadFileExt] = useState<string>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 列表项定义 */
|
|
|
|
|
const columns: ProColumns<TableListItem>[] = [
|
|
|
|
|
{
|
|
|
|
@ -112,6 +119,19 @@ const CourseList: React.FC = () => {
|
|
|
|
|
hideInDescriptions: false,
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
formItemProps: {
|
|
|
|
|
// 参照 https://ant.design/components/form-cn/#Rule
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: '此项为必填项',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
max: 50,
|
|
|
|
|
message: '最大长度为50字符',
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
}, // 传递给 Form.Item 的配置
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '主讲教师',
|
|
|
|
@ -122,6 +142,19 @@ const CourseList: React.FC = () => {
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
renderText: (val: string) => `${val}`,
|
|
|
|
|
formItemProps: {
|
|
|
|
|
// 参照 https://ant.design/components/form-cn/#Rule
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: '此项为必填项',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
max: 20,
|
|
|
|
|
message: '最大长度为20字符',
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
}, // 传递给 Form.Item 的配置
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '课时',
|
|
|
|
@ -132,6 +165,19 @@ const CourseList: React.FC = () => {
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
renderText: (val: string) => `${val}`,
|
|
|
|
|
formItemProps: {
|
|
|
|
|
// 参照 https://ant.design/components/form-cn/#Rule
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: '此项为必填项',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
max: 4,
|
|
|
|
|
message: '最大长度为4字符',
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
}, // 传递给 Form.Item 的配置
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '课程描述',
|
|
|
|
@ -142,14 +188,52 @@ const CourseList: React.FC = () => {
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
renderText: (val: string) => `${val}`,
|
|
|
|
|
formItemProps: {
|
|
|
|
|
// 参照 https://ant.design/components/form-cn/#Rule
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: '此项为必填项',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
max: 150,
|
|
|
|
|
message: '最大长度为150字符',
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
}, // 传递给 Form.Item 的配置
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '标签',
|
|
|
|
|
dataIndex: 'tag_name',
|
|
|
|
|
sorter: false,
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
hideInForm: true,
|
|
|
|
|
renderText: (val: string) => `${val}`,
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '标签',
|
|
|
|
|
dataIndex: 'tag_id',
|
|
|
|
|
sorter: false,
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
request: async () => {
|
|
|
|
|
const {data: Items} = await queryTagList({});
|
|
|
|
|
const tags = []
|
|
|
|
|
for(let i=0; i<Items.length; i++){
|
|
|
|
|
tags.push({label:Items[i].tag_name, value: Items[i].tag_id})
|
|
|
|
|
}
|
|
|
|
|
return tags;
|
|
|
|
|
},
|
|
|
|
|
formItemProps: {
|
|
|
|
|
// 参照 https://ant.design/components/form-cn/#Rule
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: '此项为必填项',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}, // 传递给 Form.Item 的配置
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '视频',
|
|
|
|
@ -158,10 +242,40 @@ const CourseList: React.FC = () => {
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
renderFormItem: () => (
|
|
|
|
|
<Upload >
|
|
|
|
|
<Upload
|
|
|
|
|
action='/dsideal_yy/res/plupload/'
|
|
|
|
|
beforeUpload={(file)=>{
|
|
|
|
|
console.log('file', file)
|
|
|
|
|
// 获取文件名
|
|
|
|
|
SetUploadFileName(file?.name) ;
|
|
|
|
|
// 获取最后一个.的位置
|
|
|
|
|
const index = file?.name.lastIndexOf(".");
|
|
|
|
|
// 获取后缀
|
|
|
|
|
SetUploadFileExt(file?.name.substr(index+1));
|
|
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
data={{
|
|
|
|
|
name: uploadFileName,
|
|
|
|
|
chunk: 0,
|
|
|
|
|
chunks: 1,
|
|
|
|
|
key: `down/Syzx/${uuid?.substr(0,2)}/${uuid}.${uploadFileExt}`
|
|
|
|
|
}}
|
|
|
|
|
maxCount={1}
|
|
|
|
|
multiple={false}
|
|
|
|
|
>
|
|
|
|
|
<Button icon={<UploadOutlined />}>上传视频</Button>
|
|
|
|
|
</Upload>),
|
|
|
|
|
renderText: (val: string) => `${val}M`,
|
|
|
|
|
</Upload>
|
|
|
|
|
),
|
|
|
|
|
formItemProps: {
|
|
|
|
|
// 参照 https://ant.design/components/form-cn/#Rule
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: '此项为必填项',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}, // 传递给 Form.Item 的配置
|
|
|
|
|
//renderText: (val: string) => `${val}M`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '视频大小',
|
|
|
|
@ -170,6 +284,15 @@ const CourseList: React.FC = () => {
|
|
|
|
|
hideInForm: true,
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
renderText: (val: string) => `${val}M`,
|
|
|
|
|
formItemProps: {
|
|
|
|
|
// 参照 https://ant.design/components/form-cn/#Rule
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
message: '此项为必填项',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}, // 传递给 Form.Item 的配置
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '创建时间',
|
|
|
|
@ -179,7 +302,6 @@ const CourseList: React.FC = () => {
|
|
|
|
|
hideInTable: true,
|
|
|
|
|
hideInForm: true,
|
|
|
|
|
hideInSearch: false,
|
|
|
|
|
|
|
|
|
|
//renderText: (val: string) => `${val}`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
@ -190,7 +312,6 @@ const CourseList: React.FC = () => {
|
|
|
|
|
<a
|
|
|
|
|
key="detail"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
//console.log('entity', entity);
|
|
|
|
|
setCurrentRow(record);
|
|
|
|
|
handleDetailModalVisible(true);
|
|
|
|
|
}}
|
|
|
|
@ -206,7 +327,11 @@ const CourseList: React.FC = () => {
|
|
|
|
|
>
|
|
|
|
|
编辑
|
|
|
|
|
</a>,
|
|
|
|
|
<a key="remove" onClick={() => { }}>
|
|
|
|
|
<a
|
|
|
|
|
key="remove"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
handleRemove(record);
|
|
|
|
|
}}>
|
|
|
|
|
删除
|
|
|
|
|
</a>,
|
|
|
|
|
],
|
|
|
|
@ -294,9 +419,9 @@ const CourseList: React.FC = () => {
|
|
|
|
|
>
|
|
|
|
|
批量删除
|
|
|
|
|
</Button>
|
|
|
|
|
<Button type="primary">批量审批</Button>
|
|
|
|
|
</FooterToolbar>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
title={currentRow?.course_name || '课程详细'}
|
|
|
|
|
width="50%"
|
|
|
|
@ -329,7 +454,7 @@ const CourseList: React.FC = () => {
|
|
|
|
|
fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
|
|
|
|
|
sources: [
|
|
|
|
|
{
|
|
|
|
|
src: (currentRow?.attachment_json?.url) || 'http://10.10.14.199/dsideal_yy/html/down/M3u8/2D/2D99BF1D-2F37-47FB-8A24-45112A236B8F.m3u8', // 测试地址后续请删除
|
|
|
|
|
src: (currentRow?.attachment_json?.url) || '/dsideal_yy/html/down/M3u8/2D/2D99BF1D-2F37-47FB-8A24-45112A236B8F.m3u8', // 测试地址后续请删除
|
|
|
|
|
type: 'application/x-mpegURL'
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
@ -412,9 +537,9 @@ const CourseList: React.FC = () => {
|
|
|
|
|
wrapperCol={{ span: 12 }}
|
|
|
|
|
onFinish={async (values: any) => {
|
|
|
|
|
// 表单处理
|
|
|
|
|
console.log('columns:', columns);
|
|
|
|
|
console.log('values:', values);
|
|
|
|
|
|
|
|
|
|
//console.log('columns:', columns);
|
|
|
|
|
//console.log('values:', values);
|
|
|
|
|
handleAdd(values);
|
|
|
|
|
}}
|
|
|
|
|
submitter={{
|
|
|
|
|
render: (props, doms) => (
|
|
|
|
@ -427,7 +552,7 @@ const CourseList: React.FC = () => {
|
|
|
|
|
}}
|
|
|
|
|
// action = ''
|
|
|
|
|
title="新建"
|
|
|
|
|
columns={columns}
|
|
|
|
|
columns={columns||[]}
|
|
|
|
|
/>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
@ -441,7 +566,7 @@ const CourseList: React.FC = () => {
|
|
|
|
|
}}
|
|
|
|
|
footer={null}
|
|
|
|
|
>
|
|
|
|
|
{currentRow?.name && (
|
|
|
|
|
{currentRow?.course_id && (
|
|
|
|
|
<BetaSchemaForm<DataItem>
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
layoutType="Form"
|
|
|
|
|