music-sheet-klx.tsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. import { defineComponent, onMounted, reactive, ref } from 'vue'
  2. import SaveForm from '@components/save-form'
  3. import {
  4. DataTableRowKey,
  5. NButton,
  6. NDataTable,
  7. NDatePicker,
  8. NDescriptions,
  9. NDescriptionsItem,
  10. NFormItem,
  11. NImage,
  12. NInput,
  13. NModal,
  14. NSelect,
  15. NSpace,
  16. NTag,
  17. useDialog,
  18. useMessage
  19. } from 'naive-ui'
  20. import Pagination from '@components/pagination'
  21. import TheTooltip from '@components/TheTooltip'
  22. import AddMusic from '@views/music-library/project-music-sheet/module/klx/addMusic'
  23. import { getMapValueByKey, getSelectDataFromObj } from '@/utils/objectUtil'
  24. import {
  25. appKey,
  26. musicSheetAudioType,
  27. musicSheetAvailableType,
  28. musicSheetPaymentType,
  29. musicSheetSourceType,
  30. musicSheetType
  31. } from '@/utils/constant'
  32. import {
  33. musicSheetApplicationExtendDel,
  34. musicSheetApplicationExtendStatus,
  35. musicSheetApplicationExtendTagList,
  36. musicSheetApplicationOwnerList,
  37. musicSheetPageByApplication
  38. } from '@views/music-library/api'
  39. import {
  40. musicSheetApplicationExtendSubjectList,
  41. sysApplicationPage
  42. } from '@views/system-manage/api'
  43. import { filterTimes } from '@/utils/dateUtil'
  44. import deepClone from '@/utils/deep.clone'
  45. import { copyText, getOwnerName } from '@views/music-library/musicUtil'
  46. import UpdateMusic from '@views/music-library/project-music-sheet/module/klx/updateMusic'
  47. import MusicPreView from '@views/music-library/music-sheet/modal/musicPreView'
  48. export default defineComponent({
  49. name: 'music-sheet-KLX',
  50. props: {
  51. appKey: {
  52. type: String,
  53. default: 'KLX'
  54. }
  55. },
  56. setup(props) {
  57. const dialog = useDialog()
  58. const message = useMessage()
  59. const state = reactive({
  60. loading: false,
  61. appId: null as any,
  62. pagination: {
  63. page: 1,
  64. rows: 10,
  65. pageTotal: 0
  66. },
  67. searchForm: {
  68. keyword: null,
  69. // musicSheetType: null, //曲目类型(SINGLE:单曲 CONCERT:合奏)
  70. subjectId: null, //声部ID
  71. subjectIds: null, //曲目声部ID集合
  72. status: null, //曲目状态(0:停用,1:启用)
  73. sourceType: null, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
  74. paymentType: null, //收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
  75. userId: null, //所属人
  76. musicCategoryId: null, //曲目分类ID
  77. times: null, // 上传时间
  78. audioType: null, //音频类型(HOMEMODE: 自制 COMMON: 普通)
  79. exquisiteFlag: null, //精品标志
  80. topFlag: null, //是否置顶(0:否;1:是)
  81. availableType: null, //可用途径 ORG 机构 PLATFORM 平台
  82. appAuditFlag: null, //是否审核版本
  83. detailFlag: null, //是否查询详情
  84. musicTagIds: [] as any, //曲目标签
  85. applicationId: null, //所属人项目ID
  86. extendApplicationId: null //所属人项目ID
  87. },
  88. subjectList: [],
  89. dataList: [] as any[],
  90. showAddDialog: false,
  91. showEditDialog: false,
  92. userIdDisable: true,
  93. userIdData: [] as any,
  94. updateRow: {} as any, // 修改选择的行
  95. musicTagList: [] as any, //曲目标签
  96. applicationId: null, //应用ID
  97. musicPreview: false,
  98. musicPreviewScoreType: 'staff', // 预览谱面类型
  99. musicScore: null as any,
  100. useProjectData: [] as any // 适用项目行数据
  101. })
  102. onMounted(async () => {
  103. state.loading = true
  104. // 获取应用APP信息
  105. try {
  106. const { data } = await sysApplicationPage({ page: 1, rows: 1, appKey: props.appKey })
  107. const tempList = data.rows || []
  108. if (!tempList || tempList.length == 0) {
  109. state.loading = false
  110. message.error('加载项目信息失败')
  111. return
  112. }
  113. state.appId = tempList[0].id
  114. state.applicationId = tempList[0].id
  115. } catch {}
  116. // 加载声部
  117. try {
  118. // const { data } = await subjectPage({ page: 1, rows: 999 })
  119. // const tempList = data.rows || []
  120. // tempList.forEach((item: any) => {
  121. // item.label = item.name
  122. // item.value = item.id + ''
  123. // })
  124. // state.subjectList = tempList
  125. const { data } = await musicSheetApplicationExtendSubjectList({
  126. applicationId: state.applicationId
  127. })
  128. const tempList = data || []
  129. tempList.forEach((item: any) => {
  130. item.label = item.subjectName
  131. item.value = item.subjectId
  132. })
  133. state.subjectList = tempList
  134. } catch {}
  135. // 加载曲目标签
  136. try {
  137. const { data } = await musicSheetApplicationExtendTagList({ applicationId: state.appId })
  138. if (data && data.length > 0) {
  139. data.forEach((item: any) => {
  140. state.musicTagList.push({
  141. ...item,
  142. label: item.name,
  143. value: item.id
  144. })
  145. })
  146. }
  147. } catch (err) {}
  148. // 加载表格数据
  149. initUseAppList()
  150. getList()
  151. })
  152. const saveForm = ref()
  153. const onSearch = () => {
  154. checkedRowKeysRef.value = []
  155. saveForm.value?.submit()
  156. }
  157. const onBtnReset = () => {
  158. saveForm.value?.reset()
  159. }
  160. const onSubmit = () => {
  161. state.pagination.page = 1
  162. getList()
  163. }
  164. const initUseAppList = async () => {
  165. try {
  166. const appKeys = Object.keys(appKey)
  167. const { data } = await sysApplicationPage({ page: 1, rows: 999 })
  168. const tempList = data.rows || []
  169. state.useProjectData = []
  170. const filter = tempList.filter((next: any) => {
  171. return appKeys.includes(next.appKey)
  172. })
  173. filter.forEach((item: any) => {
  174. state.useProjectData.push({
  175. ...item,
  176. label: item.appName,
  177. value: item.id
  178. })
  179. })
  180. } catch {}
  181. }
  182. const checkedRowKeysRef = ref<DataTableRowKey[]>([])
  183. const handleCheck = (rowKeys: DataTableRowKey[]) => {
  184. checkedRowKeysRef.value = rowKeys
  185. }
  186. const getList = async () => {
  187. try {
  188. state.loading = true
  189. const sourceType = state.searchForm.sourceType
  190. let userId = state.searchForm.userId
  191. let organizationRoleId = null
  192. if (sourceType && sourceType === 'ORG') {
  193. organizationRoleId = deepClone(userId)
  194. userId = null
  195. }
  196. const { data } = await musicSheetPageByApplication({
  197. ...state.pagination,
  198. ...state.searchForm,
  199. userId: sourceType && sourceType === 'PERSON' ? state.searchForm.userId : null,
  200. organizationRoleId: sourceType && sourceType === 'ORG' ? state.searchForm.userId : null,
  201. musicTagIds: state.searchForm.musicTagIds?.join(','),
  202. ...filterTimes(state.searchForm.times, ['startTime', 'endTime']),
  203. applicationId: state.applicationId
  204. })
  205. state.pagination.pageTotal = Number(data.total)
  206. state.dataList = data.rows || []
  207. } catch {}
  208. state.loading = false
  209. }
  210. const onChangeStatus = (row: any) => {
  211. const statusStr = row.status ? '停用' : '启用'
  212. dialog.warning({
  213. title: '提示',
  214. content: `是否${statusStr}?`,
  215. positiveText: '确定',
  216. negativeText: '取消',
  217. onPositiveClick: async () => {
  218. try {
  219. await musicSheetApplicationExtendStatus({
  220. ids: row.applicationExtendId,
  221. status: !row.status
  222. })
  223. getList()
  224. message.success(`${statusStr}成功`)
  225. } catch {}
  226. }
  227. })
  228. }
  229. const onBatchChangeStatus = (status: boolean) => {
  230. const length = checkedRowKeysRef.value.length
  231. if (length == 0) {
  232. message.warning('未选择数据')
  233. }
  234. const statusStr = !status ? '停用' : '启用'
  235. dialog.warning({
  236. title: '提示',
  237. content: `是否${statusStr}` + length + `条数据?`,
  238. positiveText: '确定',
  239. negativeText: '取消',
  240. onPositiveClick: async () => {
  241. try {
  242. await musicSheetApplicationExtendStatus({
  243. ids: checkedRowKeysRef.value.join(','),
  244. status: status
  245. })
  246. getList()
  247. message.success(`${statusStr}成功`)
  248. } catch {}
  249. }
  250. })
  251. }
  252. const getPaymentType = (paymentType: any) => {
  253. const paymentTypeName = []
  254. if (paymentType && paymentType.length > 0) {
  255. for (let i = 0; i < paymentType.length; i++) {
  256. const name = getMapValueByKey(
  257. paymentType[i],
  258. new Map(Object.entries(musicSheetPaymentType))
  259. )
  260. paymentTypeName.push(name)
  261. }
  262. }
  263. return paymentTypeName.join(',')
  264. }
  265. const updateUserIdData = async (sourceType: any) => {
  266. if (!state.searchForm.extendApplicationId) {
  267. return
  268. }
  269. state.userIdData = []
  270. state.searchForm.userId = null
  271. if (sourceType && sourceType !== 'PLATFORM') {
  272. const { data } = await musicSheetApplicationOwnerList({
  273. page: 1,
  274. rows: 9999,
  275. sourceType: sourceType,
  276. applicationId: state.searchForm.extendApplicationId
  277. })
  278. const temp = data.rows || []
  279. temp.forEach((next: any) => {
  280. state.userIdData.push({
  281. ...next,
  282. label: sourceType === 'PERSON' ? next.userName : next.organizationRole,
  283. value: sourceType === 'PERSON' ? next.userId : next.organizationRoleId
  284. })
  285. })
  286. }
  287. }
  288. const onRmove = (row: any): void => {
  289. dialog.warning({
  290. title: '提示',
  291. content: `删除曲目,是否继续?`,
  292. positiveText: '确定',
  293. negativeText: '取消',
  294. onPositiveClick: async () => {
  295. try {
  296. await musicSheetApplicationExtendDel(row.applicationExtendId)
  297. getList()
  298. message.success('删除成功')
  299. } catch {}
  300. }
  301. })
  302. }
  303. const columns = (): any => {
  304. return [
  305. {
  306. type: 'selection'
  307. },
  308. {
  309. title: '曲目名称',
  310. key: 'id',
  311. render: (row: any) => (
  312. <>
  313. <NDescriptions labelPlacement="left" column={1}>
  314. <NDescriptionsItem label="曲目名称">
  315. <TheTooltip content={row.name} />{' '}
  316. </NDescriptionsItem>
  317. <NDescriptionsItem label="曲目编号">
  318. <div
  319. onDblclick={() => {
  320. copyText(message, row.id)
  321. }}
  322. >
  323. <TheTooltip content={row.id} />
  324. </div>
  325. </NDescriptionsItem>
  326. </NDescriptions>
  327. </>
  328. )
  329. },
  330. {
  331. title: '封面图',
  332. key: 'musicCover',
  333. render(row: any): JSX.Element {
  334. return <NImage width={60} height={60} src={row.musicCover} />
  335. }
  336. },
  337. {
  338. title: '曲目信息',
  339. key: 'musicSheetCategoriesName',
  340. render: (row: any) => (
  341. <>
  342. <NDescriptions labelPlacement="left" column={1}>
  343. <NDescriptionsItem label="曲目来源">
  344. {getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)))}
  345. </NDescriptionsItem>
  346. {/* <NDescriptionsItem label="谱面渲染">
  347. {getMapValueByKey(row.musicSheetType, new Map(Object.entries(musicSheetType)))}
  348. </NDescriptionsItem> */}
  349. <NDescriptionsItem label="所属人">
  350. <TheTooltip content={getOwnerName(row.musicSheetExtend, row.sourceType)} />
  351. </NDescriptionsItem>
  352. <NDescriptionsItem label="可用声部">
  353. <TheTooltip content={row.subjectNames} />
  354. </NDescriptionsItem>
  355. </NDescriptions>
  356. </>
  357. )
  358. },
  359. {
  360. title: '伴奏类型',
  361. key: 'audioType',
  362. render: (row: any) => {
  363. return (
  364. <div>
  365. {getMapValueByKey(row.audioType, new Map(Object.entries(musicSheetAudioType)))}
  366. </div>
  367. )
  368. }
  369. },
  370. // {
  371. // title: '可用声部',
  372. // key: 'subjectNames',
  373. // render: (row: any) => {
  374. // return <TheTooltip content={row.subjectNames}/>
  375. // }
  376. // },
  377. {
  378. title: '曲目标签',
  379. key: 'musicTagNames'
  380. },
  381. {
  382. title: '可用途径',
  383. key: 'applicationAvailableType',
  384. render: (row: any) => {
  385. return (
  386. <div>
  387. {getMapValueByKey(
  388. row.applicationAvailableType,
  389. new Map(Object.entries(musicSheetAvailableType))
  390. )}
  391. </div>
  392. )
  393. }
  394. },
  395. {
  396. title: '是否置顶',
  397. key: 'topFlag',
  398. render: (row: any) => {
  399. return <div>{row.topFlag ? '是' : '否'}</div>
  400. }
  401. },
  402. {
  403. title: '是否精品',
  404. key: 'exquisiteFlag',
  405. render: (row: any) => {
  406. return <div>{row.topFlag ? '是' : '否'}</div>
  407. }
  408. },
  409. {
  410. title: '收费方式',
  411. key: 'paymentType',
  412. render: (row: any) => {
  413. return <div>{getPaymentType(row.paymentType?.split(','))}</div>
  414. }
  415. },
  416. {
  417. title: '曲目价格',
  418. key: 'musicPrice'
  419. },
  420. {
  421. title: '上传人',
  422. minWidth: '150px',
  423. key: 'composer',
  424. render(row: any) {
  425. return (
  426. <NDescriptions labelPlacement="left" column={1}>
  427. <NDescriptionsItem label="上传人">{row.createByName}</NDescriptionsItem>
  428. <NDescriptionsItem label="上传时间">{row.createTime}</NDescriptionsItem>
  429. </NDescriptions>
  430. )
  431. }
  432. },
  433. {
  434. title: '状态',
  435. key: 'status',
  436. render(row: any) {
  437. return (
  438. <NTag type={row.status ? 'primary' : 'default'}>{row.status ? '启用' : '停用'}</NTag>
  439. )
  440. }
  441. },
  442. {
  443. title: '操作',
  444. key: 'operation',
  445. fixed: 'right',
  446. render(row: any) {
  447. return (
  448. <NSpace>
  449. <NButton
  450. type="primary"
  451. size="small"
  452. text
  453. onClick={() => {
  454. state.musicPreview = true
  455. state.musicScore = row
  456. if ('STAVE' == row.scoreType) {
  457. state.musicPreviewScoreType = 'staff'
  458. } else if ('JIAN' == row.scoreType) {
  459. state.musicPreviewScoreType = 'fixedTone'
  460. } else if ('FIRST' == row.scoreType) {
  461. state.musicPreviewScoreType = 'firstTone'
  462. } else {
  463. return
  464. }
  465. }}
  466. >
  467. 预览
  468. </NButton>
  469. <NButton
  470. type="primary"
  471. size="small"
  472. text
  473. v-auth="musicSheetApplicationExtend/status1751229794627878914"
  474. onClick={() => onChangeStatus(row)}
  475. >
  476. {row.status ? '停用' : '启用'}
  477. </NButton>
  478. <NButton
  479. type="primary"
  480. size="small"
  481. text
  482. v-auth="musicSheetApplicationExtend/update1751235573456044033"
  483. onClick={() => {
  484. state.showEditDialog = true
  485. state.updateRow = row
  486. }}
  487. >
  488. 修改
  489. </NButton>
  490. <NButton
  491. type="primary"
  492. size="small"
  493. text
  494. disabled={!!row.status}
  495. onClick={() => onRmove(row)}
  496. v-auth="musicSheetApplicationExtend/del1770708473623916546"
  497. >
  498. 删除
  499. </NButton>
  500. </NSpace>
  501. )
  502. }
  503. }
  504. ]
  505. }
  506. return () => {
  507. return (
  508. <div class="system-menu-container">
  509. <SaveForm
  510. ref={saveForm}
  511. model={state.searchForm}
  512. onSubmit={onSubmit}
  513. saveKey="music-sheet-klx"
  514. onSetModel={(val: any) => (state.searchForm = val)}
  515. >
  516. <NFormItem label="关键词" path="keyword">
  517. <NInput
  518. placeholder="请输入曲目名称/编号"
  519. v-model:value={state.searchForm.keyword}
  520. clearable
  521. />
  522. </NFormItem>
  523. <NFormItem label="曲目来源" path="sourceType">
  524. <NSelect
  525. placeholder="请选择曲目来源"
  526. v-model:value={state.searchForm.sourceType}
  527. options={getSelectDataFromObj(musicSheetSourceType)}
  528. onUpdateValue={async (value: any) => {
  529. state.userIdData = []
  530. state.searchForm.userId = null
  531. if (value && value !== 'PLATFORM') {
  532. await updateUserIdData(value)
  533. state.userIdDisable = !state.searchForm.extendApplicationId
  534. } else {
  535. state.userIdDisable = true
  536. }
  537. }}
  538. clearable
  539. />
  540. </NFormItem>
  541. <NFormItem label="所属项目" path="applicationId">
  542. <NSelect
  543. placeholder="请选择所属项目"
  544. v-model:value={state.searchForm.extendApplicationId}
  545. options={state.useProjectData}
  546. clearable
  547. onUpdateValue={async (value: any) => {
  548. state.searchForm.extendApplicationId = value
  549. if (value) {
  550. await updateUserIdData(state.searchForm.sourceType)
  551. state.userIdDisable = !(
  552. state.searchForm.sourceType && state.searchForm.sourceType !== 'PLATFORM'
  553. )
  554. } else {
  555. state.searchForm.userId = null
  556. state.userIdDisable = true
  557. state.userIdData = []
  558. }
  559. }}
  560. />
  561. </NFormItem>
  562. <NFormItem label="所属人" path="userId">
  563. <NSelect
  564. filterable
  565. placeholder="请选择所属人"
  566. disabled={state.userIdDisable}
  567. v-model:value={state.searchForm.userId}
  568. options={state.userIdData}
  569. clearable
  570. ></NSelect>
  571. </NFormItem>
  572. {/* <NFormItem label="谱面渲染" path="subjectType">
  573. <NSelect
  574. placeholder="请选择谱面渲染"
  575. v-model:value={state.searchForm.musicSheetType}
  576. options={getSelectDataFromObj(musicSheetType)}
  577. clearable
  578. />
  579. </NFormItem> */}
  580. <NFormItem label="伴奏类型" path="audioType">
  581. <NSelect
  582. placeholder="请选择伴奏类型"
  583. v-model:value={state.searchForm.audioType}
  584. options={getSelectDataFromObj(musicSheetAudioType)}
  585. clearable
  586. />
  587. </NFormItem>
  588. <NFormItem label="可用声部" path="subjectId">
  589. <NSelect
  590. placeholder="请选择可用声部"
  591. v-model:value={state.searchForm.subjectId}
  592. options={state.subjectList}
  593. clearable
  594. filterable
  595. />
  596. </NFormItem>
  597. <NFormItem label="曲目标签" path="musicTagIds">
  598. <NSelect
  599. placeholder="请选择曲目标签"
  600. v-model:value={state.searchForm.musicTagIds}
  601. options={state.musicTagList}
  602. multiple
  603. maxTagCount={2}
  604. clearable
  605. filterable
  606. />
  607. </NFormItem>
  608. {/*<NFormItem*/}
  609. {/* label="可用途径"*/}
  610. {/* path="availableType"*/}
  611. {/*>*/}
  612. {/* <NSelect*/}
  613. {/* placeholder="请选择可用途径"*/}
  614. {/* v-model:value={state.searchForm.availableType}*/}
  615. {/* options={getSelectDataFromObj(musicSheetAvailableType)}*/}
  616. {/* clearable*/}
  617. {/* >*/}
  618. {/* </NSelect>*/}
  619. {/*</NFormItem>*/}
  620. <NFormItem label="收费方式" path="paymentType">
  621. <NSelect
  622. placeholder="请选择收费方式"
  623. v-model:value={state.searchForm.paymentType}
  624. options={getSelectDataFromObj(musicSheetPaymentType)}
  625. clearable
  626. ></NSelect>
  627. </NFormItem>
  628. <NFormItem label="状态" path="status">
  629. <NSelect
  630. v-model:value={state.searchForm.status}
  631. placeholder="请选择状态"
  632. options={
  633. [
  634. {
  635. label: '启用',
  636. value: true
  637. },
  638. {
  639. label: '停用',
  640. value: false
  641. }
  642. ] as any
  643. }
  644. clearable
  645. />
  646. </NFormItem>
  647. <NFormItem label="上传时间" path="authorFrom">
  648. <NDatePicker
  649. v-model:value={state.searchForm.times}
  650. type="daterange"
  651. clearable
  652. value-format="yyyy.MM.dd"
  653. startPlaceholder="开始时间"
  654. endPlaceholder="结束时间"
  655. />
  656. </NFormItem>
  657. <NFormItem>
  658. <NSpace>
  659. <NButton type="primary" onClick={onSearch}>
  660. 搜索
  661. </NButton>
  662. <NButton type="default" onClick={onBtnReset}>
  663. 重置
  664. </NButton>
  665. </NSpace>
  666. </NFormItem>
  667. </SaveForm>
  668. <div class={['section-container']}>
  669. <NSpace style={{ paddingBottom: '12px' }}>
  670. <NButton
  671. type="primary"
  672. v-auth="musicSheetApplicationExtend/saveBatch1751227277370195969"
  673. onClick={() => {
  674. state.showAddDialog = true
  675. }}
  676. >
  677. 添加曲目
  678. </NButton>
  679. <NButton
  680. disabled={checkedRowKeysRef.value.length == 0}
  681. v-auth="musicSheetApplicationExtend/status1751229794627878914"
  682. onClick={() => {
  683. onBatchChangeStatus(false)
  684. }}
  685. >
  686. 批量停用
  687. </NButton>
  688. <NButton
  689. disabled={checkedRowKeysRef.value.length == 0}
  690. v-auth="musicSheetApplicationExtend/status1751229794627878914"
  691. onClick={() => {
  692. onBatchChangeStatus(true)
  693. }}
  694. >
  695. 批量启用
  696. </NButton>
  697. </NSpace>
  698. <NDataTable
  699. loading={state.loading}
  700. columns={columns()}
  701. data={state.dataList}
  702. rowKey={(row: any) => row.applicationExtendId}
  703. v-model:checkedRowKeys={checkedRowKeysRef.value}
  704. scrollX={'2000'}
  705. ></NDataTable>
  706. <Pagination
  707. v-model:page={state.pagination.page}
  708. v-model:pageSize={state.pagination.rows}
  709. v-model:pageTotal={state.pagination.pageTotal}
  710. onList={getList}
  711. sync
  712. saveKey="music-sheet-klx"
  713. ></Pagination>
  714. </div>
  715. <NModal
  716. v-model:show={state.showAddDialog}
  717. preset="dialog"
  718. showIcon={false}
  719. title={'添加曲目'}
  720. style={{ width: '1300px' }}
  721. >
  722. <AddMusic
  723. onClose={() => (state.showAddDialog = false)}
  724. onGetList={onSubmit}
  725. subjectList={state.subjectList}
  726. appId={state.appId}
  727. musicSheetTagList={state.musicTagList}
  728. />
  729. </NModal>
  730. <NModal
  731. v-model:show={state.showEditDialog}
  732. preset="dialog"
  733. showIcon={false}
  734. title={'修改曲目'}
  735. style={{ width: '500px' }}
  736. >
  737. <UpdateMusic
  738. onClose={() => (state.showEditDialog = false)}
  739. onGetList={() => {
  740. state.pagination.page = 1
  741. getList()
  742. }}
  743. rowData={state.updateRow}
  744. appId={state.appId}
  745. musicSheetTagList={state.musicTagList}
  746. />
  747. </NModal>
  748. <NModal
  749. blockScroll={true}
  750. v-model:show={state.musicPreview}
  751. preset="dialog"
  752. showIcon={false}
  753. title={'曲目预览'}
  754. style={{ width: 'auto' }}
  755. >
  756. <MusicPreView item={state.musicScore} scoreType={state.musicPreviewScoreType} />
  757. </NModal>
  758. </div>
  759. )
  760. }
  761. }
  762. })