material-list.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. import SaveForm from '@/components/save-form'
  2. import Pagination from '@/components/pagination'
  3. import {
  4. DataTableColumn,
  5. NButton,
  6. NCascader,
  7. NDataTable,
  8. NDatePicker,
  9. NDescriptions,
  10. NDescriptionsItem,
  11. NFormItem,
  12. NInput,
  13. NModal,
  14. NSelect,
  15. NSpace,
  16. NTag,
  17. NTooltip,
  18. useDialog,
  19. useMessage
  20. } from 'naive-ui'
  21. import { defineComponent, inject, onMounted, reactive, ref, provide } from 'vue'
  22. import { fetchCategoryList, fetchMaterialList, deleteMaterial, updateMaterailData } from '../api'
  23. import styles from '../index.module.less'
  24. import { InternalRowData } from 'naive-ui/es/data-table/src/interface'
  25. import AddMaterial from '../model/addMaterial'
  26. import { getLessonType, lessonType } from '@/views/knowledge-manage/knowledgeTypeData'
  27. import { filterTimes, getTimes } from '@/utils/dateUtil'
  28. import { useRoute } from 'vue-router'
  29. import { subjectPage } from '@views/system-manage/subject-manage/api'
  30. const classType: { [_: string]: any } = {
  31. VIDEO: '视频',
  32. IMG: '图片',
  33. SONG: '曲目'
  34. }
  35. const classTypeList = Object.keys(classType).map((key: string) => {
  36. return { label: classType[key], value: key }
  37. })
  38. export default defineComponent({
  39. name: 'material-list',
  40. setup(props) {
  41. const dialog = useDialog()
  42. const message = useMessage()
  43. const state = reactive({
  44. loading: false,
  45. pagination: {
  46. page: 1,
  47. rows: 10,
  48. pageTotal: 10
  49. },
  50. visiableCity: false,
  51. dataList: [] as any,
  52. cityType: 'add',
  53. materail: null,
  54. isLook: false,
  55. employeeList: [] as any
  56. })
  57. const searchForm = reactive({
  58. keyword: null as any,
  59. time: null as any,
  60. courseTypeCode: null,
  61. materialCategoryId: null,
  62. type: null
  63. })
  64. const route = useRoute()
  65. // 获取分类列表
  66. const category = reactive({
  67. list: [] as any,
  68. index: -1
  69. })
  70. const getCategoryList = async () => {
  71. try {
  72. const { data } = await fetchCategoryList({ page: 1 })
  73. category.list = data?.rows || []
  74. } catch {}
  75. }
  76. provide('categoryList', category)
  77. // 声部
  78. const subjects = reactive({
  79. list: [] as any
  80. })
  81. const getSubjects = async () => {
  82. try {
  83. const { data } = await subjectPage({ page: 1, row: 1000 })
  84. subjects.list = data?.rows || []
  85. } catch {}
  86. }
  87. provide('subjects', subjects)
  88. onMounted(() => {
  89. console.log(route.query, 'route.query')
  90. if (route.query.id) {
  91. searchForm.keyword = route.query.id as string
  92. }
  93. getCategoryList()
  94. getSubjects()
  95. })
  96. const columns = (): DataTableColumn[] => {
  97. return [
  98. {
  99. title: '素材名称',
  100. key: 'name',
  101. render(row: any) {
  102. return (
  103. <NDescriptions labelPlacement="left" column={1}>
  104. <NDescriptionsItem label="素材名称">{row.name}</NDescriptionsItem>
  105. <NDescriptionsItem label="素材编号">{row.id}</NDescriptionsItem>
  106. <NDescriptionsItem label="素材分类">{row.materialCategoryName}</NDescriptionsItem>
  107. </NDescriptions>
  108. )
  109. }
  110. },
  111. // {
  112. // title: '编号',
  113. // key: 'id'
  114. // },
  115. // {
  116. // title: '素材分类',
  117. // key: 'materialCategoryName'
  118. // }, 分段编号
  119. {
  120. title: '素材信息',
  121. key: 'sn',
  122. render(row: any) {
  123. return (
  124. <NDescriptions labelPlacement="left" column={1}>
  125. <NDescriptionsItem label="分段编号">{row.sn}</NDescriptionsItem>
  126. <NDescriptionsItem label="素材类型">
  127. {classType[row.type as string]}
  128. </NDescriptionsItem>
  129. {/* <NDescriptionsItem label="课程类型">{row.courseTypeName}</NDescriptionsItem> */}
  130. </NDescriptions>
  131. )
  132. }
  133. },
  134. {
  135. title: '课程信息',
  136. key: 'type',
  137. render(row: any) {
  138. return (
  139. <NDescriptions labelPlacement="left" column={1}>
  140. <NDescriptionsItem label="课程类型">{row.courseTypeName}</NDescriptionsItem>
  141. {/*
  142. <NDescriptionsItem label="建议时长">
  143. {row.adviseStudyTimeSecond ? row.adviseStudyTimeSecond + '秒' : ''}
  144. </NDescriptionsItem> */}
  145. </NDescriptions>
  146. )
  147. }
  148. },
  149. // {
  150. // title: '课程类型',
  151. // key: 'courseTypeName',
  152. // width: 200,
  153. // ellipsis: true,
  154. // render(row: InternalRowData) {
  155. // return (
  156. // <NTooltip placement="top-start">
  157. // {{
  158. // default: () => row.courseTypeName,
  159. // trigger: () => row.courseTypeName
  160. // }}
  161. // </NTooltip>
  162. // )
  163. // }
  164. // },
  165. // {
  166. // title: '建议学习时长',
  167. // key: 'adviseStudyTimeSecond',
  168. // render(row: InternalRowData) {
  169. // return row.adviseStudyTimeSecond ? row.adviseStudyTimeSecond + '秒' : ''
  170. // }
  171. // },
  172. {
  173. title: '操作信息',
  174. key: 'createTime',
  175. render(row: any) {
  176. return (
  177. <NDescriptions labelPlacement="left" column={1}>
  178. <NDescriptionsItem label="上传人">{row.operatorName}</NDescriptionsItem>
  179. <NDescriptionsItem label="上传时间">
  180. {row.createTime ? row.createTime : '--'}
  181. </NDescriptionsItem>
  182. </NDescriptions>
  183. )
  184. }
  185. },
  186. // {
  187. // title: '上传人',
  188. // key: 'operatorName'
  189. // },
  190. {
  191. title: '状态',
  192. key: 'delFlag',
  193. render(row: InternalRowData) {
  194. return (
  195. <>
  196. <NTag type={row.enableFlag ? 'success' : 'warning'}>
  197. {row.enableFlag ? '启用' : '停用'}
  198. </NTag>
  199. </>
  200. )
  201. }
  202. },
  203. {
  204. title: '操作',
  205. key: 'operation',
  206. fixed: 'right',
  207. width: 160,
  208. render(row: any) {
  209. return (
  210. <NSpace>
  211. {/* <NButton
  212. type={row.enableFlag ? 'error' : 'success'}
  213. text
  214. v-auth="material/update1599948375910109186"
  215. onClick={() => handleChange(row)}
  216. >
  217. {row.enableFlag ? '停用' : '启用'}
  218. </NButton> */}
  219. <NButton
  220. type="primary"
  221. text
  222. onClick={() => {
  223. state.isLook = true
  224. state.materail = row
  225. state.visiableCity = true
  226. }}
  227. >
  228. 查看
  229. </NButton>
  230. <NButton
  231. type="primary"
  232. text
  233. v-auth="material/update1599948375910109186"
  234. onClick={() => {
  235. state.cityType = 'update'
  236. state.materail = row
  237. state.visiableCity = true
  238. }}
  239. >
  240. 修改
  241. </NButton>
  242. <NButton
  243. type="primary"
  244. text
  245. disabled={row.enableFlag}
  246. v-auth="material/remove1599948195949301762"
  247. onClick={() => handleDelete(row)}
  248. >
  249. 删除
  250. </NButton>
  251. </NSpace>
  252. )
  253. }
  254. }
  255. ]
  256. }
  257. const saveForm = ref()
  258. const onSubmit = () => {
  259. state.pagination.page = 1
  260. getList()
  261. }
  262. const onSearch = () => {
  263. saveForm.value?.submit()
  264. }
  265. const onBtnReset = () => {
  266. saveForm.value?.reset()
  267. }
  268. const getList = async () => {
  269. try {
  270. state.loading = true
  271. const { time, ...reset } = searchForm
  272. const body = {
  273. ...reset,
  274. ...filterTimes(time, ['startTime', 'endTime']),
  275. page: state.pagination.page,
  276. rows: state.pagination.rows
  277. }
  278. const { data } = await fetchMaterialList(body)
  279. state.loading = false
  280. state.pagination.pageTotal = Number(data.total)
  281. state.dataList = data.rows || []
  282. } catch {
  283. state.loading = false
  284. }
  285. }
  286. // 删除
  287. const handleDelete = async (row: any) => {
  288. dialog.warning({
  289. title: '警告',
  290. content: '是否确认删除此素材?',
  291. positiveText: '确定',
  292. negativeText: '取消',
  293. onPositiveClick: async () => {
  294. const res = await deleteMaterial(row.id)
  295. if (res.data) {
  296. onSubmit()
  297. message.success('删除成功')
  298. }
  299. }
  300. })
  301. }
  302. // 启用,停用
  303. const handleChange = (row: any) => {
  304. dialog.warning({
  305. title: '提示',
  306. content: row.enableFlag ? '是否停用此素材?' : '是否启用此素材?',
  307. positiveText: '确定',
  308. negativeText: '取消',
  309. onPositiveClick: async () => {
  310. const res = await deleteMaterial(row.id)
  311. if (res.data) {
  312. await updateMaterailData({ id: row.id, enableFlag: row.enableFlag ? 0 : 1 })
  313. message.success('修改成功')
  314. getList()
  315. }
  316. }
  317. })
  318. }
  319. onMounted(() => {
  320. getList()
  321. })
  322. return () => (
  323. <>
  324. <SaveForm
  325. ref={saveForm}
  326. label-width=""
  327. model={searchForm}
  328. onSubmit={onSubmit}
  329. onSetModel={(val: any) => Object.assign(searchForm, val)}
  330. saveKey="material-key"
  331. >
  332. <NFormItem label="搜索条件" path="keyword">
  333. <NInput
  334. v-model:value={searchForm.keyword}
  335. onKeydown={(e) => {
  336. if (e.code === 'Enter') {
  337. onSubmit()
  338. }
  339. }}
  340. placeholder={'素材名称/编号'}
  341. clearable
  342. />
  343. </NFormItem>
  344. <NFormItem label="素材分类" path="materialCategoryId">
  345. <NCascader
  346. v-model:value={searchForm.materialCategoryId}
  347. options={category.list}
  348. checkStrategy="child"
  349. childrenField="subMaterialCategoryList"
  350. expandTrigger="hover"
  351. valueField="id"
  352. labelField="name"
  353. clearable
  354. filterable
  355. />
  356. </NFormItem>
  357. <NFormItem label="素材类型" path="type">
  358. <NSelect clearable v-model:value={searchForm.type} options={classTypeList} />
  359. </NFormItem>
  360. <NFormItem label="课程类型" path="courseTypeCode">
  361. <NSelect clearable v-model:value={searchForm.courseTypeCode} options={lessonType} />
  362. </NFormItem>
  363. <NFormItem label="搜索时间" path="time">
  364. <NDatePicker
  365. class={styles.datepicker}
  366. v-model:value={searchForm.time}
  367. type="daterange"
  368. clearable
  369. />
  370. </NFormItem>
  371. <NFormItem>
  372. <NSpace>
  373. <NButton type="primary" onClick={onSearch}>
  374. 搜索
  375. </NButton>
  376. <NButton type="default" onClick={onBtnReset}>
  377. 重置
  378. </NButton>
  379. </NSpace>
  380. </NFormItem>
  381. </SaveForm>
  382. <NSpace style={{ paddingBottom: '12px' }}>
  383. <NButton
  384. type="primary"
  385. v-auth="material/save1599948016487616513"
  386. onClick={() => {
  387. state.cityType = 'add'
  388. state.materail = null
  389. state.visiableCity = true
  390. }}
  391. >
  392. 添加素材
  393. </NButton>
  394. </NSpace>
  395. <NDataTable loading={state.loading} columns={columns()} data={state.dataList}></NDataTable>
  396. <Pagination
  397. v-model:page={state.pagination.page}
  398. v-model:pageSize={state.pagination.rows}
  399. v-model:pageTotal={state.pagination.pageTotal}
  400. onList={getList}
  401. sync
  402. saveKey="material-key"
  403. ></Pagination>
  404. <NModal
  405. v-model:show={state.visiableCity}
  406. preset="dialog"
  407. showIcon={false}
  408. title={state.cityType === 'add' ? '添加素材' : '修改素材'}
  409. style={{ width: '700px' }}
  410. onClose={() => {
  411. state.isLook = false
  412. }}
  413. >
  414. {state.visiableCity && (
  415. <AddMaterial
  416. item={state.materail}
  417. isLook={state.isLook}
  418. onClose={() => {
  419. state.visiableCity = false
  420. }}
  421. onHandleSuccess={() => {
  422. state.visiableCity = false
  423. if (!state.materail) {
  424. state.pagination.page = 1
  425. }
  426. getList()
  427. }}
  428. />
  429. )}
  430. </NModal>
  431. </>
  432. )
  433. }
  434. })