diff --git a/admin/src/pages/course/option/service.ts b/admin/src/pages/course/option/service.ts index 5c68eb0..316d84c 100644 --- a/admin/src/pages/course/option/service.ts +++ b/admin/src/pages/course/option/service.ts @@ -28,6 +28,29 @@ export async function queryCourseList( }); } +/** 获取课程列表(不分页) GET /dsideal_yy/ypt/careerTraining/course/list */ +export async function queryCourseListByTag( + params: { + tag_ids?: string; // 过滤标签 + }, + options?: Record, +) { + return request<{ + data: TableListItem[]; + /** 列表的内容总数 */ + total_row?: number; + /** 页面的容量 */ + page_size?: number; + success?: boolean; + }>('/dsideal_yy/ypt/careerTraining/component/listCourseByTag', { + method: 'GET', + params: { + ...params, + }, + ...(options || {}), + }); +} + /** * 获取主题列表 diff --git a/admin/src/pages/course/subject/index.tsx b/admin/src/pages/course/subject/index.tsx index 8c86b25..48c1986 100644 --- a/admin/src/pages/course/subject/index.tsx +++ b/admin/src/pages/course/subject/index.tsx @@ -103,13 +103,12 @@ const TableList: React.FC = () => { }, { title: '图片', - dataIndex: 'name', - tip: '主题名称是唯一的 key', + tip: '主题封面', hideInSearch: true, render: (dom, entity) => { // console.log(entity, 'entity') return ( - + ); }, }, @@ -150,9 +149,9 @@ const TableList: React.FC = () => { return (
- 章节数:{entity.total_chapter_number}
- 课程数:{entity.total_course_number}
- 考核学时:{entity.total_course_minutes}分钟 + 章节数:{entity.total_chapter_number} 个
+ 课程数:{entity.total_course_number} 个
+ 考核学时:{entity.total_course_minutes} 分钟
); @@ -297,7 +296,7 @@ const TableList: React.FC = () => { }} > { + return request('/dsideal_yy/ypt/careerTraining/subject/listChapterBySubject', { + params, + }); +} + +/** + * 新建/修改章节 POST /dsideal_yy/ypt/careerTraining/course/save */ +export async function saveChapter(data: Record, options?: Record) { + return request('/dsideal_yy/ypt/careerTraining/subject/saveChapter', { + data, + method: 'POST', + requestType: 'form', + ...(options || {}), + }); +} diff --git a/admin/src/pages/course/subject/step/index.tsx b/admin/src/pages/course/subject/step/index.tsx index b4fcbbb..1dc53e6 100644 --- a/admin/src/pages/course/subject/step/index.tsx +++ b/admin/src/pages/course/subject/step/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; -import { history } from 'umi'; +import { history, useParams, useRequest } from 'umi'; import type { ProFormInstance } from '@ant-design/pro-form'; import { BetaSchemaForm, ProFormRadio, ProFormUploadButton } from '@ant-design/pro-form'; import ProForm, { @@ -12,7 +12,7 @@ import ProForm, { ProFormDateRangePicker, } from '@ant-design/pro-form'; import ProCard from '@ant-design/pro-card'; -import { Button, Checkbox, Col, Divider, List, Menu, message, Modal, Radio, Row, Space, Typography } from 'antd'; +import { Button, Checkbox, Col, Divider, List, Menu, message, Modal, Radio, Result, Row, Space, Typography } from 'antd'; import { PageContainer } from '@ant-design/pro-layout'; import ProDescriptions from '@ant-design/pro-descriptions'; import styles from './index.less' @@ -23,7 +23,11 @@ import ProFormRichEdit from '../components/ProFormRichEdit'; import type { ActionType, ProColumns } from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table'; import type { TableListItem, TableListPagination } from '../../option/data'; -import { getSubjectInfo, saveSubject } from '../../option/service'; +import { queryCourseList, queryCourseListByTag, queryTagList, saveSubject } from '../../option/service'; +import { getSubjectInfo, queryListChapterBySubject, saveChapter } from '../service'; +import { v4 as uuidv4 } from 'uuid'; + + /** 列表项定义 */ const columns: ProColumns[] = [ @@ -35,32 +39,108 @@ const columns: ProColumns[] = [ }, { title: '章节名称', - dataIndex: 'course_name', + dataIndex: 'chapter_name', valueType: 'text', hideInTable: false, hideInDescriptions: false, hideInForm: false, hideInSearch: true, + formItemProps: { + rules: [ + { + required: true, + message: '请填写章节名称', + }, + ] + }, }, { title: '简介', - dataIndex: 'lecture_teacher', - valueType: 'text', + dataIndex: 'chapter_describe', + valueType: 'textarea', sorter: false, hideInTable: false, hideInForm: false, hideInSearch: true, + formItemProps: { + rules: [ + { + required: true, + message: '请填写章节简介', + }, + ] + }, + renderText: (val: string) => (
), + renderFormItem: (item, { defaultRender, ...rest }, form) => ( + + ), + }, + { + title: '标签', + valueType: 'select', + dataIndex: 'tags', + sorter: false, + hideInTable: true, + hideInForm: false, + hideInSearch: true, + fieldProps: { + mode: "multiple" + }, renderText: (val: string) => `${val}`, + request: async () => { + const { data: Items } = await queryTagList({}); + console.log('queryTagList...') + const tags = [] + for (let i = 0; i < Items.length; i++) { + tags.push({ label: Items[i].tag_name, value: Items[i].tag_id }) + } + console.log(tags, 'tags:::'); + return tags; + }, }, { title: '课程', - valueType: 'textarea', - dataIndex: 'course_describe', + valueType: 'select', + dataIndex: 'course_ids', sorter: false, hideInTable: false, hideInForm: false, hideInSearch: true, + fieldProps: { + mode: "multiple" + }, + formItemProps: { + rules: [ + { + required: true, + message: '请填选择课程', + }, + ] + }, renderText: (val: string) => `${val}`, + dependencies: ['tags'], + request: async (params) => { + const {tags} = params; + const { data: Items } = await queryCourseListByTag({tag_ids: tags?.toString()}); + console.log('queryCourseListByTag...') + const courses = [] + for (let i = 0; i < Items?.length; i++) { + courses.push({ label: Items[i]?.course_name, value: Items[i]?.course_id }) + } + console.log(courses, 'courses:::'); + return courses; + }, + }, { title: '学时', @@ -68,14 +148,16 @@ const columns: ProColumns[] = [ valueType: 'text', sorter: false, hideInTable: false, - hideInForm: false, + hideInForm: true, hideInSearch: true, renderText: (val: string) => `${val}`, }, + { title: '操作', dataIndex: 'option', valueType: 'option', + width: 200, render: (_dom: any, record: React.SetStateAction) => [ [] = [ }, ]; -const waitTime = (time: number = 100) => { - return new Promise((resolve) => { - setTimeout(() => { - resolve(true); - }, time); - }); +/** + * 添加章节 + * + * @param fields + */ +const handleAddChapter = async (fields: TableListItem) => { + const hide = message.loading('正在添加'); + try { + const {course_ids} = fields + const {code, msg} = await saveChapter({ ...fields, course_ids: course_ids.toString()}); + if(code === 2000){ + hide(); + message.success('添加成功'); + return true; + }else{ + hide(); + message.warn(msg); + return false; + } + } catch (error) { + hide(); + message.error('添加失败请重试!'); + return false; + } }; -const numbers = []; -for (let i = 0; i < 50; i++) { - numbers.push({ id: `${i}` }) -} + export default () => { + const uuid = uuidv4(); + const formRef = useRef(); const actionRef = useRef(); @@ -123,15 +222,39 @@ export default () => { const [detailModalVisible, handleDetailModalVisible] = useState(false); const [updateModalVisible, handleUpdateModalVisible] = useState(false); + const [uploadFileName, SetUploadFileName] = useState(); + const [uploadFileExt, SetUploadFileExt] = useState(); + + const [subjectIntro, setSubjectIntro] = useState({}); + const formMapRef = useRef | undefined>[]>([]); + + const params = useParams(); + //console.log('params', params); + + const {data:subjectInfo} = useRequest(() => { + return getSubjectInfo({subject_id: params?.id}); + }); + useEffect(() => { - waitTime(1000).then(() => { - // 编辑场景下需要使用formMapRef循环设置formData - formMapRef.current.forEach((formInstanceRef) => { - formInstanceRef.current?.setFieldsValue({subject_name:'123'}); + console.log('getSubjectInfo', subjectInfo); + console.log('url', subjectInfo?.attachment_json?.url); + // 编辑场景下需要使用formMapRef循环设置formData + formMapRef.current.forEach((formInstanceRef) => { + formInstanceRef.current?.setFieldsValue({ + subject_name:subjectInfo?.subject_name, + subject_describe:subjectInfo?.subject_describe, + upload:[ + { + name: subjectInfo?.attachment_json?.name, + status: 'done', + url: `/dsideal_yy/html/${subjectInfo?.attachment_json?.url}` + } + ] }); }); - }, []); + + }, [subjectInfo]); return ( @@ -142,7 +265,7 @@ export default () => { formMapRef={formMapRef} formRef={formRef} onFinish={async () => { - await waitTime(1000); + message.success('提交成功'); }} formProps={{ @@ -162,25 +285,25 @@ export default () => { stepProps={{ description: false, }} + /* request={async () => { - const data = await getSubjectInfo(5); - console.log(data); + console.log('getSubjectInfo', data); // return { data: bean } - }} - - - - onFinish={async (value) => { + }}*/ + onFinish={async (value: any) => { console.log(value, "vvvvv"); + const url = value?.upload[0]?.url?.replace('/dsideal_yy/html/','') || value?.upload[0]?.response?.url; const _data = await saveSubject({ ...value, - attachment_json: `{ "url": "${value.upload[0].response.url}"}` + subject_id: params?.id, + attachment_json: `{ "url": "${url}"}` }); + setSubjectIntro({subject_name:value?.subject_name, subject_describe:value?.subject_describe}); return { current: _data?.page_number, data: _data?.data?.list, @@ -192,10 +315,9 @@ export default () => { { { fieldProps={{ name: 'file', listType: 'picture-card', + maxCount: 1, + beforeUpload: (file) => { + console.log('file', file) + // 获取文件名 + SetUploadFileName(file?.name); + // 获取最后一个.的位置 + const index = file?.name.lastIndexOf("."); + // 获取后缀 + SetUploadFileExt(file?.name.substr(index + 1)); + }, data: { - name: '5.jpg', + name: uploadFileName, chunk: 0, chunks: 1, - key: 'down/Material/BC/BCFFEA09-9660-9D40-8D11-EF7D7110F7A5.jpg' + key: `down/Syzx/${uuid?.substr(0, 2)}/${uuid}.${uploadFileExt}` } }} action="/dsideal_yy/res/plupload/" @@ -244,6 +376,7 @@ export default () => { description: false, }} onFinish={async (fileds) => { + /* if (params.id) { fileds = { ...fileds, id: params.id } } @@ -258,6 +391,7 @@ export default () => { }); // await waitTime(2000); + */ return true; }} @@ -268,17 +402,21 @@ export default () => { column={1} //actionRef={actionRef} title="主题信息" + /* request={async () => { + console.log('step2 主题信息') return Promise.resolve({ success: true, data: { id: '这是一段文本', object: '', date: '2020-07-30 08:00', duration: '', grade: 100, through: '>60', learn: '>20 min', times: 2 }, }); - }} + }}*/ extra={false} > - - + {subjectIntro?.subject_name} + +
+ @@ -299,17 +437,18 @@ export default () => { , ]} request={async (value) => { - - // const _data = await saveSubject({ - // ...value, - // attachment_json: `{ "url": "${value.upload[0].response.url}"}` - // }); - // return { - // current: _data?.page_number, - // data: _data?.data?.list, - // pageSize: _data?.page_size, - // total: _data?.total_row || 0, - // }; + const { data } = await queryListChapterBySubject({ + subject_id: params?.id || 0, + page_number: value?.current || 1, + page_size: value?.pageSize, + }); + return { + current: data?.page_number, + data: data?.list, + pageSize: data?.page_size, + success: true, + total: data?.total_row || 0, + }; }} // dataSource={list} columns={columns} @@ -335,7 +474,14 @@ export default () => { // 表单处理 console.log('columns:', columns); console.log('values:', values); - + const success = await handleAddChapter({ + ...values, + subject_id: params?.id || 0, + }); + if(success){ + handleCreateModalVisible(false); + actionRef.current?.reloadAndRest?.(); + } }} submitter={{ render: (props, doms) => ( @@ -369,30 +515,18 @@ export default () => { > - - { - return Promise.resolve({ - success: true, - data: { id: '这是一段文本', object: '', date: '2020-07-30 08:00', duration: '', grade: 100, through: '>60', learn: '>20 min', times: 2 }, - }); - }} - extra={false} - > - - - - - - - - - - + + + 主题 {subjectIntro?.subject_name} 创建/修改完成成功 +
+ } + subTitle="点击提交将设置为发布状态。" + //extra={actions} + />
diff --git a/admin/src/pages/demo/index.tsx b/admin/src/pages/demo/index.tsx index 6ff7ac4..4f9fba5 100644 --- a/admin/src/pages/demo/index.tsx +++ b/admin/src/pages/demo/index.tsx @@ -1,5 +1,5 @@ import { DingdingOutlined, UploadOutlined } from '@ant-design/icons'; -import { Button, Card, Steps, Result, Descriptions, Modal, Input, Upload } from 'antd'; +import { Button, Card, Steps, Result, Descriptions, Modal, Input, Upload, Popconfirm } from 'antd'; import { Fragment, useRef, useState } from 'react'; import { GridContent } from '@ant-design/pro-layout'; @@ -100,6 +100,9 @@ export default () => { /> + +
Delete + ) }; diff --git a/admin/src/pages/examinationrules/normal/index.tsx b/admin/src/pages/examinationrules/normal/index.tsx index c0a4706..ce30577 100644 --- a/admin/src/pages/examinationrules/normal/index.tsx +++ b/admin/src/pages/examinationrules/normal/index.tsx @@ -41,7 +41,7 @@ const handleAdd = async (fields: TableListItem) => { * * @param fields */ - +/* const handleUpdate = async (fields: FormValueType, currentRow?: TableListItem) => { const hide = message.loading('正在配置'); @@ -59,6 +59,7 @@ const handleUpdate = async (fields: FormValueType, currentRow?: TableListItem) = return false; } }; +*/ /** * 删除考试 diff --git a/admin/src/pages/training/option/index.tsx b/admin/src/pages/training/option/index.tsx index a38fbe5..37bcda7 100644 --- a/admin/src/pages/training/option/index.tsx +++ b/admin/src/pages/training/option/index.tsx @@ -12,6 +12,7 @@ import UpdateForm from './components/UpdateForm'; import { queryTrainList, saveTrain, removeTrain, queryOrgTree, queryValueByKey } from './service'; import type { TableListItem, TableListPagination } from './data'; import { useRequest } from 'umi'; + /** * 添加培训 *