123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- import {
- NButton,
- NCascader,
- NForm,
- NFormItem,
- NInput,
- NScrollbar,
- NSelect,
- NSpace,
- useMessage
- } from 'naive-ui';
- import {
- TransitionGroup,
- defineComponent,
- onMounted,
- reactive,
- ref
- } from 'vue';
- import styles from './index.module.less';
- import UploadFile from '@/components/upload-file';
- import { nextTick } from 'vue';
- import { scrollToErrorForm } from '@/utils';
- import { api_lessonCoursewareSave } from '../../api';
- import iconUpload from '../../images/icon-upload.png';
- import iconUpload2 from '../../images/icon-upload2.png';
- import iconAdd from '../../images/icon-add.png';
- import iconMenu from '../../images/icon-menu.png';
- import btnAdd from '../../images/btn-add.png';
- import btnDelete from '../../images/btn-delete.png';
- import btnUp from '../../images/btn-up.png';
- import btnDown from '../../images/btn-down.png';
- import btnRemove from '../../images/btn-remove.png';
- import { lessonCoursewareDetail } from '/src/views/prepare-lessons/api';
- import { useCatchStore } from '/src/store/modules/catchData';
- export const BOOK_DATA = {
- grades: [
- { label: '一年级', value: 1 },
- { label: '二年级', value: 2 },
- { label: '三年级', value: 3 },
- { label: '四年级', value: 4 },
- { label: '五年级', value: 5 },
- { label: '六年级', value: 6 },
- { label: '七年级', value: 7 },
- { label: '八年级', value: 8 },
- { label: '九年级', value: 9 }
- ],
- bookTypes: [
- { label: '上册', value: 'LAST' },
- { label: '下册', value: 'NEXT' }
- ]
- };
- /** 添加单元 */
- const createLesson = () => {
- return {
- key: 'item' + Date.now(),
- name: '', // 单元名称
- lessonTargetDesc: '', // 课时目标描述
- knowledgeList: [
- {
- key: Date.now() + '' + 0,
- name: '' // 章节名称
- }
- ] // 章节信息
- };
- };
- const initState = () => ({
- id: null, // 教材id
- name: '',
- currentGradeNum: null as any,
- instrumentIds: null as any,
- // bookType: null, // 上下册
- coverImg: '', // 封面
- instruemntIds: [] as any,
- enableFlag: true, // 状态
- bookTypes: [], // 册别
- type: 'COURSEWARE', // 教材类型:COURSEWARE,THEORY,可用值:COURSEWARE,THEORY
- lessonList: [] as any // 单元列表
- });
- export default defineComponent({
- name: 'addNatural',
- props: {
- item: {
- type: Object,
- default: () => ({})
- }
- },
- emits: ['close', 'confirm'],
- setup(props, { emit }) {
- const catchStore = useCatchStore();
- const message = useMessage();
- const data = reactive({
- uploading: false,
- subjectList: [] as any
- });
- const formRef = ref();
- const form = reactive(initState());
- const handleSave = () => {
- formRef.value?.validate((err: any) => {
- if (err) {
- nextTick(scrollToErrorForm);
- return;
- }
- handleSubmit();
- });
- };
- const handleSubmit = async () => {
- data.uploading = true;
- try {
- const { currentGradeNum, bookTypes, instrumentIds, ...more } = form;
- await api_lessonCoursewareSave({
- currentGradeNum: currentGradeNum?.join(','),
- bookTypes: bookTypes?.join(','),
- instrumentIds: instrumentIds?.join(','),
- ...more
- });
- Object.assign(form, initState());
- message.success(props.item.id ? '保存成功' : '添加成功');
- emit('close', true);
- emit('confirm');
- } catch {
- //
- }
- data.uploading = false;
- };
- onMounted(async () => {
- if (!props.item.id) {
- form.lessonList = [createLesson()];
- }
- await catchStore.getSubjects();
- if (props.item.id) {
- // form.lessonList = [];
- const { data } = await lessonCoursewareDetail({ id: props.item.id });
- form.id = data.id;
- form.name = data.name;
- form.currentGradeNum = data.currentGradeNum
- ? data.currentGradeNum.split(',').map((item: any) => Number(item))
- : null;
- form.bookTypes = data.bookTypes ? data.bookTypes.split(',') : null
- form.instrumentIds = data.instrumentIds
- ? data.instrumentIds.split(',').map((item: any) => item)
- : null;
- // form.bookType = data.bookType;
- form.coverImg = data.coverImg;
- form.lessonList = [];
- const lessonList = data.lessonList || [];
- const tempLesson: any[] = [];
- lessonList.forEach((item: any) => {
- const tmpItem: any = {
- id: item.id,
- key: 'item' + Date.now() + '-' + Math.random() * 100,
- name: item.name,
- lessonTargetDesc: item.lessonTargetDesc,
- knowledgeList: [] as any
- };
- if (item.knowledgeList && item.knowledgeList.length) {
- item.knowledgeList.forEach((knowledge: any) => {
- tmpItem.knowledgeList.push({
- id: knowledge.id,
- key: Date.now() + '-' + Math.random() * 100,
- name: knowledge.name
- });
- });
- }
- tempLesson.push(tmpItem);
- });
- form.lessonList = tempLesson;
- }
- data.subjectList = catchStore.getEnableSingleAllSubjects(
- form.instrumentIds
- );
- });
- return () => (
- <div class={styles.container}>
- <NScrollbar style={{ 'max-height': '65vh' }}>
- <NForm
- ref={formRef}
- labelPlacement="left"
- labelWidth={120}
- model={form}>
- <div class={styles.topForms}>
- <NFormItem
- path="coverImg"
- rule={[
- {
- required: true,
- message: '请上传教材封面',
- trigger: ['change']
- }
- ]}>
- <UploadFile
- cropper
- // tips="建议尺寸:210*297, 文件大小: 5MB以内;"
- v-model:fileList={form.coverImg}
- showType="custom"
- size={2}
- accept=".jpg,jpeg,.png"
- options={{
- autoCropWidth: 210,
- autoCropHeight: 297,
- fixedBox: true
- }}>
- {{
- custom: () => (
- <div class={styles.uploadContent}>
- <img src={iconUpload2} class={styles.iconUpload} />
- <p>请上传教材封面</p>
- </div>
- )
- }}
- </UploadFile>
- </NFormItem>
- <div class={styles.topFormInput}>
- <NFormItem
- style={{ minWidth: '360px' }}
- path="name"
- rule={[
- {
- required: true,
- message: '请输入教材名称',
- trigger: ['blur', 'change']
- }
- ]}>
- <NInput
- placeholder="请输入教材名称"
- maxlength={25}
- v-model:value={form.name}
- clearable></NInput>
- </NFormItem>
- <NFormItem
- path="currentGradeNum"
- rule={{
- required: true,
- message: '请选择年级',
- trigger: 'change',
- type: 'array'
- }}>
- <NSelect
- style={{ minWidth: '360px' }}
- placeholder="请选择年级"
- options={BOOK_DATA.grades}
- v-model:value={form.currentGradeNum}
- clearable
- multiple
- filterable
- maxTagCount={3}
- />
- </NFormItem>
- <NFormItem
- path="bookTypes">
- <NSelect
- style={{ minWidth: '360px' }}
- placeholder="请选择册别(选填)"
- options={[{
- label: '上册',
- value: 'LAST'
- }, {
- label: '下册',
- value: 'NEXT'
- }]}
- v-model:value={form.bookTypes}
- clearable
- multiple
- filterable
- />
- </NFormItem>
- <NFormItem
- path="instrumentIds"
- style={{ width: '360px' }}
- rule={{
- required: true,
- message: '请选择乐器',
- trigger: 'change',
- type: 'array'
- }}>
- <NCascader
- placeholder="请选择乐器"
- options={data.subjectList}
- v-model:value={form.instrumentIds}
- checkStrategy="child"
- showPath={false}
- childrenField="instruments"
- expandTrigger="hover"
- labelField="name"
- valueField="id"
- clearable
- filterable
- multiple
- maxTagCount="responsive"
- style={{ width: '400px' }}
- />
- </NFormItem>
- {/* <NFormItem
- path="bookType"
- style={{ width: '360px' }}
- rule={{
- required: true,
- message: '请选择册别',
- trigger: 'change'
- }}>
- <NSelect
- placeholder="请选择册别"
- options={BOOK_DATA.bookTypes}
- v-model:value={form.bookType}
- clearable
- />
- </NFormItem> */}
- </div>
- </div>
- <div class={styles.menuTitle}>
- <img src={iconMenu} class={styles.iconMenu} />
- 目录
- </div>
- <TransitionGroup name="list" tag="div">
- {form.lessonList.map((item: any, index: number) => {
- return (
- <NSpace
- class={styles.lessonItem}
- wrap={false}
- wrapItem={false}
- align="start"
- key={item.key}>
- <NFormItem
- label="单元名称"
- labelPlacement="top"
- path={`lessonList[${index}].name`}
- rule={{
- required: true,
- message: '填写单元名称',
- trigger: ['blur', 'change']
- }}>
- <NInput
- placeholder="填写单元名称"
- maxlength={25}
- v-model:value={item.name}
- clearable></NInput>
- </NFormItem>
- <TransitionGroup name="list" tag="div">
- {item.knowledgeList.map((know: any, knowIndex: number) => {
- return (
- <NFormItem
- style={{
- '--n-label-height': knowIndex === 0 ? '26px' : '0'
- }}
- labelPlacement="top"
- label={knowIndex === 0 ? '章节名称' : ''}
- key={know.key}
- path={`lessonList[${index}].knowledgeList[${knowIndex}].name`}
- rule={{
- required: true,
- message: '填写章节名称',
- trigger: ['blur', 'change']
- }}>
- <NSpace
- wrap={false}
- align="center"
- class={styles.btnGroupAll}
- wrapItem={false}>
- <NInput
- maxlength={25}
- placeholder="填写章节名称"
- v-model:value={know.name}
- clearable></NInput>
- <NButton
- quaternary
- circle
- onClick={() => {
- item.knowledgeList.splice(knowIndex + 1, 0, {
- name: '',
- key: Date.now() + '' + knowIndex
- });
- }}>
- {{
- icon: () => (
- <img src={btnAdd} class={styles.btnImg} />
- )
- }}
- </NButton>
- <NButton
- quaternary
- circle
- disabled={item.knowledgeList.length < 2}
- onClick={() => {
- item.knowledgeList.splice(knowIndex, 1);
- }}>
- {{
- icon: () => (
- <img
- src={btnDelete}
- class={styles.btnImg}
- />
- )
- }}
- </NButton>
- <NButton
- quaternary
- circle
- disabled={knowIndex === 0}
- onClick={() => {
- if (knowIndex === 0) return;
- const tmp = item.knowledgeList[knowIndex - 1];
- item.knowledgeList[knowIndex - 1] =
- item.knowledgeList[knowIndex];
- item.knowledgeList[knowIndex] = tmp;
- }}>
- {{
- icon: () => (
- <img src={btnUp} class={styles.btnImg} />
- )
- }}
- </NButton>
- <NButton
- quaternary
- circle
- disabled={
- knowIndex === item.knowledgeList.length - 1
- }
- onClick={() => {
- if (
- knowIndex ===
- item.knowledgeList.length - 1
- )
- return;
- const tmp = item.knowledgeList[knowIndex + 1];
- item.knowledgeList[knowIndex + 1] =
- item.knowledgeList[knowIndex];
- item.knowledgeList[knowIndex] = tmp;
- }}>
- {{
- icon: () => (
- <img src={btnDown} class={styles.btnImg} />
- )
- }}
- </NButton>
- </NSpace>
- </NFormItem>
- );
- })}
- </TransitionGroup>
- <NButton
- class={styles.closeBtn}
- secondary
- circle
- size="small"
- disabled={form.lessonList.length < 2}
- onClick={() => {
- form.lessonList.splice(index, 1);
- }}>
- <img src={btnRemove} />
- </NButton>
- </NSpace>
- );
- })}
- </TransitionGroup>
- <div class={styles.line}></div>
- <NButton
- block
- class={styles.addUnitBtn}
- ghost
- color="#198CFE"
- onClick={() => {
- form.lessonList.push(createLesson());
- }}>
- {{
- icon: () => <img src={iconAdd} />,
- default: () => '新增单元'
- }}
- </NButton>
- </NForm>
- </NScrollbar>
- <NSpace class={styles.btnGroup} justify="center">
- <NButton round onClick={() => emit('close')}>
- 取消
- </NButton>
- <NButton
- round
- loading={data.uploading}
- type="primary"
- onClick={() => handleSave()}>
- 保存
- </NButton>
- </NSpace>
- </div>
- );
- }
- });
|