CourseKnowledgePoint.tsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. import { knowledgeTypeData } from '@/views/knowledge-manage/knowledgeTypeData'
  2. import {
  3. DataTableColumn,
  4. NButton,
  5. NDataTable,
  6. NDrawerContent,
  7. NInput,
  8. NModal,
  9. NSpace,
  10. NTooltip,
  11. useDialog,
  12. useMessage
  13. } from 'naive-ui'
  14. import { InternalRowData } from 'naive-ui/es/data-table/src/interface'
  15. import { defineComponent, onMounted, reactive } from 'vue'
  16. import { useRoute, useRouter } from 'vue-router'
  17. import {
  18. lessonCoursewareDetailPageKnowledgePoint,
  19. lessonCoursewareDetailRemoveKnowledgePoint,
  20. lessonCoursewareDetailUpOrDownKnowledgePoint
  21. } from '../../api'
  22. import AddseKnowledge from './AddseKnowledge'
  23. import TheLink from '@/components/TheLink'
  24. export default defineComponent({
  25. name: 'CourseKnowledgePoint',
  26. props: {
  27. item: {
  28. type: Object,
  29. default: () => {}
  30. },
  31. courseTypeCode: {
  32. type: String,
  33. default: ''
  34. }
  35. },
  36. emits: ['handleSuccess'],
  37. setup(props, { emit }) {
  38. const message = useMessage()
  39. const dialog = useDialog()
  40. const route = useRoute()
  41. const state = reactive({
  42. pagination: {
  43. page: 1,
  44. rows: 1000,
  45. pageTotal: 0
  46. },
  47. searchForm: {
  48. keyword: '',
  49. knowledgePointId: ''
  50. },
  51. loading: false,
  52. dataList: [] as any,
  53. checkList: [] as string[],
  54. visiableKnowledge: false
  55. })
  56. const columns = [
  57. {
  58. type: 'selection'
  59. },
  60. {
  61. title: '知识点名称',
  62. key: 'name',
  63. render(row: any) {
  64. return row.children ? (
  65. <>
  66. {row.name}({row.knowledgePointId})
  67. </>
  68. ) : (
  69. <TheLink
  70. to={{
  71. path: '/educationalManage/knowledgeManage',
  72. query: { keyword: row.knowledgePointId }
  73. }}
  74. >
  75. {row.name}({row.knowledgePointId})
  76. </TheLink>
  77. )
  78. }
  79. },
  80. {
  81. title: '课程类型',
  82. key: 'courseTypeName',
  83. width: 200,
  84. ellipsis: true,
  85. render(row: InternalRowData) {
  86. return (
  87. <NTooltip placement="top-start">
  88. {{
  89. default: () => row.courseTypeName,
  90. trigger: () => row.courseTypeName
  91. }}
  92. </NTooltip>
  93. )
  94. }
  95. },
  96. {
  97. title: '素材数量',
  98. key: 'totalMaterialNum'
  99. },
  100. {
  101. title: '建议学习时长',
  102. key: 'totalMaterialTimeSecond',
  103. render(row: any) {
  104. return row.totalMaterialTimeSecond + 's'
  105. }
  106. },
  107. {
  108. title: '操作',
  109. key: 'operation',
  110. fixed: 'right',
  111. render(row: InternalRowData, rowIndex: number) {
  112. return (
  113. <NSpace>
  114. <NButton
  115. text
  116. type="primary"
  117. disabled={row.relOrder === 1}
  118. onClick={() => handleRowMove('up', row)}
  119. >
  120. 上移
  121. </NButton>
  122. <NButton
  123. text
  124. type="primary"
  125. disabled={checkLastItem(row)}
  126. onClick={() => handleRowMove('down', row)}
  127. >
  128. 下移
  129. </NButton>
  130. </NSpace>
  131. )
  132. }
  133. }
  134. ]
  135. const getList = async () => {
  136. state.loading = true
  137. try {
  138. const { data } = await lessonCoursewareDetailPageKnowledgePoint({
  139. ...state.searchForm,
  140. lessonCoursewareDetailId: props.item?.id,
  141. page: state.pagination.page,
  142. rows: state.pagination.rows
  143. })
  144. if (Array.isArray(data?.rows)) {
  145. state.dataList = data.rows.map((n: any, i: number) => ({
  146. ...n,
  147. relOrder: i + 1,
  148. parentId: 0
  149. }))
  150. state.dataList.forEach((item: any) => {
  151. if (item.children && item.children.length > 0) {
  152. item.children.forEach((child: any, i: number) => {
  153. child.relOrder = i + 1
  154. child.parentId = item.id
  155. })
  156. }
  157. })
  158. console.log(state.dataList, 'dataList')
  159. }
  160. } catch {}
  161. state.loading = false
  162. }
  163. onMounted(() => {
  164. getList()
  165. })
  166. // 批量删除
  167. const hanldeDelete = () => {
  168. const d = dialog.warning({
  169. title: '警告',
  170. content: '是否确认删除知识点关联?',
  171. positiveText: '确定',
  172. negativeText: '取消',
  173. onPositiveClick: async () => {
  174. d.loading = true
  175. console.log(props.item)
  176. try {
  177. const res = await lessonCoursewareDetailRemoveKnowledgePoint({
  178. id: props.item?.id,
  179. knowledgePointIds: state.checkList.join(',')
  180. })
  181. message.success('删除成功')
  182. state.checkList = []
  183. getList()
  184. emit('handleSuccess')
  185. } catch (error) {}
  186. d.loading = false
  187. }
  188. })
  189. }
  190. // 判断是否是最后一个
  191. const checkLastItem = (row: any) => {
  192. const dataList = state.dataList || []
  193. if (row.parentId > 0) {
  194. const childList = dataList.find((n: any) => n.id === row.parentId)
  195. return row.relOrder === childList.children.length
  196. } else {
  197. return row.relOrder === dataList.length
  198. }
  199. }
  200. // 表格行移动
  201. const handleRowMove = (type: 'up' | 'down', row: any) => {
  202. if (state.loading) return
  203. const moveData = []
  204. const index = row.relOrder - 1
  205. const tempList =
  206. row.parentId > 0 ? state.dataList : state.dataList.find((n: any) => n.id === row.parentId)
  207. if (type === 'up') {
  208. if (row.parentId <= 0) {
  209. state.dataList[index] = state.dataList.splice(index - 1, 1, state.dataList[index])[0]
  210. } else {
  211. state.dataList.forEach((item: any) => {
  212. if (item.id === row.parentId) {
  213. item.children[index] = item.children.splice(index - 1, 1, item.children[index])[0]
  214. }
  215. })
  216. }
  217. } else {
  218. if (row.parentId <= 0) {
  219. state.dataList[index] = state.dataList.splice(index + 1, 1, state.dataList[index])[0]
  220. } else {
  221. state.dataList.forEach((item: any) => {
  222. if (item.id === row.parentId) {
  223. item.children[index] = item.children.splice(index + 1, 1, item.children[index])[0]
  224. }
  225. })
  226. }
  227. }
  228. const moveList: any = []
  229. let sort: number = 0
  230. state.dataList.forEach((item: any, index: number) => {
  231. item.relOrder = index + 1
  232. if (item.children && item.children.length > 0) {
  233. item.children.forEach((child: any, i: number) => {
  234. child.relOrder = i + 1
  235. child.parentId = item.id
  236. sort = sort + 1
  237. moveList.push({
  238. sortNo: sort,
  239. id: child.id
  240. })
  241. })
  242. } else {
  243. sort = sort + 1
  244. moveList.push({
  245. sortNo: sort,
  246. id: item.id
  247. })
  248. }
  249. })
  250. console.log(moveList)
  251. handleSaveRow(moveList)
  252. }
  253. // 记录排序后的位置
  254. const handleSaveRow = async (moveData: any) => {
  255. try {
  256. await lessonCoursewareDetailUpOrDownKnowledgePoint(moveData)
  257. // getList()
  258. } catch {}
  259. }
  260. return () => (
  261. <div>
  262. <NSpace style={{ paddingBottom: '12px' }}>
  263. <NButton type="primary" onClick={() => (state.visiableKnowledge = true)}>
  264. 关联知识点
  265. </NButton>
  266. <NButton
  267. type="error"
  268. disabled={state.checkList.length ? false : true}
  269. onClick={() => hanldeDelete()}
  270. >
  271. 批量删除
  272. </NButton>
  273. </NSpace>
  274. <NSpace style={{ paddingBottom: '12px' }}>
  275. <NInput placeholder="知识点名称" v-model:value={state.searchForm.keyword}></NInput>
  276. <NButton
  277. type="primary"
  278. onClick={() => {
  279. state.pagination.page = 1
  280. getList()
  281. }}
  282. >
  283. 搜索
  284. </NButton>
  285. <NButton
  286. onClick={() => {
  287. state.searchForm.keyword = ''
  288. state.pagination.page = 1
  289. getList()
  290. }}
  291. >
  292. 重置
  293. </NButton>
  294. </NSpace>
  295. <NDataTable
  296. loading={state.loading}
  297. rowKey={(row: any) => row.id}
  298. v-model:columns={columns}
  299. data={state.dataList}
  300. onUpdateCheckedRowKeys={(value: any, rows: any) => {
  301. let tempIds: any = []
  302. rows.forEach((row: any) => {
  303. if (!(row.children && row.children.length > 0)) {
  304. tempIds.push(row.id)
  305. }
  306. })
  307. state.checkList = tempIds
  308. }}
  309. ></NDataTable>
  310. <NModal
  311. preset="dialog"
  312. v-model:show={state.visiableKnowledge}
  313. title="添加知识点"
  314. showIcon={false}
  315. style={{ width: '1000px' }}
  316. >
  317. <AddseKnowledge
  318. courseTypeCode={props.courseTypeCode as any}
  319. item={props.item}
  320. onClose={() => {
  321. state.visiableKnowledge = false
  322. }}
  323. onHandleSuccess={() => {
  324. state.visiableKnowledge = false
  325. getList()
  326. emit('handleSuccess')
  327. }}
  328. />
  329. </NModal>
  330. </div>
  331. )
  332. }
  333. })