Browse Source

课件从管乐团代码同步

yuanliang 1 year ago
parent
commit
bd28db8f75

+ 46 - 4
src/views/educational-manage/component/material-list.tsx

@@ -111,6 +111,15 @@ export default defineComponent({
             )
           }
         },
+        // {
+        //   title: '编号',
+        //   key: 'id'
+        // },
+
+        // {
+        //   title: '素材分类',
+        //   key: 'materialCategoryName'
+        // }, 分段编号
         {
           title: '素材信息',
           key: 'sn',
@@ -141,21 +150,48 @@ export default defineComponent({
             )
           }
         },
+        // {
+        //   title: '课程类型',
+        //   key: 'courseTypeName',
+        //   width: 200,
+        //   ellipsis: true,
+        //   render(row: InternalRowData) {
+        //     return (
+        //       <NTooltip placement="top-start">
+        //         {{
+        //           default: () => row.courseTypeName,
+        //           trigger: () => row.courseTypeName
+        //         }}
+        //       </NTooltip>
+        //     )
+        //   }
+        // },
+        // {
+        //   title: '建议学习时长',
+        //   key: 'adviseStudyTimeSecond',
+        //   render(row: InternalRowData) {
+        //     return row.adviseStudyTimeSecond ? row.adviseStudyTimeSecond + '秒' : ''
+        //   }
+        // },
         {
           title: '操作信息',
-          key: 'updateTime',
+          key: 'createTime',
           render(row: any) {
             return (
               <NDescriptions labelPlacement="left" column={1}>
                 <NDescriptionsItem label="上传人">{row.operatorName}</NDescriptionsItem>
 
                 <NDescriptionsItem label="上传时间">
-                  {row.updateTime ? row.updateTime : '--'}
+                  {row.createTime ? row.createTime : '--'}
                 </NDescriptionsItem>
               </NDescriptions>
             )
           }
         },
+        // {
+        //   title: '上传人',
+        //   key: 'operatorName'
+        // },
         {
           title: '状态',
           key: 'delFlag',
@@ -178,10 +214,17 @@ export default defineComponent({
           render(row: any) {
             return (
               <NSpace>
+                {/* <NButton
+                  type={row.enableFlag ? 'error' : 'success'}
+                  text
+                  v-auth="material/update1599948375910109186"
+                  onClick={() => handleChange(row)}
+                >
+                  {row.enableFlag ? '停用' : '启用'}
+                </NButton> */}
                 <NButton
                   type="primary"
                   text
-                  v-auth="material/detail1608362411857137665"
                   onClick={() => {
                     state.isLook = true
                     state.materail = row
@@ -285,7 +328,6 @@ export default defineComponent({
     }
 
     onMounted(() => {
-      state.pagination.page = 1
       getList()
     })
 

+ 11 - 6
src/views/educational-manage/model/selectMusicSheet.tsx

@@ -1,7 +1,7 @@
 import Pagination from '@/components/pagination'
 import SaveForm from '@/components/save-form'
 import { musicSheetPage, musicTagPage } from '@/views/content-manage/api'
-import { subjectBasicConfigPage } from '@/views/system-manage/api'
+import {subjectPage} from '@/views/system-manage/api'
 import { NButton, NImage, NSpace, NTag, NDataTable, NFormItem, NInput, NSelect } from 'naive-ui'
 import { defineComponent, onMounted, reactive, ref } from 'vue'
 import { accompanimentTypeArray, audioTypeArray } from '@/utils/searchArray'
@@ -53,7 +53,7 @@ export default defineComponent({
         },
         {
           title: '分类',
-          key: 'musicSheetCategoriesName',
+          key: 'musicSheetCategoriesName'
         },
         {
           title: '伴奏类型',
@@ -113,7 +113,12 @@ export default defineComponent({
     const getList = async () => {
       try {
         state.loading = true
-        const { data } = await musicSheetPage({ page: state.pagination.page, rows: state.pagination.rows, ...state.searchForm,status: 1 })
+        const { data } = await musicSheetPage({
+          page: state.pagination.page,
+          rows: state.pagination.rows,
+          ...state.searchForm,
+          status: 1
+        })
         state.loading = false
         state.pagination.pageTotal = Number(data.total)
         state.dataList = data.rows || []
@@ -138,11 +143,11 @@ export default defineComponent({
     // 获取声部
     const getSubjectList = async () => {
       try {
-        const { data } = await subjectBasicConfigPage({ page: 1, rows: 999 })
+        const { data } = await subjectPage({ page: 1, rows: 999 })
         const tempList = data.rows || []
         tempList.forEach((item: any) => {
-          item.label = item.subjectName
-          item.value = item.subjectId
+          item.label = item.name
+          item.value = item.id + ''
         })
         state.subjectList = tempList
       } catch {}

+ 9 - 1
src/views/knowledge-manage/knowledge-detail/index.tsx

@@ -59,6 +59,7 @@ export default defineComponent({
           render(row: any) {
             return (
               <TheLink
+                authLink="material/page1599589713102299138"
                 to={{ path: '/educationalManage/educationalManage', query: { id: row.materialId } }}
               >
                 {row.materialName}
@@ -74,7 +75,14 @@ export default defineComponent({
           title: '分段编号',
           key: 'sn',
           render(row: any) {
-            return <TheLink to={{ path: '/educationalManage/educationalManage' }}>{row.sn}</TheLink>
+            return (
+              <TheLink
+                authLink="material/page1599589713102299138"
+                to={{ path: '/educationalManage/educationalManage' }}
+              >
+                {row.sn}
+              </TheLink>
+            )
           }
         },
         {

+ 1 - 0
src/views/teaching-manage/after-class-training-detail/index.tsx

@@ -66,6 +66,7 @@ export default defineComponent({
           render(row: any) {
             return (
               <TheLink
+                authLink="material/page1599589713102299138"
                 to={{ path: '/educationalManage/educationalManage', query: { id: row.materialId } }}
               >
                 {row.materialName}

+ 16 - 7
src/views/teaching-manage/after-class-training-detail/model/addMaterialTrainingClass.tsx

@@ -182,7 +182,16 @@ export default defineComponent({
         const { data } = await lessonTrainingDetailMaterialPage(tranbody)
         state.loading = false
         state.pagination.pageTotal = Number(data.total)
-        state.dataList = data.rows || []
+        // state.dataList = data.rows || []
+        const tempRows = data.rows || []
+        tempRows.forEach((row: any) => {
+          row.tempIndex = new Date().getTime() + '' + Math.random()
+          // state.dataList.push({
+          //   ...row
+          // })
+        })
+        console.log(tempRows, 'rows')
+        state.dataList = tempRows
       } catch {
         state.loading = false
       }
@@ -200,9 +209,9 @@ export default defineComponent({
     const handleSave = async () => {
       state.saveLoading = true
       const list = state.checkList.map((n: any) => {
-        const item = state.selectCheckList.find((item: any) => item.materialId === n)
+        const item = state.selectCheckList.find((item: any) => item.tempIndex === n)
         return {
-          materialId: n,
+          materialId: item.materialId,
           knowledgePointId: item.knowledgePointId,
           lessonTrainingId: props.parentData.id
         }
@@ -294,7 +303,7 @@ export default defineComponent({
         <NDataTable
           loading={state.loading}
           maxHeight="calc(100vh - 270px)"
-          rowKey={(row: any) => row.materialId}
+          rowKey={(row: any) => row.tempIndex}
           columns={columns()}
           data={state.dataList}
           v-model:checkedRowKeys={state.checkList}
@@ -303,15 +312,15 @@ export default defineComponent({
             // 处理删除的数据
             const tempList: any = []
             state.selectCheckList.forEach((item: any) => {
-              if (state.checkList.includes(item.materialId)) {
+              if (state.checkList.includes(item.tempIndex)) {
                 tempList.push(item)
               }
             })
 
             // 添加新增的数据
             state.checkList.forEach((key: string) => {
-              const item = state.dataList.find((item: any) => item.materialId === key)
-              const index = state.selectCheckList.findIndex((item: any) => item.materialId === key)
+              const item = state.dataList.find((item: any) => item.tempIndex === key)
+              const index = state.selectCheckList.findIndex((item: any) => item.tempIndex === key)
               if (index <= -1) {
                 tempList.push(item)
               }

+ 3 - 1
src/views/teaching-manage/after-class-training-detail/model/addTrainStandard.tsx

@@ -16,6 +16,7 @@ import {
 } from 'naive-ui'
 import { defineComponent, reactive } from 'vue'
 import { lessonTrainingDetailBatchInsert, lessonTrainingDetailTempBatchUpSet } from '../../api'
+import ColVideo from '@/components/col-video'
 
 export default defineComponent({
   name: 'addTrainStandard',
@@ -166,7 +167,8 @@ export default defineComponent({
         <div>{props.item?.materialName}</div>
         {props.item?.type == 'VIDEO' && (
           <div>
-            <video style={{ width: '100%' }} src={props.item.content} controls></video>
+            {/* <video style={{ width: '100%' }} src={props.item.content} controls></video> */}
+            <ColVideo styleValue={{ width: '100%', height: '375px' }} src={props.item.content} />
 
             {state.list.map((item: any) => {
               return (

+ 11 - 0
src/views/teaching-manage/api.ts

@@ -587,3 +587,14 @@ export const lessonCoursewareDetailLock = (data: any) => {
     method: 'post'
   } as any)
 }
+
+/**
+ * 课件导入,单元测验导入,课后训练导入
+ */
+export const api_openFileImportInfoSave = (data: any) => {
+  return request({
+    url: `/api-backend/open/fileImportInfo/save`,
+    method: 'post',
+    data
+  } as any)
+}

+ 354 - 187
src/views/teaching-manage/courseware-manage/components/courseConfiguration.tsx

@@ -5,6 +5,7 @@ import {
   NDialog,
   NDrawer,
   NDrawerContent,
+  NDropdown,
   NEmpty,
   NForm,
   NFormItem,
@@ -15,7 +16,10 @@ import {
   NModal,
   NSelect,
   NSpace,
+  NSpin,
   NTooltip,
+  NUpload,
+  UploadCustomRequestOptions,
   useDialog,
   useMessage
 } from 'naive-ui'
@@ -28,7 +32,8 @@ import {
   lessonTrainingPage,
   lessonCoursewareDetailRemove,
   lessonCoursewareExaminationMapperQueryAll,
-  lessonCoursewareDetailLock
+  lessonCoursewareDetailLock,
+  api_openFileImportInfoSave
 } from '../../api'
 import styles from '../index.module.less'
 import { EditFilled, DeleteFilled, LockFilled, UnlockFilled } from '@vicons/antd'
@@ -36,6 +41,7 @@ import CourseKnowledgePoint from '../model/CourseKnowledgePoint'
 import SelectAfterClassTraining from '../model/selectAfterClassTraining'
 import AddUnitTest from '../model/AddUnitTest'
 import TheLink from '@/components/TheLink'
+import { api_uploadFile } from '@/plugins/uploadFile'
 
 export default defineComponent({
   name: 'courseConfiguration',
@@ -56,7 +62,8 @@ export default defineComponent({
       name: '', //课时名称
       lessonTargetDesc: '', //课时名称
       lessonTrainingId: '', //课后作业
-      lockEnable: 'true'
+      lockEnable: 'true',
+      accessScope: 0
     })
     // 课件添加课程
     const addCourseware = () => {
@@ -66,7 +73,8 @@ export default defineComponent({
             lessonCoursewareId: route.query.id,
             name: addForm.name,
             lessonTargetDesc: addForm.lessonTargetDesc,
-            lockEnable: addForm.lockEnable
+            lockEnable: addForm.lockEnable,
+            accessScope: addForm.accessScope
           }
           let res: any
           if (addForm.id) {
@@ -194,235 +202,364 @@ export default defineComponent({
         }
       })
     }
+
+    const customRequest_importData = reactive({
+      loading: false,
+      dataType: 'EXAMINATION',
+      importRef: null as any
+    })
+    const customRequest_importFile = async (data: UploadCustomRequestOptions) => {
+      console.log(data.file)
+      const msg = message.loading('正在上传文件', { duration: 0 })
+      customRequest_importData.loading = true
+      const fileUrl = await api_uploadFile(data.file.file, () => {})
+      const res = await api_openFileImportInfoSave({
+        dataType: customRequest_importData.dataType,
+        fileName: data.file.name,
+        importUrl: fileUrl,
+        lessonId: route.query.id
+      })
+      console.log('🚀 ~ res:', res)
+      customRequest_importData.loading = false
+      if (res.data) {
+        msg.destroy()
+        // 空表格
+        if (res.data.insertRow === 0 && res.data.invalidRow === 0) {
+          message.error('导入失败,表格为空')
+          return
+        }
+        if (res.data.respUrl) {
+          dialog.error({
+            title: '信息',
+            content: () => (
+              <NSpace>
+                <div>导入失败,点击下载错误信息</div>
+                <a href={res.data.respUrl} download>
+                  下载
+                </a>
+              </NSpace>
+            )
+          })
+          return
+        }
+        getDetail()
+        message.success('导入成功')
+      } else {
+        message.error('请下载模板后,填写数据再导入')
+      }
+    }
     return () => (
       <div class={styles.courseConfiguration}>
-        <NSpace>
-          <NButton
-            disabled={route.query.isLook ? true : false}
-            type="primary"
-            onClick={() => {
-              addForm.name = ''
-              addForm.lessonTargetDesc = ''
-              addForm.lessonTrainingId = ''
-              addForm.id = ''
-              addForm.lockEnable = ''
-              addForm.open = true
-            }}
-          >
-            添加课程
-          </NButton>
-          <NButton
-            type="primary"
-            disabled={route.query.isLook ? true : false}
-            onClick={() => {
-              unitData.open = true
-              unitData.model = {}
-            }}
-          >
-            添加阶段自测
-          </NButton>
-        </NSpace>
-        <NAlert class={styles.title} title="教学内容" />
-        <NGrid xGap={12} yGap={8} cols={3}>
-          {state.dataList.map((item: any) => {
-            const mapper = state.mapperList.find((n: any) => n.parentCoursewareDetailId == item.id)
-            return (
-              <>
-                <NGi>
-                  <NCard
-                    title={item.name}
-                    style={{
-                      '--n-padding-top': '5px',
-                      '--n-padding-bottom': '5px',
-                      height: '100%'
+        <NSpin show={customRequest_importData.loading}>
+          <NSpace justify="space-between">
+            <NSpace>
+              <NButton
+                disabled={route.query.isLook ? true : false}
+                type="primary"
+                onClick={() => {
+                  addForm.name = ''
+                  addForm.lessonTargetDesc = ''
+                  addForm.lessonTrainingId = ''
+                  addForm.id = ''
+                  addForm.lockEnable = ''
+                  addForm.accessScope = 0
+                  addForm.open = true
+                }}
+              >
+                添加课程
+              </NButton>
+              <NButton
+                type="primary"
+                disabled={route.query.isLook ? true : false}
+                onClick={() => {
+                  unitData.open = true
+                  unitData.model = {}
+                }}
+              >
+                添加阶段自测
+              </NButton>
+            </NSpace>
+            <NSpace style={{ marginLeft: 'auto' }}>
+              <NDropdown
+                size="huge"
+                trigger="hover"
+                options={[
+                  {
+                    key: '3',
+                    type: 'render',
+                    render: () => (
+                      <NButton
+                        size="large"
+                        quaternary
+                        tag="a"
+                        //@ts-ignore
+                        href="https://oss.dayaedu.com/daya-docs/%E5%8D%95%E5%85%83%E6%B5%8B%E9%AA%8C%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx"
+                        download
+                      >
+                        单元测验模板
+                      </NButton>
+                    )
+                  },
+                  {
+                    key: '1',
+                    type: 'render',
+                    render: () => (
+                      <NButton
+                        v-auth="downloadAfter-schoolTraining1702252098317451265"
+                        size="large"
+                        quaternary
+                        tag="a"
+                        //@ts-ignore
+                        href="https://oss.dayaedu.com/daya-docs/%E8%AF%BE%E5%90%8E%E8%AE%AD%E7%BB%83%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx"
+                        download
+                      >
+                        课后训练模板
+                      </NButton>
+                    )
+                  }
+                ]}
+              >
+                <NButton type="primary" v-auth="downloadUnitQuiz1702251742292344833">
+                  下载模板
+                </NButton>
+              </NDropdown>
+              <div v-auth="importCourseDate1702252535879827458">
+                <NUpload
+                  multiple={false}
+                  ref={(el: any) => (customRequest_importData.importRef = el)}
+                  showFileList={false}
+                  accept=".xlsx"
+                  customRequest={customRequest_importFile}
+                >
+                  <NDropdown
+                    size="huge"
+                    trigger="hover"
+                    options={[
+                      { label: '课件', key: 'COURSEWARE' },
+                      { label: '单元测验', key: 'EXAMINATION' },
+                      { label: '课后训练', key: 'HOMEWORK' }
+                    ]}
+                    onSelect={(key: string) => {
+                      customRequest_importData.dataType = key
+                      console.log(customRequest_importData.importRef)
+                      customRequest_importData.importRef?.clear()
+                      customRequest_importData.importRef?.openOpenFileDialog()
                     }}
                   >
-                    {{
-                      default: () => (
-                        <div>
-                          <div style={{ paddingBottom: '12px' }}>{item.lessonTargetDesc}</div>
-                          <table style={{ width: '100%' }}>
-                            <tr>
-                              <td>建议学习时长</td>
-                              <td style={{ 'text-align': 'right' }}>
-                                {item.lessonDurationSecond || '0'}s
-                              </td>
-                            </tr>
-                            <tr>
-                              <td>知识点</td>
-                              <td style={{ 'text-align': 'right' }}>
-                                {item.knowledgePointIds?.split(',').filter(Boolean).length || 0}个
-                              </td>
-                            </tr>
-                            <tr>
-                              <td>课后作业</td>
-                              <td style={{ 'text-align': 'right' }}>
-                                {item.lessonTrainingId ? (
-                                  <TheLink
-                                    // to={`/#/afterClassTrainingDetail?id=${item.lessonTrainingId}&name=${item.lessonTrainingName}&courseTypeCode=TRUMPET_SINGLE`}
-                                    to={{
-                                      path: '/afterClassTrainingManage',
-                                      query: { id: item.lessonTrainingId }
-                                    }}
-                                  >
-                                    {item.lessonTrainingName}
-                                  </TheLink>
-                                ) : (
-                                  '无'
-                                )}
-                              </td>
-                            </tr>
-                          </table>
-                        </div>
-                      ),
-                      'header-extra': () => (
-                        <>
-                          <NTooltip>
-                            {{
-                              default: () => (item.lockFlag ? '解锁' : '锁定'),
-                              trigger: () => (
-                                <NButton
-                                  disabled={route.query.isLook ? true : false}
-                                  quaternary
-                                  circle
-                                  onClick={() => toggleLock(item)}
-                                >
-                                  <NIcon
-                                    component={item.lockFlag ? <LockFilled /> : <UnlockFilled />}
-                                  />
-                                </NButton>
-                              )
-                            }}
-                          </NTooltip>
-
-                          <NTooltip>
-                            {{
-                              default: () => '编辑',
-                              trigger: () => (
-                                <NButton
-                                  disabled={route.query.isLook ? true : false}
-                                  quaternary
-                                  circle
-                                  onClick={() => {
-                                    addForm.name = item.name
-                                    addForm.lessonTargetDesc = item.lessonTargetDesc
-                                    addForm.id = item.id
-                                    addForm.lockEnable = item.lockEnable + ''
-                                    addForm.open = true
-                                  }}
-                                >
-                                  <NIcon component={<EditFilled />} />
-                                </NButton>
-                              )
-                            }}
-                          </NTooltip>
-                          <NTooltip>
-                            {{
-                              default: () => '删除',
-                              trigger: () => (
-                                <NButton
-                                  disabled={route.query.isLook ? true : false}
-                                  quaternary
-                                  circle
-                                  onClick={() => hanldeDelete(item)}
-                                >
-                                  <NIcon component={<DeleteFilled />} />
-                                </NButton>
-                              )
-                            }}
-                          </NTooltip>
-                        </>
-                      ),
-                      action: () => (
-                        <NSpace justify="space-around">
-                          <NButton
-                            text
-                            disabled={route.query.isLook ? true : false}
-                            onClick={() => {
-                              courseData.title = item.name
-                              courseData.open = true
-                              courseData.item = item
-                            }}
-                          >
-                            选择知识点
-                          </NButton>
-                          <NButton
-                            text
-                            disabled={route.query.isLook ? true : false}
-                            onClick={() => {
-                              addForm.id = item.id
-                              addForm.lessonTargetDesc = item.lessonTargetDesc
-                              addForm.name = item.name
-                              afterTrain.open = true
-                            }}
-                          >
-                            选择课后作业
-                          </NButton>
-                        </NSpace>
-                      )
-                    }}
-                  </NCard>
-                </NGi>
-                {mapper && (
+                    <NButton type="primary" onClick={(e: Event) => e.stopPropagation()}>
+                      导入数据
+                    </NButton>
+                  </NDropdown>
+                </NUpload>
+              </div>
+            </NSpace>
+          </NSpace>
+          <NAlert class={styles.title} title="教学内容" />
+          <NGrid xGap={12} yGap={8} cols={3}>
+            {state.dataList.map((item: any) => {
+              const mapper = state.mapperList.find(
+                (n: any) => n.parentCoursewareDetailId == item.id
+              )
+              return (
+                <>
                   <NGi>
                     <NCard
-                      title={mapper.name}
+                      title={item.name}
                       style={{
                         '--n-padding-top': '5px',
                         '--n-padding-bottom': '5px',
-                        '--n-color': 'rgba(238,243,254,1)',
-                        '--n-action-color': 'rgba(238,243,254,1)',
                         height: '100%'
                       }}
                     >
                       {{
                         default: () => (
                           <div>
-                            <div style={{ paddingBottom: '12px' }}>{mapper.desc}</div>
+                            <div style={{ paddingBottom: '12px' }}>{item.lessonTargetDesc}</div>
                             <table style={{ width: '100%' }}>
                               <tr>
-                                <td>单团学生</td>
+                                <td>建议学习时长</td>
                                 <td style={{ 'text-align': 'right' }}>
-                                  {mapper?.details?.[0]?.unitExaminationName || '无'}
+                                  {item.lessonDurationSecond || '0'}s
                                 </td>
                               </tr>
                               <tr>
-                                <td>双团学生</td>
+                                <td>知识点</td>
                                 <td style={{ 'text-align': 'right' }}>
-                                  {mapper?.details?.[1]?.unitExaminationName || '无'}
+                                  {item.knowledgePointIds?.split(',').filter(Boolean).length || 0}个
                                 </td>
                               </tr>
                               <tr>
-                                <td>多团学生</td>
+                                <td>课后作业</td>
                                 <td style={{ 'text-align': 'right' }}>
-                                  {mapper?.details?.[2]?.unitExaminationName || '无'}
+                                  {item.lessonTrainingId ? (
+                                    <TheLink
+                                      // to={`/#/afterClassTrainingDetail?id=${item.lessonTrainingId}&name=${item.lessonTrainingName}&courseTypeCode=TRUMPET_SINGLE`}
+                                      authLink="afterClassTrainingManage1599968711187746818"
+                                      to={{
+                                        path: '/afterClassTrainingManage',
+                                        query: { id: item.lessonTrainingId }
+                                      }}
+                                    >
+                                      {item.lessonTrainingName}
+                                    </TheLink>
+                                  ) : (
+                                    '无'
+                                  )}
                                 </td>
                               </tr>
                             </table>
                           </div>
                         ),
+                        'header-extra': () => (
+                          <>
+                            <NTooltip>
+                              {{
+                                default: () => (item.lockFlag ? '解锁' : '锁定'),
+                                trigger: () => (
+                                  <NButton
+                                    disabled={route.query.isLook ? true : false}
+                                    quaternary
+                                    circle
+                                    onClick={() => toggleLock(item)}
+                                  >
+                                    <NIcon
+                                      component={item.lockFlag ? <LockFilled /> : <UnlockFilled />}
+                                    />
+                                  </NButton>
+                                )
+                              }}
+                            </NTooltip>
+
+                            <NTooltip>
+                              {{
+                                default: () => '编辑',
+                                trigger: () => (
+                                  <NButton
+                                    disabled={route.query.isLook ? true : false}
+                                    quaternary
+                                    circle
+                                    onClick={() => {
+                                      addForm.name = item.name
+                                      addForm.lessonTargetDesc = item.lessonTargetDesc
+                                      addForm.id = item.id
+                                      addForm.lockEnable = item.lockEnable + ''
+                                      addForm.accessScope = item.accessScope ?? 0
+                                      addForm.open = true
+                                    }}
+                                  >
+                                    <NIcon component={<EditFilled />} />
+                                  </NButton>
+                                )
+                              }}
+                            </NTooltip>
+                            <NTooltip>
+                              {{
+                                default: () => '删除',
+                                trigger: () => (
+                                  <NButton
+                                    disabled={route.query.isLook ? true : false}
+                                    quaternary
+                                    circle
+                                    onClick={() => hanldeDelete(item)}
+                                  >
+                                    <NIcon component={<DeleteFilled />} />
+                                  </NButton>
+                                )
+                              }}
+                            </NTooltip>
+                          </>
+                        ),
                         action: () => (
                           <NSpace justify="space-around">
                             <NButton
                               text
                               disabled={route.query.isLook ? true : false}
                               onClick={() => {
-                                unitData.open = true
-                                unitData.model = mapper
+                                courseData.title = item.name
+                                courseData.open = true
+                                courseData.item = item
                               }}
                             >
-                              编辑阶段自测
+                              选择知识点
+                            </NButton>
+                            <NButton
+                              text
+                              disabled={route.query.isLook ? true : false}
+                              onClick={() => {
+                                addForm.id = item.id
+                                addForm.lessonTargetDesc = item.lessonTargetDesc
+                                addForm.name = item.name
+                                afterTrain.open = true
+                              }}
+                            >
+                              选择课后作业
                             </NButton>
                           </NSpace>
                         )
                       }}
                     </NCard>
                   </NGi>
-                )}
-              </>
-            )
-          })}
-        </NGrid>
+                  {mapper && (
+                    <NGi>
+                      <NCard
+                        title={mapper.name}
+                        style={{
+                          '--n-padding-top': '5px',
+                          '--n-padding-bottom': '5px',
+                          '--n-color': 'rgba(238,243,254,1)',
+                          '--n-action-color': 'rgba(238,243,254,1)',
+                          height: '100%'
+                        }}
+                      >
+                        {{
+                          default: () => (
+                            <div>
+                              <div style={{ paddingBottom: '12px' }}>{mapper.desc}</div>
+                              <table style={{ width: '100%' }}>
+                                <tr>
+                                  <td>单团学生</td>
+                                  <td style={{ 'text-align': 'right' }}>
+                                    {mapper?.details?.[0]?.unitExaminationName || '无'}
+                                  </td>
+                                </tr>
+                                <tr>
+                                  <td>双团学生</td>
+                                  <td style={{ 'text-align': 'right' }}>
+                                    {mapper?.details?.[1]?.unitExaminationName || '无'}
+                                  </td>
+                                </tr>
+                                <tr>
+                                  <td>多团学生</td>
+                                  <td style={{ 'text-align': 'right' }}>
+                                    {mapper?.details?.[2]?.unitExaminationName || '无'}
+                                  </td>
+                                </tr>
+                              </table>
+                            </div>
+                          ),
+                          action: () => (
+                            <NSpace justify="space-around">
+                              <NButton
+                                text
+                                disabled={route.query.isLook ? true : false}
+                                onClick={() => {
+                                  unitData.open = true
+                                  unitData.model = mapper
+                                }}
+                              >
+                                编辑阶段自测
+                              </NButton>
+                            </NSpace>
+                          )
+                        }}
+                      </NCard>
+                    </NGi>
+                  )}
+                </>
+              )
+            })}
+          </NGrid>
+        </NSpin>
         {state.dataList.length ? null : <NEmpty />}
 
         {/* 课程编辑 */}
@@ -465,6 +602,36 @@ export default defineComponent({
               ></NSelect>
             </NFormItem>
             <NFormItem
+              label="是否免费"
+              required
+              path="accessScope"
+              rule={[
+                {
+                  type: 'number',
+                  required: true,
+                  message: '设置是否免费',
+                  trigger: ['blur', 'change']
+                }
+              ]}
+            >
+              <NSelect
+                v-model:value={addForm.accessScope}
+                options={
+                  [
+                    {
+                      label: '是',
+                      value: 0
+                    },
+                    {
+                      label: '否',
+                      value: 1
+                    }
+                  ] as any
+                }
+                clearable
+              ></NSelect>
+            </NFormItem>
+            <NFormItem
               label="教学目标"
               required
               path="lessonTargetDesc"

+ 163 - 88
src/views/teaching-manage/courseware-manage/index.tsx

@@ -12,6 +12,9 @@ import {
   NInput,
   NSelect,
   NSpace,
+  NSpin,
+  NUpload,
+  UploadCustomRequestOptions,
   useDialog,
   useMessage
 } from 'naive-ui'
@@ -20,13 +23,15 @@ import dayjs from 'dayjs'
 import {
   lessonCoursewarePage,
   lessonCoursewareUpdateEnableFlag,
-  lessonCoursewareDelete
+  lessonCoursewareDelete,
+  api_openFileImportInfoSave
 } from '../api'
 import { InternalRowData } from 'naive-ui/es/data-table/src/interface'
 import { useRouter } from 'vue-router'
 import { knowledgeTypeData, lessonType } from '@/views/knowledge-manage/knowledgeTypeData'
 import { orchestraTypes } from '../teachingData'
 import { sysEmployeePage } from '@/views/system-manage/api'
+import { api_uploadFile } from '@/plugins/uploadFile'
 
 export default defineComponent({
   name: 'courseware-manage',
@@ -334,99 +339,169 @@ export default defineComponent({
       saveForm.value?.reset()
     }
 
+    const customRequest_importData = reactive({
+      loading: false,
+      importRef: null as any
+    })
+    const customRequest_importFile = async (data: UploadCustomRequestOptions) => {
+      console.log(data.file)
+      customRequest_importData.loading = true
+      const fileUrl = await api_uploadFile(data.file.file, () => {})
+      const res = await api_openFileImportInfoSave({
+        dataType: 'COURSEWARE',
+        fileName: data.file.name,
+        importUrl: fileUrl
+      })
+      console.log('🚀 ~ res:', res)
+      customRequest_importData.loading = false
+      if (res.data) {
+        // 空表格
+        if (res.data.insertRow === 0 && res.data.invalidRow === 0) {
+          message.error('导入失败,表格为空')
+          return
+        }
+        if (res.data.respUrl) {
+          dialog.error({
+            title: '信息',
+            content: () => (
+              <NSpace>
+                <div>导入失败,点击下载错误信息</div>
+                <a href={res.data.respUrl} download>
+                  下载
+                </a>
+              </NSpace>
+            )
+          })
+          return
+        }
+        message.success('导入成功')
+      }
+    }
+
     return () => (
       <div class="system-menu-container">
-        <div class={['section-container']}>
-          <SaveForm
-            ref={saveForm}
-            model={searchForm}
-            onSubmit={onSubmit}
-            onSetModel={(val: any) => Object.assign(searchForm, val)}
-            saveKey="courseware-manage-ad-key"
-          >
-            <NFormItem path="keyword" label="关键字">
-              <NInput
-                v-model:value={searchForm.keyword}
-                placeholder="请输入课件名称/编号"
-                clearable
-              />
-            </NFormItem>
-            <NFormItem path="courseTypeCode" label="课程类型">
-              <NSelect
-                placeholder="请选择课程类型"
-                clearable
-                v-model:value={searchForm.courseTypeCode}
-                options={lessonType}
-              />
-            </NFormItem>
-            <NFormItem path="enableFlag" label="是否启用">
-              <NSelect
-                placeholder="是否启用"
-                clearable
-                v-model:value={searchForm.enableFlag}
-                options={[
-                  { label: '是', value: 1 },
-                  { label: '否', value: 0 }
-                ]}
-              />
-            </NFormItem>
-            <NFormItem path="orchestraType" label="乐团类型">
-              <NSelect
-                placeholder="请输入乐团类型"
-                clearable
-                v-model:value={searchForm.orchestraType}
-                options={state.orchestraTypeList}
-              />
-            </NFormItem>
-            <NFormItem path="operatorId" label="更新人">
-              <NSelect
-                placeholder="请输入更新人"
-                clearable
-                v-model:value={searchForm.operatorId}
-                options={state.staffList}
-                filterable
-              />
-            </NFormItem>
-            <NFormItem>
+        <NSpin show={customRequest_importData.loading}>
+          <div class={['section-container']}>
+            <SaveForm
+              ref={saveForm}
+              model={searchForm}
+              onSubmit={onSubmit}
+              onSetModel={(val: any) => Object.assign(searchForm, val)}
+              saveKey="courseware-manage-ad-key"
+            >
+              <NFormItem path="keyword" label="关键字">
+                <NInput
+                  v-model:value={searchForm.keyword}
+                  placeholder="请输入课件名称/编号"
+                  clearable
+                />
+              </NFormItem>
+              <NFormItem path="courseTypeCode" label="课程类型">
+                <NSelect
+                  placeholder="请选择课程类型"
+                  clearable
+                  v-model:value={searchForm.courseTypeCode}
+                  options={lessonType}
+                />
+              </NFormItem>
+              <NFormItem path="enableFlag" label="是否启用">
+                <NSelect
+                  placeholder="是否启用"
+                  clearable
+                  v-model:value={searchForm.enableFlag}
+                  options={[
+                    { label: '是', value: 1 },
+                    { label: '否', value: 0 }
+                  ]}
+                />
+              </NFormItem>
+              <NFormItem path="orchestraType" label="乐团类型">
+                <NSelect
+                  placeholder="请输入乐团类型"
+                  clearable
+                  v-model:value={searchForm.orchestraType}
+                  options={state.orchestraTypeList}
+                />
+              </NFormItem>
+              <NFormItem path="operatorId" label="更新人">
+                <NSelect
+                  placeholder="请输入更新人"
+                  clearable
+                  v-model:value={searchForm.operatorId}
+                  options={state.staffList}
+                  filterable
+                />
+              </NFormItem>
+              <NFormItem>
+                <NSpace>
+                  <NButton type="primary" onClick={onSearch}>
+                    搜索
+                  </NButton>
+                  <NButton type="default" onClick={onBtnReset}>
+                    重置
+                  </NButton>
+                </NSpace>
+              </NFormItem>
+            </SaveForm>
+            <NSpace style={{ paddingBottom: '12px' }} justify="space-between">
+              <NButton
+                type="primary"
+              v-auth="coursewareDetail1607207526805606402"
+                onClick={() => {
+                  state.visiableKnowledge = true
+                  router.push({
+                    path: '/coursewareDetail'
+                  })
+                }}
+              >
+                新增课件
+              </NButton>
               <NSpace>
-                <NButton type="primary" onClick={onSearch}>
-                  搜索
-                </NButton>
-                <NButton type="default" onClick={onBtnReset}>
-                  重置
+                <NButton
+                  v-auth="downloadCoursewareTemplate1702249619299237890"
+                  type="primary"
+                  tag="a"
+                  //@ts-ignore
+                  href="https://oss.dayaedu.com/daya-docs/%E8%AF%BE%E4%BB%B6%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx"
+                  download
+                >
+                  下载课件模板
                 </NButton>
+                <div v-auth="Importcourseware1702250576212918273">
+                  <NUpload
+                    ref={(el: any) => (customRequest_importData.importRef = el)}
+                    showFileList={false}
+                    accept=".xlsx"
+                    customRequest={customRequest_importFile}
+                  >
+                    <NButton
+                      type="primary"
+                      onClick={() => {
+                        customRequest_importData.importRef?.clear()
+                      }}
+                    >
+                      导入课件
+                    </NButton>
+                  </NUpload>
+                </div>
               </NSpace>
-            </NFormItem>
-          </SaveForm>
-          <NSpace style={{ paddingBottom: '12px' }}>
-            <NButton
-              type="primary"
-              v-auth="coursewareDetail1607207526805606402"
-              onClick={() => {
-                state.visiableKnowledge = true
-                router.push({
-                  path: '/coursewareDetail'
-                })
-              }}
-            >
-              新增课件
-            </NButton>
-          </NSpace>
+            </NSpace>
 
-          <NDataTable
-            loading={state.loading}
-            columns={columns()}
-            data={state.dataList}
-          ></NDataTable>
-          <Pagination
-            saveKey="courseware-manage-ad-key"
-            v-model:page={state.pagination.page}
-            v-model:pageSize={state.pagination.rows}
-            v-model:pageTotal={state.pagination.pageTotal}
-            onList={getList}
-            sync
-          ></Pagination>
-        </div>
+            <NDataTable
+              loading={state.loading}
+              columns={columns()}
+              data={state.dataList}
+            ></NDataTable>
+            <Pagination
+              saveKey="courseware-manage-ad-key"
+              v-model:page={state.pagination.page}
+              v-model:pageSize={state.pagination.rows}
+              v-model:pageTotal={state.pagination.pageTotal}
+              onList={getList}
+              sync
+            ></Pagination>
+          </div>
+        </NSpin>
       </div>
     )
   }

+ 4 - 1
src/views/teaching-manage/teaching-plan/plan-detail.tsx

@@ -59,7 +59,10 @@ export default defineComponent({
           key: 'name',
           render: (row: any) => (
             <>
-              <TheLink to={{ path: '/coursewareDetail', query: { id: row.lessonCoursewareId } }}>
+              <TheLink
+                authLink="coursewareManage1606856890826199041"
+                to={{ path: '/coursewareDetail', query: { id: row.lessonCoursewareId } }}
+              >
                 {row.name}
               </TheLink>
             </>

+ 2 - 19
src/views/teaching-manage/unit-test/index.module.less

@@ -2,7 +2,6 @@
   .form {
     :global {
       .n-form-item-blank {
-
         .n-input,
         .n-select {
           width: 160px;
@@ -11,45 +10,37 @@
     }
   }
 }
-
 .kaodian {
   :global {
     .n-base-selection-input {
       color: #333 !important;
     }
-
     .n-base-loading.n-base-suffix {
       display: none;
     }
   }
 }
-
 .coustomBank {
   :global {
     .n-tabs-nav {
       display: none;
     }
-
     .n-tab-pane {
       padding-top: 0;
     }
   }
 }
-
 .answerItem {
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding: 10px 0;
-
   &:hover {
     background-color: rgba(0, 0, 0, 0.1);
   }
-
   .handle {
     width: 50px;
   }
-
   .itemContent {
     flex: 1;
     padding: 0 50px 0 0;
@@ -57,43 +48,35 @@
     align-items: center;
   }
 }
-
 .juanWrap {
   margin-bottom: 20px;
 }
-
 .unit-test-index-editAndUpdate {
   .ramdomItem {
     position: relative;
     border-radius: 8px;
-    padding: 30px 10px 0px 10px;
-
+    padding: 10px 10px 0 10px;
     :global {
       .n-form-item-label {
         display: flex;
         flex-direction: row;
         align-items: center;
       }
-
       .n-form-item-label__asterisk {
         display: none;
       }
     }
-
     .kaoLabel {
       span {
         color: var(--n-asterisk-color);
       }
     }
-
     &:hover {
       background-color: rgba(0, 0, 0, 0.1);
-
       .delIcon {
         visibility: visible;
       }
     }
-
     .delIcon {
       position: absolute;
       right: 10px;
@@ -101,4 +84,4 @@
       visibility: hidden;
     }
   }
-}
+}

+ 1 - 1
src/views/teaching-manage/unit-test/index.tsx

@@ -49,7 +49,7 @@ export default defineComponent({
           <div class={styles.unitTest}>
             <NTabs
               v-model:value={data.active}
-              type="line"
+              type="card"
               onUpdate:value={(val: any) => setTabs(val)}
             >
               <NTabPane name="1" tab="阶段自测" v-auth="unitExamination/page1614564155343577090">

+ 18 - 6
src/views/teaching-manage/unit-test/model/addQuestionList.tsx

@@ -130,10 +130,22 @@ export default defineComponent({
           rows: 1000
         })
         if (Array.isArray(res?.data?.rows)) {
-          data.categorys = res.data.rows
+          data.categorys = formatList(res.data.rows)
         }
       } catch (error) {}
     }
+
+    const formatList = (item: any) => {
+      item.forEach((child: any) => {
+        if (child.children && child.children.length) {
+          formatList(child.children)
+        } else {
+          child.children = null
+        }
+      })
+      return item
+    }
+
     const onSubmit = () => {
       data.pagination.page = 1
       getList()
@@ -153,7 +165,7 @@ export default defineComponent({
           onSetModel={(val: any) => Object.assign(searchForm, val)}
           saveKey="add-question-list-key"
         >
-          <NFormItem path="keyword" label='关键字'>
+          <NFormItem path="keyword" label="关键字">
             <NInput
               placeholder="请输入题目名称/编号"
               v-model:value={searchForm.keyword}
@@ -165,7 +177,7 @@ export default defineComponent({
               clearable
             />
           </NFormItem>
-          <NFormItem path="score" label='分值'>
+          <NFormItem path="score" label="分值">
             <NInput
               placeholder="请输入分值"
               v-model:value={searchForm.score}
@@ -177,7 +189,7 @@ export default defineComponent({
               clearable
             />
           </NFormItem>
-          <NFormItem path="questionTypeCode" label='题目类型'>
+          <NFormItem path="questionTypeCode" label="题目类型">
             <NSelect
               placeholder="请选择题目类型"
               v-model:value={searchForm.questionTypeCode}
@@ -196,7 +208,7 @@ export default defineComponent({
               options={lessonType}
             />
           </NFormItem> */}
-          <NFormItem path="categoryId" label='考点'>
+          <NFormItem path="categoryId" label="考点">
             <NCascader
               placeholder="请选择考点"
               v-model:value={searchForm.categoryId}
@@ -209,7 +221,7 @@ export default defineComponent({
               clearable
             />
           </NFormItem>
-          <NFormItem path="difficultyCoefficient" label='难度'>
+          <NFormItem path="difficultyCoefficient" label="难度">
             <NSelect
               placeholder="请选择难度"
               clearable

+ 1 - 2
src/views/teaching-manage/unit-test/unit-test-index/editAndUpdate.tsx

@@ -577,7 +577,6 @@ export default defineComponent({
                                 default: () => (
                                   <NSelect
                                     multiple
-                                    clearable
                                     options={questions}
                                     v-model:value={item.questionTypeCodes}
                                   />
@@ -603,7 +602,7 @@ export default defineComponent({
                       )
                     })}
                   </NForm>
-                  <NSpace style={{ padding: '10px 10px 0 10px' }}>
+                  <NSpace style={{ padding: '0 10px 0 10px' }}>
                     <NButton
                       type="warning"
                       style={{ width: '170px' }}

+ 26 - 6
src/views/teaching-manage/unit-test/unit-test-index/previewUnit.tsx

@@ -4,6 +4,11 @@ import { computed, defineComponent, reactive } from 'vue'
 import { difficultyCoefficients, questionTypeCode } from '../question-bank'
 import styles from './previewUnit.module.less'
 const items = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'M']
+const difficultyEmun = [
+  { label: '普通级', value: '1' },
+  { label: '进阶级', value: '2' },
+  { label: '大师级', value: '3' }
+]
 export default defineComponent({
   name: 'previewUnit',
   props: {
@@ -30,9 +35,8 @@ export default defineComponent({
           }) || []
         let questionExtendsInfo = ''
         try {
-          questionExtendsInfo = n.questionTypeCode != "PLAY"
-            ? n.questionExtendsInfo
-            : JSON.parse(n.questionExtendsInfo)
+          questionExtendsInfo =
+            n.questionTypeCode != 'PLAY' ? n.questionExtendsInfo : JSON.parse(n.questionExtendsInfo)
         } catch (error) {}
         arr.push({
           ...n,
@@ -73,12 +77,11 @@ export default defineComponent({
                     <div>
                       <div innerHTML={n.questionDetail}></div>
 
-                      {n.questionTypeCode != "PLAY" ? (
+                      {n.questionTypeCode != 'PLAY' ? (
                         <div>
                           <NSpace>
                             {n.mediaUrls.map((media: any) => (
                               <>
-                                {/* <audio src='https://daya.ks3-cn-beijing.ksyun.com/202205/T6doLdd.mp3' controls></audio> */}
                                 {media.type === 'audio' ? (
                                   <audio src={media.src} controls></audio>
                                 ) : (
@@ -119,7 +122,24 @@ export default defineComponent({
                             modalData.music = { id: n.questionExtendsInfo?.musicSheetId }
                           }}
                         >
-                          演奏曲目: {n.questionExtendsInfo?.musicName} (合格分数: {n.questionExtendsInfo?.score})
+                          演奏曲目: {n.questionExtendsInfo?.musicName}
+                          <NSpace style={{ marginLeft: '8px' }}>
+                            <NTag size="small" type="primary">
+                              合格分数: {n.questionExtendsInfo?.score}
+                            </NTag>
+                            <NTag size="small" type="primary">
+                              练习小节:
+                              {n.questionExtendsInfo?.start}-{n.questionExtendsInfo?.end}
+                            </NTag>
+                            <NTag size="small" type="primary">
+                              测验难度:
+                              {
+                                difficultyEmun.find(
+                                  (d: any) => d.value == n.questionExtendsInfo?.difficulty
+                                )?.label
+                              }
+                            </NTag>
+                          </NSpace>
                         </NButton>
                       )}