addMusic.tsx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. import { defineComponent, h, onMounted, reactive, ref } from 'vue'
  2. import SaveForm from '@components/save-form'
  3. import {
  4. DataTableColumns,
  5. DataTableRowKey,
  6. NButton,
  7. NCascader,
  8. NDataTable,
  9. NFormItem,
  10. NIcon,
  11. NImage,
  12. NInput,
  13. NInputNumber,
  14. NSelect,
  15. NSpace,
  16. NStep,
  17. NSteps,
  18. useDialog,
  19. useMessage
  20. } from 'naive-ui'
  21. import Pagination from '@components/pagination'
  22. import { getMapValueByKey, getSelectDataFromObj } from '@/utils/objectUtil'
  23. import {appKey, musicSheetAvailableType, musicSheetSourceType, musicSheetType} from '@/utils/constant'
  24. import {musicSheetApplicationExtendCategoryList, musicSheetApplicationExtendSaveBatch, musicSheetApplicationOwnerList, musicSheetPage} from '@views/music-library/api'
  25. import deepClone from '@/utils/deep.clone'
  26. import { getOwnerName } from '@views/music-library/musicUtil'
  27. import TheTooltip from "@components/TheTooltip";
  28. import {sysApplicationPage} from "@views/menu-manage/api";
  29. export default defineComponent({
  30. name: 'gyt-addMusic',
  31. props: {
  32. appId: {
  33. type: String,
  34. required: true
  35. },
  36. subjectList: {
  37. type: Array,
  38. default: () => []
  39. },
  40. musicSheetCategories: {
  41. type: Array,
  42. default: () => []
  43. }
  44. },
  45. emits: ['close', 'getList'],
  46. setup(props, { slots, attrs, emit }) {
  47. const dialogs = useDialog()
  48. const message = useMessage()
  49. const state = reactive({
  50. loading: false,
  51. pagination: {
  52. page: 1,
  53. rows: 5,
  54. pageTotal: 0
  55. },
  56. stepPagination: {
  57. page: 1,
  58. rows: 5,
  59. pageTotal: 0
  60. },
  61. searchForm: {
  62. keyword: null,
  63. musicSheetType: null,
  64. subjectId: null,
  65. sourceType: null,
  66. composer : null,
  67. userId : null,
  68. applicationId : null,
  69. },
  70. subjectList: [] as any,
  71. showAdd: false,
  72. currentStep: 1,
  73. dataList: [],
  74. selectRowData: [] as any, // 选择的数据列表
  75. musicSheetCategories: [] as any,
  76. startSortNum: null as any, // 排序起始值
  77. projectMusicCategoryId: null as any, // 曲目分类ID
  78. useProjectData: [] as any, // 适用项目行数据
  79. userIdDisable: true,
  80. userIdData: [] as any,
  81. globalAvailableType : null as any,
  82. })
  83. onMounted(async () => {
  84. state.searchForm.keyword = null
  85. state.searchForm.musicSheetType = null
  86. state.searchForm.subjectId = null
  87. state.searchForm.sourceType = null
  88. state.searchForm.composer = null
  89. state.searchForm.userId = null
  90. state.searchForm.applicationId = null
  91. state.loading = true
  92. state.subjectList = props.subjectList
  93. // state.musicSheetCategories = props.musicSheetCategories
  94. //加载曲目分类列表
  95. try {
  96. const {data} = await musicSheetApplicationExtendCategoryList({
  97. applicationIds: props.appId
  98. })
  99. if (data && data.length > 0) {
  100. state.musicSheetCategories = data[0].musicSheetCategories
  101. }
  102. } catch {
  103. }
  104. await initUseAppList()
  105. await getList()
  106. })
  107. const initUseAppList = async () => {
  108. try {
  109. const appKeys = Object.keys(appKey)
  110. const { data } = await sysApplicationPage({ page: 1, rows: 999 })
  111. const tempList = data.rows || []
  112. state.useProjectData = []
  113. const filter = tempList.filter((next: any) => {
  114. return appKeys.includes(next.appKey)
  115. })
  116. filter.forEach((item: any) => {
  117. state.useProjectData.push({
  118. ...item,
  119. label: item.appName,
  120. value: item.id
  121. })
  122. })
  123. } catch {}
  124. }
  125. const getList = async () => {
  126. try {
  127. state.loading = true
  128. const search = {
  129. ...state.searchForm,
  130. userId: (state.searchForm.sourceType && state.searchForm.sourceType == 'PERSON') ? state.searchForm.userId : null,
  131. organizationRoleId: (state.searchForm.sourceType && state.searchForm.sourceType == 'ORG') ? state.searchForm.userId : null,
  132. }
  133. const { data } = await musicSheetPage({
  134. ...state.pagination,
  135. ...search,
  136. addAppId: props.appId
  137. })
  138. state.pagination.pageTotal = Number(data.total)
  139. state.dataList = data.rows || []
  140. } catch {}
  141. state.loading = false
  142. }
  143. const saveForm = ref()
  144. const onSearch = () => {
  145. saveForm.value?.submit()
  146. }
  147. const onBtnReset = () => {
  148. saveForm.value?.reset()
  149. }
  150. const onSubmit = () => {
  151. state.pagination.page = 1
  152. getList()
  153. }
  154. const updateUserIdData = async (sourceType: any) => {
  155. if (!state.searchForm.applicationId) {
  156. return
  157. }
  158. state.userIdData = []
  159. state.searchForm.userId = null
  160. if (sourceType && sourceType !== 'PLATFORM') {
  161. const { data } = await musicSheetApplicationOwnerList({
  162. page: 1,
  163. rows: 9999,
  164. sourceType: sourceType,
  165. applicationId: state.searchForm.applicationId
  166. })
  167. const temp = data.rows || []
  168. temp.forEach((next: any) => {
  169. state.userIdData.push({
  170. ...next,
  171. label: sourceType === 'PERSON' ? next.userName : next.organizationRole,
  172. value: sourceType === 'PERSON' ? next.userId : next.organizationRoleId
  173. })
  174. })
  175. }
  176. }
  177. const onSave = async () => {
  178. if (state.selectRowData.length == 0) {
  179. message.error('未选择曲目')
  180. return
  181. }
  182. const params = [] as any[]
  183. for (let i = 0; i < state.selectRowData.length; i++) {
  184. const item = state.selectRowData[i]
  185. if (!item.availableType) {
  186. message.error('可用途径不能为空')
  187. return
  188. }
  189. if (!item.projectMusicCategoryId) {
  190. message.error('曲目分类不能为空')
  191. return
  192. }
  193. if (item.sortNo === null || item.sortNo === undefined || item.sortNo === '') {
  194. message.error('排序号不能为空')
  195. return
  196. }
  197. params.push({
  198. ...item,
  199. musicSheetId: item.id,
  200. musicSheetCategoryId: item.projectMusicCategoryId,
  201. availableType: item.availableType,
  202. applicationId: props.appId,
  203. id: null
  204. })
  205. }
  206. const res = (await musicSheetApplicationExtendSaveBatch(params)) as any
  207. if (res && res.code == '200') {
  208. message.success(`添加成功`)
  209. emit('getList')
  210. emit('close')
  211. }
  212. }
  213. const columnsField = [
  214. {
  215. type: 'selection'
  216. },
  217. {
  218. title: '曲目编号',
  219. key: 'id'
  220. },
  221. {
  222. title: '封面图',
  223. key: 'titleImg',
  224. render(row: any) {
  225. return <NImage width={40} height={40} src={row.musicCover} />
  226. }
  227. },
  228. {
  229. title: '可用声部',
  230. key: 'subjectNames',
  231. render: (row: any) => {
  232. return <TheTooltip content={row.subjectNames}/>
  233. }
  234. },
  235. {
  236. title: '曲目名称',
  237. key: 'name'
  238. },
  239. {
  240. title: '音乐人',
  241. key: 'composer'
  242. },
  243. {
  244. title: '多声轨渲染',
  245. key: 'musicSheetType',
  246. render: (row: any) => {
  247. return (
  248. <div>
  249. {getMapValueByKey(row.musicSheetType, new Map(Object.entries(musicSheetType)))}
  250. </div>
  251. )
  252. }
  253. },
  254. {
  255. title: '曲目来源',
  256. key: 'sourceType',
  257. render(row: any) {
  258. return getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)))
  259. }
  260. },
  261. {
  262. title: '所属人',
  263. key: 'userName',
  264. render: (row: any) => {
  265. return <TheTooltip content={getOwnerName(row.musicSheetExtend, row.sourceType)} />
  266. }
  267. }
  268. ]
  269. const columns = (): any => {
  270. return columnsField
  271. }
  272. const stepColumns = (): DataTableColumns => {
  273. const field = deepClone(columnsField)
  274. field.splice(0, 1)
  275. field.push({
  276. title(column: any) {
  277. return (
  278. <NSpace>
  279. 可用途径
  280. <NButton
  281. type="primary"
  282. size="small"
  283. text
  284. onClick={() => {
  285. dialogs.create({
  286. title: '请选择可用途径',
  287. showIcon: false,
  288. content: () => {
  289. return h(
  290. 'div',
  291. {
  292. class: 'flex flex-col justify-center items-center text-14px'
  293. },
  294. [
  295. // icon
  296. h(NSelect, {
  297. onUpdateValue(v) {
  298. state.globalAvailableType = v
  299. },
  300. clearable: true,
  301. options: [
  302. {
  303. label: '学校',
  304. value: 'ORG'
  305. },
  306. {
  307. label: '平台',
  308. value: 'PLATFORM'
  309. },
  310. {
  311. label: '个人',
  312. value: 'PERSON'
  313. },
  314. ]
  315. })
  316. ]
  317. )
  318. },
  319. positiveText: '确定',
  320. negativeText: '取消',
  321. onPositiveClick: () => {
  322. for (let i = 0; i < state.selectRowData.length; i++) {
  323. const item = state.selectRowData[i]
  324. item.availableType = state.globalAvailableType
  325. }
  326. }
  327. })
  328. }}
  329. >
  330. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  331. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  332. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  333. <path
  334. d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
  335. fill="currentColor"
  336. ></path>
  337. </svg>
  338. </NIcon>
  339. </NButton>
  340. </NSpace>
  341. )
  342. },
  343. key: 'availableType',
  344. render: (row: any) => {
  345. return (
  346. <NSelect
  347. placeholder="请选择可用途径"
  348. value={row.availableType}
  349. options={[
  350. {
  351. label: '学校',
  352. value: 'ORG'
  353. },
  354. {
  355. label: '平台',
  356. value: 'PLATFORM'
  357. },
  358. {
  359. label: '个人',
  360. value: 'PERSON'
  361. },
  362. ]}
  363. onUpdateValue={(value) => {
  364. row['availableType'] = value
  365. }}
  366. clearable
  367. />
  368. )
  369. }
  370. })
  371. field.push({
  372. title(column: any) {
  373. return (
  374. <NSpace>
  375. 曲目分类
  376. <NButton
  377. type="primary"
  378. size="small"
  379. text
  380. onClick={() => {
  381. dialogs.create({
  382. title: '请选择曲目分类',
  383. showIcon: false,
  384. content: () => {
  385. return h(
  386. 'div',
  387. {
  388. class: 'flex flex-col justify-center items-center text-14px'
  389. },
  390. [
  391. // icon
  392. h(NCascader, {
  393. onUpdateValue(v) {
  394. state.projectMusicCategoryId = v
  395. },
  396. valueField: 'id',
  397. labelField: 'name',
  398. childrenField: 'children',
  399. placeholderField: '请选择曲目分类',
  400. options: state.musicSheetCategories
  401. })
  402. ]
  403. )
  404. },
  405. positiveText: '确定',
  406. negativeText: '取消',
  407. onPositiveClick: () => {
  408. for (let i = 0; i < state.selectRowData.length; i++) {
  409. const item = state.selectRowData[i]
  410. item.projectMusicCategoryId = state.projectMusicCategoryId
  411. }
  412. }
  413. })
  414. }}
  415. >
  416. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  417. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  418. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  419. <path
  420. d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
  421. fill="currentColor"
  422. ></path>
  423. </svg>
  424. </NIcon>
  425. </NButton>
  426. </NSpace>
  427. )
  428. },
  429. key: 'projectMusicCategoryId',
  430. fixed: 'right',
  431. width: 200,
  432. render: (row: any) => {
  433. // })
  434. return (
  435. <NCascader
  436. valueField="id"
  437. labelField="name"
  438. children-field="children"
  439. placeholder="请选择曲目分类"
  440. value={row.projectMusicCategoryId}
  441. options={state.musicSheetCategories}
  442. onUpdateValue={(value: any) => {
  443. row.projectMusicCategoryId = value
  444. }}
  445. clearable
  446. />
  447. )
  448. }
  449. })
  450. field.push({
  451. title(column: any) {
  452. return (
  453. <NSpace>
  454. 排序
  455. <NButton
  456. type="primary"
  457. size="small"
  458. text
  459. onClick={() => {
  460. dialogs.create({
  461. title: '请输入排序起始值',
  462. showIcon: false,
  463. content: () => {
  464. return h(
  465. 'div',
  466. {
  467. class: 'flex flex-col justify-center items-center text-14px'
  468. },
  469. [
  470. // icon
  471. h(NInputNumber, {
  472. onUpdateValue(v) {
  473. state.startSortNum = v
  474. },
  475. min: 0,
  476. max: 9999
  477. })
  478. ]
  479. )
  480. },
  481. positiveText: '确定',
  482. negativeText: '取消',
  483. onPositiveClick: () => {
  484. if (state.startSortNum) {
  485. for (let i = 0; i < state.selectRowData.length; i++) {
  486. const item = state.selectRowData[i]
  487. item.sortNo = state.startSortNum + i
  488. }
  489. }
  490. }
  491. })
  492. }}
  493. >
  494. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  495. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  496. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  497. <path
  498. d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
  499. fill="currentColor"
  500. ></path>
  501. </svg>
  502. </NIcon>
  503. </NButton>
  504. </NSpace>
  505. )
  506. },
  507. key: 'sortNo',
  508. fixed: 'right',
  509. width: 150,
  510. render: (row: any) => {
  511. return h(NInputNumber, {
  512. value: row.sortNo,
  513. min: 0,
  514. max: 9999,
  515. onUpdateValue(value: any) {
  516. row.sortNo = value
  517. }
  518. })
  519. }
  520. })
  521. field.push({
  522. title: '操作',
  523. key: 'operation',
  524. fixed: 'right',
  525. render(row: any) {
  526. return (
  527. <NSpace>
  528. <NButton
  529. type="primary"
  530. size="small"
  531. text
  532. //v-auth="musicSheet/update1602302618558099458"
  533. onClick={() => {
  534. dialogs.warning({
  535. title: '提示',
  536. content: `是否删除该数据?`,
  537. positiveText: '确定',
  538. negativeText: '取消',
  539. onPositiveClick: async () => {
  540. try {
  541. const index = state.selectRowData.findIndex((item: any) => {
  542. if (item.id == row.id) {
  543. return true
  544. }
  545. })
  546. if (index > -1) {
  547. state.selectRowData.splice(index, 1)
  548. }
  549. const index1 = checkedRowKeysRef.value.findIndex((item: any) => {
  550. if (item == row.id) {
  551. return true
  552. }
  553. })
  554. if (index1 > -1) {
  555. checkedRowKeysRef.value.splice(index, 1)
  556. }
  557. } catch {}
  558. }
  559. })
  560. }}
  561. >
  562. 移除
  563. </NButton>
  564. </NSpace>
  565. )
  566. }
  567. })
  568. return field
  569. }
  570. const checkedRowKeysRef = ref<DataTableRowKey[]>([])
  571. const handleCheck = (rowKeys: DataTableRowKey[]) => {
  572. checkedRowKeysRef.value = rowKeys
  573. // 添加行更新值
  574. state.dataList.forEach((next: any) => {
  575. if (checkedRowKeysRef.value.includes(next.id)) {
  576. const find = state.selectRowData.find((row: any) => {
  577. return row.id === next.id
  578. })
  579. if (!find) {
  580. state.selectRowData.push(next)
  581. }
  582. }
  583. })
  584. // 去掉行更新值
  585. state.selectRowData = state.selectRowData.filter((next: any) => {
  586. return checkedRowKeysRef.value.includes(next.id)
  587. })
  588. }
  589. return () => {
  590. return (
  591. <div class="system-menu-container">
  592. <NSpace vertical size="medium">
  593. <NSteps
  594. current={state.currentStep}
  595. // onUpdateCurrent={()=>{
  596. // state.currentStep = val
  597. // }}
  598. style={'margin-bottom: 10px;margin-top: 10px'}
  599. >
  600. <NStep title="选择曲目" description=""></NStep>
  601. <NStep title="设置曲目信息" description=""></NStep>
  602. </NSteps>
  603. </NSpace>
  604. {state.currentStep === 1 && (
  605. <div class="system-menu-container">
  606. <SaveForm
  607. ref={saveForm}
  608. model={state.searchForm}
  609. onSubmit={onSubmit}
  610. // saveKey="cooleshow-edu-addMusic"
  611. onSetModel={(val: any) => (state.searchForm = val)}
  612. >
  613. <NFormItem label="关键词" path="keyword">
  614. <NInput
  615. v-model:value={state.searchForm.keyword}
  616. placeholder="请输入曲目名称/编号"
  617. clearable
  618. />
  619. </NFormItem>
  620. <NFormItem label="多声轨渲染" path="musicSheetType">
  621. <NSelect
  622. placeholder="请选择多声轨渲染"
  623. v-model:value={state.searchForm.musicSheetType}
  624. options={getSelectDataFromObj(musicSheetType)}
  625. clearable
  626. />
  627. </NFormItem>
  628. <NFormItem label="可用声部" path="musicSubject">
  629. <NSelect
  630. placeholder="请选择可用声部"
  631. v-model:value={state.searchForm.subjectId}
  632. options={state.subjectList}
  633. clearable
  634. />
  635. </NFormItem>
  636. <NFormItem label="音乐人" path="composer">
  637. <NInput
  638. placeholder="请选择音乐人"
  639. v-model:value={state.searchForm.composer}
  640. clearable
  641. />
  642. </NFormItem>
  643. <NFormItem label="曲目来源" path="sourceType">
  644. <NSelect
  645. placeholder="请选择曲目来源"
  646. v-model:value={state.searchForm.sourceType}
  647. options={getSelectDataFromObj(musicSheetSourceType)}
  648. onUpdateValue={async (value: any) => {
  649. state.userIdData = []
  650. state.searchForm.userId = null
  651. if (value && value !== 'PLATFORM') {
  652. await updateUserIdData(value)
  653. state.userIdDisable = false
  654. } else {
  655. state.userIdDisable = true
  656. }
  657. }}
  658. clearable
  659. />
  660. </NFormItem>
  661. <NFormItem label="所属项目" path="applicationId">
  662. <NSelect
  663. placeholder="请选择所属项目"
  664. v-model:value={state.searchForm.applicationId}
  665. options={state.useProjectData}
  666. clearable
  667. onUpdateValue={async (value: any) => {
  668. state.searchForm.applicationId = value
  669. if (value) {
  670. await updateUserIdData(state.searchForm.sourceType)
  671. state.userIdDisable = !(
  672. state.searchForm.sourceType && state.searchForm.sourceType !== 'PLATFORM'
  673. )
  674. } else {
  675. state.searchForm.userId = null
  676. state.userIdDisable = true
  677. state.userIdData = []
  678. }
  679. }}
  680. />
  681. </NFormItem>
  682. <NFormItem label="所属人" path="author">
  683. <NSelect
  684. filterable
  685. placeholder="请选择所属人"
  686. disabled={state.userIdDisable || (!state.searchForm.applicationId && !state.searchForm.sourceType)}
  687. v-model:value={state.searchForm.userId}
  688. options={state.userIdData}
  689. clearable
  690. ></NSelect>
  691. </NFormItem>
  692. <NFormItem>
  693. <NSpace>
  694. <NButton type="primary" onClick={onSearch}>
  695. 搜索
  696. </NButton>
  697. <NButton type="default" onClick={onBtnReset}>
  698. 重置
  699. </NButton>
  700. </NSpace>
  701. </NFormItem>
  702. </SaveForm>
  703. <p style={{ paddingBottom: '12px' }}>
  704. 你选择了<span style={'color:red;padding:0 8px'}>{state.selectRowData.length}</span>
  705. 条曲目
  706. </p>
  707. <NDataTable
  708. loading={state.loading}
  709. columns={columns()}
  710. data={state.dataList}
  711. rowKey={(row: any) => row.id}
  712. onUpdateCheckedRowKeys={handleCheck}
  713. ></NDataTable>
  714. <Pagination
  715. v-model:page={state.pagination.page}
  716. v-model:pageSize={state.pagination.rows}
  717. v-model:pageTotal={state.pagination.pageTotal}
  718. onList={getList}
  719. sync
  720. // saveKey="cooleshow-edu-addMusic"
  721. ></Pagination>
  722. </div>
  723. )}
  724. {state.currentStep === 2 && (
  725. <div class="system-menu-container" style={'margin-top: 15px;'}>
  726. <NDataTable
  727. loading={state.loading}
  728. columns={stepColumns()}
  729. data={state.selectRowData}
  730. rowKey={(row: any) => row.id}
  731. maxHeight={500}
  732. ></NDataTable>
  733. </div>
  734. )}
  735. <NSpace justify="end" style={'margin-top:10px'}>
  736. <NButton
  737. type="default"
  738. onClick={() => {
  739. if (state.currentStep > 1) {
  740. state.currentStep = state.currentStep - 1
  741. } else {
  742. emit('close')
  743. }
  744. }}
  745. >
  746. {state.currentStep === 1 ? '取消' : '上一步'}
  747. </NButton>
  748. <NButton
  749. type="primary"
  750. onClick={() => {
  751. if (state.currentStep < 2) {
  752. if (state.selectRowData.length == 0) {
  753. message.warning('请选择曲目')
  754. return
  755. }
  756. state.currentStep = state.currentStep + 1
  757. } else {
  758. onSave()
  759. }
  760. }}
  761. // loading={btnLoading.value}
  762. // disabled={btnLoading.value}
  763. >
  764. {state.currentStep === 2 ? '确定' : '下一步'}
  765. </NButton>
  766. </NSpace>
  767. </div>
  768. )
  769. }
  770. }
  771. })